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..09477c59800 --- /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/.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/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index 397fe8a43b9..de34d7b8004 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -39,7 +39,7 @@ jobs: python-version: "3.11" architecture: x64 - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version-file: './ui/.nvmrc' registry-url: 'https://registry.npmjs.org' diff --git a/.github/workflows/deploy-website.yml b/.github/workflows/deploy-website.yml index b5dbe7444a9..f402f907919 100644 --- a/.github/workflows/deploy-website.yml +++ b/.github/workflows/deploy-website.yml @@ -43,7 +43,7 @@ jobs: uses: actions/configure-pages@v4 - name: Upload artifact - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@v4 with: path: infra/website/dist diff --git a/.github/workflows/master_only.yml b/.github/workflows/master_only.yml index 83355979546..c4a22b8c756 100644 --- a/.github/workflows/master_only.yml +++ b/.github/workflows/master_only.yml @@ -36,17 +36,17 @@ jobs: python-version: ${{ matrix.python-version }} architecture: x64 - 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 run: gcloud info - 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/workflows/nightly-ci.yml b/.github/workflows/nightly-ci.yml index fc25a0d0cc9..e4ab32acd6d 100644 --- a/.github/workflows/nightly-ci.yml +++ b/.github/workflows/nightly-ci.yml @@ -39,7 +39,7 @@ jobs: python-version: "3.11" architecture: x64 - 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 }} @@ -50,11 +50,11 @@ jobs: pip install google-cloud-bigtable pip install tqdm - 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 @@ -96,21 +96,21 @@ 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 run: gcloud info - 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/workflows/operator-e2e-integration-tests.yml b/.github/workflows/operator-e2e-integration-tests.yml index bdaa3240702..a0e5e75398f 100644 --- a/.github/workflows/operator-e2e-integration-tests.yml +++ b/.github/workflows/operator-e2e-integration-tests.yml @@ -52,7 +52,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.22.9 + go-version: 1.24.12 - name: Create KIND cluster run: | diff --git a/.github/workflows/operator_pr.yml b/.github/workflows/operator_pr.yml index 8f08c91b890..39066286e53 100644 --- a/.github/workflows/operator_pr.yml +++ b/.github/workflows/operator_pr.yml @@ -14,7 +14,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: 1.22.9 + go-version: 1.24.12 - name: Operator tests run: make -C infra/feast-operator test - name: After code formatting, check for uncommitted differences diff --git a/.github/workflows/pr_integration_tests.yml b/.github/workflows/pr_integration_tests.yml index cac38222475..936b2777f1d 100644 --- a/.github/workflows/pr_integration_tests.yml +++ b/.github/workflows/pr_integration_tests.yml @@ -57,17 +57,17 @@ jobs: python-version: ${{ matrix.python-version }} architecture: x64 - 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 run: gcloud info - 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/workflows/pr_local_integration_tests.yml b/.github/workflows/pr_local_integration_tests.yml index b607c2c6b1e..4926d9970d2 100644 --- a/.github/workflows/pr_local_integration_tests.yml +++ b/.github/workflows/pr_local_integration_tests.yml @@ -59,7 +59,7 @@ jobs: - name: Install Go uses: actions/setup-go@v5 with: - go-version: 1.22.9 + go-version: 1.24.12 - name: Operator Data Source types test run: make -C infra/feast-operator test-datasources - name: Minimize uv cache diff --git a/.github/workflows/pr_registration_integration_tests.yml b/.github/workflows/pr_registration_integration_tests.yml index 4085a320057..76cbe701cf4 100644 --- a/.github/workflows/pr_registration_integration_tests.yml +++ b/.github/workflows/pr_registration_integration_tests.yml @@ -60,15 +60,15 @@ jobs: submodules: recursive persist-credentials: false - 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: 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/workflows/publish_helm_charts.yml b/.github/workflows/publish_helm_charts.yml index b137a33d985..85c780a23b9 100644 --- a/.github/workflows/publish_helm_charts.yml +++ b/.github/workflows/publish_helm_charts.yml @@ -40,11 +40,11 @@ jobs: custom_version: ${{ github.event.inputs.custom_version }} token: ${{ github.event.inputs.token }} - 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 }} - run: gcloud auth configure-docker --quiet diff --git a/.github/workflows/publish_images.yml b/.github/workflows/publish_images.yml index 63055981a90..9a626b434dd 100644 --- a/.github/workflows/publish_images.yml +++ b/.github/workflows/publish_images.yml @@ -55,11 +55,11 @@ jobs: username: ${{ secrets.QUAYIO_USERNAME }} password: ${{ secrets.QUAYIO_TOKEN }} - 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/workflows/publish_web_ui.yml b/.github/workflows/publish_web_ui.yml index 8ce629f31da..f8f52f6a84c 100644 --- a/.github/workflows/publish_web_ui.yml +++ b/.github/workflows/publish_web_ui.yml @@ -106,7 +106,7 @@ jobs: echo "version_without_prefix=$CURRENT_VERSION" >> $GITHUB_OUTPUT echo "Final current version (without prefix): $CURRENT_VERSION" - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version-file: './ui/.nvmrc' registry-url: 'https://registry.npmjs.org' diff --git a/.github/workflows/registry-rest-api-tests.yml b/.github/workflows/registry-rest-api-tests.yml index 6175cab3d8f..68be4e9b91d 100644 --- a/.github/workflows/registry-rest-api-tests.yml +++ b/.github/workflows/registry-rest-api-tests.yml @@ -50,7 +50,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.22.9 + go-version: 1.24.12 - name: Create KIND cluster run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 57826d56924..b2e8f39fbef 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -52,7 +52,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: "lts/*" - name: Release (Dry Run) @@ -80,7 +80,7 @@ jobs: with: fetch-depth: 0 - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: "lts/*" - name: Bump file versions @@ -109,9 +109,9 @@ jobs: - name: Validate all version consistency run: ./infra/scripts/helm/validate-helm-chart-versions.sh $NEXT_VERSION - name: Install Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v5 with: - go-version: 1.22.9 + go-version: 1.24.12 - name: Build & version operator-specific release files run: make -C infra/feast-operator build-installer bundle @@ -132,7 +132,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version-file: './ui/.nvmrc' - name: Set up Homebrew @@ -142,9 +142,9 @@ jobs: run: | brew install norwoodj/tap/helm-docs - name: Install Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v5 with: - go-version: 1.22.9 + go-version: 1.24.12 - name: Compile Go Test Binaries run: | cd infra/feast-operator diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index c12998fce57..0259d8a2b9e 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -32,15 +32,15 @@ jobs: uses: actions/checkout@v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@v3 + uses: github/codeql-action/autobuild@v4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 with: category: "/language:${{ matrix.language }}" diff --git a/.gitignore b/.gitignore index c0fdd58d338..4d83daeead1 100644 --- a/.gitignore +++ b/.gitignore @@ -266,4 +266,7 @@ Desktop.ini .agentready/ # Claude Code project settings -.claude/ +# Claude Code local state (conversation history, credentials, cache) +.claude/settings.local.json +.claude/todos/ +.claude/cache/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2ce95f07707..fcfce78288e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -38,6 +38,17 @@ repos: entry: uv run make build-templates pass_filenames: false + # Pre-push lint gate — check-only. Auto-fix omitted: pre-push cannot change committed objects. + # If blocked, run "make format-python", then amend/commit and push again. + - id: lint-push + name: Lint Before Push + stages: [push] + language: system + types: [python] + exclude: '_pb2\.py$' + entry: bash -c 'uv run ruff check "$@" && uv run ruff format --check "$@"' -- + pass_filenames: true + - repo: https://github.com/Yelp/detect-secrets rev: v1.5.0 hooks: diff --git a/.secrets.baseline b/.secrets.baseline index 96bf780809c..3d012df0987 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -934,7 +934,7 @@ "filename": "infra/feast-operator/api/v1/featurestore_types.go", "hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c", "is_verified": false, - "line_number": 761 + "line_number": 879 } ], "infra/feast-operator/api/v1/zz_generated.deepcopy.go": [ @@ -943,21 +943,21 @@ "filename": "infra/feast-operator/api/v1/zz_generated.deepcopy.go", "hashed_secret": "f914fc9324de1bec1ad13dec94a8ea2ddb41fc87", "is_verified": false, - "line_number": 693 + "line_number": 785 }, { "type": "Secret Keyword", "filename": "infra/feast-operator/api/v1/zz_generated.deepcopy.go", "hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c", "is_verified": false, - "line_number": 754 + "line_number": 846 }, { "type": "Secret Keyword", "filename": "infra/feast-operator/api/v1/zz_generated.deepcopy.go", "hashed_secret": "c2028031c154bbe86fd69bef740855c74b927dcf", "is_verified": false, - "line_number": 1300 + "line_number": 1491 } ], "infra/feast-operator/api/v1alpha1/featurestore_types.go": [ @@ -1122,7 +1122,7 @@ "filename": "infra/feast-operator/internal/controller/featurestore_controller_oidc_auth_test.go", "hashed_secret": "a1f14fc6f33ba39a8b6d006fefa6fe0fe8d60ae2", "is_verified": false, - "line_number": 447 + "line_number": 450 } ], "infra/feast-operator/internal/controller/featurestore_controller_test_utils_test.go": [ @@ -1140,14 +1140,14 @@ "filename": "infra/feast-operator/internal/controller/services/repo_config.go", "hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c", "is_verified": false, - "line_number": 114 + "line_number": 129 }, { "type": "Secret Keyword", "filename": "infra/feast-operator/internal/controller/services/repo_config.go", "hashed_secret": "e2fb052132fd6a07a56af2013e0b62a1f510572c", "is_verified": false, - "line_number": 205 + "line_number": 220 } ], "infra/feast-operator/internal/controller/services/services.go": [ @@ -1340,7 +1340,7 @@ "filename": "sdk/python/tests/integration/registration/test_universal_registry.py", "hashed_secret": "53e9042a36213bf85ef29a4371896aef8ba9196a", "is_verified": false, - "line_number": 126 + "line_number": 127 } ], "sdk/python/tests/integration/rest_api/resource/feast_config_rhoai.yaml": [ @@ -1426,7 +1426,7 @@ "filename": "sdk/python/tests/unit/infra/utils/snowflake/test_snowflake_utils.py", "hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", "is_verified": false, - "line_number": 10 + "line_number": 14 } ], "sdk/python/tests/unit/local_feast_tests/test_init.py": [ @@ -1460,14 +1460,14 @@ "filename": "sdk/python/tests/universal/feature_repos/repo_configuration.py", "hashed_secret": "d90e76ef629fb00c95f4e84fec29fbda111e2392", "is_verified": false, - "line_number": 459 + "line_number": 466 }, { "type": "Secret Keyword", "filename": "sdk/python/tests/universal/feature_repos/repo_configuration.py", "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", "is_verified": false, - "line_number": 461 + "line_number": 468 } ], "sdk/python/tests/universal/feature_repos/universal/data_sources/file.py": [ @@ -1510,7 +1510,7 @@ "filename": "sdk/python/tests/universal/feature_repos/universal/online_store/postgres.py", "hashed_secret": "95433727ea51026e1e0dc8deadaabd4a3baaaaf4", "is_verified": false, - "line_number": 19 + "line_number": 20 } ], "sdk/python/tests/universal/feature_repos/universal/online_store/singlestore.py": [ @@ -1539,5 +1539,5 @@ } ] }, - "generated_at": "2026-04-07T15:56:56Z" + "generated_at": "2026-05-01T07:12:24Z" } diff --git a/AGENTS.md b/AGENTS.md index 935fb7e3938..e8ebb031cdc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,98 +17,51 @@ Feast (Feature Store) is a Python-based project that provides: ### Setup ```bash -# Install development dependencies make install-python-dependencies-dev - -# Install minimal dependencies make install-python-dependencies-minimal ``` ### Code Quality ```bash -# Format Python code +# Format Python code (entire codebase) make format-python -# Lint Python code +# Lint Python code (entire codebase) make lint-python -# Type check -cd sdk/python && python -m mypy feast -``` - -### Testing -```bash -# Run unit tests -make test-python-unit - -# Run integration tests (local) -make test-python-integration-local +# Full type check (entire codebase) +uv run bash -c "cd sdk/python && mypy feast" -# Run integration tests (CI) -make test-python-integration - -# Run all Python tests -make test-python-universal +# Full type check including tests +make mypy-full ``` -### Protobuf Compilation +#### Single-file lint and type-check +When working on a specific file, run checks scoped to that file to get fast feedback: ```bash -# Compile Python protobuf files -make compile-protos-python - -# Compile all protos -make protos +uv run ruff check sdk/python/feast/path/to/file.py # lint +uv run ruff check --fix sdk/python/feast/path/to/file.py # lint + auto-fix +uv run ruff format sdk/python/feast/path/to/file.py # format +uv run bash -c "cd sdk/python && mypy feast/path/to/file.py" # type-check ``` -### Go Development +### Testing ```bash -# Build Go code -make build-go - -# Test Go code -make test-go - -# Format Go code -make format-go - -# Lint Go code -make lint-go +make test-python-unit # unit tests +make test-python-integration-local # integration tests (local) +make test-python-integration # integration tests (CI) +make test-python-universal # all Python tests ``` -### Docker +### Protobuf Compilation ```bash -# Build all Docker images -make build-docker - -# Build feature server Docker image -make build-feature-server-docker +make compile-protos-python # Python protobufs +make protos # all protos ``` -### Documentation +### Go Development ```bash -# Build Sphinx documentation -make build-sphinx - -# Build templates -make build-templates - -# Build Helm docs -make build-helm-docs -``` - -## Project Structure - -``` -feast/ -├── sdk/python/ # Python SDK and core implementation -├── go/ # Go implementation -├── ui/ # Web UI -├── docs/ # Documentation -├── examples/ # Example projects -├── infra/ # Infrastructure and deployment -│ ├── charts/ # Helm charts -│ └── feast-operator/ # Kubernetes operator -└── protos/ # Protocol buffer definitions +make build-go && make test-go && make format-go && make lint-go ``` ## Key Technologies @@ -120,24 +73,30 @@ feast/ - **Offline Stores**: BigQuery, Snowflake, Redshift, Spark, Dask, DuckDB - **Cloud Providers**: AWS, GCP, Azure -## Common Development Tasks +## Agent Skills + +The `skills/` directory contains tool-agnostic skills (compatible with Claude Code, OpenAI Codex, and other agent tools): + +| Skill | Path | Use when… | +|---|---|---| +| **feast-user-guide** | `skills/feast-user-guide/SKILL.md` | Working with Feast as a user: defining features, retrieval, CLI, RAG | +| **feast-dev** | `skills/feast-dev/SKILL.md` | Contributing to Feast: setup, tests, Docker, docs, PR workflow | +| **feast-architecture** | `skills/feast-architecture/SKILL.md` | Understanding how each component works: registry, materialization, feature server, data flows | +| **feast-testing** | `skills/feast-testing/SKILL.md` | Writing tests, running targeted tests, debugging registry/online store issues | + +Reference docs: `skills/references/` — feature definitions, configuration, retrieval & RAG. -### Running Tests -The project uses pytest for Python testing with extensive integration test suites for different data sources and stores. +Architecture & design intent: `docs/getting-started/architecture/` (overview, write patterns, RBAC), `docs/getting-started/components/` (per-component pages), `docs/adr/` (design decisions). + +## Code Style -### Code Style - Use type hints on all Python function signatures - Follow existing patterns in the module you are modifying - PR titles must follow semantic conventions: `feat:`, `fix:`, `ci:`, `chore:`, `docs:` - Sign off commits with `git commit -s` (DCO requirement) -- Uses `ruff` for Python linting and formatting -- Go uses standard `gofmt` - -### Protobuf Development -Protocol buffers are used for data serialization and gRPC APIs. Recompile protos after making changes to `.proto` files. - -### Multi-language Support -Feast supports Python and Go SDKs. Changes to core functionality may require updates across both languages. +- Uses `ruff` for Python linting and formatting; Go uses standard `gofmt` +- Recompile protos after making changes to `.proto` files (`make protos`) +- Changes to core functionality may require updates across both Python and Go SDKs ## Documentation and Blog Posts diff --git a/CHANGELOG.md b/CHANGELOG.md index cdc815b6421..7f1643e3ed0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,60 @@ # Changelog +# [0.63.0](https://github.com/feast-dev/feast/compare/v0.62.0...v0.63.0) (2026-05-04) + + +### Bug Fixes + +* Add project filter to apply_data_source and delete_data_source (closes [#6206](https://github.com/feast-dev/feast/issues/6206)) ([#6322](https://github.com/feast-dev/feast/issues/6322)) ([96562c4](https://github.com/feast-dev/feast/commit/96562c421e40229772c6899b9cf33510d861dc13)) +* Add project_id filter to SnowflakeRegistry UPDATE path ([#6243](https://github.com/feast-dev/feast/issues/6243)) ([6658b71](https://github.com/feast-dev/feast/commit/6658b71b1786289cb3189bf90204d6e1fbef5210)), closes [#6208](https://github.com/feast-dev/feast/issues/6208) [feast-dev/feast#6208](https://github.com/feast-dev/feast/issues/6208) +* Add subprocess timeouts to prevent test_e2e_local hanging on Dask atexit handler ([3de6556](https://github.com/feast-dev/feast/commit/3de6556dc49561d0998958119f2504f7b9fa6eb2)) +* Ambiguous truth value of array during materialization ([#6259](https://github.com/feast-dev/feast/issues/6259)) ([d0c8984](https://github.com/feast-dev/feast/commit/d0c89846f3340fabaa036a4a8f61795b541e920d)) +* Auto-detect GCS/S3 registry store when registry is passed as string ([#6260](https://github.com/feast-dev/feast/issues/6260)) ([7ebcf03](https://github.com/feast-dev/feast/commit/7ebcf03d6d33a3904bcfd9f4cbc01ce7d606856d)) +* **bigquery:** Prefer query over table in get_table_query_string ([#6360](https://github.com/feast-dev/feast/issues/6360)) ([77ed779](https://github.com/feast-dev/feast/commit/77ed779bc894e6aafac20d4a331367e727e22136)), closes [#6200](https://github.com/feast-dev/feast/issues/6200) +* correct project_id scoping in get_user_metadata and delete_project ([0c469a7](https://github.com/feast-dev/feast/commit/0c469a7f1d49046c6be7be61bd65ca706b2f207e)) +* disable Redis RDB persistence in test deployments ([44cd682](https://github.com/feast-dev/feast/commit/44cd68272685e011be4450fa25d0c720ff7fccd9)) +* Disable snowflake tests temporarily in CI ([#6356](https://github.com/feast-dev/feast/issues/6356)) ([31d5a98](https://github.com/feast-dev/feast/commit/31d5a9879449ec4c9054842dad07818cb12134de)) +* Filter empty SQL commands at execute_snowflake_statement call sites ([#6249](https://github.com/feast-dev/feast/issues/6249)) ([92ffbb9](https://github.com/feast-dev/feast/commit/92ffbb999c6f11764b8e2c3225268d1cd2c1d5ab)) +* Fix five bugs in milvus online store ([#6275](https://github.com/feast-dev/feast/issues/6275)) ([212504b](https://github.com/feast-dev/feast/commit/212504bb7aa32fb6ff14be82490a2f5f50616937)) +* Fix issue with apply feature view ([835cda8](https://github.com/feast-dev/feast/commit/835cda8e2c1359f1f496ad72701dbd6a73bdb25a)) +* Fix streaming materialization for exotic sources with lazy UDF pipelines ([c07972d](https://github.com/feast-dev/feast/commit/c07972dd09d2366c43ed9b632a669162b5d45f97)) +* Handle missing features gracefully instead of panicking ([7d00b3a](https://github.com/feast-dev/feast/commit/7d00b3ac2f07d7611b20cf3baf1220868825baa6)) +* Harden informer cache with label selectors and memory optimizations ([#6242](https://github.com/feast-dev/feast/issues/6242)) ([3f11356](https://github.com/feast-dev/feast/commit/3f11356d78d6a3e4d1e030228faa4b12908d730f)) +* **helm:** Avoid nil pointer for metrics.enabled inside podAnnotations ([#6251](https://github.com/feast-dev/feast/issues/6251)) ([c833f1a](https://github.com/feast-dev/feast/commit/c833f1a5990376999938406e464649c601b9d339)) +* Include git in feast server image ([fb03c46](https://github.com/feast-dev/feast/commit/fb03c469cb108443bc24ac5c8dfbe17769746deb)) +* Include StreamFeatureView in freshness metric ([#6269](https://github.com/feast-dev/feast/issues/6269)) ([463f16c](https://github.com/feast-dev/feast/commit/463f16ccec6837f35c7e365d8b21815db487b2df)) +* Pre-create S3A event log dir before SparkContext init ([#6317](https://github.com/feast-dev/feast/issues/6317)) ([9feca77](https://github.com/feast-dev/feast/commit/9feca77f855db527b2d494e28bd8c872a372b97e)) +* Remote Online Store Type Inference Error with All-NULL Columns ([#6063](https://github.com/feast-dev/feast/issues/6063)) ([de67bdd](https://github.com/feast-dev/feast/commit/de67bdd849f819b10306bc80732bd55779248ed1)) +* Remove selector with kustomize overlay using a JSON 6902 patch ([9107a43](https://github.com/feast-dev/feast/commit/9107a43d9cccd3a8545e7e1977ad87821c665c94)) +* Resolve multiple bugs in SnowflakeRegistry and Snowflake connection handling ([#6315](https://github.com/feast-dev/feast/issues/6315)) ([7e66a2e](https://github.com/feast-dev/feast/commit/7e66a2ef9a5af01467f2f1eb83f9b9a3e102843a)) +* **spark:** BatchFeatureView with TransformationMode.PYTHON now reads all source columns ([a310eaf](https://github.com/feast-dev/feast/commit/a310eaf304a2aa816fed389cc6a39ed126f21c6b)) +* **spark:** Use SELECT * when feature_name_columns is empty in pull_all_from_table_or_query ([e1b1d2d](https://github.com/feast-dev/feast/commit/e1b1d2d6e832b286b5f3011a19ca3bedabc05e80)) +* Support pandas mode in feature builder and fix dask column extraction ([863315e](https://github.com/feast-dev/feast/commit/863315e212a1aa3179b17cd1761f159100ffda15)) +* support SQL string as entity_df in RemoteOfflineStore.get_historical_features ([c559889](https://github.com/feast-dev/feast/commit/c559889c244ef2abe151d472c383287f6e16f01a)) +* Wrap LocalOutputNode return value in ArrowTableValue for consist… ([#6286](https://github.com/feast-dev/feast/issues/6286)) ([a16cd55](https://github.com/feast-dev/feast/commit/a16cd550983531e74f2f4da857f8eb8a53c7fcdb)) + + +### Features + +* Add agent skills and Cursor/Claude rules for Feast development ([312eea3](https://github.com/feast-dev/feast/commit/312eea3e363910ef99901c6c4048698cd24166a8)) +* Add feature view versioning support to FAISS online store ([b36acb7](https://github.com/feast-dev/feast/commit/b36acb71673894db78283664dde10da9fec20c21)) +* Add feature view versioning support to Redis and DynamoDB online stores ([#6257](https://github.com/feast-dev/feast/issues/6257)) ([edf25af](https://github.com/feast-dev/feast/commit/edf25af12686ace485a93d1a742e04f4d7681bf8)), closes [#6164](https://github.com/feast-dev/feast/issues/6164) [#6163](https://github.com/feast-dev/feast/issues/6163) +* Add optional 'org' in feature view ([#6288](https://github.com/feast-dev/feast/issues/6288)) ([#6301](https://github.com/feast-dev/feast/issues/6301)) ([608b105](https://github.com/feast-dev/feast/commit/608b1058b4885fa29dcf2a1e5979ac7f525d9c95)) +* Add RaySource, to_ray_dataset first-class method, docs, and tests ([1c98157](https://github.com/feast-dev/feast/commit/1c9815718670827a25f4ddf90337d115ff9b99d0)) +* Add TLS support for Go Feature Server ([#6229](https://github.com/feast-dev/feast/issues/6229)) ([28a58d0](https://github.com/feast-dev/feast/commit/28a58d0735ce4bf22554e1e562aef6b97e7bafe4)) +* Add Vector Search support to MongoDBOnlineStore ([#6344](https://github.com/feast-dev/feast/issues/6344)) ([c102738](https://github.com/feast-dev/feast/commit/c1027384f54518300acc68f68377f67433fba844)) +* Add versioning support to Milvus online store ([#6330](https://github.com/feast-dev/feast/issues/6330)) ([3268ced](https://github.com/feast-dev/feast/commit/3268ced977592609ea69316eb62e7b1040a03f58)) +* Addresses performance issues in the Redis online store ([2e50da0](https://github.com/feast-dev/feast/commit/2e50da040735960084f48af8de3ec2510d93f9bd)) +* Allow to set gpu for ray ([5580ab4](https://github.com/feast-dev/feast/commit/5580ab476470fa0f00a2c6788420d44829d81540)) +* Bump redis-py version cap from <5 to <8 ([#6339](https://github.com/feast-dev/feast/issues/6339)) ([9538180](https://github.com/feast-dev/feast/commit/95381805dc91789a264935ede6f4c385d8c8b4a8)) +* Expose feature_server, materialization, and openlineage configuration via FeatureStore CRD ([ec6ecfd](https://github.com/feast-dev/feast/commit/ec6ecfdf762dedff23cde813be5cc39a5ef296c1)) +* Make online_write_batch_size configurable in MaterializationConfig ([#6268](https://github.com/feast-dev/feast/issues/6268)) ([d41becf](https://github.com/feast-dev/feast/commit/d41becff2ecade63788903e44aeb3ec05878105b)) +* Make udf optional if agg defined ([#5689](https://github.com/feast-dev/feast/issues/5689)) ([#6328](https://github.com/feast-dev/feast/issues/6328)) ([f630056](https://github.com/feast-dev/feast/commit/f630056dfdf6676ae1033175dff5ea7226033c7a)) +* MongoDB offline store ([#6138](https://github.com/feast-dev/feast/issues/6138)) ([8eebad7](https://github.com/feast-dev/feast/commit/8eebad76e3cf0acc08e89260fc1fbf2edb294417)) +* Optional input_schema for ODFV ([#6308](https://github.com/feast-dev/feast/issues/6308)) ([#6312](https://github.com/feast-dev/feast/issues/6312)) ([f08b4e8](https://github.com/feast-dev/feast/commit/f08b4e823abe2b64de5f91cec205c8367d61a44a)) +* Provision minimal TokenReview RBAC for OIDC auth and add SSL error logging in token parser ([#6240](https://github.com/feast-dev/feast/issues/6240)) ([dca57e8](https://github.com/feast-dev/feast/commit/dca57e8336f657058bd0abeda898fcb833af03de)) +* **spark:** Add compute-on-read support for BatchFeatureView in get_… ([#6357](https://github.com/feast-dev/feast/issues/6357)) ([630d9f8](https://github.com/feast-dev/feast/commit/630d9f86e9e6a5ac466039091d95c031d4587ca3)) + # [0.62.0](https://github.com/feast-dev/feast/compare/v0.61.0...v0.62.0) (2026-04-08) diff --git a/Makefile b/Makefile index 58c99b8c984..799bc9c42fc 100644 --- a/Makefile +++ b/Makefile @@ -68,10 +68,12 @@ precommit-check: format-python lint-python ## Run all precommit checks @echo "✅ All precommit checks passed" # Install precommit hooks with correct stages -install-precommit: ## Install precommit hooks (runs on commit, not push) +install-precommit: ## Install precommit hooks (runs on commit + commit-msg + pre-push) uv pip install pre-commit pre-commit install --hook-type pre-commit - @echo "✅ Precommit hooks installed (will run on commit, not push)" + pre-commit install --hook-type commit-msg + pre-commit install --hook-type pre-push + @echo "✅ Precommit hooks installed (lint on commit, commitlint on commit-msg, lint on push)" # Manual full type check mypy-full: ## Full MyPy type checking with all files @@ -91,6 +93,7 @@ setup-scripts: ## Make helper scripts executable install-python-dependencies-dev: ## Install Python dev dependencies using uv (editable install) uv pip sync --require-hashes sdk/python/requirements/py$(PYTHON_VERSION)-ci-requirements.txt uv pip install --no-deps -e . + $(MAKE) install-precommit install-python-dependencies-minimal: ## Install minimal Python dependencies using uv (editable install) uv pip sync --require-hashes sdk/python/requirements/py$(PYTHON_VERSION)-minimal-requirements.txt @@ -186,7 +189,7 @@ test-python-smoke: ## Quick smoke test for development test-python-integration: ## Run Python integration tests (CI) uv run python -m pytest --tb=short -v -n 8 --integration --color=yes --durations=10 --timeout=1200 --timeout_method=thread --dist loadgroup \ - -k "(not snowflake or not test_historical_features_main)" \ + -k "not snowflake" \ -m "not rbac_remote_integration_test and not ray_offline_stores_only" \ --ignore=sdk/python/tests/integration/registration \ --ignore=sdk/python/tests/component/ray \ @@ -279,6 +282,7 @@ test-python-universal-spark: ## Run Python Spark integration tests not test_push_features_to_offline_store.py and \ not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_universal_types and \ not test_snowflake" \ sdk/python/tests @@ -313,6 +317,7 @@ test-python-universal-trino: ## Run Python Trino integration tests not test_push_features_to_offline_store.py and \ not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_universal_types and \ not test_snowflake" \ sdk/python/tests @@ -328,6 +333,7 @@ test-python-universal-mssql: ## Run Python MSSQL integration tests python -m pytest -n 8 --integration \ -k "not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_lambda_materialization and \ not test_snowflake and \ not test_historical_features_persisting and \ @@ -361,6 +367,7 @@ test-python-universal-athena: ## Run Python Athena integration tests not test_historical_retrieval_fails_on_validation and \ not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_snowflake" \ sdk/python/tests @@ -381,6 +388,7 @@ test-python-universal-postgres-offline: ## Run Python Postgres integration tests not test_push_features_to_offline_store and \ not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_snowflake and \ not test_spark" \ sdk/python/tests @@ -402,6 +410,7 @@ test-python-universal-postgres-offline: ## Run Python Postgres integration tests not test_push_features_to_offline_store and \ not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_snowflake and \ not test_spark" \ sdk/python/tests @@ -424,6 +433,7 @@ test-python-universal-postgres-online: ## Run Python Postgres integration tests not test_push_features_to_offline_store and \ not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_universal_types and \ not test_snowflake" \ sdk/python/tests @@ -443,6 +453,7 @@ test-python-universal-postgres-online: ## Run Python Postgres integration tests not test_push_features_to_offline_store and \ not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_universal_types and \ not test_validation and \ not test_spark_materialization_consistency and \ @@ -465,6 +476,7 @@ test-python-universal-mysql-online: ## Run Python MySQL integration tests not test_push_features_to_offline_store and \ not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_universal_types and \ not test_snowflake" \ sdk/python/tests @@ -495,6 +507,7 @@ test-python-universal-hazelcast: ## Run Python Hazelcast integration tests not test_push_features_to_offline_store and \ not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_universal_types and \ not test_snowflake" \ sdk/python/tests @@ -513,6 +526,7 @@ test-python-universal-cassandra-no-cloud-providers: ## Run Python Cassandra inte not test_nullable_online_store and \ not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_snowflake" \ sdk/python/tests @@ -531,6 +545,7 @@ test-python-universal-elasticsearch-online: ## Run Python Elasticsearch online s not test_push_features_to_offline_store and \ not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_universal_types and \ not test_snowflake" \ sdk/python/tests @@ -550,6 +565,7 @@ test-python-universal-mongodb-online: ## Run Python MongoDB online store integra not test_push_features_to_offline_store and \ not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_universal_types and \ not test_snowflake" \ sdk/python/tests @@ -570,6 +586,7 @@ test-python-universal-singlestore-online: ## Run Python Singlestore online store -k "not test_universal_cli and \ not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_snowflake" \ sdk/python/tests @@ -604,6 +621,7 @@ test-python-universal-couchbase-offline: ## Run Python Couchbase offline store i not test_push_features_to_offline_store and \ not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_snowflake and \ not test_universal_types" \ sdk/python/tests @@ -623,6 +641,7 @@ test-python-universal-couchbase-online: ## Run Python Couchbase online store int not test_push_features_to_offline_store and \ not gcs_registry and \ not s3_registry and \ + not snowflake_registry and \ not test_universal_types and \ not test_snowflake" \ sdk/python/tests diff --git a/OWNERS b/OWNERS index f1700bfcc65..9bbefc01d3f 100644 --- a/OWNERS +++ b/OWNERS @@ -1,7 +1,6 @@ # This file is being used by RedHat for running e2e CI approvers: -- redhathameed - tmihalac - accorvin - amsharma3 @@ -10,10 +9,9 @@ approvers: - jyejare options: {} reviewers: -- redhathameed - tmihalac - accorvin - amsharma3 - franciscojavierarceo - ntkathole -- jyejare \ No newline at end of file +- jyejare diff --git a/README.md b/README.md index 1190fa20fac..115bd37903f 100644 --- a/README.md +++ b/README.md @@ -185,6 +185,8 @@ The list below contains the functionality that contributors are planning to deve * [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) @@ -203,6 +205,7 @@ The list below contains the functionality that contributors are planning to deve * [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** diff --git a/community/governance.md b/community/governance.md index 087b3599dbf..b13c07fbeba 100644 --- a/community/governance.md +++ b/community/governance.md @@ -217,8 +217,9 @@ The "RFC" (request for comments) process is intended to provide a consistent and 2. Users, Contributors, and Maintainers discuss and upvote the draft 3. If confident on its success, contributor completes the RFC with more in-detail technical specifications 4. Maintainers approve RFC when it is ready -5. Maintainers meet every quarter and choose three or five items based on popularity and alignment with project vision and goals -6. Those selected items become part of the Mid-term goals +5. Once finalized, the RFC should be added as an [Architecture Decision Record (ADR)](../docs/adr/README.md) in the repository +6. Maintainers meet every quarter and choose three or five items based on popularity and alignment with project vision and goals +7. Those selected items become part of the Mid-term goals ### When to Use RFCs diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 95379b39a15..44c1cc09477 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -55,6 +55,7 @@ * [Retrieval Augmented Generation (RAG) with Feast](tutorials/rag-with-docling.md) * [RAG Fine Tuning with Feast and Milvus](../examples/rag-retriever/README.md) * [MCP - AI Agent Example](../examples/mcp_feature_store/README.md) +* [Feast-Powered AI Agent](../examples/agent_feature_store/README.md) ## How-to Guides @@ -70,6 +71,15 @@ * [Multi-Team Feature Store Setup](how-to-guides/federated-feature-store.md) * [Running Feast in production (e.g. on Kubernetes)](how-to-guides/running-feast-in-production.md) * [Feast on Kubernetes](how-to-guides/feast-on-kubernetes.md) + * [Operator Configuration Guides](how-to-guides/feast-operator/README.md) + * [1 — Project Provisioning](how-to-guides/feast-operator/01-project-provisioning.md) + * [2 — Persistence](how-to-guides/feast-operator/02-persistence.md) + * [3 — Serving & Observability](how-to-guides/feast-operator/03-serving-and-observability.md) + * [4 — Registry Topology](how-to-guides/feast-operator/04-registry-topology.md) + * [5 — Security](how-to-guides/feast-operator/05-security.md) + * [6 — Batch & Jobs](how-to-guides/feast-operator/06-batch-and-jobs.md) + * [7 — OpenLineage & Materialization](how-to-guides/feast-operator/07-openlineage-and-materialization.md) +* [Feast Production Deployment Topologies](how-to-guides/production-deployment-topologies.md) * [Online Server Performance Tuning](how-to-guides/online-server-performance-tuning.md) * [Customizing Feast](how-to-guides/customizing-feast/README.md) * [Adding a custom batch materialization engine](how-to-guides/customizing-feast/creating-a-custom-materialization-engine.md) @@ -102,6 +112,8 @@ * [Oracle (contrib)](reference/data-sources/oracle.md) * [Athena (contrib)](reference/data-sources/athena.md) * [Clickhouse (contrib)](reference/data-sources/clickhouse.md) + * [Ray (contrib)](reference/data-sources/ray.md) + * [MongoDB (contrib)](reference/data-sources/mongodb.md) * [Offline stores](reference/offline-stores/README.md) * [Overview](reference/offline-stores/overview.md) * [Dask](reference/offline-stores/dask.md) @@ -118,6 +130,7 @@ * [Ray (contrib)](reference/offline-stores/ray.md) * [Oracle (contrib)](reference/offline-stores/oracle.md) * [Athena (contrib)](reference/offline-stores/athena.md) + * [MongoDB (contrib)](reference/offline-stores/mongodb.md) * [Remote Offline](reference/offline-stores/remote-offline-store.md) * [Hybrid](reference/offline-stores/hybrid.md) * [Online stores](reference/online-stores/README.md) @@ -191,3 +204,15 @@ * [Versioning policy](project/versioning-policy.md) * [Release process](project/release-process.md) * [Feast 0.9 vs Feast 0.10+](project/feast-0.9-vs-feast-0.10+.md) +* [Architecture Decision Records](adr/README.md) + * [ADR-0001: Feature Services](adr/ADR-0001-feature-services.md) + * [ADR-0002: Component Refactor](adr/ADR-0002-component-refactor.md) + * [ADR-0003: On-Demand Transformations](adr/ADR-0003-on-demand-transformations.md) + * [ADR-0004: Entity Join Key Mapping](adr/ADR-0004-entity-join-key-mapping.md) + * [ADR-0005: Stream Transformations](adr/ADR-0005-stream-transformations.md) + * [ADR-0006: Kubernetes Operator](adr/ADR-0006-kubernetes-operator.md) + * [ADR-0007: Unified Feature Transformations](adr/ADR-0007-unified-feature-transformations.md) + * [ADR-0008: Feature View Versioning](adr/ADR-0008-feature-view-versioning.md) + * [ADR-0009: Contribution and Extensibility](adr/ADR-0009-contribution-extensibility.md) + * [ADR-0010: Vector Database Integration](adr/ADR-0010-vector-database-integration.md) + * [ADR-0011: Data Quality Monitoring](adr/ADR-0011-data-quality-monitoring.md) diff --git a/docs/adr/ADR-0001-feature-services.md b/docs/adr/ADR-0001-feature-services.md new file mode 100644 index 00000000000..c234e67198f --- /dev/null +++ b/docs/adr/ADR-0001-feature-services.md @@ -0,0 +1,87 @@ +# ADR-0001: Feature Services + +## Status + +Accepted + +## Context + +Feast's Feature Views allowed for storage-level grouping of features based on how they are produced. However, there was no concept of a retrieval-level grouping of features that maps to models. Without this: + +- There was no way to track which features were used to train a model or serve a specific model. +- Retrieving features during training required a complete list of features to be provided and persisted manually, which was error-prone. +- There was no way to ensure consumers wouldn't face breaking changes when feature views changed. + +## Decision + +Introduce a `FeatureService` object that allows users to define which features to use for a specific ML use case. A feature service groups features from one or more feature views for model training and online serving. + +### API Design + +Feature services use a Pandas-like API where feature views can be referenced directly: + +```python +from feast import FeatureService + +feature_service = FeatureService( + name="my_model_v1", + features=[ + shop_raw, # select all features + customer_sales[["average_order_value", "max_order_value"]], # select specific features + ], +) +``` + +Feature selection with aliasing: + +```python +feature_service = FeatureService( + name="my_model_v1", + features=[ + shop_raw, + customer_sales[["average_order_value", "max_order_value"]] + .alias({"average_order_value": "avg_o_val"}), + ], +) +``` + +### Retrieval + +```python +# Online inference +row = store.get_online_features( + feature_service="my_model_v1", + entity_rows=[{"customer_id": 123, "shop_id": 456}], +).to_dict() + +# Training +historical_df = store.get_historical_features( + feature_service="my_model_v1", + entity_df=entity_df, +) +``` + +### Key Decisions + +- **Name**: `FeatureService` was chosen over `FeatureSet` because it conveys the concept of a serving layer bridging models and data. `FeatureService` is analogous to model services in model serving systems. +- **Mutability**: Feature services are mutable. Immutability may be considered in the future. +- **Versioning**: Not included in the first version; users manage versions through naming conventions. + +## Consequences + +### Positive + +- Users can track which features are used for training and serving specific models. +- Provides a consistent interface for both online and offline feature retrieval. +- Reduces error-prone manual feature list management. +- Enables future functionality like logging, monitoring, and endpoint provisioning. + +### Negative + +- Adds another abstraction layer to the Feast data model. +- Feature services are mutable, which may lead to inconsistencies if not carefully managed. + +## References + +- Original RFC: [Feast RFC-015: Feature Services](https://docs.google.com/document/d/1jC0RJbyYLilXTOrLVBeR22PYLK5fe2JmQK1mKdZ-eno/edit) +- Implementation: `sdk/python/feast/feature_service.py` diff --git a/docs/adr/ADR-0002-component-refactor.md b/docs/adr/ADR-0002-component-refactor.md new file mode 100644 index 00000000000..854a1c3765b --- /dev/null +++ b/docs/adr/ADR-0002-component-refactor.md @@ -0,0 +1,71 @@ +# ADR-0002: Component Refactor + +## Status + +Accepted + +## Context + +The Feast project originally existed as a single monolithic repository containing many tightly coupled components: Core Registry, Serving Service, Job Service, Client Libraries, Spark ingestion code, Helm charts, and Terraform configurations. + +Two distinct user groups were identified: + +- **Platform teams**: Capable of running a complete feature store on Kubernetes with Spark, managing large-scale infrastructure. +- **Solution teams**: Small data science or data engineering teams wanting to solve ML business problems without deploying and managing Kubernetes or Spark clusters. + +Delivering a viable minimal product to solution teams required a lighter-weight approach. However, the monolithic codebase made this difficult due to tight coupling between components. + +## Decision + +Adopt a staged approach to decouple the Feast codebase into modular, composable components: + +### Stage 1: Move Out Non-Core Components + +Split the monorepo into focused repositories: + +- **feast** (main repo): Feast Python SDK, Documentation, and Protos (starting at v0.10.0). +- **feast-java**: Core Registry, Serving, and Java Client. +- **feast-spark**: Spark Ingestion, Spark Python SDK, and Job Service. +- **feast-helm-charts**: Helm charts for Kubernetes deployments. + +### Stage 2: Document Contracts + +Document all component-level contracts (I/O), API specifications (Protobuf), data contracts, and architecture diagrams. + +### Stage 3: Remove Coupling + +Remove unnecessary coupling between components, keeping only service contracts (Protobuf), data contracts, and integration tests as shared dependencies. + +### Stage 4: Converge + +Reverse the relationship so the main Feast SDK can use Spark-related code as a specific compute provider, rather than requiring it. + +### Key Principles + +- The main Feast repository provides a fully functional Python-based feature store that works without infrastructure dependencies. +- Spark and Kubernetes-based components remain available for platform teams. +- All existing functionality is maintained with no breaking changes during the transition. + +## Consequences + +### Positive + +- Enabled a super lightweight core framework for Feast that teams can start with in seconds. +- Made it possible for teams to pick and choose components they want to adopt. +- Teams with existing internal implementations (ingestion, registry, serving) can integrate more easily. +- The Python SDK became the primary entry point, significantly lowering the barrier to getting started. + +### Negative + +- Temporary divergence between Feast and Feast-Spark codebases during the transition. +- Multiple repositories added coordination overhead during the migration period. + +### Neutral + +- Components have since been reconverged into the main repository with a cleaner separation of concerns. +- The Go, Java, and Python SDKs coexist in the main repository under separate directories. + +## References + +- Original RFC: [Feast RFC-020: Component Refactor](https://docs.google.com/document/d/1CjR3Ph3l65hF5bRuchR9u9WSoirnIuEb7ILY9Ioh1Sk/edit) +- GitHub Discussion: [#1353](https://github.com/feast-dev/feast/discussions/1353) diff --git a/docs/adr/ADR-0003-on-demand-transformations.md b/docs/adr/ADR-0003-on-demand-transformations.md new file mode 100644 index 00000000000..66365d0358c --- /dev/null +++ b/docs/adr/ADR-0003-on-demand-transformations.md @@ -0,0 +1,97 @@ +# ADR-0003: On-Demand Transformations + +## Status + +Accepted + +## Context + +For many ML use cases, it is not possible or feasible to precompute and persist feature values for serving: + +- **Transactional use cases**: Inputs are part of the transaction/booking/order event. +- **Clickstream use cases**: User event data contains raw data used for feature engineering. +- **Location-based use cases**: Distance calculations between feature views (e.g., customer and driver locations). +- **Time-dependent features**: e.g., `user_account_age = current_time - account_creation_time`. +- **Crossed features**: e.g., user-user, user-tweet based features where the keyspace is too large to precompute. + +Additionally, Feast did not provide a means for post-processing features, forcing all feature development to upstream systems. + +## Decision + +Introduce **On-Demand Feature Views** as a feature transformation layer with the following properties: + +- Transformations execute at retrieval time (post-processing step after reading from the store). +- The calling client can input data as part of the retrieval request via a `RequestSource`. +- Users define arbitrary transformations on both stored features and request-time input data. +- Transformations are row-level operations only (no aggregations). + +### Definition API + +Uses the `@on_demand_feature_view` decorator (Option 3 from the RFC was chosen): + +```python +from feast import on_demand_feature_view, Field, RequestSource +from feast.types import Float64, String + +input_request = RequestSource( + name="transaction", + schema=[Field(name="input_lat", dtype=Float64), Field(name="input_lon", dtype=Float64)], +) + +@on_demand_feature_view( + sources=[driver_fv, input_request], + schema=[Field(name="distance", dtype=Float64)], +) +def driver_distance(inputs: pd.DataFrame) -> pd.DataFrame: + from haversine import haversine + df = pd.DataFrame() + df["distance"] = inputs.apply( + lambda r: haversine((r["lat"], r["lon"]), (r["input_lat"], r["input_lon"])), + axis=1, + ) + return df +``` + +### Retrieval + +```python +# Online - request data passed as entity rows +features = store.get_online_features( + features=["driver_distance:distance"], + entity_rows=[{"driver_id": 1001, "input_lat": 1.234, "input_lon": 5.678}], +).to_dict() + +# Offline - request data columns included in entity_df +df = store.get_historical_features( + entity_df=entity_df_with_request_columns, + features=["driver_distance:distance"], +).to_df() +``` + +### Key Decisions + +- **Decorator approach** chosen over adding transforms to FeatureService or FeatureView directly. This avoids changing existing APIs and keeps transformations self-contained. +- **Pandas DataFrames** as the input/output type to support vectorized operations. +- **All imports must be self-contained** within the function block for serialization. +- **Offline transformations** initially execute client-side using Dask for scalability. +- **Feature Transformation Server (FTS)** handles online transformations via HTTP/REST, deployed at `apply` time. + +## Consequences + +### Positive + +- Enables real-time feature engineering that depends on request-time data. +- Keeps feature logic co-located with feature definitions in the repository. +- Provides a consistent interface for both online and offline feature retrieval. +- The FTS allows horizontal scaling independent of feature serving. + +### Negative + +- Adds computational overhead to the serving path since transformations run at read time. +- On-demand feature views are limited to row-level transformations (no aggregations). +- Python function serialization requires self-contained imports within function blocks. + +## References + +- Original RFC: [Feast RFC-021: On-Demand Transformations](https://docs.google.com/document/d/1lgfIw0Drc65LpaxbUu49RCeJgMew547meSJttnUqz7c/edit) +- Implementation: `sdk/python/feast/on_demand_feature_view.py` diff --git a/docs/adr/ADR-0004-entity-join-key-mapping.md b/docs/adr/ADR-0004-entity-join-key-mapping.md new file mode 100644 index 00000000000..e6d09df4f34 --- /dev/null +++ b/docs/adr/ADR-0004-entity-join-key-mapping.md @@ -0,0 +1,78 @@ +# ADR-0004: Entity Join Key Mapping + +## Status + +Accepted + +## Context + +Multiple different entity keys in the source data may need to map onto the same entity from the feature data table during a join. For example, `spammer_id` and `reporter_id` may both need the `years_on_platform` feature from a table keyed by `user_id`. + +Without entity join key mapping: + +- Users had to rename columns in their entity dataframe to match the feature view's join key before retrieval. +- It was impossible to join a feature view twice on two different columns in the entity data (e.g., getting user features for both `spammer_id` and `reporter_id` in the same query). + +### Example + +Entity source data: + +| spammer_id | reporter_id | timestamp | +|------------|-------------|------------| +| 2 | 8 | 1629909366 | +| 1 | 2 | 1629909323 | + +Desired joined data should include `spammer_feature_a` and `reporter_feature_a`, both sourced from the same `user` feature view but joined on different keys. + +## Decision + +Implement join key overrides using a `with_join_key_map()` method on feature views, combined with `with_name()` for disambiguation. This was **Option 8b** from the RFC. + +### API + +```python +abuse_feature_service = FeatureService( + name="my_abuse_model_v1", + features=[ + user_features + .with_name("reporter_features") + .with_join_key_map({"user_id": "reporter_id"}), + user_features + .with_name("spammer_features") + .with_join_key_map({"user_id": "spammer_id"}), + ], +) +``` + +### Key Decisions + +- **Query-time mapping** rather than registration-time. This provides flexibility since the same feature view can be used with different mappings in different contexts. +- **Join key level mapping** rather than entity-level mapping. While entity-level mapping (Option 10) better preserves abstraction boundaries, join key mapping is more flexible and doesn't require registering additional entities. +- **`with_name()` required** when using the same feature view multiple times to avoid output column name collisions. If omitted, a name collision error is raised. +- **Mapping overwrites wholly**: specifying a mapping replaces the default join behavior entirely. If you want the original join key included, it must be explicitly listed. + +### Implementation + +- **Offline (historical) retrieval**: After feature subtable cleaning and dedup, entity columns are renamed based on the mapping before the join. +- **Online retrieval**: Shadow entity keys are translated to the original join key for the online store lookup, then results are remapped to the shadow entity names. +- The `join_key_map` is stored on `FeatureViewProjection` and flows through both online and offline retrieval paths. + +## Consequences + +### Positive + +- Users can join the same feature view on different entity columns in a single query. +- No need to register additional entities or manually rename columns before retrieval. +- Works consistently across both online and offline retrieval. +- Feature view definitions remain clean and reusable. + +### Negative + +- Adds complexity to the retrieval path with column renaming logic. +- Users must remember to use `with_name()` to avoid collisions when joining the same feature view multiple times. + +## References + +- Original RFC: [Feast RFC-023: Shadow Entities Mapping](https://docs.google.com/document/d/1TsCwKf3nVXTAfL0f8i26jnCgHA3bRd4dKQ8QdM87vIA/edit) +- GitHub Issue: [#1762](https://github.com/feast-dev/feast/issues/1762) +- Implementation: `sdk/python/feast/feature_view.py` (`with_join_key_map` method), `sdk/python/feast/feature_view_projection.py` (`join_key_map` field) diff --git a/docs/adr/ADR-0005-stream-transformations.md b/docs/adr/ADR-0005-stream-transformations.md new file mode 100644 index 00000000000..8d2e97f61c4 --- /dev/null +++ b/docs/adr/ADR-0005-stream-transformations.md @@ -0,0 +1,93 @@ +# ADR-0005: Stream Transformations + +## Status + +Accepted + +## Context + +Feast supported batch features well but lacked in-house support for pull-based stream ingestion or registered stream transformations. While Kafka and Kinesis data sources could be registered, users had to either: + +- Write a custom Provider to launch ingestion jobs outside the Feast environment. +- Manually push stream data into the online store via the Push API. + +The stream transformation pipeline existed entirely outside of Feast, making it harder to track, version, and manage streaming features. + +## Decision + +Introduce a `StreamFeatureView` and a `StreamProcessor` interface to provide a standardized pipeline for ingesting and transforming stream data. + +### Stream Feature View + +```python +from feast import StreamFeatureView, Entity, Field, Aggregation +from feast.types import Float32 + +@stream_feature_view( + entities=[entity], + ttl=timedelta(days=30), + owner="test@example.com", + online=True, + schema=[Field(name="dummy_field", dtype=Float32)], + description="Stream feature view with aggregations", + aggregations=[ + Aggregation(column="dummy_field", function="max", time_window=timedelta(days=1)), + Aggregation(column="dummy_field2", function="count", time_window=timedelta(days=24)), + ], + timestamp_field="event_timestamp", + mode="spark", + source=stream_source, +) +def pandas_view(pandas_df): + df = pandas_df.transform(lambda x: x + 10, axis=1) + return df +``` + +### Stream Processor + +The `StreamProcessor` is a pluggable interface for stream engines (Spark, Flink, etc.): + +```python +class StreamProcessor(ABC): + sfv: StreamFeatureView + data_source: DataSource + + def ingest_stream_feature_view(self) -> None: ... + def _ingest_stream_data(self) -> StreamTable: ... + def _construct_transformation_plan(self, table: StreamTable) -> StreamTable: ... + def _write_to_online_store(self, table: StreamTable) -> None: ... +``` + +### Unified Push API + +A unified push API was introduced to allow pushing features to both online and offline stores, supporting the Kappa architectural approach to streaming. + +### Aggregations + +Built-in aggregation functions: `sum`, `count`, `mean`, `max`, `min`. Aggregations use full aggregation with RocksDB for the initial implementation, keeping it simple while reducing request-time latency. + +### Key Decisions + +- **Full aggregations** chosen over partial aggregations for simplicity and lower request-time latency, using RocksDB to handle memory pressure. +- **Single time window restriction** for initial release; aggregations across different time windows (stream joins) add significant complexity. +- **User-managed ingestion**: Users handle their own ingestion jobs using the StreamProcessor interface with their preferred streaming engine. + +## Consequences + +### Positive + +- Streaming features can be registered and tracked in the Feast registry alongside batch features. +- UDFs for stream transformations are versioned with the feature view definition. +- The pluggable StreamProcessor interface supports multiple streaming engines. +- Unified Push API enables backfilling streaming features to the offline store. + +### Negative + +- Users must implement their own StreamProcessor for their streaming engine. +- Aggregation support is limited to basic functions in the initial release. +- Stream joins across different time windows are not supported. + +## References + +- Original RFC: [Feast RFC-036: Stream Transformations](https://docs.google.com/document/d/1Onjy-kiRlHt0USw5ggHu40hpezw1AV8KsgJAh46LoNY/edit) +- Implementation: `sdk/python/feast/stream_feature_view.py` diff --git a/docs/adr/ADR-0006-kubernetes-operator.md b/docs/adr/ADR-0006-kubernetes-operator.md new file mode 100644 index 00000000000..6969673d98d --- /dev/null +++ b/docs/adr/ADR-0006-kubernetes-operator.md @@ -0,0 +1,92 @@ +# ADR-0006: Kubernetes Operator + +## Status + +Accepted + +## Context + +As the Feast project grew, deploying a fully functional Feature Store in a production-like manner became increasingly difficult. Existing installers required many manual operations that led to configuration errors. Users needed a simpler way to install and maintain Feature Store environments, especially with features like RBAC. + +The existing Helm-based operator had limitations in handling complex installation requirements. A more capable operator was needed to manage the full lifecycle of Feast deployments on Kubernetes. + +## Decision + +Build a **Go Operator** using the `operator-sdk` framework with a cluster-scoped controller and a namespaced `FeatureStore` Custom Resource Definition (CRD). + +### FeatureStore CRD + +The operator manages Feast through a single CRD that defines the entire feature store deployment: + +```yaml +apiVersion: feast.dev/v1alpha1 +kind: FeatureStore +metadata: + name: example + namespace: feast +spec: + feastProject: my-project + auth: + kubernetes: + roles: [reader, writer] + services: + registry: + replicas: 1 + persistence: + file: + pvc: + capacity: 5Gi + onlineStore: + replicas: 2 + persistence: + postgresql: + secretRef: online-store-creds + offlineStore: + replicas: 3 + feastApplyJob: + configMapRef: feast-definitions +``` + +### Architecture + +- **Operator deploys Feast services** (Registry, Online Store, Offline Store) as defined in the CR. +- **Operator generates `feature_store.yaml`** from the CR spec, including only relevant sections for each server type. +- **Client ConfigMap** is created automatically for remote connectivity. +- **`feast apply` Job** can be triggered from a ConfigMap or Git repo to initialize the registry. +- **CR status.applied** is the single source of truth for the deployed state. + +### Key Decisions + +- **Go over Python**: Go is better suited for Kubernetes operators. Python is great for ML work but not for cloud-native infrastructure management. +- **Single CRD** (`FeatureStore`) instead of separate CRDs per service type. All services are part of a functioning Feature Store and should be managed together. +- **Operator manages `feature_store.yaml`** entirely to ensure consistency and validation (e.g., `remote` types are only used where appropriate). +- **Data store deployments are out of scope**: The operator assumes data stores are pre-provisioned and accessible. +- **Deprecation of Helm-based operator**: The existing Helm-based operator is deprecated in favor of the Go operator. + +### Persistence Options + +- **Default**: Ephemeral file-based stores. +- **File with PVC**: For clusters supporting persistent volumes. +- **PostgreSQL**: Via referenced Kubernetes secrets for credentials. + +## Consequences + +### Positive + +- Simplified, standardized deployment of Feast on Kubernetes. +- Full lifecycle management including RBAC, metrics, and feature store initialization. +- Supports multiple Feature Store deployments in a single cluster without conflict. +- Proper validation and consistency enforcement through the operator reconciliation loop. +- Deployable with kustomize; compatible with OLM and OperatorHub. + +### Negative + +- Requires Kubernetes as the deployment platform. +- Data store management is left to users (intentionally out of scope). +- Initial release supports limited persistence backends; additional stores added incrementally. + +## References + +- Original RFC: [Feast RFC-042: Operator](https://docs.google.com/document/d/1vGKMizf3_14IyiF_W_Ik7CR03joFkQfzbKT0jH4PZJM/edit) +- GitHub Issue: [#4561](https://github.com/feast-dev/feast/issues/4561) +- Implementation: `infra/feast-operator/` diff --git a/docs/adr/ADR-0007-unified-feature-transformations.md b/docs/adr/ADR-0007-unified-feature-transformations.md new file mode 100644 index 00000000000..86e77c0a73c --- /dev/null +++ b/docs/adr/ADR-0007-unified-feature-transformations.md @@ -0,0 +1,91 @@ +# ADR-0007: Unified Feature Transformations and Feature Views + +## Status + +Accepted + +## Context + +In Feast, the `OnDemandFeatureView` name did not clearly convey that transformations execute at read time. The term "On Demand" was ambiguous about when the transformation occurs. Additionally, there were multiple feature view types (`FeatureView`, `BatchFeatureView`, `StreamFeatureView`, `OnDemandFeatureView`) with: + +- **Excessive logic** handling each type throughout the codebase (e.g., `FeatureStore.apply()`, `get_online_features`, `get_historical_features`). +- **Redundant fields** across the different feature view classes. +- **Unclear transformation timing**: when transformations occur, where they execute, and how materialization works varied by type. + +| Type | When Transformation Occurs | Where | Materialization | +|------|---------------------------|-------|-----------------| +| FeatureView | Undefined | Outside Feast | Feature Server or Batch | +| BatchFeatureView | Batch process | Offline Store (external) | Feature Server or Batch | +| StreamFeatureView | Streaming process | Stream Processor (external) | Stream Processor | +| OnDemandFeatureView | On Read | Feature Server | Feature Server | +| OnDemandFeatureView (writes) | On Write | Feature Server | Feature Server | + +## Decision + +Unify Batch, Streaming, and On-Demand feature views into a single `FeatureView` class with a `@transform` decorator that makes execution timing explicit. + +### Transformation Types + +```python +from enum import Enum + +class FeastTransformation(Enum): + NONE = 0 # No transformations (default) + ON_READ = 1 # Current On Demand Feature View behavior + ON_WRITE = 2 # Transformations at write time + BATCH = 3 # Batch processing transformations + STREAMING = 4 # Stream transformations +``` + +### Proposed API + +```python +@transform( + type=FeastTransformation.ON_WRITE, + schema=[...], + entity=[...], + sources=[...], + mode="python", # pandas, substrate, etc. + engine="feature_server", # Spark, Snowflake, etc. + orchestrator=None, # Airflow, KFP, etc. +) +def my_feature_view(inputs): + outputs = { + "my_feature": [v * 1.0 for v in inputs["input_feature_1"]], + } + return outputs +``` + +### Key Decisions + +- **Single class** rather than defining a V2 class. A breaking change in stages is preferred to avoid rework for Java and Go servers. +- **Explicit transformation timing** via enum rather than implicit behavior based on class type. +- **Staggered release**: Ship a version supporting both old and new APIs with deprecation logging, then ship a breaking version. +- **Five clear primitives**: Entities, DataSources, Fields, FeatureViews, and FeatureServices. + +### Current Implementation Status + +The codebase currently uses a `transformation()` decorator and `TransformationMode` enum (with modes like PANDAS, PYTHON, SPARK, RAY, SQL, SUBSTRAIT) in `sdk/python/feast/transformation/base.py`. The legacy `OnDemandFeatureView`, `StreamFeatureView`, and `BatchFeatureView` classes still exist during the migration period. + +## Consequences + +### Positive + +- Clearer, more explicit API that makes transformation timing obvious. +- Removes excessive handling of each feature view type throughout the codebase. +- Eliminates redundant field definitions across multiple classes. +- Establishes five clear primitives for the Feast data model. +- FeatureViews can declare other FeatureViews as data sources, enabling computational graphs. + +### Negative + +- Requires a migration period with both old and new APIs supported. +- Breaking change that needs careful coordination across Python, Java, and Go components. +- Users must update existing feature view definitions during migration. + +## References + +- Original RFC: [Feast RFC-043: Unify Feature Transformations and Feature Views](https://docs.google.com/document/d/1KXCXcsXq1bUvbSpfhnUjDSsu4HpuUZ5XiZoQyltCkvo/edit) +- GitHub Issue: [#4584](https://github.com/feast-dev/feast/issues/4584) +- Related RFCs: RFC-021 (On-Demand Transformations), RFC-036 (Stream Transformations) +- Implementation: `sdk/python/feast/transformation/base.py` diff --git a/docs/adr/ADR-0008-feature-view-versioning.md b/docs/adr/ADR-0008-feature-view-versioning.md new file mode 100644 index 00000000000..f6f63922077 --- /dev/null +++ b/docs/adr/ADR-0008-feature-view-versioning.md @@ -0,0 +1,129 @@ +# ADR-0008: Feature View Versioning + +## Status + +Accepted + +## Context + +When a feature view's schema changed in Feast, the old definition was silently overwritten. This created several problems: + +1. **No audit trail**: Teams couldn't answer "what did this feature view look like last week?" or "who changed the schema and when?" +2. **No safe rollback**: If a schema change broke a downstream model, there was no way to revert without manually reconstructing the previous definition. +3. **No multi-version serving**: During migrations, teams often need to serve both old and new schemas simultaneously (e.g., model A uses v1 features, model B uses v2 features). This required creating entirely separate feature views. + +## Decision + +Add automatic version tracking to Feast feature views. Every time `feast apply` detects a schema or UDF change, a versioned snapshot is saved to the registry. + +### Core Concepts + +- **Version number**: Auto-incrementing integer (v0, v1, v2, ...) for each schema-significant change. +- **Version snapshot**: Serialized copy of the full feature view proto stored in the registry. +- **Version pin**: Setting `version="v2"` on a feature view replaces the active definition with the v2 snapshot. +- **Version-qualified ref**: The `@v` syntax (e.g., `driver_stats@v2:trips_today`) for reading from a specific version. + +### What Triggers a New Version + +Only schema and UDF changes create new versions: + +- Adding, removing, or retyping feature columns. +- Changing entities or entity columns. +- Changing UDF code (StreamFeatureView, OnDemandFeatureView). + +Metadata-only changes (description, tags, owner, TTL) update the active definition in place without creating a version. + +### Version History Is Always-On + +Version history tracking is lightweight registry metadata (serialized proto snapshots). There is no performance cost to the online path. Every `feast apply` that changes a feature view will: + +- Record a version snapshot. +- Support `feast feature-views list-versions ` to list history. +- Support `registry.list_feature_view_versions(name, project)` programmatically. +- Support `registry.get_feature_view_by_version(name, project, version_number)`. + +### Online Versioning Is Opt-In + +Version-qualified reads from separate online store tables are gated behind a config flag: + +```yaml +registry: + path: data/registry.db + enable_online_feature_view_versioning: true +``` + +When enabled, `driver_stats@v2:trips_today` reads from a version-specific table (`project_driver_stats_v2`). When disabled (default), using `@v` refs raises a clear error. + +### Version Pinning + +```python +driver_stats = FeatureView( + name="driver_stats", + entities=[driver], + schema=[...], + source=my_source, + version="v2", # revert to v2's definition +) +``` + +Safety: The user's definition (minus the version field) must match the currently active definition. If both schema and version pin are changed, `feast apply` raises `FeatureViewPinConflict`. + +### Staged Publishing (`--no-promote`) + +The `--no-promote` flag saves a version snapshot without updating the active definition, enabling phased rollouts: + +```bash +# Stage the new version +feast apply --no-promote + +# Populate the v2 online table +feast materialize --views driver_stats --version v2 ... + +# Migrate consumers one at a time (using @v2 refs) + +# Promote v2 as the default +feast apply +``` + +### Materialization + +Each version's data lives in its own online store table. By default, `feast materialize` targets the active version. A `--version` flag targets specific versions: + +```bash +feast materialize --views driver_stats --version v1 2024-01-01T00:00:00 2024-01-15T00:00:00 +``` + +### Concurrency + +- **SQL registry**: Unique constraint on `(feature_view_name, project_id, version_number)` with retry logic for auto-increment races. +- **File registry**: Last-write-wins (pre-existing limitation). + +### Limitations + +- Online store coverage: Version-qualified reads are only on SQLite initially. +- Offline store versioning is out of scope. +- No mechanism to prune old versions. +- Cross-version joins in `get_historical_features` are not supported. + +## Consequences + +### Positive + +- Full audit trail of schema changes for every feature view. +- Safe rollback capability through version pinning. +- Multi-version serving enables gradual migrations without creating duplicate feature views. +- Always-on history tracking with zero performance cost to the online path. +- Staged publishing supports safe, phased rollouts of breaking changes. + +### Negative + +- Version-qualified online reads are initially limited to SQLite. +- Offline versioning is not supported, creating a gap for reproducing historical training data. +- No version pruning mechanism may lead to unbounded growth in long-lived feature views. +- Concurrency handling differs between SQL and file registries. + +## References + +- Original RFC: [Feature View Versioning](https://docs.google.com/document/d/1OE-S-10kdBwxWHG4TI_zdg_VAQNST38IkSVmQkCfjeQ/edit) +- Pull Request: [#6101](https://github.com/feast-dev/feast/pull/6101) +- Implementation: `sdk/python/feast/feature_view.py` (version fields), `docs/adr/feature-view-versioning.md` diff --git a/docs/adr/ADR-0009-contribution-extensibility.md b/docs/adr/ADR-0009-contribution-extensibility.md new file mode 100644 index 00000000000..4e5c94a01de --- /dev/null +++ b/docs/adr/ADR-0009-contribution-extensibility.md @@ -0,0 +1,87 @@ +# ADR-0009: Contribution and Extensibility Architecture + +## Status + +Accepted + +## Context + +A design goal for Feast is that it should be extensible and easy to use with different technologies (storage, compute, deployment environments). After the launch of Feast 0.10, community interest grew in adding support for new online stores (Dynamo, Redis, Cassandra, HBase) and custom compute engines (Dataflow, Flink). + +However, several problems existed: + +1. **No decoupled interfaces**: Online stores were not decoupled from providers, so new online store contributions required building entire new providers. +2. **No contrib path**: Contributors had no way to extend the core codebase with experimental code while benefiting from the test suite. +3. **No plugin system**: No clearly defined plugin points for Providers, Offline Stores, Online Stores, and Compute, where code could live outside the Feast codebase. + +## Decision + +Introduce a three-tier extensibility architecture: **Interfaces**, **Contrib**, and **Plugins**. + +### Interfaces + +Create abstract base classes for `OnlineStore`, `OfflineStore`, and `Provider` so that different providers can reuse functionality without reimplementing it: + +``` +Provider (top-level orchestrator) +├── OnlineStore (abstract) +├── OfflineStore (abstract) +└── Compute (future) +``` + +### Contrib Module + +Add a `contrib` module to the Feast SDK for community-contributed implementations: + +``` +feast/ +└── contrib/ + ├── compute/ + │ └── spark.py + ├── offline_stores/ + │ └── postgres.py + ├── online_stores/ + │ ├── cassandra.py + │ └── hbase.py + └── providers/ + └── azure.py +``` + +Contrib implementations are referenced by classpath in `feature_store.yaml`: + +```yaml +online_store: + type: feast.contrib.online_stores.hbase.HbaseOnlineStore +``` + +Each contrib module follows a convention: a `*Config` class for configuration and a `*Test` class for setup/teardown of test infrastructure (e.g., Docker containers). Contrib code is covered by CI but failures produce warnings only. + +### Plugins + +External Python packages can be imported and used from within Feast without merging code upstream: + +```yaml +provider: + type: my_company_feast.MyCompanyFeastProvider +``` + +The key difference: contrib code is covered by Feast's test suite; external plugins are not. + +## Consequences + +### Positive + +- Enabled a large ecosystem of community-contributed stores (Cassandra, HBase, Postgres, Spark, Trino, etc.). +- Teams can extend Feast without forking or merging code upstream. +- Clear separation between core, community-contributed, and external plugin code. +- Consistent testing patterns across all contrib implementations. + +### Negative + +- Contrib code may become unmaintained if original contributors disengage. +- Plugin interface requires careful versioning to avoid breaking external implementations. + +## References + +- Original RFC: [Feast RFC-014: Contribution Plan](https://docs.google.com/document/d/1MD0aS2_hGzd1tJ7DNjE3NgEtcuekh3O06OeQ9aavylY/edit) +- Implementation: `sdk/python/feast/infra/online_stores/`, `sdk/python/feast/infra/offline_stores/`, `sdk/python/feast/infra/contrib/` diff --git a/docs/adr/ADR-0010-vector-database-integration.md b/docs/adr/ADR-0010-vector-database-integration.md new file mode 100644 index 00000000000..e5a40e22c8e --- /dev/null +++ b/docs/adr/ADR-0010-vector-database-integration.md @@ -0,0 +1,89 @@ +# ADR-0010: Vector Database Integration for LLM/RAG Support + +## Status + +Accepted + +## Context + +Feast is an abstraction layer for ML infrastructure that integrates with diverse online and offline data sources. With the rise of Large Language Model (LLM) applications, particularly Retrieval Augmented Generation (RAG), there was a need to support: + +- Transforming document data into embeddings (features). +- Loading embeddings into vector-capable databases (online stores). +- Retrieving the most similar documents given a query embedding at serving time. + +These capabilities align naturally with Feast's existing concepts of feature views, materialization, and online serving, but required a new retrieval interface for similarity search. + +## Decision + +Extend Feast's online store interface with a `retrieve_online_documents` method that performs approximate nearest neighbor (ANN) search. + +### Core Design + +Treat embeddings/vectors as features within existing feature views. Add a new retrieval interface to online stores: + +```python +class OnlineStore: + def retrieve_online_documents( + self, + config: RepoConfig, + table: FeatureView, + requested_feature: str, + embedding: List[float], + top_k: int, + distance_metric: Optional[str] = None, + ) -> List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]]: + ... +``` + +### Supported Stores + +Online stores that implement vector search: + +- **PostgreSQL with pgvector**: ANN search using HNSW and IVFFlat indexes. +- **Elasticsearch**: Vector similarity search with hybrid search capabilities. +- **Milvus**: Dedicated vector database with large-scale ANN support. +- **Qdrant**: Vector similarity search engine. +- **SQLite with sqlite-vec**: Lightweight local vector search. + +### Usage + +```python +from feast import FeatureStore + +store = FeatureStore(".") + +# Retrieve top-k similar documents +results = store.retrieve_online_documents( + feature="document_embeddings:embedding", + query=query_embedding, + top_k=5, +) +``` + +### Key Decisions + +- **Embeddings as features**: Rather than introducing a new primitive, embeddings are stored as features in existing feature views. This reuses Feast's materialization, versioning, and serving infrastructure. +- **Interface on OnlineStore**: The `retrieve_online_documents` method is added to the `OnlineStore` interface, allowing each store implementation to use its native vector search capabilities. +- **Incremental store support**: Not all online stores support vector search. Stores that don't implement the method raise a clear error. New stores are added based on community demand and contributions. + +## Consequences + +### Positive + +- Feast naturally extends from MLops to LLMops/RAG use cases. +- Reuses existing Feast concepts (feature views, materialization, online stores) without introducing new primitives. +- Multiple vector database backends supported, giving users flexibility. +- RAG applications can use Feast as a unified feature and document store. + +### Negative + +- Vector search capabilities vary significantly across stores (e.g., hybrid search in Elasticsearch vs. pure ANN in others). Feast's interface targets the lowest common denominator. +- Embedding pipeline (encoding documents into vectors) is not fully managed by Feast; users handle this externally. + +## References + +- Original RFC: [Feast RFC-040: Document Store / LLM Extension](https://docs.google.com/document/d/18IWzLEA9i2lDWnbfbwXnMCg3StlqaLVI-uRpQjr_Vos/edit) +- GitHub Issue: [#3965](https://github.com/feast-dev/feast/issues/3965) +- Implementation: Online store implementations in `sdk/python/feast/infra/online_stores/` +- Examples: `examples/rag/`, `examples/online_store/pgvector_tutorial/`, `examples/online_store/milvus_tutorial/` diff --git a/docs/adr/ADR-0011-data-quality-monitoring.md b/docs/adr/ADR-0011-data-quality-monitoring.md new file mode 100644 index 00000000000..55df3aa1ddd --- /dev/null +++ b/docs/adr/ADR-0011-data-quality-monitoring.md @@ -0,0 +1,90 @@ +# ADR-0011: Data Quality Monitoring + +## Status + +Accepted + +## Context + +Data quality issues can significantly impact ML model performance. Several complex data problems needed to be addressed: + +- **Data consistency**: New training datasets can differ significantly from previous datasets, potentially requiring changes in model architecture. +- **Upstream pipeline bugs**: Bugs in upstream pipelines can cause invalid values to overwrite existing valid values in an online store. +- **Training/serving skew**: Distribution shift between training and serving data can decrease model performance. + +Feast needed a mechanism to validate data at retrieval time to catch these issues before they affect model training or serving. + +## Decision + +Introduce a Data Quality Monitoring (DQM) module that validates datasets against user-curated rules, initially targeting historical retrieval (training dataset generation). + +### Design + +The validation process uses a **reference dataset** and a **profiler** pattern: + +1. User prepares a reference dataset (saved from a known-good historical retrieval). +2. User defines a profiler function that produces a profile (set of expectations) from a dataset. +3. Validation is performed by comparing the tested dataset against the reference profile. + +### Integration with Great Expectations + +The initial implementation uses [Great Expectations](https://greatexpectations.io/) as the validation engine: + +```python +from feast.dqm.profilers.ge_profiler import ge_profiler +from great_expectations.dataset import Dataset +from great_expectations.core.expectation_suite import ExpectationSuite + +@ge_profiler +def my_profiler(dataset: Dataset) -> ExpectationSuite: + dataset.expect_column_max_to_be_between("column", 1, 2) + dataset.expect_column_values_to_not_be_null("important_feature") + return dataset.get_expectation_suite() +``` + +### Usage + +Validation is triggered during historical feature retrieval via a `validation_reference` parameter: + +```python +from feast import FeatureStore + +store = FeatureStore(".") + +job = store.get_historical_features(...) +df = job.to_df( + validation_reference=store + .get_saved_dataset("my_reference_dataset") + .as_reference(profiler=my_profiler) +) +``` + +If validation fails, a `ValidationFailed` exception is raised with details for all expectations that didn't pass. If validation succeeds, the materialized dataset is returned normally. + +### Key Decisions + +- **Profiler-based approach**: Users define their own validation rules via profiler functions rather than Feast prescribing fixed validation rules. +- **Great Expectations integration**: Leverages an established data validation framework rather than building custom validation logic. +- **Validation at retrieval time**: Validation is performed when datasets are materialized (`.to_df()` or `.to_arrow()`), not during ingestion. +- **ValidationReference as a registry object**: Saved datasets and their validation references are stored in the Feast registry for reuse. + +## Consequences + +### Positive + +- Users can detect data quality issues before they affect model training. +- Flexible profiler pattern allows custom validation rules per use case. +- Integration with Great Expectations provides a rich set of built-in expectations. +- Reference datasets provide a baseline for detecting data drift. + +### Negative + +- Currently limited to historical retrieval; online store write/read validation is planned but not yet implemented. +- Dependency on Great Expectations adds to the install footprint (optional via `feast[ge]`). +- Automatic profiling capabilities are limited; manual expectation crafting is recommended. + +## References + +- Original RFC: Feast RFC-027: Data Quality Monitoring +- Implementation: `sdk/python/feast/dqm/`, `sdk/python/feast/saved_dataset.py` +- Documentation: [Data Quality Monitoring](../reference/dqm.md) diff --git a/docs/adr/ADR-TEMPLATE.md b/docs/adr/ADR-TEMPLATE.md new file mode 100644 index 00000000000..084dc3d20f9 --- /dev/null +++ b/docs/adr/ADR-TEMPLATE.md @@ -0,0 +1,31 @@ +# ADR-XXXX: Title + +## Status + +Proposed | Accepted | Deprecated | Superseded + +## Context + +Describe the context and problem statement. What is the issue that motivated this decision? + +## Decision + +Describe the decision that was made. Include any relevant design details, API examples, or architecture diagrams. + +## Consequences + +### Positive + +- List positive outcomes of this decision. + +### Negative + +- List any trade-offs or negative outcomes. + +### Neutral + +- List any neutral observations. + +## References + +- Link to the original RFC, GitHub issues, or pull requests. diff --git a/docs/adr/README.md b/docs/adr/README.md new file mode 100644 index 00000000000..49e20f81885 --- /dev/null +++ b/docs/adr/README.md @@ -0,0 +1,37 @@ +# Architecture Decision Records (ADR) + +This directory contains Architecture Decision Records (ADRs) for the Feast project. ADRs document significant architectural decisions made during the development of Feast, providing context, rationale, and consequences for each decision. + +## What is an ADR? + +An Architecture Decision Record captures a single architectural decision, including the context in which it was made, the decision itself, and the expected consequences. ADRs serve as a historical record for current and future contributors to understand why the project is structured the way it is. + +## ADR Index + +| ADR | Title | Status | Original RFC | +|-----|-------|--------|-------------| +| [ADR-0001](ADR-0001-feature-services.md) | Feature Services | Accepted | RFC-015 | +| [ADR-0002](ADR-0002-component-refactor.md) | Component Refactor | Accepted | RFC-020 | +| [ADR-0003](ADR-0003-on-demand-transformations.md) | On-Demand Transformations | Accepted | RFC-021 | +| [ADR-0004](ADR-0004-entity-join-key-mapping.md) | Entity Join Key Mapping | Accepted | RFC-023 | +| [ADR-0005](ADR-0005-stream-transformations.md) | Stream Transformations | Accepted | RFC-036 | +| [ADR-0006](ADR-0006-kubernetes-operator.md) | Kubernetes Operator | Accepted | RFC-042 | +| [ADR-0007](ADR-0007-unified-feature-transformations.md) | Unified Feature Transformations and Feature Views | Accepted | RFC-043 | +| [ADR-0008](ADR-0008-feature-view-versioning.md) | Feature View Versioning | Accepted | Feature View Versioning RFC | +| [ADR-0009](ADR-0009-contribution-extensibility.md) | Contribution and Extensibility Architecture | Accepted | RFC-014 | +| [ADR-0010](ADR-0010-vector-database-integration.md) | Vector Database Integration for LLM/RAG Support | Accepted | RFC-040 | +| [ADR-0011](ADR-0011-data-quality-monitoring.md) | Data Quality Monitoring | Accepted | RFC-027 | + +## Creating a New ADR + +1. Copy the [ADR template](ADR-TEMPLATE.md) to a new file with the next sequential number. +2. Fill in all sections of the template. +3. Submit a pull request with the new ADR. +4. Once the RFC is finalized and approved, update the ADR status to "Accepted". + +## ADR Statuses + +- **Proposed**: The decision is under discussion. +- **Accepted**: The decision has been accepted and is being (or has been) implemented. +- **Deprecated**: The decision is no longer relevant due to changes in the project. +- **Superseded**: The decision has been replaced by a newer ADR. diff --git a/docs/rfcs/feature-view-versioning.md b/docs/adr/feature-view-versioning.md similarity index 100% rename from docs/rfcs/feature-view-versioning.md rename to docs/adr/feature-view-versioning.md diff --git a/docs/getting-started/concepts/feature-retrieval.md b/docs/getting-started/concepts/feature-retrieval.md index c7b414af806..b3c4062edfd 100644 --- a/docs/getting-started/concepts/feature-retrieval.md +++ b/docs/getting-started/concepts/feature-retrieval.md @@ -297,6 +297,59 @@ training_df = store.get_historical_features( ).to_df() ``` +### Step 3: Choosing an output format + +`get_historical_features()` returns a `RetrievalJob` object. You can convert it +to the format that suits your downstream pipeline: + +**Data conversion methods** + +| Method | Returns | When to use | +|---|---|---| +| `.to_df()` | `pandas.DataFrame` | General-purpose; scikit-learn, XGBoost, statsmodels | +| `.to_feast_df()` | `FeastDataFrame` | Feast-native wrapper with engine metadata; preferred for Feast-internal tooling | +| `.to_arrow()` | `pyarrow.Table` | Arrow-native pipelines, Polars, DuckDB, zero-copy interchange | +| `.to_tensor(kind="torch")` | `Dict[str, torch.Tensor]` | Direct PyTorch training loops; numeric columns become tensors | +| `.to_ray_dataset()` | `ray.data.Dataset` | Ray Train, Ray Serve, distributed ML workloads | + +**Persistence methods** + +| Method | Effect | When to use | +|---|---|---| +| `.persist(storage)` | Writes result to offline storage | Save a training dataset for later reuse or auditing | +| `.to_remote_storage()` | Exports result to S3/GCS as Parquet files | Hand off to external systems or data pipelines | + +#### Retrieving as a Ray Dataset + +`to_ray_dataset()` is a **first-class method** on every `RetrievalJob`. When +the underlying offline store is a `RayOfflineStore`, the dataset is returned +directly without a copy through Arrow. For all other offline stores, a +zero-copy Arrow → Ray Dataset conversion is used as a fallback. + +```python +from feast import FeatureStore + +store = FeatureStore(".") + +# to_ray_dataset() is a first-class method on the RetrievalJob — chain it +# directly after get_historical_features(). +ray_ds = store.get_historical_features( + entity_df=entity_df, + features=["driver_hourly_stats:conv_rate", "driver_hourly_stats:acc_rate"], +).to_ray_dataset() + +# Use with Ray Train +import ray.train +trainer = ray.train.torch.TorchTrainer( + train_loop_per_worker=..., + datasets={"train": ray_ds}, +) +``` + +> **Note:** `to_ray_dataset()` requires `feast[ray]` to be installed. + +--- + ## Retrieving online features (for model inference) Feast will ensure the latest feature values for registered features are available. At retrieval time, you need to supply a list of **entities** and the corresponding **features** to be retrieved. Similar to `get_historical_features`, we recommend using feature services as a mechanism for grouping features in a model version. diff --git a/docs/getting-started/concepts/feature-view.md b/docs/getting-started/concepts/feature-view.md index ee70d5024dd..5be9b287305 100644 --- a/docs/getting-started/concepts/feature-view.md +++ b/docs/getting-started/concepts/feature-view.md @@ -23,6 +23,8 @@ Feature views consist of: * a name to uniquely identify this feature view in the project. * (optional, but recommended) a schema specifying one or more [features](feature-view.md#field) (without this, Feast will infer the schema by reading from the data source) * (optional, but recommended) metadata (for example, description, or other free-form metadata via `tags`) +* (optional) `owner`: the email of the primary maintainer +* (optional) `org`: the organizational unit that owns the feature view (e.g. `"ads"`, `"search"`); useful for grouping feature views by team or product area * (optional) a TTL, which limits how far back Feast will look when generating historical datasets * (optional) `enable_validation=True`, which enables schema validation during materialization (see [Schema Validation](#schema-validation) below) @@ -270,7 +272,7 @@ def transformed_conv_rate(features_df: pd.DataFrame) -> pd.DataFrame: A stream feature view is an extension of a normal feature view. The primary difference is that stream feature views have both stream and batch data sources, whereas a normal feature view only has a batch data source. -Stream feature views should be used instead of normal feature views when there are stream data sources (e.g. Kafka and Kinesis) available to provide fresh features in an online setting. Here is an example definition of a stream feature view with an attached transformation: +Stream feature views should be used instead of normal feature views when there are stream data sources (e.g. Kafka and Kinesis) available to provide fresh features in an online setting. Like regular feature views, stream feature views support the optional `org` field for grouping by organizational unit. Here is an example definition of a stream feature view with an attached transformation: ```python from datetime import timedelta @@ -308,6 +310,7 @@ driver_stats_stream_source = KafkaSource( timestamp_field="event_timestamp", online=True, source=driver_stats_stream_source, + org="ads", # optional ) def driver_hourly_stats_stream(df: DataFrame): from pyspark.sql.functions import col diff --git a/docs/getting-started/genai.md b/docs/getting-started/genai.md index d8798b481d7..f65aeac85e2 100644 --- a/docs/getting-started/genai.md +++ b/docs/getting-started/genai.md @@ -56,6 +56,53 @@ The transformation workflow typically involves: 3. **Chunking**: Split documents into smaller, semantically meaningful chunks 4. **Embedding Generation**: Convert text chunks into vector embeddings 5. **Storage**: Store embeddings and metadata in Feast's feature store + +### DocEmbedder: End-to-End Document Ingestion Pipeline + +The `DocEmbedder` class provides an end-to-end pipeline for ingesting documents into Feast's online vector store. It handles chunking, embedding generation, and writing results -- all in a single step. + +#### Key Components + +* **`DocEmbedder`**: High-level orchestrator that runs the full pipeline: chunk → embed → schema transform → write to online store +* **`BaseChunker` / `TextChunker`**: Pluggable chunking layer. `TextChunker` splits text by word count with configurable `chunk_size`, `chunk_overlap`, `min_chunk_size`, and `max_chunk_chars` +* **`BaseEmbedder` / `MultiModalEmbedder`**: Pluggable embedding layer with modality routing. `MultiModalEmbedder` supports text (via sentence-transformers) and image (via CLIP) with lazy model loading +* **`SchemaTransformFn`**: A user-defined function that transforms the chunked + embedded DataFrame into the format expected by the FeatureView schema + +#### Quick Example + +```python +from feast import DocEmbedder +import pandas as pd + +# Prepare your documents +df = pd.DataFrame({ + "id": ["doc1", "doc2"], + "text": ["First document content...", "Second document content..."], +}) + +# Create DocEmbedder -- automatically generates a FeatureView and applies the repo +embedder = DocEmbedder( + repo_path="feature_repo/", + feature_view_name="text_feature_view", +) + +# Embed and ingest documents in one step +result = embedder.embed_documents( + documents=df, + id_column="id", + source_column="text", + column_mapping=("text", "text_embedding"), +) +``` + +#### Features + +* **Auto-generates FeatureView**: Creates a Python file with Entity and FeatureView definitions compatible with `feast apply` +* **Auto-applies repo**: Registers the generated FeatureView in the registry automatically +* **Custom schema transform**: Provide your own `SchemaTransformFn` to control how chunked + embedded data maps to your FeatureView schema +* **Extensible**: Subclass `BaseChunker` or `BaseEmbedder` to plug in your own chunking or embedding strategies + +For a complete walkthrough, see the [DocEmbedder tutorial notebook](../../examples/rag-retriever/rag_feast_docembedder.ipynb). ### Feature Transformation for LLMs Feast supports transformations that can be used to: @@ -89,6 +136,17 @@ Implement semantic search by: 2. Converting search queries to embeddings 3. Finding semantically similar documents using vector search +### AI Agents with Context and Memory + +Feast can serve as both the **context provider** and **persistent memory layer** for AI agents. Unlike stateless RAG pipelines, agents make autonomous decisions about which tools to call and can write state back to the feature store: + +1. **Structured context**: Retrieve customer profiles, account data, and other entity-keyed features +2. **Knowledge retrieval**: Search vector embeddings for relevant documents +3. **Persistent memory**: Store and recall per-entity interaction history (last topic, resolution, preferences) using `write_to_online_store` +4. **Governed access**: All reads and writes are subject to the same RBAC, TTL, and audit policies as any other feature + +With MCP enabled, agents built with any framework (LangChain, LlamaIndex, CrewAI, AutoGen, or custom) can discover and call Feast tools dynamically. See the [Feast-Powered AI Agent example](../../examples/agent_feature_store/) and the blog post [Building AI Agents with Feast](https://feast.dev/blog/feast-agents-mcp/) for a complete walkthrough. + ### Scaling with Spark Integration Feast integrates with Apache Spark to enable large-scale processing of unstructured data for GenAI applications: @@ -167,9 +225,11 @@ The MCP integration uses the `fastapi_mcp` library to automatically transform yo The fastapi_mcp integration automatically exposes your Feast feature server's FastAPI endpoints as MCP tools. This means AI assistants can: * **Call `/get-online-features`** to retrieve features from the feature store +* **Call `/retrieve-online-documents`** to perform vector similarity search +* **Call `/write-to-online-store`** to persist agent state (memory, notes, interaction history) * **Use `/health`** to check server status -For a complete example, see the [MCP Feature Store Example](../../examples/mcp_feature_store/). +For a basic MCP example, see the [MCP Feature Store Example](../../examples/mcp_feature_store/). For a full agent with persistent memory, see the [Feast-Powered AI Agent Example](../../examples/agent_feature_store/). ## Learn More @@ -177,10 +237,13 @@ For more detailed information and examples: * [Vector Database Reference](../reference/alpha-vector-database.md) * [RAG Tutorial with Docling](../tutorials/rag-with-docling.md) +* [DocEmbedder Tutorial Notebook](../../examples/rag-retriever/rag_feast_docembedder.ipynb) * [RAG Fine Tuning with Feast and Milvus](../../examples/rag-retriever/README.md) * [Milvus Quickstart Example](https://github.com/feast-dev/feast/tree/master/examples/rag/milvus-quickstart.ipynb) * [Feast + Ray: Distributed Processing for RAG Applications](https://feast.dev/blog/feast-ray-distributed-processing/) * [MCP Feature Store Example](../../examples/mcp_feature_store/) +* [Feast-Powered AI Agent Example (with Memory)](../../examples/agent_feature_store/) +* [Blog: Building AI Agents with Feast](https://feast.dev/blog/feast-agents-mcp/) * [MCP Feature Server Reference](../reference/feature-servers/mcp-feature-server.md) * [Spark Data Source](../reference/data-sources/spark.md) * [Spark Offline Store](../reference/offline-stores/spark.md) diff --git a/docs/how-to-guides/feast-on-kubernetes.md b/docs/how-to-guides/feast-on-kubernetes.md index f5df67273bb..923fc387032 100644 --- a/docs/how-to-guides/feast-on-kubernetes.md +++ b/docs/how-to-guides/feast-on-kubernetes.md @@ -10,6 +10,10 @@ Kubernetes is a common target environment for running Feast in production. You c 2. Run scheduled and ad-hoc jobs (e.g. materialization jobs) as Kubernetes Jobs. 3. Operate Feast components using Kubernetes-native primitives. +{% hint style="info" %} +**Planning a production deployment?** See the [Feast Production Deployment Topologies](./production-deployment-topologies.md) guide for architecture diagrams, sample FeatureStore CRs, RBAC policies, infrastructure recommendations, and scaling best practices across Minimal, Standard, and Enterprise topologies. +{% endhint %} + ## Feast Operator To deploy Feast components on Kubernetes, use the included [feast-operator](../../infra/feast-operator). @@ -64,6 +68,12 @@ spec: > _More advanced FeatureStore CR examples can be found in the feast-operator [samples directory](../../infra/feast-operator/config/samples)._ +{% hint style="info" %} +**Advanced configuration:** To configure persistence, metrics, MCP, OpenLineage, security, +batch jobs, and more via the operator, see the +[Operator Configuration Guides](feast-operator/README.md). +{% endhint %} + ## Upgrading the Operator ### OLM-managed installations diff --git a/docs/how-to-guides/feast-operator/01-project-provisioning.md b/docs/how-to-guides/feast-operator/01-project-provisioning.md new file mode 100644 index 00000000000..b54ce57eeeb --- /dev/null +++ b/docs/how-to-guides/feast-operator/01-project-provisioning.md @@ -0,0 +1,190 @@ +# Guide 1 — Project Provisioning + +The operator needs a Feast feature repository (a directory containing `feature_store.yaml` +and Python feature-view definitions) to work from. `spec.feastProjectDir` controls how that +directory is created inside the pods. Exactly one of `git` or `init` must be set. + +--- + +## Option A — Clone from a Git repository (`feastProjectDir.git`) + +The operator runs an init container that clones the repository before the Feast processes +start. Use this for production: your feature definitions live in version control and the +operator tracks a specific commit or branch. + +### Minimal example + +```yaml +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: my-feature-store +spec: + feastProject: credit_scoring + feastProjectDir: + git: + url: https://github.com/my-org/feast-feature-repo + ref: main # branch, tag, or commit SHA +``` + +### Pinning to a specific commit (recommended for production) + +```yaml +feastProjectDir: + git: + url: https://github.com/my-org/feast-feature-repo + ref: 598a270 # immutable SHA — no surprise changes on pod restart +``` + +### Monorepo: feature repo in a subdirectory + +When the Feast feature repository lives inside a larger monorepo, use `featureRepoPath` +to point at the subdirectory (relative path, no leading `/`): + +```yaml +feastProjectDir: + git: + url: https://github.com/my-org/data-platform + ref: e959053 + featureRepoPath: ml/feast/feature_repo # relative to repo root +``` + +### Private repositories — token authentication + +Create a Kubernetes Secret containing the token: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: git-token +stringData: + TOKEN: +``` + +Reference the Secret from `envFrom` and rewrite the remote URL via `configs`: + +```yaml +feastProjectDir: + git: + url: https://github.com/my-org/private-repo + configs: + # Replaces the HTTPS URL with one that includes the token + 'url."https://api:${TOKEN}@github.com/".insteadOf': 'https://github.com/' + envFrom: + - secretRef: + name: git-token +``` + +### Disabling TLS verification (not recommended for production) + +```yaml +feastProjectDir: + git: + url: https://internal-git.corp/feast-repo + configs: + http.sslVerify: 'false' +``` + +### Full `git` field reference + +| Field | Type | Description | +|-------|------|-------------| +| `url` | string | Repository URL (HTTPS or SSH) | +| `ref` | string | Branch, tag, or commit SHA. Defaults to the remote HEAD | +| `featureRepoPath` | string | Relative path within the repo to the feature repository directory. Default: `feature_repo` | +| `configs` | map[string]string | Key-value pairs passed to `git -c` before clone | +| `env` | EnvVar[] | Environment variables for the git init container | +| `envFrom` | EnvFromSource[] | Sources (Secrets, ConfigMaps) for init container environment | + +--- + +## Option B — Scaffold a new project (`feastProjectDir.init`) + +The operator runs `feast init` on first startup to create a minimal feature repository. +Use this for development, demos, and CI environments where you do not yet have a feature +repo to point at. + +```yaml +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: feast-dev +spec: + feastProject: sample_project + feastProjectDir: + init: {} # defaults: template=local, minimal=false +``` + +### Templates + +`feast init` supports store-specific templates. Set `template` to generate a scaffold that +matches your chosen online/offline store: + +```yaml +feastProjectDir: + init: + template: spark # scaffolds Spark-compatible feature_store.yaml +``` + +Available templates (validated by the CRD): +`local` · `gcp` · `aws` · `snowflake` · `spark` · `postgres` · `hbase` · `cassandra` · +`hazelcast` · `couchbase` · `clickhouse` + +### Minimal scaffold + +`minimal: true` skips example feature-view files and creates only the bare +`feature_store.yaml`: + +```yaml +feastProjectDir: + init: + minimal: true +``` + +### Full `init` field reference + +| Field | Type | Default | Description | +|-------|------|---------|-------------| +| `template` | string | `local` | Template name for `feast init --template` | +| `minimal` | bool | `false` | Pass `--minimal` to `feast init` | + +--- + +## `feast apply` on startup + +By default, when the init container completes (git clone or `feast init`), the operator runs +`feast apply` before starting the servers. This registers all feature definitions with the +registry. + +To **skip** `feast apply` on pod start (e.g. you manage registry updates separately): + +```yaml +services: + disableInitContainers: true # skip both clone/init AND feast apply +``` + +Or to keep the init container but skip the apply step: + +```yaml +services: + runFeastApplyOnInit: false +``` + +--- + +## When `feastProjectDir` is omitted + +If neither `git` nor `init` is set, the operator mounts an empty directory. In this case +you must supply a `feature_store.yaml` through another mechanism (e.g. a ConfigMap volume +mount via `services.volumes` + `volumeMounts`). + +--- + +## See also + +- [API reference — `FeastProjectDir`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#feastprojectdir) +- [Sample: public git repo](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_git.yaml) +- [Sample: private git repo with token](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_git_token.yaml) +- [Sample: monorepo with featureRepoPath](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_git_repopath.yaml) +- [Sample: feast init](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_init.yaml) diff --git a/docs/how-to-guides/feast-operator/02-persistence.md b/docs/how-to-guides/feast-operator/02-persistence.md new file mode 100644 index 00000000000..1097e68a6ce --- /dev/null +++ b/docs/how-to-guides/feast-operator/02-persistence.md @@ -0,0 +1,307 @@ +# Guide 2 — Persistence + +The offline store, online store, and registry each need a place to store data. The operator +supports two persistence patterns for each: + +- **File persistence** — a path on a volume (ephemeral or PVC-backed) +- **DB/store persistence** — an external database or managed store, wired via a Kubernetes Secret + +The pattern is the same for all three services; only the store types differ. + +--- + +## Persistence patterns at a glance + +| Pattern | Best for | Data survives pod restart? | +|---------|----------|-----------------------------| +| **File — emptyDir** | Dev / CI | No | +| **File — PVC (ref)** | Single-node prod or testing | Yes (if PVC is retained) | +| **File — PVC (create)** | Operator-managed storage | Yes | +| **DB store** | Production, HA, multi-pod | Yes | + +--- + +## File persistence + +### Ephemeral (emptyDir) + +The default when no `persistence` block is set. Data lives on the pod's local disk and is +lost on restart. Suitable for development only. + +```yaml +services: + onlineStore: + server: {} # no persistence block → emptyDir +``` + +### PVC — reference an existing PVC + +When you already have a PVC provisioned (e.g. by your storage team): + +```yaml +services: + onlineStore: + persistence: + file: + path: online_store.db # filename relative to mountPath + pvc: + ref: + name: online-pvc # name of the existing PVC + mountPath: /data/online # where the PVC is mounted in the pod +``` + +### PVC — let the operator create one + +```yaml +services: + offlineStore: + persistence: + file: + type: duckdb # offline file type: file | dask | duckdb + pvc: + create: + storageClassName: standard + resources: + requests: + storage: 20Gi + mountPath: /data/offline +``` + +Omitting `storageClassName` uses the cluster default StorageClass. Omitting `create` +entirely creates a PVC with the operator's built-in defaults (1 Gi, default StorageClass). + +```yaml +registry: + local: + persistence: + file: + path: registry.db + pvc: + create: {} # operator defaults: 1 Gi, default StorageClass + mountPath: /data/registry +``` + +--- + +## DB / store persistence + +For production, point the operator at an external database. The operator reads connection +details from a Kubernetes Secret and writes them into `feature_store.yaml`. + +### Secret format + +The Secret must contain one key per store component. The **key name** is the store type +(e.g. `postgres`, `sql`, `redis`). The **value** is a YAML snippet identical to what you +would write under the corresponding section in `feature_store.yaml`, **minus the `type:` key** +(the operator inserts it from `persistence.store.type`). + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: feast-data-stores +stringData: + # Key for online store type "postgres" + postgres: | + host: postgres.feast.svc.cluster.local + port: 5432 + database: feast + db_schema: public + user: feast + password: feast + + # Key for registry type "sql" (SQLAlchemy URL) + sql: | + path: postgresql+psycopg://feast:feast@postgres.feast.svc.cluster.local:5432/feast #pragma: allowlist secret + cache_ttl_seconds: 60 + sqlalchemy_config_kwargs: + echo: false + pool_pre_ping: true +``` + +Reference the Secret from the CR: + +```yaml +services: + onlineStore: + persistence: + store: + type: postgres + secretRef: + name: feast-data-stores # key "postgres" is read automatically + registry: + local: + persistence: + store: + type: sql + secretRef: + name: feast-data-stores # key "sql" is read automatically +``` + +> **Key lookup rule**: the operator looks up the Secret key that matches +> `persistence.store.type` (e.g. `type: postgres` → key `postgres`). +> Keep all stores in one Secret or split across multiple — both work. + +### Injecting DB credentials into the server pod + +The Secret key values in the example above hard-code passwords. For production, keep +credentials in a separate Secret and inject them as environment variables using `envFrom`, +then reference them with `${VAR}` substitution in the data-stores Secret value: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: postgres-creds +stringData: + POSTGRES_USER: feast + POSTGRES_PASSWORD: s3cr3t +--- +apiVersion: v1 +kind: Secret +metadata: + name: feast-data-stores +stringData: + postgres: | + host: postgres.feast.svc.cluster.local + port: 5432 + database: feast + user: ${POSTGRES_USER} + password: ${POSTGRES_PASSWORD} +``` + +```yaml +services: + onlineStore: + server: + envFrom: + - secretRef: + name: postgres-creds # expands ${POSTGRES_USER} / ${POSTGRES_PASSWORD} + persistence: + store: + type: postgres + secretRef: + name: feast-data-stores +``` + +--- + +## Store types by component + +### Online store + +| `type` | Secret key | SDK docs | +|--------|------------|---------| +| `sqlite` | `sqlite` | [SQLite](../reference/online-stores/sqlite.md) | +| `redis` | `redis` | [Redis](../reference/online-stores/redis.md) | +| `postgres` | `postgres` | [Postgres](../reference/online-stores/postgres.md) | +| `cassandra` | `cassandra` | [Cassandra](../reference/online-stores/cassandra.md) | +| `hazelcast` | `hazelcast` | [Hazelcast](../reference/online-stores/hazelcast.md) | +| `hbase` | `hbase` | [HBase](../reference/online-stores/hbase.md) | +| `datastore` | `datastore` | [Datastore](../reference/online-stores/datastore.md) | +| `dynamodb` | `dynamodb` | [DynamoDB](../reference/online-stores/dynamodb.md) | +| `bigtable` | `bigtable` | [Bigtable](../reference/online-stores/bigtable.md) | + +> For all store-specific YAML keys (connection options, pool sizes, etc.) see the +> linked SDK docs — the Secret value accepts the same keys. + +### Offline store + +| `type` (file) | Notes | +|-------|-------| +| `file` | Default pandas-based parquet offline store | +| `dask` | Dask-based parallel parquet | +| `duckdb` | DuckDB in-process analytical engine | + +For external DB-backed offline stores (BigQuery, Snowflake, Spark, Trino, etc.), use +`persistence.store.type` and a Secret with the matching key. See +[Offline Stores](../reference/offline-stores/) in the SDK docs. + +### Registry + +| `type` | Secret key | Notes | +|--------|------------|-------| +| `file` | *(file persistence, no Secret)* | SQLite-backed file registry | +| `sql` | `sql` | SQLAlchemy URL — supports PostgreSQL, MySQL, SQLite | +| `snowflake.registry` | `snowflake.registry` | Snowflake-backed registry | + +For `sql`, the Secret value is a `path:` (SQLAlchemy URL) plus optional `cache_ttl_seconds` +and `sqlalchemy_config_kwargs`: + +```yaml +# feast-data-stores Secret, key "sql" +sql: | + path: postgresql+psycopg://user:pass@host:5432/feast #pragma: allowlist secret + cache_ttl_seconds: 60 +``` + +--- + +## Common patterns + +### Redis online store + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: feast-data-stores +stringData: + redis: | + connection_string: redis.feast.svc.cluster.local:6379 +--- +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: sample-redis +spec: + feastProject: my_project + services: + onlineStore: + server: {} + persistence: + store: + type: redis + secretRef: + name: feast-data-stores +``` + +### Postgres for both online store and registry + +```yaml +services: + onlineStore: + persistence: + store: + type: postgres + secretRef: + name: feast-data-stores # reads key "postgres" + offlineStore: + persistence: + file: + type: duckdb + pvc: + create: {} + mountPath: /data/offline + registry: + local: + persistence: + store: + type: sql + secretRef: + name: feast-data-stores # reads key "sql" +``` + +--- + +## See also + +- [API reference — `OnlineStorePersistence`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#onlinestorepersistence) +- [API reference — `OfflineStorePersistence`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#offlinepersistence) +- [API reference — `RegistryPersistence`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#registrypersistence) +- [Sample: DB persistence (Postgres)](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_db_persistence.yaml) +- [Sample: PVC persistence](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_pvc_persistence.yaml) +- [Sample: object store (GCS)](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_gcs.yaml) +- [Feast SDK — Online Stores](../reference/online-stores/) +- [Feast SDK — Offline Stores](../reference/offline-stores/) +- [Feast SDK — Registries](../reference/registries/) diff --git a/docs/how-to-guides/feast-operator/03-serving-and-observability.md b/docs/how-to-guides/feast-operator/03-serving-and-observability.md new file mode 100644 index 00000000000..efd7b5e5300 --- /dev/null +++ b/docs/how-to-guides/feast-operator/03-serving-and-observability.md @@ -0,0 +1,308 @@ +# Guide 3 — Serving & Observability + +This guide covers the `spec.services.onlineStore.serving` block and general server +configuration (`server` block) for all Feast services: per-worker tuning, log levels, +Prometheus metrics, offline push batching, and MCP (Model Context Protocol). + +--- + +## Server configuration (`server` block) + +Every deployable Feast service (online store, offline store, registry, UI) accepts a +`server` block under `spec.services.`. The online and offline stores use +`ServerConfigs`; the registry uses `RegistryServerConfigs` (adds `restAPI` / `grpc` toggles). + +### Enable a server + +An empty `server: {}` is enough to deploy a service. Without it the component is not +deployed (e.g. the offline store runs as a local process, not as a network server): + +```yaml +services: + onlineStore: + server: {} # deploys the online feature server on port 6566 + offlineStore: + server: {} # deploys the offline feature server on port 8815 + registry: + local: + server: {} # deploys the registry server on port 6570 + ui: {} # deploys the Feast UI +``` + +### Log level + +```yaml +services: + onlineStore: + server: + logLevel: debug # debug | info | warning | error | critical + offlineStore: + server: + logLevel: info + registry: + local: + server: + logLevel: warning +``` + +### Container image and resources + +The operator resolves the feature server image through the following priority chain: + +1. **`server.image` in the CR** — per-service override, highest priority +2. **`RELATED_IMAGE_FEATURE_SERVER` env var on the operator pod** — cluster-wide default set by OLM/platform +3. **Built-in default** — `quay.io/feastdev/feature-server:` + +The same `RELATED_IMAGE_FEATURE_SERVER` image is used for **all server containers** (online, +offline, registry, UI) and for the **init containers** (git clone, `feast apply`). Setting +it overrides all of them at once without touching any CR. + +The **cronJob** container uses a separate env var: `RELATED_IMAGE_CRON_JOB` +(default: `quay.io/openshift/origin-cli:4.17`). + +**Cluster-wide image override (operator env var)** — set this on the operator `Deployment` +to redirect all pods cluster-wide to a different registry (e.g. a private mirror or a +pinned digest): + +```sh +kubectl set env deployment/feast-operator-controller-manager \ + RELATED_IMAGE_FEATURE_SERVER=my-registry.example.com/feast/feature-server:custom \ + RELATED_IMAGE_CRON_JOB=my-registry.example.com/tools/cli:latest \ + -n feast-operator-system +``` + +**Per-service CR override** — for a single `FeatureStore` or to pin one service to a +different image than the cluster default: + +```yaml +services: + onlineStore: + server: + image: quay.io/feastdev/feature-server:0.62.0 + resources: + requests: + cpu: "500m" + memory: "512Mi" + limits: + cpu: "2" + memory: "2Gi" +``` + +### Worker configuration (gunicorn) + +The online and offline servers run on gunicorn. Tune worker count, connections, and +request limits: + +```yaml +services: + onlineStore: + server: + workerConfigs: + workers: -1 # -1 = auto (2 × CPU cores + 1) + workerConnections: 1000 # simultaneous clients per worker + maxRequests: 1000 # requests before worker restart (memory leak prevention) + maxRequestsJitter: 50 # jitter to avoid thundering herd + keepAliveTimeout: 30 # keep-alive timeout in seconds + registryTtlSec: 60 # registry refresh interval in seconds +``` + +> **Production recommendation**: set `workers: -1` and `registryTtlSec: 60` or higher. +> See [Online Server Performance Tuning](../online-server-performance-tuning.md) +> for detailed guidance. + +### Environment variables and secrets + +Inject environment variables from Secrets or ConfigMaps into any server: + +```yaml +services: + onlineStore: + server: + envFrom: + - secretRef: + name: my-db-credentials + env: + - name: FEAST_USAGE + value: "false" +``` + +### Volume mounts + +Mount additional volumes (ConfigMaps, Secrets, PVCs) into the server containers: + +```yaml +services: + volumes: + - name: ca-cert + configMap: + name: cluster-ca + onlineStore: + server: + volumeMounts: + - name: ca-cert + mountPath: /etc/ssl/certs/cluster-ca.crt + subPath: ca.crt +``` + +--- + +## TLS + +All servers support TLS termination. Provide a Kubernetes Secret containing the TLS +certificate and key, and reference it from `tls`: + +```yaml +services: + onlineStore: + server: + tls: + secretRef: + name: feast-tls # Secret with keys tls.crt and tls.key +``` + +For mTLS (mutual TLS), also set a CA certificate ConfigMap: + +```yaml + tls: + secretRef: + name: feast-tls + caCertConfigMapRef: + name: cluster-ca + certKeyName: tls.crt # default +``` + +--- + +## Prometheus Metrics + +When metrics are enabled the feature server starts an HTTP server on port **8000** for +Prometheus scraping. The operator automatically adds a `containerPort`, a Kubernetes `Service` +port, and a `ServiceMonitor` for Prometheus discovery. + +### Two paths — use either or both + +**Path 1: CLI flag** (existing, simple) + +```yaml +services: + onlineStore: + server: + metrics: true # injects --metrics into feast serve; exposes port 8000 +``` + +**Path 2: YAML config** (new, granular) + +```yaml +services: + onlineStore: + serving: + metrics: + enabled: true + categories: + resource: true # CPU / memory gauges + request: true # per-endpoint latency and request counters + online_features: true # feature retrieval metrics + push: true # push request counters + materialization: true # materialization counters and histograms + freshness: false # feature freshness (can be expensive at scale) +``` + +Both paths expose port 8000 and create a `ServiceMonitor`. When `serving.metrics.enabled` +is true the Python server reads it from `feature_store.yaml` directly; no `--metrics` flag +is injected. When `server.metrics: true` is used, the `--metrics` flag is injected. + +> **SDK note**: `MetricsConfig` uses `extra="forbid"` in Pydantic. Only use category keys +> that are recognized by your Feast SDK version. + +**Verify monitoring is wired:** +```sh +kubectl get servicemonitor -n +kubectl port-forward svc/-online 8000:8000 -n +curl http://localhost:8000/metrics +``` + +--- + +## Offline Push Batching + +When features are pushed to the online store via `/push`, each request also triggers a +synchronous offline store write. At high push throughput this causes OOM. Push batching +groups these writes into fixed-size batches flushed on a timer. + +```yaml +services: + onlineStore: + serving: + offlinePushBatching: + enabled: true + batchSize: 1000 # max rows per batch + batchIntervalSeconds: 10 # flush interval in seconds +``` + +| Field | Type | Description | +|-------|------|-------------| +| `enabled` | bool | Activates batching | +| `batchSize` | int | Max rows per batch; flush when reached | +| `batchIntervalSeconds` | int | Flush interval even when batch is not full | + +--- + +## MCP (Model Context Protocol) + +MCP mounts LLM-agent-compatible tool endpoints alongside the existing REST API on port 6566. +The REST API is not replaced — MCP is additive. + +The operator writes `feature_server.type: mcp` into `feature_store.yaml` only when +`serving.mcp.enabled: true`. Setting `enabled: false` reverts to `type: local`. + +```yaml +services: + onlineStore: + server: {} + serving: + mcp: + enabled: true + serverName: feast-mcp-server + serverVersion: "1.0.0" + transport: sse # "sse" (default) or "http" +``` + +| Field | Type | Default | Description | +|-------|------|---------|-------------| +| `enabled` | bool | — | Must be `true`; `false` keeps `type: local` | +| `serverName` | string | `feast-mcp-server` | Name advertised to MCP clients | +| `serverVersion` | string | `1.0.0` | Version advertised to MCP clients | +| `transport` | string | `sse` | `sse` (SSE-based) or `http` (Streamable HTTP) | + +MCP is mounted at `/mcp` on port 6566 — no additional Kubernetes Service is created. + +> **Dependency**: the feature server image must include `feast[mcp]` (`fastapi-mcp`). +> Without it the server starts normally but MCP routes are not registered. + +--- + +## `serving` vs `server` — summary + +| Capability | `server.*` block | `serving.*` block | +|-----------|-----------------|------------------| +| Enable the server | `server: {}` | — | +| Log level | `server.logLevel` | — | +| Workers / gunicorn | `server.workerConfigs` | — | +| TLS | `server.tls` | — | +| Env vars / image | `server.env`, `server.image` | — | +| Metrics (simple) | `server.metrics: true` | — | +| Metrics (per-category) | — | `serving.metrics.categories` | +| Offline push batching | — | `serving.offlinePushBatching` | +| MCP | — | `serving.mcp` | + +--- + +## See also + +- [API reference — `ServerConfigs`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#serverconfigs) +- [API reference — `ServingConfig`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#servingconfig) +- [Sample: serving + metrics + offline push batching](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_serving.yaml) +- [Sample: MCP](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_mcp.yaml) +- [Sample: log levels](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_services_loglevel.yaml) +- [Feast SDK — Python Feature Server](../reference/feature-servers/python-feature-server.md) +- [Online Server Performance Tuning](../online-server-performance-tuning.md) diff --git a/docs/how-to-guides/feast-operator/04-registry-topology.md b/docs/how-to-guides/feast-operator/04-registry-topology.md new file mode 100644 index 00000000000..32741cd68ee --- /dev/null +++ b/docs/how-to-guides/feast-operator/04-registry-topology.md @@ -0,0 +1,191 @@ +# Guide 4 — Registry Topology + +The Feast registry stores metadata about feature views, entities, and feature services. The +operator supports three topology options: + +| Topology | Use case | +|----------|----------| +| **Local** (file or DB) | Self-contained deployment; registry runs alongside other services | +| **Local + server** | Local registry exposed as a gRPC / REST server for remote clients | +| **Remote** | Multiple `FeatureStore` CRs share a single registry managed by another CR | + +--- + +## Local registry + +### File-backed (default) + +```yaml +services: + registry: + local: + persistence: + file: + path: registry.db + pvc: + create: {} + mountPath: /data/registry +``` + +### DB-backed (SQL / Snowflake) + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: feast-data-stores +stringData: + sql: | + path: postgresql+psycopg://feast:feast@postgres:5432/feast #pragma: allowlist secret + cache_ttl_seconds: 60 +--- +services: + registry: + local: + persistence: + store: + type: sql + secretRef: + name: feast-data-stores # reads key "sql" +``` + +### Exposing the registry as a server + +Add `server: {}` under `registry.local` to expose it on port **6570**: + +```yaml +services: + registry: + local: + server: {} # exposes gRPC on 6570 + persistence: + store: + type: sql + secretRef: + name: feast-data-stores +``` + +The registry server also supports REST and gRPC independently: + +```yaml +registry: + local: + server: + restAPI: true # enable REST API (default: true when server is set) + grpc: true # enable gRPC (default: true when server is set) +``` + +--- + +## Remote registry + +A remote registry lets multiple `FeatureStore` CRs (e.g. in different namespaces or teams) +share a single registry. One CR owns the registry; the others point at it. + +### Using a hostname + +Point at any existing Feast registry server endpoint: + +```yaml +services: + registry: + remote: + hostname: feast-registry.feast-system.svc.cluster.local:6570 +``` + +### Using `feastRef` (recommended for operator-managed registries) + +`feastRef` lets one `FeatureStore` CR reference another CR's registry without hard-coding +hostnames. The operator resolves the Service name automatically: + +```yaml +# CR that owns the registry (in namespace "feast-system") +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: registry-owner + namespace: feast-system +spec: + feastProject: shared_project + services: + registry: + local: + server: {} + persistence: + store: + type: sql + secretRef: + name: feast-data-stores +``` + +```yaml +# CR that consumes the shared registry (in namespace "team-a") +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: team-a-store + namespace: team-a +spec: + feastProject: shared_project + services: + registry: + remote: + feastRef: + name: registry-owner + namespace: feast-system # omit if same namespace +``` + +### Remote registry with TLS + +If the remote registry server uses TLS, provide the CA certificate so clients can verify it: + +```yaml +services: + registry: + remote: + feastRef: + name: registry-owner + namespace: feast-system + tls: + configMapRef: + name: registry-ca-cert # ConfigMap containing the CA cert + certKeyName: ca.crt # key inside the ConfigMap (default: ca.crt) +``` + +--- + +## All-remote topology + +For teams that deploy services independently, all services can use remote endpoints: + +```yaml +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: client-store +spec: + feastProject: my_project + services: + offlineStore: + remote: + hostname: feast-offline.feast-system.svc.cluster.local:8815 + onlineStore: + remote: + hostname: feast-online.feast-system.svc.cluster.local:6566 + registry: + remote: + feastRef: + name: central-registry + namespace: feast-system +``` + +--- + +## See also + +- [API reference — `RegistryConfig`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#registryconfig) +- [API reference — `LocalRegistryConfig`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#localregistryconfig) +- [API reference — `RemoteRegistryConfig`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#remoteregistryconfig) +- [Sample: all remote servers](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_all_remote_servers.yaml) +- [Sample: DB persistence](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_db_persistence.yaml) +- [Feast SDK — Registries](../reference/registries/) diff --git a/docs/how-to-guides/feast-operator/05-security.md b/docs/how-to-guides/feast-operator/05-security.md new file mode 100644 index 00000000000..4c28aba9805 --- /dev/null +++ b/docs/how-to-guides/feast-operator/05-security.md @@ -0,0 +1,190 @@ +# Guide 5 — Security + +The operator supports two authorization models via `spec.authz`, plus TLS for all servers. +Authorization is optional — omitting `authz` deploys Feast with no access control. + +--- + +## Kubernetes RBAC authorization + +Kubernetes RBAC authorization uses ServiceAccount tokens. The operator creates +`ClusterRole`s for each named role you declare and binds them to ServiceAccounts. Feast +servers enforce these roles on every API call. + +```yaml +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: sample-rbac +spec: + feastProject: feast_rbac + authz: + kubernetes: + roles: + - feast-writer # created as a ClusterRole + - feast-reader + services: + offlineStore: + server: {} + onlineStore: + server: {} + registry: + local: + server: {} +``` + +The operator creates `ClusterRole` resources named after each entry in `roles`. Bind them +to subjects using standard Kubernetes `ClusterRoleBinding` or `RoleBinding` resources. + +> Kubernetes auth requires all services to be exposed as servers (the controller rejects +> partial configurations where some services are local while RBAC is enabled). + +**SDK docs**: [Feast RBAC](../reference/auth/rbac.md) + +--- + +## OIDC authorization + +OIDC authorization validates Bearer tokens against an OIDC provider (Keycloak, Dex, etc.). + +### Secret format + +Create a Secret with the OIDC client credentials: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: oidc-secret +stringData: + client_id: + auth_discovery_url: https://keycloak.example.com/realms/feast/.well-known/openid-configuration + client_secret: + username: # used for client-credentials flow + password: +``` + +Reference the Secret from the CR: + +```yaml +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: sample-oidc +spec: + feastProject: my_project + authz: + oidc: + secretRef: + name: oidc-secret +``` + +### Advanced OIDC options + +```yaml +authz: + oidc: + secretRef: + name: oidc-secret + secretKeyName: client_id # override the default Secret key name + tokenEnvVar: FEAST_TOKEN # env var from which servers read the Bearer token + verifySSL: false # disable SSL verification (dev only) + caCertConfigMap: oidc-ca-cert # ConfigMap with CA cert for SSL verification +``` + +**SDK docs**: [Feast OIDC Auth](../reference/auth/oidc.md) + +--- + +## TLS for servers + +Each server accepts a `tls` block pointing to a Kubernetes Secret that holds the TLS +certificate and key. + +### Creating a TLS Secret + +```sh +kubectl create secret tls feast-tls \ + --cert=path/to/tls.crt \ + --key=path/to/tls.key \ + -n +``` + +### Applying TLS to servers + +```yaml +services: + onlineStore: + server: + tls: + secretRef: + name: feast-tls + offlineStore: + server: + tls: + secretRef: + name: feast-tls + registry: + local: + server: + tls: + secretRef: + name: feast-tls +``` + +Each service can use different TLS Secrets. + +### Custom certificate key names + +By default the operator looks for keys `tls.crt` and `tls.key`. Override with: + +```yaml +tls: + secretRef: + name: feast-tls + certKeyName: server.crt # default: tls.crt +``` + +### mTLS — providing a CA certificate + +For mutual TLS (client certificate verification), supply a CA cert via a ConfigMap: + +```yaml +tls: + secretRef: + name: feast-tls + caCertConfigMapRef: + name: client-ca-cert + certKeyName: tls.crt +``` + +--- + +## OpenShift non-TLS mode + +On OpenShift, services are typically accessed via Routes with TLS termination at the edge. +In this case it is common to run the Feast servers without internal TLS: + +```yaml +# See config/samples/v1_featurestore_all_openshift_non_tls.yaml +services: + onlineStore: + server: {} # no tls block + offlineStore: + server: {} + registry: + local: + server: {} +``` + +--- + +## See also + +- [API reference — `AuthzConfig`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#authzconfig) +- [API reference — `TlsConfigs`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#tlsconfigs) +- [Sample: Kubernetes auth](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_kubernetes_auth.yaml) +- [Sample: OIDC auth](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_oidc_auth.yaml) +- [Sample: Postgres with TLS volumes](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_postgres_db_volumes_tls.yaml) +- [Sample: OpenShift non-TLS](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_all_openshift_non_tls.yaml) +- [Feast SDK — Auth Overview](../reference/auth/) diff --git a/docs/how-to-guides/feast-operator/06-batch-and-jobs.md b/docs/how-to-guides/feast-operator/06-batch-and-jobs.md new file mode 100644 index 00000000000..fd513168c54 --- /dev/null +++ b/docs/how-to-guides/feast-operator/06-batch-and-jobs.md @@ -0,0 +1,266 @@ +# Guide 6 — Batch Engine & Scheduled Jobs + +This guide covers two related top-level spec fields: + +- **`spec.batchEngine`** — override the compute engine used for materialization +- **`spec.cronJob`** — schedule periodic `feast materialize-incremental` (or any command) as a Kubernetes `CronJob` + +--- + +## Batch Engine (`spec.batchEngine`) + +By default, Feast runs materialization using the **local** batch engine (in-process Python). +For large feature sets you can point the operator at a Spark, Ray, or other supported engine +via a Kubernetes ConfigMap. + +### ConfigMap format + +Create a ConfigMap whose value is a YAML snippet identical to the `batch_engine` section of +`feature_store.yaml`. Include the `type:` key and all engine-specific options: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: feast-batch-engine +data: + config: | + type: spark + spark_conf: + spark.master: k8s://https://kubernetes.default.svc + spark.kubernetes.namespace: feast + spark.kubernetes.container.image: ghcr.io/feast-dev/feast-spark:latest + spark.executor.instances: "2" + spark.executor.memory: 4g + spark.driver.memory: 2g +``` + +Reference the ConfigMap from the CR: + +```yaml +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: sample-spark +spec: + feastProject: my_project + batchEngine: + configMapRef: + name: feast-batch-engine # ConfigMap name + configMapKey: config # key inside the ConfigMap (default: "config") +``` + +### Engine types + +| `type` | Notes | +|--------|-------| +| `local` | Default; in-process Python, no extra infra | +| `spark` | Apache Spark; requires a Spark operator or standalone cluster | +| `ray` | Ray cluster; requires a Ray operator | +| `bytewax` | Bytewax streaming engine | +| `snowflake.engine` | Snowflake Snowpark compute | + +> For engine-specific YAML options (Spark conf, Ray address, etc.) see the +> [Feast SDK — Compute Engine](../reference/compute-engine/) docs. + +--- + +## Scheduled Materialization (`spec.cronJob`) + +The operator can deploy a Kubernetes `CronJob` that runs `feast materialize-incremental` +(or any custom command) on a schedule. This is the recommended way to keep your online store +fresh without managing an external job scheduler. + +### CronJob image resolution + +The CronJob container image is resolved through the following priority chain: + +1. **`cronJob.containerConfigs.image` in the CR** — per-CronJob override +2. **`RELATED_IMAGE_CRON_JOB` env var on the operator pod** — cluster-wide default set by OLM/platform (default: `quay.io/openshift/origin-cli:4.17`) + +```sh +# Override cluster-wide for all CronJobs +kubectl set env deployment/feast-operator-controller-manager \ + RELATED_IMAGE_CRON_JOB=my-registry.example.com/tools/cli:latest \ + -n feast-operator-system +``` + +### Minimal example — nightly materialization + +```yaml +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: feast-production +spec: + feastProject: my_project + cronJob: + schedule: "0 2 * * *" # every day at 02:00 UTC + containerConfigs: + image: quay.io/feastdev/feature-server:0.62.0 +``` + +The CronJob runs the default `feast materialize-incremental` command using the same +`feature_store.yaml` that the operator generated for this `FeatureStore`. + +### Custom command + +Override the container command to run any Feast CLI command: + +```yaml +cronJob: + schedule: "*/30 * * * *" + containerConfigs: + image: quay.io/feastdev/feature-server:0.62.0 + commands: + - feast + - materialize-incremental + - "2099-01-01T00:00:00" # materialize up to a fixed end time +``` + +Or run a Python script instead: + +```yaml +containerConfigs: + commands: + - python + - /app/materialize.py +``` + +### Time zone + +```yaml +cronJob: + schedule: "0 3 * * *" + timeZone: "Asia/Kolkata" # defaults to the kube-controller-manager time zone +``` + +### Concurrency policy + +```yaml +cronJob: + schedule: "0 * * * *" + concurrencyPolicy: Forbid # Allow | Forbid | Replace + startingDeadlineSeconds: 300 # skip if missed by > 5 minutes +``` + +### Job history retention + +```yaml +cronJob: + schedule: "0 2 * * *" + successfulJobsHistoryLimit: 3 # keep last 3 successful runs + failedJobsHistoryLimit: 5 # keep last 5 failed runs +``` + +### Suspend a CronJob + +To temporarily pause scheduled runs without deleting the `CronJob`: + +```yaml +cronJob: + schedule: "0 2 * * *" + suspend: true +``` + +### Resource requests for the job pod + +```yaml +cronJob: + schedule: "0 2 * * *" + containerConfigs: + image: quay.io/feastdev/feature-server:0.62.0 + resources: + requests: + cpu: "1" + memory: "2Gi" + limits: + cpu: "4" + memory: "8Gi" +``` + +### Environment variables and secrets in the job pod + +```yaml +cronJob: + schedule: "0 2 * * *" + containerConfigs: + image: quay.io/feastdev/feature-server:0.62.0 + envFrom: + - secretRef: + name: feast-data-stores + env: + - name: FEAST_USAGE + value: "false" +``` + +### Advanced job spec + +```yaml +cronJob: + schedule: "0 2 * * *" + jobSpec: + parallelism: 1 + completions: 1 + activeDeadlineSeconds: 3600 # abort if job takes more than 1 hour + backoffLimit: 2 # retry up to 2 times on failure + podTemplateAnnotations: + prometheus.io/scrape: "false" + containerConfigs: + image: quay.io/feastdev/feature-server:0.62.0 +``` + +### Full `cronJob` field reference + +| Field | Type | Default | Description | +|-------|------|---------|-------------| +| `schedule` | string | — | Cron expression (required) | +| `timeZone` | string | kube-controller-manager TZ | IANA time zone name | +| `concurrencyPolicy` | string | `Allow` | `Allow` / `Forbid` / `Replace` | +| `suspend` | bool | `false` | Suspend future runs | +| `startingDeadlineSeconds` | int64 | — | Abort if start missed by this many seconds | +| `successfulJobsHistoryLimit` | int32 | — | Successful job history to keep | +| `failedJobsHistoryLimit` | int32 | — | Failed job history to keep | +| `annotations` | map | — | CronJob metadata annotations | +| `jobSpec.parallelism` | int32 | 1 | Job pod parallelism | +| `jobSpec.completions` | int32 | 1 | Required completions | +| `jobSpec.activeDeadlineSeconds` | int64 | — | Max job duration | +| `jobSpec.backoffLimit` | int32 | — | Retry limit | +| `containerConfigs.image` | string | operator default | Feature server image | +| `containerConfigs.commands` | []string | `feast materialize-incremental` | Override container command | +| `containerConfigs.resources` | ResourceRequirements | — | CPU/memory requests and limits | +| `containerConfigs.env` / `envFrom` | — | — | Environment variables | + +--- + +## Combining batchEngine + cronJob + +Use both together to run scheduled Spark-based materialization: + +```yaml +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: feast-spark +spec: + feastProject: my_project + batchEngine: + configMapRef: + name: feast-spark-engine + cronJob: + schedule: "0 1 * * *" + concurrencyPolicy: Forbid + containerConfigs: + image: quay.io/feastdev/feature-server:0.62.0 + resources: + requests: + memory: "4Gi" +``` + +--- + +## See also + +- [API reference — `BatchEngineConfig`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#batchengineconfig) +- [API reference — `FeastCronJob`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#feastcronjob) +- [Feast SDK — Compute Engine](../reference/compute-engine/) diff --git a/docs/how-to-guides/feast-operator/07-openlineage-and-materialization.md b/docs/how-to-guides/feast-operator/07-openlineage-and-materialization.md new file mode 100644 index 00000000000..72b2fe92a7e --- /dev/null +++ b/docs/how-to-guides/feast-operator/07-openlineage-and-materialization.md @@ -0,0 +1,218 @@ +# Guide 7 — OpenLineage & Materialization + +Both `spec.openlineage` and `spec.materialization` are written into `feature_store.yaml` +for **all** service pods — they apply to the online server, offline server, registry, and +materialization jobs alike. + +--- + +## OpenLineage Data Lineage (`spec.openlineage`) + +OpenLineage emits data lineage events during `feast apply` (registry changes) and +materialization. Events go outbound from Feast pods to your OpenLineage-compatible backend +([Marquez](https://marquezproject.ai), any OpenLineage HTTP endpoint, Kafka, or a file). +No inbound ports or additional Kubernetes Services are required. + +> **Dependency**: the Feast image must include `feast[openlineage]` (`openlineage-python`). + +### HTTP transport (Marquez) + +```yaml +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: sample-openlineage +spec: + feastProject: my_project + openlineage: + enabled: true + transportType: http + transportUrl: "http://marquez.feast.svc.cluster.local:5000" + transportEndpoint: "api/v1/lineage" + extraConfig: + namespace: "my-feast-project" + producer: "feast-operator" + emit_on_apply: "true" + emit_on_materialize: "true" +``` + +### HTTP with API key authentication + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: openlineage-secret + namespace: feast +stringData: + api_key: "" +--- +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: sample-openlineage-auth + namespace: feast +spec: + feastProject: my_project + openlineage: + enabled: true + transportType: http + transportUrl: "https://marquez.example.com" + transportEndpoint: "api/v1/lineage" + apiKeySecretRef: + name: openlineage-secret # Secret must contain key "api_key" + extraConfig: + namespace: "my-feast-project" + emit_on_apply: "true" + emit_on_materialize: "true" +``` + +The operator reads the `api_key` value from the Secret and writes it into +`feature_store.yaml`. The Secret must be in the same namespace as the `FeatureStore`. + +### Kafka transport + +```yaml +openlineage: + enabled: true + transportType: kafka + extraConfig: + namespace: "my-feast-project" + emit_on_apply: "true" + emit_on_materialize: "true" + bootstrap_servers: "kafka.svc:9092" + topic: "openlineage" + sasl_mechanism: "PLAIN" +``` + +### Console transport (development) + +Events are printed to stdout — useful for verifying integration without a backend: + +```yaml +openlineage: + enabled: true + transportType: console + extraConfig: + emit_on_apply: "true" + emit_on_materialize: "true" +``` + +### Field reference + +| Field | Type | Description | +|-------|------|-------------| +| `enabled` | bool | Activates OpenLineage. Must be `true` | +| `transportType` | string | `http` / `console` / `file` / `kafka` | +| `transportUrl` | string | Base URL for HTTP transport | +| `transportEndpoint` | string | API path appended to `transportUrl` | +| `apiKeySecretRef.name` | string | Name of a Secret containing key `api_key` | +| `extraConfig` | map[string]string | Additional settings (see below) | + +### `extraConfig` keys + +Values that are `"true"` or `"false"` are automatically coerced to native YAML booleans +so that Feast's Pydantic `StrictBool` validators accept them. + +| Key | Type | Description | +|-----|------|-------------| +| `namespace` | string | OpenLineage namespace for emitted events | +| `producer` | string | Producer identifier in emitted events | +| `emit_on_apply` | bool string | Emit events on `feast apply` | +| `emit_on_materialize` | bool string | Emit events on materialization | +| `bootstrap_servers` | string | Kafka: comma-separated broker addresses | +| `topic` | string | Kafka: target topic name | +| `sasl_mechanism` | string | Kafka: SASL mechanism (e.g. `PLAIN`, `SCRAM-SHA-256`) | +| `file_path` | string | File transport: path to write lineage events | + +--- + +## Materialization (`spec.materialization`) + +Controls how features are written to the online store during materialization jobs. Settings +are written into `feature_store.yaml` for all pods. + +```yaml +spec: + materialization: + onlineWriteBatchSize: 10000 + extraConfig: + pull_latest_features: "false" +``` + +### `onlineWriteBatchSize` + +Limits the number of rows written per batch during materialization. Without this, all rows +for a feature view are written in a single batch — this can cause OOM for large feature views. + +- Supported engines: **local**, **Spark**, **Ray** +- Minimum value: **1** (enforced by CRD validation) + +```yaml +materialization: + onlineWriteBatchSize: 10000 # 10 k rows per batch +``` + +### `extraConfig` + +Passes additional `MaterializationConfig` settings inline. Boolean strings +(`"true"` / `"false"`) are coerced to native YAML booleans. + +```yaml +materialization: + extraConfig: + pull_latest_features: "false" # only materialize the latest value per entity +``` + +| Key | Type | Description | +|-----|------|-------------| +| `pull_latest_features` | bool string | When `"true"`, only the latest feature value per entity is materialized. Default is engine-dependent | + +--- + +## Full example + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: openlineage-secret + namespace: feast +stringData: + api_key: "" +--- +apiVersion: feast.dev/v1 +kind: FeatureStore +metadata: + name: feast-production + namespace: feast +spec: + feastProject: my_project + materialization: + onlineWriteBatchSize: 10000 + openlineage: + enabled: true + transportType: http + transportUrl: "http://marquez.feast.svc.cluster.local:5000" + transportEndpoint: "api/v1/lineage" + apiKeySecretRef: + name: openlineage-secret + extraConfig: + namespace: "my-feast-project" + producer: "feast-operator" + emit_on_apply: "true" + emit_on_materialize: "true" + services: + onlineStore: + server: {} +``` + +--- + +## See also + +- [API reference — `OpenLineageConfig`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#openlineageconfig) +- [API reference — `MaterializationConfig`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#materializationconfig) +- [Sample: materialization + openlineage](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/v1_featurestore_materialization_openlineage.yaml) +- [Feast SDK — OpenLineage](../reference/openlineage.md) +- [Guide 6 — Batch Engine & Scheduled Jobs](06-batch-and-jobs.md) diff --git a/docs/how-to-guides/feast-operator/README.md b/docs/how-to-guides/feast-operator/README.md new file mode 100644 index 00000000000..26e515f309f --- /dev/null +++ b/docs/how-to-guides/feast-operator/README.md @@ -0,0 +1,54 @@ +# Feast Operator Configuration Guides + +These guides cover the `FeatureStore` Custom Resource (CR) from an **operator perspective** — +what to put in the CR, how the operator translates it into Kubernetes objects, and where to +look for store-specific YAML options in the Feast SDK docs. + +## How the docs are organised + +| Layer | Source | What it covers | +|-------|--------|----------------| +| **CR field reference** | [`api/markdown/ref.md`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md) | Every field, type, validation constraint — auto-generated from Go types | +| **Operator guides** (this folder) | Narrative how-tos | CR→K8s behavior, Secret formats, PVC patterns, operator-specific trade-offs | +| **Feast SDK reference** | [`feast/docs/reference/`](../reference/) | Store-specific `feature_store.yaml` options (online/offline store drivers, registry drivers, etc.) | +| **Sample CRs** | [`config/samples/`](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/config/samples/) | Copy-paste starting points for common configurations | + +> **Rule of thumb**: if you need to know *what to put in the CR and why*, read the operator +> guides. If you need to know *which keys a particular store driver accepts*, read the Feast +> SDK docs for that store. + +--- + +## Guide index + +| # | Guide | Topic | +|---|-------|-------| +| 1 | [Project Provisioning](01-project-provisioning.md) | `feastProjectDir`: cloning a git repo vs `feast init` templates | +| 2 | [Persistence](02-persistence.md) | File (path + PVC) vs DB store for offline/online/registry; Secret format | +| 3 | [Serving & Observability](03-serving-and-observability.md) | Feature server workers, log level, Prometheus metrics, offline push batching, MCP | +| 4 | [Registry Topology](04-registry-topology.md) | Local vs remote registry, cross-namespace `feastRef`, remote TLS | +| 5 | [Security](05-security.md) | Kubernetes RBAC roles vs OIDC auth; TLS for all servers | +| 6 | [Batch Jobs](06-batch-and-jobs.md) | `batchEngine` ConfigMap contract, `cronJob` for scheduled materialization | +| 7 | [OpenLineage & Materialization](07-openlineage-and-materialization.md) | Lineage transports, API key Secret, materialization batch size | + +--- + +## Quick-start: which guide do I need? + +- **"How do I point the operator at my existing git feature repo?"** → [Guide 1](01-project-provisioning.md) +- **"How do I wire Postgres/Redis/DuckDB as my store?"** → [Guide 2](02-persistence.md) +- **"How do I enable Prometheus scraping for the feature server?"** → [Guide 3](03-serving-and-observability.md) +- **"How do I make all services share a remote registry?"** → [Guide 4](04-registry-topology.md) +- **"How do I enable Kubernetes RBAC or OIDC auth?"** → [Guide 5](05-security.md) +- **"How do I schedule nightly materialization?"** → [Guide 6](06-batch-and-jobs.md) +- **"How do I send lineage events to Marquez?"** → [Guide 7](07-openlineage-and-materialization.md) +- **"What are all valid fields on `ServingConfig`?"** → [API ref](https://github.com/feast-dev/feast/blob/stable/infra/feast-operator/docs/api/markdown/ref.md#servingconfig) + +--- + +## Scaling & HA + +Horizontal scaling, HPA, PodDisruptionBudget, affinity, and topology spread constraints are +covered in the main Feast docs: + +→ [Horizontal Scaling with the Feast Operator](../scaling-feast.md#horizontal-scaling-with-the-feast-operator) diff --git a/docs/how-to-guides/online-server-performance-tuning.md b/docs/how-to-guides/online-server-performance-tuning.md index f942c94944b..34508ff6ce4 100644 --- a/docs/how-to-guides/online-server-performance-tuning.md +++ b/docs/how-to-guides/online-server-performance-tuning.md @@ -31,6 +31,10 @@ When the server processes a `get_online_features()` call, it groups the requeste **Guideline:** For features that share the same entity key and are frequently requested together, consolidate them into a **single feature view**. This reduces the number of store round-trips per request. Split feature views only when features have different entities, different materialization schedules, or different data source update frequencies. +{% hint style="info" %} +**Redis exception:** The Redis online store overrides `get_online_features()` to batch all `HMGET` commands across every feature view into a **single pipeline execution**. Because all feature views for the same entity share one Redis hash key, the number of Redis round trips is always **1**, regardless of how many feature views the request touches. This means the "fewer feature views" guideline is less critical for Redis than for other stores — but consolidating feature views still reduces serialization and protobuf overhead at the application layer. +{% endhint %} + ### Feature services are free A [Feature Service](../getting-started/concepts/feature-retrieval.md) is a named collection of feature references — it's a convenience grouping, not a separate storage or execution unit. Using a feature service adds only a registry lookup (cached) compared to listing features individually. There is no performance penalty for using feature services, and they are the recommended way to define stable, versioned feature sets for production models. @@ -229,7 +233,7 @@ The online store is the single largest factor in `get_online_features()` latency | Store | Typical p50 latency | Async read | Best for | Key trade-off | | ----- | ------------------- | ---------- | -------- | ------------- | -| **Redis / Dragonfly** | < 1 ms | No (threadpool) | Ultra-low latency, high throughput | Requires in-memory capacity for your dataset | +| **Redis / Dragonfly** | < 1 ms | No (threadpool) | Ultra-low latency, high throughput; all FV reads batched into 1 pipeline | Requires in-memory capacity for your dataset | | **DynamoDB** | 2–5 ms | Yes | Serverless, auto-scaling on AWS | Pay-per-request cost; batch API limits (100 items) | | **PostgreSQL** | 3–10 ms | No (threadpool) | Teams with existing Postgres infra | Connection pooling needed at scale | | **MongoDB** | 2–5 ms | Yes | Flexible schema, async-native | Requires index tuning for large datasets | @@ -259,7 +263,7 @@ The feature server can read from the online store using either an **async** or * | **DynamoDB** | Yes | Yes | Uses `aiobotocore` for non-blocking I/O | | **MongoDB** | Yes | Yes | Uses `motor` (async MongoDB driver) | | **PostgreSQL** | Implemented | No | Has `online_read_async` but does not yet advertise via `async_supported`; uses sync/threadpool path | -| **Redis** | Implemented | No | Has `online_read_async` but does not yet advertise via `async_supported`; uses sync/threadpool path | +| **Redis** | Implemented | **Yes** | `online_read_async` and `online_write_batch_async` both implemented; uses sync/threadpool path for `get_online_features` (overridden with batched single pipeline) | | All others | No | No | Fall back to sync with `run_in_threadpool()` | **When async matters most:** @@ -329,12 +333,39 @@ online_store: connection_string: "redis-cluster.internal:6379,ssl=true" redis_type: redis_cluster key_ttl_seconds: 604800 + skip_dedup: false # set true for initial bulk loads to halve write round trips ``` - Use `redis_cluster` for horizontal partitioning across shards. -- Set `key_ttl_seconds` to auto-expire stale feature data, keeping memory usage bounded. +- Set `key_ttl_seconds` to auto-expire stale feature data, keeping memory usage bounded. This is a **key-level** TTL — it expires the entire entity hash (all feature views for that entity) together. - Ensure the Redis instance is in the **same availability zone** as the feature server pods to minimize network round-trips. +#### Batched multi-feature-view reads + +The Redis online store overrides `get_online_features()` to issue all `HMGET` commands — across every feature view in the request — in a **single pipeline execution**. This reduces Redis round trips from `N` (one per feature view) to `1` regardless of request size. + +| Feature views | Round trips (other stores) | Round trips (Redis) | +| :---: | :---: | :---: | +| 1 | 1 | 1 | +| 5 | 5 | **1** | +| 10 | 10 | **1** | +| 20 | 20 | **1** | + +This means the latency cost of adding feature views to a Redis-backed request is primarily **serialization and protobuf overhead** at the application layer, not Redis network latency. + +#### Write throughput: `skip_dedup` + +For initial bulk loads or append-only materialization pipelines: + +```yaml +online_store: + type: redis + connection_string: "localhost:6379" + skip_dedup: true +``` + +With `skip_dedup: true`, `online_write_batch()` skips the existing-timestamp read pipeline and writes all values directly in a single pass, halving write round trips. Use only when you can guarantee write ordering — under concurrent writers, an older record can overwrite a newer one. + ### Cassandra / ScyllaDB tuning Cassandra and ScyllaDB share the same Feast connector. The key read-path knobs are concurrency and data-center-aware routing: @@ -421,7 +452,7 @@ Different online stores have different optimal batch sizes for `get_online_featu | Store | Default batch size | Max batch size | Recommendation | | ----- | ------------------ | -------------- | -------------- | | DynamoDB | 100 | 100 (API limit) | Keep at 100; tune `max_read_workers` for parallelism | -| Redis | N/A (pipelined) | N/A | Redis pipelines all keys in one round-trip; no batch tuning needed | +| Redis | N/A (pipelined) | N/A | All entity keys **and** all feature views are batched into a single pipeline; no batch tuning needed | | PostgreSQL | N/A (single query) | N/A | Single `SELECT ... WHERE key IN (...)` query; tune connection pool instead | Profile your workload by measuring `feast_feature_server_online_store_read_duration_seconds` (see [Metrics setup](#metrics-setup-prometheus--opentelemetry)) across different entity counts to find the sweet spot. @@ -980,6 +1011,72 @@ registry: --- +## Materialization write performance + +Materialization (`feast materialize` / `feast materialize-incremental`) reads features from the offline store and writes them to the online store. For large feature views, two common bottlenecks arise: **memory exhaustion** during proto conversion and **write throughput** to the online store. + +### Memory: `online_write_batch_size` + +By default, Feast converts the entire Arrow table returned by the offline store into Python protobuf objects in a single pass before writing to the online store. For datasets with millions of rows this can consume tens of gigabytes of memory on the materialization worker. + +Set `online_write_batch_size` in `feature_store.yaml` to break the write into manageable chunks: + +```yaml +materialization: + online_write_batch_size: 10000 # rows per write batch +``` + +Each chunk is independently converted and written, keeping peak memory proportional to the batch size rather than the full dataset. This is supported by the **local, Spark, and Ray** compute engines. + +| Dataset size | Without batching | With `online_write_batch_size: 10000` | +| --- | --- | --- | +| 1 M rows (100 bytes/row) | ~100 MB peak | ~1 MB peak | +| 10 M rows | ~1 GB peak | ~1 MB peak | +| 100 M rows | OOM / swap | ~1 MB peak | + +**Choosing a value:** + +- **Larger batches** (50 000+): fewer write calls to the online store, lower overhead per row — good when worker memory allows. +- **Smaller batches** (1 000–5 000): lower peak memory — necessary for memory-constrained workers or very wide feature views (many features per row). +- For **Redis**: pipeline overhead per batch is negligible; a batch size of 10 000–50 000 is a good starting point. +- For **DynamoDB**: each batch maps to one or more `BatchWriteItem` calls (max 25 items per call); a larger `online_write_batch_size` amortizes the per-call overhead but doesn't change the 25-item DynamoDB limit. + +See the [feature-store-yaml reference](../reference/feature-repository/feature-store-yaml.md#online_write_batch_size) for the complete option documentation. + +### Throughput: parallel feature view materialization + +Each feature view in a `feast materialize` call is materialized sequentially by the local engine. To materialize multiple feature views in parallel, use a job orchestrator (Airflow, Kubernetes Jobs) and materialize one feature view per job: + +```bash +# Airflow / cron: one task per feature view +feast materialize-incremental $(date -u +"%Y-%m-%dT%H:%M:%S") \ + --views driver_stats +``` + +Alternatively, use the **Spark** or **Ray** compute engines which distribute the work across a cluster. + +### Redis: combine with `skip_dedup` for bulk reloads + +When performing a full historical reload into Redis (not an incremental update), combine `online_write_batch_size` with `skip_dedup` for maximum throughput: + +```yaml +materialization: + online_write_batch_size: 50000 # large chunks — memory is bounded + +online_store: + type: redis + connection_string: "redis-cluster.internal:6379" + skip_dedup: true # skip per-row timestamp check — halves write round trips +``` + +`skip_dedup: true` eliminates the timestamp-read pipeline before each write (see [Redis tuning](#redis-tuning)), while `online_write_batch_size` prevents the write worker from converting the entire dataset into memory at once. + +{% hint style="warning" %} +Reset `skip_dedup` to `false` (or remove it) after the bulk reload. Under normal incremental materialization, deduplication prevents older feature values from overwriting newer ones. +{% endhint %} + +--- + ## Further reading - [Scaling Feast](./scaling-feast.md) — Horizontal scaling, HPA, KEDA, and HA in detail @@ -987,5 +1084,6 @@ registry: - [OpenTelemetry Integration](../getting-started/components/open-telemetry.md) — Full OTEL setup with Prometheus Operator - [DynamoDB Online Store](../reference/online-stores/dynamodb.md) — Store-specific configuration and performance tuning - [PostgreSQL Online Store](../reference/online-stores/postgres.md) — Connection pooling and SSL configuration -- [Redis Online Store](../reference/online-stores/redis.md) — Cluster mode, Sentinel, and TTL configuration +- [Redis Online Store](../reference/online-stores/redis.md) — Cluster mode, Sentinel, TTL configuration, and batched reads - [On Demand Feature Views](../reference/beta-on-demand-feature-view.md) — Transformation modes and write-time transforms +- [feature_store.yaml reference](../reference/feature-repository/feature-store-yaml.md) — Full configuration reference including `materialization` options diff --git a/docs/how-to-guides/production-deployment-topologies.md b/docs/how-to-guides/production-deployment-topologies.md new file mode 100644 index 00000000000..ee8bb49be54 --- /dev/null +++ b/docs/how-to-guides/production-deployment-topologies.md @@ -0,0 +1,1529 @@ +# Feast Production Deployment Topologies + +## Table of Contents + +* [Overview](#overview) +* [1. Minimal Production](#1-minimal-production) +* [2. Standard Production (Recommended)](#2-standard-production-recommended) +* [3. Enterprise Production](#3-enterprise-production) + * [Isolated Registries (per namespace)](#architecture--isolated-registries-per-namespace) + * [Shared Registry (cross-namespace)](#architecture--shared-registry-cross-namespace) + * [Reliability & Disaster Recovery](#reliability--disaster-recovery) +* [Feast Permissions and RBAC](#feast-permissions-and-rbac) + * [Actions](#actions) + * [Policy types](#policy-types) + * [Examples](#example-role-based-permissions) + * [Authorization configuration](#authorization-configuration) +* [Infrastructure-Specific Recommendations](#infrastructure-specific-recommendations) + * [AWS / EKS / ROSA](#aws--eks--rosa) + * [GCP / GKE](#gcp--gke) + * [On-Premise / OpenShift](#on-premise--openshift--self-managed-kubernetes) +* [Air-Gapped / Disconnected Environments](#air-gapped--disconnected-environment-deployments) +* [Hybrid Store Configuration](#hybrid-store-configuration) + * [Hybrid online store](#hybrid-online-store) + * [Hybrid offline store](#hybrid-offline-store) +* [Performance Considerations](#performance-considerations) + * [Server sizing](#online-feature-server-sizing) + * [Store latency](#online-store-latency-guidelines) + * [Connection pooling](#connection-pooling-for-remote-online-store) + * [Registry cache tuning at scale](#registry-cache-tuning-at-scale) + * [Materialization](#materialization-performance) + * [Redis sizing](#redis-sizing-guidelines) +* [Design Principles](#design-principles) + * [Control plane vs data plane](#control-plane-vs-data-plane) + * [Stateless vs stateful](#stateless-vs-stateful-components) + * [Scalability](#scalability-guidelines) +* [Topology Comparison](#topology-comparison) +* [Next Steps](#next-steps) + +--- + +## Overview + +This guide defines three production-ready deployment topologies for Feast on Kubernetes using the [Feast Operator](./feast-on-kubernetes.md). Each topology addresses a different stage of organizational maturity, from getting started safely to running large-scale multi-tenant deployments. + +| Topology | Target audience | Key traits | +|---|---|---| +| [Minimal Production](#1-minimal-production) | Small teams, POCs moving to production | Single namespace, no HA, simple setup | +| [Standard Production](#2-standard-production-recommended) | Most production workloads | HA registry, autoscaling, TLS, RBAC | +| [Enterprise Production](#3-enterprise-production) | Large orgs, multi-tenant | Namespace isolation, managed stores, full observability | + +Beyond the core topologies, this guide also covers: + +* [Feast Permissions and RBAC](#feast-permissions-and-rbac) — securing resources with policies +* [Infrastructure-Specific Recommendations](#infrastructure-specific-recommendations) — store choices for AWS, GCP, and on-premise +* [Hybrid Store Configuration](#hybrid-store-configuration) — routing to multiple backends from a single deployment +* [Performance Considerations](#performance-considerations) — tuning for production workloads + +{% hint style="info" %} +**Prerequisites:** All topologies assume a running Kubernetes cluster with the [Feast Operator installed](./feast-on-kubernetes.md#deploy-feast-feature-servers-on-kubernetes). Familiarity with Feast [concepts](../getting-started/concepts/overview.md) and [components](../getting-started/components/overview.md) is recommended. +{% endhint %} + +--- + +## 1. Minimal Production + +### When to use + +* Small teams with a single ML use case +* POCs graduating to production +* Low-traffic, non-critical workloads where simplicity is more important than availability + +### Architecture + +```mermaid +graph TD + subgraph Kubernetes["Kubernetes (single namespace)"] + Operator["Feast Operator"] + Registry["Registry Server
(1 replica)"] + OnlineServer["Online Feature Server
(1 replica)"] + MaterializationJob["Materialization Job
(feast materialize / CronJob)"] + NotebookPod(["Notebook / Training Pod
(Feast SDK — remote online + registry)"]) + end + + subgraph BackingStores["Backing Stores (inside or outside Kubernetes)"] + Redis["Online Store
(e.g. Redis for prod; SQLite for dev)"] + OfflineStore["Offline Store
(e.g. DuckDB/PVC for dev; S3/MinIO for prod)"] + end + + Operator -->|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/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 index fbfc733afc6..c9a0a998915 100644 --- a/docs/reference/alpha-feature-view-versioning.md +++ b/docs/reference/alpha-feature-view-versioning.md @@ -206,7 +206,7 @@ Version history tracking in the registry (listing versions, pinning, `--no-promo ## Full Details -For the complete design, concurrency semantics, and feature service interactions, see the [Feature View Versioning RFC](../rfcs/feature-view-versioning.md). +For the complete design, concurrency semantics, and feature service interactions, see the [Feature View Versioning RFC](../adr/feature-view-versioning.md). ## Naming Restrictions 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/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 9d2873c56c3..24bf18dbe86 100644 --- a/docs/reference/data-sources/README.md +++ b/docs/reference/data-sources/README.md @@ -65,3 +65,11 @@ Please see [Data Source](../../getting-started/concepts/data-ingestion.md) for a {% 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/mongodb.md b/docs/reference/data-sources/mongodb.md new file mode 100644 index 00000000000..c1b6eed1bed --- /dev/null +++ b/docs/reference/data-sources/mongodb.md @@ -0,0 +1,113 @@ +# 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 [Atlas Vector Search](https://www.mongodb.com/docs/atlas/atlas-vector-search/), enabling similarity search over feature embeddings stored in MongoDB Atlas. This is powered by the `$vectorSearch` aggregation stage and requires MongoDB Atlas (or the `mongodb/mongodb-atlas-local` Docker image for local development). + +See [PR #6344](https://github.com/feast-dev/feast/pull/6344) for full implementation details. + +### 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 + 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`, Atlas 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 +source = FeatureStore(repo_path=".") +results = store.retrieve_online_documents_v2( + config=repo_config, + table=item_embeddings, + requested_features=["embedding", "title"], + embedding=[0.1, 0.2, ...], # query vector + top_k=5, +) + +# Each result is a (event_timestamp, entity_key_proto, feature_dict) tuple. +# feature_dict includes a synthetic "distance" key with the vector search score. +for ts, entity_key, features in results: + print(features["title"].string_val, features["distance"].float_val) +``` +``` + +### How It Works + +- **Index creation**: `update()` creates an Atlas 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/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/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/offline-stores/README.md b/docs/reference/offline-stores/README.md index 5f4e146326a..1c0d24c8d07 100644 --- a/docs/reference/offline-stores/README.md +++ b/docs/reference/offline-stores/README.md @@ -62,6 +62,10 @@ Please see [Offline Store](../../getting-started/components/offline-store.md) fo [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 %} diff --git a/docs/reference/offline-stores/mongodb.md b/docs/reference/offline-stores/mongodb.md new file mode 100644 index 00000000000..0e8d1786699 --- /dev/null +++ b/docs/reference/offline-stores/mongodb.md @@ -0,0 +1,103 @@ +# MongoDB offline store (contrib) + +## Description + +The MongoDB offline store provides support for reading [MongoDBSource](../data-sources/mongodb.md). +* Uses a single shared collection with a compound index for all FeatureViews, distinguished by a `feature_view` discriminator field. +* Entity dataframes can be provided as a Pandas dataframe. The offline store converts entity identifiers into serialized entity keys for efficient lookup against the collection. + +## 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/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/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/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/roadmap.md b/docs/roadmap.md index a6389b3ce51..e47aa79b573 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -20,6 +20,8 @@ The list below contains the functionality that contributors are planning to deve * [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) @@ -38,6 +40,7 @@ The list below contains the functionality that contributors are planning to deve * [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** 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/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/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/go.mod b/go.mod index d59d6cfa4b3..b76ac71d1e1 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 @@ -26,11 +24,11 @@ require ( 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 v1.43.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 + go.opentelemetry.io/otel/sdk v1.43.0 + go.opentelemetry.io/otel/trace v1.43.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 @@ -113,8 +111,8 @@ require ( go.opentelemetry.io/contrib/detectors/gcp v1.36.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/otel/metric v1.43.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/crypto v0.45.0 // indirect @@ -122,7 +120,7 @@ require ( 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/sys v0.42.0 // indirect golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 // indirect golang.org/x/text v0.31.0 // indirect golang.org/x/time v0.14.0 // indirect diff --git a/go.sum b/go.sum index b9112cc4961..b43b860c04f 100644 --- a/go.sum +++ b/go.sum @@ -262,22 +262,22 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 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 v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= 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/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/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= +go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= 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.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -306,8 +306,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc 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/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= 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= 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/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 4813f341db7..4077a9e06fa 100644 --- a/go/internal/feast/onlinestore/postgresonlinestore.go +++ b/go/internal/feast/onlinestore/postgresonlinestore.go @@ -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/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 5f72378ec3a..711dd910e95 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.62.0 +version: 0.63.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 a59b872f897..24013786f14 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.62.0` +Current chart version is `0.63.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.62.0"` | The Docker image tag (can be overwritten if custom feature server deps are needed for on demand transforms) | +| image.tag | string | `"0.63.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 12707ea97b2..6a3cfda4419 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.62.0 + tag: 0.63.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 796ef7c3251..04f4994176e 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.62.0 +version: 0.63.0 keywords: - machine learning - big data diff --git a/infra/charts/feast/README.md b/infra/charts/feast/README.md index 0f49894bc46..a79e14e4196 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.62.0` +Feature store for machine learning Current chart version is `0.63.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.62.0 | -| https://feast-helm-charts.storage.googleapis.com | transformation-service(transformation-service) | 0.62.0 | +| https://feast-helm-charts.storage.googleapis.com | feature-server(feature-server) | 0.63.0 | +| https://feast-helm-charts.storage.googleapis.com | transformation-service(transformation-service) | 0.63.0 | ## Values diff --git a/infra/charts/feast/charts/feature-server/Chart.yaml b/infra/charts/feast/charts/feature-server/Chart.yaml index 12c49185845..1c3f0314d00 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.62.0 -appVersion: v0.62.0 +version: 0.63.0 +appVersion: v0.63.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 ce02467c442..1899373fee2 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.62.0](https://img.shields.io/badge/Version-0.62.0-informational?style=flat-square) ![AppVersion: v0.62.0](https://img.shields.io/badge/AppVersion-v0.62.0-informational?style=flat-square) +![Version: 0.63.0](https://img.shields.io/badge/Version-0.63.0-informational?style=flat-square) ![AppVersion: v0.63.0](https://img.shields.io/badge/AppVersion-v0.63.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.62.0"` | Image tag | +| image.tag | string | `"0.63.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 a964d8f05b9..655bcec15e5 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.62.0 + tag: 0.63.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 351ff6e4268..6252eb0d4bb 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.62.0 -appVersion: v0.62.0 +version: 0.63.0 +appVersion: v0.63.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 78e5ec12350..5c7d6de89eb 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.62.0](https://img.shields.io/badge/Version-0.62.0-informational?style=flat-square) ![AppVersion: v0.62.0](https://img.shields.io/badge/AppVersion-v0.62.0-informational?style=flat-square) +![Version: 0.63.0](https://img.shields.io/badge/Version-0.63.0-informational?style=flat-square) ![AppVersion: v0.63.0](https://img.shields.io/badge/AppVersion-v0.63.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.62.0"` | Image tag | +| image.tag | string | `"0.63.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 5ede3852e91..03d2f8acf78 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.62.0 + tag: 0.63.0 # image.pullPolicy -- Image pull policy pullPolicy: IfNotPresent diff --git a/infra/charts/feast/requirements.yaml b/infra/charts/feast/requirements.yaml index 181c8d95fca..1b962cc0b89 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.62.0 + version: 0.63.0 condition: feature-server.enabled repository: https://feast-helm-charts.storage.googleapis.com - name: transformation-service alias: transformation-service - version: 0.62.0 + version: 0.63.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..4895f41d8fb 100644 --- a/infra/feast-operator/.golangci.yml +++ b/infra/feast-operator/.golangci.yml @@ -1,55 +1,65 @@ +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 + - lll + path: internal/* + - linters: + - 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..e3a4ebbed28 100644 --- a/infra/feast-operator/Dockerfile +++ b/infra/feast-operator/Dockerfile @@ -1,7 +1,8 @@ # 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.24 AS builder ARG TARGETOS ARG TARGETARCH +ENV GOTOOLCHAIN=auto # Copy the Go Modules manifests COPY go.mod go.mod diff --git a/infra/feast-operator/Makefile b/infra/feast-operator/Makefile index b845cb2b01b..b9515682e06 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.62.0 +VERSION ?= 0.63.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)" 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.3.0 +ENVTEST_VERSION ?= release-0.21 +GOLANGCI_LINT_VERSION ?= v2.1.0 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 9250b88ff1b..29ab2b9e7c6 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.62.0" +const FeastVersion = "0.63.0" diff --git a/infra/feast-operator/api/v1/featurestore_types.go b/infra/feast-operator/api/v1/featurestore_types.go index 95d8130ab99..55da3f5118e 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." @@ -87,6 +132,14 @@ type FeatureStoreSpec struct { // +kubebuilder:default=1 // +kubebuilder:validation:Minimum=1 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. @@ -437,6 +490,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 diff --git a/infra/feast-operator/api/v1/zz_generated.deepcopy.go b/infra/feast-operator/api/v1/zz_generated.deepcopy.go index 8d0e4848f5f..c94dc5a5c71 100644 --- a/infra/feast-operator/api/v1/zz_generated.deepcopy.go +++ b/infra/feast-operator/api/v1/zz_generated.deepcopy.go @@ -455,6 +455,16 @@ func (in *FeatureStoreSpec) DeepCopyInto(out *FeatureStoreSpec) { *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. @@ -662,6 +672,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 @@ -811,6 +903,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. @@ -884,6 +981,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 @@ -1289,6 +1428,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/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.clusterserviceversion.yaml b/infra/feast-operator/bundle/manifests/feast-operator.clusterserviceversion.yaml index 318c01d0ce8..6a99755a2c3 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,29 @@ 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" + } + } + } + } + } + }, { "apiVersion": "feast.dev/v1", "kind": "FeatureStore", @@ -35,6 +87,39 @@ metadata: } } }, + { + "apiVersion": "feast.dev/v1", + "kind": "FeatureStore", + "metadata": { + "name": "sample-serving" + }, + "spec": { + "feastProject": "my_project", + "services": { + "onlineStore": { + "server": {}, + "serving": { + "metrics": { + "categories": { + "freshness": false, + "materialization": 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 +135,10 @@ metadata: } ] capabilities: Basic Install - createdAt: "2026-04-08T14:26:31Z" - operators.operatorframework.io/builder: operator-sdk-v1.38.0 + createdAt: "2026-05-04T03:44:24Z" + operators.operatorframework.io/builder: operator-sdk-v1.41.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v4 - name: feast-operator.v0.62.0 + name: feast-operator.v0.63.0 namespace: placeholder spec: apiservicedefinitions: {} @@ -79,9 +164,12 @@ spec: clusterPermissions: - rules: - apiGroups: - - apps + - "" resources: - - deployments + - configmaps + - persistentvolumeclaims + - serviceaccounts + - services verbs: - create - delete @@ -90,65 +178,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: @@ -267,11 +352,13 @@ spec: - /manager env: - name: RELATED_IMAGE_FEATURE_SERVER - value: quay.io/feastdev/feature-server:0.62.0 + value: quay.io/feastdev/feature-server:0.63.0 - name: RELATED_IMAGE_CRON_JOB value: quay.io/openshift/origin-cli:4.17 + - name: GOMEMLIMIT + value: 230MiB - name: OIDC_ISSUER_URL - image: quay.io/feastdev/feast-operator:0.62.0 + image: quay.io/feastdev/feast-operator:0.63.0 livenessProbe: httpGet: path: /healthz @@ -361,8 +448,8 @@ spec: name: Feast Community url: https://lf-aidata.atlassian.net/wiki/spaces/FEAST/ relatedImages: - - image: quay.io/feastdev/feature-server:0.62.0 + - image: quay.io/feastdev/feature-server:0.63.0 name: feature-server - image: quay.io/openshift/origin-cli:4.17 name: cron-job - version: 0.62.0 + version: 0.63.0 diff --git a/infra/feast-operator/bundle/manifests/feast.dev_featurestores.yaml b/infra/feast-operator/bundle/manifests/feast.dev_featurestores.yaml index ce1d34b5fca..0625be63cf3 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: @@ -167,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. @@ -267,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 @@ -286,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 @@ -333,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 @@ -374,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: @@ -557,8 +560,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. @@ -657,7 +659,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 @@ -676,8 +678,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 @@ -739,6 +741,73 @@ spec: 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: |- @@ -762,7 +831,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 @@ -848,9 +917,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. @@ -939,7 +1008,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 @@ -1064,7 +1133,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 @@ -1082,13 +1151,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: |- @@ -1205,7 +1274,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 @@ -1218,9 +1287,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 @@ -1345,7 +1414,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 @@ -1363,13 +1432,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: |- @@ -1486,7 +1555,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 @@ -1684,8 +1753,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 @@ -1785,7 +1853,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 @@ -1804,8 +1872,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 @@ -1867,6 +1935,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 @@ -2194,8 +2266,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 @@ -2295,7 +2366,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 @@ -2314,8 +2385,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 @@ -2377,6 +2448,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 @@ -2535,6 +2610,75 @@ 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: @@ -2752,8 +2896,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 @@ -2856,7 +2999,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 @@ -2875,8 +3018,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 @@ -2942,6 +3086,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 @@ -3223,9 +3371,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 @@ -3270,9 +3427,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: @@ -3287,12 +3453,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 @@ -3307,10 +3473,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: @@ -3357,10 +3522,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 @@ -3411,10 +3575,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: @@ -3480,10 +3643,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 @@ -3534,10 +3696,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: @@ -3573,7 +3734,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 @@ -3584,10 +3745,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 @@ -3638,10 +3798,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: @@ -3676,7 +3835,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 @@ -3687,10 +3846,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: @@ -3784,6 +3942,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: @@ -3822,13 +3984,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. @@ -3939,7 +4106,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: |- @@ -3975,8 +4142,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. @@ -4075,7 +4241,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 @@ -4094,8 +4260,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 @@ -4156,6 +4322,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 @@ -4324,7 +4494,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 @@ -4366,6 +4536,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. @@ -4374,9 +4545,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. @@ -4407,7 +4579,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: |- @@ -4455,7 +4627,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: |- @@ -4501,7 +4673,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. @@ -4541,7 +4713,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 @@ -4553,7 +4725,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: "" @@ -4615,7 +4787,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: @@ -4864,9 +5036,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 @@ -4901,7 +5073,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: "" @@ -4922,7 +5094,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. @@ -4932,7 +5104,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 @@ -4961,7 +5133,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -4979,9 +5151,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: |- @@ -5021,6 +5192,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 @@ -5046,6 +5233,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). @@ -5136,7 +5324,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -5153,7 +5341,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: |- @@ -5183,10 +5371,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 @@ -5266,7 +5457,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. @@ -5337,7 +5528,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: @@ -5386,7 +5577,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. @@ -5452,7 +5643,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: |- @@ -5467,12 +5658,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: |- @@ -5488,9 +5679,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 @@ -5502,6 +5692,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. @@ -5516,6 +5707,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -5543,6 +5735,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -5557,6 +5750,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. @@ -5594,6 +5788,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 @@ -5628,7 +5823,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. @@ -5703,7 +5898,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: |- @@ -5898,8 +6093,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 @@ -5999,7 +6193,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 @@ -6018,8 +6212,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 @@ -6066,6 +6260,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 @@ -6107,7 +6305,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: @@ -6293,8 +6491,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 @@ -6394,7 +6591,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 @@ -6413,8 +6610,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 @@ -6477,6 +6674,73 @@ spec: 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: |- @@ -6500,7 +6764,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 @@ -6587,9 +6851,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 @@ -6678,7 +6942,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 @@ -6806,7 +7070,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 @@ -6824,13 +7088,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: |- @@ -6947,7 +7211,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 @@ -6961,9 +7225,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 @@ -7091,7 +7355,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 @@ -7109,13 +7373,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: |- @@ -7232,7 +7496,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 @@ -7433,8 +7697,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 @@ -7537,7 +7800,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 @@ -7556,8 +7819,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 @@ -7619,6 +7883,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 @@ -7951,8 +8219,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 @@ -8055,7 +8322,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 @@ -8074,8 +8341,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 @@ -8137,6 +8405,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 @@ -8296,6 +8568,77 @@ 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: @@ -8521,8 +8864,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 @@ -8627,7 +8969,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 @@ -8646,9 +8988,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 @@ -8714,6 +9056,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 @@ -9004,9 +9350,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 @@ -9052,9 +9407,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: @@ -9069,12 +9433,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 @@ -9089,10 +9453,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: @@ -9139,10 +9502,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 @@ -9193,10 +9555,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: @@ -9263,10 +9624,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 @@ -9317,10 +9677,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: @@ -9356,7 +9715,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 @@ -9367,10 +9726,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 @@ -9421,10 +9779,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: @@ -9459,7 +9816,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 @@ -9470,10 +9827,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: @@ -9567,6 +9923,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. @@ -9606,13 +9967,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. @@ -9726,7 +10092,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: |- @@ -9762,8 +10128,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 @@ -9863,7 +10228,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 @@ -9882,8 +10247,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 @@ -9945,6 +10310,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 @@ -10113,7 +10482,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 @@ -10155,6 +10524,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. @@ -10163,9 +10533,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. @@ -10196,7 +10567,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: |- @@ -10245,7 +10616,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: |- @@ -10291,7 +10662,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. @@ -10331,7 +10702,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 @@ -10344,7 +10715,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: "" @@ -10408,7 +10779,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: @@ -10660,9 +11031,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 @@ -10697,7 +11068,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: "" @@ -10718,7 +11089,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. @@ -10728,7 +11099,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 @@ -10757,7 +11128,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -10775,9 +11146,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: |- @@ -10817,6 +11187,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 @@ -10842,6 +11228,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). @@ -10933,7 +11320,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -10950,7 +11337,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: |- @@ -10980,10 +11367,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 @@ -11064,7 +11454,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. @@ -11137,7 +11527,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: @@ -11186,7 +11576,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. @@ -11252,7 +11642,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: |- @@ -11267,12 +11657,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: |- @@ -11288,9 +11678,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 @@ -11302,6 +11691,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. @@ -11316,6 +11706,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -11343,6 +11734,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -11357,6 +11749,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. @@ -11394,6 +11787,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 @@ -11428,7 +11822,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. @@ -11503,7 +11897,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: |- @@ -11608,10 +12002,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 @@ -11782,8 +12173,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. @@ -11882,7 +12272,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 @@ -11901,8 +12291,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 @@ -11948,6 +12338,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 @@ -11989,7 +12383,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: @@ -12172,8 +12566,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. @@ -12272,7 +12665,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 @@ -12291,8 +12684,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 @@ -12546,8 +12939,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 @@ -12647,7 +13039,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 @@ -12666,8 +13058,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 @@ -12729,6 +13121,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 @@ -13056,8 +13452,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 @@ -13157,7 +13552,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 @@ -13176,8 +13571,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 @@ -13239,6 +13634,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 @@ -13584,8 +13983,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 @@ -13688,7 +14086,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 @@ -13707,8 +14105,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 @@ -13774,6 +14173,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 @@ -14044,6 +14447,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: @@ -14082,13 +14489,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. @@ -14145,8 +14557,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. @@ -14245,7 +14656,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 @@ -14264,8 +14675,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 @@ -14326,6 +14737,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 @@ -14494,7 +14909,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 @@ -14536,6 +14951,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. @@ -14544,9 +14960,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. @@ -14577,7 +14994,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: |- @@ -14625,7 +15042,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: |- @@ -14671,7 +15088,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. @@ -14711,7 +15128,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 @@ -14723,7 +15140,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: "" @@ -14785,7 +15202,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: @@ -15034,9 +15451,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 @@ -15071,7 +15488,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: "" @@ -15092,7 +15509,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. @@ -15102,7 +15519,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 @@ -15131,7 +15548,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -15149,9 +15566,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: |- @@ -15191,6 +15607,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 @@ -15216,6 +15648,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). @@ -15306,7 +15739,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -15323,7 +15756,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: |- @@ -15353,10 +15786,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 @@ -15436,7 +15872,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. @@ -15507,7 +15943,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: @@ -15556,7 +15992,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. @@ -15622,7 +16058,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: |- @@ -15637,12 +16073,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: |- @@ -15658,9 +16094,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 @@ -15672,6 +16107,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. @@ -15686,6 +16122,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -15713,6 +16150,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -15727,6 +16165,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. @@ -15764,6 +16203,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 @@ -15798,7 +16238,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. @@ -15873,7 +16313,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: |- @@ -15989,8 +16429,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 @@ -16090,7 +16529,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 @@ -16109,8 +16548,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 @@ -16157,6 +16596,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 @@ -16198,7 +16641,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: @@ -16384,8 +16827,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 @@ -16485,7 +16927,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 @@ -16504,8 +16946,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 @@ -16763,8 +17205,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 @@ -16867,7 +17308,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 @@ -16886,8 +17327,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 @@ -16949,6 +17391,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 @@ -17281,8 +17727,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 @@ -17385,7 +17830,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 @@ -17404,8 +17849,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 @@ -17467,6 +17913,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 @@ -17821,8 +18271,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 @@ -17927,7 +18376,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 @@ -17946,9 +18395,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 @@ -18014,6 +18463,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 @@ -18292,6 +18745,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. @@ -18331,13 +18789,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. @@ -18395,8 +18858,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 @@ -18496,7 +18958,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 @@ -18515,8 +18977,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 @@ -18578,6 +19040,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 @@ -18746,7 +19212,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 @@ -18788,6 +19254,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. @@ -18796,9 +19263,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. @@ -18829,7 +19297,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: |- @@ -18878,7 +19346,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: |- @@ -18924,7 +19392,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. @@ -18964,7 +19432,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 @@ -18977,7 +19445,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: "" @@ -19041,7 +19509,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: @@ -19293,9 +19761,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 @@ -19330,7 +19798,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: "" @@ -19351,7 +19819,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. @@ -19361,7 +19829,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 @@ -19390,7 +19858,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -19408,9 +19876,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: |- @@ -19450,6 +19917,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 @@ -19475,6 +19958,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). @@ -19566,7 +20050,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -19583,7 +20067,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: |- @@ -19613,10 +20097,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 @@ -19697,7 +20184,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. @@ -19770,7 +20257,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: @@ -19819,7 +20306,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. @@ -19885,7 +20372,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: |- @@ -19900,12 +20387,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: |- @@ -19921,9 +20408,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 @@ -19935,6 +20421,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. @@ -19949,6 +20436,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -19976,6 +20464,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -19990,6 +20479,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. @@ -20027,6 +20517,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 @@ -20061,7 +20552,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. @@ -20136,7 +20627,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: |- @@ -20210,10 +20701,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..40483cc0c43 --- /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 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..ead6e93ce72 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" @@ -59,6 +66,29 @@ 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 @@ -105,7 +135,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 +153,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 +175,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{}, }, }, }, diff --git a/infra/feast-operator/config/component_metadata.yaml b/infra/feast-operator/config/component_metadata.yaml index c84deab6d83..052dcffaf32 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.62.0 + version: 0.63.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 2631a049fb9..183fbf3be53 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 @@ -167,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. @@ -267,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 @@ -286,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 @@ -333,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 @@ -374,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: @@ -557,8 +560,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. @@ -657,7 +659,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 @@ -676,8 +678,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 @@ -739,6 +741,73 @@ spec: 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: |- @@ -762,7 +831,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 @@ -848,9 +917,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. @@ -939,7 +1008,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 @@ -1064,7 +1133,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 @@ -1082,13 +1151,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: |- @@ -1205,7 +1274,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 @@ -1218,9 +1287,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 @@ -1345,7 +1414,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 @@ -1363,13 +1432,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: |- @@ -1486,7 +1555,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 @@ -1684,8 +1753,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 @@ -1785,7 +1853,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 @@ -1804,8 +1872,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 @@ -1867,6 +1935,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 @@ -2194,8 +2266,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 @@ -2295,7 +2366,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 @@ -2314,8 +2385,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 @@ -2377,6 +2448,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 @@ -2535,6 +2610,75 @@ 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: @@ -2752,8 +2896,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 @@ -2856,7 +2999,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 @@ -2875,8 +3018,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 @@ -2942,6 +3086,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 @@ -3223,9 +3371,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 @@ -3270,9 +3427,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: @@ -3287,12 +3453,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 @@ -3307,10 +3473,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: @@ -3357,10 +3522,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 @@ -3411,10 +3575,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: @@ -3480,10 +3643,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 @@ -3534,10 +3696,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: @@ -3573,7 +3734,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 @@ -3584,10 +3745,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 @@ -3638,10 +3798,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: @@ -3676,7 +3835,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 @@ -3687,10 +3846,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: @@ -3784,6 +3942,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: @@ -3822,13 +3984,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. @@ -3939,7 +4106,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: |- @@ -3975,8 +4142,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. @@ -4075,7 +4241,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 @@ -4094,8 +4260,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 @@ -4156,6 +4322,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 @@ -4324,7 +4494,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 @@ -4366,6 +4536,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. @@ -4374,9 +4545,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. @@ -4407,7 +4579,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: |- @@ -4455,7 +4627,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: |- @@ -4501,7 +4673,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. @@ -4541,7 +4713,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 @@ -4553,7 +4725,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: "" @@ -4615,7 +4787,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: @@ -4864,9 +5036,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 @@ -4901,7 +5073,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: "" @@ -4922,7 +5094,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. @@ -4932,7 +5104,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 @@ -4961,7 +5133,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -4979,9 +5151,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: |- @@ -5021,6 +5192,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 @@ -5046,6 +5233,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). @@ -5136,7 +5324,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -5153,7 +5341,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: |- @@ -5183,10 +5371,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 @@ -5266,7 +5457,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. @@ -5337,7 +5528,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: @@ -5386,7 +5577,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. @@ -5452,7 +5643,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: |- @@ -5467,12 +5658,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: |- @@ -5488,9 +5679,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 @@ -5502,6 +5692,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. @@ -5516,6 +5707,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -5543,6 +5735,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -5557,6 +5750,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. @@ -5594,6 +5788,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 @@ -5628,7 +5823,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. @@ -5703,7 +5898,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: |- @@ -5898,8 +6093,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 @@ -5999,7 +6193,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 @@ -6018,8 +6212,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 @@ -6066,6 +6260,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 @@ -6107,7 +6305,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: @@ -6293,8 +6491,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 @@ -6394,7 +6591,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 @@ -6413,8 +6610,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 @@ -6477,6 +6674,73 @@ spec: 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: |- @@ -6500,7 +6764,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 @@ -6587,9 +6851,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 @@ -6678,7 +6942,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 @@ -6806,7 +7070,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 @@ -6824,13 +7088,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: |- @@ -6947,7 +7211,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 @@ -6961,9 +7225,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 @@ -7091,7 +7355,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 @@ -7109,13 +7373,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: |- @@ -7232,7 +7496,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 @@ -7433,8 +7697,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 @@ -7537,7 +7800,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 @@ -7556,8 +7819,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 @@ -7619,6 +7883,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 @@ -7951,8 +8219,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 @@ -8055,7 +8322,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 @@ -8074,8 +8341,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 @@ -8137,6 +8405,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 @@ -8296,6 +8568,77 @@ 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: @@ -8521,8 +8864,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 @@ -8627,7 +8969,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 @@ -8646,9 +8988,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 @@ -8714,6 +9056,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 @@ -9004,9 +9350,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 @@ -9052,9 +9407,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: @@ -9069,12 +9433,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 @@ -9089,10 +9453,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: @@ -9139,10 +9502,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 @@ -9193,10 +9555,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: @@ -9263,10 +9624,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 @@ -9317,10 +9677,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: @@ -9356,7 +9715,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 @@ -9367,10 +9726,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 @@ -9421,10 +9779,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: @@ -9459,7 +9816,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 @@ -9470,10 +9827,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: @@ -9567,6 +9923,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. @@ -9606,13 +9967,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. @@ -9726,7 +10092,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: |- @@ -9762,8 +10128,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 @@ -9863,7 +10228,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 @@ -9882,8 +10247,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 @@ -9945,6 +10310,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 @@ -10113,7 +10482,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 @@ -10155,6 +10524,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. @@ -10163,9 +10533,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. @@ -10196,7 +10567,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: |- @@ -10245,7 +10616,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: |- @@ -10291,7 +10662,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. @@ -10331,7 +10702,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 @@ -10344,7 +10715,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: "" @@ -10408,7 +10779,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: @@ -10660,9 +11031,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 @@ -10697,7 +11068,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: "" @@ -10718,7 +11089,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. @@ -10728,7 +11099,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 @@ -10757,7 +11128,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -10775,9 +11146,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: |- @@ -10817,6 +11187,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 @@ -10842,6 +11228,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). @@ -10933,7 +11320,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -10950,7 +11337,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: |- @@ -10980,10 +11367,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 @@ -11064,7 +11454,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. @@ -11137,7 +11527,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: @@ -11186,7 +11576,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. @@ -11252,7 +11642,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: |- @@ -11267,12 +11657,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: |- @@ -11288,9 +11678,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 @@ -11302,6 +11691,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. @@ -11316,6 +11706,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -11343,6 +11734,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -11357,6 +11749,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. @@ -11394,6 +11787,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 @@ -11428,7 +11822,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. @@ -11503,7 +11897,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: |- @@ -11608,10 +12002,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 @@ -11782,8 +12173,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. @@ -11882,7 +12272,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 @@ -11901,8 +12291,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 @@ -11948,6 +12338,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 @@ -11989,7 +12383,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: @@ -12172,8 +12566,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. @@ -12272,7 +12665,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 @@ -12291,8 +12684,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 @@ -12546,8 +12939,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 @@ -12647,7 +13039,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 @@ -12666,8 +13058,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 @@ -12729,6 +13121,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 @@ -13056,8 +13452,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 @@ -13157,7 +13552,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 @@ -13176,8 +13571,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 @@ -13239,6 +13634,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 @@ -13584,8 +13983,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 @@ -13688,7 +14086,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 @@ -13707,8 +14105,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 @@ -13774,6 +14173,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 @@ -14044,6 +14447,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: @@ -14082,13 +14489,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. @@ -14145,8 +14557,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. @@ -14245,7 +14656,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 @@ -14264,8 +14675,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 @@ -14326,6 +14737,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 @@ -14494,7 +14909,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 @@ -14536,6 +14951,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. @@ -14544,9 +14960,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. @@ -14577,7 +14994,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: |- @@ -14625,7 +15042,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: |- @@ -14671,7 +15088,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. @@ -14711,7 +15128,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 @@ -14723,7 +15140,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: "" @@ -14785,7 +15202,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: @@ -15034,9 +15451,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 @@ -15071,7 +15488,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: "" @@ -15092,7 +15509,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. @@ -15102,7 +15519,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 @@ -15131,7 +15548,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -15149,9 +15566,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: |- @@ -15191,6 +15607,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 @@ -15216,6 +15648,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). @@ -15306,7 +15739,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -15323,7 +15756,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: |- @@ -15353,10 +15786,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 @@ -15436,7 +15872,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. @@ -15507,7 +15943,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: @@ -15556,7 +15992,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. @@ -15622,7 +16058,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: |- @@ -15637,12 +16073,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: |- @@ -15658,9 +16094,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 @@ -15672,6 +16107,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. @@ -15686,6 +16122,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -15713,6 +16150,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -15727,6 +16165,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. @@ -15764,6 +16203,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 @@ -15798,7 +16238,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. @@ -15873,7 +16313,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: |- @@ -15989,8 +16429,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 @@ -16090,7 +16529,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 @@ -16109,8 +16548,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 @@ -16157,6 +16596,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 @@ -16198,7 +16641,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: @@ -16384,8 +16827,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 @@ -16485,7 +16927,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 @@ -16504,8 +16946,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 @@ -16763,8 +17205,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 @@ -16867,7 +17308,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 @@ -16886,8 +17327,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 @@ -16949,6 +17391,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 @@ -17281,8 +17727,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 @@ -17385,7 +17830,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 @@ -17404,8 +17849,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 @@ -17467,6 +17913,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 @@ -17821,8 +18271,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 @@ -17927,7 +18376,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 @@ -17946,9 +18395,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 @@ -18014,6 +18463,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 @@ -18292,6 +18745,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. @@ -18331,13 +18789,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. @@ -18395,8 +18858,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 @@ -18496,7 +18958,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 @@ -18515,8 +18977,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 @@ -18578,6 +19040,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 @@ -18746,7 +19212,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 @@ -18788,6 +19254,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. @@ -18796,9 +19263,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. @@ -18829,7 +19297,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: |- @@ -18878,7 +19346,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: |- @@ -18924,7 +19392,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. @@ -18964,7 +19432,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 @@ -18977,7 +19445,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: "" @@ -19041,7 +19509,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: @@ -19293,9 +19761,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 @@ -19330,7 +19798,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: "" @@ -19351,7 +19819,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. @@ -19361,7 +19829,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 @@ -19390,7 +19858,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -19408,9 +19876,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: |- @@ -19450,6 +19917,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 @@ -19475,6 +19958,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). @@ -19566,7 +20050,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -19583,7 +20067,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: |- @@ -19613,10 +20097,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 @@ -19697,7 +20184,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. @@ -19770,7 +20257,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: @@ -19819,7 +20306,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. @@ -19885,7 +20372,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: |- @@ -19900,12 +20387,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: |- @@ -19921,9 +20408,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 @@ -19935,6 +20421,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. @@ -19949,6 +20436,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -19976,6 +20464,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -19990,6 +20479,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. @@ -20027,6 +20517,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 @@ -20061,7 +20552,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. @@ -20136,7 +20627,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: |- @@ -20210,10 +20701,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 6de980383f0..d7f0617fb5b 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.62.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.63.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 cbec14cc6ba..8a25a8041b3 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.62.0 + newTag: 0.63.0 diff --git a/infra/feast-operator/config/manager/manager.yaml b/infra/feast-operator/config/manager/manager.yaml index 2fddf4725ba..4213787e075 100644 --- a/infra/feast-operator/config/manager/manager.yaml +++ b/infra/feast-operator/config/manager/manager.yaml @@ -73,6 +73,8 @@ spec: drop: - "ALL" env: + - name: GOMEMLIMIT + value: "230MiB" - name: RELATED_IMAGE_FEATURE_SERVER value: feast:latest - name: RELATED_IMAGE_CRON_JOB diff --git a/infra/feast-operator/config/overlays/odh/kustomization.yaml b/infra/feast-operator/config/overlays/odh/kustomization.yaml index 044614f01fe..cc9d0e4dfd3 100644 --- a/infra/feast-operator/config/overlays/odh/kustomization.yaml +++ b/infra/feast-operator/config/overlays/odh/kustomization.yaml @@ -11,6 +11,14 @@ resources: patches: # patch to remove default `system` namespace in ../../manager/manager.yaml - path: delete-namespace.yaml + # Remove app.kubernetes.io/name from the Deployment selector to avoid + # immutable spec.selector errors on upgrade. The label remains in the + # pod template so the metrics Service selector still targets only + # feast-operator pods. + - path: remove_selector_label_patch.yaml + target: + kind: Deployment + name: controller-manager configMapGenerator: - name: feast-operator-parameters diff --git a/infra/feast-operator/config/overlays/odh/params.env b/infra/feast-operator/config/overlays/odh/params.env index 20f56181337..3a37a22adef 100644 --- a/infra/feast-operator/config/overlays/odh/params.env +++ b/infra/feast-operator/config/overlays/odh/params.env @@ -1,5 +1,5 @@ -RELATED_IMAGE_FEAST_OPERATOR=quay.io/feastdev/feast-operator:0.62.0 -RELATED_IMAGE_FEATURE_SERVER=quay.io/feastdev/feature-server:0.62.0 +RELATED_IMAGE_FEAST_OPERATOR=quay.io/feastdev/feast-operator:0.63.0 +RELATED_IMAGE_FEATURE_SERVER=quay.io/feastdev/feature-server:0.63.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/odh/remove_selector_label_patch.yaml b/infra/feast-operator/config/overlays/odh/remove_selector_label_patch.yaml new file mode 100644 index 00000000000..e842c1f7a58 --- /dev/null +++ b/infra/feast-operator/config/overlays/odh/remove_selector_label_patch.yaml @@ -0,0 +1,2 @@ +- op: remove + path: /spec/selector/matchLabels/app.kubernetes.io~1name diff --git a/infra/feast-operator/config/overlays/rhoai/kustomization.yaml b/infra/feast-operator/config/overlays/rhoai/kustomization.yaml index b9d075bdf39..5708b1f0c37 100644 --- a/infra/feast-operator/config/overlays/rhoai/kustomization.yaml +++ b/infra/feast-operator/config/overlays/rhoai/kustomization.yaml @@ -11,6 +11,14 @@ resources: patches: # patch to remove default `system` namespace in ../../manager/manager.yaml - path: delete-namespace.yaml + # Remove app.kubernetes.io/name from the Deployment selector to avoid + # immutable spec.selector errors on upgrade. The label remains in the + # pod template so the metrics Service selector still targets only + # feast-operator pods. + - path: remove_selector_label_patch.yaml + target: + kind: Deployment + name: controller-manager configMapGenerator: - name: feast-operator-parameters diff --git a/infra/feast-operator/config/overlays/rhoai/params.env b/infra/feast-operator/config/overlays/rhoai/params.env index c2ba0ae07cb..c19204cedd2 100644 --- a/infra/feast-operator/config/overlays/rhoai/params.env +++ b/infra/feast-operator/config/overlays/rhoai/params.env @@ -1,5 +1,5 @@ -RELATED_IMAGE_FEAST_OPERATOR=quay.io/feastdev/feast-operator:0.62.0 -RELATED_IMAGE_FEATURE_SERVER=quay.io/feastdev/feature-server:0.62.0 +RELATED_IMAGE_FEAST_OPERATOR=quay.io/feastdev/feast-operator:0.63.0 +RELATED_IMAGE_FEATURE_SERVER=quay.io/feastdev/feature-server:0.63.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/overlays/rhoai/remove_selector_label_patch.yaml b/infra/feast-operator/config/overlays/rhoai/remove_selector_label_patch.yaml new file mode 100644 index 00000000000..e842c1f7a58 --- /dev/null +++ b/infra/feast-operator/config/overlays/rhoai/remove_selector_label_patch.yaml @@ -0,0 +1,2 @@ +- op: remove + path: /spec/selector/matchLabels/app.kubernetes.io~1name diff --git a/infra/feast-operator/config/rbac/role.yaml b/infra/feast-operator/config/rbac/role.yaml index c5dc4850303..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: 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..4ad45cdffa3 --- /dev/null +++ b/infra/feast-operator/config/samples/v1_featurestore_mcp.yaml @@ -0,0 +1,19 @@ +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 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..f60640624c9 --- /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) + # Example: when a future SDK adds "registry_sync", enable it here + # registry_sync: false + 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 558279cd396..6feb187cce3 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 @@ -175,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. @@ -275,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 @@ -294,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 @@ -341,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 @@ -382,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: @@ -565,8 +568,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. @@ -665,7 +667,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 @@ -684,8 +686,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 @@ -747,6 +749,73 @@ spec: 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: |- @@ -770,7 +839,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 @@ -856,9 +925,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. @@ -947,7 +1016,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 @@ -1072,7 +1141,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 @@ -1090,13 +1159,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: |- @@ -1213,7 +1282,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 @@ -1226,9 +1295,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 @@ -1353,7 +1422,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 @@ -1371,13 +1440,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: |- @@ -1494,7 +1563,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 @@ -1692,8 +1761,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 @@ -1793,7 +1861,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 @@ -1812,8 +1880,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 @@ -1875,6 +1943,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 @@ -2202,8 +2274,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 @@ -2303,7 +2374,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 @@ -2322,8 +2393,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 @@ -2385,6 +2456,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 @@ -2543,6 +2618,75 @@ 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: @@ -2760,8 +2904,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 @@ -2864,7 +3007,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 @@ -2883,8 +3026,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 @@ -2950,6 +3094,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 @@ -3231,9 +3379,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 @@ -3278,9 +3435,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: @@ -3295,12 +3461,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 @@ -3315,10 +3481,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: @@ -3365,10 +3530,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 @@ -3419,10 +3583,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: @@ -3488,10 +3651,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 @@ -3542,10 +3704,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: @@ -3581,7 +3742,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 @@ -3592,10 +3753,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 @@ -3646,10 +3806,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: @@ -3684,7 +3843,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 @@ -3695,10 +3854,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: @@ -3792,6 +3950,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: @@ -3830,13 +3992,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. @@ -3947,7 +4114,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: |- @@ -3983,8 +4150,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. @@ -4083,7 +4249,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 @@ -4102,8 +4268,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 @@ -4164,6 +4330,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 @@ -4332,7 +4502,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 @@ -4374,6 +4544,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. @@ -4382,9 +4553,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. @@ -4415,7 +4587,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: |- @@ -4463,7 +4635,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: |- @@ -4509,7 +4681,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. @@ -4549,7 +4721,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 @@ -4561,7 +4733,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: "" @@ -4623,7 +4795,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: @@ -4872,9 +5044,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 @@ -4909,7 +5081,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: "" @@ -4930,7 +5102,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. @@ -4940,7 +5112,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 @@ -4969,7 +5141,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -4987,9 +5159,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: |- @@ -5029,6 +5200,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 @@ -5054,6 +5241,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). @@ -5144,7 +5332,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -5161,7 +5349,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: |- @@ -5191,10 +5379,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 @@ -5274,7 +5465,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. @@ -5345,7 +5536,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: @@ -5394,7 +5585,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. @@ -5460,7 +5651,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: |- @@ -5475,12 +5666,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: |- @@ -5496,9 +5687,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 @@ -5510,6 +5700,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. @@ -5524,6 +5715,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -5551,6 +5743,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -5565,6 +5758,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. @@ -5602,6 +5796,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 @@ -5636,7 +5831,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. @@ -5711,7 +5906,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: |- @@ -5906,8 +6101,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 @@ -6007,7 +6201,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 @@ -6026,8 +6220,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 @@ -6074,6 +6268,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 @@ -6115,7 +6313,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: @@ -6301,8 +6499,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 @@ -6402,7 +6599,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 @@ -6421,8 +6618,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 @@ -6485,6 +6682,73 @@ spec: 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: |- @@ -6508,7 +6772,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 @@ -6595,9 +6859,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 @@ -6686,7 +6950,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 @@ -6814,7 +7078,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 @@ -6832,13 +7096,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: |- @@ -6955,7 +7219,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 @@ -6969,9 +7233,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 @@ -7099,7 +7363,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 @@ -7117,13 +7381,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: |- @@ -7240,7 +7504,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 @@ -7441,8 +7705,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 @@ -7545,7 +7808,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 @@ -7564,8 +7827,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 @@ -7627,6 +7891,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 @@ -7959,8 +8227,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 @@ -8063,7 +8330,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 @@ -8082,8 +8349,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 @@ -8145,6 +8413,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 @@ -8304,6 +8576,77 @@ 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: @@ -8529,8 +8872,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 @@ -8635,7 +8977,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 @@ -8654,9 +8996,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 @@ -8722,6 +9064,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 @@ -9012,9 +9358,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 @@ -9060,9 +9415,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: @@ -9077,12 +9441,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 @@ -9097,10 +9461,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: @@ -9147,10 +9510,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 @@ -9201,10 +9563,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: @@ -9271,10 +9632,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 @@ -9325,10 +9685,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: @@ -9364,7 +9723,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 @@ -9375,10 +9734,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 @@ -9429,10 +9787,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: @@ -9467,7 +9824,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 @@ -9478,10 +9835,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: @@ -9575,6 +9931,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. @@ -9614,13 +9975,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. @@ -9734,7 +10100,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: |- @@ -9770,8 +10136,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 @@ -9871,7 +10236,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 @@ -9890,8 +10255,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 @@ -9953,6 +10318,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 @@ -10121,7 +10490,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 @@ -10163,6 +10532,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. @@ -10171,9 +10541,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. @@ -10204,7 +10575,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: |- @@ -10253,7 +10624,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: |- @@ -10299,7 +10670,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. @@ -10339,7 +10710,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 @@ -10352,7 +10723,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: "" @@ -10416,7 +10787,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: @@ -10668,9 +11039,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 @@ -10705,7 +11076,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: "" @@ -10726,7 +11097,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. @@ -10736,7 +11107,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 @@ -10765,7 +11136,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -10783,9 +11154,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: |- @@ -10825,6 +11195,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 @@ -10850,6 +11236,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). @@ -10941,7 +11328,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -10958,7 +11345,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: |- @@ -10988,10 +11375,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 @@ -11072,7 +11462,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. @@ -11145,7 +11535,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: @@ -11194,7 +11584,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. @@ -11260,7 +11650,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: |- @@ -11275,12 +11665,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: |- @@ -11296,9 +11686,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 @@ -11310,6 +11699,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. @@ -11324,6 +11714,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -11351,6 +11742,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -11365,6 +11757,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. @@ -11402,6 +11795,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 @@ -11436,7 +11830,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. @@ -11511,7 +11905,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: |- @@ -11616,10 +12010,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 @@ -11790,8 +12181,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. @@ -11890,7 +12280,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 @@ -11909,8 +12299,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 @@ -11956,6 +12346,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 @@ -11997,7 +12391,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: @@ -12180,8 +12574,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. @@ -12280,7 +12673,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 @@ -12299,8 +12692,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 @@ -12554,8 +12947,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 @@ -12655,7 +13047,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 @@ -12674,8 +13066,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 @@ -12737,6 +13129,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 @@ -13064,8 +13460,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 @@ -13165,7 +13560,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 @@ -13184,8 +13579,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 @@ -13247,6 +13642,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 @@ -13592,8 +13991,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 @@ -13696,7 +14094,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 @@ -13715,8 +14113,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 @@ -13782,6 +14181,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 @@ -14052,6 +14455,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: @@ -14090,13 +14497,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. @@ -14153,8 +14565,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. @@ -14253,7 +14664,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 @@ -14272,8 +14683,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 @@ -14334,6 +14745,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 @@ -14502,7 +14917,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 @@ -14544,6 +14959,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. @@ -14552,9 +14968,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. @@ -14585,7 +15002,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: |- @@ -14633,7 +15050,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: |- @@ -14679,7 +15096,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. @@ -14719,7 +15136,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 @@ -14731,7 +15148,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: "" @@ -14793,7 +15210,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: @@ -15042,9 +15459,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 @@ -15079,7 +15496,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: "" @@ -15100,7 +15517,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. @@ -15110,7 +15527,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 @@ -15139,7 +15556,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -15157,9 +15574,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: |- @@ -15199,6 +15615,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 @@ -15224,6 +15656,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). @@ -15314,7 +15747,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -15331,7 +15764,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: |- @@ -15361,10 +15794,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 @@ -15444,7 +15880,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. @@ -15515,7 +15951,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: @@ -15564,7 +16000,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. @@ -15630,7 +16066,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: |- @@ -15645,12 +16081,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: |- @@ -15666,9 +16102,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 @@ -15680,6 +16115,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. @@ -15694,6 +16130,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -15721,6 +16158,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -15735,6 +16173,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. @@ -15772,6 +16211,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 @@ -15806,7 +16246,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. @@ -15881,7 +16321,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: |- @@ -15997,8 +16437,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 @@ -16098,7 +16537,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 @@ -16117,8 +16556,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 @@ -16165,6 +16604,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 @@ -16206,7 +16649,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: @@ -16392,8 +16835,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 @@ -16493,7 +16935,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 @@ -16512,8 +16954,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 @@ -16771,8 +17213,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 @@ -16875,7 +17316,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 @@ -16894,8 +17335,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 @@ -16957,6 +17399,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 @@ -17289,8 +17735,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 @@ -17393,7 +17838,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 @@ -17412,8 +17857,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 @@ -17475,6 +17921,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 @@ -17829,8 +18279,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 @@ -17935,7 +18384,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 @@ -17954,9 +18403,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 @@ -18022,6 +18471,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 @@ -18300,6 +18753,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. @@ -18339,13 +18797,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. @@ -18403,8 +18866,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 @@ -18504,7 +18966,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 @@ -18523,8 +18985,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 @@ -18586,6 +19048,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 @@ -18754,7 +19220,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 @@ -18796,6 +19262,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. @@ -18804,9 +19271,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. @@ -18837,7 +19305,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: |- @@ -18886,7 +19354,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: |- @@ -18932,7 +19400,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. @@ -18972,7 +19440,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 @@ -18985,7 +19453,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: "" @@ -19049,7 +19517,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: @@ -19301,9 +19769,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 @@ -19338,7 +19806,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: "" @@ -19359,7 +19827,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. @@ -19369,7 +19837,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 @@ -19398,7 +19866,7 @@ spec: gitRepo: description: |- gitRepo represents a git repository at a particular revision. - DEPRECATED: GitRepo is deprecated. + Deprecated: GitRepo is deprecated. properties: directory: description: |- @@ -19416,9 +19884,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: |- @@ -19458,6 +19925,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 @@ -19483,6 +19966,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). @@ -19574,7 +20058,7 @@ spec: photonPersistentDisk: description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host - machine + machine. properties: fsType: description: |- @@ -19591,7 +20075,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: |- @@ -19621,10 +20105,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 @@ -19705,7 +20192,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. @@ -19778,7 +20265,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: @@ -19827,7 +20314,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. @@ -19893,7 +20380,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: |- @@ -19908,12 +20395,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: |- @@ -19929,9 +20416,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 @@ -19943,6 +20429,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. @@ -19957,6 +20444,7 @@ spec: type: array x-kubernetes-list-type: atomic pool: + default: rbd description: |- pool is the rados pool name. Default is rbd. @@ -19984,6 +20472,7 @@ spec: type: object x-kubernetes-map-type: atomic user: + default: admin description: |- user is the rados user name. Default is admin. @@ -19998,6 +20487,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. @@ -20035,6 +20525,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 @@ -20069,7 +20560,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. @@ -20144,7 +20635,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: |- @@ -20218,10 +20709,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 @@ -20371,9 +20859,12 @@ metadata: name: feast-operator-manager-role rules: - apiGroups: - - apps + - "" resources: - - deployments + - configmaps + - persistentvolumeclaims + - serviceaccounts + - services verbs: - create - delete @@ -20382,65 +20873,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: @@ -20651,12 +21139,14 @@ spec: - /manager env: - name: RELATED_IMAGE_FEATURE_SERVER - value: quay.io/feastdev/feature-server:0.62.0 + value: quay.io/feastdev/feature-server:0.63.0 - name: RELATED_IMAGE_CRON_JOB value: quay.io/openshift/origin-cli:4.17 + - name: GOMEMLIMIT + value: 230MiB - name: OIDC_ISSUER_URL value: "" - image: quay.io/feastdev/feast-operator:0.62.0 + image: quay.io/feastdev/feast-operator:0.63.0 livenessProbe: httpGet: path: /healthz diff --git a/infra/feast-operator/dist/operator-e2e-tests b/infra/feast-operator/dist/operator-e2e-tests index bb4e4c5d319..8a4bbe95ca8 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 df3e3456967..fc95a3b9eb4 100644 --- a/infra/feast-operator/docs/api/markdown/ref.md +++ b/infra/feast-operator/docs/api/markdown/ref.md @@ -150,7 +150,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 | @@ -278,6 +277,10 @@ _Appears in:_ | `batchEngine` _[BatchEngineConfig](#batchengineconfig)_ | | | `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 @@ -362,7 +365,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. | @@ -394,12 +396,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. @@ -411,7 +411,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 @@ -430,7 +429,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. @@ -472,6 +470,59 @@ _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:_ +- [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 @@ -581,6 +632,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 @@ -629,6 +682,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 @@ -918,6 +997,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/go.mod b/infra/feast-operator/go.mod index 7c60279b27b..c243e03d71b 100644 --- a/infra/feast-operator/go.mod +++ b/infra/feast-operator/go.mod @@ -1,34 +1,36 @@ module github.com/feast-dev/feast/infra/feast-operator -go 1.22.9 +go 1.24.12 require ( - github.com/onsi/ginkgo/v2 v2.17.2 - github.com/onsi/gomega v1.33.1 + 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.2 - k8s.io/apimachinery v0.30.2 - k8s.io/client-go v0.30.2 - sigs.k8s.io/controller-runtime v0.18.4 + k8s.io/api v0.33.0 + k8s.io/apimachinery v0.33.0 + k8s.io/client-go v0.33.0 + sigs.k8s.io/controller-runtime v0.21.0 ) require ( github.com/prometheus-operator/prometheus-operator/pkg/client v0.75.0 - k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 + k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 ) require ( - github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect + cel.dev/expr v0.19.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/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.1 // indirect - github.com/evanphx/json-patch/v5 v5.9.0 // indirect - github.com/felixge/httpsnoop v1.0.3 // 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/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/zapr v1.3.0 // indirect @@ -37,64 +39,65 @@ require ( github.com/go-openapi/swag v0.23.0 // 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-20240424215950-a892ee059fd6 // 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.16.0 // indirect - github.com/imdario/mergo v0.3.6 // 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/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-operator/prometheus-operator/pkg/apis/monitoring v0.75.0 // 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/client_golang v1.22.0 // indirect + github.com/prometheus/client_model v0.6.1 // 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.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect + go.opentelemetry.io/otel v1.33.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.33.0 // indirect + go.opentelemetry.io/otel/sdk v1.33.0 // indirect + go.opentelemetry.io/otel/trace v1.33.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.21.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.5.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.38.0 // indirect + golang.org/x/oauth2 v0.27.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/term v0.30.0 // indirect + golang.org/x/text v0.23.0 // indirect + golang.org/x/time v0.9.0 // indirect + golang.org/x/tools v0.28.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // 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.34.2 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect + google.golang.org/grpc v1.68.1 // indirect + google.golang.org/protobuf v1.36.5 // 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.2 // indirect - k8s.io/apiserver v0.30.2 // indirect - k8s.io/component-base v0.30.2 // indirect + k8s.io/apiextensions-apiserver v0.33.0 // indirect + k8s.io/apiserver v0.33.0 // indirect + k8s.io/component-base v0.33.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20240620174524-b456828f718b // 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/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-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.6.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 a95f53739b5..47e16adc5e2 100644 --- a/infra/feast-operator/go.sum +++ b/infra/feast-operator/go.sum @@ -1,13 +1,16 @@ -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.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4= +cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +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/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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -16,12 +19,14 @@ github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtz github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= github.com/evanphx/json-patch v5.9.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/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.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -39,44 +44,44 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v 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.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-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= -github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +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.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= -github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +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/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/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +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.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/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= @@ -84,10 +89,10 @@ 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.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= -github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= -github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= -github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +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= @@ -99,140 +104,153 @@ github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.75.0 h github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.75.0/go.mod h1:XYrdZw5dW12Cjkt4ndbeNZZTBp4UCHtW0ccR9+sTtPU= github.com/prometheus-operator/prometheus-operator/pkg/client v0.75.0 h1:QcchdrYyQ9qRY0KZlEjx6gYUjPOvkZDbzOlHMp4ix88= github.com/prometheus-operator/prometheus-operator/pkg/client v0.75.0/go.mod h1:ptPuQIiTdOvagifFhojZSJ/8VinU3/l7gOQ+Y6M0aqI= -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.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +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.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +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.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +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.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +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.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= +go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= +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.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= +go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= +go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= +go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= +go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= +go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= +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-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.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= -golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= +golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= 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.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 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-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.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= +golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= -golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= 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.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= +golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= 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/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.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q= +google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= +google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= +google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= 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.2 h1:+ZhRj+28QT4UOH+BKznu4CBgPWgkXO7XAvMcMl0qKvI= -k8s.io/api v0.30.2/go.mod h1:ULg5g9JvOev2dG0u2hig4Z7tQ2hHIuS+m8MNZ+X6EmI= -k8s.io/apiextensions-apiserver v0.30.2 h1:l7Eue2t6QiLHErfn2vwK4KgF4NeDgjQkCXtEbOocKIE= -k8s.io/apiextensions-apiserver v0.30.2/go.mod h1:lsJFLYyK40iguuinsb3nt+Sj6CmodSI4ACDLep1rgjw= -k8s.io/apimachinery v0.30.2 h1:fEMcnBj6qkzzPGSVsAZtQThU62SmQ4ZymlXRC5yFSCg= -k8s.io/apimachinery v0.30.2/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= -k8s.io/apiserver v0.30.2 h1:ACouHiYl1yFI2VFI3YGM+lvxgy6ir4yK2oLOsLI1/tw= -k8s.io/apiserver v0.30.2/go.mod h1:BOTdFBIch9Sv0ypSEcUR6ew/NUFGocRFNl72Ra7wTm8= -k8s.io/client-go v0.30.2 h1:sBIVJdojUNPDU/jObC+18tXWcTJVcwyqS9diGdWHk50= -k8s.io/client-go v0.30.2/go.mod h1:JglKSWULm9xlJLx4KCkfLLQ7XwtlbflV6uFFSHTMgVs= -k8s.io/component-base v0.30.2 h1:pqGBczYoW1sno8q9ObExUqrYSKhtE5rW3y6gX88GZII= -k8s.io/component-base v0.30.2/go.mod h1:yQLkQDrkK8J6NtP+MGJOws+/PPeEXNpwFixsUI7h/OE= +k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU= +k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM= +k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs= +k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc= +k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ= +k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= +k8s.io/apiserver v0.33.0 h1:QqcM6c+qEEjkOODHppFXRiw/cE2zP85704YrQ9YaBbc= +k8s.io/apiserver v0.33.0/go.mod h1:EixYOit0YTxt8zrO2kBU7ixAtxFce9gKGq367nFmqI8= +k8s.io/client-go v0.33.0 h1:UASR0sAYVUzs2kYuKn/ZakZlcs2bEHaizrrHUZg0G98= +k8s.io/client-go v0.33.0/go.mod h1:kGkd+l/gNGg8GYWAPr0xF1rRKvVWvzh9vmZAMXtaKOg= +k8s.io/component-base v0.33.0 h1:Ot4PyJI+0JAD9covDhwLp9UNkUja209OzsJ4FzScBNk= +k8s.io/component-base v0.33.0/go.mod h1:aXYZLbw3kihdkOPMDhWbjGCO6sg+luw554KP51t8qCU= 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-20240620174524-b456828f718b h1:Q9xmGWBvOGd8UJyccgpYlLosk/JlfP3xQLNkQlHJeXw= -k8s.io/kube-openapi v0.0.0-20240620174524-b456828f718b/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= -k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/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/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-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/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-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= +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.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= +sigs.k8s.io/structured-merge-diff/v4 v4.6.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 e9811c1c789..3ca5a6237ce 100644 --- a/infra/feast-operator/internal/controller/authz/authz.go +++ b/infra/feast-operator/internal/controller/authz/authz.go @@ -18,23 +18,33 @@ import ( // 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.createFeastClusterRole(); err != nil { - return err + if err := authz.createOidcClusterRole(); err != nil { + return authz.setFeastOidcAuthCondition(err) } - if err := authz.createFeastClusterRoleBinding(); err != nil { - return 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 } @@ -327,13 +337,110 @@ 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{"authentication.k8s.io"}, + Resources: []string{"tokenreviews"}, + Verbs: []string{"create"}, + }, + } + 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 = "Error: " + 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) diff --git a/infra/feast-operator/internal/controller/authz/authz_types.go b/infra/feast-operator/internal/controller/authz/authz_types.go index aea5e5f7a65..422b5f17525 100644 --- a/infra/feast-operator/internal/controller/authz/authz_types.go +++ b/infra/feast-operator/internal/controller/authz/authz_types.go @@ -25,4 +25,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_oidc_auth_test.go b/infra/feast-operator/internal/controller/featurestore_controller_oidc_auth_test.go index 16b57f8d7f5..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 @@ -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()) diff --git a/infra/feast-operator/internal/controller/services/namespace_registry.go b/infra/feast-operator/internal/controller/services/namespace_registry.go index c796f4ca6b6..dcea98a5764 100644 --- a/infra/feast-operator/internal/controller/services/namespace_registry.go +++ b/infra/feast-operator/internal/controller/services/namespace_registry.go @@ -20,7 +20,6 @@ import ( "encoding/json" "fmt" "os" - "reflect" corev1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" @@ -181,30 +180,17 @@ func (feast *FeastServices) setNamespaceRegistryRoleBinding(rb *rbacv1.RoleBindi Namespace: rb.Namespace, }, } - role.Rules = desiredRules + role.SetGroupVersionKind(rbacv1.SchemeGroupVersion.WithKind("Role")) - // Attempt to create; tolerate AlreadyExists so concurrent reconcilers don't fail. - if err := feast.Handler.Client.Create(feast.Handler.Context, role); err != nil && !apierrors.IsAlreadyExists(err) { - return fmt.Errorf("failed to create namespace registry Role: %w", err) - } - - // Re-fetch the authoritative copy to compare rules and obtain the latest resourceVersion. - existingRole := &rbacv1.Role{} - if err := feast.Handler.Client.Get(feast.Handler.Context, types.NamespacedName{ - Name: roleName, - Namespace: rb.Namespace, - }, existingRole); err != nil { - return fmt.Errorf("failed to get namespace registry Role: %w", err) - } - - if !reflect.DeepEqual(existingRole.Rules, desiredRules) { - existingRole.Rules = desiredRules - // On conflict the reconciler will re-queue automatically. - if err := feast.Handler.Client.Update(feast.Handler.Context, existingRole); err != nil { - return fmt.Errorf("failed to update namespace registry Role: %w", err) - } + 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 fmt.Errorf("failed to reconcile namespace registry Role: %w", err) } + rb.Labels = feast.getLabels() rb.RoleRef = rbacv1.RoleRef{ APIGroup: "rbac.authorization.k8s.io", Kind: "Role", diff --git a/infra/feast-operator/internal/controller/services/repo_config.go b/infra/feast-operator/internal/controller/services/repo_config.go index b67d948033b..42ca5373fd9 100644 --- a/infra/feast-operator/internal/controller/services/repo_config.go +++ b/infra/feast-operator/internal/controller/services/repo_config.go @@ -91,6 +91,21 @@ 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 + } + } + return repoConfig, nil } @@ -341,6 +356,127 @@ func setRepoConfigBatchEngine( return nil } +// 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 "true": + return true + case "false": + return false + } + return v +} + func (feast *FeastServices) getClientFeatureStoreYaml() ([]byte, error) { clientRepo := getClientRepoConfig(feast.Handler.FeatureStore, feast) return yaml.Marshal(clientRepo) 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 20fff934f19..8e1ae1d60bf 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() { @@ -317,6 +319,276 @@ var _ = Describe("Repo Config", func() { Expect(repoConfig.OnlineStore).To(Equal(expectedOnlineConfig)) Expect(repoConfig.Registry).To(Equal(expectedRegistryConfig)) }) + + 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 materialization block", func() { + featureStore := minimalFeatureStore() + batchSize := int32(10000) + + featureStore.Spec.Materialization = &feastdevv1.MaterializationConfig{ + OnlineWriteBatchSize: &batchSize, + ExtraConfig: map[string]string{ + "pull_latest_features": "false", + "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": "true", + "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: "lineage-secret", + }, + } + 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: "lineage-secret", + }, + } + 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("lineage-secret")) + }) + + 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: "lineage-secret", + }, + } + 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("lineage-secret")) + }) + + 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() 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/services.go b/infra/feast-operator/internal/controller/services/services.go index d8ff12a9348..47226d460aa 100644 --- a/infra/feast-operator/internal/controller/services/services.go +++ b/infra/feast-operator/internal/controller/services/services.go @@ -384,10 +384,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) @@ -408,9 +411,10 @@ 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{ @@ -600,7 +604,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 @@ -818,7 +825,7 @@ 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{ { @@ -868,6 +875,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, @@ -914,14 +922,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 } @@ -976,7 +1012,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()), }} } @@ -999,7 +1035,7 @@ 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()), }, }}, }, @@ -1060,12 +1096,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 + ":" @@ -1438,10 +1486,10 @@ func IsDeploymentAvailable(conditions []appsv1.DeploymentCondition) bool { // 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{} - labels := feast.getLabels() + selectorLabels := feast.getSelectorLabels() if err := feast.Handler.Client.List(feast.Handler.Context, &podList, client.InNamespace(deploy.Namespace), - client.MatchingLabels(labels), + client.MatchingLabels(selectorLabels), ); err != nil { return "" } diff --git a/infra/feast-operator/internal/controller/services/services_types.go b/infra/feast-operator/internal/controller/services/services_types.go index 5b4479698f3..aa67f529c44 100644 --- a/infra/feast-operator/internal/controller/services/services_types.go +++ b/infra/feast-operator/internal/controller/services/services_types.go @@ -103,6 +103,11 @@ const ( OidcMissingSecretError string = "missing OIDC secret: %s" ) +const ( + ManagedByLabelKey = "app.kubernetes.io/managed-by" + ManagedByLabelValue = "feast-operator" +) + var ( DefaultImage = "quay.io/feastdev/feature-server:" + feastversion.FeastVersion DefaultCronJobImage = "quay.io/openshift/origin-cli:4.17" @@ -255,14 +260,63 @@ 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"` +} + +// 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"` +} + +// 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. 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 b6e2fc9623c..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 @@ -16,6 +16,7 @@ spec: containers: - name: redis image: 'quay.io/feastdev-ci/feast-test-images:redis-7-alpine' + command: ["redis-server", "--save", ""] ports: - containerPort: 6379 env: 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/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/java/pom.xml b/java/pom.xml index 8d21af1c940..6e71d1bc19f 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -35,7 +35,7 @@ - 0.62.0 + 0.63.0 https://github.com/feast-dev/feast UTF-8 diff --git a/pixi.lock b/pixi.lock index 193bb7ea383..e6e724dce74 100644 --- a/pixi.lock +++ b/pixi.lock @@ -394,7 +394,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-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/fa/a6/5833ae272ae79dceeea58b6c7381c47cbcbd0113d0d0b04da8ae1ac45e48/testcontainers-4.15.0rc2-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/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 @@ -523,7 +523,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-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/fa/a6/5833ae272ae79dceeea58b6c7381c47cbcbd0113d0d0b04da8ae1ac45e48/testcontainers-4.15.0rc2-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/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 @@ -652,7 +652,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-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/fa/a6/5833ae272ae79dceeea58b6c7381c47cbcbd0113d0d0b04da8ae1ac45e48/testcontainers-4.15.0rc2-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/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 @@ -793,7 +793,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-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/fa/a6/5833ae272ae79dceeea58b6c7381c47cbcbd0113d0d0b04da8ae1ac45e48/testcontainers-4.15.0rc2-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/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 @@ -915,7 +915,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-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/fa/a6/5833ae272ae79dceeea58b6c7381c47cbcbd0113d0d0b04da8ae1ac45e48/testcontainers-4.15.0rc2-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/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 @@ -1037,7 +1037,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-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/fa/a6/5833ae272ae79dceeea58b6c7381c47cbcbd0113d0d0b04da8ae1ac45e48/testcontainers-4.15.0rc2-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/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 @@ -1144,7 +1144,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/b2/23/55d40e1bf54c141f541ab31b4b4b0f58610440c8837b1406f3467c2b4853/grpcio_testing-1.62.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/43/c8/8aaf447698c4d59aa853fd318eed300b5c9e44459f242ab8ead6c9c09792/gunicorn-25.3.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/b4/c6/b54c15a80c6192c0f7b518b2cbdc0c0b713c02428ba3099cba5dc2023e40/hiredis-3.3.1-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/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl @@ -1211,7 +1211,7 @@ environments: - 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/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/74/3a/95deec7db1eb53979973ebd156f3369a72732208d1391cd2e5d127062a32/redis-7.4.0-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/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3b/5d/63d4ae3b9daea098d5d6f5da83984853c1bbacd5dc826764b249fe119d24/requests_oauthlib-2.0.0-py2.py3-none-any.whl @@ -1226,7 +1226,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-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/fa/a6/5833ae272ae79dceeea58b6c7381c47cbcbd0113d0d0b04da8ae1ac45e48/testcontainers-4.15.0rc2-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/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b5/11/87d6d29fb5d237229d67973a6c9e06e048f01cf4994dee194ab0ea841814/tomlkit-0.14.0-py3-none-any.whl @@ -1317,7 +1317,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/b2/23/55d40e1bf54c141f541ab31b4b4b0f58610440c8837b1406f3467c2b4853/grpcio_testing-1.62.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/43/c8/8aaf447698c4d59aa853fd318eed300b5c9e44459f242ab8ead6c9c09792/gunicorn-25.3.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/80/76/88edf234200e9592c19f0de7d7af37092151524553b9c29a029f81fe7c9f/hiredis-3.3.1-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/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl @@ -1384,7 +1384,7 @@ environments: - 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/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/74/3a/95deec7db1eb53979973ebd156f3369a72732208d1391cd2e5d127062a32/redis-7.4.0-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/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3b/5d/63d4ae3b9daea098d5d6f5da83984853c1bbacd5dc826764b249fe119d24/requests_oauthlib-2.0.0-py2.py3-none-any.whl @@ -1399,7 +1399,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-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/fa/a6/5833ae272ae79dceeea58b6c7381c47cbcbd0113d0d0b04da8ae1ac45e48/testcontainers-4.15.0rc2-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/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b5/11/87d6d29fb5d237229d67973a6c9e06e048f01cf4994dee194ab0ea841814/tomlkit-0.14.0-py3-none-any.whl @@ -1490,7 +1490,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/b2/23/55d40e1bf54c141f541ab31b4b4b0f58610440c8837b1406f3467c2b4853/grpcio_testing-1.62.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/43/c8/8aaf447698c4d59aa853fd318eed300b5c9e44459f242ab8ead6c9c09792/gunicorn-25.3.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/10/13/433c4dada704c7f1b1b8261e713483b4cdfa462b1fced1a910ca173c1832/hiredis-3.3.1-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/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl @@ -1557,7 +1557,7 @@ environments: - 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/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/74/3a/95deec7db1eb53979973ebd156f3369a72732208d1391cd2e5d127062a32/redis-7.4.0-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/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/3b/5d/63d4ae3b9daea098d5d6f5da83984853c1bbacd5dc826764b249fe119d24/requests_oauthlib-2.0.0-py2.py3-none-any.whl @@ -1572,7 +1572,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-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/fa/a6/5833ae272ae79dceeea58b6c7381c47cbcbd0113d0d0b04da8ae1ac45e48/testcontainers-4.15.0rc2-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/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b5/11/87d6d29fb5d237229d67973a6c9e06e048f01cf4994dee194ab0ea841814/tomlkit-0.14.0-py3-none-any.whl @@ -2229,8 +2229,8 @@ packages: requires_python: '>=3.10' - pypi: ./ name: feast - version: 0.60.1.dev87+ge33047ba1 - sha256: d7bc70f699b91a11b2fe3f88eb56144eca2156776247d94c40f658ab39caa4a8 + version: 0.62.1.dev58+g4f142a3c1.d20260501 + sha256: 168dda185ac1fd0b97d388a4c5af598965dc17dfaaf09d35c7bb4ddbd3dafe43 requires_dist: - click>=7.0.0,<9.0.0 - colorama>=0.3.9,<1 @@ -2324,8 +2324,8 @@ packages: - 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' + - 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' @@ -2341,11 +2341,11 @@ 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 ; 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' + - feast[aws,azure,cassandra,clickhouse,couchbase,delta,docling,duckdb,elasticsearch,faiss,gcp,ge,go,grpcio,hazelcast,hbase,ibis,image,k8s,mcp,milvus,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' @@ -2967,20 +2967,20 @@ 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/10/13/433c4dada704c7f1b1b8261e713483b4cdfa462b1fced1a910ca173c1832/hiredis-3.3.1-cp310-cp310-macosx_11_0_arm64.whl name: hiredis - version: 2.4.0 - sha256: 87a8ece3e893f45354395c6b9dc0479744c1c8c6ee4471b60945d96c9b5ce6c2 + version: 3.3.1 + sha256: c1d68c6980d4690a4550bd3db6c03146f7be68ef5d08d38bb1fb68b3e9c32fe3 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/80/76/88edf234200e9592c19f0de7d7af37092151524553b9c29a029f81fe7c9f/hiredis-3.3.1-cp310-cp310-macosx_10_15_x86_64.whl name: hiredis - version: 2.4.0 - sha256: 76503a0edaf3d1557518127511e69e5d9fa37b6ff15598b0d9d9c2db18b08a41 + version: 3.3.1 + sha256: 6e2e1024f0a021777740cb7c633a0efb2c4a4bc570f508223a8dcbcf79f99ef9 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/b4/c6/b54c15a80c6192c0f7b518b2cbdc0c0b713c02428ba3099cba5dc2023e40/hiredis-3.3.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: hiredis - version: 2.4.0 - sha256: b027b53adb1df11923753d85587e3ab611fe70bc69596e9eb3269acab809c376 + version: 3.3.1 + sha256: 042e57de8a2cae91e3e7c0af32960ea2c5107b2f27f68a740295861e68780a8a requires_python: '>=3.8' - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl name: httpcore @@ -6316,19 +6316,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/74/3a/95deec7db1eb53979973ebd156f3369a72732208d1391cd2e5d127062a32/redis-7.4.0-py3-none-any.whl name: redis - version: 4.6.0 - sha256: e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c + version: 7.4.0 + sha256: a9c74a5c893a5ef8455a5adb793a31bb70feb821c86eccb62eebef5a19c429ec 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.9.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 @@ -6857,50 +6861,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/fa/a6/5833ae272ae79dceeea58b6c7381c47cbcbd0113d0d0b04da8ae1ac45e48/testcontainers-4.15.0rc2-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.0rc2 + sha256: e55b9045842c5bdfdd295e0d0b09aeafb3c1fb9d6f30bd8e718df8fd48dcdc41 + 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 diff --git a/protos/feast/core/FeatureView.proto b/protos/feast/core/FeatureView.proto index 19ffe562dc8..90207928ed0 100644 --- a/protos/feast/core/FeatureView.proto +++ b/protos/feast/core/FeatureView.proto @@ -36,7 +36,7 @@ message FeatureView { FeatureViewMeta meta = 2; } -// Next available id: 19 +// 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. @@ -97,6 +97,9 @@ message FeatureViewSpec { // 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; } message FeatureViewMeta { diff --git a/protos/feast/core/OnDemandFeatureView.proto b/protos/feast/core/OnDemandFeatureView.proto index d518f22c6cd..87c6a0eabfb 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: 18 +// Next available id: 19 message OnDemandFeatureViewSpec { // Name of the feature view. Must be unique. Not updated. string name = 1; @@ -77,6 +77,9 @@ message OnDemandFeatureViewSpec { // 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; } message OnDemandFeatureViewMeta { diff --git a/protos/feast/core/StreamFeatureView.proto b/protos/feast/core/StreamFeatureView.proto index 05c829b70d3..4aff7cc37e7 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: 22 +// Next available id: 23 message StreamFeatureViewSpec { // Name of the feature view. Must be unique. Not updated. string name = 1; @@ -105,5 +105,8 @@ message StreamFeatureViewSpec { // 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; } diff --git a/pyproject.toml b/pyproject.toml index 2e45d1820e7..a7b6b79ae33 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -123,8 +123,8 @@ ray = [ 'codeflare-sdk>=0.31.1; python_version > "3.10"' ] 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 = [ @@ -146,14 +146,14 @@ 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", ] 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, 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", @@ -295,7 +295,8 @@ 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"] } 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.rst b/sdk/python/docs/source/feast.rst index ffb8a2eb580..27231480da8 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 ---------------------------------- diff --git a/sdk/python/feast/__init__.py b/sdk/python/feast/__init__.py index c91e6b4c3ec..b1881c50150 100644 --- a/sdk/python/feast/__init__.py +++ b/sdk/python/feast/__init__.py @@ -17,7 +17,7 @@ from .chunker import BaseChunker, ChunkingConfig, TextChunker from .data_source import KafkaSource, KinesisSource, PushSource, RequestSource from .dataframe import DataFrameEngine, FeastDataFrame -from .doc_embedder import DocEmbedder, LogicalLayerFn +from .doc_embedder import DocEmbedder, SchemaTransformFn from .embedder import BaseEmbedder, EmbeddingConfig, MultiModalEmbedder from .entity import Entity from .feature import Feature @@ -66,7 +66,7 @@ "Project", "FeastVectorStore", "DocEmbedder", - "LogicalLayerFn", + "SchemaTransformFn", "BaseChunker", "TextChunker", "ChunkingConfig", diff --git a/sdk/python/feast/batch_feature_view.py b/sdk/python/feast/batch_feature_view.py index c9c53dfef91..95385da1d91 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] = "", @@ -151,6 +152,7 @@ def __init__( offline=offline, description=description, owner=owner, + org=org, schema=schema, source=source, # type: ignore[arg-type] sink_source=sink_source, @@ -189,6 +191,7 @@ 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", @@ -219,6 +222,7 @@ def decorator(user_function): offline=offline, description=description, owner=owner, + org=org, schema=schema, udf=user_function, udf_string=udf_string, diff --git a/sdk/python/feast/doc_embedder.py b/sdk/python/feast/doc_embedder.py index dca2fdef2d0..9ccd8ec461b 100644 --- a/sdk/python/feast/doc_embedder.py +++ b/sdk/python/feast/doc_embedder.py @@ -14,11 +14,11 @@ @runtime_checkable -class LogicalLayerFn(Protocol): +class SchemaTransformFn(Protocol): """ - Protocol defining the structure for logical layer functions. + Protocol defining the structure for schema transform functions. - The logical layer transforms the output of Chunker + Embedder + The schema transform converts the output of Chunker + Embedder into the format expected by the FeatureView schema. """ @@ -35,9 +35,9 @@ def __call__(self, df: pd.DataFrame) -> pd.DataFrame: ... -def default_logical_layer_fn(df: pd.DataFrame) -> pd.DataFrame: +def default_schema_transform_fn(df: pd.DataFrame) -> pd.DataFrame: """ - Default logical layer function that transforms the output of Chunker + Embedder + Default schema transform function that transforms the output of Chunker + Embedder into the format expected by the FeatureView schema. """ from datetime import datetime, timezone @@ -156,7 +156,7 @@ class DocEmbedder: 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. - logical_layer_fn: Logical layer function to use for transforming the output of the chunker and embedder into the format expected by the FeatureView schema. + 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 @@ -172,7 +172,7 @@ def __init__( feature_view_name: str = "text_feature_view", chunker: Optional[BaseChunker] = None, embedder: Optional[BaseEmbedder] = None, - logical_layer_fn: LogicalLayerFn = default_logical_layer_fn, + schema_transform_fn: SchemaTransformFn = default_schema_transform_fn, create_feature_view: bool = True, vector_length: Optional[int] = None, auto_apply_repo: bool = True, @@ -184,7 +184,7 @@ def __init__( self.embedder = embedder or MultiModalEmbedder() self.store: Optional[FeatureStore] = None - sig = inspect.signature(logical_layer_fn) + sig = inspect.signature(schema_transform_fn) params = list(sig.parameters.values()) if ( len(params) != 1 @@ -192,9 +192,9 @@ def __init__( or sig.return_annotation != pd.DataFrame ): raise ValueError( - "logical_layer_fn must be a function that takes a DataFrame and returns a DataFrame" + "schema_transform_fn must be a function that takes a DataFrame and returns a DataFrame" ) - self.logical_layer_fn = logical_layer_fn + self.schema_transform_fn = schema_transform_fn if create_feature_view: resolved_vector_length = self._resolve_vector_length(vector_length, "text") generate_repo_file( @@ -287,7 +287,7 @@ def embed_documents( source_column: str, type_column: Optional[str] = None, column_mapping: Optional[tuple[str, str]] = None, - custom_logical_layer_fn: Optional[ + custom_schema_transform_fn: Optional[ Callable[[pd.DataFrame], pd.DataFrame] ] = None, ) -> pd.DataFrame: @@ -300,7 +300,7 @@ def embed_documents( 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_logical_layer_fn: Custom logical layer function to use for transforming the output of the chunker and embedder into the format expected by the FeatureView schema. + 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. @@ -315,8 +315,8 @@ def embed_documents( df = embed_documents(documents=documents, id_column="id", source_column="source", type_column="type", column_mapping=column_mapping) """ - if custom_logical_layer_fn is not None: - sig = inspect.signature(custom_logical_layer_fn) + if custom_schema_transform_fn is not None: + sig = inspect.signature(custom_schema_transform_fn) params = list(sig.parameters.values()) if ( len(params) != 1 @@ -324,27 +324,27 @@ def embed_documents( or sig.return_annotation != pd.DataFrame ): raise ValueError( - "custom_logical_layer_fn must be a function that takes a DataFrame and returns a DataFrame" + "custom_schema_transform_fn must be a function that takes a DataFrame and returns a DataFrame" ) - current_logical_layer_fn = ( - custom_logical_layer_fn - if custom_logical_layer_fn is not None - else self.logical_layer_fn + 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_logical_layer_fn is default_logical_layer_fn + 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_logical_layer_fn, which expects " + 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 logical_layer_fn." + f"Provide a custom schema_transform_fn." ) if column_mapping[0] == "text": @@ -363,15 +363,15 @@ def embed_documents( if ( column_mapping[0] == "text" - or current_logical_layer_fn is not default_logical_layer_fn + or current_schema_transform_fn is not default_schema_transform_fn ): - df = current_logical_layer_fn(df) + df = current_schema_transform_fn(df) else: warnings.warn( - f"Modality '{column_mapping[0]}' is not supported by the default logical layer function. " + 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 logical layer function to handle this.", + f"You can provide a custom schema transform function to handle this.", UserWarning, stacklevel=2, ) 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 fb35ff79de8..515a6c39b11 100644 --- a/sdk/python/feast/errors.py +++ b/sdk/python/feast/errors.py @@ -142,7 +142,7 @@ 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, and MySQL support version-qualified feature references. " + f"Currently only SQLite, PostgreSQL, MySQL, FAISS, Redis, and DynamoDB support version-qualified feature references. " ) diff --git a/sdk/python/feast/feature_view.py b/sdk/python/feast/feature_view.py index 3863634ac80..da11a7958ca 100644 --- a/sdk/python/feast/feature_view.py +++ b/sdk/python/feast/feature_view.py @@ -89,6 +89,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). @@ -107,6 +109,7 @@ 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 @@ -125,6 +128,7 @@ 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", @@ -152,6 +156,8 @@ 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 @@ -278,6 +284,7 @@ def __init__( owner=owner, source=self.batch_source, ) + self.org = org self.online = online self.offline = offline self.mode = mode @@ -302,6 +309,7 @@ def __copy__(self): version=self.version, description=self.description, owner=self.owner, + org=self.org, ) # This is deliberately set outside of the FV initialization as we do not have the Entity objects. @@ -355,6 +363,7 @@ def __eq__(self, other): 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 @@ -485,6 +494,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, @@ -520,14 +530,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. @@ -561,7 +574,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 ] @@ -581,22 +594,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: @@ -611,6 +625,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=( @@ -633,6 +648,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=( diff --git a/sdk/python/feast/field.py b/sdk/python/feast/field.py index e155836467b..3055bd70830 100644 --- a/sdk/python/feast/field.py +++ b/sdk/python/feast/field.py @@ -136,7 +136,7 @@ def to_proto(self) -> FieldProto: 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, 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/feature_builder.py b/sdk/python/feast/infra/compute_engines/feature_builder.py index 8510b676c07..43f17ee2986 100644 --- a/sdk/python/feast/infra/compute_engines/feature_builder.py +++ b/sdk/python/feast/infra/compute_engines/feature_builder.py @@ -158,9 +158,14 @@ 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") or getattr(mode, "value", None) in ( + "ray", + "pandas", + "python", + ): + # 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/local/nodes.py b/sdk/python/feast/infra/compute_engines/local/nodes.py index db65761a5e2..808231419cd 100644 --- a/sdk/python/feast/infra/compute_engines/local/nodes.py +++ b/sdk/python/feast/infra/compute_engines/local/nodes.py @@ -361,10 +361,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 +375,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 +404,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 5b16f3edd05..026c46d4233 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 @@ -559,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__( @@ -566,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.""" @@ -577,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, @@ -688,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( @@ -830,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..5aa8c384cdd 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, 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,49 @@ 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 = {"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/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/feature_servers/multicloud/Dockerfile b/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile index 2834f98ca10..010447371a8 100644 --- a/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile +++ b/sdk/python/feast/infra/feature_servers/multicloud/Dockerfile @@ -1,7 +1,7 @@ FROM registry.access.redhat.com/ubi9/python-312-minimal:1 USER 0 -RUN microdnf install -y gcc libpq-devel python3.12-devel && microdnf clean all +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 diff --git a/sdk/python/feast/infra/feature_servers/multicloud/requirements.txt b/sdk/python/feast/infra/feature_servers/multicloud/requirements.txt index 18fc3a66969..6c97dbd7f0a 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.62.0 +feast[minimal] == 0.63.0 diff --git a/sdk/python/feast/infra/offline_stores/bigquery_source.py b/sdk/python/feast/infra/offline_stores/bigquery_source.py index 69e42e3fd09..7b476afdcda 100644 --- a/sdk/python/feast/infra/offline_stores/bigquery_source.py +++ b/sdk/python/feast/infra/offline_stores/bigquery_source.py @@ -47,15 +47,15 @@ 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. date_partition_column (optional): Timestamp column used for partitioning. - query (optional): The query to be executed to obtain the features. Exactly one of 'table' - and 'query' must be specified. + 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 @@ -156,10 +156,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]: @@ -185,14 +185,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/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/ray_offline_store/ray.py b/sdk/python/feast/infra/offline_stores/contrib/ray_offline_store/ray.py index 47785ccea29..1831959651f 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 @@ -365,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: """ @@ -382,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: @@ -421,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" ) @@ -1010,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, @@ -1060,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 @@ -1140,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): @@ -1246,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( @@ -1256,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: @@ -1417,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: @@ -1462,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: @@ -1477,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) @@ -1635,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], @@ -1643,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 = ( @@ -1703,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( @@ -1742,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 group.drop_duplicates(subset=available_join_keys, keep="first") - return batch - - 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( @@ -1777,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(): @@ -1841,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) @@ -2159,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..d915c596de8 --- /dev/null +++ b/sdk/python/feast/infra/offline_stores/contrib/ray_offline_store/ray_offline_store_reader.py @@ -0,0 +1,130 @@ +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": + from datasets import load_dataset + + dataset_name = opts.get("dataset_name") or path + split = opts.get("split", "train") + # trust_remote_code was removed in datasets>=3.0; skip silently if present. + extra = { + k: v + for k, v in opts.items() + if k not in ("dataset_name", "split", "trust_remote_code") + } + hf_dataset = load_dataset(dataset_name, split=split, **extra) + return ray_wrapper.from_huggingface(hf_dataset) + + 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 c7ed40ccc02..3fc675ea402 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 @@ -33,6 +33,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 @@ -260,6 +261,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), @@ -387,12 +392,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( @@ -707,6 +718,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/dask.py b/sdk/python/feast/infra/offline_stores/dask.py index be430f87c90..3e640ce5af0 100644 --- a/sdk/python/feast/infra/offline_stores/dask.py +++ b/sdk/python/feast/infra/offline_stores/dask.py @@ -377,7 +377,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( @@ -399,16 +402,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: @@ -483,9 +493,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( diff --git a/sdk/python/feast/infra/offline_stores/offline_store.py b/sdk/python/feast/infra/offline_stores/offline_store.py index 8887a5a7d0c..4ae0c680c3b 100644 --- a/sdk/python/feast/infra/offline_stores/offline_store.py +++ b/sdk/python/feast/infra/offline_stores/offline_store.py @@ -259,6 +259,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. diff --git a/sdk/python/feast/infra/offline_stores/remote.py b/sdk/python/feast/infra/offline_stores/remote.py index 4e48f225f16..a32774ad085 100644 --- a/sdk/python/feast/infra/offline_stores/remote.py +++ b/sdk/python/feast/infra/offline_stores/remote.py @@ -249,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__, @@ -470,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/online_stores/dynamodb.py b/sdk/python/feast/infra/online_stores/dynamodb.py index 814058c77e5..1998167e4b0 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 @@ -1154,8 +1154,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/faiss_online_store.py b/sdk/python/feast/infra/online_stores/faiss_online_store.py index 3e3d92cde6d..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)) @@ -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 40e0f50a62c..59ef9185c1f 100644 --- a/sdk/python/feast/infra/online_stores/helpers.py +++ b/sdk/python/feast/infra/online_stores/helpers.py @@ -72,8 +72,8 @@ def _to_naive_utc(ts: datetime) -> datetime: return ts.astimezone(tz=timezone.utc).replace(tzinfo=None) -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.""" +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) @@ -81,4 +81,9 @@ def compute_table_id(project: str, table: Any, enable_versioning: bool = False) version = getattr(table, "current_version_number", None) if version is not None and version > 0: name = f"{table.name}_v{version}" - return f"{project}_{name}" + 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 ee2534684cc..941de3b64cd 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,4 +1,5 @@ import base64 +import logging from datetime import datetime from pathlib import Path from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple, Union @@ -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, @@ -140,11 +144,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,7 +165,9 @@ 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) @@ -339,10 +347,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 +496,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 +517,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, @@ -547,7 +555,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") @@ -686,9 +696,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 @@ -745,9 +754,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/online_store.py b/sdk/python/feast/infra/online_stores/online_store.py index 41555ccfb2b..5b5daf17575 100644 --- a/sdk/python/feast/infra/online_stores/online_store.py +++ b/sdk/python/feast/infra/online_stores/online_store.py @@ -274,6 +274,32 @@ def _check_versioned_read_support(self, grouped_refs): supported_types.append(PostgreSQLOnlineStore) except ImportError: pass + try: + from feast.infra.online_stores.faiss_online_store import FaissOnlineStore + + supported_types.append(FaissOnlineStore) + except ImportError: + pass + try: + from feast.infra.online_stores.redis import RedisOnlineStore + + supported_types.append(RedisOnlineStore) + except Exception: + pass + try: + from feast.infra.online_stores.dynamodb import DynamoDBOnlineStore + + supported_types.append(DynamoDBOnlineStore) + except Exception: + pass + try: + from feast.infra.online_stores.milvus_online_store.milvus import ( + MilvusOnlineStore, + ) + + supported_types.append(MilvusOnlineStore) + except ImportError: + pass if isinstance(self, tuple(supported_types)): return diff --git a/sdk/python/feast/infra/online_stores/redis.py b/sdk/python/feast/infra/online_stores/redis.py index aeeb540b910..7531fd5d2f0 100644 --- a/sdk/python/feast/infra/online_stores/redis.py +++ b/sdk/python/feast/infra/online_stores/redis.py @@ -22,6 +22,7 @@ Dict, List, Literal, + Mapping, Optional, Sequence, Tuple, @@ -32,9 +33,18 @@ 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.feature_service import FeatureService +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.registry.base_registry import BaseRegistry +from feast.online_response import OnlineResponse 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 @@ -51,6 +61,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 +96,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): """ @@ -113,27 +135,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 +180,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 +319,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,6 +406,98 @@ 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]: @@ -355,13 +515,15 @@ 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,158 @@ 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 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: + """ + Fetch online features for multiple feature views in a single Redis pipeline. + + Overrides the base class implementation which issues one pipeline per feature view + (O(N_feature_views) round trips). This implementation batches all HMGET commands + across all feature views into a single pipeline execution (O(1) round trips), + exploiting the fact that all feature views for the same entity share the same + Redis hash key. + """ + 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(): + try: + columnar[key].append(value) + except KeyError as e: + raise ValueError( + "All entity_rows must have the same keys." + ) from e + entity_rows = columnar + + ( + join_key_values, + grouped_refs, + entity_name_to_join_key_map, + requested_on_demand_feature_views, + feature_refs, + requested_result_row_names, + online_features_response, + ) = utils._prepare_entities_to_read_from_online_store( + registry=registry, + project=project, + features=features, + entity_values=entity_rows, + full_feature_names=full_feature_names, + native_entity_values=True, + ) + + 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() + + # Pre-compute all Redis keys and hash field keys for every feature view so we + # can issue all HMGET commands in a single pipeline execution below. + 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 + ) + + # Mutates requested_features in place (appends ts_key) — consistent with + # the base class behavior so _populate_response_from_feature_data works correctly. + 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) + ) + + # Single pipeline across all feature views: O(1) round trips instead of O(N_fv). + 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, + ) + + 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) + def _get_features_for_entity( self, values: List[ByteString], @@ -459,4 +772,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 9bead1fcb9d..ac3cc2b4b13 100644 --- a/sdk/python/feast/infra/online_stores/remote.py +++ b/sdk/python/feast/infra/online_stores/remote.py @@ -501,7 +501,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/ray_initializer.py b/sdk/python/feast/infra/ray_initializer.py index eea21eaa321..9504e46a2b8 100644 --- a/sdk/python/feast/infra/ray_initializer.py +++ b/sdk/python/feast/infra/ray_initializer.py @@ -219,6 +219,53 @@ 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: Any, **kwargs) -> Any: + """Convert a HuggingFace datasets.Dataset to a Ray Dataset.""" + return ray.data.from_huggingface(dataset, **kwargs) + def from_pandas(self, df: Any) -> Any: """Create dataset from pandas DataFrame using standard Ray.""" return ray.data.from_pandas(df) @@ -239,6 +286,8 @@ def __init__( auth_server: str, skip_tls: bool = False, enable_logging: bool = False, + num_gpus: float = 0, + worker_task_options: Optional[Dict[str, Any]] = None, ): """Initialize CodeFlare Ray wrapper with cluster connection parameters.""" self.cluster_name = cluster_name @@ -247,6 +296,8 @@ 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.cluster = None # Authenticate and setup Ray connection @@ -307,54 +358,220 @@ 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: Any, **kwargs) -> Any: + """Convert a HuggingFace dataset - dispatched via @ray.remote to cluster workers. + + Serialises the HuggingFace dataset and runs ray.data.from_huggingface() + on the cluster so the Ray Client driver is not involved in Ray Data ops. + """ + from feast.infra.ray_shared_utils import RemoteDatasetProxy + + @ray.remote + def _remote(hf_dataset, read_kwargs): + import ray + + return ray.data.from_huggingface(hf_dataset, **read_kwargs) + + opts = self._get_task_options() + remote_fn = _remote.options(**opts) if opts else _remote + return RemoteDatasetProxy(remote_fn.remote(dataset, 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 @@ -551,6 +768,8 @@ def _initialize_kuberay(config: Any, enable_logging: bool = False) -> None: auth_server=kuberay_config["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), ) 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/registry.py b/sdk/python/feast/infra/registry/registry.py index 76da6ad831d..f3437b08f30 100644 --- a/sdk/python/feast/infra/registry/registry.py +++ b/sdk/python/feast/infra/registry/registry.py @@ -386,6 +386,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 @@ -394,7 +400,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: @@ -423,7 +432,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() diff --git a/sdk/python/feast/infra/registry/snowflake.py b/sdk/python/feast/infra/registry/snowflake.py index 68bf376e650..6382fa1c010 100644 --- a/sdk/python/feast/infra/registry/snowflake.py +++ b/sdk/python/feast/infra/registry/snowflake.py @@ -139,20 +139,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 +161,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 +191,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 +206,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 +227,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) @@ -373,7 +385,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) @@ -518,10 +531,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, @@ -535,10 +546,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, @@ -554,9 +563,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", @@ -573,10 +582,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, @@ -592,9 +599,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", @@ -638,9 +645,9 @@ def list_all_feature_views( tags: Optional[dict[str, str]] = None, ) -> 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 ) return ( @@ -676,9 +683,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", @@ -695,10 +702,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, @@ -714,9 +719,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", @@ -733,9 +738,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", @@ -784,10 +789,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, @@ -807,10 +810,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, @@ -827,10 +828,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 ) @@ -842,9 +841,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", @@ -862,9 +861,9 @@ def list_feature_views( tags: Optional[dict[str, str]] = None, ) -> 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 ) return self._list_objects( "FEATURE_VIEWS", @@ -882,9 +881,9 @@ def list_on_demand_feature_views( tags: Optional[dict[str, str]] = None, ) -> 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 ) return self._list_objects( "ON_DEMAND_FEATURE_VIEWS", @@ -902,9 +901,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", @@ -922,9 +921,9 @@ def list_stream_feature_views( tags: Optional[dict[str, str]] = None, ) -> 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 ) return self._list_objects( "STREAM_FEATURE_VIEWS", @@ -987,10 +986,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, @@ -1039,10 +1036,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 @@ -1116,7 +1111,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() @@ -1135,18 +1131,6 @@ 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) @@ -1161,7 +1145,9 @@ def process_project(project: Project): (self.list_validation_references, r.validation_references), (self.list_permissions, r.permissions), ]: - objs: List[Any] = lister(project_name, allow_cache) # type: ignore + # Always bypass cache here: proto() builds the cache, so using + # allow_cache=True would cause infinite recursion via refresh(). + objs: List[Any] = lister(project_name, False) # type: ignore if objs: obj_protos = [obj.to_proto() for obj in objs] for obj_proto in obj_protos: @@ -1322,7 +1308,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 @@ -1350,8 +1336,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( @@ -1367,7 +1353,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) @@ -1380,8 +1366,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/utils/snowflake/registry/snowflake_table_deletion.sql b/sdk/python/feast/infra/utils/snowflake/registry/snowflake_table_deletion.sql index 780424abd17..dde984c3823 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,6 @@ 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"; diff --git a/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py b/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py index b9254e72699..1890cb6a087 100644 --- a/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py +++ b/sdk/python/feast/infra/utils/snowflake/snowflake_utils.py @@ -86,9 +86,9 @@ def __enter__(self): # 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/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 7786af6f2f5..694f25a687e 100644 --- a/sdk/python/feast/metrics.py +++ b/sdk/python/feast/metrics.py @@ -198,6 +198,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 @@ -334,6 +339,22 @@ def track_online_store_read(duration_seconds: float): 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: @@ -378,8 +399,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: diff --git a/sdk/python/feast/offline_server.py b/sdk/python/feast/offline_server.py index ffe648e8749..0373b3a8146 100644 --- a/sdk/python/feast/offline_server.py +++ b/sdk/python/feast/offline_server.py @@ -436,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 530a96065a8..dbd7738f21d 100644 --- a/sdk/python/feast/on_demand_feature_view.py +++ b/sdk/python/feast/on_demand_feature_view.py @@ -131,20 +131,24 @@ 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 @@ -158,7 +162,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, @@ -166,6 +171,7 @@ 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, @@ -183,6 +189,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) @@ -192,6 +203,8 @@ 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 @@ -211,18 +224,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] = [] @@ -259,9 +302,12 @@ 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": @@ -271,6 +317,20 @@ def __init__( # noqa: C901 self.track_metrics = track_metrics self.aggregations = aggregations or [] + 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: """ Add a source to the appropriate collection with explicit type checking. @@ -325,15 +385,18 @@ 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 @@ -408,6 +471,7 @@ def __eq__(self, other): or self.aggregations != other.aggregations or normalize_version_string(self.version) != normalize_version_string(other.version) + or self.org != other.org ): return False @@ -472,6 +536,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()) @@ -533,6 +601,14 @@ def to_proto(self) -> OnDemandFeatureViewProto: request_data_source=request_sources.to_proto() ) + # 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() + ) + feature_transformation = transformation_to_proto(self.feature_transformation) tags = dict(self.tags) if self.tags else {} @@ -554,9 +630,10 @@ def to_proto(self) -> OnDemandFeatureViewProto: description=self.description, 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, ) return OnDemandFeatureViewProto(spec=spec, meta=meta) @@ -578,11 +655,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 + ) + + # 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 + # 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 @@ -602,11 +693,13 @@ def from_proto( 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=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, @@ -643,7 +736,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] = [] @@ -652,7 +745,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( @@ -673,9 +768,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 @@ -700,6 +798,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: @@ -807,6 +907,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: @@ -898,6 +1002,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 ) @@ -983,6 +1088,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 @@ -1024,6 +1130,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 @@ -1079,7 +1193,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 @@ -1124,6 +1238,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]]: @@ -1211,17 +1332,22 @@ 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, @@ -1239,11 +1365,17 @@ 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 @@ -1266,15 +1398,18 @@ 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, 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..45d021f2f07 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( diff --git a/sdk/python/feast/openlineage/emitter.py b/sdk/python/feast/openlineage/emitter.py index 1f63e39210e..7486d04be27 100644 --- a/sdk/python/feast/openlineage/emitter.py +++ b/sdk/python/feast/openlineage/emitter.py @@ -644,11 +644,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/protos/feast/core/FeatureView_pb2.py b/sdk/python/feast/protos/feast/core/FeatureView_pb2.py index 43995d4aa72..de3fb93cb1f 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\"\x80\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\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x80\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\"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\"\x8d\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\x1a+\n\tTagsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\x80\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\"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') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -32,13 +32,13 @@ _globals['_FEATUREVIEW']._serialized_start=197 _globals['_FEATUREVIEW']._serialized_end=296 _globals['_FEATUREVIEWSPEC']._serialized_start=299 - _globals['_FEATUREVIEWSPEC']._serialized_end=939 - _globals['_FEATUREVIEWSPEC_TAGSENTRY']._serialized_start=896 - _globals['_FEATUREVIEWSPEC_TAGSENTRY']._serialized_end=939 - _globals['_FEATUREVIEWMETA']._serialized_start=942 - _globals['_FEATUREVIEWMETA']._serialized_end=1198 - _globals['_MATERIALIZATIONINTERVAL']._serialized_start=1200 - _globals['_MATERIALIZATIONINTERVAL']._serialized_end=1319 - _globals['_FEATUREVIEWLIST']._serialized_start=1321 - _globals['_FEATUREVIEWLIST']._serialized_end=1385 + _globals['_FEATUREVIEWSPEC']._serialized_end=952 + _globals['_FEATUREVIEWSPEC_TAGSENTRY']._serialized_start=909 + _globals['_FEATUREVIEWSPEC_TAGSENTRY']._serialized_end=952 + _globals['_FEATUREVIEWMETA']._serialized_start=955 + _globals['_FEATUREVIEWMETA']._serialized_end=1211 + _globals['_MATERIALIZATIONINTERVAL']._serialized_start=1213 + _globals['_MATERIALIZATIONINTERVAL']._serialized_end=1332 + _globals['_FEATUREVIEWLIST']._serialized_start=1334 + _globals['_FEATUREVIEWLIST']._serialized_end=1398 # @@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 a62e275260f..4e22ad1b12b 100644 --- a/sdk/python/feast/protos/feast/core/FeatureView_pb2.pyi +++ b/sdk/python/feast/protos/feast/core/FeatureView_pb2.pyi @@ -58,7 +58,7 @@ class FeatureView(google.protobuf.message.Message): global___FeatureView = FeatureView class FeatureViewSpec(google.protobuf.message.Message): - """Next available id: 19 + """Next available id: 20 TODO(adchia): refactor common fields from this and ODFV into separate metadata proto """ @@ -97,6 +97,7 @@ class FeatureViewSpec(google.protobuf.message.Message): MODE_FIELD_NUMBER: builtins.int ENABLE_VALIDATION_FIELD_NUMBER: builtins.int VERSION_FIELD_NUMBER: builtins.int + ORG_FIELD_NUMBER: builtins.int name: builtins.str """Name of the feature view. Must be unique. Not updated.""" project: builtins.str @@ -151,6 +152,8 @@ class FeatureViewSpec(google.protobuf.message.Message): """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").""" def __init__( self, *, @@ -172,9 +175,10 @@ class FeatureViewSpec(google.protobuf.message.Message): mode: builtins.str = ..., enable_validation: builtins.bool = ..., version: builtins.str = ..., + org: builtins.str = ..., ) -> 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", "version", b"version"]) -> None: ... + 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", "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 diff --git a/sdk/python/feast/protos/feast/core/OnDemandFeatureView_pb2.py b/sdk/python/feast/protos/feast/core/OnDemandFeatureView_pb2.py index 629c02c3a5f..313d93ca38d 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\"\xd0\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\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\"\xc0\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\"\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\"\xdd\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\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\"\xc0\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\"\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=1119 - _globals['_ONDEMANDFEATUREVIEWSPEC_SOURCESENTRY']._serialized_start=1000 - _globals['_ONDEMANDFEATUREVIEWSPEC_SOURCESENTRY']._serialized_end=1074 - _globals['_ONDEMANDFEATUREVIEWSPEC_TAGSENTRY']._serialized_start=1076 - _globals['_ONDEMANDFEATUREVIEWSPEC_TAGSENTRY']._serialized_end=1119 - _globals['_ONDEMANDFEATUREVIEWMETA']._serialized_start=1122 - _globals['_ONDEMANDFEATUREVIEWMETA']._serialized_end=1314 - _globals['_ONDEMANDSOURCE']._serialized_start=1317 - _globals['_ONDEMANDSOURCE']._serialized_end=1517 - _globals['_USERDEFINEDFUNCTION']._serialized_start=1519 - _globals['_USERDEFINEDFUNCTION']._serialized_end=1591 - _globals['_ONDEMANDFEATUREVIEWLIST']._serialized_start=1593 - _globals['_ONDEMANDFEATUREVIEWLIST']._serialized_end=1681 + _globals['_ONDEMANDFEATUREVIEWSPEC']._serialized_end=1132 + _globals['_ONDEMANDFEATUREVIEWSPEC_SOURCESENTRY']._serialized_start=1013 + _globals['_ONDEMANDFEATUREVIEWSPEC_SOURCESENTRY']._serialized_end=1087 + _globals['_ONDEMANDFEATUREVIEWSPEC_TAGSENTRY']._serialized_start=1089 + _globals['_ONDEMANDFEATUREVIEWSPEC_TAGSENTRY']._serialized_end=1132 + _globals['_ONDEMANDFEATUREVIEWMETA']._serialized_start=1135 + _globals['_ONDEMANDFEATUREVIEWMETA']._serialized_end=1327 + _globals['_ONDEMANDSOURCE']._serialized_start=1330 + _globals['_ONDEMANDSOURCE']._serialized_end=1530 + _globals['_USERDEFINEDFUNCTION']._serialized_start=1532 + _globals['_USERDEFINEDFUNCTION']._serialized_end=1604 + _globals['_ONDEMANDFEATUREVIEWLIST']._serialized_start=1606 + _globals['_ONDEMANDFEATUREVIEWLIST']._serialized_end=1694 # @@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 42fd91f7725..52998281a3f 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: 18""" + """Next available id: 19""" DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -111,6 +111,7 @@ class OnDemandFeatureViewSpec(google.protobuf.message.Message): SINGLETON_FIELD_NUMBER: builtins.int AGGREGATIONS_FIELD_NUMBER: builtins.int VERSION_FIELD_NUMBER: builtins.int + ORG_FIELD_NUMBER: builtins.int name: builtins.str """Name of the feature view. Must be unique. Not updated.""" project: builtins.str @@ -147,6 +148,8 @@ class OnDemandFeatureViewSpec(google.protobuf.message.Message): """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").""" def __init__( self, *, @@ -166,9 +169,10 @@ class OnDemandFeatureViewSpec(google.protobuf.message.Message): singleton: builtins.bool = ..., aggregations: collections.abc.Iterable[feast.core.Aggregation_pb2.Aggregation] | None = ..., version: builtins.str = ..., + org: builtins.str = ..., ) -> 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", "version", b"version", "write_to_online_store", b"write_to_online_store"]) -> None: ... + 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", "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 diff --git a/sdk/python/feast/protos/feast/core/StreamFeatureView_pb2.py b/sdk/python/feast/protos/feast/core/StreamFeatureView_pb2.py index 3c87e635b92..85a61d06005 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\"\x9f\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\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\"\xac\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\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=1181 - _globals['_STREAMFEATUREVIEWSPEC_TAGSENTRY']._serialized_start=1138 - _globals['_STREAMFEATUREVIEWSPEC_TAGSENTRY']._serialized_end=1181 + _globals['_STREAMFEATUREVIEWSPEC']._serialized_end=1194 + _globals['_STREAMFEATUREVIEWSPEC_TAGSENTRY']._serialized_start=1151 + _globals['_STREAMFEATUREVIEWSPEC_TAGSENTRY']._serialized_end=1194 # @@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 b4ab6a9a016..26ff6a42534 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: 22""" + """Next available id: 23""" DESCRIPTOR: google.protobuf.descriptor.Descriptor @@ -99,6 +99,7 @@ class StreamFeatureViewSpec(google.protobuf.message.Message): TILING_HOP_SIZE_FIELD_NUMBER: builtins.int ENABLE_VALIDATION_FIELD_NUMBER: builtins.int VERSION_FIELD_NUMBER: builtins.int + ORG_FIELD_NUMBER: builtins.int name: builtins.str """Name of the feature view. Must be unique. Not updated.""" project: builtins.str @@ -158,6 +159,8 @@ class StreamFeatureViewSpec(google.protobuf.message.Message): """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").""" def __init__( self, *, @@ -182,8 +185,9 @@ class StreamFeatureViewSpec(google.protobuf.message.Message): tiling_hop_size: google.protobuf.duration_pb2.Duration | None = ..., enable_validation: builtins.bool = ..., version: builtins.str = ..., + org: builtins.str = ..., ) -> 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", "version", b"version"]) -> None: ... + 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", "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/types/Value_pb2.pyi b/sdk/python/feast/protos/feast/types/Value_pb2.pyi index c0b7bada7bb..80c6a717acf 100644 --- a/sdk/python/feast/protos/feast/types/Value_pb2.pyi +++ b/sdk/python/feast/protos/feast/types/Value_pb2.pyi @@ -16,46 +16,44 @@ 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 collections import abc as _abc -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf.internal import containers as _containers -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper -import builtins as _builtins +import builtins +import collections.abc +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.internal.enum_type_wrapper +import google.protobuf.message import sys -import typing as _typing +import typing if sys.version_info >= (3, 10): - from typing import TypeAlias as _TypeAlias + import typing as typing_extensions else: - from typing_extensions import TypeAlias as _TypeAlias + import typing_extensions -DESCRIPTOR: _descriptor.FileDescriptor +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor class _Null: - ValueType = _typing.NewType("ValueType", _builtins.int) - V: _TypeAlias = ValueType # noqa: Y015 + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType -class _NullEnumTypeWrapper(_enum_type_wrapper._EnumTypeWrapper[_Null.ValueType], _builtins.type): - DESCRIPTOR: _descriptor.EnumDescriptor +class _NullEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_Null.ValueType], builtins.type): # noqa: F821 + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor NULL: _Null.ValueType # 0 class Null(_Null, metaclass=_NullEnumTypeWrapper): ... NULL: Null.ValueType # 0 -Global___Null: _TypeAlias = Null # noqa: Y015 +global___Null = Null -@_typing.final -class ValueType(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class ValueType(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor class _Enum: - ValueType = _typing.NewType("ValueType", _builtins.int) - V: _TypeAlias = ValueType # noqa: Y015 + ValueType = typing.NewType("ValueType", builtins.int) + V: typing_extensions.TypeAlias = ValueType - class _EnumEnumTypeWrapper(_enum_type_wrapper._EnumTypeWrapper[ValueType._Enum.ValueType], _builtins.type): - DESCRIPTOR: _descriptor.EnumDescriptor + class _EnumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[ValueType._Enum.ValueType], builtins.type): # noqa: F821 + DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor INVALID: ValueType._Enum.ValueType # 0 BYTES: ValueType._Enum.ValueType # 1 STRING: ValueType._Enum.ValueType # 2 @@ -149,490 +147,448 @@ class ValueType(_message.Message): self, ) -> None: ... -Global___ValueType: _TypeAlias = ValueType # noqa: Y015 - -@_typing.final -class Value(_message.Message): - DESCRIPTOR: _descriptor.Descriptor - - BYTES_VAL_FIELD_NUMBER: _builtins.int - STRING_VAL_FIELD_NUMBER: _builtins.int - INT32_VAL_FIELD_NUMBER: _builtins.int - INT64_VAL_FIELD_NUMBER: _builtins.int - DOUBLE_VAL_FIELD_NUMBER: _builtins.int - FLOAT_VAL_FIELD_NUMBER: _builtins.int - BOOL_VAL_FIELD_NUMBER: _builtins.int - UNIX_TIMESTAMP_VAL_FIELD_NUMBER: _builtins.int - BYTES_LIST_VAL_FIELD_NUMBER: _builtins.int - STRING_LIST_VAL_FIELD_NUMBER: _builtins.int - INT32_LIST_VAL_FIELD_NUMBER: _builtins.int - INT64_LIST_VAL_FIELD_NUMBER: _builtins.int - DOUBLE_LIST_VAL_FIELD_NUMBER: _builtins.int - FLOAT_LIST_VAL_FIELD_NUMBER: _builtins.int - BOOL_LIST_VAL_FIELD_NUMBER: _builtins.int - UNIX_TIMESTAMP_LIST_VAL_FIELD_NUMBER: _builtins.int - NULL_VAL_FIELD_NUMBER: _builtins.int - MAP_VAL_FIELD_NUMBER: _builtins.int - MAP_LIST_VAL_FIELD_NUMBER: _builtins.int - BYTES_SET_VAL_FIELD_NUMBER: _builtins.int - STRING_SET_VAL_FIELD_NUMBER: _builtins.int - INT32_SET_VAL_FIELD_NUMBER: _builtins.int - INT64_SET_VAL_FIELD_NUMBER: _builtins.int - DOUBLE_SET_VAL_FIELD_NUMBER: _builtins.int - FLOAT_SET_VAL_FIELD_NUMBER: _builtins.int - BOOL_SET_VAL_FIELD_NUMBER: _builtins.int - UNIX_TIMESTAMP_SET_VAL_FIELD_NUMBER: _builtins.int - JSON_VAL_FIELD_NUMBER: _builtins.int - 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 - bytes_val: _builtins.bytes - string_val: _builtins.str - int32_val: _builtins.int - int64_val: _builtins.int - double_val: _builtins.float - float_val: _builtins.float - bool_val: _builtins.bool - unix_timestamp_val: _builtins.int - null_val: Global___Null.ValueType - json_val: _builtins.str - uuid_val: _builtins.str - time_uuid_val: _builtins.str - decimal_val: _builtins.str - @_builtins.property - def bytes_list_val(self) -> Global___BytesList: ... - @_builtins.property - def string_list_val(self) -> Global___StringList: ... - @_builtins.property - def int32_list_val(self) -> Global___Int32List: ... - @_builtins.property - def int64_list_val(self) -> Global___Int64List: ... - @_builtins.property - def double_list_val(self) -> Global___DoubleList: ... - @_builtins.property - def float_list_val(self) -> Global___FloatList: ... - @_builtins.property - def bool_list_val(self) -> Global___BoolList: ... - @_builtins.property - def unix_timestamp_list_val(self) -> Global___Int64List: ... - @_builtins.property - def map_val(self) -> Global___Map: ... - @_builtins.property - def map_list_val(self) -> Global___MapList: ... - @_builtins.property - def bytes_set_val(self) -> Global___BytesSet: ... - @_builtins.property - def string_set_val(self) -> Global___StringSet: ... - @_builtins.property - def int32_set_val(self) -> Global___Int32Set: ... - @_builtins.property - def int64_set_val(self) -> Global___Int64Set: ... - @_builtins.property - def double_set_val(self) -> Global___DoubleSet: ... - @_builtins.property - def float_set_val(self) -> Global___FloatSet: ... - @_builtins.property - def bool_set_val(self) -> Global___BoolSet: ... - @_builtins.property - def unix_timestamp_set_val(self) -> Global___Int64Set: ... - @_builtins.property - def json_list_val(self) -> Global___StringList: ... - @_builtins.property - def struct_val(self) -> Global___Map: ... - @_builtins.property - def struct_list_val(self) -> Global___MapList: ... - @_builtins.property - def uuid_list_val(self) -> Global___StringList: ... - @_builtins.property - def time_uuid_list_val(self) -> Global___StringList: ... - @_builtins.property - def uuid_set_val(self) -> Global___StringSet: ... - @_builtins.property - def time_uuid_set_val(self) -> Global___StringSet: ... - @_builtins.property - def list_val(self) -> Global___RepeatedValue: ... - @_builtins.property - def set_val(self) -> Global___RepeatedValue: ... - @_builtins.property - def decimal_list_val(self) -> Global___StringList: ... - @_builtins.property - def decimal_set_val(self) -> Global___StringSet: ... +global___ValueType = ValueType + +class Value(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BYTES_VAL_FIELD_NUMBER: builtins.int + STRING_VAL_FIELD_NUMBER: builtins.int + INT32_VAL_FIELD_NUMBER: builtins.int + INT64_VAL_FIELD_NUMBER: builtins.int + DOUBLE_VAL_FIELD_NUMBER: builtins.int + FLOAT_VAL_FIELD_NUMBER: builtins.int + BOOL_VAL_FIELD_NUMBER: builtins.int + UNIX_TIMESTAMP_VAL_FIELD_NUMBER: builtins.int + BYTES_LIST_VAL_FIELD_NUMBER: builtins.int + STRING_LIST_VAL_FIELD_NUMBER: builtins.int + INT32_LIST_VAL_FIELD_NUMBER: builtins.int + INT64_LIST_VAL_FIELD_NUMBER: builtins.int + DOUBLE_LIST_VAL_FIELD_NUMBER: builtins.int + FLOAT_LIST_VAL_FIELD_NUMBER: builtins.int + BOOL_LIST_VAL_FIELD_NUMBER: builtins.int + UNIX_TIMESTAMP_LIST_VAL_FIELD_NUMBER: builtins.int + NULL_VAL_FIELD_NUMBER: builtins.int + MAP_VAL_FIELD_NUMBER: builtins.int + MAP_LIST_VAL_FIELD_NUMBER: builtins.int + BYTES_SET_VAL_FIELD_NUMBER: builtins.int + STRING_SET_VAL_FIELD_NUMBER: builtins.int + INT32_SET_VAL_FIELD_NUMBER: builtins.int + INT64_SET_VAL_FIELD_NUMBER: builtins.int + DOUBLE_SET_VAL_FIELD_NUMBER: builtins.int + FLOAT_SET_VAL_FIELD_NUMBER: builtins.int + BOOL_SET_VAL_FIELD_NUMBER: builtins.int + UNIX_TIMESTAMP_SET_VAL_FIELD_NUMBER: builtins.int + JSON_VAL_FIELD_NUMBER: builtins.int + 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 + bytes_val: builtins.bytes + string_val: builtins.str + int32_val: builtins.int + int64_val: builtins.int + double_val: builtins.float + float_val: builtins.float + bool_val: builtins.bool + unix_timestamp_val: builtins.int + @property + def bytes_list_val(self) -> global___BytesList: ... + @property + def string_list_val(self) -> global___StringList: ... + @property + def int32_list_val(self) -> global___Int32List: ... + @property + def int64_list_val(self) -> global___Int64List: ... + @property + def double_list_val(self) -> global___DoubleList: ... + @property + def float_list_val(self) -> global___FloatList: ... + @property + def bool_list_val(self) -> global___BoolList: ... + @property + def unix_timestamp_list_val(self) -> global___Int64List: ... + null_val: global___Null.ValueType + @property + def map_val(self) -> global___Map: ... + @property + def map_list_val(self) -> global___MapList: ... + @property + def bytes_set_val(self) -> global___BytesSet: ... + @property + def string_set_val(self) -> global___StringSet: ... + @property + def int32_set_val(self) -> global___Int32Set: ... + @property + def int64_set_val(self) -> global___Int64Set: ... + @property + def double_set_val(self) -> global___DoubleSet: ... + @property + def float_set_val(self) -> global___FloatSet: ... + @property + def bool_set_val(self) -> global___BoolSet: ... + @property + def unix_timestamp_set_val(self) -> global___Int64Set: ... + json_val: builtins.str + @property + def json_list_val(self) -> global___StringList: ... + @property + 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: ... def __init__( self, *, - bytes_val: _builtins.bytes = ..., - string_val: _builtins.str = ..., - int32_val: _builtins.int = ..., - int64_val: _builtins.int = ..., - double_val: _builtins.float = ..., - float_val: _builtins.float = ..., - bool_val: _builtins.bool = ..., - unix_timestamp_val: _builtins.int = ..., - bytes_list_val: Global___BytesList | None = ..., - string_list_val: Global___StringList | None = ..., - int32_list_val: Global___Int32List | None = ..., - int64_list_val: Global___Int64List | None = ..., - double_list_val: Global___DoubleList | None = ..., - float_list_val: Global___FloatList | None = ..., - bool_list_val: Global___BoolList | None = ..., - unix_timestamp_list_val: Global___Int64List | None = ..., - null_val: Global___Null.ValueType = ..., - map_val: Global___Map | None = ..., - map_list_val: Global___MapList | None = ..., - bytes_set_val: Global___BytesSet | None = ..., - string_set_val: Global___StringSet | None = ..., - int32_set_val: Global___Int32Set | None = ..., - int64_set_val: Global___Int64Set | None = ..., - double_set_val: Global___DoubleSet | None = ..., - float_set_val: Global___FloatSet | None = ..., - bool_set_val: Global___BoolSet | None = ..., - unix_timestamp_set_val: Global___Int64Set | None = ..., - json_val: _builtins.str = ..., - 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 = ..., + bytes_val: builtins.bytes = ..., + string_val: builtins.str = ..., + int32_val: builtins.int = ..., + int64_val: builtins.int = ..., + double_val: builtins.float = ..., + float_val: builtins.float = ..., + bool_val: builtins.bool = ..., + unix_timestamp_val: builtins.int = ..., + bytes_list_val: global___BytesList | None = ..., + string_list_val: global___StringList | None = ..., + int32_list_val: global___Int32List | None = ..., + int64_list_val: global___Int64List | None = ..., + double_list_val: global___DoubleList | None = ..., + float_list_val: global___FloatList | None = ..., + bool_list_val: global___BoolList | None = ..., + unix_timestamp_list_val: global___Int64List | None = ..., + null_val: global___Null.ValueType = ..., + map_val: global___Map | None = ..., + map_list_val: global___MapList | None = ..., + bytes_set_val: global___BytesSet | None = ..., + string_set_val: global___StringSet | None = ..., + int32_set_val: global___Int32Set | None = ..., + int64_set_val: global___Int64Set | None = ..., + double_set_val: global___DoubleSet | None = ..., + float_set_val: global___FloatSet | None = ..., + bool_set_val: global___BoolSet | None = ..., + unix_timestamp_set_val: global___Int64Set | None = ..., + json_val: builtins.str = ..., + 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 = ..., ) -> None: ... - _HasFieldArgType: _TypeAlias = _typing.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", "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", "val", b"val"] # noqa: Y015 - def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... - _ClearFieldArgType: _TypeAlias = _typing.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", "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", "val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... - _WhichOneofReturnType_val: _TypeAlias = _typing.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"] # noqa: Y015 - _WhichOneofArgType_val: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def WhichOneof(self, oneof_group: _WhichOneofArgType_val) -> _WhichOneofReturnType_val | None: ... - -Global___Value: _TypeAlias = Value # noqa: Y015 - -@_typing.final -class BytesList(_message.Message): - DESCRIPTOR: _descriptor.Descriptor - - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedScalarFieldContainer[_builtins.bytes]: ... + 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", "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", "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", "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", "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"] | None: ... + +global___Value = Value + +class BytesList(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.bytes]: ... def __init__( self, *, - val: _abc.Iterable[_builtins.bytes] | None = ..., + val: collections.abc.Iterable[builtins.bytes] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___BytesList: _TypeAlias = BytesList # noqa: Y015 +global___BytesList = BytesList -@_typing.final -class StringList(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class StringList(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedScalarFieldContainer[_builtins.str]: ... + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... def __init__( self, *, - val: _abc.Iterable[_builtins.str] | None = ..., + val: collections.abc.Iterable[builtins.str] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___StringList: _TypeAlias = StringList # noqa: Y015 +global___StringList = StringList -@_typing.final -class Int32List(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class Int32List(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedScalarFieldContainer[_builtins.int]: ... + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: ... def __init__( self, *, - val: _abc.Iterable[_builtins.int] | None = ..., + val: collections.abc.Iterable[builtins.int] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___Int32List: _TypeAlias = Int32List # noqa: Y015 +global___Int32List = Int32List -@_typing.final -class Int64List(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class Int64List(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedScalarFieldContainer[_builtins.int]: ... + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: ... def __init__( self, *, - val: _abc.Iterable[_builtins.int] | None = ..., + val: collections.abc.Iterable[builtins.int] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___Int64List: _TypeAlias = Int64List # noqa: Y015 +global___Int64List = Int64List -@_typing.final -class DoubleList(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class DoubleList(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedScalarFieldContainer[_builtins.float]: ... + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.float]: ... def __init__( self, *, - val: _abc.Iterable[_builtins.float] | None = ..., + val: collections.abc.Iterable[builtins.float] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___DoubleList: _TypeAlias = DoubleList # noqa: Y015 +global___DoubleList = DoubleList -@_typing.final -class FloatList(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class FloatList(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedScalarFieldContainer[_builtins.float]: ... + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.float]: ... def __init__( self, *, - val: _abc.Iterable[_builtins.float] | None = ..., + val: collections.abc.Iterable[builtins.float] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___FloatList: _TypeAlias = FloatList # noqa: Y015 +global___FloatList = FloatList -@_typing.final -class BoolList(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class BoolList(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedScalarFieldContainer[_builtins.bool]: ... + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.bool]: ... def __init__( self, *, - val: _abc.Iterable[_builtins.bool] | None = ..., + val: collections.abc.Iterable[builtins.bool] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___BoolList: _TypeAlias = BoolList # noqa: Y015 +global___BoolList = BoolList -@_typing.final -class BytesSet(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class BytesSet(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedScalarFieldContainer[_builtins.bytes]: ... + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.bytes]: ... def __init__( self, *, - val: _abc.Iterable[_builtins.bytes] | None = ..., + val: collections.abc.Iterable[builtins.bytes] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___BytesSet: _TypeAlias = BytesSet # noqa: Y015 +global___BytesSet = BytesSet -@_typing.final -class StringSet(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class StringSet(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedScalarFieldContainer[_builtins.str]: ... + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]: ... def __init__( self, *, - val: _abc.Iterable[_builtins.str] | None = ..., + val: collections.abc.Iterable[builtins.str] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___StringSet: _TypeAlias = StringSet # noqa: Y015 +global___StringSet = StringSet -@_typing.final -class Int32Set(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class Int32Set(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedScalarFieldContainer[_builtins.int]: ... + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: ... def __init__( self, *, - val: _abc.Iterable[_builtins.int] | None = ..., + val: collections.abc.Iterable[builtins.int] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___Int32Set: _TypeAlias = Int32Set # noqa: Y015 +global___Int32Set = Int32Set -@_typing.final -class Int64Set(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class Int64Set(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedScalarFieldContainer[_builtins.int]: ... + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: ... def __init__( self, *, - val: _abc.Iterable[_builtins.int] | None = ..., + val: collections.abc.Iterable[builtins.int] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___Int64Set: _TypeAlias = Int64Set # noqa: Y015 +global___Int64Set = Int64Set -@_typing.final -class DoubleSet(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class DoubleSet(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedScalarFieldContainer[_builtins.float]: ... + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.float]: ... def __init__( self, *, - val: _abc.Iterable[_builtins.float] | None = ..., + val: collections.abc.Iterable[builtins.float] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___DoubleSet: _TypeAlias = DoubleSet # noqa: Y015 +global___DoubleSet = DoubleSet -@_typing.final -class FloatSet(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class FloatSet(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedScalarFieldContainer[_builtins.float]: ... + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.float]: ... def __init__( self, *, - val: _abc.Iterable[_builtins.float] | None = ..., + val: collections.abc.Iterable[builtins.float] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___FloatSet: _TypeAlias = FloatSet # noqa: Y015 +global___FloatSet = FloatSet -@_typing.final -class BoolSet(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class BoolSet(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedScalarFieldContainer[_builtins.bool]: ... + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.bool]: ... def __init__( self, *, - val: _abc.Iterable[_builtins.bool] | None = ..., + val: collections.abc.Iterable[builtins.bool] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___BoolSet: _TypeAlias = BoolSet # noqa: Y015 +global___BoolSet = BoolSet -@_typing.final -class Map(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class Map(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - @_typing.final - class ValEntry(_message.Message): - DESCRIPTOR: _descriptor.Descriptor + class ValEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - KEY_FIELD_NUMBER: _builtins.int - VALUE_FIELD_NUMBER: _builtins.int - key: _builtins.str - @_builtins.property - def value(self) -> Global___Value: ... + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: builtins.str + @property + def value(self) -> global___Value: ... def __init__( self, *, - key: _builtins.str = ..., - value: Global___Value | None = ..., + key: builtins.str = ..., + value: global___Value | None = ..., ) -> None: ... - _HasFieldArgType: _TypeAlias = _typing.Literal["value", b"value"] # noqa: Y015 - def HasField(self, field_name: _HasFieldArgType) -> _builtins.bool: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["key", b"key", "value", b"value"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... - - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.MessageMap[_builtins.str, Global___Value]: ... + 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: ... + + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.MessageMap[builtins.str, global___Value]: ... def __init__( self, *, - val: _abc.Mapping[_builtins.str, Global___Value] | None = ..., + val: collections.abc.Mapping[builtins.str, global___Value] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___Map: _TypeAlias = Map # noqa: Y015 +global___Map = Map -@_typing.final -class MapList(_message.Message): - DESCRIPTOR: _descriptor.Descriptor +class MapList(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedCompositeFieldContainer[Global___Map]: ... + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Map]: ... def __init__( self, *, - val: _abc.Iterable[Global___Map] | None = ..., + val: collections.abc.Iterable[global___Map] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___MapList: _TypeAlias = MapList # noqa: Y015 +global___MapList = MapList -@_typing.final -class RepeatedValue(_message.Message): +class RepeatedValue(google.protobuf.message.Message): """This is to avoid an issue of being unable to specify `repeated value` in oneofs or maps In JSON "val" field can be omitted """ - DESCRIPTOR: _descriptor.Descriptor + DESCRIPTOR: google.protobuf.descriptor.Descriptor - VAL_FIELD_NUMBER: _builtins.int - @_builtins.property - def val(self) -> _containers.RepeatedCompositeFieldContainer[Global___Value]: ... + VAL_FIELD_NUMBER: builtins.int + @property + def val(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Value]: ... def __init__( self, *, - val: _abc.Iterable[Global___Value] | None = ..., + val: collections.abc.Iterable[global___Value] | None = ..., ) -> None: ... - _ClearFieldArgType: _TypeAlias = _typing.Literal["val", b"val"] # noqa: Y015 - def ClearField(self, field_name: _ClearFieldArgType) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["val", b"val"]) -> None: ... -Global___RepeatedValue: _TypeAlias = RepeatedValue # noqa: Y015 +global___RepeatedValue = RepeatedValue diff --git a/sdk/python/feast/registry_server.py b/sdk/python/feast/registry_server.py index f033c5201ec..344453ad61e 100644 --- a/sdk/python/feast/registry_server.py +++ b/sdk/python/feast/registry_server.py @@ -342,22 +342,35 @@ def ApplyFeatureView( self, request: RegistryServer_pb2.ApplyFeatureViewRequest, context ): feature_view_type = request.WhichOneof("base_feature_view") + 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 + ) assert_permissions_to_update( - resource=feature_view, - # Will replace with the new get_any_feature_view method later + resource=feature_view_meta, getter=self.proxied_registry.get_feature_view, project=request.project, ) + 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) + ( self.proxied_registry.apply_feature_view( feature_view=feature_view, diff --git a/sdk/python/feast/repo_config.py b/sdk/python/feast/repo_config.py index 208307dc5d5..eb2898a962d 100644 --- a/sdk/python/feast/repo_config.py +++ b/sdk/python/feast/repo_config.py @@ -214,6 +214,12 @@ 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 OpenLineageConfig(FeastBaseModel): """Configuration for OpenLineage integration. @@ -337,7 +343,7 @@ 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). """ def __init__(self, **data: Any): super().__init__(**data) @@ -398,10 +404,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 diff --git a/sdk/python/feast/stream_feature_view.py b/sdk/python/feast/stream_feature_view.py index 2773484ecbb..3d0f98edae3 100644 --- a/sdk/python/feast/stream_feature_view.py +++ b/sdk/python/feast/stream_feature_view.py @@ -67,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. @@ -88,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] @@ -112,6 +115,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, @@ -183,6 +187,7 @@ def __init__( offline=offline, description=description, owner=owner, + org=org, schema=schema, source=source, # type: ignore[arg-type] mode=mode, @@ -304,6 +309,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, @@ -320,7 +326,7 @@ def to_proto(self): 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") @@ -333,7 +339,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 = ( @@ -351,6 +357,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 @@ -434,6 +441,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, @@ -463,6 +471,7 @@ 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, @@ -498,6 +507,7 @@ def decorator(user_function): tags=tags, online=online, owner=owner, + org=org, aggregations=aggregations, mode=mode, timestamp_field=timestamp_field, 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 046ecb03ac7..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", 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/type_map.py b/sdk/python/feast/type_map.py index 691a398c8ef..7960a3a3620 100644 --- a/sdk/python/feast/type_map.py +++ b/sdk/python/feast/type_map.py @@ -909,6 +909,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], @@ -929,16 +939,34 @@ 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 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, ( @@ -951,20 +979,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: @@ -1107,12 +1150,18 @@ 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 ): - 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}") @@ -1216,6 +1265,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) @@ -2000,6 +2051,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: diff --git a/sdk/python/feast/utils.py b/sdk/python/feast/utils.py index 3f9fcc6525b..55ad6c6a0b8 100644 --- a/sdk/python/feast/utils.py +++ b/sdk/python/feast/utils.py @@ -1566,6 +1566,15 @@ def _populate_response_from_feature_data( 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( 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 4a5a8e1e77a..6b9913159f1 100644 --- a/sdk/python/requirements/py3.10-ci-requirements.txt +++ b/sdk/python/requirements/py3.10-ci-requirements.txt @@ -251,9 +251,9 @@ attrs==26.1.0 \ # jsonschema # openlineage-python # referencing -azure-core==1.39.0 \ - --hash=sha256:4ac7b70fab5438c3f68770649a78daf97833caa83827f91df9c14e0e0ea7d34f \ - --hash=sha256:8a90a562998dd44ce84597590fff6249701b98c0e8797c95fcdd695b54c35d74 +azure-core==1.40.0 \ + --hash=sha256:7f3ea02579b1bb1d34e45043423b650621d11d7c2ea3b05e5554010080b78dfd \ + --hash=sha256:ecf5b6ddf2564471fae9d576147b7e77a4da285958b2d9f4fd6c3af104f3e9d7 # via # azure-identity # azure-storage-blob @@ -301,49 +301,44 @@ botocore==1.38.46 \ # moto # s3transfer # snowflake-connector-python -build==1.4.2 \ - --hash=sha256:35b14e1ee329c186d3f08466003521ed7685ec15ecffc07e68d706090bf161d1 \ - --hash=sha256:7a4d8651ea877cb2a89458b1b198f2e69f536c95e89129dbf5d448045d60db88 +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 +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.4.22 \ + --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ + --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 # via # clickhouse-connect # docling @@ -580,9 +575,9 @@ charset-normalizer==3.4.7 \ # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.3.3 \ + --hash=sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2 \ + --hash=sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 # via # feast (pyproject.toml) # dask @@ -851,56 +846,56 @@ coverage[toml]==7.13.5 \ --hash=sha256:f70c9ab2595c56f81a89620e22899eea8b212a4041bd728ac6f4a28bf5d3ddd0 \ --hash=sha256:fbabfaceaeb587e16f7008f7795cd80d20ec548dc7f94fbb0d4ec2e038ce563f # via pytest-cov -cryptography==46.0.6 \ - --hash=sha256:02fad249cb0e090b574e30b276a3da6a149e04ee2f049725b1f69e7b8351ec70 \ - --hash=sha256:063b67749f338ca9c5a0b7fe438a52c25f9526b851e24e6c9310e7195aad3b4d \ - --hash=sha256:12cae594e9473bca1a7aceb90536060643128bb274fcea0fc459ab90f7d1ae7a \ - --hash=sha256:12f0fa16cc247b13c43d56d7b35287ff1569b5b1f4c5e87e92cc4fcc00cd10c0 \ - --hash=sha256:22259338084d6ae497a19bae5d4c66b7ca1387d3264d1c2c0e72d9e9b6a77b97 \ - --hash=sha256:26031f1e5ca62fcb9d1fcb34b2b60b390d1aacaa15dc8b895a9ed00968b97b30 \ - --hash=sha256:27550628a518c5c6c903d84f637fbecf287f6cb9ced3804838a1295dc1fd0759 \ - --hash=sha256:2b417edbe8877cda9022dde3a008e2deb50be9c407eef034aeeb3a8b11d9db3c \ - --hash=sha256:2ea0f37e9a9cf0df2952893ad145fd9627d326a59daec9b0802480fa3bcd2ead \ - --hash=sha256:2ef9e69886cbb137c2aef9772c2e7138dc581fad4fcbcf13cc181eb5a3ab6275 \ - --hash=sha256:341359d6c9e68834e204ceaf25936dffeafea3829ab80e9503860dcc4f4dac58 \ - --hash=sha256:380343e0653b1c9d7e1f55b52aaa2dbb2fdf2730088d48c43ca1c7c0abb7cc2f \ - --hash=sha256:3c21d92ed15e9cfc6eb64c1f5a0326db22ca9c2566ca46d845119b45b4400361 \ - --hash=sha256:3dfa6567f2e9e4c5dceb8ccb5a708158a2a871052fa75c8b78cb0977063f1507 \ - --hash=sha256:456b3215172aeefb9284550b162801d62f5f264a081049a3e94307fe20792cfa \ - --hash=sha256:4668298aef7cddeaf5c6ecc244c2302a2b8e40f384255505c22875eebb47888b \ - --hash=sha256:50575a76e2951fe7dbd1f56d181f8c5ceeeb075e9ff88e7ad997d2f42af06e7b \ - --hash=sha256:639301950939d844a9e1c4464d7e07f902fe9a7f6b215bb0d4f28584729935d8 \ - --hash=sha256:64235194bad039a10bb6d2d930ab3323baaec67e2ce36215fd0952fad0930ca8 \ - --hash=sha256:6617f67b1606dfd9fe4dbfa354a9508d4a6d37afe30306fe6c101b7ce3274b72 \ - --hash=sha256:67177e8a9f421aa2d3a170c3e56eca4e0128883cf52a071a7cbf53297f18b175 \ - --hash=sha256:6728c49e3b2c180ef26f8e9f0a883a2c585638db64cf265b49c9ba10652d430e \ - --hash=sha256:6739d56300662c468fddb0e5e291f9b4d084bead381667b9e654c7dd81705124 \ - --hash=sha256:69cf0056d6947edc6e6760e5f17afe4bea06b56a9ac8a06de9d2bd6b532d4f3a \ - --hash=sha256:760997a4b950ff00d418398ad73fbc91aa2894b5c1db7ccb45b4f68b42a63b3c \ - --hash=sha256:79e865c642cfc5c0b3eb12af83c35c5aeff4fa5c672dc28c43721c2c9fdd2f0f \ - --hash=sha256:7e6142674f2a9291463e5e150090b95a8519b2fb6e6aaec8917dd8d094ce750d \ - --hash=sha256:7f417f034f91dcec1cb6c5c35b07cdbb2ef262557f701b4ecd803ee8cefed4f4 \ - --hash=sha256:7f6690b6c55e9c5332c0b59b9c8a3fb232ebf059094c17f9019a51e9827df91c \ - --hash=sha256:8927ccfbe967c7df312ade694f987e7e9e22b2425976ddbf28271d7e58845290 \ - --hash=sha256:8ce35b77aaf02f3b59c90b2c8a05c73bac12cea5b4e8f3fbece1f5fddea5f0ca \ - --hash=sha256:8e7304c4f4e9490e11efe56af6713983460ee0780f16c63f219984dab3af9d2d \ - --hash=sha256:90e5f0a7b3be5f40c3a0a0eafb32c681d8d2c181fc2a1bdabe9b3f611d9f6b1a \ - --hash=sha256:97c8115b27e19e592a05c45d0dd89c57f81f841cc9880e353e0d3bf25b2139ed \ - --hash=sha256:9a693028b9cbe51b5a1136232ee8f2bc242e4e19d456ded3fa7c86e43c713b4a \ - --hash=sha256:9a9c42a2723999a710445bc0d974e345c32adfd8d2fac6d8a251fa829ad31cfb \ - --hash=sha256:a3e84d5ec9ba01f8fd03802b2147ba77f0c8f2617b2aff254cedd551844209c8 \ - --hash=sha256:aad75154a7ac9039936d50cf431719a2f8d4ed3d3c277ac03f3339ded1a5e707 \ - --hash=sha256:b12c6b1e1651e42ab5de8b1e00dc3b6354fdfd778e7fa60541ddacc27cd21410 \ - --hash=sha256:b928a3ca837c77a10e81a814a693f2295200adb3352395fad024559b7be7a736 \ - --hash=sha256:bcb87663e1f7b075e48c3be3ecb5f0b46c8fc50b50a97cf264e7f60242dca3f2 \ - --hash=sha256:c797e2517cb7880f8297e2c0f43bb910e91381339336f75d2c1c2cbf811b70b4 \ - --hash=sha256:c89eb37fae9216985d8734c1afd172ba4927f5a05cfd9bf0e4863c6d5465b013 \ - --hash=sha256:cdcd3edcbc5d55757e5f5f3d330dd00007ae463a7e7aa5bf132d1f22a4b62b19 \ - --hash=sha256:d24c13369e856b94892a89ddf70b332e0b70ad4a5c43cf3e9cb71d6d7ffa1f7b \ - --hash=sha256:d4e4aadb7fc1f88687f47ca20bb7227981b03afaae69287029da08096853b738 \ - --hash=sha256:d9528b535a6c4f8ff37847144b8986a9a143585f0540fbcb1a98115b543aa463 \ - --hash=sha256:ed3775295fb91f70b4027aeba878d79b3e55c0b3e97eaa4de71f8f23a9f2eb77 \ - --hash=sha256:ed418c37d095aeddf5336898a132fba01091f0ac5844e3e8018506f014b6d2c4 +cryptography==47.0.0 \ + --hash=sha256:0024b87d47ae2399165a6bfb20d24888881eeab83ae2566d62467c5ff0030ce7 \ + --hash=sha256:07efe86201817e7d3c18781ca9770bc0db04e1e48c994be384e4602bc38f8f27 \ + --hash=sha256:09f6d7bf6724f8db8b32f11eccf23efc8e759924bc5603800335cf8859a3ddbd \ + --hash=sha256:11438c7518132d95f354fa01a4aa2f806d172a061a7bed18cf18cbdacdb204d7 \ + --hash=sha256:11dbb9f50a0f1bb9757b3d8c27c1101780efb8f0bdecfb12439c22a74d64c001 \ + --hash=sha256:14432c8a9bcb37009784f9594a62fae211a2ae9543e96c92b2a8e4c3cd5cd0c4 \ + --hash=sha256:1581aef4219f7ca2849d0250edaa3866212fb74bf5667284f46aa92f9e65c1ca \ + --hash=sha256:160ad728f128972d362e714054f6ba0067cab7fb350c5202a9ae8ae4ce3ef1a0 \ + --hash=sha256:1a405c08857258c11016777e11c02bacbe7ef596faf259305d282272a3a05cbe \ + --hash=sha256:1e47422b5557bb82d3fff997e8d92cff4e28b9789576984f08c248d2b3535d93 \ + --hash=sha256:20fdbe3e38fb67c385d233c89371fa27f9909f6ebca1cecc20c13518dae65475 \ + --hash=sha256:2207a498b03275d0051589e326b79d4cf59985c99031b05bb292ac52631c37fe \ + --hash=sha256:256d07c78a04d6b276f5df935a9923275f53bd1522f214447fdf365494e2d515 \ + --hash=sha256:2b45761c6ec22b7c726d6a829558777e32d0f1c8be7c3f3480f9c912d5ee8a10 \ + --hash=sha256:2ebd84adf0728c039a3be2700289378e1c164afc6748df1a5ed456767bef9ba7 \ + --hash=sha256:34b4358b925a5ea3e14384ca781a2c0ef7ac219b57bb9eacc4457078e2b19f92 \ + --hash=sha256:3fb8fa48075fad7193f2e5496135c6a76ac4b2aa5a38433df0a539296b377829 \ + --hash=sha256:4e1de79e047e25d6e9f8cea71c86b4a53aced64134f0f003bbcbf3655fd172c8 \ + --hash=sha256:4f7722c97826770bab8ae92959a2e7b20a5e9e9bf4deae68fd86c3ca457bab52 \ + --hash=sha256:51c9313e90bd1690ec5a75ed047c27c0b8e6c570029712943d6116ef9a90620b \ + --hash=sha256:5d0e362ff51041b0c0d219cc7d6924d7b8996f57ce5712bdcef71eb3c65a59cc \ + --hash=sha256:6651d32eff255423503aa276739da98c30f26c40cbeffcc6048e0d54ef704c0c \ + --hash=sha256:6eebcaf0df1d21ce1f90605c9b432dd2c4f4ab665ac29a40d5e3fc68f51b5e63 \ + --hash=sha256:6f29f36582e6151d9686235e586dd35bb67491f024767d10b842e520dc6a07ac \ + --hash=sha256:7a02675e2fabd0c0fc04c868b8781863cbf1967691543c22f5470500ff840b31 \ + --hash=sha256:7f1207974a904e005f762869996cf620e9bf79ecb4622f148550bb48e0eb35a7 \ + --hash=sha256:7f68d6fbc7fbbcfb0939fea72c3b96a9f9a6edfc0e1b1d29778a2066030418b1 \ + --hash=sha256:7fda2f02c9015db3f42bb8a22324a454516ed10a8c29ca6ece6cdbb5efe2a203 \ + --hash=sha256:80887c5cbd1774683cb126f0ab4184567f080071d5acf62205acb354b4b753b7 \ + --hash=sha256:835d2d7f47cdc53b3224e90810fb1d36ca94ea29cc1801fb4c1bc43876735769 \ + --hash=sha256:8c1a736bbb3288005796c3f7ccb9453360d7fed483b13b9f468aea5171432923 \ + --hash=sha256:9af828c0d5a65c70ec729cd7495a4bf1a67ecb66417b8f02ff125ab8a6326a74 \ + --hash=sha256:9c59ab0e0fa3a180a5a9c59f3a5abe3ef90d474bc56d7fadfbe80359491b615b \ + --hash=sha256:9f8e55fe4e63613a5e1cc5819030f27b97742d720203a087802ce4ce9ceb52bb \ + --hash=sha256:9fe6b7c64926c765f9dff301f9c1b867febcda5768868ca084e18589113732ab \ + --hash=sha256:a49a3eb5341b9503fa3000a9a0db033161db90d47285291f53c2a9d2cd1b7f76 \ + --hash=sha256:a9b761f012a943b7de0e828843c5688d0de94a0578d44d6c85a1bae32f87791f \ + --hash=sha256:b1c76fca783aa7698eb21eb14f9c4aa09452248ee54a627d125025a43f83e7a7 \ + --hash=sha256:b9a8943e359b7615db1a3ba587994618e094ff3d6fa5a390c73d079ce18b3973 \ + --hash=sha256:be12cb6a204f77ed968bcefe68086eb061695b540a3dd05edac507a3111b25f0 \ + --hash=sha256:cffbba3392df0fa8629bb7f43454ee2925059ee158e23c54620b9063912b86c8 \ + --hash=sha256:ed67ea4e0cfb5faa5bc7ecb6e2b8838f3807a03758eec239d6c21c8769355310 \ + --hash=sha256:edd4da498015da5b9f26d38d3bfc2e90257bfa9cbed1f6767c282a0025ae649b \ + --hash=sha256:ef6b3634087f18d2155b1e8ce264e5345a753da2c5fa9815e7d41315c90f8318 \ + --hash=sha256:f1557695e5c2b86e204f6ce9470497848634100787935ab7adc5397c54abd7ab \ + --hash=sha256:f5c15764f261394b22aef6b00252f5195f46f2ca300bec57149474e2538b31f8 \ + --hash=sha256:f5c3296dab66202f1b18a91fa266be93d6aa0c2806ea3d67762c69f60adc71aa \ + --hash=sha256:f7db373287273d8af1414cf95dc4118b13ffdc62be521997b0f2b270771fef50 \ + --hash=sha256:f9a034b642b960767fb343766ae5ba6ad653f2e890ddd82955aef288ffea8736 # via # feast (pyproject.toml) # azure-identity @@ -920,9 +915,9 @@ dask[dataframe]==2026.3.0 \ --hash=sha256:be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d \ --hash=sha256:f7d96c8274e8a900d217c1ff6ea8d1bbf0b4c2c21e74a409644498d925eb8f85 # via feast (pyproject.toml) -datasets==4.8.4 \ - --hash=sha256:a1429ed853275ce7943a01c6d2e25475b4501eb758934362106a280470df3a52 \ - --hash=sha256:cdc8bee4698e549d78bf1fed6aea2eebc760b22b084f07e6fc020c6577a6ce6d +datasets==4.8.5 \ + --hash=sha256:0f0c1c3d56ffff2c93b2f4c63c95bac94f3d7e8621aea2a2a576275233bba772 \ + --hash=sha256:5079900781719c0e063a8efdd2cd95a31ad0c63209178669cd23cf1b926149ff # via feast (pyproject.toml) db-dtypes==1.5.1 \ --hash=sha256:901099b807c9312bc61a5bddbfb07512884e6c6d5a9edacf24d50bcf303aa5f7 \ @@ -930,9 +925,9 @@ db-dtypes==1.5.1 \ # via # google-cloud-bigquery # pandas-gbq -dbt-artifacts-parser==0.13.0 \ - --hash=sha256:304f2b857650566fed4ed8b976ed3582332eda3cedfe7167158dbbcfced3fe47 \ - --hash=sha256:55498e8bd0d9064d56617f9c714ced8607d94ccb61e70d4b49dcfd8a28a030d8 +dbt-artifacts-parser==0.13.1 \ + --hash=sha256:c341730fa34ebb38cc7d2de0282e8b713e2fc65fc6577f0d944f8abee8949dc4 \ + --hash=sha256:c7a3c4e309ae2d7d566a615e92043b0d346a77998203b0cc466234717b806e40 # via feast (pyproject.toml) debugpy==1.8.20 \ --hash=sha256:077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad \ @@ -985,6 +980,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 @@ -1000,6 +999,12 @@ distlib==0.4.0 \ --hash=sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 \ --hash=sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d # 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 @@ -1008,16 +1013,16 @@ docling==2.27.0 \ --hash=sha256:1288ed75b27e33bf94daff34faffc6d11b7d7ccc13e3df84fb24adad3991f72d \ --hash=sha256:faba35662612a2c687a3a463e501d95f645316436084af92a0442ce162429a3d # via feast (pyproject.toml) -docling-core[chunking]==2.71.0 \ - --hash=sha256:4761857816853b2b35263b5b4518e1ea6214e0565db0bbf1d929fb976665d1a0 \ - --hash=sha256:4caa9f50c68b9dd332584ae16170b36db05d773532b14d7078b580d89d8bd2a4 +docling-core[chunking]==2.74.1 \ + --hash=sha256:46bf298686f2c51ddd69b6935a27dff1cc80838f2f5f1a8823492d99cf1a357b \ + --hash=sha256:e6464078012b3d45f4e0accd101fcb277063903f355eabbb9aee8de00527a789 # via # docling # docling-ibm-models # docling-parse -docling-ibm-models==3.13.0 \ - --hash=sha256:a11acc6034b06e0bed8dc0ca1fa700615b8246eacce411619168e1f6562b0d0d \ - --hash=sha256:f402effae8a63b0e5c3b5ce13120601baa2cd8098beef1d53ab5a056443758d3 +docling-ibm-models==3.13.2 \ + --hash=sha256:195e02dd119df34d2ce5f76ac614da82825851013e4898db7b0468cdf8740a3d \ + --hash=sha256:5fa0838bf15a4e06d2fcb686d756a6f4c329ea0a8820d085f06d07abe96269ed # via docling docling-parse==4.7.3 \ --hash=sha256:1790e7e4ae202d67875c1c48fd6f8ef5c51d10b0c23157e4989b8673f2f31308 \ @@ -1052,42 +1057,42 @@ docutils==0.19 \ --hash=sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6 \ --hash=sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc # via sphinx -duckdb==1.5.1 \ - --hash=sha256:054ad424b051b334052afac58cb216f3b1ebb8579fc8c641e60f0182e8725ea9 \ - --hash=sha256:05fc91767d0cfc4cf2fa68966ab5b479ac07561752e42dd0ae30327bd160f64a \ - --hash=sha256:0a6acc2040bec1f05de62a2f3f68f4c12f3ec7d6012b4317d0ab1a195af26225 \ - --hash=sha256:26e56b5f0c96189e3288d83cf7b476e23615987902f801e5788dee15ee9f24a9 \ - --hash=sha256:36e8e32621a9e2a9abe75dc15a4b54a3997f2d8b1e53ad754bae48a083c91130 \ - --hash=sha256:40c5220ec93790b18ec6278da9c6ac2608d997ee6d6f7cd44c5c3992764e8e71 \ - --hash=sha256:446d500a2977c6ae2077f340c510a25956da5c77597175c316edfa87248ceda3 \ - --hash=sha256:46f92ada9023e59f27edc048167b31ac9a03911978b1296c845a34462a27f096 \ - --hash=sha256:482f8a13f2600f527e427f73c42b5aa75536f9892868068f0aaf573055a0135f \ - --hash=sha256:553c273a6a8f140adaa6da6a6135c7f95bdc8c2e5f95252fcdf9832d758e2141 \ - --hash=sha256:5ae7c0d744d64e2753149634787cc4ab60f05ef1e542b060eeab719f3cdb7723 \ - --hash=sha256:5d4147422d91ccdc2d2abf6ed24196025e020259d1d267970ae20c13c2ce84b1 \ - --hash=sha256:6af347debc8b721aa72e48671166282da979d5e5ae52dbc660ab417282b48e23 \ - --hash=sha256:6ba302115f63f6482c000ccfd62efdb6c41d9d182a5bcd4a90e7ab8cd13856eb \ - --hash=sha256:6f7361d66cc801d9eb4df734b139cd7b0e3c257a16f3573ebd550ddb255549e6 \ - --hash=sha256:715f05ea198d20d7f8b407b9b84e0023d17f2b9096c194cea702b7840e74f1f7 \ - --hash=sha256:71dddcebbc5a70e946a06c30b59b5dd7999c9833d307168f90fb4e4b672ab63e \ - --hash=sha256:8150c569b2aa4573b51ba8475e814aa41fd53a3d510c1ffb96f1139f46faf611 \ - --hash=sha256:8843bd9594e1387f1e601439e19ad73abdf57356104fd1e53a708255bb95a13d \ - --hash=sha256:8c0088765747ae5d6c9f89987bb36f9fb83564f07090d721344ce8e1abedffea \ - --hash=sha256:972d0dbf283508f9bc446ee09c3838cb7c7f114b5bdceee41753288c97fe2f7c \ - --hash=sha256:a28531cee2a5a42d89f9ba4da53bfeb15681f12acc0263476c8705380dadce07 \ - --hash=sha256:a3be2072315982e232bfe49c9d3db0a59ba67b2240a537ef42656cc772a887c7 \ - --hash=sha256:ac2804043bd1bc10b5da18f8f4c706877197263a510c41be9b4c0062f5783dcc \ - --hash=sha256:afab8b4b1f4469c3879bb049dd039f8fce402712050324e9524a43d7324c5e87 \ - --hash=sha256:b370d1620a34a4538ef66524fcee9de8171fa263c701036a92bc0b4c1f2f9c6d \ - --hash=sha256:b8b0808dba0c63b7633bdaefb34e08fe0612622224f9feb0e7518904b1615101 \ - --hash=sha256:bc7ca6a1a40e7e4c933017e6c09ef18032add793df4e42624c6c0c87e0bebdad \ - --hash=sha256:caa65e1f5bf007430bf657c37cab7ab81a4ddf8d337e3062bcc5085d17ef038b \ - --hash=sha256:d68c5a01a283cb13b79eafe016fe5869aa11bff8c46e7141c70aa0aac808010f \ - --hash=sha256:da137802688190835b4c863cafa77fd7e29dff662ee6d905a9ffc14f00299c91 \ - --hash=sha256:e56a20ab6cdb90a95b0c99652e28de3504ce77129087319c03c9098266183ae5 \ - --hash=sha256:e878ccb7d20872065e1597935fdb5e65efa43220c8edd0d9c4a1a7ff1f3eb277 \ - --hash=sha256:eba81e0b3011c1f23df7ea47ef4ffaa8239817959ae291515b6efd068bde2161 \ - --hash=sha256:ed6d23a3f806898e69c77430ebd8da0c79c219f97b9acbc9a29a653e09740c59 +duckdb==1.5.2 \ + --hash=sha256:0b291786014df1133f8f18b9df4d004484613146e858d71a21791e0fcca16cf4 \ + --hash=sha256:2323c1195c10fb2bb982fc0218c730b43d1b92a355d61e68e3c5f3ac9d44c34f \ + --hash=sha256:2a1de4f4d454b8c97aec546c82003fc834d3422ce4bc6a19902f3462ef293bed \ + --hash=sha256:35579b8e3a064b5eaf15b0eafc558056a13f79a0a62e34cc4baf57119daecfec \ + --hash=sha256:376856066c65ccd55fcb3a380bbe33a71ce089fc4623d229ffc6e82251afdb6d \ + --hash=sha256:411ad438bd4140f189a10e7f515781335962c5d18bd07837dc6d202e3985253d \ + --hash=sha256:4420b3f47027a7849d0e1815532007f377fa95ee5810b47ea717d35525c12f79 \ + --hash=sha256:486c862bf7f163c0110b6d85b3e5c031d224a671cca468f12ebb1d3a348f6b39 \ + --hash=sha256:52a21823f3fbb52f0f0e5425e20b07391ad882464b955879499b5ff0b45a376b \ + --hash=sha256:5596bbfc31b1b259db69c8d847b42d036ce2c4804f9ccb28f9fc46a16de7bc53 \ + --hash=sha256:56d38b3c4e0ef2abb58898d0fd423933999ed535c45e75e9d9f72e1d5fed69b8 \ + --hash=sha256:638da0d5102b6cb6f7d47f83d0600708ac1d3cb46c5e9aaabc845f9ba4d69246 \ + --hash=sha256:63bf8687feefeed51adf45fa3b062ab8b1b1c350492b7518491b86bae68b1da1 \ + --hash=sha256:6b0fe75c148000f060aa1a27b293cacc0ea08cc1cad724fbf2143d56070a3785 \ + --hash=sha256:70631c847ca918ee710ec874241b00cf9d2e5be90762cbb2a0389f17823c08f7 \ + --hash=sha256:7f69164b048e498b9e9140a24343108a5ae5f17bfb3485185f55fdf9b1aa924d \ + --hash=sha256:81fc4fbf0b5e25840b39ba2a10b78c6953c0314d5d0434191e7898f34ab1bba3 \ + --hash=sha256:84b193aca20565dedb3172de15f843c659c3a6c773bf14843a9bd781c850e7db \ + --hash=sha256:8d599758b4e48bf12e18c9b960cf491d219f0c4972d19a45489c05cc5ab36f83 \ + --hash=sha256:8dbd7e31e5dc157bfe8803fa7d2652336265c6c19926c5a4a9b40f8222868d08 \ + --hash=sha256:98c0535cd6d901f61a5ea3c2e26a1fd28482953d794deb183daf568e3aa5dda6 \ + --hash=sha256:a9cd5e71702d446613750405cde03f66ed268f4c321da071b0472759dad19536 \ + --hash=sha256:bb42e6ed543902e14eae647850da24103a89f0bc2587dec5601b1c1f213bd2ed \ + --hash=sha256:be37680ddb380015cb37318e378c53511c45c4f0d8fac5599d22b7d092b9217a \ + --hash=sha256:c69907354ffee94ba8cf782daf0480dab7557f21ce27fffa6c0ea8f74ed4b8e2 \ + --hash=sha256:c99ef73a277c8921bc0a1f16dee38d924484251d9cfd20951748c20fcd5ed855 \ + --hash=sha256:c9f3e0b71b8a50fccfb42794899285d9d318ce2503782b9dd54868e5ecd0ad31 \ + --hash=sha256:ce0b8141a10d37ecef729c45bc41d334854013f4389f1488bd6035c5579aaac1 \ + --hash=sha256:ce17670bb392ea1b3650537db02bd720908776b5b95f6d2472d31a7de59d1dc1 \ + --hash=sha256:d72b8856b1839d35648f38301b058f6232f4d36b463fe4dc8f4d3fdff2df1a2e \ + --hash=sha256:d9b4f5430bf4f05d4c0dc4c55c75def3a5af4be0343be20fa2bfc577343fbfc9 \ + --hash=sha256:e6495b00cad16888384119842797c49316a96ae1cb132bb03856d980d95afee1 \ + --hash=sha256:ea58ff5b0880593a280cf5511734b17711b32ee1f58b47d726e8600848358160 \ + --hash=sha256:ef461bca07313412dc09961c4a4757a851f56b95ac01c58fac6007632b7b94f2 \ + --hash=sha256:fc85a5dbcbe6eccac1113c72370d1d3aacfdd49198d63950bdf7d8638a307f00 # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ @@ -1154,9 +1159,9 @@ faiss-cpu==1.10.0 \ --hash=sha256:e71f7e24d5b02d3a51df47b77bd10f394a1b48a8331d5c817e71e9e27a8a75ac \ --hash=sha256:f71c5860c860df2320299f9e4f2ca1725beb559c04acb1cf961ed24e6218277a # via feast (pyproject.toml) -fastapi==0.135.3 \ - --hash=sha256:9b0f590c813acd13d0ab43dd8494138eb58e484bfac405db1f3187cfc5810d98 \ - --hash=sha256:bd6d7caf1a2bdd8d676843cdcd2287729572a1ef524fc4d65c17ae002a1be654 +fastapi==0.136.1 \ + --hash=sha256:7af665ad7acfa0a3baf8983d393b6b471b9da10ede59c60045f49fbc89a0fa7f \ + --hash=sha256:a6e9d7eeada96c93a4d69cb03836b44fa34e2854accb7244a1ece36cd4781c3f # via # feast (pyproject.toml) # fastapi-mcp @@ -1168,9 +1173,9 @@ fastjsonschema==2.21.2 \ --hash=sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463 \ --hash=sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de # via nbformat -filelock==3.25.2 \ - --hash=sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694 \ - --hash=sha256:ca8afb0da15f229774c9ad1b455ed96e85a81373065fb10446672f64444ddf70 +filelock==3.29.0 \ + --hash=sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90 \ + --hash=sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258 # via # datasets # huggingface-hub @@ -1334,9 +1339,9 @@ geomet==1.1.0 \ --hash=sha256:4372fe4e286a34acc6f2e9308284850bd8c4aa5bc12065e2abbd4995900db12f \ --hash=sha256:51e92231a0ef6aaa63ac20c443377ba78a303fd2ecd179dc3567de79f3c11605 # via cassandra-driver -google-api-core[grpc]==2.30.2 \ - --hash=sha256:9a8113e1a88bdc09a7ff629707f2214d98d61c7f6ceb0ea38c42a095d02dc0f9 \ - --hash=sha256:a4c226766d6af2580577db1f1a51bf53cd262f722b49731ce7414c43068a9594 +google-api-core[grpc]==2.30.3 \ + --hash=sha256:a85761ba72c444dad5d611c2220633480b2b6be2521eca69cca2dbb3ffd6bfe8 \ + --hash=sha256:e601a37f148585319b26db36e219df68c5d07b6382cff2d580e83404e44d641b # via # feast (pyproject.toml) # google-cloud-bigquery @@ -1346,9 +1351,9 @@ google-api-core[grpc]==2.30.2 \ # google-cloud-datastore # google-cloud-storage # pandas-gbq -google-auth==2.49.1 \ - --hash=sha256:16d40da1c3c5a0533f57d268fe72e0ebb0ae1cc3b567024122651c045d879b64 \ - --hash=sha256:195ebe3dca18eddd1b3db5edc5189b76c13e96f29e73043b923ebcf3f1a860f7 +google-auth==2.50.0 \ + --hash=sha256:04382175e28b94f49694977f0a792688b59a668def1499e9d8de996dc9ce5b15 \ + --hash=sha256:f35eafb191195328e8ce10a7883970877e7aeb49c2bfaa54aa0e394316d353d0 # via # google-api-core # google-auth-oauthlib @@ -1643,101 +1648,112 @@ hf-xet==1.4.3 \ --hash=sha256:e23717ce4186b265f69afa66e6f0069fe7efbf331546f5c313d00e123dc84583 \ --hash=sha256:fc360b70c815bf340ed56c7b8c63aacf11762a4b099b2fe2c9bd6d6068668c08 # 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.3.1 \ + --hash=sha256:002fc0201b9af1cc8960e27cdc501ad1f8cdd6dbadb2091c6ddbd4e5ace6cb77 \ + --hash=sha256:011a9071c3df4885cac7f58a2623feac6c8e2ad30e6ba93c55195af05ce61ff5 \ + --hash=sha256:01cf82a514bc4fd145b99333c28523e61b7a9ad051a245804323ebf4e7b1c6a6 \ + --hash=sha256:027ce4fabfeff5af5b9869d5524770877f9061d118bc36b85703ae3faf5aad8e \ + --hash=sha256:03baa381964b8df356d19ec4e3a6ae656044249a87b0def257fe1e08dbaf6094 \ + --hash=sha256:042e57de8a2cae91e3e7c0af32960ea2c5107b2f27f68a740295861e68780a8a \ + --hash=sha256:09d41a3a965f7c261223d516ebda607aee4d8440dd7637f01af9a4c05872f0c4 \ + --hash=sha256:09f5e510f637f2c72d2a79fb3ad05f7b6211e057e367ca5c4f97bb3d8c9d71f4 \ + --hash=sha256:0b5ff2f643f4b452b0597b7fe6aa35d398cb31d8806801acfafb1558610ea2aa \ + --hash=sha256:0caf3fc8af0767794b335753781c3fa35f2a3e975c098edbc8f733d35d6a95e4 \ + --hash=sha256:0fac4af8515e6cca74fc701169ae4dc9a71a90e9319c9d21006ec9454b43aa2f \ + --hash=sha256:113e098e4a6b3cc5500e05e7cb1548ba9e83de5fe755941b11f6020a76e6c03a \ + --hash=sha256:137c14905ea6f2933967200bc7b2a0c8ec9387888b273fd0004f25b994fd0343 \ + --hash=sha256:156be6a0c736ee145cfe0fb155d0e96cec8d4872cf8b4f76ad6a2ee6ab391d0a \ + --hash=sha256:17ec8b524055a88b80d76c177dbbbe475a25c17c5bf4b67bdbdbd0629bcae838 \ + --hash=sha256:1ac7697365dbe45109273b34227fee6826b276ead9a4a007e0877e1d3f0fcf21 \ + --hash=sha256:1b46e96b50dad03495447860510daebd2c96fd44ed25ba8ccb03e9f89eaa9d34 \ + --hash=sha256:1ebc307a87b099d0877dbd2bdc0bae427258e7ec67f60a951e89027f8dc2568f \ + --hash=sha256:1f7bceb03a1b934872ffe3942eaeed7c7e09096e67b53f095b81f39c7a819113 \ + --hash=sha256:2611bfaaadc5e8d43fb7967f9bbf1110c8beaa83aee2f2d812c76f11cfb56c6a \ + --hash=sha256:264ee7e9cb6c30dc78da4ecf71d74cf14ca122817c665d838eda8b4384bce1b0 \ + --hash=sha256:26f899cde0279e4b7d370716ff80320601c2bd93cdf3e774a42bdd44f65b41f8 \ + --hash=sha256:29fe35e3c6fe03204e75c86514f452591957a1e06b05d86e10d795455b71c355 \ + --hash=sha256:2afc675b831f7552da41116fffffca4340f387dc03f56d6ec0c7895ab0b59a10 \ + --hash=sha256:2b6da6e07359107c653a809b3cff2d9ccaeedbafe33c6f16434aef6f53ce4a2b \ + --hash=sha256:2b96da7e365d6488d2a75266a662cbe3cc14b28c23dd9b0c9aa04b5bc5c20192 \ + --hash=sha256:2f1c1b2e8f00b71e6214234d313f655a3a27cd4384b054126ce04073c1d47045 \ + --hash=sha256:304481241e081bc26f0778b2c2b99f9c43917e4e724a016dcc9439b7ab12c726 \ + --hash=sha256:318f772dd321404075d406825266e574ee0f4751be1831424c2ebd5722609398 \ + --hash=sha256:3586c8a5f56d34b9dddaaa9e76905f31933cac267251006adf86ec0eef7d0400 \ + --hash=sha256:3724f0e58c6ff76fd683429945491de71324ab1bc0ad943a8d68cb0932d24075 \ + --hash=sha256:3fb6573efa15a29c12c0c0f7170b14e7c1347fe4bb39b6a15b779f46015cc929 \ + --hash=sha256:40ae8a7041fcb328a6bc7202d8c4e6e0d38d434b2e3880b1ee8ed754f17cd836 \ + --hash=sha256:4106201cd052d9eabe3cb7b5a24b0fe37307792bda4fcb3cf6ddd72f697828e8 \ + --hash=sha256:439f9a5cc8f9519ce208a24cdebfa0440fef26aa682a40ba2c92acb10a53f5e0 \ + --hash=sha256:4479e36d263251dba8ab8ea81adf07e7f1163603c7102c5de1e130b83b4fad3b \ + --hash=sha256:487658e1db83c1ee9fbbac6a43039ea76957767a5987ffb16b590613f9e68297 \ + --hash=sha256:48ff424f8aa36aacd9fdaa68efeb27d2e8771f293af4305bdb15d92194ca6631 \ + --hash=sha256:4f7e242eab698ad0be5a4b2ec616fa856569c57455cc67c625fd567726290e5f \ + --hash=sha256:526db52e5234a9463520e960a509d6c1bd5128d1ab1b569cbf459fe39189e8ab \ + --hash=sha256:52d5641027d6731bc7b5e7d126a5158a99784a9f8c6de3d97ca89aca4969e9f8 \ + --hash=sha256:53148a4e21057541b6d8e493b2ea1b500037ddf34433c391970036f3cbce00e3 \ + --hash=sha256:583de2f16528e66081cbdfe510d8488c2de73039dc00aada7d22bd49d73a4a94 \ + --hash=sha256:5e55d90b431b0c6b64ae5a624208d4aea318566d31872e595ee723c0f5b9a79f \ + --hash=sha256:5f316cf2d0558f5027aab19dde7d7e4901c26c21fa95367bc37784e8f547bbf2 \ + --hash=sha256:60543f3b068b16a86e99ed96b7fdae71cdc1d8abdfe9b3f82032a555e52ece7e \ + --hash=sha256:62cc62284541bb2a86c898c7d5e8388661cade91c184cb862095ed547e80588f \ + --hash=sha256:65c05b79cb8366c123357b354a16f9fc3f7187159422f143638d1c26b7240ed4 \ + --hash=sha256:65f6ac06a9f0c32c254660ec6a9329d81d589e8f5d0a9837a941d5424a6be1ef \ + --hash=sha256:6d1434d0bcc1b3ef048bae53f26456405c08aeed9827e65b24094f5f3a6793f1 \ + --hash=sha256:6e2e1024f0a021777740cb7c633a0efb2c4a4bc570f508223a8dcbcf79f99ef9 \ + --hash=sha256:6ffa7ba2e2da1f806f3181b9730b3e87ba9dbfec884806725d4584055ba3faa6 \ + --hash=sha256:743b85bd6902856cac457ddd8cd7dd48c89c47d641b6016ff5e4d015bfbd4799 \ + --hash=sha256:77c5d2bebbc9d06691abb512a31d0f54e1562af0b872891463a67a949b5278ef \ + --hash=sha256:79cd03e7ff550c17758a7520bf437c156d3d4c8bb74214deeafa69cda49c85a4 \ + --hash=sha256:80aba5f85d6227faee628ae28d1c3b69c661806a0636548ac56c68782606454f \ + --hash=sha256:81a1669b6631976b1dc9d3d58ed1ab3333e9f52feb91a2a1fb8241101ac3b665 \ + --hash=sha256:8597c35c9e82f65fd5897c4a2188c65d7daf10607b102960137b23d261cd957b \ + --hash=sha256:8650158217b469d8b6087f490929211b0493a9121154c4efaafd1dec9e19319e \ + --hash=sha256:8887bf0f31e4b550bd988c8863b527b6587d200653e9375cd91eea2b944b7424 \ + --hash=sha256:8a52b24cd710690c4a7e191c7e300136ad2ecb3c68ffe7e95b598e76de166e5e \ + --hash=sha256:8e3754ce60e1b11b0afad9a053481ff184d2ee24bea47099107156d1b84a84aa \ + --hash=sha256:907f7b5501a534030738f0f27459a612d2266fd0507b007bb8f3e6de08167920 \ + --hash=sha256:90d6b9f2652303aefd2c5a26a5e14cb74a3a63d10faa642c08d790e99442a088 \ + --hash=sha256:98fd5b39410e9d69e10e90d0330e35650becaa5dd2548f509b9598f1f3c6124d \ + --hash=sha256:9bfdeff778d3f7ff449ca5922ab773899e7d31e26a576028b06a5e9cf0ed8c34 \ + --hash=sha256:9ebae74ce2b977c2fcb22d6a10aa0acb730022406977b2bcb6ddd6788f5c414a \ + --hash=sha256:a110d19881ca78a88583d3b07231e7c6864864f5f1f3491b638863ea45fa8708 \ + --hash=sha256:a1d190790ee39b8b7adeeb10fc4090dc4859eb4e75ed27bd8108710eef18f358 \ + --hash=sha256:a2f049c3f3c83e886cd1f53958e2a1ebb369be626bef9e50d8b24d79864f1df6 \ + --hash=sha256:a3af4e9f277d6b8acd369dc44a723a055752fca9d045094383af39f90a3e3729 \ + --hash=sha256:a42c7becd4c9ec4ab5769c754eb61112777bdc6e1c1525e2077389e193b5f5aa \ + --hash=sha256:a58a58cef0d911b1717154179a9ff47852249c536ea5966bde4370b6b20638ff \ + --hash=sha256:ab1f646ff531d70bfd25f01e60708dfa3d105eb458b7dedd9fe9a443039fd809 \ + --hash=sha256:ad940dc2db545dc978cb41cb9a683e2ff328f3ef581230b9ca40ff6c3d01d542 \ + --hash=sha256:afe3c3863f16704fb5d7c2c6ff56aaf9e054f6d269f7b4c9074c5476178d1aba \ + --hash=sha256:b1e3b9f4bf9a4120510ba77a77b2fb674893cd6795653545152bb11a79eecfcb \ + --hash=sha256:b2390ad81c03d93ef1d5afd18ffcf5935de827f1a2b96b2c829437968bdabccb \ + --hash=sha256:b37df4b10cb15dedfc203f69312d8eedd617b941c21df58c13af59496c53ad0f \ + --hash=sha256:b3df9447f9209f9aa0434ca74050e9509670c1ad99398fe5807abb90e5f3a014 \ + --hash=sha256:b4fe7f38aa8956fcc1cea270e62601e0e11066aff78e384be70fd283d30293b6 \ + --hash=sha256:c1d68c6980d4690a4550bd3db6c03146f7be68ef5d08d38bb1fb68b3e9c32fe3 \ + --hash=sha256:c24c1460486b6b36083252c2db21a814becf8495ccd0e76b7286623e37239b63 \ + --hash=sha256:c25132902d3eff38781e0d54f27a0942ec849e3c07dbdce83c4d92b7e43c8dce \ + --hash=sha256:c74bd9926954e7e575f9cd9890f63defd90cd8f812dfbf8e1efb72acc9355456 \ + --hash=sha256:c8139e9011117822391c5bcfd674c5948fb1e4b8cb9adf6f13d9890859ee3a1a \ + --hash=sha256:ce334915f5d31048f76a42c607bf26687cf045eb1bc852b7340f09729c6a64fc \ + --hash=sha256:d14229beaa76e66c3a25f9477d973336441ca820df853679a98796256813316f \ + --hash=sha256:d42f3a13290f89191568fc113d95a3d2c8759cdd8c3672f021d8b7436f909e75 \ + --hash=sha256:d8e56e0d1fe607bfff422633f313aec9191c3859ab99d11ff097e3e6e068000c \ + --hash=sha256:da6f0302360e99d32bc2869772692797ebadd536e1b826d0103c72ba49d38698 \ + --hash=sha256:db46baf157feefd88724e6a7f145fe996a5990a8604ed9292b45d563360e513b \ + --hash=sha256:dcea8c3f53674ae68e44b12e853b844a1d315250ca6677b11ec0c06aff85e86c \ + --hash=sha256:de94b409f49eb6a588ebdd5872e826caec417cd77c17af0fb94f2128427f1a2a \ + --hash=sha256:e0356561b4a97c83b9ee3de657a41b8d1a1781226853adaf47b550bb988fda6f \ + --hash=sha256:e0db44cf81e4d7b94f3776b9f89111f74ed6bbdbfd42a22bc4a5ce0644d3e060 \ + --hash=sha256:e31e92b61d56244047ad600812e16f7587a6172f74810fd919ff993af12b9149 \ + --hash=sha256:e89dabf436ee79b358fd970dcbed6333a36d91db73f27069ca24a02fb138a404 \ + --hash=sha256:eddeb9a153795cf6e615f9f3cef66a1d573ff3b6ee16df2b10d1d1c2f2baeaa8 \ + --hash=sha256:ee11fd431f83d8a5b29d370b9d79a814d3218d30113bdcd44657e9bdf715fc92 \ + --hash=sha256:ee37fe8cf081b72dea72f96a0ee604f492ec02252eb77dc26ff6eec3f997b580 \ + --hash=sha256:f19ee7dc1ef8a6497570d91fa4057ba910ad98297a50b8c44ff37589f7c89d17 \ + --hash=sha256:f2f94355affd51088f57f8674b0e294704c3c7c3d7d3b1545310f5b135d4843b \ + --hash=sha256:f525734382a47f9828c9d6a1501522c78d5935466d8e2be1a41ba40ca5bb922b \ + --hash=sha256:f915a34fb742e23d0d61573349aa45d6f74037fde9d58a9f340435eff8d62736 # via feast (pyproject.toml) hpack==4.1.0 \ --hash=sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496 \ @@ -1828,13 +1844,13 @@ ibis-framework[duckdb, mssql, oracle]==12.0.0 \ --hash=sha256:0bbd790f268da9cb87926d5eaad2b827a573927113c4ed3be5095efa89b9e512 \ --hash=sha256:238624f2c14fdab8382ca2f4f667c3cdb81e29844cd5f8db8a325d0743767c61 # via feast (pyproject.toml) -identify==2.6.18 \ - --hash=sha256:873ac56a5e3fd63e7438a7ecbc4d91aca692eb3fefa4534db2b7913f3fc352fd \ - --hash=sha256:8db9d3c8ea9079db92cafb0ebf97abdc09d52e97f4dcf773a2e694048b7cd737 +identify==2.6.19 \ + --hash=sha256:20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a \ + --hash=sha256:6be5020c38fcb07da56c53733538a3081ea5aa70d36a156f83044bfbf9173842 # via pre-commit -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.13 \ + --hash=sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242 \ + --hash=sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 # via # anyio # httpx @@ -1856,9 +1872,9 @@ importlib-metadata==9.0.0 \ # via # build # dask -importlib-resources==6.5.2 \ - --hash=sha256:185f87adef5bcc288449d98fb4fba07cea78bc036455dd44c5fc4a2fe78fed2c \ - --hash=sha256:789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec +importlib-resources==7.1.0 \ + --hash=sha256:0722d4c6212489c530f2a145a34c0a7a3b4721bc96a15fada5930e2a0b760708 \ + --hash=sha256:1bd7b48b4088eddb2cd16382150bb515af0bd2c70128194392725f82ad2c96a1 # via happybase iniconfig==2.3.0 \ --hash=sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730 \ @@ -1973,9 +1989,9 @@ 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.1 \ --hash=sha256:71b954d834e85ff3096400554f2eefaf7fe37053036f9a782b0f7c5e42dadb81 \ @@ -1994,9 +2010,9 @@ jupyter-server-terminals==0.5.4 \ --hash=sha256:55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14 \ --hash=sha256:bbda128ed41d0be9020349f9f1f2a4ab9952a73ed5f5ac9f1419794761fb87f5 # via jupyter-server -jupyterlab==4.5.6 \ - --hash=sha256:642fe2cfe7f0f5922a8a558ba7a0d246c7bc133b708dfe43f7b3a826d163cf42 \ - --hash=sha256:d6b3dac883aa4d9993348e0f8e95b24624f75099aed64eab6a4351a9cdd1e580 +jupyterlab==4.5.7 \ + --hash=sha256:55a9822c4754da305f41e113452c68383e214dcf96de760146af89ce5d5117b0 \ + --hash=sha256:fba4cb0e2c44a52859669d8c98b45de029d5e515f8407bf8534d2a8fc5f0964d # via notebook jupyterlab-pygments==0.3.0 \ --hash=sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d \ @@ -2012,9 +2028,9 @@ 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 \ @@ -2024,9 +2040,9 @@ lark==1.3.1 \ --hash=sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905 \ --hash=sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12 # via rfc3987-syntax -latex2mathml==3.79.0 \ - --hash=sha256:11bde318c2d2d6fcdd105a07509d867cee2208f653278eb80243dec7ea77a0ce \ - --hash=sha256:9f10720d4fcf6b22d1b81f6628237832419a7a29783c13aa92fa8d680165e63d +latex2mathml==3.81.0 \ + --hash=sha256:4b959cdc3cac8686bc0e3e5aece8127dfb1b81ca1241bed8e00ef31b82bb4022 \ + --hash=sha256:d317710393fe20579aea39cfe8928fa2ad9b8780896e585326c75e89c1d1d1a4 # via docling-core lazy-loader==0.5 \ --hash=sha256:717f9179a0dbed357012ddad50a5ad3d5e4d9a0b8712680d4e687f5e6e6ed9b3 \ @@ -2501,9 +2517,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.36.0 \ + --hash=sha256:36ecac30e2ff4322d956029aabce3c82301c29f0acb1ad89b94edcabb0e58ec4 \ + --hash=sha256:3f6a4af2b036b476a4215111c4297b4e6e236ed186cd804faefba23e4990978b # via # azure-identity # msal-extensions @@ -2789,9 +2805,9 @@ nbclient==0.10.4 \ --hash=sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9 \ --hash=sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440 # 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 \ @@ -2836,9 +2852,9 @@ nodeenv==1.10.0 \ --hash=sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 \ --hash=sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb # via pre-commit -notebook==7.5.5 \ - --hash=sha256:a7c14dbeefa6592e87f72290ca982e0c10f5bbf3786be2a600fda9da2764a2b8 \ - --hash=sha256:dc0bfab0f2372c8278c457423d3256c34154ac2cc76bf20e9925260c461013c3 +notebook==7.5.6 \ + --hash=sha256:4dde3f8fb55fa8fb7946d58c6e869ce9baf46d00fc070664f62604569d0faca0 \ + --hash=sha256:621174aade80108f0020b0f00738000b215f75fa3cd90771ad7aa0f24536a4e1 # via great-expectations notebook-shim==0.2.4 \ --hash=sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef \ @@ -2942,8 +2958,8 @@ opencv-python-headless==4.13.0.92 \ --hash=sha256:a7cf08e5b191f4ebb530791acc0825a7986e0d0dee2a3c491184bd8599848a4b \ --hash=sha256:eb60e36b237b1ebd40a912da5384b348df8ed534f6f644d8e0b4f103e272ba7d # via easyocr -openlineage-python==1.45.0 \ - --hash=sha256:cf66e7d517d3c8b510b39ad646d8fd0ca2f0cc92d7d6d601d93b2a859783f380 +openlineage-python==1.46.0 \ + --hash=sha256:f6228a01d34990e76ede5b55b3f99169e54e2e624814c4493f064b9cb1bfba37 # via feast (pyproject.toml) openpyxl==3.1.5 \ --hash=sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2 \ @@ -3062,9 +3078,9 @@ 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 @@ -3316,9 +3332,9 @@ pillow==11.3.0 \ # python-pptx # scikit-image # torchvision -pip==26.0.1 \ - --hash=sha256:bdb1b08f4274833d62c1aa29e20907365a2ceb950410df15fc9521bad440122b \ - --hash=sha256:c4037d8a277c89b320abe636d59f91e6d0922d08a05b60e85e53b296613346d8 +pip==26.1 \ + --hash=sha256:4e8486d821d814b77319acb7b9e8bf5a4ee7590a643e7cb21029f209be8573c1 \ + --hash=sha256:81e13ebcca3ffa8cc85e4deff5c27e1ee26dea0aa7fc2f294a073ac208806ff3 # via pip-tools pip-tools==7.5.3 \ --hash=sha256:3aac0c473240ae90db7213c033401f345b05197293ccbdd2704e52e7a783785e \ @@ -3350,9 +3366,9 @@ pre-commit==3.3.1 \ --hash=sha256:218e9e3f7f7f3271ebc355a15598a4d3893ad9fc7b57fe446db75644543323b9 \ --hash=sha256:733f78c9a056cdd169baa6cd4272d51ecfda95346ef8a89bf93712706021b907 # via feast (pyproject.toml) -prometheus-client==0.24.1 \ - --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ - --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 +prometheus-client==0.25.0 \ + --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ + --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 # via # feast (pyproject.toml) # jupyter-server @@ -3658,57 +3674,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 @@ -3820,9 +3836,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.3 \ + --hash=sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927 \ + --hash=sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d # via # feast (pyproject.toml) # dbt-artifacts-parser @@ -3836,134 +3852,134 @@ pydantic==2.12.5 \ # mcp # 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.3 \ + --hash=sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba \ + --hash=sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35 \ + --hash=sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4 \ + --hash=sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505 \ + --hash=sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7 \ + --hash=sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8 \ + --hash=sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4 \ + --hash=sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37 \ + --hash=sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25 \ + --hash=sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022 \ + --hash=sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1 \ + --hash=sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7 \ + --hash=sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c \ + --hash=sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3 \ + --hash=sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb \ + --hash=sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3 \ + --hash=sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976 \ + --hash=sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c \ + --hash=sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab \ + --hash=sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa \ + --hash=sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6 \ + --hash=sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396 \ + --hash=sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c \ + --hash=sha256:3d08782c4045f90724b44c95d35ebec0d67edb8a957a2ac81d5a8e4b8a200495 \ + --hash=sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c \ + --hash=sha256:4335e87c7afa436a0dfa899e138d57a72f8aad542e2cf19c36fb428461caabd0 \ + --hash=sha256:4b068543bdb707f5d935dab765d99227aa2545ef2820935f2e5dd801795c7dbd \ + --hash=sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf \ + --hash=sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531 \ + --hash=sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5 \ + --hash=sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda \ + --hash=sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d \ + --hash=sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e \ + --hash=sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df \ + --hash=sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6 \ + --hash=sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c \ + --hash=sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13 \ + --hash=sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536 \ + --hash=sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287 \ + --hash=sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0 \ + --hash=sha256:68ef2f623dda6d5a9067ac014e406c020c780b2a358930a7e5c1b73702900720 \ + --hash=sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050 \ + --hash=sha256:6dff8cc884679df229ebc6d8eb2321ea6f8e091bc7d4886d4dc2e0e71452843c \ + --hash=sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1 \ + --hash=sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8 \ + --hash=sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0 \ + --hash=sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374 \ + --hash=sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807 \ + --hash=sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6 \ + --hash=sha256:831eb19aa789a97356979e94c981e5667759301fb708d1c0d5adf1bc0098b873 \ + --hash=sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57 \ + --hash=sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f \ + --hash=sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c \ + --hash=sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad \ + --hash=sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e \ + --hash=sha256:91249bcb7c165c2fb2a2f852dbc5c91636e2e218e75d96dfdd517e4078e173dd \ + --hash=sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23 \ + --hash=sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46 \ + --hash=sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1 \ + --hash=sha256:99421e7684a60f7f3550a1d159ade5fdff1954baedb6bdd407cba6a307c9f27d \ + --hash=sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1 \ + --hash=sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee \ + --hash=sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c \ + --hash=sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874 \ + --hash=sha256:9f247596366f4221af52beddd65af1218797771d6989bc891a0b86ccaa019168 \ + --hash=sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a \ + --hash=sha256:a35cc284c8dd7edae8a31533713b4d2467dfe7c4f1b5587dd4031f28f90d1d13 \ + --hash=sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f \ + --hash=sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a \ + --hash=sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789 \ + --hash=sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe \ + --hash=sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f \ + --hash=sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5 \ + --hash=sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943 \ + --hash=sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b \ + --hash=sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089 \ + --hash=sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b \ + --hash=sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff \ + --hash=sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67 \ + --hash=sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803 \ + --hash=sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045 \ + --hash=sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8 \ + --hash=sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346 \ + --hash=sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2 \ + --hash=sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f \ + --hash=sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687 \ + --hash=sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76 \ + --hash=sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1 \ + --hash=sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f \ + --hash=sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2 \ + --hash=sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c \ + --hash=sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018 \ + --hash=sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba \ + --hash=sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c \ + --hash=sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf \ + --hash=sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7 \ + --hash=sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47 \ + --hash=sha256:d56bdb4af1767cc15b0386b3c581fdfe659bb9ee4a4f776e92c1cd9d074000d6 \ + --hash=sha256:dcda6583921c05a40533f982321532f2d8db29326c7b95c4026941fa5074bd79 \ + --hash=sha256:dd81f6907932ebac3abbe41378dac64b2380db1287e2aa64d8d88f78d170f51a \ + --hash=sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e \ + --hash=sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a \ + --hash=sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34 \ + --hash=sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b \ + --hash=sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85 \ + --hash=sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca \ + --hash=sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f \ + --hash=sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3 \ + --hash=sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64 \ + --hash=sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22 \ + --hash=sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72 \ + --hash=sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec \ + --hash=sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d \ + --hash=sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3 \ + --hash=sha256:fa3eb7c2995aa443687a825bc30395c8521b7c6ec201966e55debfd1128bcceb \ + --hash=sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395 \ + --hash=sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb \ + --hash=sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4 \ + --hash=sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127 \ + --hash=sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56 # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.0 \ + --hash=sha256:24285fd4b0e0c06507dd9fdfd331ee23794305352aaec8fc4eb92d4047aeb67d \ + --hash=sha256:fc8d5d692eb7092e43c8647c1c35a3ecd00e040fcf02ed86f4cb5458ca62182e # via # docling + # docling-core # fastapi-mcp # mcp pydata-google-auth==1.9.1 \ @@ -3996,6 +4012,79 @@ pymilvus==2.5.18 \ --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d # 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 \ --hash=sha256:0768d90f96ae3267d7561d3bcfe94dd671d107489e870388b12570c3debbc552 \ @@ -4056,9 +4145,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.1.3 \ + --hash=sha256:8164ba62c552f6105f3b11753352d0f16b90d1703ba67d81923d5a8a5d1c5289 \ + --hash=sha256:e70ebf2047a4edf6138cf79c68ad418ef620af65900aa585c5e8bfc95044d43a # via feast (pyproject.toml) pyodbc==5.3.0 \ --hash=sha256:01166162149adf2b8a6dc21a212718f205cabbbdff4047dc0c415af3fd85867e \ @@ -4128,9 +4217,9 @@ pyodbc==5.3.0 \ # via # feast (pyproject.toml) # ibis-framework -pyopenssl==26.0.0 \ - --hash=sha256:df94d28498848b98cc1c0ffb8ef1e71e40210d3b0a8064c9d29571ed2904bf81 \ - --hash=sha256:f293934e52936f2e3413b89c6ce36df66a0b34ae1ea3a053b8c5020ff2f513fc +pyopenssl==26.1.0 \ + --hash=sha256:115563879b2c8ccb207975705d3e491434d8c9d7c79667c902ecbf5f3bbd2ece \ + --hash=sha256:737f0a2275c5bc54f3b02137687e1a765931fb3949b9a92a825e4d33b9eec08b # via snowflake-connector-python pyparsing==3.3.2 \ --hash=sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d \ @@ -4356,9 +4445,9 @@ 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.27 \ + --hash=sha256:6fccfad17a27334bd0193681b369f476eda3409f17381a2d65aa7df3f7275645 \ + --hash=sha256:9870a6a8c5a20a5bf4f07c017bd1489006ff8836cff097b6933355ee2b49b602 # via mcp python-pptx==1.0.2 \ --hash=sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba \ @@ -4565,26 +4654,29 @@ qdrant-client==1.17.1 \ --hash=sha256:22f990bbd63485ed97ba551a4c498181fcb723f71dcab5d6e4e43fe1050a2bc0 \ --hash=sha256:6cda4064adfeaf211c751f3fbc00edbbdb499850918c7aff4855a9a759d56cbd # via feast (pyproject.toml) -ray==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 +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.0 \ + --hash=sha256:64a6ea7bf567ad43c964d2c30d82853f8df927c5c9017766c55a1d1ed95d18ad \ + --hash=sha256:a9c74a5c893a5ef8455a5adb793a31bb70feb821c86eccb62eebef5a19c429ec # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -4593,121 +4685,121 @@ referencing==0.37.0 \ # jsonschema # jsonschema-specifications # jupyter-events -regex==2026.3.32 \ - --hash=sha256:03c2ebd15ff51e7b13bb3dc28dd5ac18cd39e59ebb40430b14ae1a19e833cff1 \ - --hash=sha256:09e26cad1544d856da85881ad292797289e4406338afe98163f3db9f7fac816c \ - --hash=sha256:0cec365d44835b043d7b3266487797639d07d621bec9dc0ea224b00775797cc1 \ - --hash=sha256:0d7855f5e59fcf91d0c9f4a51dc5d8847813832a2230c3e8e35912ccf20baaa2 \ - --hash=sha256:0f21ae18dfd15752cdd98d03cbd7a3640be826bfd58482a93f730dbd24d7b9fb \ - --hash=sha256:10fb2aaae1aaadf7d43c9f3c2450404253697bf8b9ce360bd5418d1d16292298 \ - --hash=sha256:110ba4920721374d16c4c8ea7ce27b09546d43e16aea1d7f43681b5b8f80ba61 \ - --hash=sha256:12917c6c6813ffcdfb11680a04e4d63c5532b88cf089f844721c5f41f41a63ad \ - --hash=sha256:18eb45f711e942c27dbed4109830bd070d8d618e008d0db39705f3f57070a4c6 \ - --hash=sha256:1a6ac1ed758902e664e0d95c1ee5991aa6fb355423f378ed184c6ec47a1ec0e9 \ - --hash=sha256:1ca02ff0ef33e9d8276a1fcd6d90ff6ea055a32c9149c0050b5b67e26c6d2c51 \ - --hash=sha256:1cb22fa9ee6a0acb22fc9aecce5f9995fe4d2426ed849357d499d62608fbd7f9 \ - --hash=sha256:1e0f6648fd48f4c73d801c55ab976cd602e2da87de99c07bff005b131f269c6a \ - --hash=sha256:245667ad430745bae6a1e41081872d25819d86fbd9e0eec485ba00d9f78ad43d \ - --hash=sha256:2820d2231885e97aff0fcf230a19ebd5d2b5b8a1ba338c20deb34f16db1c7897 \ - --hash=sha256:2c8d402ea3dfe674288fe3962016affd33b5b27213d2b5db1823ffa4de524c57 \ - --hash=sha256:2dcca2bceb823c9cc610e57b86a265d7ffc30e9fe98548c609eba8bd3c0c2488 \ - --hash=sha256:2ffbadc647325dd4e3118269bda93ded1eb5f5b0c3b7ba79a3da9fbd04f248e9 \ - --hash=sha256:34c905a721ddee0f84c99e3e3b59dd4a5564a6fe338222bc89dd4d4df166115c \ - --hash=sha256:3c054e39a9f85a3d76c62a1d50c626c5e9306964eaa675c53f61ff7ec1204bbb \ - --hash=sha256:3c0bbfbd38506e1ea96a85da6782577f06239cb9fcf9696f1ea537c980c0680b \ - --hash=sha256:3e221b615f83b15887636fcb90ed21f1a19541366f8b7ba14ba1ad8304f4ded4 \ - --hash=sha256:3ea568832eca219c2be1721afa073c1c9eb8f98a9733fdedd0a9747639fc22a5 \ - --hash=sha256:3f5747501b69299c6b0b047853771e4ed390510bada68cb16da9c9c2078343f7 \ - --hash=sha256:462a041d2160090553572f6bb0be417ab9bb912a08de54cb692829c871ee88c1 \ - --hash=sha256:4bc32b4dbdb4f9f300cf9f38f8ea2ce9511a068ffaa45ac1373ee7a943f1d810 \ - --hash=sha256:4d082be64e51671dd5ee1c208c92da2ddda0f2f20d8ef387e57634f7e97b6aae \ - --hash=sha256:4f9ae4755fa90f1dc2d0d393d572ebc134c0fe30fcfc0ab7e67c1db15f192041 \ - --hash=sha256:51a93452034d671b0e21b883d48ea66c5d6a05620ee16a9d3f229e828568f3f0 \ - --hash=sha256:51fb7e26f91f9091fd8ec6a946f99b15d3bc3667cb5ddc73dd6cb2222dd4a1cc \ - --hash=sha256:5336b1506142eb0f23c96fb4a34b37c4fefd4fed2a7042069f3c8058efe17855 \ - --hash=sha256:567b57eb987547a23306444e4f6f85d4314f83e65c71d320d898aa7550550443 \ - --hash=sha256:5aa78c857c1731bdd9863923ffadc816d823edf475c7db6d230c28b53b7bdb5e \ - --hash=sha256:5bf2f3c2c5bd8360d335c7dcd4a9006cf1dabae063ee2558ee1b07bbc8a20d88 \ - --hash=sha256:5c35d097f509cf7e40d20d5bee548d35d6049b36eb9965e8d43e4659923405b9 \ - --hash=sha256:5d86e3fb08c94f084a625c8dc2132a79a3a111c8bf6e2bc59351fa61753c2f6e \ - --hash=sha256:6062c4ef581a3e9e503dccf4e1b7f2d33fdc1c13ad510b287741ac73bc4c6b27 \ - --hash=sha256:6128dd0793a87287ea1d8bf16b4250dd96316c464ee15953d5b98875a284d41e \ - --hash=sha256:631f7d95c83f42bccfe18946a38ad27ff6b6717fb4807e60cf24860b5eb277fc \ - --hash=sha256:66a5083c3ffe5a5a95f8281ea47a88072d4f24001d562d1d9d28d4cdc005fec5 \ - --hash=sha256:66d3126afe7eac41759cd5f0b3b246598086e88e70527c0d68c9e615b81771c4 \ - --hash=sha256:67015a8162d413af9e3309d9a24e385816666fbf09e48e3ec43342c8536f7df6 \ - --hash=sha256:6980ceb5c1049d4878632f08ba0bf7234c30e741b0dc9081da0f86eca13189d3 \ - --hash=sha256:69a847a6ffaa86e8af7b9e7037606e05a6f663deec516ad851e8e05d9908d16a \ - --hash=sha256:6ada7bd5bb6511d12177a7b00416ce55caee49fbf8c268f26b909497b534cacb \ - --hash=sha256:70c634e39c5cda0da05c93d6747fdc957599f7743543662b6dbabdd8d3ba8a96 \ - --hash=sha256:7cdd508664430dd51b8888deb6c5b416d8de046b2e11837254378d31febe4a98 \ - --hash=sha256:844d88509c968dd44b30daeefac72b038b1bf31ac372d5106358ab01d393c48b \ - --hash=sha256:847087abe98b3c1ebf1eb49d6ef320dbba75a83ee4f83c94704580f1df007dd4 \ - --hash=sha256:85c9b0c131427470a6423baa0a9330be6fd8c3630cc3ee6fdee03360724cbec5 \ - --hash=sha256:879ae91f2928a13f01a55cfa168acedd2b02b11b4cd8b5bb9223e8cde777ca52 \ - --hash=sha256:887a9fa74418d74d645281ee0edcf60694053bd1bc2ebc49eb5e66bfffc6d107 \ - --hash=sha256:88ebc0783907468f17fca3d7821b30f9c21865a721144eb498cb0ff99a67bcac \ - --hash=sha256:89e50667e7e8c0e7903e4d644a2764fffe9a3a5d6578f72ab7a7b4205bf204b7 \ - --hash=sha256:8a4a3189a99ecdd1c13f42513ab3fc7fa8311b38ba7596dd98537acb8cd9acc3 \ - --hash=sha256:8aaf8ee8f34b677f90742ca089b9c83d64bdc410528767273c816a863ed57327 \ - --hash=sha256:8e4c8fa46aad1a11ae2f8fcd1c90b9d55e18925829ac0d98c5bb107f93351745 \ - --hash=sha256:8fc918cd003ba0d066bf0003deb05a259baaaab4dc9bd4f1207bbbe64224857a \ - --hash=sha256:8fe14e24124ef41220e5992a0f09432f890037df6f93fd3d6b7a0feff2db16b2 \ - --hash=sha256:918db4e34a7ef3d0beee913fa54b34231cc3424676f1c19bdb85f01828d3cd37 \ - --hash=sha256:987cdfcfb97a249abc3601ad53c7de5c370529f1981e4c8c46793e4a1e1bfe8e \ - --hash=sha256:9b9118a78e031a2e4709cd2fcc3028432e89b718db70073a8da574c249b5b249 \ - --hash=sha256:9cf7036dfa2370ccc8651521fcbb40391974841119e9982fa312b552929e6c85 \ - --hash=sha256:a094e9dcafedfb9d333db5cf880304946683f43a6582bb86688f123335122929 \ - --hash=sha256:a416ee898ecbc5d8b283223b4cf4d560f93244f6f7615c1bd67359744b00c166 \ - --hash=sha256:a5d88fa37ba5e8a80ca8d956b9ea03805cfa460223ac94b7d4854ee5e30f3173 \ - --hash=sha256:ace48c5e157c1e58b7de633c5e257285ce85e567ac500c833349c363b3df69d4 \ - --hash=sha256:ad5c53f2e8fcae9144009435ebe3d9832003508cf8935c04542a1b3b8deefa15 \ - --hash=sha256:ad8d372587e659940568afd009afeb72be939c769c552c9b28773d0337251391 \ - --hash=sha256:b193ed199848aa96618cd5959c1582a0bf23cd698b0b900cb0ffe81b02c8659c \ - --hash=sha256:b2e9c2ea2e93223579308263f359eab8837dc340530b860cb59b713651889f14 \ - --hash=sha256:b3aa21bad31db904e0b9055e12c8282df62d43169c4a9d2929407060066ebc74 \ - --hash=sha256:b565f25171e04d4fad950d1fa837133e3af6ea6f509d96166eed745eb0cf63bc \ - --hash=sha256:b56993a7aeb4140c4770f4f7965c9e5af4f024457d06e23c01b0d47501cb18ed \ - --hash=sha256:b6acb765e7c1f2fa08ac9057a33595e26104d7d67046becae184a8f100932dd9 \ - --hash=sha256:b6f366a5ef66a2df4d9e68035cfe9f0eb8473cdfb922c37fac1d169b468607b0 \ - --hash=sha256:b7836aa13721dbdef658aebd11f60d00de633a95726521860fe1f6be75fa225a \ - --hash=sha256:b8fca73e16c49dd972ce3a88278dfa5b93bf91ddef332a46e9443abe21ca2f7c \ - --hash=sha256:b953d9d496d19786f4d46e6ba4b386c6e493e81e40f9c5392332458183b0599d \ - --hash=sha256:bbc458a292aee57d572075f22c035fa32969cdb7987d454e3e34d45a40a0a8b4 \ - --hash=sha256:c1cecea3e477af105f32ef2119b8d895f297492e41d317e60d474bc4bffd62ff \ - --hash=sha256:c1d7fa44aece1fa02b8927441614c96520253a5cad6a96994e3a81e060feed55 \ - --hash=sha256:c1ed17104d1be7f807fdec35ec99777168dd793a09510d753f8710590ba54cdd \ - --hash=sha256:c3c6f6b027d10f84bfe65049028892b5740878edd9eae5fea0d1710b09b1d257 \ - --hash=sha256:c5e0fdb5744caf1036dec5510f543164f2144cb64932251f6dfd42fa872b7f9c \ - --hash=sha256:c60f1de066eb5a0fd8ee5974de4194bb1c2e7692941458807162ffbc39887303 \ - --hash=sha256:c6d9c6e783b348f719b6118bb3f187b2e138e3112576c9679eb458cc8b2e164b \ - --hash=sha256:c940e00e8d3d10932c929d4b8657c2ea47d2560f31874c3e174c0d3488e8b865 \ - --hash=sha256:c9f261ad3cd97257dc1d9355bfbaa7dd703e06574bffa0fa8fe1e31da915ee38 \ - --hash=sha256:d21a07edddb3e0ca12a8b8712abc8452481c3d3db19ae87fc94e9842d005964b \ - --hash=sha256:d363660f9ef8c734495598d2f3e527fb41f745c73159dc0d743402f049fb6836 \ - --hash=sha256:d478a2ca902b6ef28ffc9521e5f0f728d036abe35c0b250ee8ae78cfe7c5e44e \ - --hash=sha256:d571f0b2eec3513734ea31a16ce0f7840c0b85a98e7edfa0e328ed144f9ef78f \ - --hash=sha256:d6b39a2cc5625bbc4fda18919a891eab9aab934eecf83660a90ce20c53621a9a \ - --hash=sha256:d76d62909bfb14521c3f7cfd5b94c0c75ec94b0a11f647d2f604998962ec7b6c \ - --hash=sha256:dab4178a0bc1ef13178832b12db7bc7f562e8f028b2b5be186e370090dc50652 \ - --hash=sha256:db976be51375bca900e008941639448d148c655c9545071965d0571ecc04f5d0 \ - --hash=sha256:ded4fc0edf3de792850cb8b04bbf3c5bd725eeaf9df4c27aad510f6eed9c4e19 \ - --hash=sha256:e006ea703d5c0f3d112b51ba18af73b58209b954acfe3d8da42eacc9a00e4be6 \ - --hash=sha256:e3e5d1802cba785210a4a800e63fcee7a228649a880f3bf7f2aadccb151a834b \ - --hash=sha256:e480d3dac06c89bc2e0fd87524cc38c546ac8b4a38177650745e64acbbcfdeba \ - --hash=sha256:e50af656c15e2723eeb7279c0837e07accc594b95ec18b86821a4d44b51b24bf \ - --hash=sha256:e83ce8008b48762be296f1401f19afd9ea29f3d035d1974e0cecb74e9afbd1df \ - --hash=sha256:ed3b8281c5d0944d939c82db4ec2300409dd69ee087f7a75a94f2e301e855fb4 \ - --hash=sha256:ef250a3f5e93182193f5c927c5e9575b2cb14b80d03e258bc0b89cc5de076b60 \ - --hash=sha256:f1574566457161678297a116fa5d1556c5a4159d64c5ff7c760e7c564bf66f16 \ - --hash=sha256:f26262900edd16272b6360014495e8d68379c6c6e95983f9b7b322dc928a1194 \ - --hash=sha256:f28eac18a8733a124444643a66ac96fef2c0ad65f50034e0a043b90333dc677f \ - --hash=sha256:f54840bea73541652f1170dc63402a5b776fc851ad36a842da9e5163c1f504a0 \ - --hash=sha256:f785f44a44702dea89b28bce5bc82552490694ce4e144e21a4f0545e364d2150 \ - --hash=sha256:f7cc00089b4c21847852c0ad76fb3680f9833b855a0d30bcec94211c435bff6b \ - --hash=sha256:f95bd07f301135771559101c060f558e2cf896c7df00bec050ca7f93bf11585a \ - --hash=sha256:fc8ced733d6cd9af5e412f256a32f7c61cd2d7371280a65c689939ac4572499f \ - --hash=sha256:fd03e38068faeef937cc6761a250a4aaa015564bd0d61481fefcf15586d31825 +regex==2026.4.4 \ + --hash=sha256:011bb48bffc1b46553ac704c975b3348717f4e4aa7a67522b51906f99da1820c \ + --hash=sha256:04bb679bc0bde8a7bfb71e991493d47314e7b98380b083df2447cda4b6edb60f \ + --hash=sha256:0540e5b733618a2f84e9cb3e812c8afa82e151ca8e19cf6c4e95c5a65198236f \ + --hash=sha256:05568c4fbf3cb4fa9e28e3af198c40d3237cf6041608a9022285fe567ec3ad62 \ + --hash=sha256:0709f22a56798457ae317bcce42aacee33c680068a8f14097430d9f9ba364bee \ + --hash=sha256:0734f63afe785138549fbe822a8cfeaccd1bae814c5057cc0ed5b9f2de4fc883 \ + --hash=sha256:07edca1ba687998968f7db5bc355288d0c6505caa7374f013d27356d93976d13 \ + --hash=sha256:07f190d65f5a72dcb9cf7106bfc3d21e7a49dd2879eda2207b683f32165e4d99 \ + --hash=sha256:08c55c13d2eef54f73eeadc33146fb0baaa49e7335eb1aff6ae1324bf0ddbe4a \ + --hash=sha256:0a51cdb3c1e9161154f976cb2bef9894bc063ac82f31b733087ffb8e880137d0 \ + --hash=sha256:1371c2ccbb744d66ee63631cc9ca12aa233d5749972626b68fe1a649dd98e566 \ + --hash=sha256:173a66f3651cdb761018078e2d9487f4cf971232c990035ec0eb1cdc6bf929a9 \ + --hash=sha256:1b1ce5c81c9114f1ce2f9288a51a8fd3aeea33a0cc440c415bf02da323aa0a76 \ + --hash=sha256:1b9a00b83f3a40e09859c78920571dcb83293c8004079653dd22ec14bbfa98c7 \ + --hash=sha256:21e5eb86179b4c67b5759d452ea7c48eb135cd93308e7a260aa489ed2eb423a4 \ + --hash=sha256:261c015b3e2ed0919157046d768774ecde57f03d8fa4ba78d29793447f70e717 \ + --hash=sha256:2895506ebe32cc63eeed8f80e6eae453171cfccccab35b70dc3129abec35a5b8 \ + --hash=sha256:298c3ec2d53225b3bf91142eb9691025bab610e0c0c51592dde149db679b3d17 \ + --hash=sha256:2a5d273181b560ef8397c8825f2b9d57013de744da9e8257b8467e5da8599351 \ + --hash=sha256:2b69102a743e7569ebee67e634a69c4cb7e59d6fa2e1aa7d3bdbf3f61435f62d \ + --hash=sha256:2c785939dc023a1ce4ec09599c032cc9933d258a998d16ca6f2b596c010940eb \ + --hash=sha256:2da82d643fa698e5e5210e54af90181603d5853cf469f5eedf9bfc8f59b4b8c7 \ + --hash=sha256:2e19e18c568d2866d8b6a6dfad823db86193503f90823a8f66689315ba28fbe8 \ + --hash=sha256:312ec9dd1ae7d96abd8c5a36a552b2139931914407d26fba723f9e53c8186f86 \ + --hash=sha256:33424f5188a7db12958246a54f59a435b6cb62c5cf9c8d71f7cc49475a5fdada \ + --hash=sha256:3384df51ed52db0bea967e21458ab0a414f67cdddfd94401688274e55147bb81 \ + --hash=sha256:33bfda9684646d323414df7abe5692c61d297dbb0530b28ec66442e768813c59 \ + --hash=sha256:349d7310eddff40429a099c08d995c6d4a4bfaf3ff40bd3b5e5cb5a5a3c7d453 \ + --hash=sha256:36bcb9d6d1307ab629edc553775baada2aefa5c50ccc0215fbfd2afcfff43141 \ + --hash=sha256:3790ba9fb5dd76715a7afe34dbe603ba03f8820764b1dc929dd08106214ed031 \ + --hash=sha256:385edaebde5db5be103577afc8699fea73a0e36a734ba24870be7ffa61119d74 \ + --hash=sha256:39d8de85a08e32632974151ba59c6e9140646dcc36c80423962b1c5c0a92e244 \ + --hash=sha256:415a994b536440f5011aa77e50a4274d15da3245e876e5c7f19da349caaedd87 \ + --hash=sha256:421439d1bee44b19f4583ccf42670ca464ffb90e9fdc38d37f39d1ddd1e44f1f \ + --hash=sha256:475e50f3f73f73614f7cba5524d6de49dee269df00272a1b85e3d19f6d498465 \ + --hash=sha256:4ce255cc05c1947a12989c6db801c96461947adb7a59990f1360b5983fab4983 \ + --hash=sha256:504ffa8a03609a087cad81277a629b6ce884b51a24bd388a7980ad61748618ff \ + --hash=sha256:50a766ee2010d504554bfb5f578ed2e066898aa26411d57e6296230627cdefa0 \ + --hash=sha256:54170b3e95339f415d54651f97df3bff7434a663912f9358237941bbf9143f55 \ + --hash=sha256:54a1189ad9d9357760557c91103d5e421f0a2dabe68a5cdf9103d0dcf4e00752 \ + --hash=sha256:55d9304e0e7178dfb1e106c33edf834097ddf4a890e2f676f6c5118f84390f73 \ + --hash=sha256:586b89cdadf7d67bf86ae3342a4dcd2b8d70a832d90c18a0ae955105caf34dbe \ + --hash=sha256:59968142787042db793348a3f5b918cf24ced1f23247328530e063f89c128a95 \ + --hash=sha256:59efe72d37fd5a91e373e5146f187f921f365f4abc1249a5ab446a60f30dd5f8 \ + --hash=sha256:59f67cd0a0acaf0e564c20bbd7f767286f23e91e2572c5703bf3e56ea7557edb \ + --hash=sha256:5d354b18839328927832e2fa5f7c95b7a3ccc39e7a681529e1685898e6436d45 \ + --hash=sha256:62f5519042c101762509b1d717b45a69c0139d60414b3c604b81328c01bd1943 \ + --hash=sha256:6780f008ee81381c737634e75c24e5a6569cc883c4f8e37a37917ee79efcafd9 \ + --hash=sha256:6a50ab11b7779b849472337191f3a043e27e17f71555f98d0092fa6d73364520 \ + --hash=sha256:6aa809ed4dc3706cc38594d67e641601bd2f36d5555b2780ff074edfcb136cf8 \ + --hash=sha256:6c1818f37be3ca02dcb76d63f2c7aaba4b0dc171b579796c6fbe00148dfec6b1 \ + --hash=sha256:6dac006c8b6dda72d86ea3d1333d45147de79a3a3f26f10c1cf9287ca4ca0ac3 \ + --hash=sha256:7088fcdcb604a4417c208e2169715800d28838fefd7455fbe40416231d1d47c1 \ + --hash=sha256:70aadc6ff12e4b444586e57fc30771f86253f9f0045b29016b9605b4be5f7dfb \ + --hash=sha256:7429f4e6192c11d659900c0648ba8776243bf396ab95558b8c51a345afeddde6 \ + --hash=sha256:74fa82dcc8143386c7c0392e18032009d1db715c25f4ba22d23dc2e04d02a20f \ + --hash=sha256:760ef21c17d8e6a4fe8cf406a97cf2806a4df93416ccc82fc98d25b1c20425be \ + --hash=sha256:7698a6f38730fd1385d390d1ed07bb13dce39aa616aca6a6d89bea178464b9a4 \ + --hash=sha256:76d67d5afb1fe402d10a6403bae668d000441e2ab115191a804287d53b772951 \ + --hash=sha256:773d1dfd652bbffb09336abf890bfd64785c7463716bf766d0eb3bc19c8b7f27 \ + --hash=sha256:7d346fccdde28abba117cc9edc696b9518c3307fbfcb689e549d9b5979018c6d \ + --hash=sha256:8512fcdb43f1bf18582698a478b5ab73f9c1667a5b7548761329ef410cd0a760 \ + --hash=sha256:867bddc63109a0276f5a31999e4c8e0eb7bbbad7d6166e28d969a2c1afeb97f9 \ + --hash=sha256:88e9b048345c613f253bea4645b2fe7e579782b82cac99b1daad81e29cc2ed8e \ + --hash=sha256:8fae3c6e795d7678963f2170152b0d892cf6aee9ee8afc8c45e6be38d5107fe7 \ + --hash=sha256:9542ccc1e689e752594309444081582f7be2fdb2df75acafea8a075108566735 \ + --hash=sha256:9776b85f510062f5a75ef112afe5f494ef1635607bf1cc220c1391e9ac2f5e81 \ + --hash=sha256:97850d0638391bdc7d35dc1c1039974dcb921eaafa8cc935ae4d7f272b1d60b3 \ + --hash=sha256:993f657a7c1c6ec51b5e0ba97c9817d06b84ea5fa8d82e43b9405de0defdc2b9 \ + --hash=sha256:9a2741ce5a29d3c84b0b94261ba630ab459a1b847a0d6beca7d62d188175c790 \ + --hash=sha256:9e2f5217648f68e3028c823df58663587c1507a5ba8419f4fdfc8a461be76043 \ + --hash=sha256:a0d2b28aa1354c7cd7f71b7658c4326f7facac106edd7f40eda984424229fd59 \ + --hash=sha256:a152560af4f9742b96f3827090f866eeec5becd4765c8e0d3473d9d280e76a5a \ + --hash=sha256:a1c0c7d67b64d85ac2e1879923bad2f08a08f3004055f2f406ef73c850114bd4 \ + --hash=sha256:a7a5bb6aa0cf62208bb4fa079b0c756734f8ad0e333b425732e8609bd51ee22f \ + --hash=sha256:a85b620a388d6c9caa12189233109e236b3da3deffe4ff11b84ae84e218a274f \ + --hash=sha256:acd38177bd2c8e69a411d6521760806042e244d0ef94e2dd03ecdaa8a3c99427 \ + --hash=sha256:ae3e764bd4c5ff55035dc82a8d49acceb42a5298edf6eb2fc4d328ee5dd7afae \ + --hash=sha256:ae5266a82596114e41fb5302140e9630204c1b5f325c770bec654b95dd54b0aa \ + --hash=sha256:af0384cb01a33600c49505c27c6c57ab0b27bf84a74e28524c92ca897ebdac9d \ + --hash=sha256:b15b88b0d52b179712632832c1d6e58e5774f93717849a41096880442da41ab0 \ + --hash=sha256:b26c30df3a28fd9793113dac7385a4deb7294a06c0f760dd2b008bd49a9139bc \ + --hash=sha256:b40379b53ecbc747fd9bdf4a0ea14eb8188ca1bd0f54f78893a39024b28f4863 \ + --hash=sha256:b4c36a85b00fadb85db9d9e90144af0a980e1a3d2ef9cd0f8a5bef88054657c6 \ + --hash=sha256:b5f9fb784824a042be3455b53d0b112655686fdb7a91f88f095f3fee1e2a2a54 \ + --hash=sha256:be061028481186ba62a0f4c5f1cc1e3d5ab8bce70c89236ebe01023883bc903b \ + --hash=sha256:c07ab8794fa929e58d97a0e1796b8b76f70943fa39df225ac9964615cf1f9d52 \ + --hash=sha256:c228cf65b4a54583763645dcd73819b3b381ca8b4bb1b349dee1c135f4112c07 \ + --hash=sha256:c4ee50606cb1967db7e523224e05f32089101945f859928e65657a2cbb3d278b \ + --hash=sha256:c882cd92ec68585e9c1cf36c447ec846c0d94edd706fe59e0c198e65822fd23b \ + --hash=sha256:cf9b1b2e692d4877880388934ac746c99552ce6bf40792a767fd42c8c99f136d \ + --hash=sha256:d2228c02b368d69b724c36e96d3d1da721561fb9cc7faa373d7bf65e07d75cb5 \ + --hash=sha256:d51d20befd5275d092cdffba57ded05f3c436317ee56466c8928ac32d960edaf \ + --hash=sha256:db0ac18435a40a2543dbb3d21e161a6c78e33e8159bd2e009343d224bb03bb1b \ + --hash=sha256:dc4f10fbd5dd13dcf4265b4cc07d69ca70280742870c97ae10093e3d66000359 \ + --hash=sha256:dcb5453ecf9cd58b562967badd1edbf092b0588a3af9e32ee3d05c985077ce87 \ + --hash=sha256:dd2630faeb6876fb0c287f664d93ddce4d50cd46c6e88e60378c05c9047e08ca \ + --hash=sha256:e014a797de43d1847df957c0a2a8e861d1c17547ee08467d1db2c370b7568baa \ + --hash=sha256:e08270659717f6973523ce3afbafa53515c4dc5dcad637dc215b6fd50f689423 \ + --hash=sha256:e0aab3ff447845049d676827d2ff714aab4f73f340e155b7de7458cf53baa5a4 \ + --hash=sha256:e355be718caf838aa089870259cf1776dc2a4aa980514af9d02c59544d9a8b22 \ + --hash=sha256:e7ab63e9fe45a9ec3417509e18116b367e89c9ceb6219222a3396fa30b147f80 \ + --hash=sha256:e7cd3e4ee8d80447a83bbc9ab0c8459781fa77087f856c3e740d7763be0df27f \ + --hash=sha256:e9638791082eaf5b3ac112c587518ee78e083a11c4b28012d8fe2a0f536dfb17 \ + --hash=sha256:eb59c65069498dbae3c0ef07bbe224e1eaa079825a437fb47a479f0af11f774f \ + --hash=sha256:ee7337f88f2a580679f7bbfe69dc86c043954f9f9c541012f49abc554a962f2e \ + --hash=sha256:ee9627de8587c1a22201cb16d0296ab92b4df5cdcb5349f4e9744d61db7c7c98 \ + --hash=sha256:f4f83781191007b6ef43b03debc35435f10cad9b96e16d147efe84a1d48bdde4 \ + --hash=sha256:f56ebf9d70305307a707911b88469213630aba821e77de7d603f9d2f0730687d \ + --hash=sha256:f5bfc2741d150d0be3e4a0401a5c22b06e60acb9aa4daa46d9e79a6dcd0f135b \ + --hash=sha256:f94a11a9d05afcfcfa640e096319720a19cc0c9f7768e1a61fceee6a3afc6c7c \ + --hash=sha256:fa7922bbb2cc84fa062d37723f199d4c0cd200245ce269c05db82d904db66b83 \ + --hash=sha256:fe896e07a5a2462308297e515c0054e9ec2dd18dfdc9427b19900b37dfe6f40b \ + --hash=sha256:ffa81f81b80047ba89a3c69ae6a0f78d06f4a42ce5126b0eb2a0a10ad44e0b2e # via # feast (pyproject.toml) # parsimonious @@ -4772,9 +4864,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 @@ -4915,25 +5007,25 @@ ruamel-yaml==0.17.17 \ --hash=sha256:9751de4cbb57d4bfbf8fc394e125ed4a2f170fbff3dc3d78abf50be85924f8be \ --hash=sha256:9af3ec5d7f8065582f3aa841305465025d0afd26c5fb54e15b964e11838fc74f # via great-expectations -ruff==0.15.9 \ - --hash=sha256:058d8e99e1bfe79d8a0def0b481c56059ee6716214f7e425d8e737e412d69677 \ - --hash=sha256:0694e601c028fd97dc5c6ee244675bc241aeefced7ef80cd9c6935a871078f53 \ - --hash=sha256:29cbb1255a9797903f6dde5ba0188c707907ff44a9006eb273b5a17bfa0739a2 \ - --hash=sha256:2b0c7c341f68adb01c488c3b7d4b49aa8ea97409eae6462d860a79cf55f431b6 \ - --hash=sha256:45a70921b80e1c10cf0b734ef09421f71b5aa11d27404edc89d7e8a69505e43d \ - --hash=sha256:4965bac6ac9ea86772f4e23587746f0b7a395eccabb823eb8bfacc3fa06069f7 \ - --hash=sha256:55cc15eee27dc0eebdfcb0d185a6153420efbedc15eb1d38fe5e685657b0f840 \ - --hash=sha256:6d3fcbca7388b066139c523bda744c822258ebdcfbba7d24410c3f454cc9af71 \ - --hash=sha256:6efbe303983441c51975c243e26dff328aca11f94b70992f35b093c2e71801e1 \ - --hash=sha256:7b34a9766aeec27a222373d0b055722900fbc0582b24f39661aa96f3fe6ad901 \ - --hash=sha256:89dd695bc72ae76ff484ae54b7e8b0f6b50f49046e198355e44ea656e521fef9 \ - --hash=sha256:8e1ddb11dbd61d5983fa2d7d6370ef3eb210951e443cace19594c01c72abab4c \ - --hash=sha256:9439a342adb8725f32f92732e2bafb6d5246bd7a5021101166b223d312e8fc59 \ - --hash=sha256:9c5e6faf9d97c8edc43877c3f406f47446fc48c40e1442d58cfcdaba2acea745 \ - --hash=sha256:a6537f6eed5cda688c81073d46ffdfb962a5f29ecb6f7e770b2dc920598997ed \ - --hash=sha256:bde6ff36eaf72b700f32b7196088970bf8fdb2b917b7accd8c371bfc0fd573ec \ - --hash=sha256:ce187224ef1de1bd225bc9a152ac7102a6171107f026e81f317e4257052916d5 \ - --hash=sha256:eaf05aad70ca5b5a0a4b0e080df3a6b699803916d88f006efd1f5b46302daab8 +ruff==0.15.12 \ + --hash=sha256:01da3988d225628b709493d7dc67c3b9b12c0210016b08690ef9bd27970b262b \ + --hash=sha256:2849ea9f3484c3aca43a82f484210370319e7170df4dfe4843395ddf6c57bc33 \ + --hash=sha256:83b2f4f2f3b1026b5fb449b467d9264bf22067b600f7b6f41fc5958909f449d0 \ + --hash=sha256:84a1630093121375a3e2a95b4a6dc7b59e2b4ee76216e32d81aae550a832d002 \ + --hash=sha256:9ba3b8f1afd7e2e43d8943e55f249e13f9682fde09711644a6e7290eb4f3e339 \ + --hash=sha256:9cae0f92bd5700d1213188b31cd3bdd2b315361296d10b96b8e2337d3d11f53e \ + --hash=sha256:9e77c7e51c07fe396826d5969a5b846d9cd4c402535835fb6e21ce8b28fef847 \ + --hash=sha256:a538f7a82d061cee7be55542aca1d86d1393d55d81d4fcc314370f4340930d4f \ + --hash=sha256:b0c862b172d695db7598426b8af465e7e9ac00a3ea2a3630ee67eb82e366aaa6 \ + --hash=sha256:c87a162d61ab3adca47c03f7f717c68672edec7d1b5499e652331780fe74950d \ + --hash=sha256:d0185894e038d7043ba8fd6aee7499ece6462dc0ea9f1e260c7451807c714c20 \ + --hash=sha256:dd8aed930da53780d22fc70bdf84452c843cf64f8cb4eb38984319c24c5cd5fd \ + --hash=sha256:e3bcd123364c3770b8e1b7baaf343cc99a35f197c5c6e8af79015c666c423a6c \ + --hash=sha256:e852ba9fdc890655e1d78f2df1499efbe0e54126bd405362154a75e2bde159c5 \ + --hash=sha256:ecea26adb26b4232c0c2ca19ccbc0083a68344180bba2a600605538ce51a40a6 \ + --hash=sha256:f86f176e188e94d6bdbc09f09bfd9dc729059ad93d0e7390b5a73efe19f8861c \ + --hash=sha256:fb129f40f114f089ebe0ca56c0d251cf2061b17651d464bb6478dc01e69f11f5 \ + --hash=sha256:fe87510d000220aa1ed530d4448a7c696a0cae1213e5ec30e5874287b66557b5 # via feast (pyproject.toml) s3transfer==0.13.1 \ --hash=sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724 \ @@ -5089,9 +5181,9 @@ send2trash==2.1.0 \ --hash=sha256:0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c \ --hash=sha256:1c72b39f09457db3c05ce1d19158c2cbef4c32b8bedd02c155e49282b7ea7459 # via jupyter-server -sentence-transformers==5.3.0 \ - --hash=sha256:414a0a881f53a4df0e6cbace75f823bfcb6b94d674c42a384b498959b7c065e2 \ - --hash=sha256:dca6b98db790274a68185d27a65801b58b4caf653a4e556b5f62827509347c7d +sentence-transformers==5.4.1 \ + --hash=sha256:436bcb1182a0ff42a8fb2b1c43498a70d0a75b688d182f2cd0d1dd115af61ddc \ + --hash=sha256:a6d640fc363849b63affb8e140e9d328feabab86f83d58ac3e16b1c28140b790 # via feast (pyproject.toml) setuptools==80.10.2 \ --hash=sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70 \ @@ -5263,103 +5355,103 @@ 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.49 \ + --hash=sha256:01146546d84185f12721a1d2ce0c6673451a7894d1460b592d378ca4871a0c72 \ + --hash=sha256:059d7151fff513c53a4638da8778be7fce81a0c4854c7348ebd0c4078ddf28fe \ + --hash=sha256:0c98c59075b890df8abfcc6ad632879540f5791c68baebacb4f833713b510e75 \ + --hash=sha256:0f2fa354ba106eafff2c14b0cc51f22801d1e8b2e4149342023bd6f0955de5f5 \ + --hash=sha256:12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148 \ + --hash=sha256:22d8798819f86720bc646ab015baff5ea4c971d68121cb36e2ebc2ee43ead2b7 \ + --hash=sha256:233088b4b99ebcbc5258c755a097aa52fbf90727a03a5a80781c4b9c54347a2e \ + --hash=sha256:24bd94bb301ec672d8f0623eba9226cc90d775d25a0c92b5f8e4965d7f3a1518 \ + --hash=sha256:275424295f4256fd301744b8f335cff367825d270f155d522b30c7bf49903ee7 \ + --hash=sha256:32fe6a41ad97302db2931f05bb91abbcc65b5ce4c675cd44b972428dd2947700 \ + --hash=sha256:334edbcff10514ad1d66e3a70b339c0a29886394892490119dbb669627b17717 \ + --hash=sha256:3bb9ec6436a820a4c006aad1ac351f12de2f2dbdaad171692ee457a02429b672 \ + --hash=sha256:3ddcb27fb39171de36e207600116ac9dfd4ae46f86c82a9bf3934043e80ebb88 \ + --hash=sha256:42e8804962f9e6f4be2cbaedc0c3718f08f60a16910fa3d86da5a1e3b1bfe60f \ + --hash=sha256:43d044780732d9e0381ac8d5316f95d7f02ef04d6e4ef6dc82379f09795d993f \ + --hash=sha256:46796877b47034b559a593d7e4b549aba151dae73f9e78212a3478161c12ab08 \ + --hash=sha256:46d51518d53edfbe0563662c96954dc8fcace9832332b914375f45a99b77cc9a \ + --hash=sha256:47604cb2159f8bbd5a1ab48a714557156320f20871ee64d550d8bf2683d980d3 \ + --hash=sha256:4bbccb45260e4ff1b7db0be80a9025bb1e6698bdb808b83fff0000f7a90b2c0b \ + --hash=sha256:4d4e5a0ceba319942fa6b585cf82539288a61e314ef006c1209f734551ab9536 \ + --hash=sha256:55250fe61d6ebfd6934a272ee16ef1244e0f16b7af6cd18ab5b1fc9f08631db0 \ + --hash=sha256:566df36fd0e901625523a5a1835032f1ebdd7f7886c54584143fa6c668b4df3b \ + --hash=sha256:57ca426a48eb2c682dae8204cd89ea8ab7031e2675120a47924fabc7caacbc2a \ + --hash=sha256:5e61abbec255be7b122aa461021daa7c3f310f3e743411a67079f9b3cc91ece3 \ + --hash=sha256:618a308215b6cececb6240b9abde545e3acdabac7ae3e1d4e666896bf5ba44b4 \ + --hash=sha256:62557958002b69699bdb7f5137c6714ca1133f045f97b3903964f47db97ea339 \ + --hash=sha256:6270d717b11c5476b0cbb21eedc8d4dbb7d1a956fd6c15a23e96f197a6193158 \ + --hash=sha256:685e93e9c8f399b0c96a624799820176312f5ceef958c0f88215af4013d29066 \ + --hash=sha256:69469ce8ce7a8df4d37620e3163b71238719e1e2e5048d114a1b6ce0fbf8c662 \ + --hash=sha256:6eb188b84269f357669b62cb576b5b918de10fb7c728a005fa0ebb0b758adce1 \ + --hash=sha256:74ab4ee7794d7ed1b0c37e7333640e0f0a626fc7b398c07a7aef52f484fddde3 \ + --hash=sha256:77641d299179c37b89cf2343ca9972c88bb6eef0d5fc504a2f86afd15cd5adf5 \ + --hash=sha256:7c821c47ecfe05cc32140dcf8dc6fd5d21971c86dbd56eabfe5ba07a64910c01 \ + --hash=sha256:7d6be30b2a75362325176c036d7fb8d19e8846c77e87683ffaa8177b35135613 \ + --hash=sha256:7f605a456948c35260e7b2a39f8952a26f077fd25653c37740ed186b90aaa68a \ + --hash=sha256:83101a6930332b87653886c01d1ee7e294b1fe46a07dd9a2d2b4f91bcc88eec0 \ + --hash=sha256:88690f4e1f0fbf5339bedbb127e240fec1fd3070e9934c0b7bef83432f779d2f \ + --hash=sha256:8a97ac839c2c6672c4865e48f3cbad7152cee85f4233fb4ca6291d775b9b954a \ + --hash=sha256:8d6efc136f44a7e8bc8088507eaabbb8c2b55b3dbb63fe102c690da0ddebe55e \ + --hash=sha256:8e20e511dc15265fb433571391ba313e10dd8ea7e509d51686a51313b4ac01a2 \ + --hash=sha256:951d4a210744813be63019f3df343bf233b7432aadf0db54c75802247330d3af \ + --hash=sha256:9ac7a3e245fd0310fd31495eb61af772e637bdf7d88ee81e7f10a3f271bff014 \ + --hash=sha256:9b1c058c171b739e7c330760044803099c7fff11511e3ab3573e5327116a9c33 \ + --hash=sha256:9c04bff9a5335eb95c6ecf1c117576a0aa560def274876fd156cfe5510fccc61 \ + --hash=sha256:9c4969a86e41454f2858256c39bdfb966a20961e9b58bf8749b65abf447e9a8d \ + --hash=sha256:9e0400fa22f79acc334d9a6b185dc00a44a8e6578aa7e12d0ddcd8434152b187 \ + --hash=sha256:a05977bffe9bffd2229f477fa75eabe3192b1b05f408961d1bebff8d1cd4d401 \ + --hash=sha256:a143af2ea6672f2af3f44ed8f9cd020e9cc34c56f0e8db12019d5d9ecf41cb3b \ + --hash=sha256:a51d3db74ba489266ef55c7a4534eb0b8db9a326553df481c11e5d7660c8364d \ + --hash=sha256:b95b2f470c1b2683febd2e7eab1d3f0e078c91dbdd0b00e9c645d07a413bb99f \ + --hash=sha256:b9870d15ef00e4d0559ae10ee5bc71b654d1f20076dbe8bc7ed19b4c0625ceba \ + --hash=sha256:c1dc3368794d522f43914e03312202523cc89692f5389c32bea0233924f8d977 \ + --hash=sha256:c338ec6ec01c0bc8e735c58b9f5d51e75bacb6ff23296658826d7cfdfdb8678a \ + --hash=sha256:c5070135e1b7409c4161133aa525419b0062088ed77c92b1da95366ec5cbebbe \ + --hash=sha256:cc992c6ed024c8c3c592c5fc9846a03dd68a425674900c70122c77ea16c5fb0b \ + --hash=sha256:d15950a57a210e36dd4cec1aac22787e2a4d57ba9318233e2ef8b2daf9ff2d5f \ + --hash=sha256:d898cc2c76c135ef65517f4ddd7a3512fb41f23087b0650efb3418b8389a3cd1 \ + --hash=sha256:d99945830a6f3e9638d89a28ed130b1eb24c91255e4f24366fbe699b983f29e4 \ + --hash=sha256:da9b91bca419dc9b9267ffadde24eae9b1a6bffcd09d0a207e5e3af99a03ce0d \ + --hash=sha256:df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120 \ + --hash=sha256:e06e617e3d4fd9e51d385dfe45b077a41e9d1b033a7702551e3278ac597dc750 \ + --hash=sha256:ec44cfa7ef1a728e88ad41674de50f6db8cfdb3e2af84af86e0041aaf02d43d0 \ + --hash=sha256:fb37f15714ec2652d574f021d479e78cd4eb9d04396dca36568fdfffb3487982 # via feast (pyproject.toml) -sqlglot[rs]==30.2.1 \ - --hash=sha256:ef4a67cc6f66a8043085eb8ea95fa9541c1625dffa9145ad4e9815a7ba60a199 \ - --hash=sha256:f23d9ee9427ef9d20df15f9b0ffa57d9eb45e52b012219a349d1e6b50ed926d1 +sqlglot[rs]==30.6.0 \ + --hash=sha256:246d34d39927422a50a3fa155f37b2f6346fba85f1a755b13c941eb32ef93361 \ + --hash=sha256:e005fc2f47994f90d7d8df341f1cbe937518497b0b7b1507d4c03c4c9dfd2778 # via # feast (pyproject.toml) # ibis-framework -sqlglotc==30.2.1 \ - --hash=sha256:052cd7bb41fc9b841eb268d4dd601eb6b5954b7c6d5656795d4350a0f8020d53 \ - --hash=sha256:058f0e9aed2b8dff87dc893b8793e514204c8dfef699b7d3d1704dfbdd949f2b \ - --hash=sha256:0e6be524252894c0fa98d25d4e60dfae6485ba66ca1abd40bf05f16a9cf26baf \ - --hash=sha256:13f8f68808777ba7d845bc908bf09f72a0c9899a19811483dc52f0fa48b38d5a \ - --hash=sha256:1a004086ab871be0cc97766f7b6fb8866729f09dd7272254fd31c05107f3fdc8 \ - --hash=sha256:25c6f62f31cd3a051285635c3f6a01d2f3c73ca2baaa26970815166928042ace \ - --hash=sha256:2b5fe8adc1a1e2fb819e014e94974a274f30dbf9684ceed9f171fb0889f80f0b \ - --hash=sha256:2ffe527bc8664b03cc936bae7ebf965f482beb4acee7a815c2ec2d9aea720b4e \ - --hash=sha256:4aa90e08f53409b1857572836e57a31835ed20e32521c6fafdc6af96199baff7 \ - --hash=sha256:507935a971e0a9e5d4ac7ca14df479f8e270502b44904f71d95c0aaed066006f \ - --hash=sha256:515e092ab8fb522b256fa8a34f471e9b187bb8a50a7c0226a65b036a07d6d188 \ - --hash=sha256:585bb610fde3e3dd1d7e5ff3cce14f70fbd53ced6769cd104679adf8b5c4ab5b \ - --hash=sha256:850e7517dd4739cad9af65bcb9699825f9202e5971407bf955e3248fe4814f96 \ - --hash=sha256:8f063af733cbcc51686380470e7f3f80b589b8c58084baa138efb3b8ca821597 \ - --hash=sha256:b17e3002ed10747388367621b2ecf39c06d5fdc6b3c31a8c32be2f5ef546fc0b \ - --hash=sha256:d577e1635e127febb7012bc42fa1c3b958076e59a1a116ade20048c572a1be42 \ - --hash=sha256:dc292cd73e0c447253877c27f00454a2d09b71324a130ad4c58c145ab753889e \ - --hash=sha256:de168df756a21a028cf1f917f92da2f77bb135f3b6cdd960914460942a5eca10 \ - --hash=sha256:de884dd224220002c3e940ca5bdceb27ef9638e5f02493db133ffb8ae88b5610 \ - --hash=sha256:f33c7d1646ff6531cb9b07f0740b2939f3ecaa31efebfbec8adb6b275f1a45f2 \ - --hash=sha256:f9a1fc7b1ff3b51d0d03a391768a79964f68541b4c2f294a25a6f14e6670ffab \ - --hash=sha256:fae4edad0b7c5f9f963bd63452f722f0d7f77a436c2d334b555b31722f9573ad \ - --hash=sha256:fdc19623a1c7659918c3cee18ea8849fc4af9eaeb87247acf37e0393295d32b7 \ - --hash=sha256:feefc0ab7606d1fe284d23bef09ea4829ce4fad679936959c29324310f23e081 \ - --hash=sha256:ff19b7ecb931aef6c7c6168af5530c07e67915102b701d45ae80446f0695ba54 +sqlglotc==30.6.0 \ + --hash=sha256:003b15bbe3f3a4a63313baeb3f090906cf0172fe007ab24974c612a577f56c61 \ + --hash=sha256:05861b5d74ae4b0a5a6e6a9309a8a975d9572c2bf1eb9634a33af9189eb7d333 \ + --hash=sha256:0b907206ef36fd8f0c28da4c5b8c8f896bd67826da0d765616e6c950689ac849 \ + --hash=sha256:0e1aae195008c1d87ed1b1543bceed1408ae8ecf146571b3029e98b23a19c59c \ + --hash=sha256:16291ee3da0276df2689cc139df41d8723cf6014aca979f307fb75a898b0d3e8 \ + --hash=sha256:27d6c22375395f1fdfe8a5d80b5fb781ca7849e29c7db7dfb11edb466a5b7a4d \ + --hash=sha256:2b50aba396d4622c201a9dd933b51cd6858b5af5ebbcf7db1af35db7e83ece48 \ + --hash=sha256:4a5beba24625bc14070992fdddc7aed22df912007882f31f27b0e88d7b7d9445 \ + --hash=sha256:4c84a933816374b6167d9347e488fb4a357bb0e3be2e8e820dafeb3c9948feab \ + --hash=sha256:4d45ee83e1f72ee94045ccfd13e51fa7d822548f50e9d20d3d42e127bcd9f453 \ + --hash=sha256:4eb6f349c21d5a3e39733db5416e57ec171ca3b1c17b02badfdbe55d9a3666a5 \ + --hash=sha256:61a1e4f533955db0bfd4219883bfab1f2030753ffaebc9cbb4e950dfbcae3db7 \ + --hash=sha256:63b02231cc2f10d63df373fa02f3e03b4216e94c6f32ccdfd11adc770dc95fb7 \ + --hash=sha256:6e8dab3b9f84c9b591ecd1fb0920b800c08dd6c38eda3be91176fc239d3c94bc \ + --hash=sha256:7acdb7b15f060bacea01e1c68d1dd70471f03bda89478ca0ee96bac3df03d0a7 \ + --hash=sha256:87437d4f32c1dc61c3ef046dc39b9fe119ac2e2e5253e33351f1a62ba802942a \ + --hash=sha256:875c6925f3d70aa1bc4bcc405090a12deec01de71193e7229f114c5ecf39f725 \ + --hash=sha256:949f5d457c8c98998ed06d060873370d7553077ab3c2db9569acda5887cd6ce7 \ + --hash=sha256:c69c9dbe4dfab74329294d07b2956ca9a03123089a1923f3d299a21d4b66898d \ + --hash=sha256:cb4b5a532fb35ce415aea6d360fe202278b46cc59c07318b97401930a1584e35 \ + --hash=sha256:cfba6244f52bcdffe22a35334d48d741aed3077c20bb7aa9bb511c21fd766438 \ + --hash=sha256:dd781790c3fc6cb82e6c00836f7f9ab33941cf2b9dca173d7b9f41c37c78d114 \ + --hash=sha256:e397befde3d08d870a8f1c7bd80d7abc68ee119c472143ab196709319e205af4 \ + --hash=sha256:f0a37ad865b106005cb5d36efd537a412912477c83cbca1579ee45f17d73fe54 \ + --hash=sha256:fb977d427a196a620aa60b71d4b66d60c3d015c9004e7393162d4771fb435406 # via sqlglot sqlglotrs==0.13.0 \ --hash=sha256:6b934a244b16f26fca50974328a2ebc7689583c59f06203cebb46e2e6e8d93a7 \ @@ -5376,9 +5468,9 @@ sqlparams==6.2.0 \ --hash=sha256:3744a2ad16f71293db6505b21fd5229b4757489a9b09f3553656a1ae97ba7ca5 \ --hash=sha256:63b32ed9051bdc52e7e8b38bc4f78aed51796cdd9135e730f4c6a7db1048dedf # via singlestoredb -sse-starlette==3.3.4 \ - --hash=sha256:84bb06e58939a8b38d8341f1bc9792f06c2b53f48c608dd207582b664fc8f3c1 \ - --hash=sha256:aaf92fc067af8a5427192895ac028e947b484ac01edbc3caf00e7e7137c7bef1 +sse-starlette==3.4.1 \ + --hash=sha256:6b43cf21f1d574d582a6e1b0cfbde1c94dc86a32a701a7168c99c4475c6bd1d0 \ + --hash=sha256:f780bebcf6c8997fe514e3bd8e8c648d8284976b391c8bed0bcb1f611632b555 # via mcp stack-data==0.6.3 \ --hash=sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9 \ @@ -5412,9 +5504,9 @@ terminado==0.18.1 \ # via # jupyter-server # jupyter-server-terminals -testcontainers==4.9.0 \ - --hash=sha256:2cd6af070109ff68c1ab5389dc89c86c2dc3ab30a21ca734b2cb8f0f80ad479e \ - --hash=sha256:c6fee929990972c40bf6b91b7072c94064ff3649b405a14fde0274c8b2479d32 +testcontainers==4.15.0rc2 \ + --hash=sha256:4764016e73da0fa960eb8360687d22710cd68bcc01a4d03189fbe1da896a805d \ + --hash=sha256:e55b9045842c5bdfdd295e0d0b09aeafb3c1fb9d6f30bd8e718df8fd48dcdc41 # via feast (pyproject.toml) threadpoolctl==3.6.0 \ --hash=sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb \ @@ -5766,15 +5858,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 \ @@ -5823,9 +5916,9 @@ typer==0.12.5 \ # docling # docling-core # fastapi-mcp -types-cffi==2.0.0.20260402 \ - --hash=sha256:47e1320c009f630c59c55c8e3d2b8c501e280babf52e92f6109cbfb0864ba367 \ - --hash=sha256:f647a400fba0a31d603479169d82ee5359db79bd1136e41dc7e6489296e3a2b2 +types-cffi==2.0.0.20260429 \ + --hash=sha256:6a4237bfdbd50e4d0726929070d8b9983bde541726a5a6fe0e8e24e78c1b3826 \ + --hash=sha256:afe7d9777a2921139623af0b94647637a5bd0b938b77ec125e5e5e068a1727bd # via types-pyopenssl types-protobuf==3.19.22 \ --hash=sha256:d291388678af91bb045fafa864f142dc4ac22f5d4cdca097c7d8d8a32fa9b3ab \ @@ -5833,25 +5926,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.20260408 \ + --hash=sha256:b784dc37908479e3767e2d794ab507b3674adb1c686ca3d13fc9e2960dbcb9ec \ + --hash=sha256:da630647eaaa7a926a3907794f4067f269cd245b2c202c74aa3c6a3bd660a9db # 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.20260402 \ - --hash=sha256:7827e6a9c93587cc18e766944254d1351a2396262e4abe1510cbbd7601c5e01f \ - --hash=sha256:a980142b9966713acb382c467e35c5cc4208a2f91b10b8d785a0ae6765df6c0b +types-python-dateutil==2.9.0.20260408 \ + --hash=sha256:473139d514a71c9d1fbd8bb328974bedcb1cc3dba57aad04ffa4157f483c216f \ + --hash=sha256:8b056ec01568674235f64ecbcef928972a5fac412f5aab09c516dfa2acfbb582 # via feast (pyproject.toml) -types-pytz==2026.1.1.20260402 \ - --hash=sha256:0d9a60ed1c6ad4fce7c6395b5bd2d9827db41d4b83de7c0322cf85869c2bfda3 \ - --hash=sha256:79209aa51dc003a4a6a764234d92b14e5c09a1b7f24e0f00c493929fd33618e8 +types-pytz==2026.1.1.20260408 \ + --hash=sha256:89b6a34b9198ea2a4b98a9d15cbca987053f52a105fd44f7ce3789cae4349408 \ + --hash=sha256:c7e4dec76221fb7d0c97b91ad8561d689bebe39b6bcb7b728387e7ffd8cde788 # via feast (pyproject.toml) -types-pyyaml==6.0.12.20250915 \ - --hash=sha256:0f8b54a528c303f0e6f7165687dd33fafa81c807fcac23f632b63aa624ced1d3 \ - --hash=sha256:e7d4d9e064e89a3b3cae120b4990cd370874d2bf12fa5f46c97018dd5d3c9ab6 +types-pyyaml==6.0.12.20260408 \ + --hash=sha256:92a73f2b8d7f39ef392a38131f76b970f8c66e4c42b3125ae872b7c93b556307 \ + --hash=sha256:fbc42037d12159d9c801ebfcc79ebd28335a7c13b08a4cfbc6916df78fee9384 # via feast (pyproject.toml) types-redis==4.6.0.20241004 \ --hash=sha256:5f17d2b3f9091ab75384153bfa276619ffa1cf6a38da60e10d5e6749cc5b902e \ @@ -5861,15 +5954,15 @@ types-requests==2.30.0.0 \ --hash=sha256:c6cf08e120ca9f0dc4fa4e32c3f953c3fba222bcc1db6b97695bce8da1ba9864 \ --hash=sha256:dec781054324a70ba64430ae9e62e7e9c8e4618c185a5cb3f87a6738251b5a31 # via feast (pyproject.toml) -types-setuptools==82.0.0.20260402 \ - --hash=sha256:4b9a9f6c3c4c65107a3956ad6a6acbccec38e398ff6d5f78d5df7f103dadb8d6 \ - --hash=sha256:63d2b10ba7958396ad79bbc24d2f6311484e452daad4637ffd40407983a27069 +types-setuptools==82.0.0.20260408 \ + --hash=sha256:036c68caf7e672a699f5ebbf914708d40644c14e05298bc49f7272be91cf43d3 \ + --hash=sha256:ece0a215cdfa6463a65fd6f68bd940f39e455729300ddfe61cab1147ed1d2462 # via # feast (pyproject.toml) # types-cffi -types-tabulate==0.10.0.20260308 \ - --hash=sha256:724dcb1330ffba5f46d3cf6e29f45089fccb8e85801e6e7ac9efb1195bf7bea1 \ - --hash=sha256:94a9795965bc6290f844d61e8680a1270040664b88fd12014624090fd847e13c +types-tabulate==0.10.0.20260408 \ + --hash=sha256:2b19d193603d38c34645de53c0c1087e2364487d518d4a2f44268db2366723cc \ + --hash=sha256:903d62fdf7e5a0ff659fd5d629df716232f7658c6d30e98f0374488d06ffacf4 # via feast (pyproject.toml) types-urllib3==1.26.25.14 \ --hash=sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f \ @@ -5930,9 +6023,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 @@ -6310,9 +6403,9 @@ werkzeug==3.1.8 \ --hash=sha256:63a77fb8892bf28ebc3178683445222aa500e48ebad5ec77b0ad80f8726b1f50 \ --hash=sha256:9bad61a4268dac112f1c5cd4630a56ede601b6ed420300677a869083d70a4c44 # via moto -wheel==0.46.3 \ - --hash=sha256:4b399d56c9d9338230118d705d9737a2a468ccca63d5e813e2a4fc7815d8bc4d \ - --hash=sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803 +wheel==0.47.0 \ + --hash=sha256:212281cab4dff978f6cedd499cd893e1f620791ca6ff7107cf270781e587eced \ + --hash=sha256:cc72bd1009ba0cf63922e28f94d9d83b920aa2bb28f798a31d0691b02fa3c9b3 # via # pip-tools # singlestoredb @@ -6404,6 +6497,7 @@ wrapt==1.17.3 \ --hash=sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c # via # aiobotocore + # deprecated # testcontainers xlsxwriter==3.2.9 \ --hash=sha256:254b1c37a368c444eac6e2f867405cc9e461b0ed97a3233b2ac1e574efb4140c \ @@ -6413,147 +6507,194 @@ 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 \ @@ -6685,9 +6826,9 @@ yarl==1.23.0 \ --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d # via aiohttp -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==3.23.1 \ + --hash=sha256:0b3596c50a5c700c9cb40ba8d86d9f2cc4807e9bedb06bcdf7fac85633e444dc \ + --hash=sha256:32120e378d32cd9714ad503c1d024619063ec28aad2248dc6672ad13edfa5110 # 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 aafdc1baddc..bc2c15b8eac 100644 --- a/sdk/python/requirements/py3.10-minimal-requirements.txt +++ b/sdk/python/requirements/py3.10-minimal-requirements.txt @@ -196,9 +196,9 @@ botocore==1.38.46 \ # boto3 # s3transfer # snowflake-connector-python -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +certifi==2026.4.22 \ + --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ + --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 # via # httpcore # httpx @@ -426,9 +426,9 @@ charset-normalizer==3.4.7 \ # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.3.3 \ + --hash=sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2 \ + --hash=sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 # via # feast (pyproject.toml) # dask @@ -442,56 +442,56 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via feast (pyproject.toml) -cryptography==46.0.6 \ - --hash=sha256:02fad249cb0e090b574e30b276a3da6a149e04ee2f049725b1f69e7b8351ec70 \ - --hash=sha256:063b67749f338ca9c5a0b7fe438a52c25f9526b851e24e6c9310e7195aad3b4d \ - --hash=sha256:12cae594e9473bca1a7aceb90536060643128bb274fcea0fc459ab90f7d1ae7a \ - --hash=sha256:12f0fa16cc247b13c43d56d7b35287ff1569b5b1f4c5e87e92cc4fcc00cd10c0 \ - --hash=sha256:22259338084d6ae497a19bae5d4c66b7ca1387d3264d1c2c0e72d9e9b6a77b97 \ - --hash=sha256:26031f1e5ca62fcb9d1fcb34b2b60b390d1aacaa15dc8b895a9ed00968b97b30 \ - --hash=sha256:27550628a518c5c6c903d84f637fbecf287f6cb9ced3804838a1295dc1fd0759 \ - --hash=sha256:2b417edbe8877cda9022dde3a008e2deb50be9c407eef034aeeb3a8b11d9db3c \ - --hash=sha256:2ea0f37e9a9cf0df2952893ad145fd9627d326a59daec9b0802480fa3bcd2ead \ - --hash=sha256:2ef9e69886cbb137c2aef9772c2e7138dc581fad4fcbcf13cc181eb5a3ab6275 \ - --hash=sha256:341359d6c9e68834e204ceaf25936dffeafea3829ab80e9503860dcc4f4dac58 \ - --hash=sha256:380343e0653b1c9d7e1f55b52aaa2dbb2fdf2730088d48c43ca1c7c0abb7cc2f \ - --hash=sha256:3c21d92ed15e9cfc6eb64c1f5a0326db22ca9c2566ca46d845119b45b4400361 \ - --hash=sha256:3dfa6567f2e9e4c5dceb8ccb5a708158a2a871052fa75c8b78cb0977063f1507 \ - --hash=sha256:456b3215172aeefb9284550b162801d62f5f264a081049a3e94307fe20792cfa \ - --hash=sha256:4668298aef7cddeaf5c6ecc244c2302a2b8e40f384255505c22875eebb47888b \ - --hash=sha256:50575a76e2951fe7dbd1f56d181f8c5ceeeb075e9ff88e7ad997d2f42af06e7b \ - --hash=sha256:639301950939d844a9e1c4464d7e07f902fe9a7f6b215bb0d4f28584729935d8 \ - --hash=sha256:64235194bad039a10bb6d2d930ab3323baaec67e2ce36215fd0952fad0930ca8 \ - --hash=sha256:6617f67b1606dfd9fe4dbfa354a9508d4a6d37afe30306fe6c101b7ce3274b72 \ - --hash=sha256:67177e8a9f421aa2d3a170c3e56eca4e0128883cf52a071a7cbf53297f18b175 \ - --hash=sha256:6728c49e3b2c180ef26f8e9f0a883a2c585638db64cf265b49c9ba10652d430e \ - --hash=sha256:6739d56300662c468fddb0e5e291f9b4d084bead381667b9e654c7dd81705124 \ - --hash=sha256:69cf0056d6947edc6e6760e5f17afe4bea06b56a9ac8a06de9d2bd6b532d4f3a \ - --hash=sha256:760997a4b950ff00d418398ad73fbc91aa2894b5c1db7ccb45b4f68b42a63b3c \ - --hash=sha256:79e865c642cfc5c0b3eb12af83c35c5aeff4fa5c672dc28c43721c2c9fdd2f0f \ - --hash=sha256:7e6142674f2a9291463e5e150090b95a8519b2fb6e6aaec8917dd8d094ce750d \ - --hash=sha256:7f417f034f91dcec1cb6c5c35b07cdbb2ef262557f701b4ecd803ee8cefed4f4 \ - --hash=sha256:7f6690b6c55e9c5332c0b59b9c8a3fb232ebf059094c17f9019a51e9827df91c \ - --hash=sha256:8927ccfbe967c7df312ade694f987e7e9e22b2425976ddbf28271d7e58845290 \ - --hash=sha256:8ce35b77aaf02f3b59c90b2c8a05c73bac12cea5b4e8f3fbece1f5fddea5f0ca \ - --hash=sha256:8e7304c4f4e9490e11efe56af6713983460ee0780f16c63f219984dab3af9d2d \ - --hash=sha256:90e5f0a7b3be5f40c3a0a0eafb32c681d8d2c181fc2a1bdabe9b3f611d9f6b1a \ - --hash=sha256:97c8115b27e19e592a05c45d0dd89c57f81f841cc9880e353e0d3bf25b2139ed \ - --hash=sha256:9a693028b9cbe51b5a1136232ee8f2bc242e4e19d456ded3fa7c86e43c713b4a \ - --hash=sha256:9a9c42a2723999a710445bc0d974e345c32adfd8d2fac6d8a251fa829ad31cfb \ - --hash=sha256:a3e84d5ec9ba01f8fd03802b2147ba77f0c8f2617b2aff254cedd551844209c8 \ - --hash=sha256:aad75154a7ac9039936d50cf431719a2f8d4ed3d3c277ac03f3339ded1a5e707 \ - --hash=sha256:b12c6b1e1651e42ab5de8b1e00dc3b6354fdfd778e7fa60541ddacc27cd21410 \ - --hash=sha256:b928a3ca837c77a10e81a814a693f2295200adb3352395fad024559b7be7a736 \ - --hash=sha256:bcb87663e1f7b075e48c3be3ecb5f0b46c8fc50b50a97cf264e7f60242dca3f2 \ - --hash=sha256:c797e2517cb7880f8297e2c0f43bb910e91381339336f75d2c1c2cbf811b70b4 \ - --hash=sha256:c89eb37fae9216985d8734c1afd172ba4927f5a05cfd9bf0e4863c6d5465b013 \ - --hash=sha256:cdcd3edcbc5d55757e5f5f3d330dd00007ae463a7e7aa5bf132d1f22a4b62b19 \ - --hash=sha256:d24c13369e856b94892a89ddf70b332e0b70ad4a5c43cf3e9cb71d6d7ffa1f7b \ - --hash=sha256:d4e4aadb7fc1f88687f47ca20bb7227981b03afaae69287029da08096853b738 \ - --hash=sha256:d9528b535a6c4f8ff37847144b8986a9a143585f0540fbcb1a98115b543aa463 \ - --hash=sha256:ed3775295fb91f70b4027aeba878d79b3e55c0b3e97eaa4de71f8f23a9f2eb77 \ - --hash=sha256:ed418c37d095aeddf5336898a132fba01091f0ac5844e3e8018506f014b6d2c4 +cryptography==47.0.0 \ + --hash=sha256:0024b87d47ae2399165a6bfb20d24888881eeab83ae2566d62467c5ff0030ce7 \ + --hash=sha256:07efe86201817e7d3c18781ca9770bc0db04e1e48c994be384e4602bc38f8f27 \ + --hash=sha256:09f6d7bf6724f8db8b32f11eccf23efc8e759924bc5603800335cf8859a3ddbd \ + --hash=sha256:11438c7518132d95f354fa01a4aa2f806d172a061a7bed18cf18cbdacdb204d7 \ + --hash=sha256:11dbb9f50a0f1bb9757b3d8c27c1101780efb8f0bdecfb12439c22a74d64c001 \ + --hash=sha256:14432c8a9bcb37009784f9594a62fae211a2ae9543e96c92b2a8e4c3cd5cd0c4 \ + --hash=sha256:1581aef4219f7ca2849d0250edaa3866212fb74bf5667284f46aa92f9e65c1ca \ + --hash=sha256:160ad728f128972d362e714054f6ba0067cab7fb350c5202a9ae8ae4ce3ef1a0 \ + --hash=sha256:1a405c08857258c11016777e11c02bacbe7ef596faf259305d282272a3a05cbe \ + --hash=sha256:1e47422b5557bb82d3fff997e8d92cff4e28b9789576984f08c248d2b3535d93 \ + --hash=sha256:20fdbe3e38fb67c385d233c89371fa27f9909f6ebca1cecc20c13518dae65475 \ + --hash=sha256:2207a498b03275d0051589e326b79d4cf59985c99031b05bb292ac52631c37fe \ + --hash=sha256:256d07c78a04d6b276f5df935a9923275f53bd1522f214447fdf365494e2d515 \ + --hash=sha256:2b45761c6ec22b7c726d6a829558777e32d0f1c8be7c3f3480f9c912d5ee8a10 \ + --hash=sha256:2ebd84adf0728c039a3be2700289378e1c164afc6748df1a5ed456767bef9ba7 \ + --hash=sha256:34b4358b925a5ea3e14384ca781a2c0ef7ac219b57bb9eacc4457078e2b19f92 \ + --hash=sha256:3fb8fa48075fad7193f2e5496135c6a76ac4b2aa5a38433df0a539296b377829 \ + --hash=sha256:4e1de79e047e25d6e9f8cea71c86b4a53aced64134f0f003bbcbf3655fd172c8 \ + --hash=sha256:4f7722c97826770bab8ae92959a2e7b20a5e9e9bf4deae68fd86c3ca457bab52 \ + --hash=sha256:51c9313e90bd1690ec5a75ed047c27c0b8e6c570029712943d6116ef9a90620b \ + --hash=sha256:5d0e362ff51041b0c0d219cc7d6924d7b8996f57ce5712bdcef71eb3c65a59cc \ + --hash=sha256:6651d32eff255423503aa276739da98c30f26c40cbeffcc6048e0d54ef704c0c \ + --hash=sha256:6eebcaf0df1d21ce1f90605c9b432dd2c4f4ab665ac29a40d5e3fc68f51b5e63 \ + --hash=sha256:6f29f36582e6151d9686235e586dd35bb67491f024767d10b842e520dc6a07ac \ + --hash=sha256:7a02675e2fabd0c0fc04c868b8781863cbf1967691543c22f5470500ff840b31 \ + --hash=sha256:7f1207974a904e005f762869996cf620e9bf79ecb4622f148550bb48e0eb35a7 \ + --hash=sha256:7f68d6fbc7fbbcfb0939fea72c3b96a9f9a6edfc0e1b1d29778a2066030418b1 \ + --hash=sha256:7fda2f02c9015db3f42bb8a22324a454516ed10a8c29ca6ece6cdbb5efe2a203 \ + --hash=sha256:80887c5cbd1774683cb126f0ab4184567f080071d5acf62205acb354b4b753b7 \ + --hash=sha256:835d2d7f47cdc53b3224e90810fb1d36ca94ea29cc1801fb4c1bc43876735769 \ + --hash=sha256:8c1a736bbb3288005796c3f7ccb9453360d7fed483b13b9f468aea5171432923 \ + --hash=sha256:9af828c0d5a65c70ec729cd7495a4bf1a67ecb66417b8f02ff125ab8a6326a74 \ + --hash=sha256:9c59ab0e0fa3a180a5a9c59f3a5abe3ef90d474bc56d7fadfbe80359491b615b \ + --hash=sha256:9f8e55fe4e63613a5e1cc5819030f27b97742d720203a087802ce4ce9ceb52bb \ + --hash=sha256:9fe6b7c64926c765f9dff301f9c1b867febcda5768868ca084e18589113732ab \ + --hash=sha256:a49a3eb5341b9503fa3000a9a0db033161db90d47285291f53c2a9d2cd1b7f76 \ + --hash=sha256:a9b761f012a943b7de0e828843c5688d0de94a0578d44d6c85a1bae32f87791f \ + --hash=sha256:b1c76fca783aa7698eb21eb14f9c4aa09452248ee54a627d125025a43f83e7a7 \ + --hash=sha256:b9a8943e359b7615db1a3ba587994618e094ff3d6fa5a390c73d079ce18b3973 \ + --hash=sha256:be12cb6a204f77ed968bcefe68086eb061695b540a3dd05edac507a3111b25f0 \ + --hash=sha256:cffbba3392df0fa8629bb7f43454ee2925059ee158e23c54620b9063912b86c8 \ + --hash=sha256:ed67ea4e0cfb5faa5bc7ecb6e2b8838f3807a03758eec239d6c21c8769355310 \ + --hash=sha256:edd4da498015da5b9f26d38d3bfc2e90257bfa9cbed1f6767c282a0025ae649b \ + --hash=sha256:ef6b3634087f18d2155b1e8ce264e5345a753da2c5fa9815e7d41315c90f8318 \ + --hash=sha256:f1557695e5c2b86e204f6ce9470497848634100787935ab7adc5397c54abd7ab \ + --hash=sha256:f5c15764f261394b22aef6b00252f5195f46f2ca300bec57149474e2538b31f8 \ + --hash=sha256:f5c3296dab66202f1b18a91fa266be93d6aa0c2806ea3d67762c69f60adc71aa \ + --hash=sha256:f7db373287273d8af1414cf95dc4118b13ffdc62be521997b0f2b270771fef50 \ + --hash=sha256:f9a034b642b960767fb343766ae5ba6ad653f2e890ddd82955aef288ffea8736 # via # google-auth # pyjwt @@ -511,42 +511,42 @@ dill==0.3.9 \ --hash=sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a \ --hash=sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c # via feast (pyproject.toml) -duckdb==1.5.1 \ - --hash=sha256:054ad424b051b334052afac58cb216f3b1ebb8579fc8c641e60f0182e8725ea9 \ - --hash=sha256:05fc91767d0cfc4cf2fa68966ab5b479ac07561752e42dd0ae30327bd160f64a \ - --hash=sha256:0a6acc2040bec1f05de62a2f3f68f4c12f3ec7d6012b4317d0ab1a195af26225 \ - --hash=sha256:26e56b5f0c96189e3288d83cf7b476e23615987902f801e5788dee15ee9f24a9 \ - --hash=sha256:36e8e32621a9e2a9abe75dc15a4b54a3997f2d8b1e53ad754bae48a083c91130 \ - --hash=sha256:40c5220ec93790b18ec6278da9c6ac2608d997ee6d6f7cd44c5c3992764e8e71 \ - --hash=sha256:446d500a2977c6ae2077f340c510a25956da5c77597175c316edfa87248ceda3 \ - --hash=sha256:46f92ada9023e59f27edc048167b31ac9a03911978b1296c845a34462a27f096 \ - --hash=sha256:482f8a13f2600f527e427f73c42b5aa75536f9892868068f0aaf573055a0135f \ - --hash=sha256:553c273a6a8f140adaa6da6a6135c7f95bdc8c2e5f95252fcdf9832d758e2141 \ - --hash=sha256:5ae7c0d744d64e2753149634787cc4ab60f05ef1e542b060eeab719f3cdb7723 \ - --hash=sha256:5d4147422d91ccdc2d2abf6ed24196025e020259d1d267970ae20c13c2ce84b1 \ - --hash=sha256:6af347debc8b721aa72e48671166282da979d5e5ae52dbc660ab417282b48e23 \ - --hash=sha256:6ba302115f63f6482c000ccfd62efdb6c41d9d182a5bcd4a90e7ab8cd13856eb \ - --hash=sha256:6f7361d66cc801d9eb4df734b139cd7b0e3c257a16f3573ebd550ddb255549e6 \ - --hash=sha256:715f05ea198d20d7f8b407b9b84e0023d17f2b9096c194cea702b7840e74f1f7 \ - --hash=sha256:71dddcebbc5a70e946a06c30b59b5dd7999c9833d307168f90fb4e4b672ab63e \ - --hash=sha256:8150c569b2aa4573b51ba8475e814aa41fd53a3d510c1ffb96f1139f46faf611 \ - --hash=sha256:8843bd9594e1387f1e601439e19ad73abdf57356104fd1e53a708255bb95a13d \ - --hash=sha256:8c0088765747ae5d6c9f89987bb36f9fb83564f07090d721344ce8e1abedffea \ - --hash=sha256:972d0dbf283508f9bc446ee09c3838cb7c7f114b5bdceee41753288c97fe2f7c \ - --hash=sha256:a28531cee2a5a42d89f9ba4da53bfeb15681f12acc0263476c8705380dadce07 \ - --hash=sha256:a3be2072315982e232bfe49c9d3db0a59ba67b2240a537ef42656cc772a887c7 \ - --hash=sha256:ac2804043bd1bc10b5da18f8f4c706877197263a510c41be9b4c0062f5783dcc \ - --hash=sha256:afab8b4b1f4469c3879bb049dd039f8fce402712050324e9524a43d7324c5e87 \ - --hash=sha256:b370d1620a34a4538ef66524fcee9de8171fa263c701036a92bc0b4c1f2f9c6d \ - --hash=sha256:b8b0808dba0c63b7633bdaefb34e08fe0612622224f9feb0e7518904b1615101 \ - --hash=sha256:bc7ca6a1a40e7e4c933017e6c09ef18032add793df4e42624c6c0c87e0bebdad \ - --hash=sha256:caa65e1f5bf007430bf657c37cab7ab81a4ddf8d337e3062bcc5085d17ef038b \ - --hash=sha256:d68c5a01a283cb13b79eafe016fe5869aa11bff8c46e7141c70aa0aac808010f \ - --hash=sha256:da137802688190835b4c863cafa77fd7e29dff662ee6d905a9ffc14f00299c91 \ - --hash=sha256:e56a20ab6cdb90a95b0c99652e28de3504ce77129087319c03c9098266183ae5 \ - --hash=sha256:e878ccb7d20872065e1597935fdb5e65efa43220c8edd0d9c4a1a7ff1f3eb277 \ - --hash=sha256:eba81e0b3011c1f23df7ea47ef4ffaa8239817959ae291515b6efd068bde2161 \ - --hash=sha256:ed6d23a3f806898e69c77430ebd8da0c79c219f97b9acbc9a29a653e09740c59 +duckdb==1.5.2 \ + --hash=sha256:0b291786014df1133f8f18b9df4d004484613146e858d71a21791e0fcca16cf4 \ + --hash=sha256:2323c1195c10fb2bb982fc0218c730b43d1b92a355d61e68e3c5f3ac9d44c34f \ + --hash=sha256:2a1de4f4d454b8c97aec546c82003fc834d3422ce4bc6a19902f3462ef293bed \ + --hash=sha256:35579b8e3a064b5eaf15b0eafc558056a13f79a0a62e34cc4baf57119daecfec \ + --hash=sha256:376856066c65ccd55fcb3a380bbe33a71ce089fc4623d229ffc6e82251afdb6d \ + --hash=sha256:411ad438bd4140f189a10e7f515781335962c5d18bd07837dc6d202e3985253d \ + --hash=sha256:4420b3f47027a7849d0e1815532007f377fa95ee5810b47ea717d35525c12f79 \ + --hash=sha256:486c862bf7f163c0110b6d85b3e5c031d224a671cca468f12ebb1d3a348f6b39 \ + --hash=sha256:52a21823f3fbb52f0f0e5425e20b07391ad882464b955879499b5ff0b45a376b \ + --hash=sha256:5596bbfc31b1b259db69c8d847b42d036ce2c4804f9ccb28f9fc46a16de7bc53 \ + --hash=sha256:56d38b3c4e0ef2abb58898d0fd423933999ed535c45e75e9d9f72e1d5fed69b8 \ + --hash=sha256:638da0d5102b6cb6f7d47f83d0600708ac1d3cb46c5e9aaabc845f9ba4d69246 \ + --hash=sha256:63bf8687feefeed51adf45fa3b062ab8b1b1c350492b7518491b86bae68b1da1 \ + --hash=sha256:6b0fe75c148000f060aa1a27b293cacc0ea08cc1cad724fbf2143d56070a3785 \ + --hash=sha256:70631c847ca918ee710ec874241b00cf9d2e5be90762cbb2a0389f17823c08f7 \ + --hash=sha256:7f69164b048e498b9e9140a24343108a5ae5f17bfb3485185f55fdf9b1aa924d \ + --hash=sha256:81fc4fbf0b5e25840b39ba2a10b78c6953c0314d5d0434191e7898f34ab1bba3 \ + --hash=sha256:84b193aca20565dedb3172de15f843c659c3a6c773bf14843a9bd781c850e7db \ + --hash=sha256:8d599758b4e48bf12e18c9b960cf491d219f0c4972d19a45489c05cc5ab36f83 \ + --hash=sha256:8dbd7e31e5dc157bfe8803fa7d2652336265c6c19926c5a4a9b40f8222868d08 \ + --hash=sha256:98c0535cd6d901f61a5ea3c2e26a1fd28482953d794deb183daf568e3aa5dda6 \ + --hash=sha256:a9cd5e71702d446613750405cde03f66ed268f4c321da071b0472759dad19536 \ + --hash=sha256:bb42e6ed543902e14eae647850da24103a89f0bc2587dec5601b1c1f213bd2ed \ + --hash=sha256:be37680ddb380015cb37318e378c53511c45c4f0d8fac5599d22b7d092b9217a \ + --hash=sha256:c69907354ffee94ba8cf782daf0480dab7557f21ce27fffa6c0ea8f74ed4b8e2 \ + --hash=sha256:c99ef73a277c8921bc0a1f16dee38d924484251d9cfd20951748c20fcd5ed855 \ + --hash=sha256:c9f3e0b71b8a50fccfb42794899285d9d318ce2503782b9dd54868e5ecd0ad31 \ + --hash=sha256:ce0b8141a10d37ecef729c45bc41d334854013f4389f1488bd6035c5579aaac1 \ + --hash=sha256:ce17670bb392ea1b3650537db02bd720908776b5b95f6d2472d31a7de59d1dc1 \ + --hash=sha256:d72b8856b1839d35648f38301b058f6232f4d36b463fe4dc8f4d3fdff2df1a2e \ + --hash=sha256:d9b4f5430bf4f05d4c0dc4c55c75def3a5af4be0343be20fa2bfc577343fbfc9 \ + --hash=sha256:e6495b00cad16888384119842797c49316a96ae1cb132bb03856d980d95afee1 \ + --hash=sha256:ea58ff5b0880593a280cf5511734b17711b32ee1f58b47d726e8600848358160 \ + --hash=sha256:ef461bca07313412dc09961c4a4757a851f56b95ac01c58fac6007632b7b94f2 \ + --hash=sha256:fc85a5dbcbe6eccac1113c72370d1d3aacfdd49198d63950bdf7d8638a307f00 # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ @@ -556,9 +556,9 @@ exceptiongroup==1.3.1 \ --hash=sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219 \ --hash=sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598 # via anyio -fastapi==0.135.3 \ - --hash=sha256:9b0f590c813acd13d0ab43dd8494138eb58e484bfac405db1f3187cfc5810d98 \ - --hash=sha256:bd6d7caf1a2bdd8d676843cdcd2287729572a1ef524fc4d65c17ae002a1be654 +fastapi==0.136.1 \ + --hash=sha256:7af665ad7acfa0a3baf8983d393b6b471b9da10ede59c60045f49fbc89a0fa7f \ + --hash=sha256:a6e9d7eeada96c93a4d69cb03836b44fa34e2854accb7244a1ece36cd4781c3f # via # feast (pyproject.toml) # fastapi-mcp @@ -566,9 +566,9 @@ fastapi-mcp==0.4.0 \ --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d # via feast (pyproject.toml) -filelock==3.25.2 \ - --hash=sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694 \ - --hash=sha256:ca8afb0da15f229774c9ad1b455ed96e85a81373065fb10446672f64444ddf70 +filelock==3.29.0 \ + --hash=sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90 \ + --hash=sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258 # via snowflake-connector-python frozenlist==1.8.0 \ --hash=sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686 \ @@ -710,9 +710,9 @@ fsspec==2024.9.0 \ # via # feast (pyproject.toml) # dask -google-api-core[grpc]==2.30.2 \ - --hash=sha256:9a8113e1a88bdc09a7ff629707f2214d98d61c7f6ceb0ea38c42a095d02dc0f9 \ - --hash=sha256:a4c226766d6af2580577db1f1a51bf53cd262f722b49731ce7414c43068a9594 +google-api-core[grpc]==2.30.3 \ + --hash=sha256:a85761ba72c444dad5d611c2220633480b2b6be2521eca69cca2dbb3ffd6bfe8 \ + --hash=sha256:e601a37f148585319b26db36e219df68c5d07b6382cff2d580e83404e44d641b # via # feast (pyproject.toml) # google-cloud-bigquery @@ -722,9 +722,9 @@ google-api-core[grpc]==2.30.2 \ # google-cloud-datastore # google-cloud-storage # pandas-gbq -google-auth==2.49.1 \ - --hash=sha256:16d40da1c3c5a0533f57d268fe72e0ebb0ae1cc3b567024122651c045d879b64 \ - --hash=sha256:195ebe3dca18eddd1b3db5edc5189b76c13e96f29e73043b923ebcf3f1a860f7 +google-auth==2.50.0 \ + --hash=sha256:04382175e28b94f49694977f0a792688b59a668def1499e9d8de996dc9ce5b15 \ + --hash=sha256:f35eafb191195328e8ce10a7883970877e7aeb49c2bfaa54aa0e394316d353d0 # via # google-api-core # google-auth-oauthlib @@ -919,101 +919,112 @@ 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.3.1 \ + --hash=sha256:002fc0201b9af1cc8960e27cdc501ad1f8cdd6dbadb2091c6ddbd4e5ace6cb77 \ + --hash=sha256:011a9071c3df4885cac7f58a2623feac6c8e2ad30e6ba93c55195af05ce61ff5 \ + --hash=sha256:01cf82a514bc4fd145b99333c28523e61b7a9ad051a245804323ebf4e7b1c6a6 \ + --hash=sha256:027ce4fabfeff5af5b9869d5524770877f9061d118bc36b85703ae3faf5aad8e \ + --hash=sha256:03baa381964b8df356d19ec4e3a6ae656044249a87b0def257fe1e08dbaf6094 \ + --hash=sha256:042e57de8a2cae91e3e7c0af32960ea2c5107b2f27f68a740295861e68780a8a \ + --hash=sha256:09d41a3a965f7c261223d516ebda607aee4d8440dd7637f01af9a4c05872f0c4 \ + --hash=sha256:09f5e510f637f2c72d2a79fb3ad05f7b6211e057e367ca5c4f97bb3d8c9d71f4 \ + --hash=sha256:0b5ff2f643f4b452b0597b7fe6aa35d398cb31d8806801acfafb1558610ea2aa \ + --hash=sha256:0caf3fc8af0767794b335753781c3fa35f2a3e975c098edbc8f733d35d6a95e4 \ + --hash=sha256:0fac4af8515e6cca74fc701169ae4dc9a71a90e9319c9d21006ec9454b43aa2f \ + --hash=sha256:113e098e4a6b3cc5500e05e7cb1548ba9e83de5fe755941b11f6020a76e6c03a \ + --hash=sha256:137c14905ea6f2933967200bc7b2a0c8ec9387888b273fd0004f25b994fd0343 \ + --hash=sha256:156be6a0c736ee145cfe0fb155d0e96cec8d4872cf8b4f76ad6a2ee6ab391d0a \ + --hash=sha256:17ec8b524055a88b80d76c177dbbbe475a25c17c5bf4b67bdbdbd0629bcae838 \ + --hash=sha256:1ac7697365dbe45109273b34227fee6826b276ead9a4a007e0877e1d3f0fcf21 \ + --hash=sha256:1b46e96b50dad03495447860510daebd2c96fd44ed25ba8ccb03e9f89eaa9d34 \ + --hash=sha256:1ebc307a87b099d0877dbd2bdc0bae427258e7ec67f60a951e89027f8dc2568f \ + --hash=sha256:1f7bceb03a1b934872ffe3942eaeed7c7e09096e67b53f095b81f39c7a819113 \ + --hash=sha256:2611bfaaadc5e8d43fb7967f9bbf1110c8beaa83aee2f2d812c76f11cfb56c6a \ + --hash=sha256:264ee7e9cb6c30dc78da4ecf71d74cf14ca122817c665d838eda8b4384bce1b0 \ + --hash=sha256:26f899cde0279e4b7d370716ff80320601c2bd93cdf3e774a42bdd44f65b41f8 \ + --hash=sha256:29fe35e3c6fe03204e75c86514f452591957a1e06b05d86e10d795455b71c355 \ + --hash=sha256:2afc675b831f7552da41116fffffca4340f387dc03f56d6ec0c7895ab0b59a10 \ + --hash=sha256:2b6da6e07359107c653a809b3cff2d9ccaeedbafe33c6f16434aef6f53ce4a2b \ + --hash=sha256:2b96da7e365d6488d2a75266a662cbe3cc14b28c23dd9b0c9aa04b5bc5c20192 \ + --hash=sha256:2f1c1b2e8f00b71e6214234d313f655a3a27cd4384b054126ce04073c1d47045 \ + --hash=sha256:304481241e081bc26f0778b2c2b99f9c43917e4e724a016dcc9439b7ab12c726 \ + --hash=sha256:318f772dd321404075d406825266e574ee0f4751be1831424c2ebd5722609398 \ + --hash=sha256:3586c8a5f56d34b9dddaaa9e76905f31933cac267251006adf86ec0eef7d0400 \ + --hash=sha256:3724f0e58c6ff76fd683429945491de71324ab1bc0ad943a8d68cb0932d24075 \ + --hash=sha256:3fb6573efa15a29c12c0c0f7170b14e7c1347fe4bb39b6a15b779f46015cc929 \ + --hash=sha256:40ae8a7041fcb328a6bc7202d8c4e6e0d38d434b2e3880b1ee8ed754f17cd836 \ + --hash=sha256:4106201cd052d9eabe3cb7b5a24b0fe37307792bda4fcb3cf6ddd72f697828e8 \ + --hash=sha256:439f9a5cc8f9519ce208a24cdebfa0440fef26aa682a40ba2c92acb10a53f5e0 \ + --hash=sha256:4479e36d263251dba8ab8ea81adf07e7f1163603c7102c5de1e130b83b4fad3b \ + --hash=sha256:487658e1db83c1ee9fbbac6a43039ea76957767a5987ffb16b590613f9e68297 \ + --hash=sha256:48ff424f8aa36aacd9fdaa68efeb27d2e8771f293af4305bdb15d92194ca6631 \ + --hash=sha256:4f7e242eab698ad0be5a4b2ec616fa856569c57455cc67c625fd567726290e5f \ + --hash=sha256:526db52e5234a9463520e960a509d6c1bd5128d1ab1b569cbf459fe39189e8ab \ + --hash=sha256:52d5641027d6731bc7b5e7d126a5158a99784a9f8c6de3d97ca89aca4969e9f8 \ + --hash=sha256:53148a4e21057541b6d8e493b2ea1b500037ddf34433c391970036f3cbce00e3 \ + --hash=sha256:583de2f16528e66081cbdfe510d8488c2de73039dc00aada7d22bd49d73a4a94 \ + --hash=sha256:5e55d90b431b0c6b64ae5a624208d4aea318566d31872e595ee723c0f5b9a79f \ + --hash=sha256:5f316cf2d0558f5027aab19dde7d7e4901c26c21fa95367bc37784e8f547bbf2 \ + --hash=sha256:60543f3b068b16a86e99ed96b7fdae71cdc1d8abdfe9b3f82032a555e52ece7e \ + --hash=sha256:62cc62284541bb2a86c898c7d5e8388661cade91c184cb862095ed547e80588f \ + --hash=sha256:65c05b79cb8366c123357b354a16f9fc3f7187159422f143638d1c26b7240ed4 \ + --hash=sha256:65f6ac06a9f0c32c254660ec6a9329d81d589e8f5d0a9837a941d5424a6be1ef \ + --hash=sha256:6d1434d0bcc1b3ef048bae53f26456405c08aeed9827e65b24094f5f3a6793f1 \ + --hash=sha256:6e2e1024f0a021777740cb7c633a0efb2c4a4bc570f508223a8dcbcf79f99ef9 \ + --hash=sha256:6ffa7ba2e2da1f806f3181b9730b3e87ba9dbfec884806725d4584055ba3faa6 \ + --hash=sha256:743b85bd6902856cac457ddd8cd7dd48c89c47d641b6016ff5e4d015bfbd4799 \ + --hash=sha256:77c5d2bebbc9d06691abb512a31d0f54e1562af0b872891463a67a949b5278ef \ + --hash=sha256:79cd03e7ff550c17758a7520bf437c156d3d4c8bb74214deeafa69cda49c85a4 \ + --hash=sha256:80aba5f85d6227faee628ae28d1c3b69c661806a0636548ac56c68782606454f \ + --hash=sha256:81a1669b6631976b1dc9d3d58ed1ab3333e9f52feb91a2a1fb8241101ac3b665 \ + --hash=sha256:8597c35c9e82f65fd5897c4a2188c65d7daf10607b102960137b23d261cd957b \ + --hash=sha256:8650158217b469d8b6087f490929211b0493a9121154c4efaafd1dec9e19319e \ + --hash=sha256:8887bf0f31e4b550bd988c8863b527b6587d200653e9375cd91eea2b944b7424 \ + --hash=sha256:8a52b24cd710690c4a7e191c7e300136ad2ecb3c68ffe7e95b598e76de166e5e \ + --hash=sha256:8e3754ce60e1b11b0afad9a053481ff184d2ee24bea47099107156d1b84a84aa \ + --hash=sha256:907f7b5501a534030738f0f27459a612d2266fd0507b007bb8f3e6de08167920 \ + --hash=sha256:90d6b9f2652303aefd2c5a26a5e14cb74a3a63d10faa642c08d790e99442a088 \ + --hash=sha256:98fd5b39410e9d69e10e90d0330e35650becaa5dd2548f509b9598f1f3c6124d \ + --hash=sha256:9bfdeff778d3f7ff449ca5922ab773899e7d31e26a576028b06a5e9cf0ed8c34 \ + --hash=sha256:9ebae74ce2b977c2fcb22d6a10aa0acb730022406977b2bcb6ddd6788f5c414a \ + --hash=sha256:a110d19881ca78a88583d3b07231e7c6864864f5f1f3491b638863ea45fa8708 \ + --hash=sha256:a1d190790ee39b8b7adeeb10fc4090dc4859eb4e75ed27bd8108710eef18f358 \ + --hash=sha256:a2f049c3f3c83e886cd1f53958e2a1ebb369be626bef9e50d8b24d79864f1df6 \ + --hash=sha256:a3af4e9f277d6b8acd369dc44a723a055752fca9d045094383af39f90a3e3729 \ + --hash=sha256:a42c7becd4c9ec4ab5769c754eb61112777bdc6e1c1525e2077389e193b5f5aa \ + --hash=sha256:a58a58cef0d911b1717154179a9ff47852249c536ea5966bde4370b6b20638ff \ + --hash=sha256:ab1f646ff531d70bfd25f01e60708dfa3d105eb458b7dedd9fe9a443039fd809 \ + --hash=sha256:ad940dc2db545dc978cb41cb9a683e2ff328f3ef581230b9ca40ff6c3d01d542 \ + --hash=sha256:afe3c3863f16704fb5d7c2c6ff56aaf9e054f6d269f7b4c9074c5476178d1aba \ + --hash=sha256:b1e3b9f4bf9a4120510ba77a77b2fb674893cd6795653545152bb11a79eecfcb \ + --hash=sha256:b2390ad81c03d93ef1d5afd18ffcf5935de827f1a2b96b2c829437968bdabccb \ + --hash=sha256:b37df4b10cb15dedfc203f69312d8eedd617b941c21df58c13af59496c53ad0f \ + --hash=sha256:b3df9447f9209f9aa0434ca74050e9509670c1ad99398fe5807abb90e5f3a014 \ + --hash=sha256:b4fe7f38aa8956fcc1cea270e62601e0e11066aff78e384be70fd283d30293b6 \ + --hash=sha256:c1d68c6980d4690a4550bd3db6c03146f7be68ef5d08d38bb1fb68b3e9c32fe3 \ + --hash=sha256:c24c1460486b6b36083252c2db21a814becf8495ccd0e76b7286623e37239b63 \ + --hash=sha256:c25132902d3eff38781e0d54f27a0942ec849e3c07dbdce83c4d92b7e43c8dce \ + --hash=sha256:c74bd9926954e7e575f9cd9890f63defd90cd8f812dfbf8e1efb72acc9355456 \ + --hash=sha256:c8139e9011117822391c5bcfd674c5948fb1e4b8cb9adf6f13d9890859ee3a1a \ + --hash=sha256:ce334915f5d31048f76a42c607bf26687cf045eb1bc852b7340f09729c6a64fc \ + --hash=sha256:d14229beaa76e66c3a25f9477d973336441ca820df853679a98796256813316f \ + --hash=sha256:d42f3a13290f89191568fc113d95a3d2c8759cdd8c3672f021d8b7436f909e75 \ + --hash=sha256:d8e56e0d1fe607bfff422633f313aec9191c3859ab99d11ff097e3e6e068000c \ + --hash=sha256:da6f0302360e99d32bc2869772692797ebadd536e1b826d0103c72ba49d38698 \ + --hash=sha256:db46baf157feefd88724e6a7f145fe996a5990a8604ed9292b45d563360e513b \ + --hash=sha256:dcea8c3f53674ae68e44b12e853b844a1d315250ca6677b11ec0c06aff85e86c \ + --hash=sha256:de94b409f49eb6a588ebdd5872e826caec417cd77c17af0fb94f2128427f1a2a \ + --hash=sha256:e0356561b4a97c83b9ee3de657a41b8d1a1781226853adaf47b550bb988fda6f \ + --hash=sha256:e0db44cf81e4d7b94f3776b9f89111f74ed6bbdbfd42a22bc4a5ce0644d3e060 \ + --hash=sha256:e31e92b61d56244047ad600812e16f7587a6172f74810fd919ff993af12b9149 \ + --hash=sha256:e89dabf436ee79b358fd970dcbed6333a36d91db73f27069ca24a02fb138a404 \ + --hash=sha256:eddeb9a153795cf6e615f9f3cef66a1d573ff3b6ee16df2b10d1d1c2f2baeaa8 \ + --hash=sha256:ee11fd431f83d8a5b29d370b9d79a814d3218d30113bdcd44657e9bdf715fc92 \ + --hash=sha256:ee37fe8cf081b72dea72f96a0ee604f492ec02252eb77dc26ff6eec3f997b580 \ + --hash=sha256:f19ee7dc1ef8a6497570d91fa4057ba910ad98297a50b8c44ff37589f7c89d17 \ + --hash=sha256:f2f94355affd51088f57f8674b0e294704c3c7c3d7d3b1545310f5b135d4843b \ + --hash=sha256:f525734382a47f9828c9d6a1501522c78d5935466d8e2be1a41ba40ca5bb922b \ + --hash=sha256:f915a34fb742e23d0d61573349aa45d6f74037fde9d58a9f340435eff8d62736 # via feast (pyproject.toml) httpcore==1.0.9 \ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ @@ -1078,9 +1089,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.13 \ + --hash=sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242 \ + --hash=sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 # via # anyio # httpx @@ -1116,97 +1127,97 @@ kubernetes==35.0.0 \ --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee # 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.9.0 \ + --hash=sha256:07cf11f769831186eeac424376e6189f20ace4f7263e2134bdb9757340d84d4d \ + --hash=sha256:0a09c2f5869649101738653a9b7ab70cf045a1105ac66cbb8f4055e61df78f2d \ + --hash=sha256:0a1be03168b2691ba61927e299b352a6315189199ca18a57b733f86cb3cc8d38 \ + --hash=sha256:0b73e4266307e51c95e09c0750b7ec383c561d2e97d58e473f6f6a209952fbb8 \ + --hash=sha256:15cb151e52a044f06e54ac7f7b47adbfc89b5c8e2b63e1175a9d587c43e8942a \ + --hash=sha256:194fc1a32e1e21fe809d38b5faea66cc65eaa00217c8901fbdb99866938adbdb \ + --hash=sha256:1bf465d1e5b0a27713862441f6467b5ab76385f4ecf8f1f3a44f8aa3c695b4b6 \ + --hash=sha256:1c587494461ebd42229d0f1739f3aa34237dd9980623ecf1be8d3bcba79f4499 \ + --hash=sha256:224b9727eb8bc188bc3bcf29d969dba0cd61b01d9bac80c41575520cc4baabb2 \ + --hash=sha256:22a904cbdb678f7cb348c90d543d3c52f581663d687992fee47fd566dcbf5285 \ + --hash=sha256:2b8f5d00b49818f4e2b1667db994488b045835e0ac16fe2f924f3871bd2b8ac5 \ + --hash=sha256:2c3786f0f4490a5cd87f1ed6cefae833ad6b1060d52044ce0434a2e85893afd0 \ + --hash=sha256:2d03fa4fd277a7974c1978c92c374c57f44edeee163d147b477b143446ad1bf6 \ + --hash=sha256:2f8e12706dcb8ff6b3ed57514a19e45c49ad00bcd423e87b2b2e4b5f64578443 \ + --hash=sha256:3be322a15ee5e70b93b7a59cfd074614f22cc8c9ff18bd27f474e79137ea8d3b \ + --hash=sha256:3cc2917258e131ae5f958a4d872e07555b51cb7466a43433218061c74ef33745 \ + --hash=sha256:3f05d145df35dca5056a8bc3838e940efebd893a54b3e19b2dda39ceaa299bcb \ + --hash=sha256:3fe56e80badb66fdcde06bef81bbaa5bfcf6fbd7aefb86222d9e369c38c6b228 \ + --hash=sha256:42ff8a962554c350d4a83cf47d9b7b78b0e6ff7943e87df7cdfc97c07f3c016f \ + --hash=sha256:451daa98463b7695b0a30aa56bf637831ea559e7b8101ac2ef6382e8eb15e29c \ + --hash=sha256:465814ab157986acb9dfa5ccd7df944be5eefc0d08d31ec6e8d88bc71251d845 \ + --hash=sha256:4c4d0440a3a8e31d962340c3e1cc3fc9ee7febd34c8d8f770d06adb947779ea5 \ + --hash=sha256:4e3dda8345307fd7306db0ed0cb109a63a2c85ba780eb9dc2d09b2049a931f9c \ + --hash=sha256:5093043afb226ecfa1400120d1ebd4442b4f99977783e4f4f7248879009b227f \ + --hash=sha256:5112c2fb7c2eefefaeaf5c97fec81343ef44ee86a30dcfaa8223822fba6467b4 \ + --hash=sha256:527b5b820b47a09e09829051452bb0d1dd2122261254e2a6f674d12f1d793d54 \ + --hash=sha256:54d412e47c21b85865676ed0724e37a89e9593c2eee1e7367adf85bfad56ffb1 \ + --hash=sha256:56d65b583cf43b8cf4c8fbe1e1da20fa3076cc32a1149a141507af1062718236 \ + --hash=sha256:5ca8e133d799c948db2ab1afc081c333a825b5540475164726dcbf73537e5c2f \ + --hash=sha256:603138ee838ee1583f1b960b62d5d0007845c5c423feb68e44648b1359014e27 \ + --hash=sha256:63c12efcd160e1d14da11af0c46c0217473e1e0d2ae1acbccc83f561ea4c2a7b \ + --hash=sha256:657f8ba7b9eaaa82759a104137aed2a3ef7bc46ccfd43e0d89b04005b3e0a4cc \ + --hash=sha256:66b58fed90a545328e80d575467244de3741e088c1af928f0b489ebec3ef3858 \ + --hash=sha256:6788207daa0c19955d2b668f3294a368d19f67d9b5f274553fd073c1260cbb9f \ + --hash=sha256:703f4ae36d6240bfe24f542bac784c7e4194ec49c3ba5a994d02891649e2d85b \ + --hash=sha256:7202bdcac47d3a708271c4304a474a8605a4a9a4a709e954bf2d3241140aa938 \ + --hash=sha256:756775d25ec8345b837ab52effee3ad2f3b2dfd6bbee3e3f029c517bd5d8f05a \ + --hash=sha256:78042f6facfd98ecb25e9829c7e37cce23363d9d7c83bc5f72702c5059eb082b \ + --hash=sha256:789fff71757facc0738e8d89e3b84e4f0251c1c975e85e81b152cdaca927cc2d \ + --hash=sha256:7bc30ad339f4e1a01d4917d645e522a0bc0030644d8973f6346397c93ba1503f \ + --hash=sha256:7d429bdd4ac0ab17c8e4a8af0ed2a7440b16eba474909ab357131018fe8c7e71 \ + --hash=sha256:7d5c8a5929ac325729f6119802070b561f4db793dffc45e9ac750992a4ed4d22 \ + --hash=sha256:7e6274fd33fc5b2a14d41c9119629d3ff395849d8bcbc80cf637d9e8d2034da8 \ + --hash=sha256:80b25c7b570a86c03b5da69e665809deb39265476e8e21d96a9328f9762f9990 \ + --hash=sha256:81107843ed1836874b46b310f9b1816abcb89912af627868522461c3b7333c0f \ + --hash=sha256:8494cfc61e03542f2d381e71804990b3931175a29b9278fdb4a5459948778dc2 \ + --hash=sha256:850d6d03177e52700af605fd60db7f37dcb89782049a149674d1a9649c2138fd \ + --hash=sha256:8c6bc1384d9738781cfd41d09ad7f6e8af13cfea2c75ece6bd6d2566cdea2076 \ + --hash=sha256:90904fac73c478f4b83f4ed96c99c8208b75e6f9a8a1910548f69a00f1eaa671 \ + --hash=sha256:90e6d5420fc8a300518d4d2288154ff45005e920425c22cbbfe8330f3f754bd9 \ + --hash=sha256:928bd06eca2c2bbf4349e5b817f837509b0604342e65a502de1d50a7570afd15 \ + --hash=sha256:9b3e3bc363f71bda1639a4ee593cb78f7fbfeacc73411ec0d4c92f00730010a4 \ + --hash=sha256:9edcc35d1cae9fd5320171b1a838c7da8a5c968af31e82ecc3dff30b4be0957f \ + --hash=sha256:9fcb461fbf70654a52a7cc670e606f04449e2374c199b1825f754e16dacfedd8 \ + --hash=sha256:a0951822531e7aee6e0dfb556b30d5ee36bbe234faf60c20a16c01be3530869d \ + --hash=sha256:a361c9434a64d70a7dbb771d1de302c0cc9f13c0bffe1cf7e642152814b35265 \ + --hash=sha256:a4b25c6c25cac5d0d9d6d6da855195b254e0021e513e0249f0e3b444dc6e0e61 \ + --hash=sha256:a5af136bfba820d592f86c67affcef9b3ff4d4360ac3255e341e964489b48519 \ + --hash=sha256:a81eea9b999b985e4bacc650c4312805ea7008fd5e45e1bf221310176a7bcb3a \ + --hash=sha256:a9c63e04d003bc0fb6a03b348018b9a3002f98268200e22cc80f146beac5dc40 \ + --hash=sha256:aa95738a68cedd3a6f5492feddc513e2e166b50602958139e47bbdd82da0f5a7 \ + --hash=sha256:b0a2040f801406b93657a70b72fa12311063a319fee72ce98e1524da7200171f \ + --hash=sha256:b8bd70d5d816566a580d193326912f4a76ec2d28a97dc4cd4cc831c0af8e330e \ + --hash=sha256:b8da9f8035bb417770b1e1610526d87ad4fc58a2804dc4d79c53f6d2cf5a6eb9 \ + --hash=sha256:bc5518873822d2faa8ebdd2c1a4d7c8ef47b01a058495ab7924cb65bdbf5fc9a \ + --hash=sha256:c0d620e74897f8c2613b3c4e2e9c1e422eb46d2ddd07df540784d44117836af3 \ + --hash=sha256:c2640e23d2b7c98796f123ffd95cf2022c7777aa8a4a3b98b36c570d37e85eee \ + --hash=sha256:c81aef782380f0f13ead670aae01825eb653b44b046aa0e5ebbb79f76ed4aa11 \ + --hash=sha256:d4d16b608a1c43d7e33142099a75cd93af482dadce0bf82421e91cad077157f4 \ + --hash=sha256:d69fc39e627908f4c03297d5a88d9284b73f4d90b424461e32e8c2485e21c283 \ + --hash=sha256:d9da80e5b04acce03ced8ba6479a71c2a2edf535c2acc0d09c80d2f80f3bad15 \ + --hash=sha256:dd2c7e082b0b92e1baa4da28163a808672485617bc855cc22a2fd06978fa9084 \ + --hash=sha256:de7dac64e3eb832ffc7b840eb8f52f76420cde1b845be51b2a0f6b870890645e \ + --hash=sha256:e0785c2fb4a81e1aece366aa3e2e039f4a4d7d21aaaded5227d7f3c703427882 \ + --hash=sha256:e306d956cfa027fe041585f02a1602c32bfa6bb8ebea4899d373383295a6c62f \ + --hash=sha256:e78fb7419e07d98c2af4b8567b72b3eaf8cb05caad642e9963465569c8b2d87e \ + --hash=sha256:e9002e98dcb1c0a66723592520decd86238ddcef168b37ff6cfb559200b4b774 \ + --hash=sha256:e94cbc6ad9a6aeea46d775cbb11f361022f778a9cc8cc90af653d3a594b057ce \ + --hash=sha256:eea1b54943475f51698f85fa230c65ccac769f1e603b981be060ac5763d90927 \ + --hash=sha256:f100bfe2acf8a3689af9d0cc660d89f17286c9c795f9f18f7b62dd1a6b247ae6 \ + --hash=sha256:f162af66a2ed3f7d1d161a82ca584efd15acd9c1cff190a373458c32f7d42118 \ + --hash=sha256:f24b90b0e0c8cc9491fb1693ae91fe17cb7963153a1946395acdbdd5818429a4 \ + --hash=sha256:f29b68cd9714531672db62cc54f6e8ff981900f824d13fa0e00749189e13778e \ + --hash=sha256:f38bc489037eca88d6ebefc9c4d41a4e07c8e8b4de5188a9e6d290273ad7ebb1 \ + --hash=sha256:f3fd278f5e6bf7c75ccd6d12344eb686cc020712683363b66f46ac79d37c799f \ + --hash=sha256:f4003f70c56a5addd6aa0897f200dd59afd3bf7bcd5b3cce46dd21f925743bc2 \ + --hash=sha256:f48c963a76d71b9d7927eb817b543d0dccd52ab6648b99d37bd54f4cd475d856 \ + --hash=sha256:f819e0c6413e259a17a7c0d49f97f405abadd3c2a316a3b46c6440b7dbbedbb1 \ + --hash=sha256:fc5758e2b7a56532dc33e3c544d78cbaa9ecf0a0f2a2da2df882c1d6b99a317f \ + --hash=sha256:fcbdf2a9ca24e87bbebb47f1fe34e531ef06f104f98c9ccfc953a3f3344c567a # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ @@ -1583,51 +1594,51 @@ multidict==6.7.1 \ # aiobotocore # aiohttp # yarl -mypy==1.20.0 \ - --hash=sha256:002b613ae19f4ac7d18b7e168ffe1cb9013b37c57f7411984abbd3b817b0a214 \ - --hash=sha256:00e047c74d3ec6e71a2eb88e9ea551a2edb90c21f993aefa9e0d2a898e0bb732 \ - --hash=sha256:02cca0761c75b42a20a2757ae58713276605eb29a08dd8a6e092aa347c4115ca \ - --hash=sha256:0ecd63f75fdd30327e4ad8b5704bd6d91fc6c1b2e029f8ee14705e1207212489 \ - --hash=sha256:0f42dfaab7ec1baff3b383ad7af562ab0de573c5f6edb44b2dab016082b89948 \ - --hash=sha256:1973868d2adbb4584a3835780b27436f06d1dc606af5be09f187aaa25be1070f \ - --hash=sha256:26c8b52627b6552f47ff11adb4e1509605f094e29815323e487fc0053ebe93d1 \ - --hash=sha256:2721f0ce49cb74a38f00c50da67cb7d36317b5eda38877a49614dc018e91c787 \ - --hash=sha256:2fcedb16d456106e545b2bfd7ef9d24e70b38ec252d2a629823a4d07ebcdb69e \ - --hash=sha256:31b5dbb55293c1bd27c0fc813a0d2bb5ceef9d65ac5afa2e58f829dab7921fd5 \ - --hash=sha256:34506397dbf40c15dc567635d18a21d33827e9ab29014fb83d292a8f4f8953b6 \ - --hash=sha256:367e5c993ba34d5054d11937d0485ad6dfc60ba760fa326c01090fc256adf15c \ - --hash=sha256:379edf079ce44ac8d2805bcf9b3dd7340d4f97aad3a5e0ebabbf9d125b84b442 \ - --hash=sha256:39362cdb4ba5f916e7976fccecaab1ba3a83e35f60fa68b64e9a70e221bb2436 \ - --hash=sha256:4525e7010b1b38334516181c5b81e16180b8e149e6684cee5a727c78186b4e3b \ - --hash=sha256:47781555a7aa5fedcc2d16bcd72e0dc83eb272c10dd657f9fb3f9cc08e2e6abb \ - --hash=sha256:49d11c6f573a5a08f77fad13faff2139f6d0730ebed2cfa9b3d2702671dd7188 \ - --hash=sha256:555493c44a4f5a1b58d611a43333e71a9981c6dbe26270377b6f8174126a0526 \ - --hash=sha256:555658c611099455b2da507582ea20d2043dfdfe7f5ad0add472b1c6238b433f \ - --hash=sha256:697f102c5c1d526bdd761a69f17c6070f9892eebcb94b1a5963d679288c09e78 \ - --hash=sha256:76a70bf840495729be47510856b978f1b0ec7d08f257ca38c9d932720bf6b43e \ - --hash=sha256:7d3243c406773185144527f83be0e0aefc7bf4601b0b2b956665608bf7c98a83 \ - --hash=sha256:931a7630bba591593dcf6e97224a21ff80fb357e7982628d25e3c618e7f598ef \ - --hash=sha256:9804c3ad27f78e54e58b32e7cb532d128b43dbfb9f3f9f06262b821a0f6bd3f5 \ - --hash=sha256:a17c5d0bdcca61ce24a35beb828a2d0d323d3fcf387d7512206888c900193367 \ - --hash=sha256:a6e0641147cbfa7e4e94efdb95c2dab1aff8cfc159ded13e07f308ddccc8c48e \ - --hash=sha256:a79c1eba7ac4209f2d850f0edd0a2f8bba88cbfdfefe6fb76a19e9d4fe5e71a2 \ - --hash=sha256:a9336b5e6712f4adaf5afc3203a99a40b379049104349d747eb3e5a3aa23ac2e \ - --hash=sha256:b20c8b0fd5877abdf402e79a3af987053de07e6fb208c18df6659f708b535134 \ - --hash=sha256:b3a49064504be59e59da664c5e149edc1f26c67c4f8e8456f6ba6aba55033018 \ - --hash=sha256:b503ab55a836136b619b5fc21c8803d810c5b87551af8600b72eecafb0059cb0 \ - --hash=sha256:bd0212976dc57a5bfeede7c219e7cd66568a32c05c9129686dd487c059c1b88a \ - --hash=sha256:c70380fe5d64010f79fb863b9081c7004dd65225d2277333c219d93a10dad4dd \ - --hash=sha256:d99f515f95fd03a90875fdb2cca12ff074aa04490db4d190905851bdf8a549a8 \ - --hash=sha256:e80cf77847d0d3e6e3111b7b25db32a7f8762fd4b9a3a72ce53fe16a2863b281 \ - --hash=sha256:eb96c84efcc33f0b5e0e04beacf00129dd963b67226b01c00b9dfc8affb464c3 \ - --hash=sha256:ebea00201737ad4391142808ed16e875add5c17f676e0912b387739f84991e13 \ - --hash=sha256:efe8d70949c3023698c3fca1e94527e7e790a361ab8116f90d11221421cd8726 \ - --hash=sha256:f13b3e41bce9d257eded794c0f12878af3129d80aacd8a3ee0dee51f3a978651 \ - --hash=sha256:f194db59657c58593a3c47c6dfd7bad4ef4ac12dbc94d01b3a95521f78177e33 \ - --hash=sha256:f49590891d2c2f8a9de15614e32e459a794bcba84693c2394291a2038bbaaa69 \ - --hash=sha256:f75ff57defcd0f1d6e006d721ccdec6c88d4f6a7816eb92f1c4890d979d9ee62 \ - --hash=sha256:f799d9db89fc00446f03281f84a221e50018fc40113a3ba9864b132895619ebe \ - --hash=sha256:f8426d4d75d68714abc17a4292d922f6ba2cfb984b72c2278c437f6dae797865 +mypy==1.20.2 \ + --hash=sha256:0c64e5973df366b747646fc98da921f9d6eba9716d57d1db94a83c026a08e0fb \ + --hash=sha256:0deb80d062b2479f2c87ae568f89845afc71d11bc41b04179e58165fd9f31e98 \ + --hash=sha256:1e1c12f6d2db3d78b909b5f77513c11eb7f2dd2782b96a3ab6dffc7d44575c99 \ + --hash=sha256:20175a1c0f49863946ec20b7f63255768058ac4f07d2b9ded6a6b46cfb5a9100 \ + --hash=sha256:29752dbbf8cc53f89f6ac096d363314333045c257c9c75cbd189ca2de0455744 \ + --hash=sha256:2a4102b03bb7481d9a91a6da8d174740c9c8c4401024684b9ca3b7cc5e49852f \ + --hash=sha256:2de3dcea53babc1c3237a19002bc3d228ce1833278f093b8d619e06e7cc79609 \ + --hash=sha256:34397cdced6b90b836e38182076049fdb41424322e0b0728c946b0939ebdf9f6 \ + --hash=sha256:4077797a273e56e8843d001e9dfe4ba10e33323d6ade647ff260e5cd97d9758c \ + --hash=sha256:419413398fe250aae057fd2fe50166b61077083c9b82754c341cf4fd73038f30 \ + --hash=sha256:4b6481b228d072315b053210b01ac320e1be243dc17f9e5887ef167f23f5fae4 \ + --hash=sha256:4dbfcf869f6b0517f70cf0030ba6ea1d6645e132337a7d5204a18d8d5636c02b \ + --hash=sha256:4fef51b01e638974a6e69885687e9bd40c8d1e09a6cd291cca0619625cf1f558 \ + --hash=sha256:52b176444e2e5054dfcbcb8c75b0b719865c96247b37407184bbfca5c353f2c2 \ + --hash=sha256:56908d7e08318d39f85b1f0c6cfd47b0cac1a130da677630dac0de3e0623e102 \ + --hash=sha256:5a65aa591af023864fd08a97da9974e919452cfe19cb146c8a5dc692626445dc \ + --hash=sha256:688c3312e5dadb573a2c69c82af3a298d43ecf9e6d264e0f95df960b5f6ac19c \ + --hash=sha256:6e2b469efd811707bc530fd1effef0f5d6eebcb7fe376affae69025da4b979a2 \ + --hash=sha256:7488448de6007cd5177c6cea0517ac33b4c0f5ee9b5e9f2be51ce75511a85517 \ + --hash=sha256:785b08db19c9f214dc37d65f7c165d19a30fcecb48abfa30f31b01b5acaabb58 \ + --hash=sha256:7b0e817b518bff7facd7f85ea05b643ad8bdcce684cf29784987b0a7c8e1f997 \ + --hash=sha256:803203d2b6ea644982c644895c2f78b28d0e208bba7b27d9b921e0ec5eb207c6 \ + --hash=sha256:89dce27e142d25ffbc154c1819383b69f2e9234dc4ed4766f42e0e8cb264ab5c \ + --hash=sha256:913485a03f1bcf5d279409a9d2b9ed565c151f61c09f29991e5faa14033da4c8 \ + --hash=sha256:97d7b9a485b40f8ca425460e89bf1da2814625b2da627c0dcc6aa46c92631d14 \ + --hash=sha256:9bcb8aa397ff0093c824182fd76a935a9ba7ad097fcbef80ae89bf6c1731d8ec \ + --hash=sha256:9d56a78b646f2e3daa865bc70cd5ec5a46c50045801ca8ff17a0c43abc97e3ee \ + --hash=sha256:a5da6976f20cae27059ea8d0c86e7cef3de720e04c4bb9ee18e3690fdb792066 \ + --hash=sha256:a94c5a76ab46c5e6257c7972b6c8cff0574201ca7dc05647e33e795d78680563 \ + --hash=sha256:a95a9248b0c6fd933a442c03c3b113c3b61320086b88e2c444676d3fd1ca3330 \ + --hash=sha256:baf593f2765fa3a6b1ef95807dbaa3d25b594f6a52adcc506a6b9cb115e1be67 \ + --hash=sha256:bb9c2fa06887e21d6a3a868762acb82aec34e2c6fd0174064f27c93ede68ad15 \ + --hash=sha256:bba9ad231e92a3e424b3e56b65aa17704993425bba97e302c832f9466bb85bac \ + --hash=sha256:c3bae4f855d965b5453784300c12ffc63a548304ac7f99e55d4dc7c898673aa3 \ + --hash=sha256:c566c3a88b6ece59b3d70f65bedef17304f48eb52ff040a6a18214e1917b3254 \ + --hash=sha256:cdecf62abcc4292500d7858aeae87a1f8f1150f4c4dd08fb0b336ee79b2a6df3 \ + --hash=sha256:cf5a4db6dca263010e2c7bff081c89383c72d187ba2cf4c44759aac970e2f0c4 \ + --hash=sha256:d52ad8d78522da1d308789df651ee5379088e77c76cb1994858d40a426b343b9 \ + --hash=sha256:e061b58443f1736f8a37c48978d7ab581636d6ab03e3d4f99e3fa90463bb9382 \ + --hash=sha256:e2877a02380adfcdbc69071a0f74d6e9dbbf593c0dc9d174e1f223ffd5281943 \ + --hash=sha256:e73c07f23009962885c197ccb9b41356a30cc0e5a1d0c2ea8fd8fb1362d7f924 \ + --hash=sha256:e8222c26daaafd9e8626dec58ae36029f82585890589576f769a650dd20fd665 \ + --hash=sha256:edfbfca868cdd6bd8d974a60f8a3682f5565d3f5c99b327640cedd24c4264026 \ + --hash=sha256:f376e37f9bf2a946872fc5fd1199c99310748e3c26c7a26683f13f8bdb756cbd # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ @@ -1700,9 +1711,9 @@ oauthlib==3.3.1 \ --hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \ --hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1 # via requests-oauthlib -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # db-dtypes @@ -1776,9 +1787,9 @@ pandas==2.3.3 \ # pandas-gbq # pymilvus # snowflake-connector-python -pandas-gbq==0.34.1 \ - --hash=sha256:6bea5b85937251b976cf9db38151ea59abbff98771179183488d4614694bff67 \ - --hash=sha256:b74932c6ee35dfc81582f39c792e3a68c9ef9bee8c85f25667d9d05dfadd0daf +pandas-gbq==0.35.0 \ + --hash=sha256:258de481019566611031919997bf9c1ece4ca30a4dd02d3fc3664b251d446182 \ + --hash=sha256:596c908487ef0649a161e86ef272c00c267e581b95dc5ee0dc3518545b33bcfc # via google-cloud-bigquery parsy==2.2 \ --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ @@ -1788,17 +1799,17 @@ 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.9.6 \ + --hash=sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a \ + --hash=sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917 # via snowflake-connector-python -prometheus-client==0.24.1 \ - --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ - --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 +prometheus-client==0.25.0 \ + --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ + --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 # via feast (pyproject.toml) propcache==0.4.1 \ --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ @@ -1994,57 +2005,57 @@ psycopg-pool==3.3.0 \ --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 # 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 @@ -2069,141 +2080,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.3 \ + --hash=sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927 \ + --hash=sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d # 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.3 \ + --hash=sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba \ + --hash=sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35 \ + --hash=sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4 \ + --hash=sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505 \ + --hash=sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7 \ + --hash=sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8 \ + --hash=sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4 \ + --hash=sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37 \ + --hash=sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25 \ + --hash=sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022 \ + --hash=sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1 \ + --hash=sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7 \ + --hash=sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c \ + --hash=sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3 \ + --hash=sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb \ + --hash=sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3 \ + --hash=sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976 \ + --hash=sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c \ + --hash=sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab \ + --hash=sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa \ + --hash=sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6 \ + --hash=sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396 \ + --hash=sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c \ + --hash=sha256:3d08782c4045f90724b44c95d35ebec0d67edb8a957a2ac81d5a8e4b8a200495 \ + --hash=sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c \ + --hash=sha256:4335e87c7afa436a0dfa899e138d57a72f8aad542e2cf19c36fb428461caabd0 \ + --hash=sha256:4b068543bdb707f5d935dab765d99227aa2545ef2820935f2e5dd801795c7dbd \ + --hash=sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf \ + --hash=sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531 \ + --hash=sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5 \ + --hash=sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda \ + --hash=sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d \ + --hash=sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e \ + --hash=sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df \ + --hash=sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6 \ + --hash=sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c \ + --hash=sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13 \ + --hash=sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536 \ + --hash=sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287 \ + --hash=sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0 \ + --hash=sha256:68ef2f623dda6d5a9067ac014e406c020c780b2a358930a7e5c1b73702900720 \ + --hash=sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050 \ + --hash=sha256:6dff8cc884679df229ebc6d8eb2321ea6f8e091bc7d4886d4dc2e0e71452843c \ + --hash=sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1 \ + --hash=sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8 \ + --hash=sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0 \ + --hash=sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374 \ + --hash=sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807 \ + --hash=sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6 \ + --hash=sha256:831eb19aa789a97356979e94c981e5667759301fb708d1c0d5adf1bc0098b873 \ + --hash=sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57 \ + --hash=sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f \ + --hash=sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c \ + --hash=sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad \ + --hash=sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e \ + --hash=sha256:91249bcb7c165c2fb2a2f852dbc5c91636e2e218e75d96dfdd517e4078e173dd \ + --hash=sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23 \ + --hash=sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46 \ + --hash=sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1 \ + --hash=sha256:99421e7684a60f7f3550a1d159ade5fdff1954baedb6bdd407cba6a307c9f27d \ + --hash=sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1 \ + --hash=sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee \ + --hash=sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c \ + --hash=sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874 \ + --hash=sha256:9f247596366f4221af52beddd65af1218797771d6989bc891a0b86ccaa019168 \ + --hash=sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a \ + --hash=sha256:a35cc284c8dd7edae8a31533713b4d2467dfe7c4f1b5587dd4031f28f90d1d13 \ + --hash=sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f \ + --hash=sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a \ + --hash=sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789 \ + --hash=sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe \ + --hash=sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f \ + --hash=sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5 \ + --hash=sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943 \ + --hash=sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b \ + --hash=sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089 \ + --hash=sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b \ + --hash=sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff \ + --hash=sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67 \ + --hash=sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803 \ + --hash=sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045 \ + --hash=sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8 \ + --hash=sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346 \ + --hash=sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2 \ + --hash=sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f \ + --hash=sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687 \ + --hash=sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76 \ + --hash=sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1 \ + --hash=sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f \ + --hash=sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2 \ + --hash=sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c \ + --hash=sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018 \ + --hash=sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba \ + --hash=sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c \ + --hash=sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf \ + --hash=sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7 \ + --hash=sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47 \ + --hash=sha256:d56bdb4af1767cc15b0386b3c581fdfe659bb9ee4a4f776e92c1cd9d074000d6 \ + --hash=sha256:dcda6583921c05a40533f982321532f2d8db29326c7b95c4026941fa5074bd79 \ + --hash=sha256:dd81f6907932ebac3abbe41378dac64b2380db1287e2aa64d8d88f78d170f51a \ + --hash=sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e \ + --hash=sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a \ + --hash=sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34 \ + --hash=sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b \ + --hash=sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85 \ + --hash=sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca \ + --hash=sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f \ + --hash=sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3 \ + --hash=sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64 \ + --hash=sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22 \ + --hash=sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72 \ + --hash=sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec \ + --hash=sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d \ + --hash=sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3 \ + --hash=sha256:fa3eb7c2995aa443687a825bc30395c8521b7c6ec201966e55debfd1128bcceb \ + --hash=sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395 \ + --hash=sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb \ + --hash=sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4 \ + --hash=sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127 \ + --hash=sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56 # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.0 \ + --hash=sha256:24285fd4b0e0c06507dd9fdfd331ee23794305352aaec8fc4eb92d4047aeb67d \ + --hash=sha256:fc8d5d692eb7092e43c8647c1c35a3ecd00e040fcf02ed86f4cb5458ca62182e # via # fastapi-mcp # mcp @@ -2228,13 +2238,13 @@ pymilvus==2.5.18 \ --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d # via feast (pyproject.toml) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 +pymysql==1.1.3 \ + --hash=sha256:8164ba62c552f6105f3b11753352d0f16b90d1703ba67d81923d5a8a5d1c5289 \ + --hash=sha256:e70ebf2047a4edf6138cf79c68ad418ef620af65900aa585c5e8bfc95044d43a # via feast (pyproject.toml) -pyopenssl==26.0.0 \ - --hash=sha256:df94d28498848b98cc1c0ffb8ef1e71e40210d3b0a8064c9d29571ed2904bf81 \ - --hash=sha256:f293934e52936f2e3413b89c6ce36df66a0b34ae1ea3a053b8c5020ff2f513fc +pyopenssl==26.1.0 \ + --hash=sha256:115563879b2c8ccb207975705d3e491434d8c9d7c79667c902ecbf5f3bbd2ece \ + --hash=sha256:737f0a2275c5bc54f3b02137687e1a765931fb3949b9a92a825e4d33b9eec08b # via snowflake-connector-python python-dateutil==2.9.0.post0 \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ @@ -2253,9 +2263,9 @@ python-dotenv==1.2.2 \ # pydantic-settings # pymilvus # uvicorn -python-multipart==0.0.22 \ - --hash=sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155 \ - --hash=sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58 +python-multipart==0.0.27 \ + --hash=sha256:6fccfad17a27334bd0193681b369f476eda3409f17381a2d65aa7df3f7275645 \ + --hash=sha256:9870a6a8c5a20a5bf4f07c017bd1489006ff8836cff097b6933355ee2b49b602 # via mcp pytz==2026.1.post1 \ --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ @@ -2342,9 +2352,9 @@ pyyaml==6.0.3 \ # dask # kubernetes # uvicorn -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.0 \ + --hash=sha256:64a6ea7bf567ad43c964d2c30d82853f8df927c5c9017766c55a1d1ed95d18ad \ + --hash=sha256:a9c74a5c893a5ef8455a5adb793a31bb70feb821c86eccb62eebef5a19c429ec # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -2370,9 +2380,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 @@ -2549,78 +2559,78 @@ 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.49 \ + --hash=sha256:01146546d84185f12721a1d2ce0c6673451a7894d1460b592d378ca4871a0c72 \ + --hash=sha256:059d7151fff513c53a4638da8778be7fce81a0c4854c7348ebd0c4078ddf28fe \ + --hash=sha256:0c98c59075b890df8abfcc6ad632879540f5791c68baebacb4f833713b510e75 \ + --hash=sha256:0f2fa354ba106eafff2c14b0cc51f22801d1e8b2e4149342023bd6f0955de5f5 \ + --hash=sha256:12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148 \ + --hash=sha256:22d8798819f86720bc646ab015baff5ea4c971d68121cb36e2ebc2ee43ead2b7 \ + --hash=sha256:233088b4b99ebcbc5258c755a097aa52fbf90727a03a5a80781c4b9c54347a2e \ + --hash=sha256:24bd94bb301ec672d8f0623eba9226cc90d775d25a0c92b5f8e4965d7f3a1518 \ + --hash=sha256:275424295f4256fd301744b8f335cff367825d270f155d522b30c7bf49903ee7 \ + --hash=sha256:32fe6a41ad97302db2931f05bb91abbcc65b5ce4c675cd44b972428dd2947700 \ + --hash=sha256:334edbcff10514ad1d66e3a70b339c0a29886394892490119dbb669627b17717 \ + --hash=sha256:3bb9ec6436a820a4c006aad1ac351f12de2f2dbdaad171692ee457a02429b672 \ + --hash=sha256:3ddcb27fb39171de36e207600116ac9dfd4ae46f86c82a9bf3934043e80ebb88 \ + --hash=sha256:42e8804962f9e6f4be2cbaedc0c3718f08f60a16910fa3d86da5a1e3b1bfe60f \ + --hash=sha256:43d044780732d9e0381ac8d5316f95d7f02ef04d6e4ef6dc82379f09795d993f \ + --hash=sha256:46796877b47034b559a593d7e4b549aba151dae73f9e78212a3478161c12ab08 \ + --hash=sha256:46d51518d53edfbe0563662c96954dc8fcace9832332b914375f45a99b77cc9a \ + --hash=sha256:47604cb2159f8bbd5a1ab48a714557156320f20871ee64d550d8bf2683d980d3 \ + --hash=sha256:4bbccb45260e4ff1b7db0be80a9025bb1e6698bdb808b83fff0000f7a90b2c0b \ + --hash=sha256:4d4e5a0ceba319942fa6b585cf82539288a61e314ef006c1209f734551ab9536 \ + --hash=sha256:55250fe61d6ebfd6934a272ee16ef1244e0f16b7af6cd18ab5b1fc9f08631db0 \ + --hash=sha256:566df36fd0e901625523a5a1835032f1ebdd7f7886c54584143fa6c668b4df3b \ + --hash=sha256:57ca426a48eb2c682dae8204cd89ea8ab7031e2675120a47924fabc7caacbc2a \ + --hash=sha256:5e61abbec255be7b122aa461021daa7c3f310f3e743411a67079f9b3cc91ece3 \ + --hash=sha256:618a308215b6cececb6240b9abde545e3acdabac7ae3e1d4e666896bf5ba44b4 \ + --hash=sha256:62557958002b69699bdb7f5137c6714ca1133f045f97b3903964f47db97ea339 \ + --hash=sha256:6270d717b11c5476b0cbb21eedc8d4dbb7d1a956fd6c15a23e96f197a6193158 \ + --hash=sha256:685e93e9c8f399b0c96a624799820176312f5ceef958c0f88215af4013d29066 \ + --hash=sha256:69469ce8ce7a8df4d37620e3163b71238719e1e2e5048d114a1b6ce0fbf8c662 \ + --hash=sha256:6eb188b84269f357669b62cb576b5b918de10fb7c728a005fa0ebb0b758adce1 \ + --hash=sha256:74ab4ee7794d7ed1b0c37e7333640e0f0a626fc7b398c07a7aef52f484fddde3 \ + --hash=sha256:77641d299179c37b89cf2343ca9972c88bb6eef0d5fc504a2f86afd15cd5adf5 \ + --hash=sha256:7c821c47ecfe05cc32140dcf8dc6fd5d21971c86dbd56eabfe5ba07a64910c01 \ + --hash=sha256:7d6be30b2a75362325176c036d7fb8d19e8846c77e87683ffaa8177b35135613 \ + --hash=sha256:7f605a456948c35260e7b2a39f8952a26f077fd25653c37740ed186b90aaa68a \ + --hash=sha256:83101a6930332b87653886c01d1ee7e294b1fe46a07dd9a2d2b4f91bcc88eec0 \ + --hash=sha256:88690f4e1f0fbf5339bedbb127e240fec1fd3070e9934c0b7bef83432f779d2f \ + --hash=sha256:8a97ac839c2c6672c4865e48f3cbad7152cee85f4233fb4ca6291d775b9b954a \ + --hash=sha256:8d6efc136f44a7e8bc8088507eaabbb8c2b55b3dbb63fe102c690da0ddebe55e \ + --hash=sha256:8e20e511dc15265fb433571391ba313e10dd8ea7e509d51686a51313b4ac01a2 \ + --hash=sha256:951d4a210744813be63019f3df343bf233b7432aadf0db54c75802247330d3af \ + --hash=sha256:9ac7a3e245fd0310fd31495eb61af772e637bdf7d88ee81e7f10a3f271bff014 \ + --hash=sha256:9b1c058c171b739e7c330760044803099c7fff11511e3ab3573e5327116a9c33 \ + --hash=sha256:9c04bff9a5335eb95c6ecf1c117576a0aa560def274876fd156cfe5510fccc61 \ + --hash=sha256:9c4969a86e41454f2858256c39bdfb966a20961e9b58bf8749b65abf447e9a8d \ + --hash=sha256:9e0400fa22f79acc334d9a6b185dc00a44a8e6578aa7e12d0ddcd8434152b187 \ + --hash=sha256:a05977bffe9bffd2229f477fa75eabe3192b1b05f408961d1bebff8d1cd4d401 \ + --hash=sha256:a143af2ea6672f2af3f44ed8f9cd020e9cc34c56f0e8db12019d5d9ecf41cb3b \ + --hash=sha256:a51d3db74ba489266ef55c7a4534eb0b8db9a326553df481c11e5d7660c8364d \ + --hash=sha256:b95b2f470c1b2683febd2e7eab1d3f0e078c91dbdd0b00e9c645d07a413bb99f \ + --hash=sha256:b9870d15ef00e4d0559ae10ee5bc71b654d1f20076dbe8bc7ed19b4c0625ceba \ + --hash=sha256:c1dc3368794d522f43914e03312202523cc89692f5389c32bea0233924f8d977 \ + --hash=sha256:c338ec6ec01c0bc8e735c58b9f5d51e75bacb6ff23296658826d7cfdfdb8678a \ + --hash=sha256:c5070135e1b7409c4161133aa525419b0062088ed77c92b1da95366ec5cbebbe \ + --hash=sha256:cc992c6ed024c8c3c592c5fc9846a03dd68a425674900c70122c77ea16c5fb0b \ + --hash=sha256:d15950a57a210e36dd4cec1aac22787e2a4d57ba9318233e2ef8b2daf9ff2d5f \ + --hash=sha256:d898cc2c76c135ef65517f4ddd7a3512fb41f23087b0650efb3418b8389a3cd1 \ + --hash=sha256:d99945830a6f3e9638d89a28ed130b1eb24c91255e4f24366fbe699b983f29e4 \ + --hash=sha256:da9b91bca419dc9b9267ffadde24eae9b1a6bffcd09d0a207e5e3af99a03ce0d \ + --hash=sha256:df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120 \ + --hash=sha256:e06e617e3d4fd9e51d385dfe45b077a41e9d1b033a7702551e3278ac597dc750 \ + --hash=sha256:ec44cfa7ef1a728e88ad41674de50f6db8cfdb3e2af84af86e0041aaf02d43d0 \ + --hash=sha256:fb37f15714ec2652d574f021d479e78cd4eb9d04396dca36568fdfffb3487982 # via feast (pyproject.toml) -sqlglot==30.2.1 \ - --hash=sha256:ef4a67cc6f66a8043085eb8ea95fa9541c1625dffa9145ad4e9815a7ba60a199 \ - --hash=sha256:f23d9ee9427ef9d20df15f9b0ffa57d9eb45e52b012219a349d1e6b50ed926d1 +sqlglot==30.6.0 \ + --hash=sha256:246d34d39927422a50a3fa155f37b2f6346fba85f1a755b13c941eb32ef93361 \ + --hash=sha256:e005fc2f47994f90d7d8df341f1cbe937518497b0b7b1507d4c03c4c9dfd2778 # via ibis-framework -sse-starlette==3.3.4 \ - --hash=sha256:84bb06e58939a8b38d8341f1bc9792f06c2b53f48c608dd207582b664fc8f3c1 \ - --hash=sha256:aaf92fc067af8a5427192895ac028e947b484ac01edbc3caf00e7e7137c7bef1 +sse-starlette==3.4.1 \ + --hash=sha256:6b43cf21f1d574d582a6e1b0cfbde1c94dc86a32a701a7168c99c4475c6bd1d0 \ + --hash=sha256:f780bebcf6c8997fe514e3bd8e8c648d8284976b391c8bed0bcb1f611632b555 # via mcp starlette==1.0.0 \ --hash=sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149 \ @@ -2713,13 +2723,13 @@ typeguard==4.5.1 \ --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 # via feast (pyproject.toml) -typer==0.24.1 \ - --hash=sha256:112c1f0ce578bfb4cab9ffdabc68f031416ebcc216536611ba21f04e9aa84c9e \ - --hash=sha256:e39b4732d65fbdcde189ae76cf7cd48aeae72919dea1fdfc16593be016256b45 +typer==0.25.1 \ + --hash=sha256:75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89 \ + --hash=sha256:9616eb8853a09ffeabab1698952f33c6f29ffdbceb4eaeecf571880e8d7664cc # via fastapi-mcp -types-pymysql==1.1.0.20251220 \ - --hash=sha256:ae1c3df32a777489431e2e9963880a0df48f6591e0aa2fd3a6fabd9dee6eca54 \ - --hash=sha256:fa1082af7dea6c53b6caa5784241924b1296ea3a8d3bd060417352c5e10c0618 +types-pymysql==1.1.0.20260408 \ + --hash=sha256:b784dc37908479e3767e2d794ab507b3674adb1c686ca3d13fc9e2960dbcb9ec \ + --hash=sha256:da630647eaaa7a926a3907794f4067f269cd245b2c202c74aa3c6a3bd660a9db # via feast (pyproject.toml) typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ @@ -2755,9 +2765,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 # ibis-framework # pandas @@ -3302,7 +3312,7 @@ yarl==1.23.0 \ --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d # via aiohttp -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==3.23.1 \ + --hash=sha256:0b3596c50a5c700c9cb40ba8d86d9f2cc4807e9bedb06bcdf7fac85633e444dc \ + --hash=sha256:32120e378d32cd9714ad503c1d024619063ec28aad2248dc6672ad13edfa5110 # 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 3ecce8ab7be..c3116ec9f68 100644 --- a/sdk/python/requirements/py3.10-minimal-sdist-requirements-build.txt +++ b/sdk/python/requirements/py3.10-minimal-sdist-requirements-build.txt @@ -214,9 +214,9 @@ cython==3.2.4 \ # 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 \ @@ -265,9 +265,9 @@ gitdb==4.0.12 \ --hash=sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571 \ --hash=sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf # via gitpython -gitpython==3.1.46 \ - --hash=sha256:400124c7d0ef4ea03f7310ac2fbf7151e09ff97f2a3288d64a440c584a29c37f \ - --hash=sha256:79812ed143d9d25b6d176a10bb511de0f9c67b1fa641d82097b0ab90398a2058 +gitpython==3.1.49 \ + --hash=sha256:024b0422d7f84d15cd794844e029ffebd4c5d42a7eb9b936b458697ef550a02c \ + --hash=sha256:42f9399c9eb33fc581014bedd76049dfbaf6375aa2a5754575966387280315e1 # via pymilvus hatch-fancy-pypi-readme==25.1.0 \ --hash=sha256:9c58ed3dff90d51f43414ce37009ad1d5b0f08ffc9fc216998a06380f01c0045 \ @@ -322,6 +322,7 @@ hatchling==1.29.0 \ # pydantic-settings # pygments # python-multipart + # redis # referencing # scikit-build-core # starlette @@ -334,97 +335,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.9.0 \ + --hash=sha256:07cf11f769831186eeac424376e6189f20ace4f7263e2134bdb9757340d84d4d \ + --hash=sha256:0a09c2f5869649101738653a9b7ab70cf045a1105ac66cbb8f4055e61df78f2d \ + --hash=sha256:0a1be03168b2691ba61927e299b352a6315189199ca18a57b733f86cb3cc8d38 \ + --hash=sha256:0b73e4266307e51c95e09c0750b7ec383c561d2e97d58e473f6f6a209952fbb8 \ + --hash=sha256:15cb151e52a044f06e54ac7f7b47adbfc89b5c8e2b63e1175a9d587c43e8942a \ + --hash=sha256:194fc1a32e1e21fe809d38b5faea66cc65eaa00217c8901fbdb99866938adbdb \ + --hash=sha256:1bf465d1e5b0a27713862441f6467b5ab76385f4ecf8f1f3a44f8aa3c695b4b6 \ + --hash=sha256:1c587494461ebd42229d0f1739f3aa34237dd9980623ecf1be8d3bcba79f4499 \ + --hash=sha256:224b9727eb8bc188bc3bcf29d969dba0cd61b01d9bac80c41575520cc4baabb2 \ + --hash=sha256:22a904cbdb678f7cb348c90d543d3c52f581663d687992fee47fd566dcbf5285 \ + --hash=sha256:2b8f5d00b49818f4e2b1667db994488b045835e0ac16fe2f924f3871bd2b8ac5 \ + --hash=sha256:2c3786f0f4490a5cd87f1ed6cefae833ad6b1060d52044ce0434a2e85893afd0 \ + --hash=sha256:2d03fa4fd277a7974c1978c92c374c57f44edeee163d147b477b143446ad1bf6 \ + --hash=sha256:2f8e12706dcb8ff6b3ed57514a19e45c49ad00bcd423e87b2b2e4b5f64578443 \ + --hash=sha256:3be322a15ee5e70b93b7a59cfd074614f22cc8c9ff18bd27f474e79137ea8d3b \ + --hash=sha256:3cc2917258e131ae5f958a4d872e07555b51cb7466a43433218061c74ef33745 \ + --hash=sha256:3f05d145df35dca5056a8bc3838e940efebd893a54b3e19b2dda39ceaa299bcb \ + --hash=sha256:3fe56e80badb66fdcde06bef81bbaa5bfcf6fbd7aefb86222d9e369c38c6b228 \ + --hash=sha256:42ff8a962554c350d4a83cf47d9b7b78b0e6ff7943e87df7cdfc97c07f3c016f \ + --hash=sha256:451daa98463b7695b0a30aa56bf637831ea559e7b8101ac2ef6382e8eb15e29c \ + --hash=sha256:465814ab157986acb9dfa5ccd7df944be5eefc0d08d31ec6e8d88bc71251d845 \ + --hash=sha256:4c4d0440a3a8e31d962340c3e1cc3fc9ee7febd34c8d8f770d06adb947779ea5 \ + --hash=sha256:4e3dda8345307fd7306db0ed0cb109a63a2c85ba780eb9dc2d09b2049a931f9c \ + --hash=sha256:5093043afb226ecfa1400120d1ebd4442b4f99977783e4f4f7248879009b227f \ + --hash=sha256:5112c2fb7c2eefefaeaf5c97fec81343ef44ee86a30dcfaa8223822fba6467b4 \ + --hash=sha256:527b5b820b47a09e09829051452bb0d1dd2122261254e2a6f674d12f1d793d54 \ + --hash=sha256:54d412e47c21b85865676ed0724e37a89e9593c2eee1e7367adf85bfad56ffb1 \ + --hash=sha256:56d65b583cf43b8cf4c8fbe1e1da20fa3076cc32a1149a141507af1062718236 \ + --hash=sha256:5ca8e133d799c948db2ab1afc081c333a825b5540475164726dcbf73537e5c2f \ + --hash=sha256:603138ee838ee1583f1b960b62d5d0007845c5c423feb68e44648b1359014e27 \ + --hash=sha256:63c12efcd160e1d14da11af0c46c0217473e1e0d2ae1acbccc83f561ea4c2a7b \ + --hash=sha256:657f8ba7b9eaaa82759a104137aed2a3ef7bc46ccfd43e0d89b04005b3e0a4cc \ + --hash=sha256:66b58fed90a545328e80d575467244de3741e088c1af928f0b489ebec3ef3858 \ + --hash=sha256:6788207daa0c19955d2b668f3294a368d19f67d9b5f274553fd073c1260cbb9f \ + --hash=sha256:703f4ae36d6240bfe24f542bac784c7e4194ec49c3ba5a994d02891649e2d85b \ + --hash=sha256:7202bdcac47d3a708271c4304a474a8605a4a9a4a709e954bf2d3241140aa938 \ + --hash=sha256:756775d25ec8345b837ab52effee3ad2f3b2dfd6bbee3e3f029c517bd5d8f05a \ + --hash=sha256:78042f6facfd98ecb25e9829c7e37cce23363d9d7c83bc5f72702c5059eb082b \ + --hash=sha256:789fff71757facc0738e8d89e3b84e4f0251c1c975e85e81b152cdaca927cc2d \ + --hash=sha256:7bc30ad339f4e1a01d4917d645e522a0bc0030644d8973f6346397c93ba1503f \ + --hash=sha256:7d429bdd4ac0ab17c8e4a8af0ed2a7440b16eba474909ab357131018fe8c7e71 \ + --hash=sha256:7d5c8a5929ac325729f6119802070b561f4db793dffc45e9ac750992a4ed4d22 \ + --hash=sha256:7e6274fd33fc5b2a14d41c9119629d3ff395849d8bcbc80cf637d9e8d2034da8 \ + --hash=sha256:80b25c7b570a86c03b5da69e665809deb39265476e8e21d96a9328f9762f9990 \ + --hash=sha256:81107843ed1836874b46b310f9b1816abcb89912af627868522461c3b7333c0f \ + --hash=sha256:8494cfc61e03542f2d381e71804990b3931175a29b9278fdb4a5459948778dc2 \ + --hash=sha256:850d6d03177e52700af605fd60db7f37dcb89782049a149674d1a9649c2138fd \ + --hash=sha256:8c6bc1384d9738781cfd41d09ad7f6e8af13cfea2c75ece6bd6d2566cdea2076 \ + --hash=sha256:90904fac73c478f4b83f4ed96c99c8208b75e6f9a8a1910548f69a00f1eaa671 \ + --hash=sha256:90e6d5420fc8a300518d4d2288154ff45005e920425c22cbbfe8330f3f754bd9 \ + --hash=sha256:928bd06eca2c2bbf4349e5b817f837509b0604342e65a502de1d50a7570afd15 \ + --hash=sha256:9b3e3bc363f71bda1639a4ee593cb78f7fbfeacc73411ec0d4c92f00730010a4 \ + --hash=sha256:9edcc35d1cae9fd5320171b1a838c7da8a5c968af31e82ecc3dff30b4be0957f \ + --hash=sha256:9fcb461fbf70654a52a7cc670e606f04449e2374c199b1825f754e16dacfedd8 \ + --hash=sha256:a0951822531e7aee6e0dfb556b30d5ee36bbe234faf60c20a16c01be3530869d \ + --hash=sha256:a361c9434a64d70a7dbb771d1de302c0cc9f13c0bffe1cf7e642152814b35265 \ + --hash=sha256:a4b25c6c25cac5d0d9d6d6da855195b254e0021e513e0249f0e3b444dc6e0e61 \ + --hash=sha256:a5af136bfba820d592f86c67affcef9b3ff4d4360ac3255e341e964489b48519 \ + --hash=sha256:a81eea9b999b985e4bacc650c4312805ea7008fd5e45e1bf221310176a7bcb3a \ + --hash=sha256:a9c63e04d003bc0fb6a03b348018b9a3002f98268200e22cc80f146beac5dc40 \ + --hash=sha256:aa95738a68cedd3a6f5492feddc513e2e166b50602958139e47bbdd82da0f5a7 \ + --hash=sha256:b0a2040f801406b93657a70b72fa12311063a319fee72ce98e1524da7200171f \ + --hash=sha256:b8bd70d5d816566a580d193326912f4a76ec2d28a97dc4cd4cc831c0af8e330e \ + --hash=sha256:b8da9f8035bb417770b1e1610526d87ad4fc58a2804dc4d79c53f6d2cf5a6eb9 \ + --hash=sha256:bc5518873822d2faa8ebdd2c1a4d7c8ef47b01a058495ab7924cb65bdbf5fc9a \ + --hash=sha256:c0d620e74897f8c2613b3c4e2e9c1e422eb46d2ddd07df540784d44117836af3 \ + --hash=sha256:c2640e23d2b7c98796f123ffd95cf2022c7777aa8a4a3b98b36c570d37e85eee \ + --hash=sha256:c81aef782380f0f13ead670aae01825eb653b44b046aa0e5ebbb79f76ed4aa11 \ + --hash=sha256:d4d16b608a1c43d7e33142099a75cd93af482dadce0bf82421e91cad077157f4 \ + --hash=sha256:d69fc39e627908f4c03297d5a88d9284b73f4d90b424461e32e8c2485e21c283 \ + --hash=sha256:d9da80e5b04acce03ced8ba6479a71c2a2edf535c2acc0d09c80d2f80f3bad15 \ + --hash=sha256:dd2c7e082b0b92e1baa4da28163a808672485617bc855cc22a2fd06978fa9084 \ + --hash=sha256:de7dac64e3eb832ffc7b840eb8f52f76420cde1b845be51b2a0f6b870890645e \ + --hash=sha256:e0785c2fb4a81e1aece366aa3e2e039f4a4d7d21aaaded5227d7f3c703427882 \ + --hash=sha256:e306d956cfa027fe041585f02a1602c32bfa6bb8ebea4899d373383295a6c62f \ + --hash=sha256:e78fb7419e07d98c2af4b8567b72b3eaf8cb05caad642e9963465569c8b2d87e \ + --hash=sha256:e9002e98dcb1c0a66723592520decd86238ddcef168b37ff6cfb559200b4b774 \ + --hash=sha256:e94cbc6ad9a6aeea46d775cbb11f361022f778a9cc8cc90af653d3a594b057ce \ + --hash=sha256:eea1b54943475f51698f85fa230c65ccac769f1e603b981be060ac5763d90927 \ + --hash=sha256:f100bfe2acf8a3689af9d0cc660d89f17286c9c795f9f18f7b62dd1a6b247ae6 \ + --hash=sha256:f162af66a2ed3f7d1d161a82ca584efd15acd9c1cff190a373458c32f7d42118 \ + --hash=sha256:f24b90b0e0c8cc9491fb1693ae91fe17cb7963153a1946395acdbdd5818429a4 \ + --hash=sha256:f29b68cd9714531672db62cc54f6e8ff981900f824d13fa0e00749189e13778e \ + --hash=sha256:f38bc489037eca88d6ebefc9c4d41a4e07c8e8b4de5188a9e6d290273ad7ebb1 \ + --hash=sha256:f3fd278f5e6bf7c75ccd6d12344eb686cc020712683363b66f46ac79d37c799f \ + --hash=sha256:f4003f70c56a5addd6aa0897f200dd59afd3bf7bcd5b3cce46dd21f925743bc2 \ + --hash=sha256:f48c963a76d71b9d7927eb817b543d0dccd52ab6648b99d37bd54f4cd475d856 \ + --hash=sha256:f819e0c6413e259a17a7c0d49f97f405abadd3c2a316a3b46c6440b7dbbedbb1 \ + --hash=sha256:fc5758e2b7a56532dc33e3c544d78cbaa9ecf0a0f2a2da2df882c1d6b99a317f \ + --hash=sha256:fcbdf2a9ca24e87bbebb47f1fe34e531ef06f104f98c9ccfc953a3f3344c567a # via mypy markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -517,21 +585,21 @@ 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.1 \ + --hash=sha256:001741c6cff56aa8ea59a0d78ae990c0550d0e3e82b00b683eedb4158a8ef7e6 \ + --hash=sha256:01c845825c917c07c1d0b2c9032c59c16a7d383d1e649a46481d3e5693c2750f \ + --hash=sha256:2839024dcd65776abb4759e5bca29941971e095574162a4d335191da4be9ff24 \ + --hash=sha256:3da18cccf2f683c0977bff9146a0908d6ffce836d600665736ac01679f588cb9 \ + --hash=sha256:416e4e01cb88b798e606ee43929df897e42c1647b722ef68283816cca99a8742 \ + --hash=sha256:6b1e5916a253243e8f5f9e847b62bbc98420eec48c9ce2e2e8724c6da89d359b \ + --hash=sha256:72888e87819ce546d0d2df900e4b385e4ef299077d92ee37b48923a5602dae94 \ + --hash=sha256:98b5fcf1a186c217830a8295ecc2989c6b1cf50945417adfc15252107b9475b7 \ + --hash=sha256:9a87ff3b8e4d1c6eac33ebfe8e261e8236516d98d45c0323550621819b5a1a2f \ + --hash=sha256:a2017d2281203d0c6570240e7d746564d766d756105823b7de68bda6ae722711 \ + --hash=sha256:c1490584f3c70af45466ee99065b49e6657ebdccac6b10571bb44681309c9396 \ + --hash=sha256:c6a720b252c99de072922dbe4432ab19662b6f80045b0355fec23bdfccb450da \ + --hash=sha256:dc91031e0619c1e28730279ef9ee5f106c9b9ec806b013f888676b242f892eb7 \ + --hash=sha256:f69093ed4a0e6464e52a7fc26d714f859ce15630ec8070743398c6bf41f38a9e # via # cryptography # pydantic-core @@ -612,9 +680,9 @@ 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 @@ -623,9 +691,9 @@ packaging==26.0 \ # 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 @@ -654,13 +722,13 @@ poetry-core==2.3.2 \ # pkgconfig # rich # tomlkit -pybind11-global==3.0.3 \ - --hash=sha256:141adb150fdb84f6eba3e27241da886f4582574a3d1c30568bf33c1ed3ec8b82 \ - --hash=sha256:7a75ee81e903ea15bdf05db1342c37400751a72316b6620c800b66d70be45632 +pybind11-global==3.0.4 \ + --hash=sha256:95b693c3d646c6b7217a97156a36b6d40305505d4a5a728082da6fe75ada29f5 \ + --hash=sha256:a73e2ebd29f4ee5d7c754b495d555cd703f2cd26c84abe360ee56411dcd7834d # via pybind11 -pybind11==3.0.3 \ - --hash=sha256:00471cdb816882c484708bc5dde80815c8c11cea540ab2cc6410f5ddea434755 \ - --hash=sha256:fb5f8e4a64946b4dcc0451c83a8c384f803bc0a62dd1ba02f199e97dbc9aad4c +pybind11==3.0.4 \ + --hash=sha256:3286b59c8a774b9ee650169302dd5a4eedc30a8617905a0560dd8ee44775130c \ + --hash=sha256:961720ee652da51d531b7b2451a6bd2bc042b0106e6d9baa48ecb7d58034ce63 # via duckdb pycparser==3.0 \ --hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \ @@ -670,12 +738,88 @@ 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 \ @@ -689,7 +833,9 @@ setuptools-git-versioning==3.0.1 \ setuptools-rust==1.12.1 \ --hash=sha256:85ae70989d96c9cfeb5ef79cf3bac2d5200bc5564f720a06edceedbdf6664640 \ --hash=sha256:b7ebd6a182e7aefa97a072e880530c9b0ec8fcca8617e0bb8ff299c1a064f693 - # via maturin + # via + # libcst + # maturin setuptools-scm==10.0.5 \ --hash=sha256:bbba8fe754516cdefd017f4456721775e6ef9662bd7887fb52ae26813d4838c3 \ --hash=sha256:f611037d8aae618221503b8fa89319f073438252ae3420e01c9ceec249131a0a @@ -701,6 +847,7 @@ setuptools-scm==10.0.5 \ # hatch-vcs # httpx-sse # importlib-metadata + # libcst # pluggy # pyarrow # pybindgen @@ -783,6 +930,7 @@ tomli==2.4.1 \ # fastapi-mcp # flit-scm # frozenlist + # hatch-fancy-pypi-readme # hatchling # maturin # meson-python @@ -799,17 +947,17 @@ tomlkit==0.14.0 \ --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 # via uv-dynamic-versioning -trove-classifiers==2026.1.14.14 \ - --hash=sha256:00492545a1402b09d4858605ba190ea33243d361e2b01c9c296ce06b5c3325f3 \ - --hash=sha256:1f9553927f18d0513d8e5ff80ab8980b8202ce37ecae0e3274ed2ef11880e74d +trove-classifiers==2026.4.28.13 \ + --hash=sha256:8f4b1eb4e16296b57d612965444f87a83861cc989a0451ac97fe4265ddef03b8 \ + --hash=sha256:c85bb8a53c3de7330d1699b844ed9fb809a602a09ac15dc79ad6d1a509be0676 # via hatchling types-psutil==7.0.0.20250218 \ --hash=sha256:1447a30c282aafefcf8941ece854e1100eee7b0296a9d9be9977292f0269b121 \ --hash=sha256:1e642cdafe837b240295b23b1cbd4691d80b08a07d29932143cbbae30eb0db9c # via mypy -types-setuptools==82.0.0.20260402 \ - --hash=sha256:4b9a9f6c3c4c65107a3956ad6a6acbccec38e398ff6d5f78d5df7f103dadb8d6 \ - --hash=sha256:63d2b10ba7958396ad79bbc24d2f6311484e452daad4637ffd40407983a27069 +types-setuptools==82.0.0.20260408 \ + --hash=sha256:036c68caf7e672a699f5ebbf914708d40644c14e05298bc49f7272be91cf43d3 \ + --hash=sha256:ece0a215cdfa6463a65fd6f68bd940f39e455729300ddfe61cab1147ed1d2462 # via mypy typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ @@ -833,13 +981,14 @@ versioneer==0.29 \ # 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 # httpx-sse + # libcst # meson # mmh3 # pandas @@ -883,6 +1032,7 @@ setuptools==80.10.2 \ # gunicorn # httpx-sse # importlib-metadata + # libcst # librt # markupsafe # maturin @@ -901,7 +1051,6 @@ setuptools==80.10.2 \ # psycopg # psycopg-c # psycopg-pool - # pyarrow # pyasn1 # pyasn1-modules # pycparser @@ -925,7 +1074,6 @@ setuptools==80.10.2 \ # tqdm # trove-classifiers # typeguard - # types-pymysql # tzdata # ujson # uvloop @@ -944,4 +1092,5 @@ setuptools==82.0.1 \ --hash=sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb # via # python-dateutil + # types-pymysql # types-setuptools diff --git a/sdk/python/requirements/py3.10-minimal-sdist-requirements.txt b/sdk/python/requirements/py3.10-minimal-sdist-requirements.txt index 8b25c5722d1..7248630c0c1 100644 --- a/sdk/python/requirements/py3.10-minimal-sdist-requirements.txt +++ b/sdk/python/requirements/py3.10-minimal-sdist-requirements.txt @@ -208,9 +208,9 @@ 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.4.22 \ + --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ + --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 # via # httpcore # httpx @@ -438,9 +438,9 @@ charset-normalizer==3.4.7 \ # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.3.3 \ + --hash=sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2 \ + --hash=sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 # via # feast (pyproject.toml) # dask @@ -454,56 +454,56 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via feast (pyproject.toml) -cryptography==46.0.6 \ - --hash=sha256:02fad249cb0e090b574e30b276a3da6a149e04ee2f049725b1f69e7b8351ec70 \ - --hash=sha256:063b67749f338ca9c5a0b7fe438a52c25f9526b851e24e6c9310e7195aad3b4d \ - --hash=sha256:12cae594e9473bca1a7aceb90536060643128bb274fcea0fc459ab90f7d1ae7a \ - --hash=sha256:12f0fa16cc247b13c43d56d7b35287ff1569b5b1f4c5e87e92cc4fcc00cd10c0 \ - --hash=sha256:22259338084d6ae497a19bae5d4c66b7ca1387d3264d1c2c0e72d9e9b6a77b97 \ - --hash=sha256:26031f1e5ca62fcb9d1fcb34b2b60b390d1aacaa15dc8b895a9ed00968b97b30 \ - --hash=sha256:27550628a518c5c6c903d84f637fbecf287f6cb9ced3804838a1295dc1fd0759 \ - --hash=sha256:2b417edbe8877cda9022dde3a008e2deb50be9c407eef034aeeb3a8b11d9db3c \ - --hash=sha256:2ea0f37e9a9cf0df2952893ad145fd9627d326a59daec9b0802480fa3bcd2ead \ - --hash=sha256:2ef9e69886cbb137c2aef9772c2e7138dc581fad4fcbcf13cc181eb5a3ab6275 \ - --hash=sha256:341359d6c9e68834e204ceaf25936dffeafea3829ab80e9503860dcc4f4dac58 \ - --hash=sha256:380343e0653b1c9d7e1f55b52aaa2dbb2fdf2730088d48c43ca1c7c0abb7cc2f \ - --hash=sha256:3c21d92ed15e9cfc6eb64c1f5a0326db22ca9c2566ca46d845119b45b4400361 \ - --hash=sha256:3dfa6567f2e9e4c5dceb8ccb5a708158a2a871052fa75c8b78cb0977063f1507 \ - --hash=sha256:456b3215172aeefb9284550b162801d62f5f264a081049a3e94307fe20792cfa \ - --hash=sha256:4668298aef7cddeaf5c6ecc244c2302a2b8e40f384255505c22875eebb47888b \ - --hash=sha256:50575a76e2951fe7dbd1f56d181f8c5ceeeb075e9ff88e7ad997d2f42af06e7b \ - --hash=sha256:639301950939d844a9e1c4464d7e07f902fe9a7f6b215bb0d4f28584729935d8 \ - --hash=sha256:64235194bad039a10bb6d2d930ab3323baaec67e2ce36215fd0952fad0930ca8 \ - --hash=sha256:6617f67b1606dfd9fe4dbfa354a9508d4a6d37afe30306fe6c101b7ce3274b72 \ - --hash=sha256:67177e8a9f421aa2d3a170c3e56eca4e0128883cf52a071a7cbf53297f18b175 \ - --hash=sha256:6728c49e3b2c180ef26f8e9f0a883a2c585638db64cf265b49c9ba10652d430e \ - --hash=sha256:6739d56300662c468fddb0e5e291f9b4d084bead381667b9e654c7dd81705124 \ - --hash=sha256:69cf0056d6947edc6e6760e5f17afe4bea06b56a9ac8a06de9d2bd6b532d4f3a \ - --hash=sha256:760997a4b950ff00d418398ad73fbc91aa2894b5c1db7ccb45b4f68b42a63b3c \ - --hash=sha256:79e865c642cfc5c0b3eb12af83c35c5aeff4fa5c672dc28c43721c2c9fdd2f0f \ - --hash=sha256:7e6142674f2a9291463e5e150090b95a8519b2fb6e6aaec8917dd8d094ce750d \ - --hash=sha256:7f417f034f91dcec1cb6c5c35b07cdbb2ef262557f701b4ecd803ee8cefed4f4 \ - --hash=sha256:7f6690b6c55e9c5332c0b59b9c8a3fb232ebf059094c17f9019a51e9827df91c \ - --hash=sha256:8927ccfbe967c7df312ade694f987e7e9e22b2425976ddbf28271d7e58845290 \ - --hash=sha256:8ce35b77aaf02f3b59c90b2c8a05c73bac12cea5b4e8f3fbece1f5fddea5f0ca \ - --hash=sha256:8e7304c4f4e9490e11efe56af6713983460ee0780f16c63f219984dab3af9d2d \ - --hash=sha256:90e5f0a7b3be5f40c3a0a0eafb32c681d8d2c181fc2a1bdabe9b3f611d9f6b1a \ - --hash=sha256:97c8115b27e19e592a05c45d0dd89c57f81f841cc9880e353e0d3bf25b2139ed \ - --hash=sha256:9a693028b9cbe51b5a1136232ee8f2bc242e4e19d456ded3fa7c86e43c713b4a \ - --hash=sha256:9a9c42a2723999a710445bc0d974e345c32adfd8d2fac6d8a251fa829ad31cfb \ - --hash=sha256:a3e84d5ec9ba01f8fd03802b2147ba77f0c8f2617b2aff254cedd551844209c8 \ - --hash=sha256:aad75154a7ac9039936d50cf431719a2f8d4ed3d3c277ac03f3339ded1a5e707 \ - --hash=sha256:b12c6b1e1651e42ab5de8b1e00dc3b6354fdfd778e7fa60541ddacc27cd21410 \ - --hash=sha256:b928a3ca837c77a10e81a814a693f2295200adb3352395fad024559b7be7a736 \ - --hash=sha256:bcb87663e1f7b075e48c3be3ecb5f0b46c8fc50b50a97cf264e7f60242dca3f2 \ - --hash=sha256:c797e2517cb7880f8297e2c0f43bb910e91381339336f75d2c1c2cbf811b70b4 \ - --hash=sha256:c89eb37fae9216985d8734c1afd172ba4927f5a05cfd9bf0e4863c6d5465b013 \ - --hash=sha256:cdcd3edcbc5d55757e5f5f3d330dd00007ae463a7e7aa5bf132d1f22a4b62b19 \ - --hash=sha256:d24c13369e856b94892a89ddf70b332e0b70ad4a5c43cf3e9cb71d6d7ffa1f7b \ - --hash=sha256:d4e4aadb7fc1f88687f47ca20bb7227981b03afaae69287029da08096853b738 \ - --hash=sha256:d9528b535a6c4f8ff37847144b8986a9a143585f0540fbcb1a98115b543aa463 \ - --hash=sha256:ed3775295fb91f70b4027aeba878d79b3e55c0b3e97eaa4de71f8f23a9f2eb77 \ - --hash=sha256:ed418c37d095aeddf5336898a132fba01091f0ac5844e3e8018506f014b6d2c4 +cryptography==47.0.0 \ + --hash=sha256:0024b87d47ae2399165a6bfb20d24888881eeab83ae2566d62467c5ff0030ce7 \ + --hash=sha256:07efe86201817e7d3c18781ca9770bc0db04e1e48c994be384e4602bc38f8f27 \ + --hash=sha256:09f6d7bf6724f8db8b32f11eccf23efc8e759924bc5603800335cf8859a3ddbd \ + --hash=sha256:11438c7518132d95f354fa01a4aa2f806d172a061a7bed18cf18cbdacdb204d7 \ + --hash=sha256:11dbb9f50a0f1bb9757b3d8c27c1101780efb8f0bdecfb12439c22a74d64c001 \ + --hash=sha256:14432c8a9bcb37009784f9594a62fae211a2ae9543e96c92b2a8e4c3cd5cd0c4 \ + --hash=sha256:1581aef4219f7ca2849d0250edaa3866212fb74bf5667284f46aa92f9e65c1ca \ + --hash=sha256:160ad728f128972d362e714054f6ba0067cab7fb350c5202a9ae8ae4ce3ef1a0 \ + --hash=sha256:1a405c08857258c11016777e11c02bacbe7ef596faf259305d282272a3a05cbe \ + --hash=sha256:1e47422b5557bb82d3fff997e8d92cff4e28b9789576984f08c248d2b3535d93 \ + --hash=sha256:20fdbe3e38fb67c385d233c89371fa27f9909f6ebca1cecc20c13518dae65475 \ + --hash=sha256:2207a498b03275d0051589e326b79d4cf59985c99031b05bb292ac52631c37fe \ + --hash=sha256:256d07c78a04d6b276f5df935a9923275f53bd1522f214447fdf365494e2d515 \ + --hash=sha256:2b45761c6ec22b7c726d6a829558777e32d0f1c8be7c3f3480f9c912d5ee8a10 \ + --hash=sha256:2ebd84adf0728c039a3be2700289378e1c164afc6748df1a5ed456767bef9ba7 \ + --hash=sha256:34b4358b925a5ea3e14384ca781a2c0ef7ac219b57bb9eacc4457078e2b19f92 \ + --hash=sha256:3fb8fa48075fad7193f2e5496135c6a76ac4b2aa5a38433df0a539296b377829 \ + --hash=sha256:4e1de79e047e25d6e9f8cea71c86b4a53aced64134f0f003bbcbf3655fd172c8 \ + --hash=sha256:4f7722c97826770bab8ae92959a2e7b20a5e9e9bf4deae68fd86c3ca457bab52 \ + --hash=sha256:51c9313e90bd1690ec5a75ed047c27c0b8e6c570029712943d6116ef9a90620b \ + --hash=sha256:5d0e362ff51041b0c0d219cc7d6924d7b8996f57ce5712bdcef71eb3c65a59cc \ + --hash=sha256:6651d32eff255423503aa276739da98c30f26c40cbeffcc6048e0d54ef704c0c \ + --hash=sha256:6eebcaf0df1d21ce1f90605c9b432dd2c4f4ab665ac29a40d5e3fc68f51b5e63 \ + --hash=sha256:6f29f36582e6151d9686235e586dd35bb67491f024767d10b842e520dc6a07ac \ + --hash=sha256:7a02675e2fabd0c0fc04c868b8781863cbf1967691543c22f5470500ff840b31 \ + --hash=sha256:7f1207974a904e005f762869996cf620e9bf79ecb4622f148550bb48e0eb35a7 \ + --hash=sha256:7f68d6fbc7fbbcfb0939fea72c3b96a9f9a6edfc0e1b1d29778a2066030418b1 \ + --hash=sha256:7fda2f02c9015db3f42bb8a22324a454516ed10a8c29ca6ece6cdbb5efe2a203 \ + --hash=sha256:80887c5cbd1774683cb126f0ab4184567f080071d5acf62205acb354b4b753b7 \ + --hash=sha256:835d2d7f47cdc53b3224e90810fb1d36ca94ea29cc1801fb4c1bc43876735769 \ + --hash=sha256:8c1a736bbb3288005796c3f7ccb9453360d7fed483b13b9f468aea5171432923 \ + --hash=sha256:9af828c0d5a65c70ec729cd7495a4bf1a67ecb66417b8f02ff125ab8a6326a74 \ + --hash=sha256:9c59ab0e0fa3a180a5a9c59f3a5abe3ef90d474bc56d7fadfbe80359491b615b \ + --hash=sha256:9f8e55fe4e63613a5e1cc5819030f27b97742d720203a087802ce4ce9ceb52bb \ + --hash=sha256:9fe6b7c64926c765f9dff301f9c1b867febcda5768868ca084e18589113732ab \ + --hash=sha256:a49a3eb5341b9503fa3000a9a0db033161db90d47285291f53c2a9d2cd1b7f76 \ + --hash=sha256:a9b761f012a943b7de0e828843c5688d0de94a0578d44d6c85a1bae32f87791f \ + --hash=sha256:b1c76fca783aa7698eb21eb14f9c4aa09452248ee54a627d125025a43f83e7a7 \ + --hash=sha256:b9a8943e359b7615db1a3ba587994618e094ff3d6fa5a390c73d079ce18b3973 \ + --hash=sha256:be12cb6a204f77ed968bcefe68086eb061695b540a3dd05edac507a3111b25f0 \ + --hash=sha256:cffbba3392df0fa8629bb7f43454ee2925059ee158e23c54620b9063912b86c8 \ + --hash=sha256:ed67ea4e0cfb5faa5bc7ecb6e2b8838f3807a03758eec239d6c21c8769355310 \ + --hash=sha256:edd4da498015da5b9f26d38d3bfc2e90257bfa9cbed1f6767c282a0025ae649b \ + --hash=sha256:ef6b3634087f18d2155b1e8ce264e5345a753da2c5fa9815e7d41315c90f8318 \ + --hash=sha256:f1557695e5c2b86e204f6ce9470497848634100787935ab7adc5397c54abd7ab \ + --hash=sha256:f5c15764f261394b22aef6b00252f5195f46f2ca300bec57149474e2538b31f8 \ + --hash=sha256:f5c3296dab66202f1b18a91fa266be93d6aa0c2806ea3d67762c69f60adc71aa \ + --hash=sha256:f7db373287273d8af1414cf95dc4118b13ffdc62be521997b0f2b270771fef50 \ + --hash=sha256:f9a034b642b960767fb343766ae5ba6ad653f2e890ddd82955aef288ffea8736 # via # google-auth # pyjwt @@ -593,42 +593,42 @@ docutils==0.21.2 \ --hash=sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f \ --hash=sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2 # via sphinx -duckdb==1.5.1 \ - --hash=sha256:054ad424b051b334052afac58cb216f3b1ebb8579fc8c641e60f0182e8725ea9 \ - --hash=sha256:05fc91767d0cfc4cf2fa68966ab5b479ac07561752e42dd0ae30327bd160f64a \ - --hash=sha256:0a6acc2040bec1f05de62a2f3f68f4c12f3ec7d6012b4317d0ab1a195af26225 \ - --hash=sha256:26e56b5f0c96189e3288d83cf7b476e23615987902f801e5788dee15ee9f24a9 \ - --hash=sha256:36e8e32621a9e2a9abe75dc15a4b54a3997f2d8b1e53ad754bae48a083c91130 \ - --hash=sha256:40c5220ec93790b18ec6278da9c6ac2608d997ee6d6f7cd44c5c3992764e8e71 \ - --hash=sha256:446d500a2977c6ae2077f340c510a25956da5c77597175c316edfa87248ceda3 \ - --hash=sha256:46f92ada9023e59f27edc048167b31ac9a03911978b1296c845a34462a27f096 \ - --hash=sha256:482f8a13f2600f527e427f73c42b5aa75536f9892868068f0aaf573055a0135f \ - --hash=sha256:553c273a6a8f140adaa6da6a6135c7f95bdc8c2e5f95252fcdf9832d758e2141 \ - --hash=sha256:5ae7c0d744d64e2753149634787cc4ab60f05ef1e542b060eeab719f3cdb7723 \ - --hash=sha256:5d4147422d91ccdc2d2abf6ed24196025e020259d1d267970ae20c13c2ce84b1 \ - --hash=sha256:6af347debc8b721aa72e48671166282da979d5e5ae52dbc660ab417282b48e23 \ - --hash=sha256:6ba302115f63f6482c000ccfd62efdb6c41d9d182a5bcd4a90e7ab8cd13856eb \ - --hash=sha256:6f7361d66cc801d9eb4df734b139cd7b0e3c257a16f3573ebd550ddb255549e6 \ - --hash=sha256:715f05ea198d20d7f8b407b9b84e0023d17f2b9096c194cea702b7840e74f1f7 \ - --hash=sha256:71dddcebbc5a70e946a06c30b59b5dd7999c9833d307168f90fb4e4b672ab63e \ - --hash=sha256:8150c569b2aa4573b51ba8475e814aa41fd53a3d510c1ffb96f1139f46faf611 \ - --hash=sha256:8843bd9594e1387f1e601439e19ad73abdf57356104fd1e53a708255bb95a13d \ - --hash=sha256:8c0088765747ae5d6c9f89987bb36f9fb83564f07090d721344ce8e1abedffea \ - --hash=sha256:972d0dbf283508f9bc446ee09c3838cb7c7f114b5bdceee41753288c97fe2f7c \ - --hash=sha256:a28531cee2a5a42d89f9ba4da53bfeb15681f12acc0263476c8705380dadce07 \ - --hash=sha256:a3be2072315982e232bfe49c9d3db0a59ba67b2240a537ef42656cc772a887c7 \ - --hash=sha256:ac2804043bd1bc10b5da18f8f4c706877197263a510c41be9b4c0062f5783dcc \ - --hash=sha256:afab8b4b1f4469c3879bb049dd039f8fce402712050324e9524a43d7324c5e87 \ - --hash=sha256:b370d1620a34a4538ef66524fcee9de8171fa263c701036a92bc0b4c1f2f9c6d \ - --hash=sha256:b8b0808dba0c63b7633bdaefb34e08fe0612622224f9feb0e7518904b1615101 \ - --hash=sha256:bc7ca6a1a40e7e4c933017e6c09ef18032add793df4e42624c6c0c87e0bebdad \ - --hash=sha256:caa65e1f5bf007430bf657c37cab7ab81a4ddf8d337e3062bcc5085d17ef038b \ - --hash=sha256:d68c5a01a283cb13b79eafe016fe5869aa11bff8c46e7141c70aa0aac808010f \ - --hash=sha256:da137802688190835b4c863cafa77fd7e29dff662ee6d905a9ffc14f00299c91 \ - --hash=sha256:e56a20ab6cdb90a95b0c99652e28de3504ce77129087319c03c9098266183ae5 \ - --hash=sha256:e878ccb7d20872065e1597935fdb5e65efa43220c8edd0d9c4a1a7ff1f3eb277 \ - --hash=sha256:eba81e0b3011c1f23df7ea47ef4ffaa8239817959ae291515b6efd068bde2161 \ - --hash=sha256:ed6d23a3f806898e69c77430ebd8da0c79c219f97b9acbc9a29a653e09740c59 +duckdb==1.5.2 \ + --hash=sha256:0b291786014df1133f8f18b9df4d004484613146e858d71a21791e0fcca16cf4 \ + --hash=sha256:2323c1195c10fb2bb982fc0218c730b43d1b92a355d61e68e3c5f3ac9d44c34f \ + --hash=sha256:2a1de4f4d454b8c97aec546c82003fc834d3422ce4bc6a19902f3462ef293bed \ + --hash=sha256:35579b8e3a064b5eaf15b0eafc558056a13f79a0a62e34cc4baf57119daecfec \ + --hash=sha256:376856066c65ccd55fcb3a380bbe33a71ce089fc4623d229ffc6e82251afdb6d \ + --hash=sha256:411ad438bd4140f189a10e7f515781335962c5d18bd07837dc6d202e3985253d \ + --hash=sha256:4420b3f47027a7849d0e1815532007f377fa95ee5810b47ea717d35525c12f79 \ + --hash=sha256:486c862bf7f163c0110b6d85b3e5c031d224a671cca468f12ebb1d3a348f6b39 \ + --hash=sha256:52a21823f3fbb52f0f0e5425e20b07391ad882464b955879499b5ff0b45a376b \ + --hash=sha256:5596bbfc31b1b259db69c8d847b42d036ce2c4804f9ccb28f9fc46a16de7bc53 \ + --hash=sha256:56d38b3c4e0ef2abb58898d0fd423933999ed535c45e75e9d9f72e1d5fed69b8 \ + --hash=sha256:638da0d5102b6cb6f7d47f83d0600708ac1d3cb46c5e9aaabc845f9ba4d69246 \ + --hash=sha256:63bf8687feefeed51adf45fa3b062ab8b1b1c350492b7518491b86bae68b1da1 \ + --hash=sha256:6b0fe75c148000f060aa1a27b293cacc0ea08cc1cad724fbf2143d56070a3785 \ + --hash=sha256:70631c847ca918ee710ec874241b00cf9d2e5be90762cbb2a0389f17823c08f7 \ + --hash=sha256:7f69164b048e498b9e9140a24343108a5ae5f17bfb3485185f55fdf9b1aa924d \ + --hash=sha256:81fc4fbf0b5e25840b39ba2a10b78c6953c0314d5d0434191e7898f34ab1bba3 \ + --hash=sha256:84b193aca20565dedb3172de15f843c659c3a6c773bf14843a9bd781c850e7db \ + --hash=sha256:8d599758b4e48bf12e18c9b960cf491d219f0c4972d19a45489c05cc5ab36f83 \ + --hash=sha256:8dbd7e31e5dc157bfe8803fa7d2652336265c6c19926c5a4a9b40f8222868d08 \ + --hash=sha256:98c0535cd6d901f61a5ea3c2e26a1fd28482953d794deb183daf568e3aa5dda6 \ + --hash=sha256:a9cd5e71702d446613750405cde03f66ed268f4c321da071b0472759dad19536 \ + --hash=sha256:bb42e6ed543902e14eae647850da24103a89f0bc2587dec5601b1c1f213bd2ed \ + --hash=sha256:be37680ddb380015cb37318e378c53511c45c4f0d8fac5599d22b7d092b9217a \ + --hash=sha256:c69907354ffee94ba8cf782daf0480dab7557f21ce27fffa6c0ea8f74ed4b8e2 \ + --hash=sha256:c99ef73a277c8921bc0a1f16dee38d924484251d9cfd20951748c20fcd5ed855 \ + --hash=sha256:c9f3e0b71b8a50fccfb42794899285d9d318ce2503782b9dd54868e5ecd0ad31 \ + --hash=sha256:ce0b8141a10d37ecef729c45bc41d334854013f4389f1488bd6035c5579aaac1 \ + --hash=sha256:ce17670bb392ea1b3650537db02bd720908776b5b95f6d2472d31a7de59d1dc1 \ + --hash=sha256:d72b8856b1839d35648f38301b058f6232f4d36b463fe4dc8f4d3fdff2df1a2e \ + --hash=sha256:d9b4f5430bf4f05d4c0dc4c55c75def3a5af4be0343be20fa2bfc577343fbfc9 \ + --hash=sha256:e6495b00cad16888384119842797c49316a96ae1cb132bb03856d980d95afee1 \ + --hash=sha256:ea58ff5b0880593a280cf5511734b17711b32ee1f58b47d726e8600848358160 \ + --hash=sha256:ef461bca07313412dc09961c4a4757a851f56b95ac01c58fac6007632b7b94f2 \ + --hash=sha256:fc85a5dbcbe6eccac1113c72370d1d3aacfdd49198d63950bdf7d8638a307f00 # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ @@ -640,9 +640,9 @@ exceptiongroup==1.3.1 \ # via # anyio # scikit-build-core -fastapi==0.135.3 \ - --hash=sha256:9b0f590c813acd13d0ab43dd8494138eb58e484bfac405db1f3187cfc5810d98 \ - --hash=sha256:bd6d7caf1a2bdd8d676843cdcd2287729572a1ef524fc4d65c17ae002a1be654 +fastapi==0.136.1 \ + --hash=sha256:7af665ad7acfa0a3baf8983d393b6b471b9da10ede59c60045f49fbc89a0fa7f \ + --hash=sha256:a6e9d7eeada96c93a4d69cb03836b44fa34e2854accb7244a1ece36cd4781c3f # via # feast (pyproject.toml) # fastapi-mcp @@ -650,9 +650,9 @@ fastapi-mcp==0.4.0 \ --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d # via feast (pyproject.toml) -filelock==3.25.2 \ - --hash=sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694 \ - --hash=sha256:ca8afb0da15f229774c9ad1b455ed96e85a81373065fb10446672f64444ddf70 +filelock==3.29.0 \ + --hash=sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90 \ + --hash=sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258 # via snowflake-connector-python flit-core==3.12.0 \ --hash=sha256:18f63100d6f94385c6ed57a72073443e1a71a4acb4339491615d0f16d6ff01b2 \ @@ -798,9 +798,9 @@ fsspec==2024.9.0 \ # via # feast (pyproject.toml) # dask -google-api-core[grpc]==2.30.2 \ - --hash=sha256:9a8113e1a88bdc09a7ff629707f2214d98d61c7f6ceb0ea38c42a095d02dc0f9 \ - --hash=sha256:a4c226766d6af2580577db1f1a51bf53cd262f722b49731ce7414c43068a9594 +google-api-core[grpc]==2.30.3 \ + --hash=sha256:a85761ba72c444dad5d611c2220633480b2b6be2521eca69cca2dbb3ffd6bfe8 \ + --hash=sha256:e601a37f148585319b26db36e219df68c5d07b6382cff2d580e83404e44d641b # via # feast (pyproject.toml) # google-cloud-bigquery @@ -810,9 +810,9 @@ google-api-core[grpc]==2.30.2 \ # google-cloud-datastore # google-cloud-storage # pandas-gbq -google-auth==2.49.1 \ - --hash=sha256:16d40da1c3c5a0533f57d268fe72e0ebb0ae1cc3b567024122651c045d879b64 \ - --hash=sha256:195ebe3dca18eddd1b3db5edc5189b76c13e96f29e73043b923ebcf3f1a860f7 +google-auth==2.50.0 \ + --hash=sha256:04382175e28b94f49694977f0a792688b59a668def1499e9d8de996dc9ce5b15 \ + --hash=sha256:f35eafb191195328e8ce10a7883970877e7aeb49c2bfaa54aa0e394316d353d0 # via # google-api-core # google-auth-oauthlib @@ -912,60 +912,66 @@ googleapis-common-protos[grpc]==1.74.0 \ # 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.0 \ + --hash=sha256:0ecec963079cd58cbd14723582384f11f166fd58883c15dcbfb342e0bc9b5846 \ + --hash=sha256:0ed006e4b86c59de7467eb2601cd1b77b5a7d657d1ee55e30fe30d76451edba4 \ + --hash=sha256:0ff251e9a0279522e62f6176412869395a64ddf2b5c5f782ff609a8216a4e662 \ + --hash=sha256:1aa4ce8debcd4ea7fb2e150f3036588c41493d1d52c43538924ae1819003f4ce \ + --hash=sha256:1bae92a1dd94c5f9d9493c3a212dd874c202442047cf96446412c862feca83a2 \ + --hash=sha256:1eb67d5adefb5bd2e182d42678a328979a209e4e82eb93575708185d31d1f588 \ + --hash=sha256:2094acd54b272cb6eae8c03dd87b3fa1820a4cef18d6889c378d503500a1dc13 \ + --hash=sha256:2628d6c86f6cb0cb45e0c3c54058bbec559f57eaae699447748cb3928150577e \ + --hash=sha256:29ea813b2e1f45fa9649a17853b2b5465c4072fbcb072e5af6cd3a288216574a \ + --hash=sha256:362624e6a8e5bca3b8233e45eef33903a100e9539a2b995c364d595dbc4018b3 \ + --hash=sha256:3a717fbc46d8a354fa675f7c1e813485b6ba3885f9bef0cd56e5ba27d758ff5b \ + --hash=sha256:3bc59be3945ae9750b9e7d45067d01ae3fe90ea5f9ade99239dabdd6e28a5033 \ + --hash=sha256:3ec9ea74e7268ace7f9aab1b1a4e730193fc661b39a993cd91c606c32d4a3628 \ + --hash=sha256:41353ec2ecedf7aa8f682753a41919f8718031a6edac46b8d3dc7ed9e1ceb136 \ + --hash=sha256:47422135b1d308c14b2c6e758beedb1acd33bb91679f5670edf77bf46244722b \ + --hash=sha256:4964101b8585c144cbda5532b1aa644255126c08a265dae90c16e7a0e63aaa9d \ + --hash=sha256:4a448128607be0de65342dc9b31be7f948ef4cc0bc8832069350abefd310a8f2 \ + --hash=sha256:4b28037cb07768933c54d81bfe47a85f9f402f57d7d69743b991a713b63954eb \ + --hash=sha256:4d0eadc7e4d9ffb2af4247b606cae307be8e448911e5a0d0b16d72fc3d224cfd \ + --hash=sha256:54d243512da35485fc7a6bf3c178fdda6327a9d6506fcdd62b1abd1e41b2927b \ + --hash=sha256:55fa7ea52771be44af0de27d8b80c02cd18c2c3cddde6c847ecebdf72418b6a1 \ + --hash=sha256:57a43c6079a89713522bc4bcb9f75070ecf5d3dbad7792bfe42239362cbf2a16 \ + --hash=sha256:58c1c374fe2b3d852f9b6b11a7dff4c85404e51b9a596fd9e89cf904eb09866d \ + --hash=sha256:5a5ed18de6a0f6cc7087f1563f6bd93fc7df1c19165ca01e9bde5a5dc281d106 \ + --hash=sha256:5e05ba267789ea87b5a155cf0e810b1ab88bf18e9e8740813945ceb8ee4350ba \ + --hash=sha256:5ecd83806b0f4c2f53b1018e0005cd82269ea01d42befc0368730028d850ed1c \ + --hash=sha256:64d6ac45f7271f48e45f67c95b54ef73534c52ec041fcda8edf520c6d811f4bc \ + --hash=sha256:680bd0e7ad5e8daa8a4aa89f68fd6adc834b8a8036dc256533f7e08f4a4b01f7 \ + --hash=sha256:6c18dfb59c70f5a94acd271c72e90128c3c776e41e5f07767908c8c1b74ad339 \ + --hash=sha256:6d874e79afd41a96e11ff4c5d0bc90a80973e476fda1c2c64985667397df432b \ + --hash=sha256:7022615368890680e67b9965d33f5773aade330d5343bbe25560135aaa849eae \ + --hash=sha256:703cb211b820dbffbbc55a16bfc6e4583a6e6e990f33a119d2cc8b83211119c8 \ + --hash=sha256:728a73687e39ae9ca34e4694cbf2f049d3fbc7174639468d0f67200a97d8f9e2 \ + --hash=sha256:728d9667d8f2f586644b748dbd9bb67e50d6a9381767d1357714ea6825bb3bf5 \ + --hash=sha256:762612baf1161ccb8437c0161c668a688223cba28e1bf038f4eb47b13e39ccdf \ + --hash=sha256:7fc391b1566f2907d17aaebe78f8855dc45675159a775fcf9e61f8ee0078e87f \ + --hash=sha256:804a70b328e706b785c6ef16187051c394a63dd1a906d89be24b6ad77759f13f \ + --hash=sha256:83ed9f27f1680b50e89f40f6df348a290ea234b249a4003d366663a12eab94f2 \ + --hash=sha256:884f649de075b84739713d41dd4dfd41e2b910bfb769c4a3ea02ec1da52cd9bb \ + --hash=sha256:8f1cc966c126639cd152fdaa52624d2655f492faa79e013fea161de3e6dda082 \ + --hash=sha256:8f52a464e4ed91780bdfbbdd2b97197f3accaa629b98c200f4dffada759f3ae7 \ + --hash=sha256:9c615f869163e14bb1ced20322d8038fb680b08236521ac3f30cd4c1288785a0 \ + --hash=sha256:9d280a7f5c331622c69f97eb167f33577ff2d1df282c41cd15907fc0a3ca198c \ + --hash=sha256:a10a732421ab4fec934783ce3e54763470d0181db6e3468f9103a275c3ed1853 \ + --hash=sha256:a96fcee45e03fe30a62669fd16ab5c9d3c172660d3085605cb1e2d1280d3c988 \ + --hash=sha256:a97e4821aa710603f94de0da25f25096454d78ffdace5dc77f3a006bc01abba3 \ + --hash=sha256:ba8f0bdc2fae6ce915dfd0c16d2d00bca7e4247c1eae4416e06430e522137858 \ + --hash=sha256:bf2d8a80bec89ab46221ae45c5373d5ba0bd36c19aa8508e85c6cd7e5106cd37 \ + --hash=sha256:cda05425526240807408156b6960a17a79a0c760b813573b67027823be760977 \ + --hash=sha256:d419647372241bc68e957bf38d5c1f98852155e4146bd1e4121adea81f4f01e4 \ + --hash=sha256:d4d9f0624c775f2dfc56ba54d515a8c771044346852a918b405914f6b19d7fd8 \ + --hash=sha256:d60097128cb0a1cab9ea541186ea13cd7b847b8449a7787c2e2350da0cb82d86 \ + --hash=sha256:db2910d3c809444e0a20147361f343fe2798e106af8d9d8506f5305302655a9f \ + --hash=sha256:ddb36c7d6c9c0a65f18c7258634e0c416c6ab59caac8c987b96f80c2ebda0112 \ + --hash=sha256:ddc090c5c1792b10246a78e8c2163ebbe04cf877f9d785c230a7b27b39ad038e \ + --hash=sha256:e5ddf316ced87539144621453c3aef229575825fe60c604e62bedc4003f372b2 \ + --hash=sha256:f35807464c4c58c55f0d31dfa83c541a5615d825c2fe3d2b95360cf7c4e3c0a8 \ + --hash=sha256:f8c30c2225f40dd76c50790f0eb3b5c7c18431efb299e2782083e1981feed243 \ + --hash=sha256:fa94cb2288681e3a11645958f1871d48ee9211bd2f66628fdace505927d6e564 # via feast (pyproject.toml) grpc-google-iam-v1==0.14.4 \ --hash=sha256:392b3796947ed6334e61171d9ab06bf7eb357f554e5fc7556ad7aab6d0e17038 \ @@ -1077,101 +1083,112 @@ hatchling==1.29.0 \ # 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.3.1 \ + --hash=sha256:002fc0201b9af1cc8960e27cdc501ad1f8cdd6dbadb2091c6ddbd4e5ace6cb77 \ + --hash=sha256:011a9071c3df4885cac7f58a2623feac6c8e2ad30e6ba93c55195af05ce61ff5 \ + --hash=sha256:01cf82a514bc4fd145b99333c28523e61b7a9ad051a245804323ebf4e7b1c6a6 \ + --hash=sha256:027ce4fabfeff5af5b9869d5524770877f9061d118bc36b85703ae3faf5aad8e \ + --hash=sha256:03baa381964b8df356d19ec4e3a6ae656044249a87b0def257fe1e08dbaf6094 \ + --hash=sha256:042e57de8a2cae91e3e7c0af32960ea2c5107b2f27f68a740295861e68780a8a \ + --hash=sha256:09d41a3a965f7c261223d516ebda607aee4d8440dd7637f01af9a4c05872f0c4 \ + --hash=sha256:09f5e510f637f2c72d2a79fb3ad05f7b6211e057e367ca5c4f97bb3d8c9d71f4 \ + --hash=sha256:0b5ff2f643f4b452b0597b7fe6aa35d398cb31d8806801acfafb1558610ea2aa \ + --hash=sha256:0caf3fc8af0767794b335753781c3fa35f2a3e975c098edbc8f733d35d6a95e4 \ + --hash=sha256:0fac4af8515e6cca74fc701169ae4dc9a71a90e9319c9d21006ec9454b43aa2f \ + --hash=sha256:113e098e4a6b3cc5500e05e7cb1548ba9e83de5fe755941b11f6020a76e6c03a \ + --hash=sha256:137c14905ea6f2933967200bc7b2a0c8ec9387888b273fd0004f25b994fd0343 \ + --hash=sha256:156be6a0c736ee145cfe0fb155d0e96cec8d4872cf8b4f76ad6a2ee6ab391d0a \ + --hash=sha256:17ec8b524055a88b80d76c177dbbbe475a25c17c5bf4b67bdbdbd0629bcae838 \ + --hash=sha256:1ac7697365dbe45109273b34227fee6826b276ead9a4a007e0877e1d3f0fcf21 \ + --hash=sha256:1b46e96b50dad03495447860510daebd2c96fd44ed25ba8ccb03e9f89eaa9d34 \ + --hash=sha256:1ebc307a87b099d0877dbd2bdc0bae427258e7ec67f60a951e89027f8dc2568f \ + --hash=sha256:1f7bceb03a1b934872ffe3942eaeed7c7e09096e67b53f095b81f39c7a819113 \ + --hash=sha256:2611bfaaadc5e8d43fb7967f9bbf1110c8beaa83aee2f2d812c76f11cfb56c6a \ + --hash=sha256:264ee7e9cb6c30dc78da4ecf71d74cf14ca122817c665d838eda8b4384bce1b0 \ + --hash=sha256:26f899cde0279e4b7d370716ff80320601c2bd93cdf3e774a42bdd44f65b41f8 \ + --hash=sha256:29fe35e3c6fe03204e75c86514f452591957a1e06b05d86e10d795455b71c355 \ + --hash=sha256:2afc675b831f7552da41116fffffca4340f387dc03f56d6ec0c7895ab0b59a10 \ + --hash=sha256:2b6da6e07359107c653a809b3cff2d9ccaeedbafe33c6f16434aef6f53ce4a2b \ + --hash=sha256:2b96da7e365d6488d2a75266a662cbe3cc14b28c23dd9b0c9aa04b5bc5c20192 \ + --hash=sha256:2f1c1b2e8f00b71e6214234d313f655a3a27cd4384b054126ce04073c1d47045 \ + --hash=sha256:304481241e081bc26f0778b2c2b99f9c43917e4e724a016dcc9439b7ab12c726 \ + --hash=sha256:318f772dd321404075d406825266e574ee0f4751be1831424c2ebd5722609398 \ + --hash=sha256:3586c8a5f56d34b9dddaaa9e76905f31933cac267251006adf86ec0eef7d0400 \ + --hash=sha256:3724f0e58c6ff76fd683429945491de71324ab1bc0ad943a8d68cb0932d24075 \ + --hash=sha256:3fb6573efa15a29c12c0c0f7170b14e7c1347fe4bb39b6a15b779f46015cc929 \ + --hash=sha256:40ae8a7041fcb328a6bc7202d8c4e6e0d38d434b2e3880b1ee8ed754f17cd836 \ + --hash=sha256:4106201cd052d9eabe3cb7b5a24b0fe37307792bda4fcb3cf6ddd72f697828e8 \ + --hash=sha256:439f9a5cc8f9519ce208a24cdebfa0440fef26aa682a40ba2c92acb10a53f5e0 \ + --hash=sha256:4479e36d263251dba8ab8ea81adf07e7f1163603c7102c5de1e130b83b4fad3b \ + --hash=sha256:487658e1db83c1ee9fbbac6a43039ea76957767a5987ffb16b590613f9e68297 \ + --hash=sha256:48ff424f8aa36aacd9fdaa68efeb27d2e8771f293af4305bdb15d92194ca6631 \ + --hash=sha256:4f7e242eab698ad0be5a4b2ec616fa856569c57455cc67c625fd567726290e5f \ + --hash=sha256:526db52e5234a9463520e960a509d6c1bd5128d1ab1b569cbf459fe39189e8ab \ + --hash=sha256:52d5641027d6731bc7b5e7d126a5158a99784a9f8c6de3d97ca89aca4969e9f8 \ + --hash=sha256:53148a4e21057541b6d8e493b2ea1b500037ddf34433c391970036f3cbce00e3 \ + --hash=sha256:583de2f16528e66081cbdfe510d8488c2de73039dc00aada7d22bd49d73a4a94 \ + --hash=sha256:5e55d90b431b0c6b64ae5a624208d4aea318566d31872e595ee723c0f5b9a79f \ + --hash=sha256:5f316cf2d0558f5027aab19dde7d7e4901c26c21fa95367bc37784e8f547bbf2 \ + --hash=sha256:60543f3b068b16a86e99ed96b7fdae71cdc1d8abdfe9b3f82032a555e52ece7e \ + --hash=sha256:62cc62284541bb2a86c898c7d5e8388661cade91c184cb862095ed547e80588f \ + --hash=sha256:65c05b79cb8366c123357b354a16f9fc3f7187159422f143638d1c26b7240ed4 \ + --hash=sha256:65f6ac06a9f0c32c254660ec6a9329d81d589e8f5d0a9837a941d5424a6be1ef \ + --hash=sha256:6d1434d0bcc1b3ef048bae53f26456405c08aeed9827e65b24094f5f3a6793f1 \ + --hash=sha256:6e2e1024f0a021777740cb7c633a0efb2c4a4bc570f508223a8dcbcf79f99ef9 \ + --hash=sha256:6ffa7ba2e2da1f806f3181b9730b3e87ba9dbfec884806725d4584055ba3faa6 \ + --hash=sha256:743b85bd6902856cac457ddd8cd7dd48c89c47d641b6016ff5e4d015bfbd4799 \ + --hash=sha256:77c5d2bebbc9d06691abb512a31d0f54e1562af0b872891463a67a949b5278ef \ + --hash=sha256:79cd03e7ff550c17758a7520bf437c156d3d4c8bb74214deeafa69cda49c85a4 \ + --hash=sha256:80aba5f85d6227faee628ae28d1c3b69c661806a0636548ac56c68782606454f \ + --hash=sha256:81a1669b6631976b1dc9d3d58ed1ab3333e9f52feb91a2a1fb8241101ac3b665 \ + --hash=sha256:8597c35c9e82f65fd5897c4a2188c65d7daf10607b102960137b23d261cd957b \ + --hash=sha256:8650158217b469d8b6087f490929211b0493a9121154c4efaafd1dec9e19319e \ + --hash=sha256:8887bf0f31e4b550bd988c8863b527b6587d200653e9375cd91eea2b944b7424 \ + --hash=sha256:8a52b24cd710690c4a7e191c7e300136ad2ecb3c68ffe7e95b598e76de166e5e \ + --hash=sha256:8e3754ce60e1b11b0afad9a053481ff184d2ee24bea47099107156d1b84a84aa \ + --hash=sha256:907f7b5501a534030738f0f27459a612d2266fd0507b007bb8f3e6de08167920 \ + --hash=sha256:90d6b9f2652303aefd2c5a26a5e14cb74a3a63d10faa642c08d790e99442a088 \ + --hash=sha256:98fd5b39410e9d69e10e90d0330e35650becaa5dd2548f509b9598f1f3c6124d \ + --hash=sha256:9bfdeff778d3f7ff449ca5922ab773899e7d31e26a576028b06a5e9cf0ed8c34 \ + --hash=sha256:9ebae74ce2b977c2fcb22d6a10aa0acb730022406977b2bcb6ddd6788f5c414a \ + --hash=sha256:a110d19881ca78a88583d3b07231e7c6864864f5f1f3491b638863ea45fa8708 \ + --hash=sha256:a1d190790ee39b8b7adeeb10fc4090dc4859eb4e75ed27bd8108710eef18f358 \ + --hash=sha256:a2f049c3f3c83e886cd1f53958e2a1ebb369be626bef9e50d8b24d79864f1df6 \ + --hash=sha256:a3af4e9f277d6b8acd369dc44a723a055752fca9d045094383af39f90a3e3729 \ + --hash=sha256:a42c7becd4c9ec4ab5769c754eb61112777bdc6e1c1525e2077389e193b5f5aa \ + --hash=sha256:a58a58cef0d911b1717154179a9ff47852249c536ea5966bde4370b6b20638ff \ + --hash=sha256:ab1f646ff531d70bfd25f01e60708dfa3d105eb458b7dedd9fe9a443039fd809 \ + --hash=sha256:ad940dc2db545dc978cb41cb9a683e2ff328f3ef581230b9ca40ff6c3d01d542 \ + --hash=sha256:afe3c3863f16704fb5d7c2c6ff56aaf9e054f6d269f7b4c9074c5476178d1aba \ + --hash=sha256:b1e3b9f4bf9a4120510ba77a77b2fb674893cd6795653545152bb11a79eecfcb \ + --hash=sha256:b2390ad81c03d93ef1d5afd18ffcf5935de827f1a2b96b2c829437968bdabccb \ + --hash=sha256:b37df4b10cb15dedfc203f69312d8eedd617b941c21df58c13af59496c53ad0f \ + --hash=sha256:b3df9447f9209f9aa0434ca74050e9509670c1ad99398fe5807abb90e5f3a014 \ + --hash=sha256:b4fe7f38aa8956fcc1cea270e62601e0e11066aff78e384be70fd283d30293b6 \ + --hash=sha256:c1d68c6980d4690a4550bd3db6c03146f7be68ef5d08d38bb1fb68b3e9c32fe3 \ + --hash=sha256:c24c1460486b6b36083252c2db21a814becf8495ccd0e76b7286623e37239b63 \ + --hash=sha256:c25132902d3eff38781e0d54f27a0942ec849e3c07dbdce83c4d92b7e43c8dce \ + --hash=sha256:c74bd9926954e7e575f9cd9890f63defd90cd8f812dfbf8e1efb72acc9355456 \ + --hash=sha256:c8139e9011117822391c5bcfd674c5948fb1e4b8cb9adf6f13d9890859ee3a1a \ + --hash=sha256:ce334915f5d31048f76a42c607bf26687cf045eb1bc852b7340f09729c6a64fc \ + --hash=sha256:d14229beaa76e66c3a25f9477d973336441ca820df853679a98796256813316f \ + --hash=sha256:d42f3a13290f89191568fc113d95a3d2c8759cdd8c3672f021d8b7436f909e75 \ + --hash=sha256:d8e56e0d1fe607bfff422633f313aec9191c3859ab99d11ff097e3e6e068000c \ + --hash=sha256:da6f0302360e99d32bc2869772692797ebadd536e1b826d0103c72ba49d38698 \ + --hash=sha256:db46baf157feefd88724e6a7f145fe996a5990a8604ed9292b45d563360e513b \ + --hash=sha256:dcea8c3f53674ae68e44b12e853b844a1d315250ca6677b11ec0c06aff85e86c \ + --hash=sha256:de94b409f49eb6a588ebdd5872e826caec417cd77c17af0fb94f2128427f1a2a \ + --hash=sha256:e0356561b4a97c83b9ee3de657a41b8d1a1781226853adaf47b550bb988fda6f \ + --hash=sha256:e0db44cf81e4d7b94f3776b9f89111f74ed6bbdbfd42a22bc4a5ce0644d3e060 \ + --hash=sha256:e31e92b61d56244047ad600812e16f7587a6172f74810fd919ff993af12b9149 \ + --hash=sha256:e89dabf436ee79b358fd970dcbed6333a36d91db73f27069ca24a02fb138a404 \ + --hash=sha256:eddeb9a153795cf6e615f9f3cef66a1d573ff3b6ee16df2b10d1d1c2f2baeaa8 \ + --hash=sha256:ee11fd431f83d8a5b29d370b9d79a814d3218d30113bdcd44657e9bdf715fc92 \ + --hash=sha256:ee37fe8cf081b72dea72f96a0ee604f492ec02252eb77dc26ff6eec3f997b580 \ + --hash=sha256:f19ee7dc1ef8a6497570d91fa4057ba910ad98297a50b8c44ff37589f7c89d17 \ + --hash=sha256:f2f94355affd51088f57f8674b0e294704c3c7c3d7d3b1545310f5b135d4843b \ + --hash=sha256:f525734382a47f9828c9d6a1501522c78d5935466d8e2be1a41ba40ca5bb922b \ + --hash=sha256:f915a34fb742e23d0d61573349aa45d6f74037fde9d58a9f340435eff8d62736 # via feast (pyproject.toml) httpcore==1.0.9 \ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ @@ -1236,9 +1253,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.13 \ + --hash=sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242 \ + --hash=sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 # via # anyio # httpx @@ -1280,97 +1297,97 @@ kubernetes==35.0.0 \ --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee # 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.9.0 \ + --hash=sha256:07cf11f769831186eeac424376e6189f20ace4f7263e2134bdb9757340d84d4d \ + --hash=sha256:0a09c2f5869649101738653a9b7ab70cf045a1105ac66cbb8f4055e61df78f2d \ + --hash=sha256:0a1be03168b2691ba61927e299b352a6315189199ca18a57b733f86cb3cc8d38 \ + --hash=sha256:0b73e4266307e51c95e09c0750b7ec383c561d2e97d58e473f6f6a209952fbb8 \ + --hash=sha256:15cb151e52a044f06e54ac7f7b47adbfc89b5c8e2b63e1175a9d587c43e8942a \ + --hash=sha256:194fc1a32e1e21fe809d38b5faea66cc65eaa00217c8901fbdb99866938adbdb \ + --hash=sha256:1bf465d1e5b0a27713862441f6467b5ab76385f4ecf8f1f3a44f8aa3c695b4b6 \ + --hash=sha256:1c587494461ebd42229d0f1739f3aa34237dd9980623ecf1be8d3bcba79f4499 \ + --hash=sha256:224b9727eb8bc188bc3bcf29d969dba0cd61b01d9bac80c41575520cc4baabb2 \ + --hash=sha256:22a904cbdb678f7cb348c90d543d3c52f581663d687992fee47fd566dcbf5285 \ + --hash=sha256:2b8f5d00b49818f4e2b1667db994488b045835e0ac16fe2f924f3871bd2b8ac5 \ + --hash=sha256:2c3786f0f4490a5cd87f1ed6cefae833ad6b1060d52044ce0434a2e85893afd0 \ + --hash=sha256:2d03fa4fd277a7974c1978c92c374c57f44edeee163d147b477b143446ad1bf6 \ + --hash=sha256:2f8e12706dcb8ff6b3ed57514a19e45c49ad00bcd423e87b2b2e4b5f64578443 \ + --hash=sha256:3be322a15ee5e70b93b7a59cfd074614f22cc8c9ff18bd27f474e79137ea8d3b \ + --hash=sha256:3cc2917258e131ae5f958a4d872e07555b51cb7466a43433218061c74ef33745 \ + --hash=sha256:3f05d145df35dca5056a8bc3838e940efebd893a54b3e19b2dda39ceaa299bcb \ + --hash=sha256:3fe56e80badb66fdcde06bef81bbaa5bfcf6fbd7aefb86222d9e369c38c6b228 \ + --hash=sha256:42ff8a962554c350d4a83cf47d9b7b78b0e6ff7943e87df7cdfc97c07f3c016f \ + --hash=sha256:451daa98463b7695b0a30aa56bf637831ea559e7b8101ac2ef6382e8eb15e29c \ + --hash=sha256:465814ab157986acb9dfa5ccd7df944be5eefc0d08d31ec6e8d88bc71251d845 \ + --hash=sha256:4c4d0440a3a8e31d962340c3e1cc3fc9ee7febd34c8d8f770d06adb947779ea5 \ + --hash=sha256:4e3dda8345307fd7306db0ed0cb109a63a2c85ba780eb9dc2d09b2049a931f9c \ + --hash=sha256:5093043afb226ecfa1400120d1ebd4442b4f99977783e4f4f7248879009b227f \ + --hash=sha256:5112c2fb7c2eefefaeaf5c97fec81343ef44ee86a30dcfaa8223822fba6467b4 \ + --hash=sha256:527b5b820b47a09e09829051452bb0d1dd2122261254e2a6f674d12f1d793d54 \ + --hash=sha256:54d412e47c21b85865676ed0724e37a89e9593c2eee1e7367adf85bfad56ffb1 \ + --hash=sha256:56d65b583cf43b8cf4c8fbe1e1da20fa3076cc32a1149a141507af1062718236 \ + --hash=sha256:5ca8e133d799c948db2ab1afc081c333a825b5540475164726dcbf73537e5c2f \ + --hash=sha256:603138ee838ee1583f1b960b62d5d0007845c5c423feb68e44648b1359014e27 \ + --hash=sha256:63c12efcd160e1d14da11af0c46c0217473e1e0d2ae1acbccc83f561ea4c2a7b \ + --hash=sha256:657f8ba7b9eaaa82759a104137aed2a3ef7bc46ccfd43e0d89b04005b3e0a4cc \ + --hash=sha256:66b58fed90a545328e80d575467244de3741e088c1af928f0b489ebec3ef3858 \ + --hash=sha256:6788207daa0c19955d2b668f3294a368d19f67d9b5f274553fd073c1260cbb9f \ + --hash=sha256:703f4ae36d6240bfe24f542bac784c7e4194ec49c3ba5a994d02891649e2d85b \ + --hash=sha256:7202bdcac47d3a708271c4304a474a8605a4a9a4a709e954bf2d3241140aa938 \ + --hash=sha256:756775d25ec8345b837ab52effee3ad2f3b2dfd6bbee3e3f029c517bd5d8f05a \ + --hash=sha256:78042f6facfd98ecb25e9829c7e37cce23363d9d7c83bc5f72702c5059eb082b \ + --hash=sha256:789fff71757facc0738e8d89e3b84e4f0251c1c975e85e81b152cdaca927cc2d \ + --hash=sha256:7bc30ad339f4e1a01d4917d645e522a0bc0030644d8973f6346397c93ba1503f \ + --hash=sha256:7d429bdd4ac0ab17c8e4a8af0ed2a7440b16eba474909ab357131018fe8c7e71 \ + --hash=sha256:7d5c8a5929ac325729f6119802070b561f4db793dffc45e9ac750992a4ed4d22 \ + --hash=sha256:7e6274fd33fc5b2a14d41c9119629d3ff395849d8bcbc80cf637d9e8d2034da8 \ + --hash=sha256:80b25c7b570a86c03b5da69e665809deb39265476e8e21d96a9328f9762f9990 \ + --hash=sha256:81107843ed1836874b46b310f9b1816abcb89912af627868522461c3b7333c0f \ + --hash=sha256:8494cfc61e03542f2d381e71804990b3931175a29b9278fdb4a5459948778dc2 \ + --hash=sha256:850d6d03177e52700af605fd60db7f37dcb89782049a149674d1a9649c2138fd \ + --hash=sha256:8c6bc1384d9738781cfd41d09ad7f6e8af13cfea2c75ece6bd6d2566cdea2076 \ + --hash=sha256:90904fac73c478f4b83f4ed96c99c8208b75e6f9a8a1910548f69a00f1eaa671 \ + --hash=sha256:90e6d5420fc8a300518d4d2288154ff45005e920425c22cbbfe8330f3f754bd9 \ + --hash=sha256:928bd06eca2c2bbf4349e5b817f837509b0604342e65a502de1d50a7570afd15 \ + --hash=sha256:9b3e3bc363f71bda1639a4ee593cb78f7fbfeacc73411ec0d4c92f00730010a4 \ + --hash=sha256:9edcc35d1cae9fd5320171b1a838c7da8a5c968af31e82ecc3dff30b4be0957f \ + --hash=sha256:9fcb461fbf70654a52a7cc670e606f04449e2374c199b1825f754e16dacfedd8 \ + --hash=sha256:a0951822531e7aee6e0dfb556b30d5ee36bbe234faf60c20a16c01be3530869d \ + --hash=sha256:a361c9434a64d70a7dbb771d1de302c0cc9f13c0bffe1cf7e642152814b35265 \ + --hash=sha256:a4b25c6c25cac5d0d9d6d6da855195b254e0021e513e0249f0e3b444dc6e0e61 \ + --hash=sha256:a5af136bfba820d592f86c67affcef9b3ff4d4360ac3255e341e964489b48519 \ + --hash=sha256:a81eea9b999b985e4bacc650c4312805ea7008fd5e45e1bf221310176a7bcb3a \ + --hash=sha256:a9c63e04d003bc0fb6a03b348018b9a3002f98268200e22cc80f146beac5dc40 \ + --hash=sha256:aa95738a68cedd3a6f5492feddc513e2e166b50602958139e47bbdd82da0f5a7 \ + --hash=sha256:b0a2040f801406b93657a70b72fa12311063a319fee72ce98e1524da7200171f \ + --hash=sha256:b8bd70d5d816566a580d193326912f4a76ec2d28a97dc4cd4cc831c0af8e330e \ + --hash=sha256:b8da9f8035bb417770b1e1610526d87ad4fc58a2804dc4d79c53f6d2cf5a6eb9 \ + --hash=sha256:bc5518873822d2faa8ebdd2c1a4d7c8ef47b01a058495ab7924cb65bdbf5fc9a \ + --hash=sha256:c0d620e74897f8c2613b3c4e2e9c1e422eb46d2ddd07df540784d44117836af3 \ + --hash=sha256:c2640e23d2b7c98796f123ffd95cf2022c7777aa8a4a3b98b36c570d37e85eee \ + --hash=sha256:c81aef782380f0f13ead670aae01825eb653b44b046aa0e5ebbb79f76ed4aa11 \ + --hash=sha256:d4d16b608a1c43d7e33142099a75cd93af482dadce0bf82421e91cad077157f4 \ + --hash=sha256:d69fc39e627908f4c03297d5a88d9284b73f4d90b424461e32e8c2485e21c283 \ + --hash=sha256:d9da80e5b04acce03ced8ba6479a71c2a2edf535c2acc0d09c80d2f80f3bad15 \ + --hash=sha256:dd2c7e082b0b92e1baa4da28163a808672485617bc855cc22a2fd06978fa9084 \ + --hash=sha256:de7dac64e3eb832ffc7b840eb8f52f76420cde1b845be51b2a0f6b870890645e \ + --hash=sha256:e0785c2fb4a81e1aece366aa3e2e039f4a4d7d21aaaded5227d7f3c703427882 \ + --hash=sha256:e306d956cfa027fe041585f02a1602c32bfa6bb8ebea4899d373383295a6c62f \ + --hash=sha256:e78fb7419e07d98c2af4b8567b72b3eaf8cb05caad642e9963465569c8b2d87e \ + --hash=sha256:e9002e98dcb1c0a66723592520decd86238ddcef168b37ff6cfb559200b4b774 \ + --hash=sha256:e94cbc6ad9a6aeea46d775cbb11f361022f778a9cc8cc90af653d3a594b057ce \ + --hash=sha256:eea1b54943475f51698f85fa230c65ccac769f1e603b981be060ac5763d90927 \ + --hash=sha256:f100bfe2acf8a3689af9d0cc660d89f17286c9c795f9f18f7b62dd1a6b247ae6 \ + --hash=sha256:f162af66a2ed3f7d1d161a82ca584efd15acd9c1cff190a373458c32f7d42118 \ + --hash=sha256:f24b90b0e0c8cc9491fb1693ae91fe17cb7963153a1946395acdbdd5818429a4 \ + --hash=sha256:f29b68cd9714531672db62cc54f6e8ff981900f824d13fa0e00749189e13778e \ + --hash=sha256:f38bc489037eca88d6ebefc9c4d41a4e07c8e8b4de5188a9e6d290273ad7ebb1 \ + --hash=sha256:f3fd278f5e6bf7c75ccd6d12344eb686cc020712683363b66f46ac79d37c799f \ + --hash=sha256:f4003f70c56a5addd6aa0897f200dd59afd3bf7bcd5b3cce46dd21f925743bc2 \ + --hash=sha256:f48c963a76d71b9d7927eb817b543d0dccd52ab6648b99d37bd54f4cd475d856 \ + --hash=sha256:f819e0c6413e259a17a7c0d49f97f405abadd3c2a316a3b46c6440b7dbbedbb1 \ + --hash=sha256:fc5758e2b7a56532dc33e3c544d78cbaa9ecf0a0f2a2da2df882c1d6b99a317f \ + --hash=sha256:fcbdf2a9ca24e87bbebb47f1fe34e531ef06f104f98c9ccfc953a3f3344c567a # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ @@ -1749,51 +1766,51 @@ multidict==6.7.1 \ # aiobotocore # aiohttp # yarl -mypy==1.20.0 \ - --hash=sha256:002b613ae19f4ac7d18b7e168ffe1cb9013b37c57f7411984abbd3b817b0a214 \ - --hash=sha256:00e047c74d3ec6e71a2eb88e9ea551a2edb90c21f993aefa9e0d2a898e0bb732 \ - --hash=sha256:02cca0761c75b42a20a2757ae58713276605eb29a08dd8a6e092aa347c4115ca \ - --hash=sha256:0ecd63f75fdd30327e4ad8b5704bd6d91fc6c1b2e029f8ee14705e1207212489 \ - --hash=sha256:0f42dfaab7ec1baff3b383ad7af562ab0de573c5f6edb44b2dab016082b89948 \ - --hash=sha256:1973868d2adbb4584a3835780b27436f06d1dc606af5be09f187aaa25be1070f \ - --hash=sha256:26c8b52627b6552f47ff11adb4e1509605f094e29815323e487fc0053ebe93d1 \ - --hash=sha256:2721f0ce49cb74a38f00c50da67cb7d36317b5eda38877a49614dc018e91c787 \ - --hash=sha256:2fcedb16d456106e545b2bfd7ef9d24e70b38ec252d2a629823a4d07ebcdb69e \ - --hash=sha256:31b5dbb55293c1bd27c0fc813a0d2bb5ceef9d65ac5afa2e58f829dab7921fd5 \ - --hash=sha256:34506397dbf40c15dc567635d18a21d33827e9ab29014fb83d292a8f4f8953b6 \ - --hash=sha256:367e5c993ba34d5054d11937d0485ad6dfc60ba760fa326c01090fc256adf15c \ - --hash=sha256:379edf079ce44ac8d2805bcf9b3dd7340d4f97aad3a5e0ebabbf9d125b84b442 \ - --hash=sha256:39362cdb4ba5f916e7976fccecaab1ba3a83e35f60fa68b64e9a70e221bb2436 \ - --hash=sha256:4525e7010b1b38334516181c5b81e16180b8e149e6684cee5a727c78186b4e3b \ - --hash=sha256:47781555a7aa5fedcc2d16bcd72e0dc83eb272c10dd657f9fb3f9cc08e2e6abb \ - --hash=sha256:49d11c6f573a5a08f77fad13faff2139f6d0730ebed2cfa9b3d2702671dd7188 \ - --hash=sha256:555493c44a4f5a1b58d611a43333e71a9981c6dbe26270377b6f8174126a0526 \ - --hash=sha256:555658c611099455b2da507582ea20d2043dfdfe7f5ad0add472b1c6238b433f \ - --hash=sha256:697f102c5c1d526bdd761a69f17c6070f9892eebcb94b1a5963d679288c09e78 \ - --hash=sha256:76a70bf840495729be47510856b978f1b0ec7d08f257ca38c9d932720bf6b43e \ - --hash=sha256:7d3243c406773185144527f83be0e0aefc7bf4601b0b2b956665608bf7c98a83 \ - --hash=sha256:931a7630bba591593dcf6e97224a21ff80fb357e7982628d25e3c618e7f598ef \ - --hash=sha256:9804c3ad27f78e54e58b32e7cb532d128b43dbfb9f3f9f06262b821a0f6bd3f5 \ - --hash=sha256:a17c5d0bdcca61ce24a35beb828a2d0d323d3fcf387d7512206888c900193367 \ - --hash=sha256:a6e0641147cbfa7e4e94efdb95c2dab1aff8cfc159ded13e07f308ddccc8c48e \ - --hash=sha256:a79c1eba7ac4209f2d850f0edd0a2f8bba88cbfdfefe6fb76a19e9d4fe5e71a2 \ - --hash=sha256:a9336b5e6712f4adaf5afc3203a99a40b379049104349d747eb3e5a3aa23ac2e \ - --hash=sha256:b20c8b0fd5877abdf402e79a3af987053de07e6fb208c18df6659f708b535134 \ - --hash=sha256:b3a49064504be59e59da664c5e149edc1f26c67c4f8e8456f6ba6aba55033018 \ - --hash=sha256:b503ab55a836136b619b5fc21c8803d810c5b87551af8600b72eecafb0059cb0 \ - --hash=sha256:bd0212976dc57a5bfeede7c219e7cd66568a32c05c9129686dd487c059c1b88a \ - --hash=sha256:c70380fe5d64010f79fb863b9081c7004dd65225d2277333c219d93a10dad4dd \ - --hash=sha256:d99f515f95fd03a90875fdb2cca12ff074aa04490db4d190905851bdf8a549a8 \ - --hash=sha256:e80cf77847d0d3e6e3111b7b25db32a7f8762fd4b9a3a72ce53fe16a2863b281 \ - --hash=sha256:eb96c84efcc33f0b5e0e04beacf00129dd963b67226b01c00b9dfc8affb464c3 \ - --hash=sha256:ebea00201737ad4391142808ed16e875add5c17f676e0912b387739f84991e13 \ - --hash=sha256:efe8d70949c3023698c3fca1e94527e7e790a361ab8116f90d11221421cd8726 \ - --hash=sha256:f13b3e41bce9d257eded794c0f12878af3129d80aacd8a3ee0dee51f3a978651 \ - --hash=sha256:f194db59657c58593a3c47c6dfd7bad4ef4ac12dbc94d01b3a95521f78177e33 \ - --hash=sha256:f49590891d2c2f8a9de15614e32e459a794bcba84693c2394291a2038bbaaa69 \ - --hash=sha256:f75ff57defcd0f1d6e006d721ccdec6c88d4f6a7816eb92f1c4890d979d9ee62 \ - --hash=sha256:f799d9db89fc00446f03281f84a221e50018fc40113a3ba9864b132895619ebe \ - --hash=sha256:f8426d4d75d68714abc17a4292d922f6ba2cfb984b72c2278c437f6dae797865 +mypy==1.20.2 \ + --hash=sha256:0c64e5973df366b747646fc98da921f9d6eba9716d57d1db94a83c026a08e0fb \ + --hash=sha256:0deb80d062b2479f2c87ae568f89845afc71d11bc41b04179e58165fd9f31e98 \ + --hash=sha256:1e1c12f6d2db3d78b909b5f77513c11eb7f2dd2782b96a3ab6dffc7d44575c99 \ + --hash=sha256:20175a1c0f49863946ec20b7f63255768058ac4f07d2b9ded6a6b46cfb5a9100 \ + --hash=sha256:29752dbbf8cc53f89f6ac096d363314333045c257c9c75cbd189ca2de0455744 \ + --hash=sha256:2a4102b03bb7481d9a91a6da8d174740c9c8c4401024684b9ca3b7cc5e49852f \ + --hash=sha256:2de3dcea53babc1c3237a19002bc3d228ce1833278f093b8d619e06e7cc79609 \ + --hash=sha256:34397cdced6b90b836e38182076049fdb41424322e0b0728c946b0939ebdf9f6 \ + --hash=sha256:4077797a273e56e8843d001e9dfe4ba10e33323d6ade647ff260e5cd97d9758c \ + --hash=sha256:419413398fe250aae057fd2fe50166b61077083c9b82754c341cf4fd73038f30 \ + --hash=sha256:4b6481b228d072315b053210b01ac320e1be243dc17f9e5887ef167f23f5fae4 \ + --hash=sha256:4dbfcf869f6b0517f70cf0030ba6ea1d6645e132337a7d5204a18d8d5636c02b \ + --hash=sha256:4fef51b01e638974a6e69885687e9bd40c8d1e09a6cd291cca0619625cf1f558 \ + --hash=sha256:52b176444e2e5054dfcbcb8c75b0b719865c96247b37407184bbfca5c353f2c2 \ + --hash=sha256:56908d7e08318d39f85b1f0c6cfd47b0cac1a130da677630dac0de3e0623e102 \ + --hash=sha256:5a65aa591af023864fd08a97da9974e919452cfe19cb146c8a5dc692626445dc \ + --hash=sha256:688c3312e5dadb573a2c69c82af3a298d43ecf9e6d264e0f95df960b5f6ac19c \ + --hash=sha256:6e2b469efd811707bc530fd1effef0f5d6eebcb7fe376affae69025da4b979a2 \ + --hash=sha256:7488448de6007cd5177c6cea0517ac33b4c0f5ee9b5e9f2be51ce75511a85517 \ + --hash=sha256:785b08db19c9f214dc37d65f7c165d19a30fcecb48abfa30f31b01b5acaabb58 \ + --hash=sha256:7b0e817b518bff7facd7f85ea05b643ad8bdcce684cf29784987b0a7c8e1f997 \ + --hash=sha256:803203d2b6ea644982c644895c2f78b28d0e208bba7b27d9b921e0ec5eb207c6 \ + --hash=sha256:89dce27e142d25ffbc154c1819383b69f2e9234dc4ed4766f42e0e8cb264ab5c \ + --hash=sha256:913485a03f1bcf5d279409a9d2b9ed565c151f61c09f29991e5faa14033da4c8 \ + --hash=sha256:97d7b9a485b40f8ca425460e89bf1da2814625b2da627c0dcc6aa46c92631d14 \ + --hash=sha256:9bcb8aa397ff0093c824182fd76a935a9ba7ad097fcbef80ae89bf6c1731d8ec \ + --hash=sha256:9d56a78b646f2e3daa865bc70cd5ec5a46c50045801ca8ff17a0c43abc97e3ee \ + --hash=sha256:a5da6976f20cae27059ea8d0c86e7cef3de720e04c4bb9ee18e3690fdb792066 \ + --hash=sha256:a94c5a76ab46c5e6257c7972b6c8cff0574201ca7dc05647e33e795d78680563 \ + --hash=sha256:a95a9248b0c6fd933a442c03c3b113c3b61320086b88e2c444676d3fd1ca3330 \ + --hash=sha256:baf593f2765fa3a6b1ef95807dbaa3d25b594f6a52adcc506a6b9cb115e1be67 \ + --hash=sha256:bb9c2fa06887e21d6a3a868762acb82aec34e2c6fd0174064f27c93ede68ad15 \ + --hash=sha256:bba9ad231e92a3e424b3e56b65aa17704993425bba97e302c832f9466bb85bac \ + --hash=sha256:c3bae4f855d965b5453784300c12ffc63a548304ac7f99e55d4dc7c898673aa3 \ + --hash=sha256:c566c3a88b6ece59b3d70f65bedef17304f48eb52ff040a6a18214e1917b3254 \ + --hash=sha256:cdecf62abcc4292500d7858aeae87a1f8f1150f4c4dd08fb0b336ee79b2a6df3 \ + --hash=sha256:cf5a4db6dca263010e2c7bff081c89383c72d187ba2cf4c44759aac970e2f0c4 \ + --hash=sha256:d52ad8d78522da1d308789df651ee5379088e77c76cb1994858d40a426b343b9 \ + --hash=sha256:e061b58443f1736f8a37c48978d7ab581636d6ab03e3d4f99e3fa90463bb9382 \ + --hash=sha256:e2877a02380adfcdbc69071a0f74d6e9dbbf593c0dc9d174e1f223ffd5281943 \ + --hash=sha256:e73c07f23009962885c197ccb9b41356a30cc0e5a1d0c2ea8fd8fb1362d7f924 \ + --hash=sha256:e8222c26daaafd9e8626dec58ae36029f82585890589576f769a650dd20fd665 \ + --hash=sha256:edfbfca868cdd6bd8d974a60f8a3682f5565d3f5c99b327640cedd24c4264026 \ + --hash=sha256:f376e37f9bf2a946872fc5fd1199c99310748e3c26c7a26683f13f8bdb756cbd # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ @@ -1866,9 +1883,9 @@ oauthlib==3.3.1 \ --hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \ --hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1 # via requests-oauthlib -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # db-dtypes @@ -1948,9 +1965,9 @@ pandas==2.3.3 \ # pandas-gbq # pymilvus # snowflake-connector-python -pandas-gbq==0.34.1 \ - --hash=sha256:6bea5b85937251b976cf9db38151ea59abbff98771179183488d4614694bff67 \ - --hash=sha256:b74932c6ee35dfc81582f39c792e3a68c9ef9bee8c85f25667d9d05dfadd0daf +pandas-gbq==0.35.0 \ + --hash=sha256:258de481019566611031919997bf9c1ece4ca30a4dd02d3fc3664b251d446182 \ + --hash=sha256:596c908487ef0649a161e86ef272c00c267e581b95dc5ee0dc3518545b33bcfc # via google-cloud-bigquery parsy==2.2 \ --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ @@ -1971,24 +1988,24 @@ 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.9.6 \ + --hash=sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a \ + --hash=sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917 # via snowflake-connector-python pluggy==1.6.0 \ --hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \ --hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # via hatchling -prometheus-client==0.24.1 \ - --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ - --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 +prometheus-client==0.25.0 \ + --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ + --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 # via feast (pyproject.toml) propcache==0.4.1 \ --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ @@ -2184,57 +2201,57 @@ psycopg-pool==3.3.0 \ --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 # 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 @@ -2263,141 +2280,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.3 \ + --hash=sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927 \ + --hash=sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d # 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.3 \ + --hash=sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba \ + --hash=sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35 \ + --hash=sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4 \ + --hash=sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505 \ + --hash=sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7 \ + --hash=sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8 \ + --hash=sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4 \ + --hash=sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37 \ + --hash=sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25 \ + --hash=sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022 \ + --hash=sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1 \ + --hash=sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7 \ + --hash=sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c \ + --hash=sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3 \ + --hash=sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb \ + --hash=sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3 \ + --hash=sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976 \ + --hash=sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c \ + --hash=sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab \ + --hash=sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa \ + --hash=sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6 \ + --hash=sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396 \ + --hash=sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c \ + --hash=sha256:3d08782c4045f90724b44c95d35ebec0d67edb8a957a2ac81d5a8e4b8a200495 \ + --hash=sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c \ + --hash=sha256:4335e87c7afa436a0dfa899e138d57a72f8aad542e2cf19c36fb428461caabd0 \ + --hash=sha256:4b068543bdb707f5d935dab765d99227aa2545ef2820935f2e5dd801795c7dbd \ + --hash=sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf \ + --hash=sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531 \ + --hash=sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5 \ + --hash=sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda \ + --hash=sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d \ + --hash=sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e \ + --hash=sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df \ + --hash=sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6 \ + --hash=sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c \ + --hash=sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13 \ + --hash=sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536 \ + --hash=sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287 \ + --hash=sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0 \ + --hash=sha256:68ef2f623dda6d5a9067ac014e406c020c780b2a358930a7e5c1b73702900720 \ + --hash=sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050 \ + --hash=sha256:6dff8cc884679df229ebc6d8eb2321ea6f8e091bc7d4886d4dc2e0e71452843c \ + --hash=sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1 \ + --hash=sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8 \ + --hash=sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0 \ + --hash=sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374 \ + --hash=sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807 \ + --hash=sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6 \ + --hash=sha256:831eb19aa789a97356979e94c981e5667759301fb708d1c0d5adf1bc0098b873 \ + --hash=sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57 \ + --hash=sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f \ + --hash=sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c \ + --hash=sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad \ + --hash=sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e \ + --hash=sha256:91249bcb7c165c2fb2a2f852dbc5c91636e2e218e75d96dfdd517e4078e173dd \ + --hash=sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23 \ + --hash=sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46 \ + --hash=sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1 \ + --hash=sha256:99421e7684a60f7f3550a1d159ade5fdff1954baedb6bdd407cba6a307c9f27d \ + --hash=sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1 \ + --hash=sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee \ + --hash=sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c \ + --hash=sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874 \ + --hash=sha256:9f247596366f4221af52beddd65af1218797771d6989bc891a0b86ccaa019168 \ + --hash=sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a \ + --hash=sha256:a35cc284c8dd7edae8a31533713b4d2467dfe7c4f1b5587dd4031f28f90d1d13 \ + --hash=sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f \ + --hash=sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a \ + --hash=sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789 \ + --hash=sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe \ + --hash=sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f \ + --hash=sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5 \ + --hash=sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943 \ + --hash=sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b \ + --hash=sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089 \ + --hash=sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b \ + --hash=sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff \ + --hash=sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67 \ + --hash=sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803 \ + --hash=sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045 \ + --hash=sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8 \ + --hash=sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346 \ + --hash=sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2 \ + --hash=sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f \ + --hash=sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687 \ + --hash=sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76 \ + --hash=sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1 \ + --hash=sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f \ + --hash=sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2 \ + --hash=sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c \ + --hash=sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018 \ + --hash=sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba \ + --hash=sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c \ + --hash=sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf \ + --hash=sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7 \ + --hash=sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47 \ + --hash=sha256:d56bdb4af1767cc15b0386b3c581fdfe659bb9ee4a4f776e92c1cd9d074000d6 \ + --hash=sha256:dcda6583921c05a40533f982321532f2d8db29326c7b95c4026941fa5074bd79 \ + --hash=sha256:dd81f6907932ebac3abbe41378dac64b2380db1287e2aa64d8d88f78d170f51a \ + --hash=sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e \ + --hash=sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a \ + --hash=sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34 \ + --hash=sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b \ + --hash=sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85 \ + --hash=sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca \ + --hash=sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f \ + --hash=sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3 \ + --hash=sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64 \ + --hash=sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22 \ + --hash=sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72 \ + --hash=sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec \ + --hash=sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d \ + --hash=sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3 \ + --hash=sha256:fa3eb7c2995aa443687a825bc30395c8521b7c6ec201966e55debfd1128bcceb \ + --hash=sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395 \ + --hash=sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb \ + --hash=sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4 \ + --hash=sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127 \ + --hash=sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56 # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.0 \ + --hash=sha256:24285fd4b0e0c06507dd9fdfd331ee23794305352aaec8fc4eb92d4047aeb67d \ + --hash=sha256:fc8d5d692eb7092e43c8647c1c35a3ecd00e040fcf02ed86f4cb5458ca62182e # via # fastapi-mcp # mcp @@ -2423,13 +2439,13 @@ pymilvus==2.5.18 \ --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d # via feast (pyproject.toml) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 +pymysql==1.1.3 \ + --hash=sha256:8164ba62c552f6105f3b11753352d0f16b90d1703ba67d81923d5a8a5d1c5289 \ + --hash=sha256:e70ebf2047a4edf6138cf79c68ad418ef620af65900aa585c5e8bfc95044d43a # via feast (pyproject.toml) -pyopenssl==26.0.0 \ - --hash=sha256:df94d28498848b98cc1c0ffb8ef1e71e40210d3b0a8064c9d29571ed2904bf81 \ - --hash=sha256:f293934e52936f2e3413b89c6ce36df66a0b34ae1ea3a053b8c5020ff2f513fc +pyopenssl==26.1.0 \ + --hash=sha256:115563879b2c8ccb207975705d3e491434d8c9d7c79667c902ecbf5f3bbd2ece \ + --hash=sha256:737f0a2275c5bc54f3b02137687e1a765931fb3949b9a92a825e4d33b9eec08b # via snowflake-connector-python pyproject-metadata==0.11.0 \ --hash=sha256:85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 \ @@ -2452,9 +2468,9 @@ python-dotenv==1.2.2 \ # pydantic-settings # pymilvus # uvicorn -python-multipart==0.0.22 \ - --hash=sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155 \ - --hash=sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58 +python-multipart==0.0.27 \ + --hash=sha256:6fccfad17a27334bd0193681b369f476eda3409f17381a2d65aa7df3f7275645 \ + --hash=sha256:9870a6a8c5a20a5bf4f07c017bd1489006ff8836cff097b6933355ee2b49b602 # via mcp pytz==2026.1.post1 \ --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ @@ -2541,9 +2557,9 @@ pyyaml==6.0.3 \ # dask # kubernetes # uvicorn -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.0 \ + --hash=sha256:64a6ea7bf567ad43c964d2c30d82853f8df927c5c9017766c55a1d1ed95d18ad \ + --hash=sha256:a9c74a5c893a5ef8455a5adb793a31bb70feb821c86eccb62eebef5a19c429ec # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -2570,9 +2586,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 @@ -2790,78 +2806,78 @@ 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.49 \ + --hash=sha256:01146546d84185f12721a1d2ce0c6673451a7894d1460b592d378ca4871a0c72 \ + --hash=sha256:059d7151fff513c53a4638da8778be7fce81a0c4854c7348ebd0c4078ddf28fe \ + --hash=sha256:0c98c59075b890df8abfcc6ad632879540f5791c68baebacb4f833713b510e75 \ + --hash=sha256:0f2fa354ba106eafff2c14b0cc51f22801d1e8b2e4149342023bd6f0955de5f5 \ + --hash=sha256:12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148 \ + --hash=sha256:22d8798819f86720bc646ab015baff5ea4c971d68121cb36e2ebc2ee43ead2b7 \ + --hash=sha256:233088b4b99ebcbc5258c755a097aa52fbf90727a03a5a80781c4b9c54347a2e \ + --hash=sha256:24bd94bb301ec672d8f0623eba9226cc90d775d25a0c92b5f8e4965d7f3a1518 \ + --hash=sha256:275424295f4256fd301744b8f335cff367825d270f155d522b30c7bf49903ee7 \ + --hash=sha256:32fe6a41ad97302db2931f05bb91abbcc65b5ce4c675cd44b972428dd2947700 \ + --hash=sha256:334edbcff10514ad1d66e3a70b339c0a29886394892490119dbb669627b17717 \ + --hash=sha256:3bb9ec6436a820a4c006aad1ac351f12de2f2dbdaad171692ee457a02429b672 \ + --hash=sha256:3ddcb27fb39171de36e207600116ac9dfd4ae46f86c82a9bf3934043e80ebb88 \ + --hash=sha256:42e8804962f9e6f4be2cbaedc0c3718f08f60a16910fa3d86da5a1e3b1bfe60f \ + --hash=sha256:43d044780732d9e0381ac8d5316f95d7f02ef04d6e4ef6dc82379f09795d993f \ + --hash=sha256:46796877b47034b559a593d7e4b549aba151dae73f9e78212a3478161c12ab08 \ + --hash=sha256:46d51518d53edfbe0563662c96954dc8fcace9832332b914375f45a99b77cc9a \ + --hash=sha256:47604cb2159f8bbd5a1ab48a714557156320f20871ee64d550d8bf2683d980d3 \ + --hash=sha256:4bbccb45260e4ff1b7db0be80a9025bb1e6698bdb808b83fff0000f7a90b2c0b \ + --hash=sha256:4d4e5a0ceba319942fa6b585cf82539288a61e314ef006c1209f734551ab9536 \ + --hash=sha256:55250fe61d6ebfd6934a272ee16ef1244e0f16b7af6cd18ab5b1fc9f08631db0 \ + --hash=sha256:566df36fd0e901625523a5a1835032f1ebdd7f7886c54584143fa6c668b4df3b \ + --hash=sha256:57ca426a48eb2c682dae8204cd89ea8ab7031e2675120a47924fabc7caacbc2a \ + --hash=sha256:5e61abbec255be7b122aa461021daa7c3f310f3e743411a67079f9b3cc91ece3 \ + --hash=sha256:618a308215b6cececb6240b9abde545e3acdabac7ae3e1d4e666896bf5ba44b4 \ + --hash=sha256:62557958002b69699bdb7f5137c6714ca1133f045f97b3903964f47db97ea339 \ + --hash=sha256:6270d717b11c5476b0cbb21eedc8d4dbb7d1a956fd6c15a23e96f197a6193158 \ + --hash=sha256:685e93e9c8f399b0c96a624799820176312f5ceef958c0f88215af4013d29066 \ + --hash=sha256:69469ce8ce7a8df4d37620e3163b71238719e1e2e5048d114a1b6ce0fbf8c662 \ + --hash=sha256:6eb188b84269f357669b62cb576b5b918de10fb7c728a005fa0ebb0b758adce1 \ + --hash=sha256:74ab4ee7794d7ed1b0c37e7333640e0f0a626fc7b398c07a7aef52f484fddde3 \ + --hash=sha256:77641d299179c37b89cf2343ca9972c88bb6eef0d5fc504a2f86afd15cd5adf5 \ + --hash=sha256:7c821c47ecfe05cc32140dcf8dc6fd5d21971c86dbd56eabfe5ba07a64910c01 \ + --hash=sha256:7d6be30b2a75362325176c036d7fb8d19e8846c77e87683ffaa8177b35135613 \ + --hash=sha256:7f605a456948c35260e7b2a39f8952a26f077fd25653c37740ed186b90aaa68a \ + --hash=sha256:83101a6930332b87653886c01d1ee7e294b1fe46a07dd9a2d2b4f91bcc88eec0 \ + --hash=sha256:88690f4e1f0fbf5339bedbb127e240fec1fd3070e9934c0b7bef83432f779d2f \ + --hash=sha256:8a97ac839c2c6672c4865e48f3cbad7152cee85f4233fb4ca6291d775b9b954a \ + --hash=sha256:8d6efc136f44a7e8bc8088507eaabbb8c2b55b3dbb63fe102c690da0ddebe55e \ + --hash=sha256:8e20e511dc15265fb433571391ba313e10dd8ea7e509d51686a51313b4ac01a2 \ + --hash=sha256:951d4a210744813be63019f3df343bf233b7432aadf0db54c75802247330d3af \ + --hash=sha256:9ac7a3e245fd0310fd31495eb61af772e637bdf7d88ee81e7f10a3f271bff014 \ + --hash=sha256:9b1c058c171b739e7c330760044803099c7fff11511e3ab3573e5327116a9c33 \ + --hash=sha256:9c04bff9a5335eb95c6ecf1c117576a0aa560def274876fd156cfe5510fccc61 \ + --hash=sha256:9c4969a86e41454f2858256c39bdfb966a20961e9b58bf8749b65abf447e9a8d \ + --hash=sha256:9e0400fa22f79acc334d9a6b185dc00a44a8e6578aa7e12d0ddcd8434152b187 \ + --hash=sha256:a05977bffe9bffd2229f477fa75eabe3192b1b05f408961d1bebff8d1cd4d401 \ + --hash=sha256:a143af2ea6672f2af3f44ed8f9cd020e9cc34c56f0e8db12019d5d9ecf41cb3b \ + --hash=sha256:a51d3db74ba489266ef55c7a4534eb0b8db9a326553df481c11e5d7660c8364d \ + --hash=sha256:b95b2f470c1b2683febd2e7eab1d3f0e078c91dbdd0b00e9c645d07a413bb99f \ + --hash=sha256:b9870d15ef00e4d0559ae10ee5bc71b654d1f20076dbe8bc7ed19b4c0625ceba \ + --hash=sha256:c1dc3368794d522f43914e03312202523cc89692f5389c32bea0233924f8d977 \ + --hash=sha256:c338ec6ec01c0bc8e735c58b9f5d51e75bacb6ff23296658826d7cfdfdb8678a \ + --hash=sha256:c5070135e1b7409c4161133aa525419b0062088ed77c92b1da95366ec5cbebbe \ + --hash=sha256:cc992c6ed024c8c3c592c5fc9846a03dd68a425674900c70122c77ea16c5fb0b \ + --hash=sha256:d15950a57a210e36dd4cec1aac22787e2a4d57ba9318233e2ef8b2daf9ff2d5f \ + --hash=sha256:d898cc2c76c135ef65517f4ddd7a3512fb41f23087b0650efb3418b8389a3cd1 \ + --hash=sha256:d99945830a6f3e9638d89a28ed130b1eb24c91255e4f24366fbe699b983f29e4 \ + --hash=sha256:da9b91bca419dc9b9267ffadde24eae9b1a6bffcd09d0a207e5e3af99a03ce0d \ + --hash=sha256:df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120 \ + --hash=sha256:e06e617e3d4fd9e51d385dfe45b077a41e9d1b033a7702551e3278ac597dc750 \ + --hash=sha256:ec44cfa7ef1a728e88ad41674de50f6db8cfdb3e2af84af86e0041aaf02d43d0 \ + --hash=sha256:fb37f15714ec2652d574f021d479e78cd4eb9d04396dca36568fdfffb3487982 # via feast (pyproject.toml) -sqlglot==30.2.1 \ - --hash=sha256:ef4a67cc6f66a8043085eb8ea95fa9541c1625dffa9145ad4e9815a7ba60a199 \ - --hash=sha256:f23d9ee9427ef9d20df15f9b0ffa57d9eb45e52b012219a349d1e6b50ed926d1 +sqlglot==30.6.0 \ + --hash=sha256:246d34d39927422a50a3fa155f37b2f6346fba85f1a755b13c941eb32ef93361 \ + --hash=sha256:e005fc2f47994f90d7d8df341f1cbe937518497b0b7b1507d4c03c4c9dfd2778 # via ibis-framework -sse-starlette==3.3.4 \ - --hash=sha256:84bb06e58939a8b38d8341f1bc9792f06c2b53f48c608dd207582b664fc8f3c1 \ - --hash=sha256:aaf92fc067af8a5427192895ac028e947b484ac01edbc3caf00e7e7137c7bef1 +sse-starlette==3.4.1 \ + --hash=sha256:6b43cf21f1d574d582a6e1b0cfbde1c94dc86a32a701a7168c99c4475c6bd1d0 \ + --hash=sha256:f780bebcf6c8997fe514e3bd8e8c648d8284976b391c8bed0bcb1f611632b555 # via mcp starlette==1.0.0 \ --hash=sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149 \ @@ -2957,25 +2973,25 @@ tqdm==4.67.3 \ # via # feast (pyproject.toml) # milvus-lite -trove-classifiers==2026.1.14.14 \ - --hash=sha256:00492545a1402b09d4858605ba190ea33243d361e2b01c9c296ce06b5c3325f3 \ - --hash=sha256:1f9553927f18d0513d8e5ff80ab8980b8202ce37ecae0e3274ed2ef11880e74d +trove-classifiers==2026.4.28.13 \ + --hash=sha256:8f4b1eb4e16296b57d612965444f87a83861cc989a0451ac97fe4265ddef03b8 \ + --hash=sha256:c85bb8a53c3de7330d1699b844ed9fb809a602a09ac15dc79ad6d1a509be0676 # via hatchling typeguard==4.5.1 \ --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 # via feast (pyproject.toml) -typer==0.24.1 \ - --hash=sha256:112c1f0ce578bfb4cab9ffdabc68f031416ebcc216536611ba21f04e9aa84c9e \ - --hash=sha256:e39b4732d65fbdcde189ae76cf7cd48aeae72919dea1fdfc16593be016256b45 +typer==0.25.1 \ + --hash=sha256:75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89 \ + --hash=sha256:9616eb8853a09ffeabab1698952f33c6f29ffdbceb4eaeecf571880e8d7664cc # 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.20260408 \ + --hash=sha256:b784dc37908479e3767e2d794ab507b3674adb1c686ca3d13fc9e2960dbcb9ec \ + --hash=sha256:da630647eaaa7a926a3907794f4067f269cd245b2c202c74aa3c6a3bd660a9db # via feast (pyproject.toml) typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ @@ -3014,9 +3030,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 # ibis-framework # pandas @@ -3565,9 +3581,9 @@ yarl==1.23.0 \ --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d # via aiohttp -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==3.23.1 \ + --hash=sha256:0b3596c50a5c700c9cb40ba8d86d9f2cc4807e9bedb06bcdf7fac85633e444dc \ + --hash=sha256:32120e378d32cd9714ad503c1d024619063ec28aad2248dc6672ad13edfa5110 # 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 aaf668ef6ec..84fd434e171 100644 --- a/sdk/python/requirements/py3.10-requirements.txt +++ b/sdk/python/requirements/py3.10-requirements.txt @@ -24,9 +24,9 @@ bigtree==1.4.0 \ --hash=sha256:d0d99550ae64ce4529f132602ab875c2ab472c96c942f5704f8c72a17450d3ea \ --hash=sha256:e5ae2e948168da671d99601c9ed87ab3b48d9d4ea8a98f111e5748e98064c31c # via feast (pyproject.toml) -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +certifi==2026.4.22 \ + --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ + --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 # via requests charset-normalizer==3.4.7 \ --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ @@ -159,9 +159,9 @@ charset-normalizer==3.4.7 \ --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 # via requests -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.3.3 \ + --hash=sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2 \ + --hash=sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 # via # feast (pyproject.toml) # dask @@ -186,13 +186,13 @@ exceptiongroup==1.3.1 \ --hash=sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219 \ --hash=sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598 # via anyio -fastapi==0.135.3 \ - --hash=sha256:9b0f590c813acd13d0ab43dd8494138eb58e484bfac405db1f3187cfc5810d98 \ - --hash=sha256:bd6d7caf1a2bdd8d676843cdcd2287729572a1ef524fc4d65c17ae002a1be654 +fastapi==0.136.1 \ + --hash=sha256:7af665ad7acfa0a3baf8983d393b6b471b9da10ede59c60045f49fbc89a0fa7f \ + --hash=sha256:a6e9d7eeada96c93a4d69cb03836b44fa34e2854accb7244a1ece36cd4781c3f # via feast (pyproject.toml) -fsspec==2026.3.0 \ - --hash=sha256:1ee6a0e28677557f8c2f994e3eea77db6392b4de9cd1f5d7a9e87a0ae9d01b41 \ - --hash=sha256:d2ceafaad1b3457968ed14efa28798162f1638dbb5d2a6868a2db002a5ee39a4 +fsspec==2026.4.0 \ + --hash=sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 \ + --hash=sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4 # via dask gunicorn==25.3.0 \ --hash=sha256:cacea387dab08cd6776501621c295a904fe8e3b7aae9a1a3cbb26f4e7ed54660 \ @@ -249,9 +249,9 @@ httptools==0.7.1 \ --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 # via uvicorn -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.13 \ + --hash=sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242 \ + --hash=sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 # via # anyio # requests @@ -271,97 +271,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.9.0 \ + --hash=sha256:07cf11f769831186eeac424376e6189f20ace4f7263e2134bdb9757340d84d4d \ + --hash=sha256:0a09c2f5869649101738653a9b7ab70cf045a1105ac66cbb8f4055e61df78f2d \ + --hash=sha256:0a1be03168b2691ba61927e299b352a6315189199ca18a57b733f86cb3cc8d38 \ + --hash=sha256:0b73e4266307e51c95e09c0750b7ec383c561d2e97d58e473f6f6a209952fbb8 \ + --hash=sha256:15cb151e52a044f06e54ac7f7b47adbfc89b5c8e2b63e1175a9d587c43e8942a \ + --hash=sha256:194fc1a32e1e21fe809d38b5faea66cc65eaa00217c8901fbdb99866938adbdb \ + --hash=sha256:1bf465d1e5b0a27713862441f6467b5ab76385f4ecf8f1f3a44f8aa3c695b4b6 \ + --hash=sha256:1c587494461ebd42229d0f1739f3aa34237dd9980623ecf1be8d3bcba79f4499 \ + --hash=sha256:224b9727eb8bc188bc3bcf29d969dba0cd61b01d9bac80c41575520cc4baabb2 \ + --hash=sha256:22a904cbdb678f7cb348c90d543d3c52f581663d687992fee47fd566dcbf5285 \ + --hash=sha256:2b8f5d00b49818f4e2b1667db994488b045835e0ac16fe2f924f3871bd2b8ac5 \ + --hash=sha256:2c3786f0f4490a5cd87f1ed6cefae833ad6b1060d52044ce0434a2e85893afd0 \ + --hash=sha256:2d03fa4fd277a7974c1978c92c374c57f44edeee163d147b477b143446ad1bf6 \ + --hash=sha256:2f8e12706dcb8ff6b3ed57514a19e45c49ad00bcd423e87b2b2e4b5f64578443 \ + --hash=sha256:3be322a15ee5e70b93b7a59cfd074614f22cc8c9ff18bd27f474e79137ea8d3b \ + --hash=sha256:3cc2917258e131ae5f958a4d872e07555b51cb7466a43433218061c74ef33745 \ + --hash=sha256:3f05d145df35dca5056a8bc3838e940efebd893a54b3e19b2dda39ceaa299bcb \ + --hash=sha256:3fe56e80badb66fdcde06bef81bbaa5bfcf6fbd7aefb86222d9e369c38c6b228 \ + --hash=sha256:42ff8a962554c350d4a83cf47d9b7b78b0e6ff7943e87df7cdfc97c07f3c016f \ + --hash=sha256:451daa98463b7695b0a30aa56bf637831ea559e7b8101ac2ef6382e8eb15e29c \ + --hash=sha256:465814ab157986acb9dfa5ccd7df944be5eefc0d08d31ec6e8d88bc71251d845 \ + --hash=sha256:4c4d0440a3a8e31d962340c3e1cc3fc9ee7febd34c8d8f770d06adb947779ea5 \ + --hash=sha256:4e3dda8345307fd7306db0ed0cb109a63a2c85ba780eb9dc2d09b2049a931f9c \ + --hash=sha256:5093043afb226ecfa1400120d1ebd4442b4f99977783e4f4f7248879009b227f \ + --hash=sha256:5112c2fb7c2eefefaeaf5c97fec81343ef44ee86a30dcfaa8223822fba6467b4 \ + --hash=sha256:527b5b820b47a09e09829051452bb0d1dd2122261254e2a6f674d12f1d793d54 \ + --hash=sha256:54d412e47c21b85865676ed0724e37a89e9593c2eee1e7367adf85bfad56ffb1 \ + --hash=sha256:56d65b583cf43b8cf4c8fbe1e1da20fa3076cc32a1149a141507af1062718236 \ + --hash=sha256:5ca8e133d799c948db2ab1afc081c333a825b5540475164726dcbf73537e5c2f \ + --hash=sha256:603138ee838ee1583f1b960b62d5d0007845c5c423feb68e44648b1359014e27 \ + --hash=sha256:63c12efcd160e1d14da11af0c46c0217473e1e0d2ae1acbccc83f561ea4c2a7b \ + --hash=sha256:657f8ba7b9eaaa82759a104137aed2a3ef7bc46ccfd43e0d89b04005b3e0a4cc \ + --hash=sha256:66b58fed90a545328e80d575467244de3741e088c1af928f0b489ebec3ef3858 \ + --hash=sha256:6788207daa0c19955d2b668f3294a368d19f67d9b5f274553fd073c1260cbb9f \ + --hash=sha256:703f4ae36d6240bfe24f542bac784c7e4194ec49c3ba5a994d02891649e2d85b \ + --hash=sha256:7202bdcac47d3a708271c4304a474a8605a4a9a4a709e954bf2d3241140aa938 \ + --hash=sha256:756775d25ec8345b837ab52effee3ad2f3b2dfd6bbee3e3f029c517bd5d8f05a \ + --hash=sha256:78042f6facfd98ecb25e9829c7e37cce23363d9d7c83bc5f72702c5059eb082b \ + --hash=sha256:789fff71757facc0738e8d89e3b84e4f0251c1c975e85e81b152cdaca927cc2d \ + --hash=sha256:7bc30ad339f4e1a01d4917d645e522a0bc0030644d8973f6346397c93ba1503f \ + --hash=sha256:7d429bdd4ac0ab17c8e4a8af0ed2a7440b16eba474909ab357131018fe8c7e71 \ + --hash=sha256:7d5c8a5929ac325729f6119802070b561f4db793dffc45e9ac750992a4ed4d22 \ + --hash=sha256:7e6274fd33fc5b2a14d41c9119629d3ff395849d8bcbc80cf637d9e8d2034da8 \ + --hash=sha256:80b25c7b570a86c03b5da69e665809deb39265476e8e21d96a9328f9762f9990 \ + --hash=sha256:81107843ed1836874b46b310f9b1816abcb89912af627868522461c3b7333c0f \ + --hash=sha256:8494cfc61e03542f2d381e71804990b3931175a29b9278fdb4a5459948778dc2 \ + --hash=sha256:850d6d03177e52700af605fd60db7f37dcb89782049a149674d1a9649c2138fd \ + --hash=sha256:8c6bc1384d9738781cfd41d09ad7f6e8af13cfea2c75ece6bd6d2566cdea2076 \ + --hash=sha256:90904fac73c478f4b83f4ed96c99c8208b75e6f9a8a1910548f69a00f1eaa671 \ + --hash=sha256:90e6d5420fc8a300518d4d2288154ff45005e920425c22cbbfe8330f3f754bd9 \ + --hash=sha256:928bd06eca2c2bbf4349e5b817f837509b0604342e65a502de1d50a7570afd15 \ + --hash=sha256:9b3e3bc363f71bda1639a4ee593cb78f7fbfeacc73411ec0d4c92f00730010a4 \ + --hash=sha256:9edcc35d1cae9fd5320171b1a838c7da8a5c968af31e82ecc3dff30b4be0957f \ + --hash=sha256:9fcb461fbf70654a52a7cc670e606f04449e2374c199b1825f754e16dacfedd8 \ + --hash=sha256:a0951822531e7aee6e0dfb556b30d5ee36bbe234faf60c20a16c01be3530869d \ + --hash=sha256:a361c9434a64d70a7dbb771d1de302c0cc9f13c0bffe1cf7e642152814b35265 \ + --hash=sha256:a4b25c6c25cac5d0d9d6d6da855195b254e0021e513e0249f0e3b444dc6e0e61 \ + --hash=sha256:a5af136bfba820d592f86c67affcef9b3ff4d4360ac3255e341e964489b48519 \ + --hash=sha256:a81eea9b999b985e4bacc650c4312805ea7008fd5e45e1bf221310176a7bcb3a \ + --hash=sha256:a9c63e04d003bc0fb6a03b348018b9a3002f98268200e22cc80f146beac5dc40 \ + --hash=sha256:aa95738a68cedd3a6f5492feddc513e2e166b50602958139e47bbdd82da0f5a7 \ + --hash=sha256:b0a2040f801406b93657a70b72fa12311063a319fee72ce98e1524da7200171f \ + --hash=sha256:b8bd70d5d816566a580d193326912f4a76ec2d28a97dc4cd4cc831c0af8e330e \ + --hash=sha256:b8da9f8035bb417770b1e1610526d87ad4fc58a2804dc4d79c53f6d2cf5a6eb9 \ + --hash=sha256:bc5518873822d2faa8ebdd2c1a4d7c8ef47b01a058495ab7924cb65bdbf5fc9a \ + --hash=sha256:c0d620e74897f8c2613b3c4e2e9c1e422eb46d2ddd07df540784d44117836af3 \ + --hash=sha256:c2640e23d2b7c98796f123ffd95cf2022c7777aa8a4a3b98b36c570d37e85eee \ + --hash=sha256:c81aef782380f0f13ead670aae01825eb653b44b046aa0e5ebbb79f76ed4aa11 \ + --hash=sha256:d4d16b608a1c43d7e33142099a75cd93af482dadce0bf82421e91cad077157f4 \ + --hash=sha256:d69fc39e627908f4c03297d5a88d9284b73f4d90b424461e32e8c2485e21c283 \ + --hash=sha256:d9da80e5b04acce03ced8ba6479a71c2a2edf535c2acc0d09c80d2f80f3bad15 \ + --hash=sha256:dd2c7e082b0b92e1baa4da28163a808672485617bc855cc22a2fd06978fa9084 \ + --hash=sha256:de7dac64e3eb832ffc7b840eb8f52f76420cde1b845be51b2a0f6b870890645e \ + --hash=sha256:e0785c2fb4a81e1aece366aa3e2e039f4a4d7d21aaaded5227d7f3c703427882 \ + --hash=sha256:e306d956cfa027fe041585f02a1602c32bfa6bb8ebea4899d373383295a6c62f \ + --hash=sha256:e78fb7419e07d98c2af4b8567b72b3eaf8cb05caad642e9963465569c8b2d87e \ + --hash=sha256:e9002e98dcb1c0a66723592520decd86238ddcef168b37ff6cfb559200b4b774 \ + --hash=sha256:e94cbc6ad9a6aeea46d775cbb11f361022f778a9cc8cc90af653d3a594b057ce \ + --hash=sha256:eea1b54943475f51698f85fa230c65ccac769f1e603b981be060ac5763d90927 \ + --hash=sha256:f100bfe2acf8a3689af9d0cc660d89f17286c9c795f9f18f7b62dd1a6b247ae6 \ + --hash=sha256:f162af66a2ed3f7d1d161a82ca584efd15acd9c1cff190a373458c32f7d42118 \ + --hash=sha256:f24b90b0e0c8cc9491fb1693ae91fe17cb7963153a1946395acdbdd5818429a4 \ + --hash=sha256:f29b68cd9714531672db62cc54f6e8ff981900f824d13fa0e00749189e13778e \ + --hash=sha256:f38bc489037eca88d6ebefc9c4d41a4e07c8e8b4de5188a9e6d290273ad7ebb1 \ + --hash=sha256:f3fd278f5e6bf7c75ccd6d12344eb686cc020712683363b66f46ac79d37c799f \ + --hash=sha256:f4003f70c56a5addd6aa0897f200dd59afd3bf7bcd5b3cce46dd21f925743bc2 \ + --hash=sha256:f48c963a76d71b9d7927eb817b543d0dccd52ab6648b99d37bd54f4cd475d856 \ + --hash=sha256:f819e0c6413e259a17a7c0d49f97f405abadd3c2a316a3b46c6440b7dbbedbb1 \ + --hash=sha256:fc5758e2b7a56532dc33e3c544d78cbaa9ecf0a0f2a2da2df882c1d6b99a317f \ + --hash=sha256:fcbdf2a9ca24e87bbebb47f1fe34e531ef06f104f98c9ccfc953a3f3344c567a # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ @@ -567,51 +567,51 @@ mmh3==5.2.1 \ --hash=sha256:fceef7fe67c81e1585198215e42ad3fdba3a25644beda8fbdaf85f4d7b93175a \ --hash=sha256:fd96476f04db5ceba1cfa0f21228f67c1f7402296f0e73fee3513aa680ad237b # via feast (pyproject.toml) -mypy==1.20.0 \ - --hash=sha256:002b613ae19f4ac7d18b7e168ffe1cb9013b37c57f7411984abbd3b817b0a214 \ - --hash=sha256:00e047c74d3ec6e71a2eb88e9ea551a2edb90c21f993aefa9e0d2a898e0bb732 \ - --hash=sha256:02cca0761c75b42a20a2757ae58713276605eb29a08dd8a6e092aa347c4115ca \ - --hash=sha256:0ecd63f75fdd30327e4ad8b5704bd6d91fc6c1b2e029f8ee14705e1207212489 \ - --hash=sha256:0f42dfaab7ec1baff3b383ad7af562ab0de573c5f6edb44b2dab016082b89948 \ - --hash=sha256:1973868d2adbb4584a3835780b27436f06d1dc606af5be09f187aaa25be1070f \ - --hash=sha256:26c8b52627b6552f47ff11adb4e1509605f094e29815323e487fc0053ebe93d1 \ - --hash=sha256:2721f0ce49cb74a38f00c50da67cb7d36317b5eda38877a49614dc018e91c787 \ - --hash=sha256:2fcedb16d456106e545b2bfd7ef9d24e70b38ec252d2a629823a4d07ebcdb69e \ - --hash=sha256:31b5dbb55293c1bd27c0fc813a0d2bb5ceef9d65ac5afa2e58f829dab7921fd5 \ - --hash=sha256:34506397dbf40c15dc567635d18a21d33827e9ab29014fb83d292a8f4f8953b6 \ - --hash=sha256:367e5c993ba34d5054d11937d0485ad6dfc60ba760fa326c01090fc256adf15c \ - --hash=sha256:379edf079ce44ac8d2805bcf9b3dd7340d4f97aad3a5e0ebabbf9d125b84b442 \ - --hash=sha256:39362cdb4ba5f916e7976fccecaab1ba3a83e35f60fa68b64e9a70e221bb2436 \ - --hash=sha256:4525e7010b1b38334516181c5b81e16180b8e149e6684cee5a727c78186b4e3b \ - --hash=sha256:47781555a7aa5fedcc2d16bcd72e0dc83eb272c10dd657f9fb3f9cc08e2e6abb \ - --hash=sha256:49d11c6f573a5a08f77fad13faff2139f6d0730ebed2cfa9b3d2702671dd7188 \ - --hash=sha256:555493c44a4f5a1b58d611a43333e71a9981c6dbe26270377b6f8174126a0526 \ - --hash=sha256:555658c611099455b2da507582ea20d2043dfdfe7f5ad0add472b1c6238b433f \ - --hash=sha256:697f102c5c1d526bdd761a69f17c6070f9892eebcb94b1a5963d679288c09e78 \ - --hash=sha256:76a70bf840495729be47510856b978f1b0ec7d08f257ca38c9d932720bf6b43e \ - --hash=sha256:7d3243c406773185144527f83be0e0aefc7bf4601b0b2b956665608bf7c98a83 \ - --hash=sha256:931a7630bba591593dcf6e97224a21ff80fb357e7982628d25e3c618e7f598ef \ - --hash=sha256:9804c3ad27f78e54e58b32e7cb532d128b43dbfb9f3f9f06262b821a0f6bd3f5 \ - --hash=sha256:a17c5d0bdcca61ce24a35beb828a2d0d323d3fcf387d7512206888c900193367 \ - --hash=sha256:a6e0641147cbfa7e4e94efdb95c2dab1aff8cfc159ded13e07f308ddccc8c48e \ - --hash=sha256:a79c1eba7ac4209f2d850f0edd0a2f8bba88cbfdfefe6fb76a19e9d4fe5e71a2 \ - --hash=sha256:a9336b5e6712f4adaf5afc3203a99a40b379049104349d747eb3e5a3aa23ac2e \ - --hash=sha256:b20c8b0fd5877abdf402e79a3af987053de07e6fb208c18df6659f708b535134 \ - --hash=sha256:b3a49064504be59e59da664c5e149edc1f26c67c4f8e8456f6ba6aba55033018 \ - --hash=sha256:b503ab55a836136b619b5fc21c8803d810c5b87551af8600b72eecafb0059cb0 \ - --hash=sha256:bd0212976dc57a5bfeede7c219e7cd66568a32c05c9129686dd487c059c1b88a \ - --hash=sha256:c70380fe5d64010f79fb863b9081c7004dd65225d2277333c219d93a10dad4dd \ - --hash=sha256:d99f515f95fd03a90875fdb2cca12ff074aa04490db4d190905851bdf8a549a8 \ - --hash=sha256:e80cf77847d0d3e6e3111b7b25db32a7f8762fd4b9a3a72ce53fe16a2863b281 \ - --hash=sha256:eb96c84efcc33f0b5e0e04beacf00129dd963b67226b01c00b9dfc8affb464c3 \ - --hash=sha256:ebea00201737ad4391142808ed16e875add5c17f676e0912b387739f84991e13 \ - --hash=sha256:efe8d70949c3023698c3fca1e94527e7e790a361ab8116f90d11221421cd8726 \ - --hash=sha256:f13b3e41bce9d257eded794c0f12878af3129d80aacd8a3ee0dee51f3a978651 \ - --hash=sha256:f194db59657c58593a3c47c6dfd7bad4ef4ac12dbc94d01b3a95521f78177e33 \ - --hash=sha256:f49590891d2c2f8a9de15614e32e459a794bcba84693c2394291a2038bbaaa69 \ - --hash=sha256:f75ff57defcd0f1d6e006d721ccdec6c88d4f6a7816eb92f1c4890d979d9ee62 \ - --hash=sha256:f799d9db89fc00446f03281f84a221e50018fc40113a3ba9864b132895619ebe \ - --hash=sha256:f8426d4d75d68714abc17a4292d922f6ba2cfb984b72c2278c437f6dae797865 +mypy==1.20.2 \ + --hash=sha256:0c64e5973df366b747646fc98da921f9d6eba9716d57d1db94a83c026a08e0fb \ + --hash=sha256:0deb80d062b2479f2c87ae568f89845afc71d11bc41b04179e58165fd9f31e98 \ + --hash=sha256:1e1c12f6d2db3d78b909b5f77513c11eb7f2dd2782b96a3ab6dffc7d44575c99 \ + --hash=sha256:20175a1c0f49863946ec20b7f63255768058ac4f07d2b9ded6a6b46cfb5a9100 \ + --hash=sha256:29752dbbf8cc53f89f6ac096d363314333045c257c9c75cbd189ca2de0455744 \ + --hash=sha256:2a4102b03bb7481d9a91a6da8d174740c9c8c4401024684b9ca3b7cc5e49852f \ + --hash=sha256:2de3dcea53babc1c3237a19002bc3d228ce1833278f093b8d619e06e7cc79609 \ + --hash=sha256:34397cdced6b90b836e38182076049fdb41424322e0b0728c946b0939ebdf9f6 \ + --hash=sha256:4077797a273e56e8843d001e9dfe4ba10e33323d6ade647ff260e5cd97d9758c \ + --hash=sha256:419413398fe250aae057fd2fe50166b61077083c9b82754c341cf4fd73038f30 \ + --hash=sha256:4b6481b228d072315b053210b01ac320e1be243dc17f9e5887ef167f23f5fae4 \ + --hash=sha256:4dbfcf869f6b0517f70cf0030ba6ea1d6645e132337a7d5204a18d8d5636c02b \ + --hash=sha256:4fef51b01e638974a6e69885687e9bd40c8d1e09a6cd291cca0619625cf1f558 \ + --hash=sha256:52b176444e2e5054dfcbcb8c75b0b719865c96247b37407184bbfca5c353f2c2 \ + --hash=sha256:56908d7e08318d39f85b1f0c6cfd47b0cac1a130da677630dac0de3e0623e102 \ + --hash=sha256:5a65aa591af023864fd08a97da9974e919452cfe19cb146c8a5dc692626445dc \ + --hash=sha256:688c3312e5dadb573a2c69c82af3a298d43ecf9e6d264e0f95df960b5f6ac19c \ + --hash=sha256:6e2b469efd811707bc530fd1effef0f5d6eebcb7fe376affae69025da4b979a2 \ + --hash=sha256:7488448de6007cd5177c6cea0517ac33b4c0f5ee9b5e9f2be51ce75511a85517 \ + --hash=sha256:785b08db19c9f214dc37d65f7c165d19a30fcecb48abfa30f31b01b5acaabb58 \ + --hash=sha256:7b0e817b518bff7facd7f85ea05b643ad8bdcce684cf29784987b0a7c8e1f997 \ + --hash=sha256:803203d2b6ea644982c644895c2f78b28d0e208bba7b27d9b921e0ec5eb207c6 \ + --hash=sha256:89dce27e142d25ffbc154c1819383b69f2e9234dc4ed4766f42e0e8cb264ab5c \ + --hash=sha256:913485a03f1bcf5d279409a9d2b9ed565c151f61c09f29991e5faa14033da4c8 \ + --hash=sha256:97d7b9a485b40f8ca425460e89bf1da2814625b2da627c0dcc6aa46c92631d14 \ + --hash=sha256:9bcb8aa397ff0093c824182fd76a935a9ba7ad097fcbef80ae89bf6c1731d8ec \ + --hash=sha256:9d56a78b646f2e3daa865bc70cd5ec5a46c50045801ca8ff17a0c43abc97e3ee \ + --hash=sha256:a5da6976f20cae27059ea8d0c86e7cef3de720e04c4bb9ee18e3690fdb792066 \ + --hash=sha256:a94c5a76ab46c5e6257c7972b6c8cff0574201ca7dc05647e33e795d78680563 \ + --hash=sha256:a95a9248b0c6fd933a442c03c3b113c3b61320086b88e2c444676d3fd1ca3330 \ + --hash=sha256:baf593f2765fa3a6b1ef95807dbaa3d25b594f6a52adcc506a6b9cb115e1be67 \ + --hash=sha256:bb9c2fa06887e21d6a3a868762acb82aec34e2c6fd0174064f27c93ede68ad15 \ + --hash=sha256:bba9ad231e92a3e424b3e56b65aa17704993425bba97e302c832f9466bb85bac \ + --hash=sha256:c3bae4f855d965b5453784300c12ffc63a548304ac7f99e55d4dc7c898673aa3 \ + --hash=sha256:c566c3a88b6ece59b3d70f65bedef17304f48eb52ff040a6a18214e1917b3254 \ + --hash=sha256:cdecf62abcc4292500d7858aeae87a1f8f1150f4c4dd08fb0b336ee79b2a6df3 \ + --hash=sha256:cf5a4db6dca263010e2c7bff081c89383c72d187ba2cf4c44759aac970e2f0c4 \ + --hash=sha256:d52ad8d78522da1d308789df651ee5379088e77c76cb1994858d40a426b343b9 \ + --hash=sha256:e061b58443f1736f8a37c48978d7ab581636d6ab03e3d4f99e3fa90463bb9382 \ + --hash=sha256:e2877a02380adfcdbc69071a0f74d6e9dbbf593c0dc9d174e1f223ffd5281943 \ + --hash=sha256:e73c07f23009962885c197ccb9b41356a30cc0e5a1d0c2ea8fd8fb1362d7f924 \ + --hash=sha256:e8222c26daaafd9e8626dec58ae36029f82585890589576f769a650dd20fd665 \ + --hash=sha256:edfbfca868cdd6bd8d974a60f8a3682f5565d3f5c99b327640cedd24c4264026 \ + --hash=sha256:f376e37f9bf2a946872fc5fd1199c99310748e3c26c7a26683f13f8bdb756cbd # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ @@ -677,9 +677,9 @@ numpy==2.2.6 \ # feast (pyproject.toml) # dask # pandas -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # gunicorn @@ -746,13 +746,13 @@ 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 +prometheus-client==0.25.0 \ + --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ + --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 # via feast (pyproject.toml) protobuf==7.34.1 \ --hash=sha256:34b84ce27680df7cca9f231043ada0daa55d0c44a2ddfaa58ec1d0d89d8bf60a \ @@ -787,188 +787,187 @@ 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.3 \ + --hash=sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927 \ + --hash=sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d # 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.3 \ + --hash=sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba \ + --hash=sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35 \ + --hash=sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4 \ + --hash=sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505 \ + --hash=sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7 \ + --hash=sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8 \ + --hash=sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4 \ + --hash=sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37 \ + --hash=sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25 \ + --hash=sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022 \ + --hash=sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1 \ + --hash=sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7 \ + --hash=sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c \ + --hash=sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3 \ + --hash=sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb \ + --hash=sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3 \ + --hash=sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976 \ + --hash=sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c \ + --hash=sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab \ + --hash=sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa \ + --hash=sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6 \ + --hash=sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396 \ + --hash=sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c \ + --hash=sha256:3d08782c4045f90724b44c95d35ebec0d67edb8a957a2ac81d5a8e4b8a200495 \ + --hash=sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c \ + --hash=sha256:4335e87c7afa436a0dfa899e138d57a72f8aad542e2cf19c36fb428461caabd0 \ + --hash=sha256:4b068543bdb707f5d935dab765d99227aa2545ef2820935f2e5dd801795c7dbd \ + --hash=sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf \ + --hash=sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531 \ + --hash=sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5 \ + --hash=sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda \ + --hash=sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d \ + --hash=sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e \ + --hash=sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df \ + --hash=sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6 \ + --hash=sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c \ + --hash=sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13 \ + --hash=sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536 \ + --hash=sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287 \ + --hash=sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0 \ + --hash=sha256:68ef2f623dda6d5a9067ac014e406c020c780b2a358930a7e5c1b73702900720 \ + --hash=sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050 \ + --hash=sha256:6dff8cc884679df229ebc6d8eb2321ea6f8e091bc7d4886d4dc2e0e71452843c \ + --hash=sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1 \ + --hash=sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8 \ + --hash=sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0 \ + --hash=sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374 \ + --hash=sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807 \ + --hash=sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6 \ + --hash=sha256:831eb19aa789a97356979e94c981e5667759301fb708d1c0d5adf1bc0098b873 \ + --hash=sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57 \ + --hash=sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f \ + --hash=sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c \ + --hash=sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad \ + --hash=sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e \ + --hash=sha256:91249bcb7c165c2fb2a2f852dbc5c91636e2e218e75d96dfdd517e4078e173dd \ + --hash=sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23 \ + --hash=sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46 \ + --hash=sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1 \ + --hash=sha256:99421e7684a60f7f3550a1d159ade5fdff1954baedb6bdd407cba6a307c9f27d \ + --hash=sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1 \ + --hash=sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee \ + --hash=sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c \ + --hash=sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874 \ + --hash=sha256:9f247596366f4221af52beddd65af1218797771d6989bc891a0b86ccaa019168 \ + --hash=sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a \ + --hash=sha256:a35cc284c8dd7edae8a31533713b4d2467dfe7c4f1b5587dd4031f28f90d1d13 \ + --hash=sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f \ + --hash=sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a \ + --hash=sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789 \ + --hash=sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe \ + --hash=sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f \ + --hash=sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5 \ + --hash=sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943 \ + --hash=sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b \ + --hash=sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089 \ + --hash=sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b \ + --hash=sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff \ + --hash=sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67 \ + --hash=sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803 \ + --hash=sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045 \ + --hash=sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8 \ + --hash=sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346 \ + --hash=sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2 \ + --hash=sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f \ + --hash=sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687 \ + --hash=sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76 \ + --hash=sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1 \ + --hash=sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f \ + --hash=sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2 \ + --hash=sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c \ + --hash=sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018 \ + --hash=sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba \ + --hash=sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c \ + --hash=sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf \ + --hash=sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7 \ + --hash=sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47 \ + --hash=sha256:d56bdb4af1767cc15b0386b3c581fdfe659bb9ee4a4f776e92c1cd9d074000d6 \ + --hash=sha256:dcda6583921c05a40533f982321532f2d8db29326c7b95c4026941fa5074bd79 \ + --hash=sha256:dd81f6907932ebac3abbe41378dac64b2380db1287e2aa64d8d88f78d170f51a \ + --hash=sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e \ + --hash=sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a \ + --hash=sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34 \ + --hash=sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b \ + --hash=sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85 \ + --hash=sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca \ + --hash=sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f \ + --hash=sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3 \ + --hash=sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64 \ + --hash=sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22 \ + --hash=sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72 \ + --hash=sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec \ + --hash=sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d \ + --hash=sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3 \ + --hash=sha256:fa3eb7c2995aa443687a825bc30395c8521b7c6ec201966e55debfd1128bcceb \ + --hash=sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395 \ + --hash=sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb \ + --hash=sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4 \ + --hash=sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127 \ + --hash=sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56 # via pydantic pygments==2.20.0 \ --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ @@ -1201,70 +1200,70 @@ 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.49 \ + --hash=sha256:01146546d84185f12721a1d2ce0c6673451a7894d1460b592d378ca4871a0c72 \ + --hash=sha256:059d7151fff513c53a4638da8778be7fce81a0c4854c7348ebd0c4078ddf28fe \ + --hash=sha256:0c98c59075b890df8abfcc6ad632879540f5791c68baebacb4f833713b510e75 \ + --hash=sha256:0f2fa354ba106eafff2c14b0cc51f22801d1e8b2e4149342023bd6f0955de5f5 \ + --hash=sha256:12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148 \ + --hash=sha256:22d8798819f86720bc646ab015baff5ea4c971d68121cb36e2ebc2ee43ead2b7 \ + --hash=sha256:233088b4b99ebcbc5258c755a097aa52fbf90727a03a5a80781c4b9c54347a2e \ + --hash=sha256:24bd94bb301ec672d8f0623eba9226cc90d775d25a0c92b5f8e4965d7f3a1518 \ + --hash=sha256:275424295f4256fd301744b8f335cff367825d270f155d522b30c7bf49903ee7 \ + --hash=sha256:32fe6a41ad97302db2931f05bb91abbcc65b5ce4c675cd44b972428dd2947700 \ + --hash=sha256:334edbcff10514ad1d66e3a70b339c0a29886394892490119dbb669627b17717 \ + --hash=sha256:3bb9ec6436a820a4c006aad1ac351f12de2f2dbdaad171692ee457a02429b672 \ + --hash=sha256:3ddcb27fb39171de36e207600116ac9dfd4ae46f86c82a9bf3934043e80ebb88 \ + --hash=sha256:42e8804962f9e6f4be2cbaedc0c3718f08f60a16910fa3d86da5a1e3b1bfe60f \ + --hash=sha256:43d044780732d9e0381ac8d5316f95d7f02ef04d6e4ef6dc82379f09795d993f \ + --hash=sha256:46796877b47034b559a593d7e4b549aba151dae73f9e78212a3478161c12ab08 \ + --hash=sha256:46d51518d53edfbe0563662c96954dc8fcace9832332b914375f45a99b77cc9a \ + --hash=sha256:47604cb2159f8bbd5a1ab48a714557156320f20871ee64d550d8bf2683d980d3 \ + --hash=sha256:4bbccb45260e4ff1b7db0be80a9025bb1e6698bdb808b83fff0000f7a90b2c0b \ + --hash=sha256:4d4e5a0ceba319942fa6b585cf82539288a61e314ef006c1209f734551ab9536 \ + --hash=sha256:55250fe61d6ebfd6934a272ee16ef1244e0f16b7af6cd18ab5b1fc9f08631db0 \ + --hash=sha256:566df36fd0e901625523a5a1835032f1ebdd7f7886c54584143fa6c668b4df3b \ + --hash=sha256:57ca426a48eb2c682dae8204cd89ea8ab7031e2675120a47924fabc7caacbc2a \ + --hash=sha256:5e61abbec255be7b122aa461021daa7c3f310f3e743411a67079f9b3cc91ece3 \ + --hash=sha256:618a308215b6cececb6240b9abde545e3acdabac7ae3e1d4e666896bf5ba44b4 \ + --hash=sha256:62557958002b69699bdb7f5137c6714ca1133f045f97b3903964f47db97ea339 \ + --hash=sha256:6270d717b11c5476b0cbb21eedc8d4dbb7d1a956fd6c15a23e96f197a6193158 \ + --hash=sha256:685e93e9c8f399b0c96a624799820176312f5ceef958c0f88215af4013d29066 \ + --hash=sha256:69469ce8ce7a8df4d37620e3163b71238719e1e2e5048d114a1b6ce0fbf8c662 \ + --hash=sha256:6eb188b84269f357669b62cb576b5b918de10fb7c728a005fa0ebb0b758adce1 \ + --hash=sha256:74ab4ee7794d7ed1b0c37e7333640e0f0a626fc7b398c07a7aef52f484fddde3 \ + --hash=sha256:77641d299179c37b89cf2343ca9972c88bb6eef0d5fc504a2f86afd15cd5adf5 \ + --hash=sha256:7c821c47ecfe05cc32140dcf8dc6fd5d21971c86dbd56eabfe5ba07a64910c01 \ + --hash=sha256:7d6be30b2a75362325176c036d7fb8d19e8846c77e87683ffaa8177b35135613 \ + --hash=sha256:7f605a456948c35260e7b2a39f8952a26f077fd25653c37740ed186b90aaa68a \ + --hash=sha256:83101a6930332b87653886c01d1ee7e294b1fe46a07dd9a2d2b4f91bcc88eec0 \ + --hash=sha256:88690f4e1f0fbf5339bedbb127e240fec1fd3070e9934c0b7bef83432f779d2f \ + --hash=sha256:8a97ac839c2c6672c4865e48f3cbad7152cee85f4233fb4ca6291d775b9b954a \ + --hash=sha256:8d6efc136f44a7e8bc8088507eaabbb8c2b55b3dbb63fe102c690da0ddebe55e \ + --hash=sha256:8e20e511dc15265fb433571391ba313e10dd8ea7e509d51686a51313b4ac01a2 \ + --hash=sha256:951d4a210744813be63019f3df343bf233b7432aadf0db54c75802247330d3af \ + --hash=sha256:9ac7a3e245fd0310fd31495eb61af772e637bdf7d88ee81e7f10a3f271bff014 \ + --hash=sha256:9b1c058c171b739e7c330760044803099c7fff11511e3ab3573e5327116a9c33 \ + --hash=sha256:9c04bff9a5335eb95c6ecf1c117576a0aa560def274876fd156cfe5510fccc61 \ + --hash=sha256:9c4969a86e41454f2858256c39bdfb966a20961e9b58bf8749b65abf447e9a8d \ + --hash=sha256:9e0400fa22f79acc334d9a6b185dc00a44a8e6578aa7e12d0ddcd8434152b187 \ + --hash=sha256:a05977bffe9bffd2229f477fa75eabe3192b1b05f408961d1bebff8d1cd4d401 \ + --hash=sha256:a143af2ea6672f2af3f44ed8f9cd020e9cc34c56f0e8db12019d5d9ecf41cb3b \ + --hash=sha256:a51d3db74ba489266ef55c7a4534eb0b8db9a326553df481c11e5d7660c8364d \ + --hash=sha256:b95b2f470c1b2683febd2e7eab1d3f0e078c91dbdd0b00e9c645d07a413bb99f \ + --hash=sha256:b9870d15ef00e4d0559ae10ee5bc71b654d1f20076dbe8bc7ed19b4c0625ceba \ + --hash=sha256:c1dc3368794d522f43914e03312202523cc89692f5389c32bea0233924f8d977 \ + --hash=sha256:c338ec6ec01c0bc8e735c58b9f5d51e75bacb6ff23296658826d7cfdfdb8678a \ + --hash=sha256:c5070135e1b7409c4161133aa525419b0062088ed77c92b1da95366ec5cbebbe \ + --hash=sha256:cc992c6ed024c8c3c592c5fc9846a03dd68a425674900c70122c77ea16c5fb0b \ + --hash=sha256:d15950a57a210e36dd4cec1aac22787e2a4d57ba9318233e2ef8b2daf9ff2d5f \ + --hash=sha256:d898cc2c76c135ef65517f4ddd7a3512fb41f23087b0650efb3418b8389a3cd1 \ + --hash=sha256:d99945830a6f3e9638d89a28ed130b1eb24c91255e4f24366fbe699b983f29e4 \ + --hash=sha256:da9b91bca419dc9b9267ffadde24eae9b1a6bffcd09d0a207e5e3af99a03ce0d \ + --hash=sha256:df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120 \ + --hash=sha256:e06e617e3d4fd9e51d385dfe45b077a41e9d1b033a7702551e3278ac597dc750 \ + --hash=sha256:ec44cfa7ef1a728e88ad41674de50f6db8cfdb3e2af84af86e0041aaf02d43d0 \ + --hash=sha256:fb37f15714ec2652d574f021d479e78cd4eb9d04396dca36568fdfffb3487982 # via feast (pyproject.toml) starlette==1.0.0 \ --hash=sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149 \ @@ -1368,9 +1367,9 @@ 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 \ @@ -1611,7 +1610,7 @@ websockets==16.0 \ --hash=sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da \ --hash=sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4 # via uvicorn -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==3.23.1 \ + --hash=sha256:0b3596c50a5c700c9cb40ba8d86d9f2cc4807e9bedb06bcdf7fac85633e444dc \ + --hash=sha256:32120e378d32cd9714ad503c1d024619063ec28aad2248dc6672ad13edfa5110 # via importlib-metadata diff --git a/sdk/python/requirements/py3.11-ci-requirements.txt b/sdk/python/requirements/py3.11-ci-requirements.txt index 2d496a89f36..d6d91e0f371 100644 --- a/sdk/python/requirements/py3.11-ci-requirements.txt +++ b/sdk/python/requirements/py3.11-ci-requirements.txt @@ -255,9 +255,9 @@ attrs==26.1.0 \ # jsonschema # openlineage-python # referencing -azure-core==1.39.0 \ - --hash=sha256:4ac7b70fab5438c3f68770649a78daf97833caa83827f91df9c14e0e0ea7d34f \ - --hash=sha256:8a90a562998dd44ce84597590fff6249701b98c0e8797c95fcdd695b54c35d74 +azure-core==1.40.0 \ + --hash=sha256:7f3ea02579b1bb1d34e45043423b650621d11d7c2ea3b05e5554010080b78dfd \ + --hash=sha256:ecf5b6ddf2564471fae9d576147b7e77a4da285958b2d9f4fd6c3af104f3e9d7 # via # azure-identity # azure-storage-blob @@ -370,49 +370,44 @@ botocore==1.38.46 \ # moto # s3transfer # snowflake-connector-python -build==1.4.2 \ - --hash=sha256:35b14e1ee329c186d3f08466003521ed7685ec15ecffc07e68d706090bf161d1 \ - --hash=sha256:7a4d8651ea877cb2a89458b1b198f2e69f536c95e89129dbf5d448045d60db88 +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 +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.4.22 \ + --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ + --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 # via # clickhouse-connect # docling @@ -650,9 +645,9 @@ charset-normalizer==3.4.7 \ # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.3.3 \ + --hash=sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2 \ + --hash=sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 # via # feast (pyproject.toml) # dask @@ -1000,9 +995,9 @@ dask[dataframe]==2026.3.0 \ --hash=sha256:be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d \ --hash=sha256:f7d96c8274e8a900d217c1ff6ea8d1bbf0b4c2c21e74a409644498d925eb8f85 # via feast (pyproject.toml) -datasets==4.8.4 \ - --hash=sha256:a1429ed853275ce7943a01c6d2e25475b4501eb758934362106a280470df3a52 \ - --hash=sha256:cdc8bee4698e549d78bf1fed6aea2eebc760b22b084f07e6fc020c6577a6ce6d +datasets==4.8.5 \ + --hash=sha256:0f0c1c3d56ffff2c93b2f4c63c95bac94f3d7e8621aea2a2a576275233bba772 \ + --hash=sha256:5079900781719c0e063a8efdd2cd95a31ad0c63209178669cd23cf1b926149ff # via feast (pyproject.toml) db-dtypes==1.5.1 \ --hash=sha256:901099b807c9312bc61a5bddbfb07512884e6c6d5a9edacf24d50bcf303aa5f7 \ @@ -1010,9 +1005,9 @@ db-dtypes==1.5.1 \ # via # google-cloud-bigquery # pandas-gbq -dbt-artifacts-parser==0.13.0 \ - --hash=sha256:304f2b857650566fed4ed8b976ed3582332eda3cedfe7167158dbbcfced3fe47 \ - --hash=sha256:55498e8bd0d9064d56617f9c714ced8607d94ccb61e70d4b49dcfd8a28a030d8 +dbt-artifacts-parser==0.13.1 \ + --hash=sha256:c341730fa34ebb38cc7d2de0282e8b713e2fc65fc6577f0d944f8abee8949dc4 \ + --hash=sha256:c7a3c4e309ae2d7d566a615e92043b0d346a77998203b0cc466234717b806e40 # via feast (pyproject.toml) debugpy==1.8.20 \ --hash=sha256:077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad \ @@ -1065,6 +1060,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 @@ -1080,6 +1079,12 @@ distlib==0.4.0 \ --hash=sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 \ --hash=sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d # 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 @@ -1088,16 +1093,16 @@ docling==2.27.0 \ --hash=sha256:1288ed75b27e33bf94daff34faffc6d11b7d7ccc13e3df84fb24adad3991f72d \ --hash=sha256:faba35662612a2c687a3a463e501d95f645316436084af92a0442ce162429a3d # via feast (pyproject.toml) -docling-core[chunking]==2.71.0 \ - --hash=sha256:4761857816853b2b35263b5b4518e1ea6214e0565db0bbf1d929fb976665d1a0 \ - --hash=sha256:4caa9f50c68b9dd332584ae16170b36db05d773532b14d7078b580d89d8bd2a4 +docling-core[chunking]==2.74.1 \ + --hash=sha256:46bf298686f2c51ddd69b6935a27dff1cc80838f2f5f1a8823492d99cf1a357b \ + --hash=sha256:e6464078012b3d45f4e0accd101fcb277063903f355eabbb9aee8de00527a789 # via # docling # docling-ibm-models # docling-parse -docling-ibm-models==3.13.0 \ - --hash=sha256:a11acc6034b06e0bed8dc0ca1fa700615b8246eacce411619168e1f6562b0d0d \ - --hash=sha256:f402effae8a63b0e5c3b5ce13120601baa2cd8098beef1d53ab5a056443758d3 +docling-ibm-models==3.13.2 \ + --hash=sha256:195e02dd119df34d2ce5f76ac614da82825851013e4898db7b0468cdf8740a3d \ + --hash=sha256:5fa0838bf15a4e06d2fcb686d756a6f4c329ea0a8820d085f06d07abe96269ed # via docling docling-parse==4.7.3 \ --hash=sha256:1790e7e4ae202d67875c1c48fd6f8ef5c51d10b0c23157e4989b8673f2f31308 \ @@ -1132,42 +1137,42 @@ docutils==0.19 \ --hash=sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6 \ --hash=sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc # via sphinx -duckdb==1.5.1 \ - --hash=sha256:054ad424b051b334052afac58cb216f3b1ebb8579fc8c641e60f0182e8725ea9 \ - --hash=sha256:05fc91767d0cfc4cf2fa68966ab5b479ac07561752e42dd0ae30327bd160f64a \ - --hash=sha256:0a6acc2040bec1f05de62a2f3f68f4c12f3ec7d6012b4317d0ab1a195af26225 \ - --hash=sha256:26e56b5f0c96189e3288d83cf7b476e23615987902f801e5788dee15ee9f24a9 \ - --hash=sha256:36e8e32621a9e2a9abe75dc15a4b54a3997f2d8b1e53ad754bae48a083c91130 \ - --hash=sha256:40c5220ec93790b18ec6278da9c6ac2608d997ee6d6f7cd44c5c3992764e8e71 \ - --hash=sha256:446d500a2977c6ae2077f340c510a25956da5c77597175c316edfa87248ceda3 \ - --hash=sha256:46f92ada9023e59f27edc048167b31ac9a03911978b1296c845a34462a27f096 \ - --hash=sha256:482f8a13f2600f527e427f73c42b5aa75536f9892868068f0aaf573055a0135f \ - --hash=sha256:553c273a6a8f140adaa6da6a6135c7f95bdc8c2e5f95252fcdf9832d758e2141 \ - --hash=sha256:5ae7c0d744d64e2753149634787cc4ab60f05ef1e542b060eeab719f3cdb7723 \ - --hash=sha256:5d4147422d91ccdc2d2abf6ed24196025e020259d1d267970ae20c13c2ce84b1 \ - --hash=sha256:6af347debc8b721aa72e48671166282da979d5e5ae52dbc660ab417282b48e23 \ - --hash=sha256:6ba302115f63f6482c000ccfd62efdb6c41d9d182a5bcd4a90e7ab8cd13856eb \ - --hash=sha256:6f7361d66cc801d9eb4df734b139cd7b0e3c257a16f3573ebd550ddb255549e6 \ - --hash=sha256:715f05ea198d20d7f8b407b9b84e0023d17f2b9096c194cea702b7840e74f1f7 \ - --hash=sha256:71dddcebbc5a70e946a06c30b59b5dd7999c9833d307168f90fb4e4b672ab63e \ - --hash=sha256:8150c569b2aa4573b51ba8475e814aa41fd53a3d510c1ffb96f1139f46faf611 \ - --hash=sha256:8843bd9594e1387f1e601439e19ad73abdf57356104fd1e53a708255bb95a13d \ - --hash=sha256:8c0088765747ae5d6c9f89987bb36f9fb83564f07090d721344ce8e1abedffea \ - --hash=sha256:972d0dbf283508f9bc446ee09c3838cb7c7f114b5bdceee41753288c97fe2f7c \ - --hash=sha256:a28531cee2a5a42d89f9ba4da53bfeb15681f12acc0263476c8705380dadce07 \ - --hash=sha256:a3be2072315982e232bfe49c9d3db0a59ba67b2240a537ef42656cc772a887c7 \ - --hash=sha256:ac2804043bd1bc10b5da18f8f4c706877197263a510c41be9b4c0062f5783dcc \ - --hash=sha256:afab8b4b1f4469c3879bb049dd039f8fce402712050324e9524a43d7324c5e87 \ - --hash=sha256:b370d1620a34a4538ef66524fcee9de8171fa263c701036a92bc0b4c1f2f9c6d \ - --hash=sha256:b8b0808dba0c63b7633bdaefb34e08fe0612622224f9feb0e7518904b1615101 \ - --hash=sha256:bc7ca6a1a40e7e4c933017e6c09ef18032add793df4e42624c6c0c87e0bebdad \ - --hash=sha256:caa65e1f5bf007430bf657c37cab7ab81a4ddf8d337e3062bcc5085d17ef038b \ - --hash=sha256:d68c5a01a283cb13b79eafe016fe5869aa11bff8c46e7141c70aa0aac808010f \ - --hash=sha256:da137802688190835b4c863cafa77fd7e29dff662ee6d905a9ffc14f00299c91 \ - --hash=sha256:e56a20ab6cdb90a95b0c99652e28de3504ce77129087319c03c9098266183ae5 \ - --hash=sha256:e878ccb7d20872065e1597935fdb5e65efa43220c8edd0d9c4a1a7ff1f3eb277 \ - --hash=sha256:eba81e0b3011c1f23df7ea47ef4ffaa8239817959ae291515b6efd068bde2161 \ - --hash=sha256:ed6d23a3f806898e69c77430ebd8da0c79c219f97b9acbc9a29a653e09740c59 +duckdb==1.5.2 \ + --hash=sha256:0b291786014df1133f8f18b9df4d004484613146e858d71a21791e0fcca16cf4 \ + --hash=sha256:2323c1195c10fb2bb982fc0218c730b43d1b92a355d61e68e3c5f3ac9d44c34f \ + --hash=sha256:2a1de4f4d454b8c97aec546c82003fc834d3422ce4bc6a19902f3462ef293bed \ + --hash=sha256:35579b8e3a064b5eaf15b0eafc558056a13f79a0a62e34cc4baf57119daecfec \ + --hash=sha256:376856066c65ccd55fcb3a380bbe33a71ce089fc4623d229ffc6e82251afdb6d \ + --hash=sha256:411ad438bd4140f189a10e7f515781335962c5d18bd07837dc6d202e3985253d \ + --hash=sha256:4420b3f47027a7849d0e1815532007f377fa95ee5810b47ea717d35525c12f79 \ + --hash=sha256:486c862bf7f163c0110b6d85b3e5c031d224a671cca468f12ebb1d3a348f6b39 \ + --hash=sha256:52a21823f3fbb52f0f0e5425e20b07391ad882464b955879499b5ff0b45a376b \ + --hash=sha256:5596bbfc31b1b259db69c8d847b42d036ce2c4804f9ccb28f9fc46a16de7bc53 \ + --hash=sha256:56d38b3c4e0ef2abb58898d0fd423933999ed535c45e75e9d9f72e1d5fed69b8 \ + --hash=sha256:638da0d5102b6cb6f7d47f83d0600708ac1d3cb46c5e9aaabc845f9ba4d69246 \ + --hash=sha256:63bf8687feefeed51adf45fa3b062ab8b1b1c350492b7518491b86bae68b1da1 \ + --hash=sha256:6b0fe75c148000f060aa1a27b293cacc0ea08cc1cad724fbf2143d56070a3785 \ + --hash=sha256:70631c847ca918ee710ec874241b00cf9d2e5be90762cbb2a0389f17823c08f7 \ + --hash=sha256:7f69164b048e498b9e9140a24343108a5ae5f17bfb3485185f55fdf9b1aa924d \ + --hash=sha256:81fc4fbf0b5e25840b39ba2a10b78c6953c0314d5d0434191e7898f34ab1bba3 \ + --hash=sha256:84b193aca20565dedb3172de15f843c659c3a6c773bf14843a9bd781c850e7db \ + --hash=sha256:8d599758b4e48bf12e18c9b960cf491d219f0c4972d19a45489c05cc5ab36f83 \ + --hash=sha256:8dbd7e31e5dc157bfe8803fa7d2652336265c6c19926c5a4a9b40f8222868d08 \ + --hash=sha256:98c0535cd6d901f61a5ea3c2e26a1fd28482953d794deb183daf568e3aa5dda6 \ + --hash=sha256:a9cd5e71702d446613750405cde03f66ed268f4c321da071b0472759dad19536 \ + --hash=sha256:bb42e6ed543902e14eae647850da24103a89f0bc2587dec5601b1c1f213bd2ed \ + --hash=sha256:be37680ddb380015cb37318e378c53511c45c4f0d8fac5599d22b7d092b9217a \ + --hash=sha256:c69907354ffee94ba8cf782daf0480dab7557f21ce27fffa6c0ea8f74ed4b8e2 \ + --hash=sha256:c99ef73a277c8921bc0a1f16dee38d924484251d9cfd20951748c20fcd5ed855 \ + --hash=sha256:c9f3e0b71b8a50fccfb42794899285d9d318ce2503782b9dd54868e5ecd0ad31 \ + --hash=sha256:ce0b8141a10d37ecef729c45bc41d334854013f4389f1488bd6035c5579aaac1 \ + --hash=sha256:ce17670bb392ea1b3650537db02bd720908776b5b95f6d2472d31a7de59d1dc1 \ + --hash=sha256:d72b8856b1839d35648f38301b058f6232f4d36b463fe4dc8f4d3fdff2df1a2e \ + --hash=sha256:d9b4f5430bf4f05d4c0dc4c55c75def3a5af4be0343be20fa2bfc577343fbfc9 \ + --hash=sha256:e6495b00cad16888384119842797c49316a96ae1cb132bb03856d980d95afee1 \ + --hash=sha256:ea58ff5b0880593a280cf5511734b17711b32ee1f58b47d726e8600848358160 \ + --hash=sha256:ef461bca07313412dc09961c4a4757a851f56b95ac01c58fac6007632b7b94f2 \ + --hash=sha256:fc85a5dbcbe6eccac1113c72370d1d3aacfdd49198d63950bdf7d8638a307f00 # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ @@ -1229,9 +1234,9 @@ faiss-cpu==1.10.0 \ --hash=sha256:e71f7e24d5b02d3a51df47b77bd10f394a1b48a8331d5c817e71e9e27a8a75ac \ --hash=sha256:f71c5860c860df2320299f9e4f2ca1725beb559c04acb1cf961ed24e6218277a # via feast (pyproject.toml) -fastapi==0.135.3 \ - --hash=sha256:9b0f590c813acd13d0ab43dd8494138eb58e484bfac405db1f3187cfc5810d98 \ - --hash=sha256:bd6d7caf1a2bdd8d676843cdcd2287729572a1ef524fc4d65c17ae002a1be654 +fastapi==0.136.1 \ + --hash=sha256:7af665ad7acfa0a3baf8983d393b6b471b9da10ede59c60045f49fbc89a0fa7f \ + --hash=sha256:a6e9d7eeada96c93a4d69cb03836b44fa34e2854accb7244a1ece36cd4781c3f # via # feast (pyproject.toml) # fastapi-mcp @@ -1243,9 +1248,9 @@ fastjsonschema==2.21.2 \ --hash=sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463 \ --hash=sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de # via nbformat -filelock==3.25.2 \ - --hash=sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694 \ - --hash=sha256:ca8afb0da15f229774c9ad1b455ed96e85a81373065fb10446672f64444ddf70 +filelock==3.29.0 \ + --hash=sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90 \ + --hash=sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258 # via # datasets # huggingface-hub @@ -1410,9 +1415,9 @@ geomet==1.1.0 \ --hash=sha256:4372fe4e286a34acc6f2e9308284850bd8c4aa5bc12065e2abbd4995900db12f \ --hash=sha256:51e92231a0ef6aaa63ac20c443377ba78a303fd2ecd179dc3567de79f3c11605 # via cassandra-driver -google-api-core[grpc]==2.30.2 \ - --hash=sha256:9a8113e1a88bdc09a7ff629707f2214d98d61c7f6ceb0ea38c42a095d02dc0f9 \ - --hash=sha256:a4c226766d6af2580577db1f1a51bf53cd262f722b49731ce7414c43068a9594 +google-api-core[grpc]==2.30.3 \ + --hash=sha256:a85761ba72c444dad5d611c2220633480b2b6be2521eca69cca2dbb3ffd6bfe8 \ + --hash=sha256:e601a37f148585319b26db36e219df68c5d07b6382cff2d580e83404e44d641b # via # feast (pyproject.toml) # google-cloud-bigquery @@ -1423,9 +1428,9 @@ google-api-core[grpc]==2.30.2 \ # google-cloud-storage # opencensus # pandas-gbq -google-auth==2.49.1 \ - --hash=sha256:16d40da1c3c5a0533f57d268fe72e0ebb0ae1cc3b567024122651c045d879b64 \ - --hash=sha256:195ebe3dca18eddd1b3db5edc5189b76c13e96f29e73043b923ebcf3f1a860f7 +google-auth==2.50.0 \ + --hash=sha256:04382175e28b94f49694977f0a792688b59a668def1499e9d8de996dc9ce5b15 \ + --hash=sha256:f35eafb191195328e8ce10a7883970877e7aeb49c2bfaa54aa0e394316d353d0 # via # google-api-core # google-auth-oauthlib @@ -1721,101 +1726,112 @@ hf-xet==1.4.3 \ --hash=sha256:e23717ce4186b265f69afa66e6f0069fe7efbf331546f5c313d00e123dc84583 \ --hash=sha256:fc360b70c815bf340ed56c7b8c63aacf11762a4b099b2fe2c9bd6d6068668c08 # 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.3.1 \ + --hash=sha256:002fc0201b9af1cc8960e27cdc501ad1f8cdd6dbadb2091c6ddbd4e5ace6cb77 \ + --hash=sha256:011a9071c3df4885cac7f58a2623feac6c8e2ad30e6ba93c55195af05ce61ff5 \ + --hash=sha256:01cf82a514bc4fd145b99333c28523e61b7a9ad051a245804323ebf4e7b1c6a6 \ + --hash=sha256:027ce4fabfeff5af5b9869d5524770877f9061d118bc36b85703ae3faf5aad8e \ + --hash=sha256:03baa381964b8df356d19ec4e3a6ae656044249a87b0def257fe1e08dbaf6094 \ + --hash=sha256:042e57de8a2cae91e3e7c0af32960ea2c5107b2f27f68a740295861e68780a8a \ + --hash=sha256:09d41a3a965f7c261223d516ebda607aee4d8440dd7637f01af9a4c05872f0c4 \ + --hash=sha256:09f5e510f637f2c72d2a79fb3ad05f7b6211e057e367ca5c4f97bb3d8c9d71f4 \ + --hash=sha256:0b5ff2f643f4b452b0597b7fe6aa35d398cb31d8806801acfafb1558610ea2aa \ + --hash=sha256:0caf3fc8af0767794b335753781c3fa35f2a3e975c098edbc8f733d35d6a95e4 \ + --hash=sha256:0fac4af8515e6cca74fc701169ae4dc9a71a90e9319c9d21006ec9454b43aa2f \ + --hash=sha256:113e098e4a6b3cc5500e05e7cb1548ba9e83de5fe755941b11f6020a76e6c03a \ + --hash=sha256:137c14905ea6f2933967200bc7b2a0c8ec9387888b273fd0004f25b994fd0343 \ + --hash=sha256:156be6a0c736ee145cfe0fb155d0e96cec8d4872cf8b4f76ad6a2ee6ab391d0a \ + --hash=sha256:17ec8b524055a88b80d76c177dbbbe475a25c17c5bf4b67bdbdbd0629bcae838 \ + --hash=sha256:1ac7697365dbe45109273b34227fee6826b276ead9a4a007e0877e1d3f0fcf21 \ + --hash=sha256:1b46e96b50dad03495447860510daebd2c96fd44ed25ba8ccb03e9f89eaa9d34 \ + --hash=sha256:1ebc307a87b099d0877dbd2bdc0bae427258e7ec67f60a951e89027f8dc2568f \ + --hash=sha256:1f7bceb03a1b934872ffe3942eaeed7c7e09096e67b53f095b81f39c7a819113 \ + --hash=sha256:2611bfaaadc5e8d43fb7967f9bbf1110c8beaa83aee2f2d812c76f11cfb56c6a \ + --hash=sha256:264ee7e9cb6c30dc78da4ecf71d74cf14ca122817c665d838eda8b4384bce1b0 \ + --hash=sha256:26f899cde0279e4b7d370716ff80320601c2bd93cdf3e774a42bdd44f65b41f8 \ + --hash=sha256:29fe35e3c6fe03204e75c86514f452591957a1e06b05d86e10d795455b71c355 \ + --hash=sha256:2afc675b831f7552da41116fffffca4340f387dc03f56d6ec0c7895ab0b59a10 \ + --hash=sha256:2b6da6e07359107c653a809b3cff2d9ccaeedbafe33c6f16434aef6f53ce4a2b \ + --hash=sha256:2b96da7e365d6488d2a75266a662cbe3cc14b28c23dd9b0c9aa04b5bc5c20192 \ + --hash=sha256:2f1c1b2e8f00b71e6214234d313f655a3a27cd4384b054126ce04073c1d47045 \ + --hash=sha256:304481241e081bc26f0778b2c2b99f9c43917e4e724a016dcc9439b7ab12c726 \ + --hash=sha256:318f772dd321404075d406825266e574ee0f4751be1831424c2ebd5722609398 \ + --hash=sha256:3586c8a5f56d34b9dddaaa9e76905f31933cac267251006adf86ec0eef7d0400 \ + --hash=sha256:3724f0e58c6ff76fd683429945491de71324ab1bc0ad943a8d68cb0932d24075 \ + --hash=sha256:3fb6573efa15a29c12c0c0f7170b14e7c1347fe4bb39b6a15b779f46015cc929 \ + --hash=sha256:40ae8a7041fcb328a6bc7202d8c4e6e0d38d434b2e3880b1ee8ed754f17cd836 \ + --hash=sha256:4106201cd052d9eabe3cb7b5a24b0fe37307792bda4fcb3cf6ddd72f697828e8 \ + --hash=sha256:439f9a5cc8f9519ce208a24cdebfa0440fef26aa682a40ba2c92acb10a53f5e0 \ + --hash=sha256:4479e36d263251dba8ab8ea81adf07e7f1163603c7102c5de1e130b83b4fad3b \ + --hash=sha256:487658e1db83c1ee9fbbac6a43039ea76957767a5987ffb16b590613f9e68297 \ + --hash=sha256:48ff424f8aa36aacd9fdaa68efeb27d2e8771f293af4305bdb15d92194ca6631 \ + --hash=sha256:4f7e242eab698ad0be5a4b2ec616fa856569c57455cc67c625fd567726290e5f \ + --hash=sha256:526db52e5234a9463520e960a509d6c1bd5128d1ab1b569cbf459fe39189e8ab \ + --hash=sha256:52d5641027d6731bc7b5e7d126a5158a99784a9f8c6de3d97ca89aca4969e9f8 \ + --hash=sha256:53148a4e21057541b6d8e493b2ea1b500037ddf34433c391970036f3cbce00e3 \ + --hash=sha256:583de2f16528e66081cbdfe510d8488c2de73039dc00aada7d22bd49d73a4a94 \ + --hash=sha256:5e55d90b431b0c6b64ae5a624208d4aea318566d31872e595ee723c0f5b9a79f \ + --hash=sha256:5f316cf2d0558f5027aab19dde7d7e4901c26c21fa95367bc37784e8f547bbf2 \ + --hash=sha256:60543f3b068b16a86e99ed96b7fdae71cdc1d8abdfe9b3f82032a555e52ece7e \ + --hash=sha256:62cc62284541bb2a86c898c7d5e8388661cade91c184cb862095ed547e80588f \ + --hash=sha256:65c05b79cb8366c123357b354a16f9fc3f7187159422f143638d1c26b7240ed4 \ + --hash=sha256:65f6ac06a9f0c32c254660ec6a9329d81d589e8f5d0a9837a941d5424a6be1ef \ + --hash=sha256:6d1434d0bcc1b3ef048bae53f26456405c08aeed9827e65b24094f5f3a6793f1 \ + --hash=sha256:6e2e1024f0a021777740cb7c633a0efb2c4a4bc570f508223a8dcbcf79f99ef9 \ + --hash=sha256:6ffa7ba2e2da1f806f3181b9730b3e87ba9dbfec884806725d4584055ba3faa6 \ + --hash=sha256:743b85bd6902856cac457ddd8cd7dd48c89c47d641b6016ff5e4d015bfbd4799 \ + --hash=sha256:77c5d2bebbc9d06691abb512a31d0f54e1562af0b872891463a67a949b5278ef \ + --hash=sha256:79cd03e7ff550c17758a7520bf437c156d3d4c8bb74214deeafa69cda49c85a4 \ + --hash=sha256:80aba5f85d6227faee628ae28d1c3b69c661806a0636548ac56c68782606454f \ + --hash=sha256:81a1669b6631976b1dc9d3d58ed1ab3333e9f52feb91a2a1fb8241101ac3b665 \ + --hash=sha256:8597c35c9e82f65fd5897c4a2188c65d7daf10607b102960137b23d261cd957b \ + --hash=sha256:8650158217b469d8b6087f490929211b0493a9121154c4efaafd1dec9e19319e \ + --hash=sha256:8887bf0f31e4b550bd988c8863b527b6587d200653e9375cd91eea2b944b7424 \ + --hash=sha256:8a52b24cd710690c4a7e191c7e300136ad2ecb3c68ffe7e95b598e76de166e5e \ + --hash=sha256:8e3754ce60e1b11b0afad9a053481ff184d2ee24bea47099107156d1b84a84aa \ + --hash=sha256:907f7b5501a534030738f0f27459a612d2266fd0507b007bb8f3e6de08167920 \ + --hash=sha256:90d6b9f2652303aefd2c5a26a5e14cb74a3a63d10faa642c08d790e99442a088 \ + --hash=sha256:98fd5b39410e9d69e10e90d0330e35650becaa5dd2548f509b9598f1f3c6124d \ + --hash=sha256:9bfdeff778d3f7ff449ca5922ab773899e7d31e26a576028b06a5e9cf0ed8c34 \ + --hash=sha256:9ebae74ce2b977c2fcb22d6a10aa0acb730022406977b2bcb6ddd6788f5c414a \ + --hash=sha256:a110d19881ca78a88583d3b07231e7c6864864f5f1f3491b638863ea45fa8708 \ + --hash=sha256:a1d190790ee39b8b7adeeb10fc4090dc4859eb4e75ed27bd8108710eef18f358 \ + --hash=sha256:a2f049c3f3c83e886cd1f53958e2a1ebb369be626bef9e50d8b24d79864f1df6 \ + --hash=sha256:a3af4e9f277d6b8acd369dc44a723a055752fca9d045094383af39f90a3e3729 \ + --hash=sha256:a42c7becd4c9ec4ab5769c754eb61112777bdc6e1c1525e2077389e193b5f5aa \ + --hash=sha256:a58a58cef0d911b1717154179a9ff47852249c536ea5966bde4370b6b20638ff \ + --hash=sha256:ab1f646ff531d70bfd25f01e60708dfa3d105eb458b7dedd9fe9a443039fd809 \ + --hash=sha256:ad940dc2db545dc978cb41cb9a683e2ff328f3ef581230b9ca40ff6c3d01d542 \ + --hash=sha256:afe3c3863f16704fb5d7c2c6ff56aaf9e054f6d269f7b4c9074c5476178d1aba \ + --hash=sha256:b1e3b9f4bf9a4120510ba77a77b2fb674893cd6795653545152bb11a79eecfcb \ + --hash=sha256:b2390ad81c03d93ef1d5afd18ffcf5935de827f1a2b96b2c829437968bdabccb \ + --hash=sha256:b37df4b10cb15dedfc203f69312d8eedd617b941c21df58c13af59496c53ad0f \ + --hash=sha256:b3df9447f9209f9aa0434ca74050e9509670c1ad99398fe5807abb90e5f3a014 \ + --hash=sha256:b4fe7f38aa8956fcc1cea270e62601e0e11066aff78e384be70fd283d30293b6 \ + --hash=sha256:c1d68c6980d4690a4550bd3db6c03146f7be68ef5d08d38bb1fb68b3e9c32fe3 \ + --hash=sha256:c24c1460486b6b36083252c2db21a814becf8495ccd0e76b7286623e37239b63 \ + --hash=sha256:c25132902d3eff38781e0d54f27a0942ec849e3c07dbdce83c4d92b7e43c8dce \ + --hash=sha256:c74bd9926954e7e575f9cd9890f63defd90cd8f812dfbf8e1efb72acc9355456 \ + --hash=sha256:c8139e9011117822391c5bcfd674c5948fb1e4b8cb9adf6f13d9890859ee3a1a \ + --hash=sha256:ce334915f5d31048f76a42c607bf26687cf045eb1bc852b7340f09729c6a64fc \ + --hash=sha256:d14229beaa76e66c3a25f9477d973336441ca820df853679a98796256813316f \ + --hash=sha256:d42f3a13290f89191568fc113d95a3d2c8759cdd8c3672f021d8b7436f909e75 \ + --hash=sha256:d8e56e0d1fe607bfff422633f313aec9191c3859ab99d11ff097e3e6e068000c \ + --hash=sha256:da6f0302360e99d32bc2869772692797ebadd536e1b826d0103c72ba49d38698 \ + --hash=sha256:db46baf157feefd88724e6a7f145fe996a5990a8604ed9292b45d563360e513b \ + --hash=sha256:dcea8c3f53674ae68e44b12e853b844a1d315250ca6677b11ec0c06aff85e86c \ + --hash=sha256:de94b409f49eb6a588ebdd5872e826caec417cd77c17af0fb94f2128427f1a2a \ + --hash=sha256:e0356561b4a97c83b9ee3de657a41b8d1a1781226853adaf47b550bb988fda6f \ + --hash=sha256:e0db44cf81e4d7b94f3776b9f89111f74ed6bbdbfd42a22bc4a5ce0644d3e060 \ + --hash=sha256:e31e92b61d56244047ad600812e16f7587a6172f74810fd919ff993af12b9149 \ + --hash=sha256:e89dabf436ee79b358fd970dcbed6333a36d91db73f27069ca24a02fb138a404 \ + --hash=sha256:eddeb9a153795cf6e615f9f3cef66a1d573ff3b6ee16df2b10d1d1c2f2baeaa8 \ + --hash=sha256:ee11fd431f83d8a5b29d370b9d79a814d3218d30113bdcd44657e9bdf715fc92 \ + --hash=sha256:ee37fe8cf081b72dea72f96a0ee604f492ec02252eb77dc26ff6eec3f997b580 \ + --hash=sha256:f19ee7dc1ef8a6497570d91fa4057ba910ad98297a50b8c44ff37589f7c89d17 \ + --hash=sha256:f2f94355affd51088f57f8674b0e294704c3c7c3d7d3b1545310f5b135d4843b \ + --hash=sha256:f525734382a47f9828c9d6a1501522c78d5935466d8e2be1a41ba40ca5bb922b \ + --hash=sha256:f915a34fb742e23d0d61573349aa45d6f74037fde9d58a9f340435eff8d62736 # via feast (pyproject.toml) hpack==4.1.0 \ --hash=sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496 \ @@ -1906,13 +1922,13 @@ ibis-framework[duckdb, mssql, oracle]==12.0.0 \ --hash=sha256:0bbd790f268da9cb87926d5eaad2b827a573927113c4ed3be5095efa89b9e512 \ --hash=sha256:238624f2c14fdab8382ca2f4f667c3cdb81e29844cd5f8db8a325d0743767c61 # via feast (pyproject.toml) -identify==2.6.18 \ - --hash=sha256:873ac56a5e3fd63e7438a7ecbc4d91aca692eb3fefa4534db2b7913f3fc352fd \ - --hash=sha256:8db9d3c8ea9079db92cafb0ebf97abdc09d52e97f4dcf773a2e694048b7cd737 +identify==2.6.19 \ + --hash=sha256:20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a \ + --hash=sha256:6be5020c38fcb07da56c53733538a3081ea5aa70d36a156f83044bfbf9173842 # via pre-commit -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.13 \ + --hash=sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242 \ + --hash=sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 # via # anyio # httpx @@ -1934,17 +1950,17 @@ importlib-metadata==8.7.1 \ # via # dask # opentelemetry-api -importlib-resources==6.5.2 \ - --hash=sha256:185f87adef5bcc288449d98fb4fba07cea78bc036455dd44c5fc4a2fe78fed2c \ - --hash=sha256:789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec +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 \ @@ -2061,9 +2077,9 @@ 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.1 \ --hash=sha256:71b954d834e85ff3096400554f2eefaf7fe37053036f9a782b0f7c5e42dadb81 \ @@ -2082,9 +2098,9 @@ jupyter-server-terminals==0.5.4 \ --hash=sha256:55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14 \ --hash=sha256:bbda128ed41d0be9020349f9f1f2a4ab9952a73ed5f5ac9f1419794761fb87f5 # via jupyter-server -jupyterlab==4.5.6 \ - --hash=sha256:642fe2cfe7f0f5922a8a558ba7a0d246c7bc133b708dfe43f7b3a826d163cf42 \ - --hash=sha256:d6b3dac883aa4d9993348e0f8e95b24624f75099aed64eab6a4351a9cdd1e580 +jupyterlab==4.5.7 \ + --hash=sha256:55a9822c4754da305f41e113452c68383e214dcf96de760146af89ce5d5117b0 \ + --hash=sha256:fba4cb0e2c44a52859669d8c98b45de029d5e515f8407bf8534d2a8fc5f0964d # via notebook jupyterlab-pygments==0.3.0 \ --hash=sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d \ @@ -2100,9 +2116,9 @@ 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 kube-authkit==0.4.0 \ --hash=sha256:1df61ac392fca96c8f5ae8c3d6e9918f1e1655d212434b3c3da5f92cc23b660d \ @@ -2119,9 +2135,9 @@ lark==1.3.1 \ --hash=sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905 \ --hash=sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12 # via rfc3987-syntax -latex2mathml==3.79.0 \ - --hash=sha256:11bde318c2d2d6fcdd105a07509d867cee2208f653278eb80243dec7ea77a0ce \ - --hash=sha256:9f10720d4fcf6b22d1b81f6628237832419a7a29783c13aa92fa8d680165e63d +latex2mathml==3.81.0 \ + --hash=sha256:4b959cdc3cac8686bc0e3e5aece8127dfb1b81ca1241bed8e00ef31b82bb4022 \ + --hash=sha256:d317710393fe20579aea39cfe8928fa2ad9b8780896e585326c75e89c1d1d1a4 # via docling-core lazy-loader==0.5 \ --hash=sha256:717f9179a0dbed357012ddad50a5ad3d5e4d9a0b8712680d4e687f5e6e6ed9b3 \ @@ -2596,9 +2612,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.36.0 \ + --hash=sha256:36ecac30e2ff4322d956029aabce3c82301c29f0acb1ad89b94edcabb0e58ec4 \ + --hash=sha256:3f6a4af2b036b476a4215111c4297b4e6e236ed186cd804faefba23e4990978b # via # azure-identity # msal-extensions @@ -2884,9 +2900,9 @@ nbclient==0.10.4 \ --hash=sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9 \ --hash=sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440 # 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 \ @@ -2931,9 +2947,9 @@ nodeenv==1.10.0 \ --hash=sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 \ --hash=sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb # via pre-commit -notebook==7.5.5 \ - --hash=sha256:a7c14dbeefa6592e87f72290ca982e0c10f5bbf3786be2a600fda9da2764a2b8 \ - --hash=sha256:dc0bfab0f2372c8278c457423d3256c34154ac2cc76bf20e9925260c461013c3 +notebook==7.5.6 \ + --hash=sha256:4dde3f8fb55fa8fb7946d58c6e869ce9baf46d00fc070664f62604569d0faca0 \ + --hash=sha256:621174aade80108f0020b0f00738000b215f75fa3cd90771ad7aa0f24536a4e1 # via great-expectations notebook-shim==0.2.4 \ --hash=sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef \ @@ -3063,8 +3079,8 @@ opencv-python-headless==4.13.0.92 \ --hash=sha256:a7cf08e5b191f4ebb530791acc0825a7986e0d0dee2a3c491184bd8599848a4b \ --hash=sha256:eb60e36b237b1ebd40a912da5384b348df8ed534f6f644d8e0b4f103e272ba7d # via easyocr -openlineage-python==1.45.0 \ - --hash=sha256:cf66e7d517d3c8b510b39ad646d8fd0ca2f0cc92d7d6d601d93b2a859783f380 +openlineage-python==1.46.0 \ + --hash=sha256:f6228a01d34990e76ede5b55b3f99169e54e2e624814c4493f064b9cb1bfba37 # via feast (pyproject.toml) openpyxl==3.1.5 \ --hash=sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2 \ @@ -3074,30 +3090,30 @@ 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.41.1 \ + --hash=sha256:0ad1814d73b875f84494387dae86ce0b12c68556331ce6ce8fe789197c949621 \ + --hash=sha256:a22df900e75c76dc08440710e51f52f1aa6b451b429298896023e60db5b3139f # via # opentelemetry-exporter-prometheus # opentelemetry-sdk # opentelemetry-semantic-conventions -opentelemetry-exporter-prometheus==0.61b0 \ - --hash=sha256:3013b41f4370143d48d219a2351473761423e5882fa4c213811eaefacba39cb7 \ - --hash=sha256:7c4919bd8e79abd62b610767e80f42c9c3a06c5183f4dd9141eedeb57aea284b +opentelemetry-exporter-prometheus==0.62b1 \ + --hash=sha256:7a0b8a6402e107e1f93e38f074a668797e1103936b189561959531a67ffeba55 \ + --hash=sha256:7ecbac9aa76e7abb44082ab0ff2983e0a573e4091c4653f7db483b02bae03506 # 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-sdk==1.41.1 \ + --hash=sha256:724b615e1215b5aeacda0abb8a6a8922c9a1853068948bd0bd225a56d0c792e6 \ + --hash=sha256:edee379c126c1bce952b0c812b48fe8ff35b30df0eecf17e98afa4d598b7d85d # via # opentelemetry-exporter-prometheus # ray -opentelemetry-semantic-conventions==0.61b0 \ - --hash=sha256:072f65473c5d7c6dc0355b27d6c9d1a679d63b6d4b4b16a9773062cb7e31192a \ - --hash=sha256:fa530a96be229795f8cef353739b618148b0fe2b4b3f005e60e262926c4d38e2 +opentelemetry-semantic-conventions==0.62b1 \ + --hash=sha256:c5cc6e04a7f8c7cdd30be2ed81499fa4e75bfbd52c9cb70d40af1f9cd3619802 \ + --hash=sha256:cf506938103d331fbb78eded0d9788095f7fd59016f2bda813c3324e5a74a93c # via opentelemetry-sdk oracledb==3.4.2 \ --hash=sha256:00c79448017f367bb7ab6900efe0706658a53768abea2b4519a4c9b2d5743890 \ @@ -3212,9 +3228,9 @@ 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 @@ -3471,9 +3487,9 @@ pillow==11.3.0 \ # python-pptx # scikit-image # torchvision -pip==26.0.1 \ - --hash=sha256:bdb1b08f4274833d62c1aa29e20907365a2ceb950410df15fc9521bad440122b \ - --hash=sha256:c4037d8a277c89b320abe636d59f91e6d0922d08a05b60e85e53b296613346d8 +pip==26.1 \ + --hash=sha256:4e8486d821d814b77319acb7b9e8bf5a4ee7590a643e7cb21029f209be8573c1 \ + --hash=sha256:81e13ebcca3ffa8cc85e4deff5c27e1ee26dea0aa7fc2f294a073ac208806ff3 # via pip-tools pip-tools==7.5.3 \ --hash=sha256:3aac0c473240ae90db7213c033401f345b05197293ccbdd2704e52e7a783785e \ @@ -3505,9 +3521,9 @@ pre-commit==3.3.1 \ --hash=sha256:218e9e3f7f7f3271ebc355a15598a4d3893ad9fc7b57fe446db75644543323b9 \ --hash=sha256:733f78c9a056cdd169baa6cd4272d51ecfda95346ef8a89bf93712706021b907 # via feast (pyproject.toml) -prometheus-client==0.24.1 \ - --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ - --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 +prometheus-client==0.25.0 \ + --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ + --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 # via # feast (pyproject.toml) # jupyter-server @@ -3812,71 +3828,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 @@ -3989,9 +4005,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.3 \ + --hash=sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927 \ + --hash=sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d # via # feast (pyproject.toml) # codeflare-sdk @@ -4007,134 +4023,134 @@ pydantic==2.12.5 \ # 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.3 \ + --hash=sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba \ + --hash=sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35 \ + --hash=sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4 \ + --hash=sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505 \ + --hash=sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7 \ + --hash=sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8 \ + --hash=sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4 \ + --hash=sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37 \ + --hash=sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25 \ + --hash=sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022 \ + --hash=sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1 \ + --hash=sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7 \ + --hash=sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c \ + --hash=sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3 \ + --hash=sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb \ + --hash=sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3 \ + --hash=sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976 \ + --hash=sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c \ + --hash=sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab \ + --hash=sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa \ + --hash=sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6 \ + --hash=sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396 \ + --hash=sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c \ + --hash=sha256:3d08782c4045f90724b44c95d35ebec0d67edb8a957a2ac81d5a8e4b8a200495 \ + --hash=sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c \ + --hash=sha256:4335e87c7afa436a0dfa899e138d57a72f8aad542e2cf19c36fb428461caabd0 \ + --hash=sha256:4b068543bdb707f5d935dab765d99227aa2545ef2820935f2e5dd801795c7dbd \ + --hash=sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf \ + --hash=sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531 \ + --hash=sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5 \ + --hash=sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda \ + --hash=sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d \ + --hash=sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e \ + --hash=sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df \ + --hash=sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6 \ + --hash=sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c \ + --hash=sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13 \ + --hash=sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536 \ + --hash=sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287 \ + --hash=sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0 \ + --hash=sha256:68ef2f623dda6d5a9067ac014e406c020c780b2a358930a7e5c1b73702900720 \ + --hash=sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050 \ + --hash=sha256:6dff8cc884679df229ebc6d8eb2321ea6f8e091bc7d4886d4dc2e0e71452843c \ + --hash=sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1 \ + --hash=sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8 \ + --hash=sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0 \ + --hash=sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374 \ + --hash=sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807 \ + --hash=sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6 \ + --hash=sha256:831eb19aa789a97356979e94c981e5667759301fb708d1c0d5adf1bc0098b873 \ + --hash=sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57 \ + --hash=sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f \ + --hash=sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c \ + --hash=sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad \ + --hash=sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e \ + --hash=sha256:91249bcb7c165c2fb2a2f852dbc5c91636e2e218e75d96dfdd517e4078e173dd \ + --hash=sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23 \ + --hash=sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46 \ + --hash=sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1 \ + --hash=sha256:99421e7684a60f7f3550a1d159ade5fdff1954baedb6bdd407cba6a307c9f27d \ + --hash=sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1 \ + --hash=sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee \ + --hash=sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c \ + --hash=sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874 \ + --hash=sha256:9f247596366f4221af52beddd65af1218797771d6989bc891a0b86ccaa019168 \ + --hash=sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a \ + --hash=sha256:a35cc284c8dd7edae8a31533713b4d2467dfe7c4f1b5587dd4031f28f90d1d13 \ + --hash=sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f \ + --hash=sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a \ + --hash=sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789 \ + --hash=sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe \ + --hash=sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f \ + --hash=sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5 \ + --hash=sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943 \ + --hash=sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b \ + --hash=sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089 \ + --hash=sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b \ + --hash=sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff \ + --hash=sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67 \ + --hash=sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803 \ + --hash=sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045 \ + --hash=sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8 \ + --hash=sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346 \ + --hash=sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2 \ + --hash=sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f \ + --hash=sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687 \ + --hash=sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76 \ + --hash=sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1 \ + --hash=sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f \ + --hash=sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2 \ + --hash=sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c \ + --hash=sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018 \ + --hash=sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba \ + --hash=sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c \ + --hash=sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf \ + --hash=sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7 \ + --hash=sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47 \ + --hash=sha256:d56bdb4af1767cc15b0386b3c581fdfe659bb9ee4a4f776e92c1cd9d074000d6 \ + --hash=sha256:dcda6583921c05a40533f982321532f2d8db29326c7b95c4026941fa5074bd79 \ + --hash=sha256:dd81f6907932ebac3abbe41378dac64b2380db1287e2aa64d8d88f78d170f51a \ + --hash=sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e \ + --hash=sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a \ + --hash=sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34 \ + --hash=sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b \ + --hash=sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85 \ + --hash=sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca \ + --hash=sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f \ + --hash=sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3 \ + --hash=sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64 \ + --hash=sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22 \ + --hash=sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72 \ + --hash=sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec \ + --hash=sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d \ + --hash=sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3 \ + --hash=sha256:fa3eb7c2995aa443687a825bc30395c8521b7c6ec201966e55debfd1128bcceb \ + --hash=sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395 \ + --hash=sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb \ + --hash=sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4 \ + --hash=sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127 \ + --hash=sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56 # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.0 \ + --hash=sha256:24285fd4b0e0c06507dd9fdfd331ee23794305352aaec8fc4eb92d4047aeb67d \ + --hash=sha256:fc8d5d692eb7092e43c8647c1c35a3ecd00e040fcf02ed86f4cb5458ca62182e # via # docling + # docling-core # fastapi-mcp # mcp pydata-google-auth==1.9.1 \ @@ -4169,6 +4185,79 @@ pymilvus==2.5.18 \ --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d # 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 \ --hash=sha256:0768d90f96ae3267d7561d3bcfe94dd671d107489e870388b12570c3debbc552 \ @@ -4229,9 +4318,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.1.3 \ + --hash=sha256:8164ba62c552f6105f3b11753352d0f16b90d1703ba67d81923d5a8a5d1c5289 \ + --hash=sha256:e70ebf2047a4edf6138cf79c68ad418ef620af65900aa585c5e8bfc95044d43a # via feast (pyproject.toml) pynacl==1.6.2 \ --hash=sha256:018494d6d696ae03c7e656e5e74cdfd8ea1326962cc401bcf018f1ed8436811c \ @@ -4328,9 +4417,9 @@ pyodbc==5.3.0 \ # via # feast (pyproject.toml) # ibis-framework -pyopenssl==26.0.0 \ - --hash=sha256:df94d28498848b98cc1c0ffb8ef1e71e40210d3b0a8064c9d29571ed2904bf81 \ - --hash=sha256:f293934e52936f2e3413b89c6ce36df66a0b34ae1ea3a053b8c5020ff2f513fc +pyopenssl==26.1.0 \ + --hash=sha256:115563879b2c8ccb207975705d3e491434d8c9d7c79667c902ecbf5f3bbd2ece \ + --hash=sha256:737f0a2275c5bc54f3b02137687e1a765931fb3949b9a92a825e4d33b9eec08b # via snowflake-connector-python pyparsing==3.3.2 \ --hash=sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d \ @@ -4556,9 +4645,9 @@ 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.27 \ + --hash=sha256:6fccfad17a27334bd0193681b369f476eda3409f17381a2d65aa7df3f7275645 \ + --hash=sha256:9870a6a8c5a20a5bf4f07c017bd1489006ff8836cff097b6933355ee2b49b602 # via mcp python-pptx==1.0.2 \ --hash=sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba \ @@ -4783,9 +4872,9 @@ ray[data, default]==2.53.0 \ --hash=sha256:d8b95d047d947493803fb8417aea31225dcacdab15afdc75b8a238901949d457 \ --hash=sha256:eb000c17f7301071fdd15c44c4cd3ac0f7953bb4c7c227e61719fe7048195bcd # via codeflare-sdk -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.0 \ + --hash=sha256:64a6ea7bf567ad43c964d2c30d82853f8df927c5c9017766c55a1d1ed95d18ad \ + --hash=sha256:a9c74a5c893a5ef8455a5adb793a31bb70feb821c86eccb62eebef5a19c429ec # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -4794,121 +4883,121 @@ referencing==0.37.0 \ # jsonschema # jsonschema-specifications # jupyter-events -regex==2026.3.32 \ - --hash=sha256:03c2ebd15ff51e7b13bb3dc28dd5ac18cd39e59ebb40430b14ae1a19e833cff1 \ - --hash=sha256:09e26cad1544d856da85881ad292797289e4406338afe98163f3db9f7fac816c \ - --hash=sha256:0cec365d44835b043d7b3266487797639d07d621bec9dc0ea224b00775797cc1 \ - --hash=sha256:0d7855f5e59fcf91d0c9f4a51dc5d8847813832a2230c3e8e35912ccf20baaa2 \ - --hash=sha256:0f21ae18dfd15752cdd98d03cbd7a3640be826bfd58482a93f730dbd24d7b9fb \ - --hash=sha256:10fb2aaae1aaadf7d43c9f3c2450404253697bf8b9ce360bd5418d1d16292298 \ - --hash=sha256:110ba4920721374d16c4c8ea7ce27b09546d43e16aea1d7f43681b5b8f80ba61 \ - --hash=sha256:12917c6c6813ffcdfb11680a04e4d63c5532b88cf089f844721c5f41f41a63ad \ - --hash=sha256:18eb45f711e942c27dbed4109830bd070d8d618e008d0db39705f3f57070a4c6 \ - --hash=sha256:1a6ac1ed758902e664e0d95c1ee5991aa6fb355423f378ed184c6ec47a1ec0e9 \ - --hash=sha256:1ca02ff0ef33e9d8276a1fcd6d90ff6ea055a32c9149c0050b5b67e26c6d2c51 \ - --hash=sha256:1cb22fa9ee6a0acb22fc9aecce5f9995fe4d2426ed849357d499d62608fbd7f9 \ - --hash=sha256:1e0f6648fd48f4c73d801c55ab976cd602e2da87de99c07bff005b131f269c6a \ - --hash=sha256:245667ad430745bae6a1e41081872d25819d86fbd9e0eec485ba00d9f78ad43d \ - --hash=sha256:2820d2231885e97aff0fcf230a19ebd5d2b5b8a1ba338c20deb34f16db1c7897 \ - --hash=sha256:2c8d402ea3dfe674288fe3962016affd33b5b27213d2b5db1823ffa4de524c57 \ - --hash=sha256:2dcca2bceb823c9cc610e57b86a265d7ffc30e9fe98548c609eba8bd3c0c2488 \ - --hash=sha256:2ffbadc647325dd4e3118269bda93ded1eb5f5b0c3b7ba79a3da9fbd04f248e9 \ - --hash=sha256:34c905a721ddee0f84c99e3e3b59dd4a5564a6fe338222bc89dd4d4df166115c \ - --hash=sha256:3c054e39a9f85a3d76c62a1d50c626c5e9306964eaa675c53f61ff7ec1204bbb \ - --hash=sha256:3c0bbfbd38506e1ea96a85da6782577f06239cb9fcf9696f1ea537c980c0680b \ - --hash=sha256:3e221b615f83b15887636fcb90ed21f1a19541366f8b7ba14ba1ad8304f4ded4 \ - --hash=sha256:3ea568832eca219c2be1721afa073c1c9eb8f98a9733fdedd0a9747639fc22a5 \ - --hash=sha256:3f5747501b69299c6b0b047853771e4ed390510bada68cb16da9c9c2078343f7 \ - --hash=sha256:462a041d2160090553572f6bb0be417ab9bb912a08de54cb692829c871ee88c1 \ - --hash=sha256:4bc32b4dbdb4f9f300cf9f38f8ea2ce9511a068ffaa45ac1373ee7a943f1d810 \ - --hash=sha256:4d082be64e51671dd5ee1c208c92da2ddda0f2f20d8ef387e57634f7e97b6aae \ - --hash=sha256:4f9ae4755fa90f1dc2d0d393d572ebc134c0fe30fcfc0ab7e67c1db15f192041 \ - --hash=sha256:51a93452034d671b0e21b883d48ea66c5d6a05620ee16a9d3f229e828568f3f0 \ - --hash=sha256:51fb7e26f91f9091fd8ec6a946f99b15d3bc3667cb5ddc73dd6cb2222dd4a1cc \ - --hash=sha256:5336b1506142eb0f23c96fb4a34b37c4fefd4fed2a7042069f3c8058efe17855 \ - --hash=sha256:567b57eb987547a23306444e4f6f85d4314f83e65c71d320d898aa7550550443 \ - --hash=sha256:5aa78c857c1731bdd9863923ffadc816d823edf475c7db6d230c28b53b7bdb5e \ - --hash=sha256:5bf2f3c2c5bd8360d335c7dcd4a9006cf1dabae063ee2558ee1b07bbc8a20d88 \ - --hash=sha256:5c35d097f509cf7e40d20d5bee548d35d6049b36eb9965e8d43e4659923405b9 \ - --hash=sha256:5d86e3fb08c94f084a625c8dc2132a79a3a111c8bf6e2bc59351fa61753c2f6e \ - --hash=sha256:6062c4ef581a3e9e503dccf4e1b7f2d33fdc1c13ad510b287741ac73bc4c6b27 \ - --hash=sha256:6128dd0793a87287ea1d8bf16b4250dd96316c464ee15953d5b98875a284d41e \ - --hash=sha256:631f7d95c83f42bccfe18946a38ad27ff6b6717fb4807e60cf24860b5eb277fc \ - --hash=sha256:66a5083c3ffe5a5a95f8281ea47a88072d4f24001d562d1d9d28d4cdc005fec5 \ - --hash=sha256:66d3126afe7eac41759cd5f0b3b246598086e88e70527c0d68c9e615b81771c4 \ - --hash=sha256:67015a8162d413af9e3309d9a24e385816666fbf09e48e3ec43342c8536f7df6 \ - --hash=sha256:6980ceb5c1049d4878632f08ba0bf7234c30e741b0dc9081da0f86eca13189d3 \ - --hash=sha256:69a847a6ffaa86e8af7b9e7037606e05a6f663deec516ad851e8e05d9908d16a \ - --hash=sha256:6ada7bd5bb6511d12177a7b00416ce55caee49fbf8c268f26b909497b534cacb \ - --hash=sha256:70c634e39c5cda0da05c93d6747fdc957599f7743543662b6dbabdd8d3ba8a96 \ - --hash=sha256:7cdd508664430dd51b8888deb6c5b416d8de046b2e11837254378d31febe4a98 \ - --hash=sha256:844d88509c968dd44b30daeefac72b038b1bf31ac372d5106358ab01d393c48b \ - --hash=sha256:847087abe98b3c1ebf1eb49d6ef320dbba75a83ee4f83c94704580f1df007dd4 \ - --hash=sha256:85c9b0c131427470a6423baa0a9330be6fd8c3630cc3ee6fdee03360724cbec5 \ - --hash=sha256:879ae91f2928a13f01a55cfa168acedd2b02b11b4cd8b5bb9223e8cde777ca52 \ - --hash=sha256:887a9fa74418d74d645281ee0edcf60694053bd1bc2ebc49eb5e66bfffc6d107 \ - --hash=sha256:88ebc0783907468f17fca3d7821b30f9c21865a721144eb498cb0ff99a67bcac \ - --hash=sha256:89e50667e7e8c0e7903e4d644a2764fffe9a3a5d6578f72ab7a7b4205bf204b7 \ - --hash=sha256:8a4a3189a99ecdd1c13f42513ab3fc7fa8311b38ba7596dd98537acb8cd9acc3 \ - --hash=sha256:8aaf8ee8f34b677f90742ca089b9c83d64bdc410528767273c816a863ed57327 \ - --hash=sha256:8e4c8fa46aad1a11ae2f8fcd1c90b9d55e18925829ac0d98c5bb107f93351745 \ - --hash=sha256:8fc918cd003ba0d066bf0003deb05a259baaaab4dc9bd4f1207bbbe64224857a \ - --hash=sha256:8fe14e24124ef41220e5992a0f09432f890037df6f93fd3d6b7a0feff2db16b2 \ - --hash=sha256:918db4e34a7ef3d0beee913fa54b34231cc3424676f1c19bdb85f01828d3cd37 \ - --hash=sha256:987cdfcfb97a249abc3601ad53c7de5c370529f1981e4c8c46793e4a1e1bfe8e \ - --hash=sha256:9b9118a78e031a2e4709cd2fcc3028432e89b718db70073a8da574c249b5b249 \ - --hash=sha256:9cf7036dfa2370ccc8651521fcbb40391974841119e9982fa312b552929e6c85 \ - --hash=sha256:a094e9dcafedfb9d333db5cf880304946683f43a6582bb86688f123335122929 \ - --hash=sha256:a416ee898ecbc5d8b283223b4cf4d560f93244f6f7615c1bd67359744b00c166 \ - --hash=sha256:a5d88fa37ba5e8a80ca8d956b9ea03805cfa460223ac94b7d4854ee5e30f3173 \ - --hash=sha256:ace48c5e157c1e58b7de633c5e257285ce85e567ac500c833349c363b3df69d4 \ - --hash=sha256:ad5c53f2e8fcae9144009435ebe3d9832003508cf8935c04542a1b3b8deefa15 \ - --hash=sha256:ad8d372587e659940568afd009afeb72be939c769c552c9b28773d0337251391 \ - --hash=sha256:b193ed199848aa96618cd5959c1582a0bf23cd698b0b900cb0ffe81b02c8659c \ - --hash=sha256:b2e9c2ea2e93223579308263f359eab8837dc340530b860cb59b713651889f14 \ - --hash=sha256:b3aa21bad31db904e0b9055e12c8282df62d43169c4a9d2929407060066ebc74 \ - --hash=sha256:b565f25171e04d4fad950d1fa837133e3af6ea6f509d96166eed745eb0cf63bc \ - --hash=sha256:b56993a7aeb4140c4770f4f7965c9e5af4f024457d06e23c01b0d47501cb18ed \ - --hash=sha256:b6acb765e7c1f2fa08ac9057a33595e26104d7d67046becae184a8f100932dd9 \ - --hash=sha256:b6f366a5ef66a2df4d9e68035cfe9f0eb8473cdfb922c37fac1d169b468607b0 \ - --hash=sha256:b7836aa13721dbdef658aebd11f60d00de633a95726521860fe1f6be75fa225a \ - --hash=sha256:b8fca73e16c49dd972ce3a88278dfa5b93bf91ddef332a46e9443abe21ca2f7c \ - --hash=sha256:b953d9d496d19786f4d46e6ba4b386c6e493e81e40f9c5392332458183b0599d \ - --hash=sha256:bbc458a292aee57d572075f22c035fa32969cdb7987d454e3e34d45a40a0a8b4 \ - --hash=sha256:c1cecea3e477af105f32ef2119b8d895f297492e41d317e60d474bc4bffd62ff \ - --hash=sha256:c1d7fa44aece1fa02b8927441614c96520253a5cad6a96994e3a81e060feed55 \ - --hash=sha256:c1ed17104d1be7f807fdec35ec99777168dd793a09510d753f8710590ba54cdd \ - --hash=sha256:c3c6f6b027d10f84bfe65049028892b5740878edd9eae5fea0d1710b09b1d257 \ - --hash=sha256:c5e0fdb5744caf1036dec5510f543164f2144cb64932251f6dfd42fa872b7f9c \ - --hash=sha256:c60f1de066eb5a0fd8ee5974de4194bb1c2e7692941458807162ffbc39887303 \ - --hash=sha256:c6d9c6e783b348f719b6118bb3f187b2e138e3112576c9679eb458cc8b2e164b \ - --hash=sha256:c940e00e8d3d10932c929d4b8657c2ea47d2560f31874c3e174c0d3488e8b865 \ - --hash=sha256:c9f261ad3cd97257dc1d9355bfbaa7dd703e06574bffa0fa8fe1e31da915ee38 \ - --hash=sha256:d21a07edddb3e0ca12a8b8712abc8452481c3d3db19ae87fc94e9842d005964b \ - --hash=sha256:d363660f9ef8c734495598d2f3e527fb41f745c73159dc0d743402f049fb6836 \ - --hash=sha256:d478a2ca902b6ef28ffc9521e5f0f728d036abe35c0b250ee8ae78cfe7c5e44e \ - --hash=sha256:d571f0b2eec3513734ea31a16ce0f7840c0b85a98e7edfa0e328ed144f9ef78f \ - --hash=sha256:d6b39a2cc5625bbc4fda18919a891eab9aab934eecf83660a90ce20c53621a9a \ - --hash=sha256:d76d62909bfb14521c3f7cfd5b94c0c75ec94b0a11f647d2f604998962ec7b6c \ - --hash=sha256:dab4178a0bc1ef13178832b12db7bc7f562e8f028b2b5be186e370090dc50652 \ - --hash=sha256:db976be51375bca900e008941639448d148c655c9545071965d0571ecc04f5d0 \ - --hash=sha256:ded4fc0edf3de792850cb8b04bbf3c5bd725eeaf9df4c27aad510f6eed9c4e19 \ - --hash=sha256:e006ea703d5c0f3d112b51ba18af73b58209b954acfe3d8da42eacc9a00e4be6 \ - --hash=sha256:e3e5d1802cba785210a4a800e63fcee7a228649a880f3bf7f2aadccb151a834b \ - --hash=sha256:e480d3dac06c89bc2e0fd87524cc38c546ac8b4a38177650745e64acbbcfdeba \ - --hash=sha256:e50af656c15e2723eeb7279c0837e07accc594b95ec18b86821a4d44b51b24bf \ - --hash=sha256:e83ce8008b48762be296f1401f19afd9ea29f3d035d1974e0cecb74e9afbd1df \ - --hash=sha256:ed3b8281c5d0944d939c82db4ec2300409dd69ee087f7a75a94f2e301e855fb4 \ - --hash=sha256:ef250a3f5e93182193f5c927c5e9575b2cb14b80d03e258bc0b89cc5de076b60 \ - --hash=sha256:f1574566457161678297a116fa5d1556c5a4159d64c5ff7c760e7c564bf66f16 \ - --hash=sha256:f26262900edd16272b6360014495e8d68379c6c6e95983f9b7b322dc928a1194 \ - --hash=sha256:f28eac18a8733a124444643a66ac96fef2c0ad65f50034e0a043b90333dc677f \ - --hash=sha256:f54840bea73541652f1170dc63402a5b776fc851ad36a842da9e5163c1f504a0 \ - --hash=sha256:f785f44a44702dea89b28bce5bc82552490694ce4e144e21a4f0545e364d2150 \ - --hash=sha256:f7cc00089b4c21847852c0ad76fb3680f9833b855a0d30bcec94211c435bff6b \ - --hash=sha256:f95bd07f301135771559101c060f558e2cf896c7df00bec050ca7f93bf11585a \ - --hash=sha256:fc8ced733d6cd9af5e412f256a32f7c61cd2d7371280a65c689939ac4572499f \ - --hash=sha256:fd03e38068faeef937cc6761a250a4aaa015564bd0d61481fefcf15586d31825 +regex==2026.4.4 \ + --hash=sha256:011bb48bffc1b46553ac704c975b3348717f4e4aa7a67522b51906f99da1820c \ + --hash=sha256:04bb679bc0bde8a7bfb71e991493d47314e7b98380b083df2447cda4b6edb60f \ + --hash=sha256:0540e5b733618a2f84e9cb3e812c8afa82e151ca8e19cf6c4e95c5a65198236f \ + --hash=sha256:05568c4fbf3cb4fa9e28e3af198c40d3237cf6041608a9022285fe567ec3ad62 \ + --hash=sha256:0709f22a56798457ae317bcce42aacee33c680068a8f14097430d9f9ba364bee \ + --hash=sha256:0734f63afe785138549fbe822a8cfeaccd1bae814c5057cc0ed5b9f2de4fc883 \ + --hash=sha256:07edca1ba687998968f7db5bc355288d0c6505caa7374f013d27356d93976d13 \ + --hash=sha256:07f190d65f5a72dcb9cf7106bfc3d21e7a49dd2879eda2207b683f32165e4d99 \ + --hash=sha256:08c55c13d2eef54f73eeadc33146fb0baaa49e7335eb1aff6ae1324bf0ddbe4a \ + --hash=sha256:0a51cdb3c1e9161154f976cb2bef9894bc063ac82f31b733087ffb8e880137d0 \ + --hash=sha256:1371c2ccbb744d66ee63631cc9ca12aa233d5749972626b68fe1a649dd98e566 \ + --hash=sha256:173a66f3651cdb761018078e2d9487f4cf971232c990035ec0eb1cdc6bf929a9 \ + --hash=sha256:1b1ce5c81c9114f1ce2f9288a51a8fd3aeea33a0cc440c415bf02da323aa0a76 \ + --hash=sha256:1b9a00b83f3a40e09859c78920571dcb83293c8004079653dd22ec14bbfa98c7 \ + --hash=sha256:21e5eb86179b4c67b5759d452ea7c48eb135cd93308e7a260aa489ed2eb423a4 \ + --hash=sha256:261c015b3e2ed0919157046d768774ecde57f03d8fa4ba78d29793447f70e717 \ + --hash=sha256:2895506ebe32cc63eeed8f80e6eae453171cfccccab35b70dc3129abec35a5b8 \ + --hash=sha256:298c3ec2d53225b3bf91142eb9691025bab610e0c0c51592dde149db679b3d17 \ + --hash=sha256:2a5d273181b560ef8397c8825f2b9d57013de744da9e8257b8467e5da8599351 \ + --hash=sha256:2b69102a743e7569ebee67e634a69c4cb7e59d6fa2e1aa7d3bdbf3f61435f62d \ + --hash=sha256:2c785939dc023a1ce4ec09599c032cc9933d258a998d16ca6f2b596c010940eb \ + --hash=sha256:2da82d643fa698e5e5210e54af90181603d5853cf469f5eedf9bfc8f59b4b8c7 \ + --hash=sha256:2e19e18c568d2866d8b6a6dfad823db86193503f90823a8f66689315ba28fbe8 \ + --hash=sha256:312ec9dd1ae7d96abd8c5a36a552b2139931914407d26fba723f9e53c8186f86 \ + --hash=sha256:33424f5188a7db12958246a54f59a435b6cb62c5cf9c8d71f7cc49475a5fdada \ + --hash=sha256:3384df51ed52db0bea967e21458ab0a414f67cdddfd94401688274e55147bb81 \ + --hash=sha256:33bfda9684646d323414df7abe5692c61d297dbb0530b28ec66442e768813c59 \ + --hash=sha256:349d7310eddff40429a099c08d995c6d4a4bfaf3ff40bd3b5e5cb5a5a3c7d453 \ + --hash=sha256:36bcb9d6d1307ab629edc553775baada2aefa5c50ccc0215fbfd2afcfff43141 \ + --hash=sha256:3790ba9fb5dd76715a7afe34dbe603ba03f8820764b1dc929dd08106214ed031 \ + --hash=sha256:385edaebde5db5be103577afc8699fea73a0e36a734ba24870be7ffa61119d74 \ + --hash=sha256:39d8de85a08e32632974151ba59c6e9140646dcc36c80423962b1c5c0a92e244 \ + --hash=sha256:415a994b536440f5011aa77e50a4274d15da3245e876e5c7f19da349caaedd87 \ + --hash=sha256:421439d1bee44b19f4583ccf42670ca464ffb90e9fdc38d37f39d1ddd1e44f1f \ + --hash=sha256:475e50f3f73f73614f7cba5524d6de49dee269df00272a1b85e3d19f6d498465 \ + --hash=sha256:4ce255cc05c1947a12989c6db801c96461947adb7a59990f1360b5983fab4983 \ + --hash=sha256:504ffa8a03609a087cad81277a629b6ce884b51a24bd388a7980ad61748618ff \ + --hash=sha256:50a766ee2010d504554bfb5f578ed2e066898aa26411d57e6296230627cdefa0 \ + --hash=sha256:54170b3e95339f415d54651f97df3bff7434a663912f9358237941bbf9143f55 \ + --hash=sha256:54a1189ad9d9357760557c91103d5e421f0a2dabe68a5cdf9103d0dcf4e00752 \ + --hash=sha256:55d9304e0e7178dfb1e106c33edf834097ddf4a890e2f676f6c5118f84390f73 \ + --hash=sha256:586b89cdadf7d67bf86ae3342a4dcd2b8d70a832d90c18a0ae955105caf34dbe \ + --hash=sha256:59968142787042db793348a3f5b918cf24ced1f23247328530e063f89c128a95 \ + --hash=sha256:59efe72d37fd5a91e373e5146f187f921f365f4abc1249a5ab446a60f30dd5f8 \ + --hash=sha256:59f67cd0a0acaf0e564c20bbd7f767286f23e91e2572c5703bf3e56ea7557edb \ + --hash=sha256:5d354b18839328927832e2fa5f7c95b7a3ccc39e7a681529e1685898e6436d45 \ + --hash=sha256:62f5519042c101762509b1d717b45a69c0139d60414b3c604b81328c01bd1943 \ + --hash=sha256:6780f008ee81381c737634e75c24e5a6569cc883c4f8e37a37917ee79efcafd9 \ + --hash=sha256:6a50ab11b7779b849472337191f3a043e27e17f71555f98d0092fa6d73364520 \ + --hash=sha256:6aa809ed4dc3706cc38594d67e641601bd2f36d5555b2780ff074edfcb136cf8 \ + --hash=sha256:6c1818f37be3ca02dcb76d63f2c7aaba4b0dc171b579796c6fbe00148dfec6b1 \ + --hash=sha256:6dac006c8b6dda72d86ea3d1333d45147de79a3a3f26f10c1cf9287ca4ca0ac3 \ + --hash=sha256:7088fcdcb604a4417c208e2169715800d28838fefd7455fbe40416231d1d47c1 \ + --hash=sha256:70aadc6ff12e4b444586e57fc30771f86253f9f0045b29016b9605b4be5f7dfb \ + --hash=sha256:7429f4e6192c11d659900c0648ba8776243bf396ab95558b8c51a345afeddde6 \ + --hash=sha256:74fa82dcc8143386c7c0392e18032009d1db715c25f4ba22d23dc2e04d02a20f \ + --hash=sha256:760ef21c17d8e6a4fe8cf406a97cf2806a4df93416ccc82fc98d25b1c20425be \ + --hash=sha256:7698a6f38730fd1385d390d1ed07bb13dce39aa616aca6a6d89bea178464b9a4 \ + --hash=sha256:76d67d5afb1fe402d10a6403bae668d000441e2ab115191a804287d53b772951 \ + --hash=sha256:773d1dfd652bbffb09336abf890bfd64785c7463716bf766d0eb3bc19c8b7f27 \ + --hash=sha256:7d346fccdde28abba117cc9edc696b9518c3307fbfcb689e549d9b5979018c6d \ + --hash=sha256:8512fcdb43f1bf18582698a478b5ab73f9c1667a5b7548761329ef410cd0a760 \ + --hash=sha256:867bddc63109a0276f5a31999e4c8e0eb7bbbad7d6166e28d969a2c1afeb97f9 \ + --hash=sha256:88e9b048345c613f253bea4645b2fe7e579782b82cac99b1daad81e29cc2ed8e \ + --hash=sha256:8fae3c6e795d7678963f2170152b0d892cf6aee9ee8afc8c45e6be38d5107fe7 \ + --hash=sha256:9542ccc1e689e752594309444081582f7be2fdb2df75acafea8a075108566735 \ + --hash=sha256:9776b85f510062f5a75ef112afe5f494ef1635607bf1cc220c1391e9ac2f5e81 \ + --hash=sha256:97850d0638391bdc7d35dc1c1039974dcb921eaafa8cc935ae4d7f272b1d60b3 \ + --hash=sha256:993f657a7c1c6ec51b5e0ba97c9817d06b84ea5fa8d82e43b9405de0defdc2b9 \ + --hash=sha256:9a2741ce5a29d3c84b0b94261ba630ab459a1b847a0d6beca7d62d188175c790 \ + --hash=sha256:9e2f5217648f68e3028c823df58663587c1507a5ba8419f4fdfc8a461be76043 \ + --hash=sha256:a0d2b28aa1354c7cd7f71b7658c4326f7facac106edd7f40eda984424229fd59 \ + --hash=sha256:a152560af4f9742b96f3827090f866eeec5becd4765c8e0d3473d9d280e76a5a \ + --hash=sha256:a1c0c7d67b64d85ac2e1879923bad2f08a08f3004055f2f406ef73c850114bd4 \ + --hash=sha256:a7a5bb6aa0cf62208bb4fa079b0c756734f8ad0e333b425732e8609bd51ee22f \ + --hash=sha256:a85b620a388d6c9caa12189233109e236b3da3deffe4ff11b84ae84e218a274f \ + --hash=sha256:acd38177bd2c8e69a411d6521760806042e244d0ef94e2dd03ecdaa8a3c99427 \ + --hash=sha256:ae3e764bd4c5ff55035dc82a8d49acceb42a5298edf6eb2fc4d328ee5dd7afae \ + --hash=sha256:ae5266a82596114e41fb5302140e9630204c1b5f325c770bec654b95dd54b0aa \ + --hash=sha256:af0384cb01a33600c49505c27c6c57ab0b27bf84a74e28524c92ca897ebdac9d \ + --hash=sha256:b15b88b0d52b179712632832c1d6e58e5774f93717849a41096880442da41ab0 \ + --hash=sha256:b26c30df3a28fd9793113dac7385a4deb7294a06c0f760dd2b008bd49a9139bc \ + --hash=sha256:b40379b53ecbc747fd9bdf4a0ea14eb8188ca1bd0f54f78893a39024b28f4863 \ + --hash=sha256:b4c36a85b00fadb85db9d9e90144af0a980e1a3d2ef9cd0f8a5bef88054657c6 \ + --hash=sha256:b5f9fb784824a042be3455b53d0b112655686fdb7a91f88f095f3fee1e2a2a54 \ + --hash=sha256:be061028481186ba62a0f4c5f1cc1e3d5ab8bce70c89236ebe01023883bc903b \ + --hash=sha256:c07ab8794fa929e58d97a0e1796b8b76f70943fa39df225ac9964615cf1f9d52 \ + --hash=sha256:c228cf65b4a54583763645dcd73819b3b381ca8b4bb1b349dee1c135f4112c07 \ + --hash=sha256:c4ee50606cb1967db7e523224e05f32089101945f859928e65657a2cbb3d278b \ + --hash=sha256:c882cd92ec68585e9c1cf36c447ec846c0d94edd706fe59e0c198e65822fd23b \ + --hash=sha256:cf9b1b2e692d4877880388934ac746c99552ce6bf40792a767fd42c8c99f136d \ + --hash=sha256:d2228c02b368d69b724c36e96d3d1da721561fb9cc7faa373d7bf65e07d75cb5 \ + --hash=sha256:d51d20befd5275d092cdffba57ded05f3c436317ee56466c8928ac32d960edaf \ + --hash=sha256:db0ac18435a40a2543dbb3d21e161a6c78e33e8159bd2e009343d224bb03bb1b \ + --hash=sha256:dc4f10fbd5dd13dcf4265b4cc07d69ca70280742870c97ae10093e3d66000359 \ + --hash=sha256:dcb5453ecf9cd58b562967badd1edbf092b0588a3af9e32ee3d05c985077ce87 \ + --hash=sha256:dd2630faeb6876fb0c287f664d93ddce4d50cd46c6e88e60378c05c9047e08ca \ + --hash=sha256:e014a797de43d1847df957c0a2a8e861d1c17547ee08467d1db2c370b7568baa \ + --hash=sha256:e08270659717f6973523ce3afbafa53515c4dc5dcad637dc215b6fd50f689423 \ + --hash=sha256:e0aab3ff447845049d676827d2ff714aab4f73f340e155b7de7458cf53baa5a4 \ + --hash=sha256:e355be718caf838aa089870259cf1776dc2a4aa980514af9d02c59544d9a8b22 \ + --hash=sha256:e7ab63e9fe45a9ec3417509e18116b367e89c9ceb6219222a3396fa30b147f80 \ + --hash=sha256:e7cd3e4ee8d80447a83bbc9ab0c8459781fa77087f856c3e740d7763be0df27f \ + --hash=sha256:e9638791082eaf5b3ac112c587518ee78e083a11c4b28012d8fe2a0f536dfb17 \ + --hash=sha256:eb59c65069498dbae3c0ef07bbe224e1eaa079825a437fb47a479f0af11f774f \ + --hash=sha256:ee7337f88f2a580679f7bbfe69dc86c043954f9f9c541012f49abc554a962f2e \ + --hash=sha256:ee9627de8587c1a22201cb16d0296ab92b4df5cdcb5349f4e9744d61db7c7c98 \ + --hash=sha256:f4f83781191007b6ef43b03debc35435f10cad9b96e16d147efe84a1d48bdde4 \ + --hash=sha256:f56ebf9d70305307a707911b88469213630aba821e77de7d603f9d2f0730687d \ + --hash=sha256:f5bfc2741d150d0be3e4a0401a5c22b06e60acb9aa4daa46d9e79a6dcd0f135b \ + --hash=sha256:f94a11a9d05afcfcfa640e096319720a19cc0c9f7768e1a61fceee6a3afc6c7c \ + --hash=sha256:fa7922bbb2cc84fa062d37723f199d4c0cd200245ce269c05db82d904db66b83 \ + --hash=sha256:fe896e07a5a2462308297e515c0054e9ec2dd18dfdc9427b19900b37dfe6f40b \ + --hash=sha256:ffa81f81b80047ba89a3c69ae6a0f78d06f4a42ce5126b0eb2a0a10ad44e0b2e # via # feast (pyproject.toml) # parsimonious @@ -4974,9 +5063,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==14.3.4 \ + --hash=sha256:07e7adb4690f68864777b1450859253bed81a99a31ac321ac1817b2313558952 \ + --hash=sha256:817e02727f2b25b40ef56f5aa2217f400c8489f79ca8f46ea2b70dd5e14558a9 # via # codeflare-sdk # fastapi-mcp @@ -5118,25 +5207,25 @@ ruamel-yaml==0.17.17 \ --hash=sha256:9751de4cbb57d4bfbf8fc394e125ed4a2f170fbff3dc3d78abf50be85924f8be \ --hash=sha256:9af3ec5d7f8065582f3aa841305465025d0afd26c5fb54e15b964e11838fc74f # via great-expectations -ruff==0.15.9 \ - --hash=sha256:058d8e99e1bfe79d8a0def0b481c56059ee6716214f7e425d8e737e412d69677 \ - --hash=sha256:0694e601c028fd97dc5c6ee244675bc241aeefced7ef80cd9c6935a871078f53 \ - --hash=sha256:29cbb1255a9797903f6dde5ba0188c707907ff44a9006eb273b5a17bfa0739a2 \ - --hash=sha256:2b0c7c341f68adb01c488c3b7d4b49aa8ea97409eae6462d860a79cf55f431b6 \ - --hash=sha256:45a70921b80e1c10cf0b734ef09421f71b5aa11d27404edc89d7e8a69505e43d \ - --hash=sha256:4965bac6ac9ea86772f4e23587746f0b7a395eccabb823eb8bfacc3fa06069f7 \ - --hash=sha256:55cc15eee27dc0eebdfcb0d185a6153420efbedc15eb1d38fe5e685657b0f840 \ - --hash=sha256:6d3fcbca7388b066139c523bda744c822258ebdcfbba7d24410c3f454cc9af71 \ - --hash=sha256:6efbe303983441c51975c243e26dff328aca11f94b70992f35b093c2e71801e1 \ - --hash=sha256:7b34a9766aeec27a222373d0b055722900fbc0582b24f39661aa96f3fe6ad901 \ - --hash=sha256:89dd695bc72ae76ff484ae54b7e8b0f6b50f49046e198355e44ea656e521fef9 \ - --hash=sha256:8e1ddb11dbd61d5983fa2d7d6370ef3eb210951e443cace19594c01c72abab4c \ - --hash=sha256:9439a342adb8725f32f92732e2bafb6d5246bd7a5021101166b223d312e8fc59 \ - --hash=sha256:9c5e6faf9d97c8edc43877c3f406f47446fc48c40e1442d58cfcdaba2acea745 \ - --hash=sha256:a6537f6eed5cda688c81073d46ffdfb962a5f29ecb6f7e770b2dc920598997ed \ - --hash=sha256:bde6ff36eaf72b700f32b7196088970bf8fdb2b917b7accd8c371bfc0fd573ec \ - --hash=sha256:ce187224ef1de1bd225bc9a152ac7102a6171107f026e81f317e4257052916d5 \ - --hash=sha256:eaf05aad70ca5b5a0a4b0e080df3a6b699803916d88f006efd1f5b46302daab8 +ruff==0.15.12 \ + --hash=sha256:01da3988d225628b709493d7dc67c3b9b12c0210016b08690ef9bd27970b262b \ + --hash=sha256:2849ea9f3484c3aca43a82f484210370319e7170df4dfe4843395ddf6c57bc33 \ + --hash=sha256:83b2f4f2f3b1026b5fb449b467d9264bf22067b600f7b6f41fc5958909f449d0 \ + --hash=sha256:84a1630093121375a3e2a95b4a6dc7b59e2b4ee76216e32d81aae550a832d002 \ + --hash=sha256:9ba3b8f1afd7e2e43d8943e55f249e13f9682fde09711644a6e7290eb4f3e339 \ + --hash=sha256:9cae0f92bd5700d1213188b31cd3bdd2b315361296d10b96b8e2337d3d11f53e \ + --hash=sha256:9e77c7e51c07fe396826d5969a5b846d9cd4c402535835fb6e21ce8b28fef847 \ + --hash=sha256:a538f7a82d061cee7be55542aca1d86d1393d55d81d4fcc314370f4340930d4f \ + --hash=sha256:b0c862b172d695db7598426b8af465e7e9ac00a3ea2a3630ee67eb82e366aaa6 \ + --hash=sha256:c87a162d61ab3adca47c03f7f717c68672edec7d1b5499e652331780fe74950d \ + --hash=sha256:d0185894e038d7043ba8fd6aee7499ece6462dc0ea9f1e260c7451807c714c20 \ + --hash=sha256:dd8aed930da53780d22fc70bdf84452c843cf64f8cb4eb38984319c24c5cd5fd \ + --hash=sha256:e3bcd123364c3770b8e1b7baaf343cc99a35f197c5c6e8af79015c666c423a6c \ + --hash=sha256:e852ba9fdc890655e1d78f2df1499efbe0e54126bd405362154a75e2bde159c5 \ + --hash=sha256:ecea26adb26b4232c0c2ca19ccbc0083a68344180bba2a600605538ce51a40a6 \ + --hash=sha256:f86f176e188e94d6bdbc09f09bfd9dc729059ad93d0e7390b5a73efe19f8861c \ + --hash=sha256:fb129f40f114f089ebe0ca56c0d251cf2061b17651d464bb6478dc01e69f11f5 \ + --hash=sha256:fe87510d000220aa1ed530d4448a7c696a0cae1213e5ec30e5874287b66557b5 # via feast (pyproject.toml) s3transfer==0.13.1 \ --hash=sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724 \ @@ -5340,9 +5429,9 @@ send2trash==2.1.0 \ --hash=sha256:0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c \ --hash=sha256:1c72b39f09457db3c05ce1d19158c2cbef4c32b8bedd02c155e49282b7ea7459 # via jupyter-server -sentence-transformers==5.3.0 \ - --hash=sha256:414a0a881f53a4df0e6cbace75f823bfcb6b94d674c42a384b498959b7c065e2 \ - --hash=sha256:dca6b98db790274a68185d27a65801b58b4caf653a4e556b5f62827509347c7d +sentence-transformers==5.4.1 \ + --hash=sha256:436bcb1182a0ff42a8fb2b1c43498a70d0a75b688d182f2cd0d1dd115af61ddc \ + --hash=sha256:a6d640fc363849b63affb8e140e9d328feabab86f83d58ac3e16b1c28140b790 # via feast (pyproject.toml) setuptools==80.10.2 \ --hash=sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70 \ @@ -5442,9 +5531,9 @@ six==1.17.0 \ # python-dateutil # rfc3339-validator # thriftpy2 -smart-open==7.5.1 \ - --hash=sha256:3e07cbbd9c8a908bcb8e25d48becf1a5cbb4886fa975e9f34c672ed171df2318 \ - --hash=sha256:3f08e16827c4733699e6b2cc40328a3568f900cb12ad9a3ad233ba6c872d9fe7 +smart-open==7.6.0 \ + --hash=sha256:2a78f454610a826aa688065b54b4a0a9b12a5599fa61d5190e9bac2df5e5f53f \ + --hash=sha256:44717f46b5ff276fac03b88e5d13d1c416f064f3b7b081381b0fa8889004bd7e # via ray sniffio==1.3.1 \ --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ @@ -5520,103 +5609,103 @@ 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.49 \ + --hash=sha256:01146546d84185f12721a1d2ce0c6673451a7894d1460b592d378ca4871a0c72 \ + --hash=sha256:059d7151fff513c53a4638da8778be7fce81a0c4854c7348ebd0c4078ddf28fe \ + --hash=sha256:0c98c59075b890df8abfcc6ad632879540f5791c68baebacb4f833713b510e75 \ + --hash=sha256:0f2fa354ba106eafff2c14b0cc51f22801d1e8b2e4149342023bd6f0955de5f5 \ + --hash=sha256:12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148 \ + --hash=sha256:22d8798819f86720bc646ab015baff5ea4c971d68121cb36e2ebc2ee43ead2b7 \ + --hash=sha256:233088b4b99ebcbc5258c755a097aa52fbf90727a03a5a80781c4b9c54347a2e \ + --hash=sha256:24bd94bb301ec672d8f0623eba9226cc90d775d25a0c92b5f8e4965d7f3a1518 \ + --hash=sha256:275424295f4256fd301744b8f335cff367825d270f155d522b30c7bf49903ee7 \ + --hash=sha256:32fe6a41ad97302db2931f05bb91abbcc65b5ce4c675cd44b972428dd2947700 \ + --hash=sha256:334edbcff10514ad1d66e3a70b339c0a29886394892490119dbb669627b17717 \ + --hash=sha256:3bb9ec6436a820a4c006aad1ac351f12de2f2dbdaad171692ee457a02429b672 \ + --hash=sha256:3ddcb27fb39171de36e207600116ac9dfd4ae46f86c82a9bf3934043e80ebb88 \ + --hash=sha256:42e8804962f9e6f4be2cbaedc0c3718f08f60a16910fa3d86da5a1e3b1bfe60f \ + --hash=sha256:43d044780732d9e0381ac8d5316f95d7f02ef04d6e4ef6dc82379f09795d993f \ + --hash=sha256:46796877b47034b559a593d7e4b549aba151dae73f9e78212a3478161c12ab08 \ + --hash=sha256:46d51518d53edfbe0563662c96954dc8fcace9832332b914375f45a99b77cc9a \ + --hash=sha256:47604cb2159f8bbd5a1ab48a714557156320f20871ee64d550d8bf2683d980d3 \ + --hash=sha256:4bbccb45260e4ff1b7db0be80a9025bb1e6698bdb808b83fff0000f7a90b2c0b \ + --hash=sha256:4d4e5a0ceba319942fa6b585cf82539288a61e314ef006c1209f734551ab9536 \ + --hash=sha256:55250fe61d6ebfd6934a272ee16ef1244e0f16b7af6cd18ab5b1fc9f08631db0 \ + --hash=sha256:566df36fd0e901625523a5a1835032f1ebdd7f7886c54584143fa6c668b4df3b \ + --hash=sha256:57ca426a48eb2c682dae8204cd89ea8ab7031e2675120a47924fabc7caacbc2a \ + --hash=sha256:5e61abbec255be7b122aa461021daa7c3f310f3e743411a67079f9b3cc91ece3 \ + --hash=sha256:618a308215b6cececb6240b9abde545e3acdabac7ae3e1d4e666896bf5ba44b4 \ + --hash=sha256:62557958002b69699bdb7f5137c6714ca1133f045f97b3903964f47db97ea339 \ + --hash=sha256:6270d717b11c5476b0cbb21eedc8d4dbb7d1a956fd6c15a23e96f197a6193158 \ + --hash=sha256:685e93e9c8f399b0c96a624799820176312f5ceef958c0f88215af4013d29066 \ + --hash=sha256:69469ce8ce7a8df4d37620e3163b71238719e1e2e5048d114a1b6ce0fbf8c662 \ + --hash=sha256:6eb188b84269f357669b62cb576b5b918de10fb7c728a005fa0ebb0b758adce1 \ + --hash=sha256:74ab4ee7794d7ed1b0c37e7333640e0f0a626fc7b398c07a7aef52f484fddde3 \ + --hash=sha256:77641d299179c37b89cf2343ca9972c88bb6eef0d5fc504a2f86afd15cd5adf5 \ + --hash=sha256:7c821c47ecfe05cc32140dcf8dc6fd5d21971c86dbd56eabfe5ba07a64910c01 \ + --hash=sha256:7d6be30b2a75362325176c036d7fb8d19e8846c77e87683ffaa8177b35135613 \ + --hash=sha256:7f605a456948c35260e7b2a39f8952a26f077fd25653c37740ed186b90aaa68a \ + --hash=sha256:83101a6930332b87653886c01d1ee7e294b1fe46a07dd9a2d2b4f91bcc88eec0 \ + --hash=sha256:88690f4e1f0fbf5339bedbb127e240fec1fd3070e9934c0b7bef83432f779d2f \ + --hash=sha256:8a97ac839c2c6672c4865e48f3cbad7152cee85f4233fb4ca6291d775b9b954a \ + --hash=sha256:8d6efc136f44a7e8bc8088507eaabbb8c2b55b3dbb63fe102c690da0ddebe55e \ + --hash=sha256:8e20e511dc15265fb433571391ba313e10dd8ea7e509d51686a51313b4ac01a2 \ + --hash=sha256:951d4a210744813be63019f3df343bf233b7432aadf0db54c75802247330d3af \ + --hash=sha256:9ac7a3e245fd0310fd31495eb61af772e637bdf7d88ee81e7f10a3f271bff014 \ + --hash=sha256:9b1c058c171b739e7c330760044803099c7fff11511e3ab3573e5327116a9c33 \ + --hash=sha256:9c04bff9a5335eb95c6ecf1c117576a0aa560def274876fd156cfe5510fccc61 \ + --hash=sha256:9c4969a86e41454f2858256c39bdfb966a20961e9b58bf8749b65abf447e9a8d \ + --hash=sha256:9e0400fa22f79acc334d9a6b185dc00a44a8e6578aa7e12d0ddcd8434152b187 \ + --hash=sha256:a05977bffe9bffd2229f477fa75eabe3192b1b05f408961d1bebff8d1cd4d401 \ + --hash=sha256:a143af2ea6672f2af3f44ed8f9cd020e9cc34c56f0e8db12019d5d9ecf41cb3b \ + --hash=sha256:a51d3db74ba489266ef55c7a4534eb0b8db9a326553df481c11e5d7660c8364d \ + --hash=sha256:b95b2f470c1b2683febd2e7eab1d3f0e078c91dbdd0b00e9c645d07a413bb99f \ + --hash=sha256:b9870d15ef00e4d0559ae10ee5bc71b654d1f20076dbe8bc7ed19b4c0625ceba \ + --hash=sha256:c1dc3368794d522f43914e03312202523cc89692f5389c32bea0233924f8d977 \ + --hash=sha256:c338ec6ec01c0bc8e735c58b9f5d51e75bacb6ff23296658826d7cfdfdb8678a \ + --hash=sha256:c5070135e1b7409c4161133aa525419b0062088ed77c92b1da95366ec5cbebbe \ + --hash=sha256:cc992c6ed024c8c3c592c5fc9846a03dd68a425674900c70122c77ea16c5fb0b \ + --hash=sha256:d15950a57a210e36dd4cec1aac22787e2a4d57ba9318233e2ef8b2daf9ff2d5f \ + --hash=sha256:d898cc2c76c135ef65517f4ddd7a3512fb41f23087b0650efb3418b8389a3cd1 \ + --hash=sha256:d99945830a6f3e9638d89a28ed130b1eb24c91255e4f24366fbe699b983f29e4 \ + --hash=sha256:da9b91bca419dc9b9267ffadde24eae9b1a6bffcd09d0a207e5e3af99a03ce0d \ + --hash=sha256:df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120 \ + --hash=sha256:e06e617e3d4fd9e51d385dfe45b077a41e9d1b033a7702551e3278ac597dc750 \ + --hash=sha256:ec44cfa7ef1a728e88ad41674de50f6db8cfdb3e2af84af86e0041aaf02d43d0 \ + --hash=sha256:fb37f15714ec2652d574f021d479e78cd4eb9d04396dca36568fdfffb3487982 # via feast (pyproject.toml) -sqlglot[rs]==30.2.1 \ - --hash=sha256:ef4a67cc6f66a8043085eb8ea95fa9541c1625dffa9145ad4e9815a7ba60a199 \ - --hash=sha256:f23d9ee9427ef9d20df15f9b0ffa57d9eb45e52b012219a349d1e6b50ed926d1 +sqlglot[rs]==30.6.0 \ + --hash=sha256:246d34d39927422a50a3fa155f37b2f6346fba85f1a755b13c941eb32ef93361 \ + --hash=sha256:e005fc2f47994f90d7d8df341f1cbe937518497b0b7b1507d4c03c4c9dfd2778 # via # feast (pyproject.toml) # ibis-framework -sqlglotc==30.2.1 \ - --hash=sha256:052cd7bb41fc9b841eb268d4dd601eb6b5954b7c6d5656795d4350a0f8020d53 \ - --hash=sha256:058f0e9aed2b8dff87dc893b8793e514204c8dfef699b7d3d1704dfbdd949f2b \ - --hash=sha256:0e6be524252894c0fa98d25d4e60dfae6485ba66ca1abd40bf05f16a9cf26baf \ - --hash=sha256:13f8f68808777ba7d845bc908bf09f72a0c9899a19811483dc52f0fa48b38d5a \ - --hash=sha256:1a004086ab871be0cc97766f7b6fb8866729f09dd7272254fd31c05107f3fdc8 \ - --hash=sha256:25c6f62f31cd3a051285635c3f6a01d2f3c73ca2baaa26970815166928042ace \ - --hash=sha256:2b5fe8adc1a1e2fb819e014e94974a274f30dbf9684ceed9f171fb0889f80f0b \ - --hash=sha256:2ffe527bc8664b03cc936bae7ebf965f482beb4acee7a815c2ec2d9aea720b4e \ - --hash=sha256:4aa90e08f53409b1857572836e57a31835ed20e32521c6fafdc6af96199baff7 \ - --hash=sha256:507935a971e0a9e5d4ac7ca14df479f8e270502b44904f71d95c0aaed066006f \ - --hash=sha256:515e092ab8fb522b256fa8a34f471e9b187bb8a50a7c0226a65b036a07d6d188 \ - --hash=sha256:585bb610fde3e3dd1d7e5ff3cce14f70fbd53ced6769cd104679adf8b5c4ab5b \ - --hash=sha256:850e7517dd4739cad9af65bcb9699825f9202e5971407bf955e3248fe4814f96 \ - --hash=sha256:8f063af733cbcc51686380470e7f3f80b589b8c58084baa138efb3b8ca821597 \ - --hash=sha256:b17e3002ed10747388367621b2ecf39c06d5fdc6b3c31a8c32be2f5ef546fc0b \ - --hash=sha256:d577e1635e127febb7012bc42fa1c3b958076e59a1a116ade20048c572a1be42 \ - --hash=sha256:dc292cd73e0c447253877c27f00454a2d09b71324a130ad4c58c145ab753889e \ - --hash=sha256:de168df756a21a028cf1f917f92da2f77bb135f3b6cdd960914460942a5eca10 \ - --hash=sha256:de884dd224220002c3e940ca5bdceb27ef9638e5f02493db133ffb8ae88b5610 \ - --hash=sha256:f33c7d1646ff6531cb9b07f0740b2939f3ecaa31efebfbec8adb6b275f1a45f2 \ - --hash=sha256:f9a1fc7b1ff3b51d0d03a391768a79964f68541b4c2f294a25a6f14e6670ffab \ - --hash=sha256:fae4edad0b7c5f9f963bd63452f722f0d7f77a436c2d334b555b31722f9573ad \ - --hash=sha256:fdc19623a1c7659918c3cee18ea8849fc4af9eaeb87247acf37e0393295d32b7 \ - --hash=sha256:feefc0ab7606d1fe284d23bef09ea4829ce4fad679936959c29324310f23e081 \ - --hash=sha256:ff19b7ecb931aef6c7c6168af5530c07e67915102b701d45ae80446f0695ba54 +sqlglotc==30.6.0 \ + --hash=sha256:003b15bbe3f3a4a63313baeb3f090906cf0172fe007ab24974c612a577f56c61 \ + --hash=sha256:05861b5d74ae4b0a5a6e6a9309a8a975d9572c2bf1eb9634a33af9189eb7d333 \ + --hash=sha256:0b907206ef36fd8f0c28da4c5b8c8f896bd67826da0d765616e6c950689ac849 \ + --hash=sha256:0e1aae195008c1d87ed1b1543bceed1408ae8ecf146571b3029e98b23a19c59c \ + --hash=sha256:16291ee3da0276df2689cc139df41d8723cf6014aca979f307fb75a898b0d3e8 \ + --hash=sha256:27d6c22375395f1fdfe8a5d80b5fb781ca7849e29c7db7dfb11edb466a5b7a4d \ + --hash=sha256:2b50aba396d4622c201a9dd933b51cd6858b5af5ebbcf7db1af35db7e83ece48 \ + --hash=sha256:4a5beba24625bc14070992fdddc7aed22df912007882f31f27b0e88d7b7d9445 \ + --hash=sha256:4c84a933816374b6167d9347e488fb4a357bb0e3be2e8e820dafeb3c9948feab \ + --hash=sha256:4d45ee83e1f72ee94045ccfd13e51fa7d822548f50e9d20d3d42e127bcd9f453 \ + --hash=sha256:4eb6f349c21d5a3e39733db5416e57ec171ca3b1c17b02badfdbe55d9a3666a5 \ + --hash=sha256:61a1e4f533955db0bfd4219883bfab1f2030753ffaebc9cbb4e950dfbcae3db7 \ + --hash=sha256:63b02231cc2f10d63df373fa02f3e03b4216e94c6f32ccdfd11adc770dc95fb7 \ + --hash=sha256:6e8dab3b9f84c9b591ecd1fb0920b800c08dd6c38eda3be91176fc239d3c94bc \ + --hash=sha256:7acdb7b15f060bacea01e1c68d1dd70471f03bda89478ca0ee96bac3df03d0a7 \ + --hash=sha256:87437d4f32c1dc61c3ef046dc39b9fe119ac2e2e5253e33351f1a62ba802942a \ + --hash=sha256:875c6925f3d70aa1bc4bcc405090a12deec01de71193e7229f114c5ecf39f725 \ + --hash=sha256:949f5d457c8c98998ed06d060873370d7553077ab3c2db9569acda5887cd6ce7 \ + --hash=sha256:c69c9dbe4dfab74329294d07b2956ca9a03123089a1923f3d299a21d4b66898d \ + --hash=sha256:cb4b5a532fb35ce415aea6d360fe202278b46cc59c07318b97401930a1584e35 \ + --hash=sha256:cfba6244f52bcdffe22a35334d48d741aed3077c20bb7aa9bb511c21fd766438 \ + --hash=sha256:dd781790c3fc6cb82e6c00836f7f9ab33941cf2b9dca173d7b9f41c37c78d114 \ + --hash=sha256:e397befde3d08d870a8f1c7bd80d7abc68ee119c472143ab196709319e205af4 \ + --hash=sha256:f0a37ad865b106005cb5d36efd537a412912477c83cbca1579ee45f17d73fe54 \ + --hash=sha256:fb977d427a196a620aa60b71d4b66d60c3d015c9004e7393162d4771fb435406 # via sqlglot sqlglotrs==0.13.0 \ --hash=sha256:6b934a244b16f26fca50974328a2ebc7689583c59f06203cebb46e2e6e8d93a7 \ @@ -5633,9 +5722,9 @@ sqlparams==6.2.0 \ --hash=sha256:3744a2ad16f71293db6505b21fd5229b4757489a9b09f3553656a1ae97ba7ca5 \ --hash=sha256:63b32ed9051bdc52e7e8b38bc4f78aed51796cdd9135e730f4c6a7db1048dedf # via singlestoredb -sse-starlette==3.3.4 \ - --hash=sha256:84bb06e58939a8b38d8341f1bc9792f06c2b53f48c608dd207582b664fc8f3c1 \ - --hash=sha256:aaf92fc067af8a5427192895ac028e947b484ac01edbc3caf00e7e7137c7bef1 +sse-starlette==3.4.1 \ + --hash=sha256:6b43cf21f1d574d582a6e1b0cfbde1c94dc86a32a701a7168c99c4475c6bd1d0 \ + --hash=sha256:f780bebcf6c8997fe514e3bd8e8c648d8284976b391c8bed0bcb1f611632b555 # via mcp stack-data==0.6.3 \ --hash=sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9 \ @@ -5669,9 +5758,9 @@ terminado==0.18.1 \ # via # jupyter-server # jupyter-server-terminals -testcontainers==4.9.0 \ - --hash=sha256:2cd6af070109ff68c1ab5389dc89c86c2dc3ab30a21ca734b2cb8f0f80ad479e \ - --hash=sha256:c6fee929990972c40bf6b91b7072c94064ff3649b405a14fde0274c8b2479d32 +testcontainers==4.15.0rc2 \ + --hash=sha256:4764016e73da0fa960eb8360687d22710cd68bcc01a4d03189fbe1da896a805d \ + --hash=sha256:e55b9045842c5bdfdd295e0d0b09aeafb3c1fb9d6f30bd8e718df8fd48dcdc41 # via feast (pyproject.toml) threadpoolctl==3.6.0 \ --hash=sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb \ @@ -6016,15 +6105,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 \ @@ -6073,9 +6163,9 @@ typer==0.12.5 \ # docling # docling-core # fastapi-mcp -types-cffi==2.0.0.20260402 \ - --hash=sha256:47e1320c009f630c59c55c8e3d2b8c501e280babf52e92f6109cbfb0864ba367 \ - --hash=sha256:f647a400fba0a31d603479169d82ee5359db79bd1136e41dc7e6489296e3a2b2 +types-cffi==2.0.0.20260429 \ + --hash=sha256:6a4237bfdbd50e4d0726929070d8b9983bde541726a5a6fe0e8e24e78c1b3826 \ + --hash=sha256:afe7d9777a2921139623af0b94647637a5bd0b938b77ec125e5e5e068a1727bd # via types-pyopenssl types-protobuf==3.19.22 \ --hash=sha256:d291388678af91bb045fafa864f142dc4ac22f5d4cdca097c7d8d8a32fa9b3ab \ @@ -6083,25 +6173,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.20260408 \ + --hash=sha256:b784dc37908479e3767e2d794ab507b3674adb1c686ca3d13fc9e2960dbcb9ec \ + --hash=sha256:da630647eaaa7a926a3907794f4067f269cd245b2c202c74aa3c6a3bd660a9db # 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.20260402 \ - --hash=sha256:7827e6a9c93587cc18e766944254d1351a2396262e4abe1510cbbd7601c5e01f \ - --hash=sha256:a980142b9966713acb382c467e35c5cc4208a2f91b10b8d785a0ae6765df6c0b +types-python-dateutil==2.9.0.20260408 \ + --hash=sha256:473139d514a71c9d1fbd8bb328974bedcb1cc3dba57aad04ffa4157f483c216f \ + --hash=sha256:8b056ec01568674235f64ecbcef928972a5fac412f5aab09c516dfa2acfbb582 # via feast (pyproject.toml) -types-pytz==2026.1.1.20260402 \ - --hash=sha256:0d9a60ed1c6ad4fce7c6395b5bd2d9827db41d4b83de7c0322cf85869c2bfda3 \ - --hash=sha256:79209aa51dc003a4a6a764234d92b14e5c09a1b7f24e0f00c493929fd33618e8 +types-pytz==2026.1.1.20260408 \ + --hash=sha256:89b6a34b9198ea2a4b98a9d15cbca987053f52a105fd44f7ce3789cae4349408 \ + --hash=sha256:c7e4dec76221fb7d0c97b91ad8561d689bebe39b6bcb7b728387e7ffd8cde788 # via feast (pyproject.toml) -types-pyyaml==6.0.12.20250915 \ - --hash=sha256:0f8b54a528c303f0e6f7165687dd33fafa81c807fcac23f632b63aa624ced1d3 \ - --hash=sha256:e7d4d9e064e89a3b3cae120b4990cd370874d2bf12fa5f46c97018dd5d3c9ab6 +types-pyyaml==6.0.12.20260408 \ + --hash=sha256:92a73f2b8d7f39ef392a38131f76b970f8c66e4c42b3125ae872b7c93b556307 \ + --hash=sha256:fbc42037d12159d9c801ebfcc79ebd28335a7c13b08a4cfbc6916df78fee9384 # via feast (pyproject.toml) types-redis==4.6.0.20241004 \ --hash=sha256:5f17d2b3f9091ab75384153bfa276619ffa1cf6a38da60e10d5e6749cc5b902e \ @@ -6111,15 +6201,15 @@ types-requests==2.30.0.0 \ --hash=sha256:c6cf08e120ca9f0dc4fa4e32c3f953c3fba222bcc1db6b97695bce8da1ba9864 \ --hash=sha256:dec781054324a70ba64430ae9e62e7e9c8e4618c185a5cb3f87a6738251b5a31 # via feast (pyproject.toml) -types-setuptools==82.0.0.20260402 \ - --hash=sha256:4b9a9f6c3c4c65107a3956ad6a6acbccec38e398ff6d5f78d5df7f103dadb8d6 \ - --hash=sha256:63d2b10ba7958396ad79bbc24d2f6311484e452daad4637ffd40407983a27069 +types-setuptools==82.0.0.20260408 \ + --hash=sha256:036c68caf7e672a699f5ebbf914708d40644c14e05298bc49f7272be91cf43d3 \ + --hash=sha256:ece0a215cdfa6463a65fd6f68bd940f39e455729300ddfe61cab1147ed1d2462 # via # feast (pyproject.toml) # types-cffi -types-tabulate==0.10.0.20260308 \ - --hash=sha256:724dcb1330ffba5f46d3cf6e29f45089fccb8e85801e6e7ac9efb1195bf7bea1 \ - --hash=sha256:94a9795965bc6290f844d61e8680a1270040664b88fd12014624090fd847e13c +types-tabulate==0.10.0.20260408 \ + --hash=sha256:2b19d193603d38c34645de53c0c1087e2364487d518d4a2f44268db2366723cc \ + --hash=sha256:903d62fdf7e5a0ff659fd5d629df716232f7658c6d30e98f0374488d06ffacf4 # via feast (pyproject.toml) types-urllib3==1.26.25.14 \ --hash=sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f \ @@ -6175,9 +6265,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 @@ -6557,9 +6647,9 @@ werkzeug==3.1.8 \ --hash=sha256:63a77fb8892bf28ebc3178683445222aa500e48ebad5ec77b0ad80f8726b1f50 \ --hash=sha256:9bad61a4268dac112f1c5cd4630a56ede601b6ed420300677a869083d70a4c44 # via moto -wheel==0.46.3 \ - --hash=sha256:4b399d56c9d9338230118d705d9737a2a468ccca63d5e813e2a4fc7815d8bc4d \ - --hash=sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803 +wheel==0.47.0 \ + --hash=sha256:212281cab4dff978f6cedd499cd893e1f620791ca6ff7107cf270781e587eced \ + --hash=sha256:cc72bd1009ba0cf63922e28f94d9d83b920aa2bb28f798a31d0691b02fa3c9b3 # via # pip-tools # singlestoredb @@ -6651,6 +6741,7 @@ wrapt==1.17.3 \ --hash=sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c # via # aiobotocore + # deprecated # smart-open # testcontainers xlsxwriter==3.2.9 \ @@ -6661,147 +6752,194 @@ 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 \ @@ -6933,9 +7071,9 @@ yarl==1.23.0 \ --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d # via aiohttp -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==3.23.1 \ + --hash=sha256:0b3596c50a5c700c9cb40ba8d86d9f2cc4807e9bedb06bcdf7fac85633e444dc \ + --hash=sha256:32120e378d32cd9714ad503c1d024619063ec28aad2248dc6672ad13edfa5110 # 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 741d147c860..48a46a21175 100644 --- a/sdk/python/requirements/py3.11-minimal-requirements.txt +++ b/sdk/python/requirements/py3.11-minimal-requirements.txt @@ -194,9 +194,9 @@ botocore==1.38.46 \ # boto3 # s3transfer # snowflake-connector-python -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +certifi==2026.4.22 \ + --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ + --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 # via # httpcore # httpx @@ -424,9 +424,9 @@ charset-normalizer==3.4.7 \ # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.3.3 \ + --hash=sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2 \ + --hash=sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 # via # feast (pyproject.toml) # dask @@ -440,56 +440,56 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via feast (pyproject.toml) -cryptography==46.0.6 \ - --hash=sha256:02fad249cb0e090b574e30b276a3da6a149e04ee2f049725b1f69e7b8351ec70 \ - --hash=sha256:063b67749f338ca9c5a0b7fe438a52c25f9526b851e24e6c9310e7195aad3b4d \ - --hash=sha256:12cae594e9473bca1a7aceb90536060643128bb274fcea0fc459ab90f7d1ae7a \ - --hash=sha256:12f0fa16cc247b13c43d56d7b35287ff1569b5b1f4c5e87e92cc4fcc00cd10c0 \ - --hash=sha256:22259338084d6ae497a19bae5d4c66b7ca1387d3264d1c2c0e72d9e9b6a77b97 \ - --hash=sha256:26031f1e5ca62fcb9d1fcb34b2b60b390d1aacaa15dc8b895a9ed00968b97b30 \ - --hash=sha256:27550628a518c5c6c903d84f637fbecf287f6cb9ced3804838a1295dc1fd0759 \ - --hash=sha256:2b417edbe8877cda9022dde3a008e2deb50be9c407eef034aeeb3a8b11d9db3c \ - --hash=sha256:2ea0f37e9a9cf0df2952893ad145fd9627d326a59daec9b0802480fa3bcd2ead \ - --hash=sha256:2ef9e69886cbb137c2aef9772c2e7138dc581fad4fcbcf13cc181eb5a3ab6275 \ - --hash=sha256:341359d6c9e68834e204ceaf25936dffeafea3829ab80e9503860dcc4f4dac58 \ - --hash=sha256:380343e0653b1c9d7e1f55b52aaa2dbb2fdf2730088d48c43ca1c7c0abb7cc2f \ - --hash=sha256:3c21d92ed15e9cfc6eb64c1f5a0326db22ca9c2566ca46d845119b45b4400361 \ - --hash=sha256:3dfa6567f2e9e4c5dceb8ccb5a708158a2a871052fa75c8b78cb0977063f1507 \ - --hash=sha256:456b3215172aeefb9284550b162801d62f5f264a081049a3e94307fe20792cfa \ - --hash=sha256:4668298aef7cddeaf5c6ecc244c2302a2b8e40f384255505c22875eebb47888b \ - --hash=sha256:50575a76e2951fe7dbd1f56d181f8c5ceeeb075e9ff88e7ad997d2f42af06e7b \ - --hash=sha256:639301950939d844a9e1c4464d7e07f902fe9a7f6b215bb0d4f28584729935d8 \ - --hash=sha256:64235194bad039a10bb6d2d930ab3323baaec67e2ce36215fd0952fad0930ca8 \ - --hash=sha256:6617f67b1606dfd9fe4dbfa354a9508d4a6d37afe30306fe6c101b7ce3274b72 \ - --hash=sha256:67177e8a9f421aa2d3a170c3e56eca4e0128883cf52a071a7cbf53297f18b175 \ - --hash=sha256:6728c49e3b2c180ef26f8e9f0a883a2c585638db64cf265b49c9ba10652d430e \ - --hash=sha256:6739d56300662c468fddb0e5e291f9b4d084bead381667b9e654c7dd81705124 \ - --hash=sha256:69cf0056d6947edc6e6760e5f17afe4bea06b56a9ac8a06de9d2bd6b532d4f3a \ - --hash=sha256:760997a4b950ff00d418398ad73fbc91aa2894b5c1db7ccb45b4f68b42a63b3c \ - --hash=sha256:79e865c642cfc5c0b3eb12af83c35c5aeff4fa5c672dc28c43721c2c9fdd2f0f \ - --hash=sha256:7e6142674f2a9291463e5e150090b95a8519b2fb6e6aaec8917dd8d094ce750d \ - --hash=sha256:7f417f034f91dcec1cb6c5c35b07cdbb2ef262557f701b4ecd803ee8cefed4f4 \ - --hash=sha256:7f6690b6c55e9c5332c0b59b9c8a3fb232ebf059094c17f9019a51e9827df91c \ - --hash=sha256:8927ccfbe967c7df312ade694f987e7e9e22b2425976ddbf28271d7e58845290 \ - --hash=sha256:8ce35b77aaf02f3b59c90b2c8a05c73bac12cea5b4e8f3fbece1f5fddea5f0ca \ - --hash=sha256:8e7304c4f4e9490e11efe56af6713983460ee0780f16c63f219984dab3af9d2d \ - --hash=sha256:90e5f0a7b3be5f40c3a0a0eafb32c681d8d2c181fc2a1bdabe9b3f611d9f6b1a \ - --hash=sha256:97c8115b27e19e592a05c45d0dd89c57f81f841cc9880e353e0d3bf25b2139ed \ - --hash=sha256:9a693028b9cbe51b5a1136232ee8f2bc242e4e19d456ded3fa7c86e43c713b4a \ - --hash=sha256:9a9c42a2723999a710445bc0d974e345c32adfd8d2fac6d8a251fa829ad31cfb \ - --hash=sha256:a3e84d5ec9ba01f8fd03802b2147ba77f0c8f2617b2aff254cedd551844209c8 \ - --hash=sha256:aad75154a7ac9039936d50cf431719a2f8d4ed3d3c277ac03f3339ded1a5e707 \ - --hash=sha256:b12c6b1e1651e42ab5de8b1e00dc3b6354fdfd778e7fa60541ddacc27cd21410 \ - --hash=sha256:b928a3ca837c77a10e81a814a693f2295200adb3352395fad024559b7be7a736 \ - --hash=sha256:bcb87663e1f7b075e48c3be3ecb5f0b46c8fc50b50a97cf264e7f60242dca3f2 \ - --hash=sha256:c797e2517cb7880f8297e2c0f43bb910e91381339336f75d2c1c2cbf811b70b4 \ - --hash=sha256:c89eb37fae9216985d8734c1afd172ba4927f5a05cfd9bf0e4863c6d5465b013 \ - --hash=sha256:cdcd3edcbc5d55757e5f5f3d330dd00007ae463a7e7aa5bf132d1f22a4b62b19 \ - --hash=sha256:d24c13369e856b94892a89ddf70b332e0b70ad4a5c43cf3e9cb71d6d7ffa1f7b \ - --hash=sha256:d4e4aadb7fc1f88687f47ca20bb7227981b03afaae69287029da08096853b738 \ - --hash=sha256:d9528b535a6c4f8ff37847144b8986a9a143585f0540fbcb1a98115b543aa463 \ - --hash=sha256:ed3775295fb91f70b4027aeba878d79b3e55c0b3e97eaa4de71f8f23a9f2eb77 \ - --hash=sha256:ed418c37d095aeddf5336898a132fba01091f0ac5844e3e8018506f014b6d2c4 +cryptography==47.0.0 \ + --hash=sha256:0024b87d47ae2399165a6bfb20d24888881eeab83ae2566d62467c5ff0030ce7 \ + --hash=sha256:07efe86201817e7d3c18781ca9770bc0db04e1e48c994be384e4602bc38f8f27 \ + --hash=sha256:09f6d7bf6724f8db8b32f11eccf23efc8e759924bc5603800335cf8859a3ddbd \ + --hash=sha256:11438c7518132d95f354fa01a4aa2f806d172a061a7bed18cf18cbdacdb204d7 \ + --hash=sha256:11dbb9f50a0f1bb9757b3d8c27c1101780efb8f0bdecfb12439c22a74d64c001 \ + --hash=sha256:14432c8a9bcb37009784f9594a62fae211a2ae9543e96c92b2a8e4c3cd5cd0c4 \ + --hash=sha256:1581aef4219f7ca2849d0250edaa3866212fb74bf5667284f46aa92f9e65c1ca \ + --hash=sha256:160ad728f128972d362e714054f6ba0067cab7fb350c5202a9ae8ae4ce3ef1a0 \ + --hash=sha256:1a405c08857258c11016777e11c02bacbe7ef596faf259305d282272a3a05cbe \ + --hash=sha256:1e47422b5557bb82d3fff997e8d92cff4e28b9789576984f08c248d2b3535d93 \ + --hash=sha256:20fdbe3e38fb67c385d233c89371fa27f9909f6ebca1cecc20c13518dae65475 \ + --hash=sha256:2207a498b03275d0051589e326b79d4cf59985c99031b05bb292ac52631c37fe \ + --hash=sha256:256d07c78a04d6b276f5df935a9923275f53bd1522f214447fdf365494e2d515 \ + --hash=sha256:2b45761c6ec22b7c726d6a829558777e32d0f1c8be7c3f3480f9c912d5ee8a10 \ + --hash=sha256:2ebd84adf0728c039a3be2700289378e1c164afc6748df1a5ed456767bef9ba7 \ + --hash=sha256:34b4358b925a5ea3e14384ca781a2c0ef7ac219b57bb9eacc4457078e2b19f92 \ + --hash=sha256:3fb8fa48075fad7193f2e5496135c6a76ac4b2aa5a38433df0a539296b377829 \ + --hash=sha256:4e1de79e047e25d6e9f8cea71c86b4a53aced64134f0f003bbcbf3655fd172c8 \ + --hash=sha256:4f7722c97826770bab8ae92959a2e7b20a5e9e9bf4deae68fd86c3ca457bab52 \ + --hash=sha256:51c9313e90bd1690ec5a75ed047c27c0b8e6c570029712943d6116ef9a90620b \ + --hash=sha256:5d0e362ff51041b0c0d219cc7d6924d7b8996f57ce5712bdcef71eb3c65a59cc \ + --hash=sha256:6651d32eff255423503aa276739da98c30f26c40cbeffcc6048e0d54ef704c0c \ + --hash=sha256:6eebcaf0df1d21ce1f90605c9b432dd2c4f4ab665ac29a40d5e3fc68f51b5e63 \ + --hash=sha256:6f29f36582e6151d9686235e586dd35bb67491f024767d10b842e520dc6a07ac \ + --hash=sha256:7a02675e2fabd0c0fc04c868b8781863cbf1967691543c22f5470500ff840b31 \ + --hash=sha256:7f1207974a904e005f762869996cf620e9bf79ecb4622f148550bb48e0eb35a7 \ + --hash=sha256:7f68d6fbc7fbbcfb0939fea72c3b96a9f9a6edfc0e1b1d29778a2066030418b1 \ + --hash=sha256:7fda2f02c9015db3f42bb8a22324a454516ed10a8c29ca6ece6cdbb5efe2a203 \ + --hash=sha256:80887c5cbd1774683cb126f0ab4184567f080071d5acf62205acb354b4b753b7 \ + --hash=sha256:835d2d7f47cdc53b3224e90810fb1d36ca94ea29cc1801fb4c1bc43876735769 \ + --hash=sha256:8c1a736bbb3288005796c3f7ccb9453360d7fed483b13b9f468aea5171432923 \ + --hash=sha256:9af828c0d5a65c70ec729cd7495a4bf1a67ecb66417b8f02ff125ab8a6326a74 \ + --hash=sha256:9c59ab0e0fa3a180a5a9c59f3a5abe3ef90d474bc56d7fadfbe80359491b615b \ + --hash=sha256:9f8e55fe4e63613a5e1cc5819030f27b97742d720203a087802ce4ce9ceb52bb \ + --hash=sha256:9fe6b7c64926c765f9dff301f9c1b867febcda5768868ca084e18589113732ab \ + --hash=sha256:a49a3eb5341b9503fa3000a9a0db033161db90d47285291f53c2a9d2cd1b7f76 \ + --hash=sha256:a9b761f012a943b7de0e828843c5688d0de94a0578d44d6c85a1bae32f87791f \ + --hash=sha256:b1c76fca783aa7698eb21eb14f9c4aa09452248ee54a627d125025a43f83e7a7 \ + --hash=sha256:b9a8943e359b7615db1a3ba587994618e094ff3d6fa5a390c73d079ce18b3973 \ + --hash=sha256:be12cb6a204f77ed968bcefe68086eb061695b540a3dd05edac507a3111b25f0 \ + --hash=sha256:cffbba3392df0fa8629bb7f43454ee2925059ee158e23c54620b9063912b86c8 \ + --hash=sha256:ed67ea4e0cfb5faa5bc7ecb6e2b8838f3807a03758eec239d6c21c8769355310 \ + --hash=sha256:edd4da498015da5b9f26d38d3bfc2e90257bfa9cbed1f6767c282a0025ae649b \ + --hash=sha256:ef6b3634087f18d2155b1e8ce264e5345a753da2c5fa9815e7d41315c90f8318 \ + --hash=sha256:f1557695e5c2b86e204f6ce9470497848634100787935ab7adc5397c54abd7ab \ + --hash=sha256:f5c15764f261394b22aef6b00252f5195f46f2ca300bec57149474e2538b31f8 \ + --hash=sha256:f5c3296dab66202f1b18a91fa266be93d6aa0c2806ea3d67762c69f60adc71aa \ + --hash=sha256:f7db373287273d8af1414cf95dc4118b13ffdc62be521997b0f2b270771fef50 \ + --hash=sha256:f9a034b642b960767fb343766ae5ba6ad653f2e890ddd82955aef288ffea8736 # via # google-auth # pyjwt @@ -509,50 +509,50 @@ dill==0.3.9 \ --hash=sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a \ --hash=sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c # via feast (pyproject.toml) -duckdb==1.5.1 \ - --hash=sha256:054ad424b051b334052afac58cb216f3b1ebb8579fc8c641e60f0182e8725ea9 \ - --hash=sha256:05fc91767d0cfc4cf2fa68966ab5b479ac07561752e42dd0ae30327bd160f64a \ - --hash=sha256:0a6acc2040bec1f05de62a2f3f68f4c12f3ec7d6012b4317d0ab1a195af26225 \ - --hash=sha256:26e56b5f0c96189e3288d83cf7b476e23615987902f801e5788dee15ee9f24a9 \ - --hash=sha256:36e8e32621a9e2a9abe75dc15a4b54a3997f2d8b1e53ad754bae48a083c91130 \ - --hash=sha256:40c5220ec93790b18ec6278da9c6ac2608d997ee6d6f7cd44c5c3992764e8e71 \ - --hash=sha256:446d500a2977c6ae2077f340c510a25956da5c77597175c316edfa87248ceda3 \ - --hash=sha256:46f92ada9023e59f27edc048167b31ac9a03911978b1296c845a34462a27f096 \ - --hash=sha256:482f8a13f2600f527e427f73c42b5aa75536f9892868068f0aaf573055a0135f \ - --hash=sha256:553c273a6a8f140adaa6da6a6135c7f95bdc8c2e5f95252fcdf9832d758e2141 \ - --hash=sha256:5ae7c0d744d64e2753149634787cc4ab60f05ef1e542b060eeab719f3cdb7723 \ - --hash=sha256:5d4147422d91ccdc2d2abf6ed24196025e020259d1d267970ae20c13c2ce84b1 \ - --hash=sha256:6af347debc8b721aa72e48671166282da979d5e5ae52dbc660ab417282b48e23 \ - --hash=sha256:6ba302115f63f6482c000ccfd62efdb6c41d9d182a5bcd4a90e7ab8cd13856eb \ - --hash=sha256:6f7361d66cc801d9eb4df734b139cd7b0e3c257a16f3573ebd550ddb255549e6 \ - --hash=sha256:715f05ea198d20d7f8b407b9b84e0023d17f2b9096c194cea702b7840e74f1f7 \ - --hash=sha256:71dddcebbc5a70e946a06c30b59b5dd7999c9833d307168f90fb4e4b672ab63e \ - --hash=sha256:8150c569b2aa4573b51ba8475e814aa41fd53a3d510c1ffb96f1139f46faf611 \ - --hash=sha256:8843bd9594e1387f1e601439e19ad73abdf57356104fd1e53a708255bb95a13d \ - --hash=sha256:8c0088765747ae5d6c9f89987bb36f9fb83564f07090d721344ce8e1abedffea \ - --hash=sha256:972d0dbf283508f9bc446ee09c3838cb7c7f114b5bdceee41753288c97fe2f7c \ - --hash=sha256:a28531cee2a5a42d89f9ba4da53bfeb15681f12acc0263476c8705380dadce07 \ - --hash=sha256:a3be2072315982e232bfe49c9d3db0a59ba67b2240a537ef42656cc772a887c7 \ - --hash=sha256:ac2804043bd1bc10b5da18f8f4c706877197263a510c41be9b4c0062f5783dcc \ - --hash=sha256:afab8b4b1f4469c3879bb049dd039f8fce402712050324e9524a43d7324c5e87 \ - --hash=sha256:b370d1620a34a4538ef66524fcee9de8171fa263c701036a92bc0b4c1f2f9c6d \ - --hash=sha256:b8b0808dba0c63b7633bdaefb34e08fe0612622224f9feb0e7518904b1615101 \ - --hash=sha256:bc7ca6a1a40e7e4c933017e6c09ef18032add793df4e42624c6c0c87e0bebdad \ - --hash=sha256:caa65e1f5bf007430bf657c37cab7ab81a4ddf8d337e3062bcc5085d17ef038b \ - --hash=sha256:d68c5a01a283cb13b79eafe016fe5869aa11bff8c46e7141c70aa0aac808010f \ - --hash=sha256:da137802688190835b4c863cafa77fd7e29dff662ee6d905a9ffc14f00299c91 \ - --hash=sha256:e56a20ab6cdb90a95b0c99652e28de3504ce77129087319c03c9098266183ae5 \ - --hash=sha256:e878ccb7d20872065e1597935fdb5e65efa43220c8edd0d9c4a1a7ff1f3eb277 \ - --hash=sha256:eba81e0b3011c1f23df7ea47ef4ffaa8239817959ae291515b6efd068bde2161 \ - --hash=sha256:ed6d23a3f806898e69c77430ebd8da0c79c219f97b9acbc9a29a653e09740c59 +duckdb==1.5.2 \ + --hash=sha256:0b291786014df1133f8f18b9df4d004484613146e858d71a21791e0fcca16cf4 \ + --hash=sha256:2323c1195c10fb2bb982fc0218c730b43d1b92a355d61e68e3c5f3ac9d44c34f \ + --hash=sha256:2a1de4f4d454b8c97aec546c82003fc834d3422ce4bc6a19902f3462ef293bed \ + --hash=sha256:35579b8e3a064b5eaf15b0eafc558056a13f79a0a62e34cc4baf57119daecfec \ + --hash=sha256:376856066c65ccd55fcb3a380bbe33a71ce089fc4623d229ffc6e82251afdb6d \ + --hash=sha256:411ad438bd4140f189a10e7f515781335962c5d18bd07837dc6d202e3985253d \ + --hash=sha256:4420b3f47027a7849d0e1815532007f377fa95ee5810b47ea717d35525c12f79 \ + --hash=sha256:486c862bf7f163c0110b6d85b3e5c031d224a671cca468f12ebb1d3a348f6b39 \ + --hash=sha256:52a21823f3fbb52f0f0e5425e20b07391ad882464b955879499b5ff0b45a376b \ + --hash=sha256:5596bbfc31b1b259db69c8d847b42d036ce2c4804f9ccb28f9fc46a16de7bc53 \ + --hash=sha256:56d38b3c4e0ef2abb58898d0fd423933999ed535c45e75e9d9f72e1d5fed69b8 \ + --hash=sha256:638da0d5102b6cb6f7d47f83d0600708ac1d3cb46c5e9aaabc845f9ba4d69246 \ + --hash=sha256:63bf8687feefeed51adf45fa3b062ab8b1b1c350492b7518491b86bae68b1da1 \ + --hash=sha256:6b0fe75c148000f060aa1a27b293cacc0ea08cc1cad724fbf2143d56070a3785 \ + --hash=sha256:70631c847ca918ee710ec874241b00cf9d2e5be90762cbb2a0389f17823c08f7 \ + --hash=sha256:7f69164b048e498b9e9140a24343108a5ae5f17bfb3485185f55fdf9b1aa924d \ + --hash=sha256:81fc4fbf0b5e25840b39ba2a10b78c6953c0314d5d0434191e7898f34ab1bba3 \ + --hash=sha256:84b193aca20565dedb3172de15f843c659c3a6c773bf14843a9bd781c850e7db \ + --hash=sha256:8d599758b4e48bf12e18c9b960cf491d219f0c4972d19a45489c05cc5ab36f83 \ + --hash=sha256:8dbd7e31e5dc157bfe8803fa7d2652336265c6c19926c5a4a9b40f8222868d08 \ + --hash=sha256:98c0535cd6d901f61a5ea3c2e26a1fd28482953d794deb183daf568e3aa5dda6 \ + --hash=sha256:a9cd5e71702d446613750405cde03f66ed268f4c321da071b0472759dad19536 \ + --hash=sha256:bb42e6ed543902e14eae647850da24103a89f0bc2587dec5601b1c1f213bd2ed \ + --hash=sha256:be37680ddb380015cb37318e378c53511c45c4f0d8fac5599d22b7d092b9217a \ + --hash=sha256:c69907354ffee94ba8cf782daf0480dab7557f21ce27fffa6c0ea8f74ed4b8e2 \ + --hash=sha256:c99ef73a277c8921bc0a1f16dee38d924484251d9cfd20951748c20fcd5ed855 \ + --hash=sha256:c9f3e0b71b8a50fccfb42794899285d9d318ce2503782b9dd54868e5ecd0ad31 \ + --hash=sha256:ce0b8141a10d37ecef729c45bc41d334854013f4389f1488bd6035c5579aaac1 \ + --hash=sha256:ce17670bb392ea1b3650537db02bd720908776b5b95f6d2472d31a7de59d1dc1 \ + --hash=sha256:d72b8856b1839d35648f38301b058f6232f4d36b463fe4dc8f4d3fdff2df1a2e \ + --hash=sha256:d9b4f5430bf4f05d4c0dc4c55c75def3a5af4be0343be20fa2bfc577343fbfc9 \ + --hash=sha256:e6495b00cad16888384119842797c49316a96ae1cb132bb03856d980d95afee1 \ + --hash=sha256:ea58ff5b0880593a280cf5511734b17711b32ee1f58b47d726e8600848358160 \ + --hash=sha256:ef461bca07313412dc09961c4a4757a851f56b95ac01c58fac6007632b7b94f2 \ + --hash=sha256:fc85a5dbcbe6eccac1113c72370d1d3aacfdd49198d63950bdf7d8638a307f00 # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ --hash=sha256:3b41e1b601234296b4fb368338fdcd3e13e0b4fb5b67345948f4f2bf9868b286 # via kubernetes -fastapi==0.135.3 \ - --hash=sha256:9b0f590c813acd13d0ab43dd8494138eb58e484bfac405db1f3187cfc5810d98 \ - --hash=sha256:bd6d7caf1a2bdd8d676843cdcd2287729572a1ef524fc4d65c17ae002a1be654 +fastapi==0.136.1 \ + --hash=sha256:7af665ad7acfa0a3baf8983d393b6b471b9da10ede59c60045f49fbc89a0fa7f \ + --hash=sha256:a6e9d7eeada96c93a4d69cb03836b44fa34e2854accb7244a1ece36cd4781c3f # via # feast (pyproject.toml) # fastapi-mcp @@ -560,9 +560,9 @@ fastapi-mcp==0.4.0 \ --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d # via feast (pyproject.toml) -filelock==3.25.2 \ - --hash=sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694 \ - --hash=sha256:ca8afb0da15f229774c9ad1b455ed96e85a81373065fb10446672f64444ddf70 +filelock==3.29.0 \ + --hash=sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90 \ + --hash=sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258 # via snowflake-connector-python frozenlist==1.8.0 \ --hash=sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686 \ @@ -704,9 +704,9 @@ fsspec==2024.9.0 \ # via # feast (pyproject.toml) # dask -google-api-core[grpc]==2.30.2 \ - --hash=sha256:9a8113e1a88bdc09a7ff629707f2214d98d61c7f6ceb0ea38c42a095d02dc0f9 \ - --hash=sha256:a4c226766d6af2580577db1f1a51bf53cd262f722b49731ce7414c43068a9594 +google-api-core[grpc]==2.30.3 \ + --hash=sha256:a85761ba72c444dad5d611c2220633480b2b6be2521eca69cca2dbb3ffd6bfe8 \ + --hash=sha256:e601a37f148585319b26db36e219df68c5d07b6382cff2d580e83404e44d641b # via # feast (pyproject.toml) # google-cloud-bigquery @@ -716,9 +716,9 @@ google-api-core[grpc]==2.30.2 \ # google-cloud-datastore # google-cloud-storage # pandas-gbq -google-auth==2.49.1 \ - --hash=sha256:16d40da1c3c5a0533f57d268fe72e0ebb0ae1cc3b567024122651c045d879b64 \ - --hash=sha256:195ebe3dca18eddd1b3db5edc5189b76c13e96f29e73043b923ebcf3f1a860f7 +google-auth==2.50.0 \ + --hash=sha256:04382175e28b94f49694977f0a792688b59a668def1499e9d8de996dc9ce5b15 \ + --hash=sha256:f35eafb191195328e8ce10a7883970877e7aeb49c2bfaa54aa0e394316d353d0 # via # google-api-core # google-auth-oauthlib @@ -913,101 +913,112 @@ 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.3.1 \ + --hash=sha256:002fc0201b9af1cc8960e27cdc501ad1f8cdd6dbadb2091c6ddbd4e5ace6cb77 \ + --hash=sha256:011a9071c3df4885cac7f58a2623feac6c8e2ad30e6ba93c55195af05ce61ff5 \ + --hash=sha256:01cf82a514bc4fd145b99333c28523e61b7a9ad051a245804323ebf4e7b1c6a6 \ + --hash=sha256:027ce4fabfeff5af5b9869d5524770877f9061d118bc36b85703ae3faf5aad8e \ + --hash=sha256:03baa381964b8df356d19ec4e3a6ae656044249a87b0def257fe1e08dbaf6094 \ + --hash=sha256:042e57de8a2cae91e3e7c0af32960ea2c5107b2f27f68a740295861e68780a8a \ + --hash=sha256:09d41a3a965f7c261223d516ebda607aee4d8440dd7637f01af9a4c05872f0c4 \ + --hash=sha256:09f5e510f637f2c72d2a79fb3ad05f7b6211e057e367ca5c4f97bb3d8c9d71f4 \ + --hash=sha256:0b5ff2f643f4b452b0597b7fe6aa35d398cb31d8806801acfafb1558610ea2aa \ + --hash=sha256:0caf3fc8af0767794b335753781c3fa35f2a3e975c098edbc8f733d35d6a95e4 \ + --hash=sha256:0fac4af8515e6cca74fc701169ae4dc9a71a90e9319c9d21006ec9454b43aa2f \ + --hash=sha256:113e098e4a6b3cc5500e05e7cb1548ba9e83de5fe755941b11f6020a76e6c03a \ + --hash=sha256:137c14905ea6f2933967200bc7b2a0c8ec9387888b273fd0004f25b994fd0343 \ + --hash=sha256:156be6a0c736ee145cfe0fb155d0e96cec8d4872cf8b4f76ad6a2ee6ab391d0a \ + --hash=sha256:17ec8b524055a88b80d76c177dbbbe475a25c17c5bf4b67bdbdbd0629bcae838 \ + --hash=sha256:1ac7697365dbe45109273b34227fee6826b276ead9a4a007e0877e1d3f0fcf21 \ + --hash=sha256:1b46e96b50dad03495447860510daebd2c96fd44ed25ba8ccb03e9f89eaa9d34 \ + --hash=sha256:1ebc307a87b099d0877dbd2bdc0bae427258e7ec67f60a951e89027f8dc2568f \ + --hash=sha256:1f7bceb03a1b934872ffe3942eaeed7c7e09096e67b53f095b81f39c7a819113 \ + --hash=sha256:2611bfaaadc5e8d43fb7967f9bbf1110c8beaa83aee2f2d812c76f11cfb56c6a \ + --hash=sha256:264ee7e9cb6c30dc78da4ecf71d74cf14ca122817c665d838eda8b4384bce1b0 \ + --hash=sha256:26f899cde0279e4b7d370716ff80320601c2bd93cdf3e774a42bdd44f65b41f8 \ + --hash=sha256:29fe35e3c6fe03204e75c86514f452591957a1e06b05d86e10d795455b71c355 \ + --hash=sha256:2afc675b831f7552da41116fffffca4340f387dc03f56d6ec0c7895ab0b59a10 \ + --hash=sha256:2b6da6e07359107c653a809b3cff2d9ccaeedbafe33c6f16434aef6f53ce4a2b \ + --hash=sha256:2b96da7e365d6488d2a75266a662cbe3cc14b28c23dd9b0c9aa04b5bc5c20192 \ + --hash=sha256:2f1c1b2e8f00b71e6214234d313f655a3a27cd4384b054126ce04073c1d47045 \ + --hash=sha256:304481241e081bc26f0778b2c2b99f9c43917e4e724a016dcc9439b7ab12c726 \ + --hash=sha256:318f772dd321404075d406825266e574ee0f4751be1831424c2ebd5722609398 \ + --hash=sha256:3586c8a5f56d34b9dddaaa9e76905f31933cac267251006adf86ec0eef7d0400 \ + --hash=sha256:3724f0e58c6ff76fd683429945491de71324ab1bc0ad943a8d68cb0932d24075 \ + --hash=sha256:3fb6573efa15a29c12c0c0f7170b14e7c1347fe4bb39b6a15b779f46015cc929 \ + --hash=sha256:40ae8a7041fcb328a6bc7202d8c4e6e0d38d434b2e3880b1ee8ed754f17cd836 \ + --hash=sha256:4106201cd052d9eabe3cb7b5a24b0fe37307792bda4fcb3cf6ddd72f697828e8 \ + --hash=sha256:439f9a5cc8f9519ce208a24cdebfa0440fef26aa682a40ba2c92acb10a53f5e0 \ + --hash=sha256:4479e36d263251dba8ab8ea81adf07e7f1163603c7102c5de1e130b83b4fad3b \ + --hash=sha256:487658e1db83c1ee9fbbac6a43039ea76957767a5987ffb16b590613f9e68297 \ + --hash=sha256:48ff424f8aa36aacd9fdaa68efeb27d2e8771f293af4305bdb15d92194ca6631 \ + --hash=sha256:4f7e242eab698ad0be5a4b2ec616fa856569c57455cc67c625fd567726290e5f \ + --hash=sha256:526db52e5234a9463520e960a509d6c1bd5128d1ab1b569cbf459fe39189e8ab \ + --hash=sha256:52d5641027d6731bc7b5e7d126a5158a99784a9f8c6de3d97ca89aca4969e9f8 \ + --hash=sha256:53148a4e21057541b6d8e493b2ea1b500037ddf34433c391970036f3cbce00e3 \ + --hash=sha256:583de2f16528e66081cbdfe510d8488c2de73039dc00aada7d22bd49d73a4a94 \ + --hash=sha256:5e55d90b431b0c6b64ae5a624208d4aea318566d31872e595ee723c0f5b9a79f \ + --hash=sha256:5f316cf2d0558f5027aab19dde7d7e4901c26c21fa95367bc37784e8f547bbf2 \ + --hash=sha256:60543f3b068b16a86e99ed96b7fdae71cdc1d8abdfe9b3f82032a555e52ece7e \ + --hash=sha256:62cc62284541bb2a86c898c7d5e8388661cade91c184cb862095ed547e80588f \ + --hash=sha256:65c05b79cb8366c123357b354a16f9fc3f7187159422f143638d1c26b7240ed4 \ + --hash=sha256:65f6ac06a9f0c32c254660ec6a9329d81d589e8f5d0a9837a941d5424a6be1ef \ + --hash=sha256:6d1434d0bcc1b3ef048bae53f26456405c08aeed9827e65b24094f5f3a6793f1 \ + --hash=sha256:6e2e1024f0a021777740cb7c633a0efb2c4a4bc570f508223a8dcbcf79f99ef9 \ + --hash=sha256:6ffa7ba2e2da1f806f3181b9730b3e87ba9dbfec884806725d4584055ba3faa6 \ + --hash=sha256:743b85bd6902856cac457ddd8cd7dd48c89c47d641b6016ff5e4d015bfbd4799 \ + --hash=sha256:77c5d2bebbc9d06691abb512a31d0f54e1562af0b872891463a67a949b5278ef \ + --hash=sha256:79cd03e7ff550c17758a7520bf437c156d3d4c8bb74214deeafa69cda49c85a4 \ + --hash=sha256:80aba5f85d6227faee628ae28d1c3b69c661806a0636548ac56c68782606454f \ + --hash=sha256:81a1669b6631976b1dc9d3d58ed1ab3333e9f52feb91a2a1fb8241101ac3b665 \ + --hash=sha256:8597c35c9e82f65fd5897c4a2188c65d7daf10607b102960137b23d261cd957b \ + --hash=sha256:8650158217b469d8b6087f490929211b0493a9121154c4efaafd1dec9e19319e \ + --hash=sha256:8887bf0f31e4b550bd988c8863b527b6587d200653e9375cd91eea2b944b7424 \ + --hash=sha256:8a52b24cd710690c4a7e191c7e300136ad2ecb3c68ffe7e95b598e76de166e5e \ + --hash=sha256:8e3754ce60e1b11b0afad9a053481ff184d2ee24bea47099107156d1b84a84aa \ + --hash=sha256:907f7b5501a534030738f0f27459a612d2266fd0507b007bb8f3e6de08167920 \ + --hash=sha256:90d6b9f2652303aefd2c5a26a5e14cb74a3a63d10faa642c08d790e99442a088 \ + --hash=sha256:98fd5b39410e9d69e10e90d0330e35650becaa5dd2548f509b9598f1f3c6124d \ + --hash=sha256:9bfdeff778d3f7ff449ca5922ab773899e7d31e26a576028b06a5e9cf0ed8c34 \ + --hash=sha256:9ebae74ce2b977c2fcb22d6a10aa0acb730022406977b2bcb6ddd6788f5c414a \ + --hash=sha256:a110d19881ca78a88583d3b07231e7c6864864f5f1f3491b638863ea45fa8708 \ + --hash=sha256:a1d190790ee39b8b7adeeb10fc4090dc4859eb4e75ed27bd8108710eef18f358 \ + --hash=sha256:a2f049c3f3c83e886cd1f53958e2a1ebb369be626bef9e50d8b24d79864f1df6 \ + --hash=sha256:a3af4e9f277d6b8acd369dc44a723a055752fca9d045094383af39f90a3e3729 \ + --hash=sha256:a42c7becd4c9ec4ab5769c754eb61112777bdc6e1c1525e2077389e193b5f5aa \ + --hash=sha256:a58a58cef0d911b1717154179a9ff47852249c536ea5966bde4370b6b20638ff \ + --hash=sha256:ab1f646ff531d70bfd25f01e60708dfa3d105eb458b7dedd9fe9a443039fd809 \ + --hash=sha256:ad940dc2db545dc978cb41cb9a683e2ff328f3ef581230b9ca40ff6c3d01d542 \ + --hash=sha256:afe3c3863f16704fb5d7c2c6ff56aaf9e054f6d269f7b4c9074c5476178d1aba \ + --hash=sha256:b1e3b9f4bf9a4120510ba77a77b2fb674893cd6795653545152bb11a79eecfcb \ + --hash=sha256:b2390ad81c03d93ef1d5afd18ffcf5935de827f1a2b96b2c829437968bdabccb \ + --hash=sha256:b37df4b10cb15dedfc203f69312d8eedd617b941c21df58c13af59496c53ad0f \ + --hash=sha256:b3df9447f9209f9aa0434ca74050e9509670c1ad99398fe5807abb90e5f3a014 \ + --hash=sha256:b4fe7f38aa8956fcc1cea270e62601e0e11066aff78e384be70fd283d30293b6 \ + --hash=sha256:c1d68c6980d4690a4550bd3db6c03146f7be68ef5d08d38bb1fb68b3e9c32fe3 \ + --hash=sha256:c24c1460486b6b36083252c2db21a814becf8495ccd0e76b7286623e37239b63 \ + --hash=sha256:c25132902d3eff38781e0d54f27a0942ec849e3c07dbdce83c4d92b7e43c8dce \ + --hash=sha256:c74bd9926954e7e575f9cd9890f63defd90cd8f812dfbf8e1efb72acc9355456 \ + --hash=sha256:c8139e9011117822391c5bcfd674c5948fb1e4b8cb9adf6f13d9890859ee3a1a \ + --hash=sha256:ce334915f5d31048f76a42c607bf26687cf045eb1bc852b7340f09729c6a64fc \ + --hash=sha256:d14229beaa76e66c3a25f9477d973336441ca820df853679a98796256813316f \ + --hash=sha256:d42f3a13290f89191568fc113d95a3d2c8759cdd8c3672f021d8b7436f909e75 \ + --hash=sha256:d8e56e0d1fe607bfff422633f313aec9191c3859ab99d11ff097e3e6e068000c \ + --hash=sha256:da6f0302360e99d32bc2869772692797ebadd536e1b826d0103c72ba49d38698 \ + --hash=sha256:db46baf157feefd88724e6a7f145fe996a5990a8604ed9292b45d563360e513b \ + --hash=sha256:dcea8c3f53674ae68e44b12e853b844a1d315250ca6677b11ec0c06aff85e86c \ + --hash=sha256:de94b409f49eb6a588ebdd5872e826caec417cd77c17af0fb94f2128427f1a2a \ + --hash=sha256:e0356561b4a97c83b9ee3de657a41b8d1a1781226853adaf47b550bb988fda6f \ + --hash=sha256:e0db44cf81e4d7b94f3776b9f89111f74ed6bbdbfd42a22bc4a5ce0644d3e060 \ + --hash=sha256:e31e92b61d56244047ad600812e16f7587a6172f74810fd919ff993af12b9149 \ + --hash=sha256:e89dabf436ee79b358fd970dcbed6333a36d91db73f27069ca24a02fb138a404 \ + --hash=sha256:eddeb9a153795cf6e615f9f3cef66a1d573ff3b6ee16df2b10d1d1c2f2baeaa8 \ + --hash=sha256:ee11fd431f83d8a5b29d370b9d79a814d3218d30113bdcd44657e9bdf715fc92 \ + --hash=sha256:ee37fe8cf081b72dea72f96a0ee604f492ec02252eb77dc26ff6eec3f997b580 \ + --hash=sha256:f19ee7dc1ef8a6497570d91fa4057ba910ad98297a50b8c44ff37589f7c89d17 \ + --hash=sha256:f2f94355affd51088f57f8674b0e294704c3c7c3d7d3b1545310f5b135d4843b \ + --hash=sha256:f525734382a47f9828c9d6a1501522c78d5935466d8e2be1a41ba40ca5bb922b \ + --hash=sha256:f915a34fb742e23d0d61573349aa45d6f74037fde9d58a9f340435eff8d62736 # via feast (pyproject.toml) httpcore==1.0.9 \ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ @@ -1072,9 +1083,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.13 \ + --hash=sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242 \ + --hash=sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 # via # anyio # httpx @@ -1110,97 +1121,97 @@ kubernetes==35.0.0 \ --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee # 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.9.0 \ + --hash=sha256:07cf11f769831186eeac424376e6189f20ace4f7263e2134bdb9757340d84d4d \ + --hash=sha256:0a09c2f5869649101738653a9b7ab70cf045a1105ac66cbb8f4055e61df78f2d \ + --hash=sha256:0a1be03168b2691ba61927e299b352a6315189199ca18a57b733f86cb3cc8d38 \ + --hash=sha256:0b73e4266307e51c95e09c0750b7ec383c561d2e97d58e473f6f6a209952fbb8 \ + --hash=sha256:15cb151e52a044f06e54ac7f7b47adbfc89b5c8e2b63e1175a9d587c43e8942a \ + --hash=sha256:194fc1a32e1e21fe809d38b5faea66cc65eaa00217c8901fbdb99866938adbdb \ + --hash=sha256:1bf465d1e5b0a27713862441f6467b5ab76385f4ecf8f1f3a44f8aa3c695b4b6 \ + --hash=sha256:1c587494461ebd42229d0f1739f3aa34237dd9980623ecf1be8d3bcba79f4499 \ + --hash=sha256:224b9727eb8bc188bc3bcf29d969dba0cd61b01d9bac80c41575520cc4baabb2 \ + --hash=sha256:22a904cbdb678f7cb348c90d543d3c52f581663d687992fee47fd566dcbf5285 \ + --hash=sha256:2b8f5d00b49818f4e2b1667db994488b045835e0ac16fe2f924f3871bd2b8ac5 \ + --hash=sha256:2c3786f0f4490a5cd87f1ed6cefae833ad6b1060d52044ce0434a2e85893afd0 \ + --hash=sha256:2d03fa4fd277a7974c1978c92c374c57f44edeee163d147b477b143446ad1bf6 \ + --hash=sha256:2f8e12706dcb8ff6b3ed57514a19e45c49ad00bcd423e87b2b2e4b5f64578443 \ + --hash=sha256:3be322a15ee5e70b93b7a59cfd074614f22cc8c9ff18bd27f474e79137ea8d3b \ + --hash=sha256:3cc2917258e131ae5f958a4d872e07555b51cb7466a43433218061c74ef33745 \ + --hash=sha256:3f05d145df35dca5056a8bc3838e940efebd893a54b3e19b2dda39ceaa299bcb \ + --hash=sha256:3fe56e80badb66fdcde06bef81bbaa5bfcf6fbd7aefb86222d9e369c38c6b228 \ + --hash=sha256:42ff8a962554c350d4a83cf47d9b7b78b0e6ff7943e87df7cdfc97c07f3c016f \ + --hash=sha256:451daa98463b7695b0a30aa56bf637831ea559e7b8101ac2ef6382e8eb15e29c \ + --hash=sha256:465814ab157986acb9dfa5ccd7df944be5eefc0d08d31ec6e8d88bc71251d845 \ + --hash=sha256:4c4d0440a3a8e31d962340c3e1cc3fc9ee7febd34c8d8f770d06adb947779ea5 \ + --hash=sha256:4e3dda8345307fd7306db0ed0cb109a63a2c85ba780eb9dc2d09b2049a931f9c \ + --hash=sha256:5093043afb226ecfa1400120d1ebd4442b4f99977783e4f4f7248879009b227f \ + --hash=sha256:5112c2fb7c2eefefaeaf5c97fec81343ef44ee86a30dcfaa8223822fba6467b4 \ + --hash=sha256:527b5b820b47a09e09829051452bb0d1dd2122261254e2a6f674d12f1d793d54 \ + --hash=sha256:54d412e47c21b85865676ed0724e37a89e9593c2eee1e7367adf85bfad56ffb1 \ + --hash=sha256:56d65b583cf43b8cf4c8fbe1e1da20fa3076cc32a1149a141507af1062718236 \ + --hash=sha256:5ca8e133d799c948db2ab1afc081c333a825b5540475164726dcbf73537e5c2f \ + --hash=sha256:603138ee838ee1583f1b960b62d5d0007845c5c423feb68e44648b1359014e27 \ + --hash=sha256:63c12efcd160e1d14da11af0c46c0217473e1e0d2ae1acbccc83f561ea4c2a7b \ + --hash=sha256:657f8ba7b9eaaa82759a104137aed2a3ef7bc46ccfd43e0d89b04005b3e0a4cc \ + --hash=sha256:66b58fed90a545328e80d575467244de3741e088c1af928f0b489ebec3ef3858 \ + --hash=sha256:6788207daa0c19955d2b668f3294a368d19f67d9b5f274553fd073c1260cbb9f \ + --hash=sha256:703f4ae36d6240bfe24f542bac784c7e4194ec49c3ba5a994d02891649e2d85b \ + --hash=sha256:7202bdcac47d3a708271c4304a474a8605a4a9a4a709e954bf2d3241140aa938 \ + --hash=sha256:756775d25ec8345b837ab52effee3ad2f3b2dfd6bbee3e3f029c517bd5d8f05a \ + --hash=sha256:78042f6facfd98ecb25e9829c7e37cce23363d9d7c83bc5f72702c5059eb082b \ + --hash=sha256:789fff71757facc0738e8d89e3b84e4f0251c1c975e85e81b152cdaca927cc2d \ + --hash=sha256:7bc30ad339f4e1a01d4917d645e522a0bc0030644d8973f6346397c93ba1503f \ + --hash=sha256:7d429bdd4ac0ab17c8e4a8af0ed2a7440b16eba474909ab357131018fe8c7e71 \ + --hash=sha256:7d5c8a5929ac325729f6119802070b561f4db793dffc45e9ac750992a4ed4d22 \ + --hash=sha256:7e6274fd33fc5b2a14d41c9119629d3ff395849d8bcbc80cf637d9e8d2034da8 \ + --hash=sha256:80b25c7b570a86c03b5da69e665809deb39265476e8e21d96a9328f9762f9990 \ + --hash=sha256:81107843ed1836874b46b310f9b1816abcb89912af627868522461c3b7333c0f \ + --hash=sha256:8494cfc61e03542f2d381e71804990b3931175a29b9278fdb4a5459948778dc2 \ + --hash=sha256:850d6d03177e52700af605fd60db7f37dcb89782049a149674d1a9649c2138fd \ + --hash=sha256:8c6bc1384d9738781cfd41d09ad7f6e8af13cfea2c75ece6bd6d2566cdea2076 \ + --hash=sha256:90904fac73c478f4b83f4ed96c99c8208b75e6f9a8a1910548f69a00f1eaa671 \ + --hash=sha256:90e6d5420fc8a300518d4d2288154ff45005e920425c22cbbfe8330f3f754bd9 \ + --hash=sha256:928bd06eca2c2bbf4349e5b817f837509b0604342e65a502de1d50a7570afd15 \ + --hash=sha256:9b3e3bc363f71bda1639a4ee593cb78f7fbfeacc73411ec0d4c92f00730010a4 \ + --hash=sha256:9edcc35d1cae9fd5320171b1a838c7da8a5c968af31e82ecc3dff30b4be0957f \ + --hash=sha256:9fcb461fbf70654a52a7cc670e606f04449e2374c199b1825f754e16dacfedd8 \ + --hash=sha256:a0951822531e7aee6e0dfb556b30d5ee36bbe234faf60c20a16c01be3530869d \ + --hash=sha256:a361c9434a64d70a7dbb771d1de302c0cc9f13c0bffe1cf7e642152814b35265 \ + --hash=sha256:a4b25c6c25cac5d0d9d6d6da855195b254e0021e513e0249f0e3b444dc6e0e61 \ + --hash=sha256:a5af136bfba820d592f86c67affcef9b3ff4d4360ac3255e341e964489b48519 \ + --hash=sha256:a81eea9b999b985e4bacc650c4312805ea7008fd5e45e1bf221310176a7bcb3a \ + --hash=sha256:a9c63e04d003bc0fb6a03b348018b9a3002f98268200e22cc80f146beac5dc40 \ + --hash=sha256:aa95738a68cedd3a6f5492feddc513e2e166b50602958139e47bbdd82da0f5a7 \ + --hash=sha256:b0a2040f801406b93657a70b72fa12311063a319fee72ce98e1524da7200171f \ + --hash=sha256:b8bd70d5d816566a580d193326912f4a76ec2d28a97dc4cd4cc831c0af8e330e \ + --hash=sha256:b8da9f8035bb417770b1e1610526d87ad4fc58a2804dc4d79c53f6d2cf5a6eb9 \ + --hash=sha256:bc5518873822d2faa8ebdd2c1a4d7c8ef47b01a058495ab7924cb65bdbf5fc9a \ + --hash=sha256:c0d620e74897f8c2613b3c4e2e9c1e422eb46d2ddd07df540784d44117836af3 \ + --hash=sha256:c2640e23d2b7c98796f123ffd95cf2022c7777aa8a4a3b98b36c570d37e85eee \ + --hash=sha256:c81aef782380f0f13ead670aae01825eb653b44b046aa0e5ebbb79f76ed4aa11 \ + --hash=sha256:d4d16b608a1c43d7e33142099a75cd93af482dadce0bf82421e91cad077157f4 \ + --hash=sha256:d69fc39e627908f4c03297d5a88d9284b73f4d90b424461e32e8c2485e21c283 \ + --hash=sha256:d9da80e5b04acce03ced8ba6479a71c2a2edf535c2acc0d09c80d2f80f3bad15 \ + --hash=sha256:dd2c7e082b0b92e1baa4da28163a808672485617bc855cc22a2fd06978fa9084 \ + --hash=sha256:de7dac64e3eb832ffc7b840eb8f52f76420cde1b845be51b2a0f6b870890645e \ + --hash=sha256:e0785c2fb4a81e1aece366aa3e2e039f4a4d7d21aaaded5227d7f3c703427882 \ + --hash=sha256:e306d956cfa027fe041585f02a1602c32bfa6bb8ebea4899d373383295a6c62f \ + --hash=sha256:e78fb7419e07d98c2af4b8567b72b3eaf8cb05caad642e9963465569c8b2d87e \ + --hash=sha256:e9002e98dcb1c0a66723592520decd86238ddcef168b37ff6cfb559200b4b774 \ + --hash=sha256:e94cbc6ad9a6aeea46d775cbb11f361022f778a9cc8cc90af653d3a594b057ce \ + --hash=sha256:eea1b54943475f51698f85fa230c65ccac769f1e603b981be060ac5763d90927 \ + --hash=sha256:f100bfe2acf8a3689af9d0cc660d89f17286c9c795f9f18f7b62dd1a6b247ae6 \ + --hash=sha256:f162af66a2ed3f7d1d161a82ca584efd15acd9c1cff190a373458c32f7d42118 \ + --hash=sha256:f24b90b0e0c8cc9491fb1693ae91fe17cb7963153a1946395acdbdd5818429a4 \ + --hash=sha256:f29b68cd9714531672db62cc54f6e8ff981900f824d13fa0e00749189e13778e \ + --hash=sha256:f38bc489037eca88d6ebefc9c4d41a4e07c8e8b4de5188a9e6d290273ad7ebb1 \ + --hash=sha256:f3fd278f5e6bf7c75ccd6d12344eb686cc020712683363b66f46ac79d37c799f \ + --hash=sha256:f4003f70c56a5addd6aa0897f200dd59afd3bf7bcd5b3cce46dd21f925743bc2 \ + --hash=sha256:f48c963a76d71b9d7927eb817b543d0dccd52ab6648b99d37bd54f4cd475d856 \ + --hash=sha256:f819e0c6413e259a17a7c0d49f97f405abadd3c2a316a3b46c6440b7dbbedbb1 \ + --hash=sha256:fc5758e2b7a56532dc33e3c544d78cbaa9ecf0a0f2a2da2df882c1d6b99a317f \ + --hash=sha256:fcbdf2a9ca24e87bbebb47f1fe34e531ef06f104f98c9ccfc953a3f3344c567a # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ @@ -1577,51 +1588,51 @@ multidict==6.7.1 \ # aiobotocore # aiohttp # yarl -mypy==1.20.0 \ - --hash=sha256:002b613ae19f4ac7d18b7e168ffe1cb9013b37c57f7411984abbd3b817b0a214 \ - --hash=sha256:00e047c74d3ec6e71a2eb88e9ea551a2edb90c21f993aefa9e0d2a898e0bb732 \ - --hash=sha256:02cca0761c75b42a20a2757ae58713276605eb29a08dd8a6e092aa347c4115ca \ - --hash=sha256:0ecd63f75fdd30327e4ad8b5704bd6d91fc6c1b2e029f8ee14705e1207212489 \ - --hash=sha256:0f42dfaab7ec1baff3b383ad7af562ab0de573c5f6edb44b2dab016082b89948 \ - --hash=sha256:1973868d2adbb4584a3835780b27436f06d1dc606af5be09f187aaa25be1070f \ - --hash=sha256:26c8b52627b6552f47ff11adb4e1509605f094e29815323e487fc0053ebe93d1 \ - --hash=sha256:2721f0ce49cb74a38f00c50da67cb7d36317b5eda38877a49614dc018e91c787 \ - --hash=sha256:2fcedb16d456106e545b2bfd7ef9d24e70b38ec252d2a629823a4d07ebcdb69e \ - --hash=sha256:31b5dbb55293c1bd27c0fc813a0d2bb5ceef9d65ac5afa2e58f829dab7921fd5 \ - --hash=sha256:34506397dbf40c15dc567635d18a21d33827e9ab29014fb83d292a8f4f8953b6 \ - --hash=sha256:367e5c993ba34d5054d11937d0485ad6dfc60ba760fa326c01090fc256adf15c \ - --hash=sha256:379edf079ce44ac8d2805bcf9b3dd7340d4f97aad3a5e0ebabbf9d125b84b442 \ - --hash=sha256:39362cdb4ba5f916e7976fccecaab1ba3a83e35f60fa68b64e9a70e221bb2436 \ - --hash=sha256:4525e7010b1b38334516181c5b81e16180b8e149e6684cee5a727c78186b4e3b \ - --hash=sha256:47781555a7aa5fedcc2d16bcd72e0dc83eb272c10dd657f9fb3f9cc08e2e6abb \ - --hash=sha256:49d11c6f573a5a08f77fad13faff2139f6d0730ebed2cfa9b3d2702671dd7188 \ - --hash=sha256:555493c44a4f5a1b58d611a43333e71a9981c6dbe26270377b6f8174126a0526 \ - --hash=sha256:555658c611099455b2da507582ea20d2043dfdfe7f5ad0add472b1c6238b433f \ - --hash=sha256:697f102c5c1d526bdd761a69f17c6070f9892eebcb94b1a5963d679288c09e78 \ - --hash=sha256:76a70bf840495729be47510856b978f1b0ec7d08f257ca38c9d932720bf6b43e \ - --hash=sha256:7d3243c406773185144527f83be0e0aefc7bf4601b0b2b956665608bf7c98a83 \ - --hash=sha256:931a7630bba591593dcf6e97224a21ff80fb357e7982628d25e3c618e7f598ef \ - --hash=sha256:9804c3ad27f78e54e58b32e7cb532d128b43dbfb9f3f9f06262b821a0f6bd3f5 \ - --hash=sha256:a17c5d0bdcca61ce24a35beb828a2d0d323d3fcf387d7512206888c900193367 \ - --hash=sha256:a6e0641147cbfa7e4e94efdb95c2dab1aff8cfc159ded13e07f308ddccc8c48e \ - --hash=sha256:a79c1eba7ac4209f2d850f0edd0a2f8bba88cbfdfefe6fb76a19e9d4fe5e71a2 \ - --hash=sha256:a9336b5e6712f4adaf5afc3203a99a40b379049104349d747eb3e5a3aa23ac2e \ - --hash=sha256:b20c8b0fd5877abdf402e79a3af987053de07e6fb208c18df6659f708b535134 \ - --hash=sha256:b3a49064504be59e59da664c5e149edc1f26c67c4f8e8456f6ba6aba55033018 \ - --hash=sha256:b503ab55a836136b619b5fc21c8803d810c5b87551af8600b72eecafb0059cb0 \ - --hash=sha256:bd0212976dc57a5bfeede7c219e7cd66568a32c05c9129686dd487c059c1b88a \ - --hash=sha256:c70380fe5d64010f79fb863b9081c7004dd65225d2277333c219d93a10dad4dd \ - --hash=sha256:d99f515f95fd03a90875fdb2cca12ff074aa04490db4d190905851bdf8a549a8 \ - --hash=sha256:e80cf77847d0d3e6e3111b7b25db32a7f8762fd4b9a3a72ce53fe16a2863b281 \ - --hash=sha256:eb96c84efcc33f0b5e0e04beacf00129dd963b67226b01c00b9dfc8affb464c3 \ - --hash=sha256:ebea00201737ad4391142808ed16e875add5c17f676e0912b387739f84991e13 \ - --hash=sha256:efe8d70949c3023698c3fca1e94527e7e790a361ab8116f90d11221421cd8726 \ - --hash=sha256:f13b3e41bce9d257eded794c0f12878af3129d80aacd8a3ee0dee51f3a978651 \ - --hash=sha256:f194db59657c58593a3c47c6dfd7bad4ef4ac12dbc94d01b3a95521f78177e33 \ - --hash=sha256:f49590891d2c2f8a9de15614e32e459a794bcba84693c2394291a2038bbaaa69 \ - --hash=sha256:f75ff57defcd0f1d6e006d721ccdec6c88d4f6a7816eb92f1c4890d979d9ee62 \ - --hash=sha256:f799d9db89fc00446f03281f84a221e50018fc40113a3ba9864b132895619ebe \ - --hash=sha256:f8426d4d75d68714abc17a4292d922f6ba2cfb984b72c2278c437f6dae797865 +mypy==1.20.2 \ + --hash=sha256:0c64e5973df366b747646fc98da921f9d6eba9716d57d1db94a83c026a08e0fb \ + --hash=sha256:0deb80d062b2479f2c87ae568f89845afc71d11bc41b04179e58165fd9f31e98 \ + --hash=sha256:1e1c12f6d2db3d78b909b5f77513c11eb7f2dd2782b96a3ab6dffc7d44575c99 \ + --hash=sha256:20175a1c0f49863946ec20b7f63255768058ac4f07d2b9ded6a6b46cfb5a9100 \ + --hash=sha256:29752dbbf8cc53f89f6ac096d363314333045c257c9c75cbd189ca2de0455744 \ + --hash=sha256:2a4102b03bb7481d9a91a6da8d174740c9c8c4401024684b9ca3b7cc5e49852f \ + --hash=sha256:2de3dcea53babc1c3237a19002bc3d228ce1833278f093b8d619e06e7cc79609 \ + --hash=sha256:34397cdced6b90b836e38182076049fdb41424322e0b0728c946b0939ebdf9f6 \ + --hash=sha256:4077797a273e56e8843d001e9dfe4ba10e33323d6ade647ff260e5cd97d9758c \ + --hash=sha256:419413398fe250aae057fd2fe50166b61077083c9b82754c341cf4fd73038f30 \ + --hash=sha256:4b6481b228d072315b053210b01ac320e1be243dc17f9e5887ef167f23f5fae4 \ + --hash=sha256:4dbfcf869f6b0517f70cf0030ba6ea1d6645e132337a7d5204a18d8d5636c02b \ + --hash=sha256:4fef51b01e638974a6e69885687e9bd40c8d1e09a6cd291cca0619625cf1f558 \ + --hash=sha256:52b176444e2e5054dfcbcb8c75b0b719865c96247b37407184bbfca5c353f2c2 \ + --hash=sha256:56908d7e08318d39f85b1f0c6cfd47b0cac1a130da677630dac0de3e0623e102 \ + --hash=sha256:5a65aa591af023864fd08a97da9974e919452cfe19cb146c8a5dc692626445dc \ + --hash=sha256:688c3312e5dadb573a2c69c82af3a298d43ecf9e6d264e0f95df960b5f6ac19c \ + --hash=sha256:6e2b469efd811707bc530fd1effef0f5d6eebcb7fe376affae69025da4b979a2 \ + --hash=sha256:7488448de6007cd5177c6cea0517ac33b4c0f5ee9b5e9f2be51ce75511a85517 \ + --hash=sha256:785b08db19c9f214dc37d65f7c165d19a30fcecb48abfa30f31b01b5acaabb58 \ + --hash=sha256:7b0e817b518bff7facd7f85ea05b643ad8bdcce684cf29784987b0a7c8e1f997 \ + --hash=sha256:803203d2b6ea644982c644895c2f78b28d0e208bba7b27d9b921e0ec5eb207c6 \ + --hash=sha256:89dce27e142d25ffbc154c1819383b69f2e9234dc4ed4766f42e0e8cb264ab5c \ + --hash=sha256:913485a03f1bcf5d279409a9d2b9ed565c151f61c09f29991e5faa14033da4c8 \ + --hash=sha256:97d7b9a485b40f8ca425460e89bf1da2814625b2da627c0dcc6aa46c92631d14 \ + --hash=sha256:9bcb8aa397ff0093c824182fd76a935a9ba7ad097fcbef80ae89bf6c1731d8ec \ + --hash=sha256:9d56a78b646f2e3daa865bc70cd5ec5a46c50045801ca8ff17a0c43abc97e3ee \ + --hash=sha256:a5da6976f20cae27059ea8d0c86e7cef3de720e04c4bb9ee18e3690fdb792066 \ + --hash=sha256:a94c5a76ab46c5e6257c7972b6c8cff0574201ca7dc05647e33e795d78680563 \ + --hash=sha256:a95a9248b0c6fd933a442c03c3b113c3b61320086b88e2c444676d3fd1ca3330 \ + --hash=sha256:baf593f2765fa3a6b1ef95807dbaa3d25b594f6a52adcc506a6b9cb115e1be67 \ + --hash=sha256:bb9c2fa06887e21d6a3a868762acb82aec34e2c6fd0174064f27c93ede68ad15 \ + --hash=sha256:bba9ad231e92a3e424b3e56b65aa17704993425bba97e302c832f9466bb85bac \ + --hash=sha256:c3bae4f855d965b5453784300c12ffc63a548304ac7f99e55d4dc7c898673aa3 \ + --hash=sha256:c566c3a88b6ece59b3d70f65bedef17304f48eb52ff040a6a18214e1917b3254 \ + --hash=sha256:cdecf62abcc4292500d7858aeae87a1f8f1150f4c4dd08fb0b336ee79b2a6df3 \ + --hash=sha256:cf5a4db6dca263010e2c7bff081c89383c72d187ba2cf4c44759aac970e2f0c4 \ + --hash=sha256:d52ad8d78522da1d308789df651ee5379088e77c76cb1994858d40a426b343b9 \ + --hash=sha256:e061b58443f1736f8a37c48978d7ab581636d6ab03e3d4f99e3fa90463bb9382 \ + --hash=sha256:e2877a02380adfcdbc69071a0f74d6e9dbbf593c0dc9d174e1f223ffd5281943 \ + --hash=sha256:e73c07f23009962885c197ccb9b41356a30cc0e5a1d0c2ea8fd8fb1362d7f924 \ + --hash=sha256:e8222c26daaafd9e8626dec58ae36029f82585890589576f769a650dd20fd665 \ + --hash=sha256:edfbfca868cdd6bd8d974a60f8a3682f5565d3f5c99b327640cedd24c4264026 \ + --hash=sha256:f376e37f9bf2a946872fc5fd1199c99310748e3c26c7a26683f13f8bdb756cbd # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ @@ -1711,9 +1722,9 @@ oauthlib==3.3.1 \ --hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \ --hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1 # via requests-oauthlib -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # db-dtypes @@ -1787,9 +1798,9 @@ pandas==2.3.3 \ # pandas-gbq # pymilvus # snowflake-connector-python -pandas-gbq==0.34.1 \ - --hash=sha256:6bea5b85937251b976cf9db38151ea59abbff98771179183488d4614694bff67 \ - --hash=sha256:b74932c6ee35dfc81582f39c792e3a68c9ef9bee8c85f25667d9d05dfadd0daf +pandas-gbq==0.35.0 \ + --hash=sha256:258de481019566611031919997bf9c1ece4ca30a4dd02d3fc3664b251d446182 \ + --hash=sha256:596c908487ef0649a161e86ef272c00c267e581b95dc5ee0dc3518545b33bcfc # via google-cloud-bigquery parsy==2.2 \ --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ @@ -1799,17 +1810,17 @@ 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.9.6 \ + --hash=sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a \ + --hash=sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917 # via snowflake-connector-python -prometheus-client==0.24.1 \ - --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ - --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 +prometheus-client==0.25.0 \ + --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ + --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 # via feast (pyproject.toml) propcache==0.4.1 \ --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ @@ -2005,57 +2016,57 @@ psycopg-pool==3.3.0 \ --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 # 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 @@ -2080,141 +2091,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.3 \ + --hash=sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927 \ + --hash=sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d # 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.3 \ + --hash=sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba \ + --hash=sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35 \ + --hash=sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4 \ + --hash=sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505 \ + --hash=sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7 \ + --hash=sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8 \ + --hash=sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4 \ + --hash=sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37 \ + --hash=sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25 \ + --hash=sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022 \ + --hash=sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1 \ + --hash=sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7 \ + --hash=sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c \ + --hash=sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3 \ + --hash=sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb \ + --hash=sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3 \ + --hash=sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976 \ + --hash=sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c \ + --hash=sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab \ + --hash=sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa \ + --hash=sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6 \ + --hash=sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396 \ + --hash=sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c \ + --hash=sha256:3d08782c4045f90724b44c95d35ebec0d67edb8a957a2ac81d5a8e4b8a200495 \ + --hash=sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c \ + --hash=sha256:4335e87c7afa436a0dfa899e138d57a72f8aad542e2cf19c36fb428461caabd0 \ + --hash=sha256:4b068543bdb707f5d935dab765d99227aa2545ef2820935f2e5dd801795c7dbd \ + --hash=sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf \ + --hash=sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531 \ + --hash=sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5 \ + --hash=sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda \ + --hash=sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d \ + --hash=sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e \ + --hash=sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df \ + --hash=sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6 \ + --hash=sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c \ + --hash=sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13 \ + --hash=sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536 \ + --hash=sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287 \ + --hash=sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0 \ + --hash=sha256:68ef2f623dda6d5a9067ac014e406c020c780b2a358930a7e5c1b73702900720 \ + --hash=sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050 \ + --hash=sha256:6dff8cc884679df229ebc6d8eb2321ea6f8e091bc7d4886d4dc2e0e71452843c \ + --hash=sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1 \ + --hash=sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8 \ + --hash=sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0 \ + --hash=sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374 \ + --hash=sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807 \ + --hash=sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6 \ + --hash=sha256:831eb19aa789a97356979e94c981e5667759301fb708d1c0d5adf1bc0098b873 \ + --hash=sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57 \ + --hash=sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f \ + --hash=sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c \ + --hash=sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad \ + --hash=sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e \ + --hash=sha256:91249bcb7c165c2fb2a2f852dbc5c91636e2e218e75d96dfdd517e4078e173dd \ + --hash=sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23 \ + --hash=sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46 \ + --hash=sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1 \ + --hash=sha256:99421e7684a60f7f3550a1d159ade5fdff1954baedb6bdd407cba6a307c9f27d \ + --hash=sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1 \ + --hash=sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee \ + --hash=sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c \ + --hash=sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874 \ + --hash=sha256:9f247596366f4221af52beddd65af1218797771d6989bc891a0b86ccaa019168 \ + --hash=sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a \ + --hash=sha256:a35cc284c8dd7edae8a31533713b4d2467dfe7c4f1b5587dd4031f28f90d1d13 \ + --hash=sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f \ + --hash=sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a \ + --hash=sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789 \ + --hash=sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe \ + --hash=sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f \ + --hash=sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5 \ + --hash=sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943 \ + --hash=sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b \ + --hash=sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089 \ + --hash=sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b \ + --hash=sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff \ + --hash=sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67 \ + --hash=sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803 \ + --hash=sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045 \ + --hash=sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8 \ + --hash=sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346 \ + --hash=sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2 \ + --hash=sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f \ + --hash=sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687 \ + --hash=sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76 \ + --hash=sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1 \ + --hash=sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f \ + --hash=sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2 \ + --hash=sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c \ + --hash=sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018 \ + --hash=sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba \ + --hash=sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c \ + --hash=sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf \ + --hash=sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7 \ + --hash=sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47 \ + --hash=sha256:d56bdb4af1767cc15b0386b3c581fdfe659bb9ee4a4f776e92c1cd9d074000d6 \ + --hash=sha256:dcda6583921c05a40533f982321532f2d8db29326c7b95c4026941fa5074bd79 \ + --hash=sha256:dd81f6907932ebac3abbe41378dac64b2380db1287e2aa64d8d88f78d170f51a \ + --hash=sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e \ + --hash=sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a \ + --hash=sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34 \ + --hash=sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b \ + --hash=sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85 \ + --hash=sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca \ + --hash=sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f \ + --hash=sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3 \ + --hash=sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64 \ + --hash=sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22 \ + --hash=sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72 \ + --hash=sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec \ + --hash=sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d \ + --hash=sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3 \ + --hash=sha256:fa3eb7c2995aa443687a825bc30395c8521b7c6ec201966e55debfd1128bcceb \ + --hash=sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395 \ + --hash=sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb \ + --hash=sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4 \ + --hash=sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127 \ + --hash=sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56 # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.0 \ + --hash=sha256:24285fd4b0e0c06507dd9fdfd331ee23794305352aaec8fc4eb92d4047aeb67d \ + --hash=sha256:fc8d5d692eb7092e43c8647c1c35a3ecd00e040fcf02ed86f4cb5458ca62182e # via # fastapi-mcp # mcp @@ -2239,13 +2249,13 @@ pymilvus==2.5.18 \ --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d # via feast (pyproject.toml) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 +pymysql==1.1.3 \ + --hash=sha256:8164ba62c552f6105f3b11753352d0f16b90d1703ba67d81923d5a8a5d1c5289 \ + --hash=sha256:e70ebf2047a4edf6138cf79c68ad418ef620af65900aa585c5e8bfc95044d43a # via feast (pyproject.toml) -pyopenssl==26.0.0 \ - --hash=sha256:df94d28498848b98cc1c0ffb8ef1e71e40210d3b0a8064c9d29571ed2904bf81 \ - --hash=sha256:f293934e52936f2e3413b89c6ce36df66a0b34ae1ea3a053b8c5020ff2f513fc +pyopenssl==26.1.0 \ + --hash=sha256:115563879b2c8ccb207975705d3e491434d8c9d7c79667c902ecbf5f3bbd2ece \ + --hash=sha256:737f0a2275c5bc54f3b02137687e1a765931fb3949b9a92a825e4d33b9eec08b # via snowflake-connector-python python-dateutil==2.9.0.post0 \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ @@ -2264,9 +2274,9 @@ python-dotenv==1.2.2 \ # pydantic-settings # pymilvus # uvicorn -python-multipart==0.0.22 \ - --hash=sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155 \ - --hash=sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58 +python-multipart==0.0.27 \ + --hash=sha256:6fccfad17a27334bd0193681b369f476eda3409f17381a2d65aa7df3f7275645 \ + --hash=sha256:9870a6a8c5a20a5bf4f07c017bd1489006ff8836cff097b6933355ee2b49b602 # via mcp pytz==2026.1.post1 \ --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ @@ -2353,9 +2363,9 @@ pyyaml==6.0.3 \ # dask # kubernetes # uvicorn -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.0 \ + --hash=sha256:64a6ea7bf567ad43c964d2c30d82853f8df927c5c9017766c55a1d1ed95d18ad \ + --hash=sha256:a9c74a5c893a5ef8455a5adb793a31bb70feb821c86eccb62eebef5a19c429ec # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -2381,9 +2391,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 @@ -2560,78 +2570,78 @@ 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.49 \ + --hash=sha256:01146546d84185f12721a1d2ce0c6673451a7894d1460b592d378ca4871a0c72 \ + --hash=sha256:059d7151fff513c53a4638da8778be7fce81a0c4854c7348ebd0c4078ddf28fe \ + --hash=sha256:0c98c59075b890df8abfcc6ad632879540f5791c68baebacb4f833713b510e75 \ + --hash=sha256:0f2fa354ba106eafff2c14b0cc51f22801d1e8b2e4149342023bd6f0955de5f5 \ + --hash=sha256:12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148 \ + --hash=sha256:22d8798819f86720bc646ab015baff5ea4c971d68121cb36e2ebc2ee43ead2b7 \ + --hash=sha256:233088b4b99ebcbc5258c755a097aa52fbf90727a03a5a80781c4b9c54347a2e \ + --hash=sha256:24bd94bb301ec672d8f0623eba9226cc90d775d25a0c92b5f8e4965d7f3a1518 \ + --hash=sha256:275424295f4256fd301744b8f335cff367825d270f155d522b30c7bf49903ee7 \ + --hash=sha256:32fe6a41ad97302db2931f05bb91abbcc65b5ce4c675cd44b972428dd2947700 \ + --hash=sha256:334edbcff10514ad1d66e3a70b339c0a29886394892490119dbb669627b17717 \ + --hash=sha256:3bb9ec6436a820a4c006aad1ac351f12de2f2dbdaad171692ee457a02429b672 \ + --hash=sha256:3ddcb27fb39171de36e207600116ac9dfd4ae46f86c82a9bf3934043e80ebb88 \ + --hash=sha256:42e8804962f9e6f4be2cbaedc0c3718f08f60a16910fa3d86da5a1e3b1bfe60f \ + --hash=sha256:43d044780732d9e0381ac8d5316f95d7f02ef04d6e4ef6dc82379f09795d993f \ + --hash=sha256:46796877b47034b559a593d7e4b549aba151dae73f9e78212a3478161c12ab08 \ + --hash=sha256:46d51518d53edfbe0563662c96954dc8fcace9832332b914375f45a99b77cc9a \ + --hash=sha256:47604cb2159f8bbd5a1ab48a714557156320f20871ee64d550d8bf2683d980d3 \ + --hash=sha256:4bbccb45260e4ff1b7db0be80a9025bb1e6698bdb808b83fff0000f7a90b2c0b \ + --hash=sha256:4d4e5a0ceba319942fa6b585cf82539288a61e314ef006c1209f734551ab9536 \ + --hash=sha256:55250fe61d6ebfd6934a272ee16ef1244e0f16b7af6cd18ab5b1fc9f08631db0 \ + --hash=sha256:566df36fd0e901625523a5a1835032f1ebdd7f7886c54584143fa6c668b4df3b \ + --hash=sha256:57ca426a48eb2c682dae8204cd89ea8ab7031e2675120a47924fabc7caacbc2a \ + --hash=sha256:5e61abbec255be7b122aa461021daa7c3f310f3e743411a67079f9b3cc91ece3 \ + --hash=sha256:618a308215b6cececb6240b9abde545e3acdabac7ae3e1d4e666896bf5ba44b4 \ + --hash=sha256:62557958002b69699bdb7f5137c6714ca1133f045f97b3903964f47db97ea339 \ + --hash=sha256:6270d717b11c5476b0cbb21eedc8d4dbb7d1a956fd6c15a23e96f197a6193158 \ + --hash=sha256:685e93e9c8f399b0c96a624799820176312f5ceef958c0f88215af4013d29066 \ + --hash=sha256:69469ce8ce7a8df4d37620e3163b71238719e1e2e5048d114a1b6ce0fbf8c662 \ + --hash=sha256:6eb188b84269f357669b62cb576b5b918de10fb7c728a005fa0ebb0b758adce1 \ + --hash=sha256:74ab4ee7794d7ed1b0c37e7333640e0f0a626fc7b398c07a7aef52f484fddde3 \ + --hash=sha256:77641d299179c37b89cf2343ca9972c88bb6eef0d5fc504a2f86afd15cd5adf5 \ + --hash=sha256:7c821c47ecfe05cc32140dcf8dc6fd5d21971c86dbd56eabfe5ba07a64910c01 \ + --hash=sha256:7d6be30b2a75362325176c036d7fb8d19e8846c77e87683ffaa8177b35135613 \ + --hash=sha256:7f605a456948c35260e7b2a39f8952a26f077fd25653c37740ed186b90aaa68a \ + --hash=sha256:83101a6930332b87653886c01d1ee7e294b1fe46a07dd9a2d2b4f91bcc88eec0 \ + --hash=sha256:88690f4e1f0fbf5339bedbb127e240fec1fd3070e9934c0b7bef83432f779d2f \ + --hash=sha256:8a97ac839c2c6672c4865e48f3cbad7152cee85f4233fb4ca6291d775b9b954a \ + --hash=sha256:8d6efc136f44a7e8bc8088507eaabbb8c2b55b3dbb63fe102c690da0ddebe55e \ + --hash=sha256:8e20e511dc15265fb433571391ba313e10dd8ea7e509d51686a51313b4ac01a2 \ + --hash=sha256:951d4a210744813be63019f3df343bf233b7432aadf0db54c75802247330d3af \ + --hash=sha256:9ac7a3e245fd0310fd31495eb61af772e637bdf7d88ee81e7f10a3f271bff014 \ + --hash=sha256:9b1c058c171b739e7c330760044803099c7fff11511e3ab3573e5327116a9c33 \ + --hash=sha256:9c04bff9a5335eb95c6ecf1c117576a0aa560def274876fd156cfe5510fccc61 \ + --hash=sha256:9c4969a86e41454f2858256c39bdfb966a20961e9b58bf8749b65abf447e9a8d \ + --hash=sha256:9e0400fa22f79acc334d9a6b185dc00a44a8e6578aa7e12d0ddcd8434152b187 \ + --hash=sha256:a05977bffe9bffd2229f477fa75eabe3192b1b05f408961d1bebff8d1cd4d401 \ + --hash=sha256:a143af2ea6672f2af3f44ed8f9cd020e9cc34c56f0e8db12019d5d9ecf41cb3b \ + --hash=sha256:a51d3db74ba489266ef55c7a4534eb0b8db9a326553df481c11e5d7660c8364d \ + --hash=sha256:b95b2f470c1b2683febd2e7eab1d3f0e078c91dbdd0b00e9c645d07a413bb99f \ + --hash=sha256:b9870d15ef00e4d0559ae10ee5bc71b654d1f20076dbe8bc7ed19b4c0625ceba \ + --hash=sha256:c1dc3368794d522f43914e03312202523cc89692f5389c32bea0233924f8d977 \ + --hash=sha256:c338ec6ec01c0bc8e735c58b9f5d51e75bacb6ff23296658826d7cfdfdb8678a \ + --hash=sha256:c5070135e1b7409c4161133aa525419b0062088ed77c92b1da95366ec5cbebbe \ + --hash=sha256:cc992c6ed024c8c3c592c5fc9846a03dd68a425674900c70122c77ea16c5fb0b \ + --hash=sha256:d15950a57a210e36dd4cec1aac22787e2a4d57ba9318233e2ef8b2daf9ff2d5f \ + --hash=sha256:d898cc2c76c135ef65517f4ddd7a3512fb41f23087b0650efb3418b8389a3cd1 \ + --hash=sha256:d99945830a6f3e9638d89a28ed130b1eb24c91255e4f24366fbe699b983f29e4 \ + --hash=sha256:da9b91bca419dc9b9267ffadde24eae9b1a6bffcd09d0a207e5e3af99a03ce0d \ + --hash=sha256:df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120 \ + --hash=sha256:e06e617e3d4fd9e51d385dfe45b077a41e9d1b033a7702551e3278ac597dc750 \ + --hash=sha256:ec44cfa7ef1a728e88ad41674de50f6db8cfdb3e2af84af86e0041aaf02d43d0 \ + --hash=sha256:fb37f15714ec2652d574f021d479e78cd4eb9d04396dca36568fdfffb3487982 # via feast (pyproject.toml) -sqlglot==30.2.1 \ - --hash=sha256:ef4a67cc6f66a8043085eb8ea95fa9541c1625dffa9145ad4e9815a7ba60a199 \ - --hash=sha256:f23d9ee9427ef9d20df15f9b0ffa57d9eb45e52b012219a349d1e6b50ed926d1 +sqlglot==30.6.0 \ + --hash=sha256:246d34d39927422a50a3fa155f37b2f6346fba85f1a755b13c941eb32ef93361 \ + --hash=sha256:e005fc2f47994f90d7d8df341f1cbe937518497b0b7b1507d4c03c4c9dfd2778 # via ibis-framework -sse-starlette==3.3.4 \ - --hash=sha256:84bb06e58939a8b38d8341f1bc9792f06c2b53f48c608dd207582b664fc8f3c1 \ - --hash=sha256:aaf92fc067af8a5427192895ac028e947b484ac01edbc3caf00e7e7137c7bef1 +sse-starlette==3.4.1 \ + --hash=sha256:6b43cf21f1d574d582a6e1b0cfbde1c94dc86a32a701a7168c99c4475c6bd1d0 \ + --hash=sha256:f780bebcf6c8997fe514e3bd8e8c648d8284976b391c8bed0bcb1f611632b555 # via mcp starlette==1.0.0 \ --hash=sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149 \ @@ -2722,13 +2732,13 @@ typeguard==4.5.1 \ --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 # via feast (pyproject.toml) -typer==0.24.1 \ - --hash=sha256:112c1f0ce578bfb4cab9ffdabc68f031416ebcc216536611ba21f04e9aa84c9e \ - --hash=sha256:e39b4732d65fbdcde189ae76cf7cd48aeae72919dea1fdfc16593be016256b45 +typer==0.25.1 \ + --hash=sha256:75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89 \ + --hash=sha256:9616eb8853a09ffeabab1698952f33c6f29ffdbceb4eaeecf571880e8d7664cc # via fastapi-mcp -types-pymysql==1.1.0.20251220 \ - --hash=sha256:ae1c3df32a777489431e2e9963880a0df48f6591e0aa2fd3a6fabd9dee6eca54 \ - --hash=sha256:fa1082af7dea6c53b6caa5784241924b1296ea3a8d3bd060417352c5e10c0618 +types-pymysql==1.1.0.20260408 \ + --hash=sha256:b784dc37908479e3767e2d794ab507b3674adb1c686ca3d13fc9e2960dbcb9ec \ + --hash=sha256:da630647eaaa7a926a3907794f4067f269cd245b2c202c74aa3c6a3bd660a9db # via feast (pyproject.toml) typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ @@ -2759,9 +2769,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 # ibis-framework # pandas @@ -3306,7 +3316,7 @@ yarl==1.23.0 \ --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d # via aiohttp -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==3.23.1 \ + --hash=sha256:0b3596c50a5c700c9cb40ba8d86d9f2cc4807e9bedb06bcdf7fac85633e444dc \ + --hash=sha256:32120e378d32cd9714ad503c1d024619063ec28aad2248dc6672ad13edfa5110 # 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 f1eaaa0c05a..5a9824176cc 100644 --- a/sdk/python/requirements/py3.11-minimal-sdist-requirements-build.txt +++ b/sdk/python/requirements/py3.11-minimal-sdist-requirements-build.txt @@ -214,9 +214,9 @@ cython==3.2.4 \ # 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 \ @@ -257,9 +257,9 @@ gitdb==4.0.12 \ --hash=sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571 \ --hash=sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf # via gitpython -gitpython==3.1.46 \ - --hash=sha256:400124c7d0ef4ea03f7310ac2fbf7151e09ff97f2a3288d64a440c584a29c37f \ - --hash=sha256:79812ed143d9d25b6d176a10bb511de0f9c67b1fa641d82097b0ab90398a2058 +gitpython==3.1.49 \ + --hash=sha256:024b0422d7f84d15cd794844e029ffebd4c5d42a7eb9b936b458697ef550a02c \ + --hash=sha256:42f9399c9eb33fc581014bedd76049dfbaf6375aa2a5754575966387280315e1 # via pymilvus hatch-fancy-pypi-readme==25.1.0 \ --hash=sha256:9c58ed3dff90d51f43414ce37009ad1d5b0f08ffc9fc216998a06380f01c0045 \ @@ -314,6 +314,7 @@ hatchling==1.29.0 \ # pydantic-settings # pygments # python-multipart + # redis # referencing # scikit-build-core # starlette @@ -326,97 +327,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.9.0 \ + --hash=sha256:07cf11f769831186eeac424376e6189f20ace4f7263e2134bdb9757340d84d4d \ + --hash=sha256:0a09c2f5869649101738653a9b7ab70cf045a1105ac66cbb8f4055e61df78f2d \ + --hash=sha256:0a1be03168b2691ba61927e299b352a6315189199ca18a57b733f86cb3cc8d38 \ + --hash=sha256:0b73e4266307e51c95e09c0750b7ec383c561d2e97d58e473f6f6a209952fbb8 \ + --hash=sha256:15cb151e52a044f06e54ac7f7b47adbfc89b5c8e2b63e1175a9d587c43e8942a \ + --hash=sha256:194fc1a32e1e21fe809d38b5faea66cc65eaa00217c8901fbdb99866938adbdb \ + --hash=sha256:1bf465d1e5b0a27713862441f6467b5ab76385f4ecf8f1f3a44f8aa3c695b4b6 \ + --hash=sha256:1c587494461ebd42229d0f1739f3aa34237dd9980623ecf1be8d3bcba79f4499 \ + --hash=sha256:224b9727eb8bc188bc3bcf29d969dba0cd61b01d9bac80c41575520cc4baabb2 \ + --hash=sha256:22a904cbdb678f7cb348c90d543d3c52f581663d687992fee47fd566dcbf5285 \ + --hash=sha256:2b8f5d00b49818f4e2b1667db994488b045835e0ac16fe2f924f3871bd2b8ac5 \ + --hash=sha256:2c3786f0f4490a5cd87f1ed6cefae833ad6b1060d52044ce0434a2e85893afd0 \ + --hash=sha256:2d03fa4fd277a7974c1978c92c374c57f44edeee163d147b477b143446ad1bf6 \ + --hash=sha256:2f8e12706dcb8ff6b3ed57514a19e45c49ad00bcd423e87b2b2e4b5f64578443 \ + --hash=sha256:3be322a15ee5e70b93b7a59cfd074614f22cc8c9ff18bd27f474e79137ea8d3b \ + --hash=sha256:3cc2917258e131ae5f958a4d872e07555b51cb7466a43433218061c74ef33745 \ + --hash=sha256:3f05d145df35dca5056a8bc3838e940efebd893a54b3e19b2dda39ceaa299bcb \ + --hash=sha256:3fe56e80badb66fdcde06bef81bbaa5bfcf6fbd7aefb86222d9e369c38c6b228 \ + --hash=sha256:42ff8a962554c350d4a83cf47d9b7b78b0e6ff7943e87df7cdfc97c07f3c016f \ + --hash=sha256:451daa98463b7695b0a30aa56bf637831ea559e7b8101ac2ef6382e8eb15e29c \ + --hash=sha256:465814ab157986acb9dfa5ccd7df944be5eefc0d08d31ec6e8d88bc71251d845 \ + --hash=sha256:4c4d0440a3a8e31d962340c3e1cc3fc9ee7febd34c8d8f770d06adb947779ea5 \ + --hash=sha256:4e3dda8345307fd7306db0ed0cb109a63a2c85ba780eb9dc2d09b2049a931f9c \ + --hash=sha256:5093043afb226ecfa1400120d1ebd4442b4f99977783e4f4f7248879009b227f \ + --hash=sha256:5112c2fb7c2eefefaeaf5c97fec81343ef44ee86a30dcfaa8223822fba6467b4 \ + --hash=sha256:527b5b820b47a09e09829051452bb0d1dd2122261254e2a6f674d12f1d793d54 \ + --hash=sha256:54d412e47c21b85865676ed0724e37a89e9593c2eee1e7367adf85bfad56ffb1 \ + --hash=sha256:56d65b583cf43b8cf4c8fbe1e1da20fa3076cc32a1149a141507af1062718236 \ + --hash=sha256:5ca8e133d799c948db2ab1afc081c333a825b5540475164726dcbf73537e5c2f \ + --hash=sha256:603138ee838ee1583f1b960b62d5d0007845c5c423feb68e44648b1359014e27 \ + --hash=sha256:63c12efcd160e1d14da11af0c46c0217473e1e0d2ae1acbccc83f561ea4c2a7b \ + --hash=sha256:657f8ba7b9eaaa82759a104137aed2a3ef7bc46ccfd43e0d89b04005b3e0a4cc \ + --hash=sha256:66b58fed90a545328e80d575467244de3741e088c1af928f0b489ebec3ef3858 \ + --hash=sha256:6788207daa0c19955d2b668f3294a368d19f67d9b5f274553fd073c1260cbb9f \ + --hash=sha256:703f4ae36d6240bfe24f542bac784c7e4194ec49c3ba5a994d02891649e2d85b \ + --hash=sha256:7202bdcac47d3a708271c4304a474a8605a4a9a4a709e954bf2d3241140aa938 \ + --hash=sha256:756775d25ec8345b837ab52effee3ad2f3b2dfd6bbee3e3f029c517bd5d8f05a \ + --hash=sha256:78042f6facfd98ecb25e9829c7e37cce23363d9d7c83bc5f72702c5059eb082b \ + --hash=sha256:789fff71757facc0738e8d89e3b84e4f0251c1c975e85e81b152cdaca927cc2d \ + --hash=sha256:7bc30ad339f4e1a01d4917d645e522a0bc0030644d8973f6346397c93ba1503f \ + --hash=sha256:7d429bdd4ac0ab17c8e4a8af0ed2a7440b16eba474909ab357131018fe8c7e71 \ + --hash=sha256:7d5c8a5929ac325729f6119802070b561f4db793dffc45e9ac750992a4ed4d22 \ + --hash=sha256:7e6274fd33fc5b2a14d41c9119629d3ff395849d8bcbc80cf637d9e8d2034da8 \ + --hash=sha256:80b25c7b570a86c03b5da69e665809deb39265476e8e21d96a9328f9762f9990 \ + --hash=sha256:81107843ed1836874b46b310f9b1816abcb89912af627868522461c3b7333c0f \ + --hash=sha256:8494cfc61e03542f2d381e71804990b3931175a29b9278fdb4a5459948778dc2 \ + --hash=sha256:850d6d03177e52700af605fd60db7f37dcb89782049a149674d1a9649c2138fd \ + --hash=sha256:8c6bc1384d9738781cfd41d09ad7f6e8af13cfea2c75ece6bd6d2566cdea2076 \ + --hash=sha256:90904fac73c478f4b83f4ed96c99c8208b75e6f9a8a1910548f69a00f1eaa671 \ + --hash=sha256:90e6d5420fc8a300518d4d2288154ff45005e920425c22cbbfe8330f3f754bd9 \ + --hash=sha256:928bd06eca2c2bbf4349e5b817f837509b0604342e65a502de1d50a7570afd15 \ + --hash=sha256:9b3e3bc363f71bda1639a4ee593cb78f7fbfeacc73411ec0d4c92f00730010a4 \ + --hash=sha256:9edcc35d1cae9fd5320171b1a838c7da8a5c968af31e82ecc3dff30b4be0957f \ + --hash=sha256:9fcb461fbf70654a52a7cc670e606f04449e2374c199b1825f754e16dacfedd8 \ + --hash=sha256:a0951822531e7aee6e0dfb556b30d5ee36bbe234faf60c20a16c01be3530869d \ + --hash=sha256:a361c9434a64d70a7dbb771d1de302c0cc9f13c0bffe1cf7e642152814b35265 \ + --hash=sha256:a4b25c6c25cac5d0d9d6d6da855195b254e0021e513e0249f0e3b444dc6e0e61 \ + --hash=sha256:a5af136bfba820d592f86c67affcef9b3ff4d4360ac3255e341e964489b48519 \ + --hash=sha256:a81eea9b999b985e4bacc650c4312805ea7008fd5e45e1bf221310176a7bcb3a \ + --hash=sha256:a9c63e04d003bc0fb6a03b348018b9a3002f98268200e22cc80f146beac5dc40 \ + --hash=sha256:aa95738a68cedd3a6f5492feddc513e2e166b50602958139e47bbdd82da0f5a7 \ + --hash=sha256:b0a2040f801406b93657a70b72fa12311063a319fee72ce98e1524da7200171f \ + --hash=sha256:b8bd70d5d816566a580d193326912f4a76ec2d28a97dc4cd4cc831c0af8e330e \ + --hash=sha256:b8da9f8035bb417770b1e1610526d87ad4fc58a2804dc4d79c53f6d2cf5a6eb9 \ + --hash=sha256:bc5518873822d2faa8ebdd2c1a4d7c8ef47b01a058495ab7924cb65bdbf5fc9a \ + --hash=sha256:c0d620e74897f8c2613b3c4e2e9c1e422eb46d2ddd07df540784d44117836af3 \ + --hash=sha256:c2640e23d2b7c98796f123ffd95cf2022c7777aa8a4a3b98b36c570d37e85eee \ + --hash=sha256:c81aef782380f0f13ead670aae01825eb653b44b046aa0e5ebbb79f76ed4aa11 \ + --hash=sha256:d4d16b608a1c43d7e33142099a75cd93af482dadce0bf82421e91cad077157f4 \ + --hash=sha256:d69fc39e627908f4c03297d5a88d9284b73f4d90b424461e32e8c2485e21c283 \ + --hash=sha256:d9da80e5b04acce03ced8ba6479a71c2a2edf535c2acc0d09c80d2f80f3bad15 \ + --hash=sha256:dd2c7e082b0b92e1baa4da28163a808672485617bc855cc22a2fd06978fa9084 \ + --hash=sha256:de7dac64e3eb832ffc7b840eb8f52f76420cde1b845be51b2a0f6b870890645e \ + --hash=sha256:e0785c2fb4a81e1aece366aa3e2e039f4a4d7d21aaaded5227d7f3c703427882 \ + --hash=sha256:e306d956cfa027fe041585f02a1602c32bfa6bb8ebea4899d373383295a6c62f \ + --hash=sha256:e78fb7419e07d98c2af4b8567b72b3eaf8cb05caad642e9963465569c8b2d87e \ + --hash=sha256:e9002e98dcb1c0a66723592520decd86238ddcef168b37ff6cfb559200b4b774 \ + --hash=sha256:e94cbc6ad9a6aeea46d775cbb11f361022f778a9cc8cc90af653d3a594b057ce \ + --hash=sha256:eea1b54943475f51698f85fa230c65ccac769f1e603b981be060ac5763d90927 \ + --hash=sha256:f100bfe2acf8a3689af9d0cc660d89f17286c9c795f9f18f7b62dd1a6b247ae6 \ + --hash=sha256:f162af66a2ed3f7d1d161a82ca584efd15acd9c1cff190a373458c32f7d42118 \ + --hash=sha256:f24b90b0e0c8cc9491fb1693ae91fe17cb7963153a1946395acdbdd5818429a4 \ + --hash=sha256:f29b68cd9714531672db62cc54f6e8ff981900f824d13fa0e00749189e13778e \ + --hash=sha256:f38bc489037eca88d6ebefc9c4d41a4e07c8e8b4de5188a9e6d290273ad7ebb1 \ + --hash=sha256:f3fd278f5e6bf7c75ccd6d12344eb686cc020712683363b66f46ac79d37c799f \ + --hash=sha256:f4003f70c56a5addd6aa0897f200dd59afd3bf7bcd5b3cce46dd21f925743bc2 \ + --hash=sha256:f48c963a76d71b9d7927eb817b543d0dccd52ab6648b99d37bd54f4cd475d856 \ + --hash=sha256:f819e0c6413e259a17a7c0d49f97f405abadd3c2a316a3b46c6440b7dbbedbb1 \ + --hash=sha256:fc5758e2b7a56532dc33e3c544d78cbaa9ecf0a0f2a2da2df882c1d6b99a317f \ + --hash=sha256:fcbdf2a9ca24e87bbebb47f1fe34e531ef06f104f98c9ccfc953a3f3344c567a # via mypy markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -509,21 +577,21 @@ 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.1 \ + --hash=sha256:001741c6cff56aa8ea59a0d78ae990c0550d0e3e82b00b683eedb4158a8ef7e6 \ + --hash=sha256:01c845825c917c07c1d0b2c9032c59c16a7d383d1e649a46481d3e5693c2750f \ + --hash=sha256:2839024dcd65776abb4759e5bca29941971e095574162a4d335191da4be9ff24 \ + --hash=sha256:3da18cccf2f683c0977bff9146a0908d6ffce836d600665736ac01679f588cb9 \ + --hash=sha256:416e4e01cb88b798e606ee43929df897e42c1647b722ef68283816cca99a8742 \ + --hash=sha256:6b1e5916a253243e8f5f9e847b62bbc98420eec48c9ce2e2e8724c6da89d359b \ + --hash=sha256:72888e87819ce546d0d2df900e4b385e4ef299077d92ee37b48923a5602dae94 \ + --hash=sha256:98b5fcf1a186c217830a8295ecc2989c6b1cf50945417adfc15252107b9475b7 \ + --hash=sha256:9a87ff3b8e4d1c6eac33ebfe8e261e8236516d98d45c0323550621819b5a1a2f \ + --hash=sha256:a2017d2281203d0c6570240e7d746564d766d756105823b7de68bda6ae722711 \ + --hash=sha256:c1490584f3c70af45466ee99065b49e6657ebdccac6b10571bb44681309c9396 \ + --hash=sha256:c6a720b252c99de072922dbe4432ab19662b6f80045b0355fec23bdfccb450da \ + --hash=sha256:dc91031e0619c1e28730279ef9ee5f106c9b9ec806b013f888676b242f892eb7 \ + --hash=sha256:f69093ed4a0e6464e52a7fc26d714f859ce15630ec8070743398c6bf41f38a9e # via # cryptography # pydantic-core @@ -623,9 +691,9 @@ numpy==2.4.4 \ # 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 @@ -635,9 +703,9 @@ packaging==26.0 \ # 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 @@ -666,13 +734,13 @@ poetry-core==2.3.2 \ # pkgconfig # rich # tomlkit -pybind11-global==3.0.3 \ - --hash=sha256:141adb150fdb84f6eba3e27241da886f4582574a3d1c30568bf33c1ed3ec8b82 \ - --hash=sha256:7a75ee81e903ea15bdf05db1342c37400751a72316b6620c800b66d70be45632 +pybind11-global==3.0.4 \ + --hash=sha256:95b693c3d646c6b7217a97156a36b6d40305505d4a5a728082da6fe75ada29f5 \ + --hash=sha256:a73e2ebd29f4ee5d7c754b495d555cd703f2cd26c84abe360ee56411dcd7834d # via pybind11 -pybind11==3.0.3 \ - --hash=sha256:00471cdb816882c484708bc5dde80815c8c11cea540ab2cc6410f5ddea434755 \ - --hash=sha256:fb5f8e4a64946b4dcc0451c83a8c384f803bc0a62dd1ba02f199e97dbc9aad4c +pybind11==3.0.4 \ + --hash=sha256:3286b59c8a774b9ee650169302dd5a4eedc30a8617905a0560dd8ee44775130c \ + --hash=sha256:961720ee652da51d531b7b2451a6bd2bc042b0106e6d9baa48ecb7d58034ce63 # via duckdb pycparser==3.0 \ --hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \ @@ -682,12 +750,88 @@ 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 \ @@ -701,7 +845,9 @@ setuptools-git-versioning==3.0.1 \ setuptools-rust==1.12.1 \ --hash=sha256:85ae70989d96c9cfeb5ef79cf3bac2d5200bc5564f720a06edceedbdf6664640 \ --hash=sha256:b7ebd6a182e7aefa97a072e880530c9b0ec8fcca8617e0bb8ff299c1a064f693 - # via maturin + # via + # libcst + # maturin setuptools-scm==10.0.5 \ --hash=sha256:bbba8fe754516cdefd017f4456721775e6ef9662bd7887fb52ae26813d4838c3 \ --hash=sha256:f611037d8aae618221503b8fa89319f073438252ae3420e01c9ceec249131a0a @@ -712,6 +858,7 @@ setuptools-scm==10.0.5 \ # hatch-vcs # httpx-sse # importlib-metadata + # libcst # pluggy # pyarrow # pybindgen @@ -791,17 +938,17 @@ tomlkit==0.14.0 \ --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 # via uv-dynamic-versioning -trove-classifiers==2026.1.14.14 \ - --hash=sha256:00492545a1402b09d4858605ba190ea33243d361e2b01c9c296ce06b5c3325f3 \ - --hash=sha256:1f9553927f18d0513d8e5ff80ab8980b8202ce37ecae0e3274ed2ef11880e74d +trove-classifiers==2026.4.28.13 \ + --hash=sha256:8f4b1eb4e16296b57d612965444f87a83861cc989a0451ac97fe4265ddef03b8 \ + --hash=sha256:c85bb8a53c3de7330d1699b844ed9fb809a602a09ac15dc79ad6d1a509be0676 # via hatchling types-psutil==7.0.0.20250218 \ --hash=sha256:1447a30c282aafefcf8941ece854e1100eee7b0296a9d9be9977292f0269b121 \ --hash=sha256:1e642cdafe837b240295b23b1cbd4691d80b08a07d29932143cbbae30eb0db9c # via mypy -types-setuptools==82.0.0.20260402 \ - --hash=sha256:4b9a9f6c3c4c65107a3956ad6a6acbccec38e398ff6d5f78d5df7f103dadb8d6 \ - --hash=sha256:63d2b10ba7958396ad79bbc24d2f6311484e452daad4637ffd40407983a27069 +types-setuptools==82.0.0.20260408 \ + --hash=sha256:036c68caf7e672a699f5ebbf914708d40644c14e05298bc49f7272be91cf43d3 \ + --hash=sha256:ece0a215cdfa6463a65fd6f68bd940f39e455729300ddfe61cab1147ed1d2462 # via mypy typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ @@ -823,13 +970,14 @@ versioneer==0.29 \ # 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 # httpx-sse + # libcst # meson # mmh3 # pandas @@ -873,6 +1021,7 @@ setuptools==80.10.2 \ # gunicorn # httpx-sse # importlib-metadata + # libcst # librt # markupsafe # maturin @@ -891,7 +1040,6 @@ setuptools==80.10.2 \ # psycopg # psycopg-c # psycopg-pool - # pyarrow # pyasn1 # pyasn1-modules # pycparser @@ -915,7 +1063,6 @@ setuptools==80.10.2 \ # tqdm # trove-classifiers # typeguard - # types-pymysql # tzdata # ujson # uvloop @@ -934,4 +1081,5 @@ setuptools==82.0.1 \ --hash=sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb # via # python-dateutil + # types-pymysql # types-setuptools diff --git a/sdk/python/requirements/py3.11-minimal-sdist-requirements.txt b/sdk/python/requirements/py3.11-minimal-sdist-requirements.txt index 34cda10c5fb..84fa82236dc 100644 --- a/sdk/python/requirements/py3.11-minimal-sdist-requirements.txt +++ b/sdk/python/requirements/py3.11-minimal-sdist-requirements.txt @@ -206,9 +206,9 @@ 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.4.22 \ + --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ + --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 # via # httpcore # httpx @@ -436,9 +436,9 @@ charset-normalizer==3.4.7 \ # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.3.3 \ + --hash=sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2 \ + --hash=sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 # via # feast (pyproject.toml) # dask @@ -452,56 +452,56 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via feast (pyproject.toml) -cryptography==46.0.6 \ - --hash=sha256:02fad249cb0e090b574e30b276a3da6a149e04ee2f049725b1f69e7b8351ec70 \ - --hash=sha256:063b67749f338ca9c5a0b7fe438a52c25f9526b851e24e6c9310e7195aad3b4d \ - --hash=sha256:12cae594e9473bca1a7aceb90536060643128bb274fcea0fc459ab90f7d1ae7a \ - --hash=sha256:12f0fa16cc247b13c43d56d7b35287ff1569b5b1f4c5e87e92cc4fcc00cd10c0 \ - --hash=sha256:22259338084d6ae497a19bae5d4c66b7ca1387d3264d1c2c0e72d9e9b6a77b97 \ - --hash=sha256:26031f1e5ca62fcb9d1fcb34b2b60b390d1aacaa15dc8b895a9ed00968b97b30 \ - --hash=sha256:27550628a518c5c6c903d84f637fbecf287f6cb9ced3804838a1295dc1fd0759 \ - --hash=sha256:2b417edbe8877cda9022dde3a008e2deb50be9c407eef034aeeb3a8b11d9db3c \ - --hash=sha256:2ea0f37e9a9cf0df2952893ad145fd9627d326a59daec9b0802480fa3bcd2ead \ - --hash=sha256:2ef9e69886cbb137c2aef9772c2e7138dc581fad4fcbcf13cc181eb5a3ab6275 \ - --hash=sha256:341359d6c9e68834e204ceaf25936dffeafea3829ab80e9503860dcc4f4dac58 \ - --hash=sha256:380343e0653b1c9d7e1f55b52aaa2dbb2fdf2730088d48c43ca1c7c0abb7cc2f \ - --hash=sha256:3c21d92ed15e9cfc6eb64c1f5a0326db22ca9c2566ca46d845119b45b4400361 \ - --hash=sha256:3dfa6567f2e9e4c5dceb8ccb5a708158a2a871052fa75c8b78cb0977063f1507 \ - --hash=sha256:456b3215172aeefb9284550b162801d62f5f264a081049a3e94307fe20792cfa \ - --hash=sha256:4668298aef7cddeaf5c6ecc244c2302a2b8e40f384255505c22875eebb47888b \ - --hash=sha256:50575a76e2951fe7dbd1f56d181f8c5ceeeb075e9ff88e7ad997d2f42af06e7b \ - --hash=sha256:639301950939d844a9e1c4464d7e07f902fe9a7f6b215bb0d4f28584729935d8 \ - --hash=sha256:64235194bad039a10bb6d2d930ab3323baaec67e2ce36215fd0952fad0930ca8 \ - --hash=sha256:6617f67b1606dfd9fe4dbfa354a9508d4a6d37afe30306fe6c101b7ce3274b72 \ - --hash=sha256:67177e8a9f421aa2d3a170c3e56eca4e0128883cf52a071a7cbf53297f18b175 \ - --hash=sha256:6728c49e3b2c180ef26f8e9f0a883a2c585638db64cf265b49c9ba10652d430e \ - --hash=sha256:6739d56300662c468fddb0e5e291f9b4d084bead381667b9e654c7dd81705124 \ - --hash=sha256:69cf0056d6947edc6e6760e5f17afe4bea06b56a9ac8a06de9d2bd6b532d4f3a \ - --hash=sha256:760997a4b950ff00d418398ad73fbc91aa2894b5c1db7ccb45b4f68b42a63b3c \ - --hash=sha256:79e865c642cfc5c0b3eb12af83c35c5aeff4fa5c672dc28c43721c2c9fdd2f0f \ - --hash=sha256:7e6142674f2a9291463e5e150090b95a8519b2fb6e6aaec8917dd8d094ce750d \ - --hash=sha256:7f417f034f91dcec1cb6c5c35b07cdbb2ef262557f701b4ecd803ee8cefed4f4 \ - --hash=sha256:7f6690b6c55e9c5332c0b59b9c8a3fb232ebf059094c17f9019a51e9827df91c \ - --hash=sha256:8927ccfbe967c7df312ade694f987e7e9e22b2425976ddbf28271d7e58845290 \ - --hash=sha256:8ce35b77aaf02f3b59c90b2c8a05c73bac12cea5b4e8f3fbece1f5fddea5f0ca \ - --hash=sha256:8e7304c4f4e9490e11efe56af6713983460ee0780f16c63f219984dab3af9d2d \ - --hash=sha256:90e5f0a7b3be5f40c3a0a0eafb32c681d8d2c181fc2a1bdabe9b3f611d9f6b1a \ - --hash=sha256:97c8115b27e19e592a05c45d0dd89c57f81f841cc9880e353e0d3bf25b2139ed \ - --hash=sha256:9a693028b9cbe51b5a1136232ee8f2bc242e4e19d456ded3fa7c86e43c713b4a \ - --hash=sha256:9a9c42a2723999a710445bc0d974e345c32adfd8d2fac6d8a251fa829ad31cfb \ - --hash=sha256:a3e84d5ec9ba01f8fd03802b2147ba77f0c8f2617b2aff254cedd551844209c8 \ - --hash=sha256:aad75154a7ac9039936d50cf431719a2f8d4ed3d3c277ac03f3339ded1a5e707 \ - --hash=sha256:b12c6b1e1651e42ab5de8b1e00dc3b6354fdfd778e7fa60541ddacc27cd21410 \ - --hash=sha256:b928a3ca837c77a10e81a814a693f2295200adb3352395fad024559b7be7a736 \ - --hash=sha256:bcb87663e1f7b075e48c3be3ecb5f0b46c8fc50b50a97cf264e7f60242dca3f2 \ - --hash=sha256:c797e2517cb7880f8297e2c0f43bb910e91381339336f75d2c1c2cbf811b70b4 \ - --hash=sha256:c89eb37fae9216985d8734c1afd172ba4927f5a05cfd9bf0e4863c6d5465b013 \ - --hash=sha256:cdcd3edcbc5d55757e5f5f3d330dd00007ae463a7e7aa5bf132d1f22a4b62b19 \ - --hash=sha256:d24c13369e856b94892a89ddf70b332e0b70ad4a5c43cf3e9cb71d6d7ffa1f7b \ - --hash=sha256:d4e4aadb7fc1f88687f47ca20bb7227981b03afaae69287029da08096853b738 \ - --hash=sha256:d9528b535a6c4f8ff37847144b8986a9a143585f0540fbcb1a98115b543aa463 \ - --hash=sha256:ed3775295fb91f70b4027aeba878d79b3e55c0b3e97eaa4de71f8f23a9f2eb77 \ - --hash=sha256:ed418c37d095aeddf5336898a132fba01091f0ac5844e3e8018506f014b6d2c4 +cryptography==47.0.0 \ + --hash=sha256:0024b87d47ae2399165a6bfb20d24888881eeab83ae2566d62467c5ff0030ce7 \ + --hash=sha256:07efe86201817e7d3c18781ca9770bc0db04e1e48c994be384e4602bc38f8f27 \ + --hash=sha256:09f6d7bf6724f8db8b32f11eccf23efc8e759924bc5603800335cf8859a3ddbd \ + --hash=sha256:11438c7518132d95f354fa01a4aa2f806d172a061a7bed18cf18cbdacdb204d7 \ + --hash=sha256:11dbb9f50a0f1bb9757b3d8c27c1101780efb8f0bdecfb12439c22a74d64c001 \ + --hash=sha256:14432c8a9bcb37009784f9594a62fae211a2ae9543e96c92b2a8e4c3cd5cd0c4 \ + --hash=sha256:1581aef4219f7ca2849d0250edaa3866212fb74bf5667284f46aa92f9e65c1ca \ + --hash=sha256:160ad728f128972d362e714054f6ba0067cab7fb350c5202a9ae8ae4ce3ef1a0 \ + --hash=sha256:1a405c08857258c11016777e11c02bacbe7ef596faf259305d282272a3a05cbe \ + --hash=sha256:1e47422b5557bb82d3fff997e8d92cff4e28b9789576984f08c248d2b3535d93 \ + --hash=sha256:20fdbe3e38fb67c385d233c89371fa27f9909f6ebca1cecc20c13518dae65475 \ + --hash=sha256:2207a498b03275d0051589e326b79d4cf59985c99031b05bb292ac52631c37fe \ + --hash=sha256:256d07c78a04d6b276f5df935a9923275f53bd1522f214447fdf365494e2d515 \ + --hash=sha256:2b45761c6ec22b7c726d6a829558777e32d0f1c8be7c3f3480f9c912d5ee8a10 \ + --hash=sha256:2ebd84adf0728c039a3be2700289378e1c164afc6748df1a5ed456767bef9ba7 \ + --hash=sha256:34b4358b925a5ea3e14384ca781a2c0ef7ac219b57bb9eacc4457078e2b19f92 \ + --hash=sha256:3fb8fa48075fad7193f2e5496135c6a76ac4b2aa5a38433df0a539296b377829 \ + --hash=sha256:4e1de79e047e25d6e9f8cea71c86b4a53aced64134f0f003bbcbf3655fd172c8 \ + --hash=sha256:4f7722c97826770bab8ae92959a2e7b20a5e9e9bf4deae68fd86c3ca457bab52 \ + --hash=sha256:51c9313e90bd1690ec5a75ed047c27c0b8e6c570029712943d6116ef9a90620b \ + --hash=sha256:5d0e362ff51041b0c0d219cc7d6924d7b8996f57ce5712bdcef71eb3c65a59cc \ + --hash=sha256:6651d32eff255423503aa276739da98c30f26c40cbeffcc6048e0d54ef704c0c \ + --hash=sha256:6eebcaf0df1d21ce1f90605c9b432dd2c4f4ab665ac29a40d5e3fc68f51b5e63 \ + --hash=sha256:6f29f36582e6151d9686235e586dd35bb67491f024767d10b842e520dc6a07ac \ + --hash=sha256:7a02675e2fabd0c0fc04c868b8781863cbf1967691543c22f5470500ff840b31 \ + --hash=sha256:7f1207974a904e005f762869996cf620e9bf79ecb4622f148550bb48e0eb35a7 \ + --hash=sha256:7f68d6fbc7fbbcfb0939fea72c3b96a9f9a6edfc0e1b1d29778a2066030418b1 \ + --hash=sha256:7fda2f02c9015db3f42bb8a22324a454516ed10a8c29ca6ece6cdbb5efe2a203 \ + --hash=sha256:80887c5cbd1774683cb126f0ab4184567f080071d5acf62205acb354b4b753b7 \ + --hash=sha256:835d2d7f47cdc53b3224e90810fb1d36ca94ea29cc1801fb4c1bc43876735769 \ + --hash=sha256:8c1a736bbb3288005796c3f7ccb9453360d7fed483b13b9f468aea5171432923 \ + --hash=sha256:9af828c0d5a65c70ec729cd7495a4bf1a67ecb66417b8f02ff125ab8a6326a74 \ + --hash=sha256:9c59ab0e0fa3a180a5a9c59f3a5abe3ef90d474bc56d7fadfbe80359491b615b \ + --hash=sha256:9f8e55fe4e63613a5e1cc5819030f27b97742d720203a087802ce4ce9ceb52bb \ + --hash=sha256:9fe6b7c64926c765f9dff301f9c1b867febcda5768868ca084e18589113732ab \ + --hash=sha256:a49a3eb5341b9503fa3000a9a0db033161db90d47285291f53c2a9d2cd1b7f76 \ + --hash=sha256:a9b761f012a943b7de0e828843c5688d0de94a0578d44d6c85a1bae32f87791f \ + --hash=sha256:b1c76fca783aa7698eb21eb14f9c4aa09452248ee54a627d125025a43f83e7a7 \ + --hash=sha256:b9a8943e359b7615db1a3ba587994618e094ff3d6fa5a390c73d079ce18b3973 \ + --hash=sha256:be12cb6a204f77ed968bcefe68086eb061695b540a3dd05edac507a3111b25f0 \ + --hash=sha256:cffbba3392df0fa8629bb7f43454ee2925059ee158e23c54620b9063912b86c8 \ + --hash=sha256:ed67ea4e0cfb5faa5bc7ecb6e2b8838f3807a03758eec239d6c21c8769355310 \ + --hash=sha256:edd4da498015da5b9f26d38d3bfc2e90257bfa9cbed1f6767c282a0025ae649b \ + --hash=sha256:ef6b3634087f18d2155b1e8ce264e5345a753da2c5fa9815e7d41315c90f8318 \ + --hash=sha256:f1557695e5c2b86e204f6ce9470497848634100787935ab7adc5397c54abd7ab \ + --hash=sha256:f5c15764f261394b22aef6b00252f5195f46f2ca300bec57149474e2538b31f8 \ + --hash=sha256:f5c3296dab66202f1b18a91fa266be93d6aa0c2806ea3d67762c69f60adc71aa \ + --hash=sha256:f7db373287273d8af1414cf95dc4118b13ffdc62be521997b0f2b270771fef50 \ + --hash=sha256:f9a034b642b960767fb343766ae5ba6ad653f2e890ddd82955aef288ffea8736 # via # google-auth # pyjwt @@ -591,50 +591,50 @@ docutils==0.22.4 \ --hash=sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968 \ --hash=sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # via sphinx -duckdb==1.5.1 \ - --hash=sha256:054ad424b051b334052afac58cb216f3b1ebb8579fc8c641e60f0182e8725ea9 \ - --hash=sha256:05fc91767d0cfc4cf2fa68966ab5b479ac07561752e42dd0ae30327bd160f64a \ - --hash=sha256:0a6acc2040bec1f05de62a2f3f68f4c12f3ec7d6012b4317d0ab1a195af26225 \ - --hash=sha256:26e56b5f0c96189e3288d83cf7b476e23615987902f801e5788dee15ee9f24a9 \ - --hash=sha256:36e8e32621a9e2a9abe75dc15a4b54a3997f2d8b1e53ad754bae48a083c91130 \ - --hash=sha256:40c5220ec93790b18ec6278da9c6ac2608d997ee6d6f7cd44c5c3992764e8e71 \ - --hash=sha256:446d500a2977c6ae2077f340c510a25956da5c77597175c316edfa87248ceda3 \ - --hash=sha256:46f92ada9023e59f27edc048167b31ac9a03911978b1296c845a34462a27f096 \ - --hash=sha256:482f8a13f2600f527e427f73c42b5aa75536f9892868068f0aaf573055a0135f \ - --hash=sha256:553c273a6a8f140adaa6da6a6135c7f95bdc8c2e5f95252fcdf9832d758e2141 \ - --hash=sha256:5ae7c0d744d64e2753149634787cc4ab60f05ef1e542b060eeab719f3cdb7723 \ - --hash=sha256:5d4147422d91ccdc2d2abf6ed24196025e020259d1d267970ae20c13c2ce84b1 \ - --hash=sha256:6af347debc8b721aa72e48671166282da979d5e5ae52dbc660ab417282b48e23 \ - --hash=sha256:6ba302115f63f6482c000ccfd62efdb6c41d9d182a5bcd4a90e7ab8cd13856eb \ - --hash=sha256:6f7361d66cc801d9eb4df734b139cd7b0e3c257a16f3573ebd550ddb255549e6 \ - --hash=sha256:715f05ea198d20d7f8b407b9b84e0023d17f2b9096c194cea702b7840e74f1f7 \ - --hash=sha256:71dddcebbc5a70e946a06c30b59b5dd7999c9833d307168f90fb4e4b672ab63e \ - --hash=sha256:8150c569b2aa4573b51ba8475e814aa41fd53a3d510c1ffb96f1139f46faf611 \ - --hash=sha256:8843bd9594e1387f1e601439e19ad73abdf57356104fd1e53a708255bb95a13d \ - --hash=sha256:8c0088765747ae5d6c9f89987bb36f9fb83564f07090d721344ce8e1abedffea \ - --hash=sha256:972d0dbf283508f9bc446ee09c3838cb7c7f114b5bdceee41753288c97fe2f7c \ - --hash=sha256:a28531cee2a5a42d89f9ba4da53bfeb15681f12acc0263476c8705380dadce07 \ - --hash=sha256:a3be2072315982e232bfe49c9d3db0a59ba67b2240a537ef42656cc772a887c7 \ - --hash=sha256:ac2804043bd1bc10b5da18f8f4c706877197263a510c41be9b4c0062f5783dcc \ - --hash=sha256:afab8b4b1f4469c3879bb049dd039f8fce402712050324e9524a43d7324c5e87 \ - --hash=sha256:b370d1620a34a4538ef66524fcee9de8171fa263c701036a92bc0b4c1f2f9c6d \ - --hash=sha256:b8b0808dba0c63b7633bdaefb34e08fe0612622224f9feb0e7518904b1615101 \ - --hash=sha256:bc7ca6a1a40e7e4c933017e6c09ef18032add793df4e42624c6c0c87e0bebdad \ - --hash=sha256:caa65e1f5bf007430bf657c37cab7ab81a4ddf8d337e3062bcc5085d17ef038b \ - --hash=sha256:d68c5a01a283cb13b79eafe016fe5869aa11bff8c46e7141c70aa0aac808010f \ - --hash=sha256:da137802688190835b4c863cafa77fd7e29dff662ee6d905a9ffc14f00299c91 \ - --hash=sha256:e56a20ab6cdb90a95b0c99652e28de3504ce77129087319c03c9098266183ae5 \ - --hash=sha256:e878ccb7d20872065e1597935fdb5e65efa43220c8edd0d9c4a1a7ff1f3eb277 \ - --hash=sha256:eba81e0b3011c1f23df7ea47ef4ffaa8239817959ae291515b6efd068bde2161 \ - --hash=sha256:ed6d23a3f806898e69c77430ebd8da0c79c219f97b9acbc9a29a653e09740c59 +duckdb==1.5.2 \ + --hash=sha256:0b291786014df1133f8f18b9df4d004484613146e858d71a21791e0fcca16cf4 \ + --hash=sha256:2323c1195c10fb2bb982fc0218c730b43d1b92a355d61e68e3c5f3ac9d44c34f \ + --hash=sha256:2a1de4f4d454b8c97aec546c82003fc834d3422ce4bc6a19902f3462ef293bed \ + --hash=sha256:35579b8e3a064b5eaf15b0eafc558056a13f79a0a62e34cc4baf57119daecfec \ + --hash=sha256:376856066c65ccd55fcb3a380bbe33a71ce089fc4623d229ffc6e82251afdb6d \ + --hash=sha256:411ad438bd4140f189a10e7f515781335962c5d18bd07837dc6d202e3985253d \ + --hash=sha256:4420b3f47027a7849d0e1815532007f377fa95ee5810b47ea717d35525c12f79 \ + --hash=sha256:486c862bf7f163c0110b6d85b3e5c031d224a671cca468f12ebb1d3a348f6b39 \ + --hash=sha256:52a21823f3fbb52f0f0e5425e20b07391ad882464b955879499b5ff0b45a376b \ + --hash=sha256:5596bbfc31b1b259db69c8d847b42d036ce2c4804f9ccb28f9fc46a16de7bc53 \ + --hash=sha256:56d38b3c4e0ef2abb58898d0fd423933999ed535c45e75e9d9f72e1d5fed69b8 \ + --hash=sha256:638da0d5102b6cb6f7d47f83d0600708ac1d3cb46c5e9aaabc845f9ba4d69246 \ + --hash=sha256:63bf8687feefeed51adf45fa3b062ab8b1b1c350492b7518491b86bae68b1da1 \ + --hash=sha256:6b0fe75c148000f060aa1a27b293cacc0ea08cc1cad724fbf2143d56070a3785 \ + --hash=sha256:70631c847ca918ee710ec874241b00cf9d2e5be90762cbb2a0389f17823c08f7 \ + --hash=sha256:7f69164b048e498b9e9140a24343108a5ae5f17bfb3485185f55fdf9b1aa924d \ + --hash=sha256:81fc4fbf0b5e25840b39ba2a10b78c6953c0314d5d0434191e7898f34ab1bba3 \ + --hash=sha256:84b193aca20565dedb3172de15f843c659c3a6c773bf14843a9bd781c850e7db \ + --hash=sha256:8d599758b4e48bf12e18c9b960cf491d219f0c4972d19a45489c05cc5ab36f83 \ + --hash=sha256:8dbd7e31e5dc157bfe8803fa7d2652336265c6c19926c5a4a9b40f8222868d08 \ + --hash=sha256:98c0535cd6d901f61a5ea3c2e26a1fd28482953d794deb183daf568e3aa5dda6 \ + --hash=sha256:a9cd5e71702d446613750405cde03f66ed268f4c321da071b0472759dad19536 \ + --hash=sha256:bb42e6ed543902e14eae647850da24103a89f0bc2587dec5601b1c1f213bd2ed \ + --hash=sha256:be37680ddb380015cb37318e378c53511c45c4f0d8fac5599d22b7d092b9217a \ + --hash=sha256:c69907354ffee94ba8cf782daf0480dab7557f21ce27fffa6c0ea8f74ed4b8e2 \ + --hash=sha256:c99ef73a277c8921bc0a1f16dee38d924484251d9cfd20951748c20fcd5ed855 \ + --hash=sha256:c9f3e0b71b8a50fccfb42794899285d9d318ce2503782b9dd54868e5ecd0ad31 \ + --hash=sha256:ce0b8141a10d37ecef729c45bc41d334854013f4389f1488bd6035c5579aaac1 \ + --hash=sha256:ce17670bb392ea1b3650537db02bd720908776b5b95f6d2472d31a7de59d1dc1 \ + --hash=sha256:d72b8856b1839d35648f38301b058f6232f4d36b463fe4dc8f4d3fdff2df1a2e \ + --hash=sha256:d9b4f5430bf4f05d4c0dc4c55c75def3a5af4be0343be20fa2bfc577343fbfc9 \ + --hash=sha256:e6495b00cad16888384119842797c49316a96ae1cb132bb03856d980d95afee1 \ + --hash=sha256:ea58ff5b0880593a280cf5511734b17711b32ee1f58b47d726e8600848358160 \ + --hash=sha256:ef461bca07313412dc09961c4a4757a851f56b95ac01c58fac6007632b7b94f2 \ + --hash=sha256:fc85a5dbcbe6eccac1113c72370d1d3aacfdd49198d63950bdf7d8638a307f00 # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ --hash=sha256:3b41e1b601234296b4fb368338fdcd3e13e0b4fb5b67345948f4f2bf9868b286 # via kubernetes -fastapi==0.135.3 \ - --hash=sha256:9b0f590c813acd13d0ab43dd8494138eb58e484bfac405db1f3187cfc5810d98 \ - --hash=sha256:bd6d7caf1a2bdd8d676843cdcd2287729572a1ef524fc4d65c17ae002a1be654 +fastapi==0.136.1 \ + --hash=sha256:7af665ad7acfa0a3baf8983d393b6b471b9da10ede59c60045f49fbc89a0fa7f \ + --hash=sha256:a6e9d7eeada96c93a4d69cb03836b44fa34e2854accb7244a1ece36cd4781c3f # via # feast (pyproject.toml) # fastapi-mcp @@ -642,9 +642,9 @@ fastapi-mcp==0.4.0 \ --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d # via feast (pyproject.toml) -filelock==3.25.2 \ - --hash=sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694 \ - --hash=sha256:ca8afb0da15f229774c9ad1b455ed96e85a81373065fb10446672f64444ddf70 +filelock==3.29.0 \ + --hash=sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90 \ + --hash=sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258 # via snowflake-connector-python flit-core==3.12.0 \ --hash=sha256:18f63100d6f94385c6ed57a72073443e1a71a4acb4339491615d0f16d6ff01b2 \ @@ -790,9 +790,9 @@ fsspec==2024.9.0 \ # via # feast (pyproject.toml) # dask -google-api-core[grpc]==2.30.2 \ - --hash=sha256:9a8113e1a88bdc09a7ff629707f2214d98d61c7f6ceb0ea38c42a095d02dc0f9 \ - --hash=sha256:a4c226766d6af2580577db1f1a51bf53cd262f722b49731ce7414c43068a9594 +google-api-core[grpc]==2.30.3 \ + --hash=sha256:a85761ba72c444dad5d611c2220633480b2b6be2521eca69cca2dbb3ffd6bfe8 \ + --hash=sha256:e601a37f148585319b26db36e219df68c5d07b6382cff2d580e83404e44d641b # via # feast (pyproject.toml) # google-cloud-bigquery @@ -802,9 +802,9 @@ google-api-core[grpc]==2.30.2 \ # google-cloud-datastore # google-cloud-storage # pandas-gbq -google-auth==2.49.1 \ - --hash=sha256:16d40da1c3c5a0533f57d268fe72e0ebb0ae1cc3b567024122651c045d879b64 \ - --hash=sha256:195ebe3dca18eddd1b3db5edc5189b76c13e96f29e73043b923ebcf3f1a860f7 +google-auth==2.50.0 \ + --hash=sha256:04382175e28b94f49694977f0a792688b59a668def1499e9d8de996dc9ce5b15 \ + --hash=sha256:f35eafb191195328e8ce10a7883970877e7aeb49c2bfaa54aa0e394316d353d0 # via # google-api-core # google-auth-oauthlib @@ -904,60 +904,66 @@ googleapis-common-protos[grpc]==1.74.0 \ # 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.0 \ + --hash=sha256:0ecec963079cd58cbd14723582384f11f166fd58883c15dcbfb342e0bc9b5846 \ + --hash=sha256:0ed006e4b86c59de7467eb2601cd1b77b5a7d657d1ee55e30fe30d76451edba4 \ + --hash=sha256:0ff251e9a0279522e62f6176412869395a64ddf2b5c5f782ff609a8216a4e662 \ + --hash=sha256:1aa4ce8debcd4ea7fb2e150f3036588c41493d1d52c43538924ae1819003f4ce \ + --hash=sha256:1bae92a1dd94c5f9d9493c3a212dd874c202442047cf96446412c862feca83a2 \ + --hash=sha256:1eb67d5adefb5bd2e182d42678a328979a209e4e82eb93575708185d31d1f588 \ + --hash=sha256:2094acd54b272cb6eae8c03dd87b3fa1820a4cef18d6889c378d503500a1dc13 \ + --hash=sha256:2628d6c86f6cb0cb45e0c3c54058bbec559f57eaae699447748cb3928150577e \ + --hash=sha256:29ea813b2e1f45fa9649a17853b2b5465c4072fbcb072e5af6cd3a288216574a \ + --hash=sha256:362624e6a8e5bca3b8233e45eef33903a100e9539a2b995c364d595dbc4018b3 \ + --hash=sha256:3a717fbc46d8a354fa675f7c1e813485b6ba3885f9bef0cd56e5ba27d758ff5b \ + --hash=sha256:3bc59be3945ae9750b9e7d45067d01ae3fe90ea5f9ade99239dabdd6e28a5033 \ + --hash=sha256:3ec9ea74e7268ace7f9aab1b1a4e730193fc661b39a993cd91c606c32d4a3628 \ + --hash=sha256:41353ec2ecedf7aa8f682753a41919f8718031a6edac46b8d3dc7ed9e1ceb136 \ + --hash=sha256:47422135b1d308c14b2c6e758beedb1acd33bb91679f5670edf77bf46244722b \ + --hash=sha256:4964101b8585c144cbda5532b1aa644255126c08a265dae90c16e7a0e63aaa9d \ + --hash=sha256:4a448128607be0de65342dc9b31be7f948ef4cc0bc8832069350abefd310a8f2 \ + --hash=sha256:4b28037cb07768933c54d81bfe47a85f9f402f57d7d69743b991a713b63954eb \ + --hash=sha256:4d0eadc7e4d9ffb2af4247b606cae307be8e448911e5a0d0b16d72fc3d224cfd \ + --hash=sha256:54d243512da35485fc7a6bf3c178fdda6327a9d6506fcdd62b1abd1e41b2927b \ + --hash=sha256:55fa7ea52771be44af0de27d8b80c02cd18c2c3cddde6c847ecebdf72418b6a1 \ + --hash=sha256:57a43c6079a89713522bc4bcb9f75070ecf5d3dbad7792bfe42239362cbf2a16 \ + --hash=sha256:58c1c374fe2b3d852f9b6b11a7dff4c85404e51b9a596fd9e89cf904eb09866d \ + --hash=sha256:5a5ed18de6a0f6cc7087f1563f6bd93fc7df1c19165ca01e9bde5a5dc281d106 \ + --hash=sha256:5e05ba267789ea87b5a155cf0e810b1ab88bf18e9e8740813945ceb8ee4350ba \ + --hash=sha256:5ecd83806b0f4c2f53b1018e0005cd82269ea01d42befc0368730028d850ed1c \ + --hash=sha256:64d6ac45f7271f48e45f67c95b54ef73534c52ec041fcda8edf520c6d811f4bc \ + --hash=sha256:680bd0e7ad5e8daa8a4aa89f68fd6adc834b8a8036dc256533f7e08f4a4b01f7 \ + --hash=sha256:6c18dfb59c70f5a94acd271c72e90128c3c776e41e5f07767908c8c1b74ad339 \ + --hash=sha256:6d874e79afd41a96e11ff4c5d0bc90a80973e476fda1c2c64985667397df432b \ + --hash=sha256:7022615368890680e67b9965d33f5773aade330d5343bbe25560135aaa849eae \ + --hash=sha256:703cb211b820dbffbbc55a16bfc6e4583a6e6e990f33a119d2cc8b83211119c8 \ + --hash=sha256:728a73687e39ae9ca34e4694cbf2f049d3fbc7174639468d0f67200a97d8f9e2 \ + --hash=sha256:728d9667d8f2f586644b748dbd9bb67e50d6a9381767d1357714ea6825bb3bf5 \ + --hash=sha256:762612baf1161ccb8437c0161c668a688223cba28e1bf038f4eb47b13e39ccdf \ + --hash=sha256:7fc391b1566f2907d17aaebe78f8855dc45675159a775fcf9e61f8ee0078e87f \ + --hash=sha256:804a70b328e706b785c6ef16187051c394a63dd1a906d89be24b6ad77759f13f \ + --hash=sha256:83ed9f27f1680b50e89f40f6df348a290ea234b249a4003d366663a12eab94f2 \ + --hash=sha256:884f649de075b84739713d41dd4dfd41e2b910bfb769c4a3ea02ec1da52cd9bb \ + --hash=sha256:8f1cc966c126639cd152fdaa52624d2655f492faa79e013fea161de3e6dda082 \ + --hash=sha256:8f52a464e4ed91780bdfbbdd2b97197f3accaa629b98c200f4dffada759f3ae7 \ + --hash=sha256:9c615f869163e14bb1ced20322d8038fb680b08236521ac3f30cd4c1288785a0 \ + --hash=sha256:9d280a7f5c331622c69f97eb167f33577ff2d1df282c41cd15907fc0a3ca198c \ + --hash=sha256:a10a732421ab4fec934783ce3e54763470d0181db6e3468f9103a275c3ed1853 \ + --hash=sha256:a96fcee45e03fe30a62669fd16ab5c9d3c172660d3085605cb1e2d1280d3c988 \ + --hash=sha256:a97e4821aa710603f94de0da25f25096454d78ffdace5dc77f3a006bc01abba3 \ + --hash=sha256:ba8f0bdc2fae6ce915dfd0c16d2d00bca7e4247c1eae4416e06430e522137858 \ + --hash=sha256:bf2d8a80bec89ab46221ae45c5373d5ba0bd36c19aa8508e85c6cd7e5106cd37 \ + --hash=sha256:cda05425526240807408156b6960a17a79a0c760b813573b67027823be760977 \ + --hash=sha256:d419647372241bc68e957bf38d5c1f98852155e4146bd1e4121adea81f4f01e4 \ + --hash=sha256:d4d9f0624c775f2dfc56ba54d515a8c771044346852a918b405914f6b19d7fd8 \ + --hash=sha256:d60097128cb0a1cab9ea541186ea13cd7b847b8449a7787c2e2350da0cb82d86 \ + --hash=sha256:db2910d3c809444e0a20147361f343fe2798e106af8d9d8506f5305302655a9f \ + --hash=sha256:ddb36c7d6c9c0a65f18c7258634e0c416c6ab59caac8c987b96f80c2ebda0112 \ + --hash=sha256:ddc090c5c1792b10246a78e8c2163ebbe04cf877f9d785c230a7b27b39ad038e \ + --hash=sha256:e5ddf316ced87539144621453c3aef229575825fe60c604e62bedc4003f372b2 \ + --hash=sha256:f35807464c4c58c55f0d31dfa83c541a5615d825c2fe3d2b95360cf7c4e3c0a8 \ + --hash=sha256:f8c30c2225f40dd76c50790f0eb3b5c7c18431efb299e2782083e1981feed243 \ + --hash=sha256:fa94cb2288681e3a11645958f1871d48ee9211bd2f66628fdace505927d6e564 # via feast (pyproject.toml) grpc-google-iam-v1==0.14.4 \ --hash=sha256:392b3796947ed6334e61171d9ab06bf7eb357f554e5fc7556ad7aab6d0e17038 \ @@ -1069,101 +1075,112 @@ hatchling==1.29.0 \ # 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.3.1 \ + --hash=sha256:002fc0201b9af1cc8960e27cdc501ad1f8cdd6dbadb2091c6ddbd4e5ace6cb77 \ + --hash=sha256:011a9071c3df4885cac7f58a2623feac6c8e2ad30e6ba93c55195af05ce61ff5 \ + --hash=sha256:01cf82a514bc4fd145b99333c28523e61b7a9ad051a245804323ebf4e7b1c6a6 \ + --hash=sha256:027ce4fabfeff5af5b9869d5524770877f9061d118bc36b85703ae3faf5aad8e \ + --hash=sha256:03baa381964b8df356d19ec4e3a6ae656044249a87b0def257fe1e08dbaf6094 \ + --hash=sha256:042e57de8a2cae91e3e7c0af32960ea2c5107b2f27f68a740295861e68780a8a \ + --hash=sha256:09d41a3a965f7c261223d516ebda607aee4d8440dd7637f01af9a4c05872f0c4 \ + --hash=sha256:09f5e510f637f2c72d2a79fb3ad05f7b6211e057e367ca5c4f97bb3d8c9d71f4 \ + --hash=sha256:0b5ff2f643f4b452b0597b7fe6aa35d398cb31d8806801acfafb1558610ea2aa \ + --hash=sha256:0caf3fc8af0767794b335753781c3fa35f2a3e975c098edbc8f733d35d6a95e4 \ + --hash=sha256:0fac4af8515e6cca74fc701169ae4dc9a71a90e9319c9d21006ec9454b43aa2f \ + --hash=sha256:113e098e4a6b3cc5500e05e7cb1548ba9e83de5fe755941b11f6020a76e6c03a \ + --hash=sha256:137c14905ea6f2933967200bc7b2a0c8ec9387888b273fd0004f25b994fd0343 \ + --hash=sha256:156be6a0c736ee145cfe0fb155d0e96cec8d4872cf8b4f76ad6a2ee6ab391d0a \ + --hash=sha256:17ec8b524055a88b80d76c177dbbbe475a25c17c5bf4b67bdbdbd0629bcae838 \ + --hash=sha256:1ac7697365dbe45109273b34227fee6826b276ead9a4a007e0877e1d3f0fcf21 \ + --hash=sha256:1b46e96b50dad03495447860510daebd2c96fd44ed25ba8ccb03e9f89eaa9d34 \ + --hash=sha256:1ebc307a87b099d0877dbd2bdc0bae427258e7ec67f60a951e89027f8dc2568f \ + --hash=sha256:1f7bceb03a1b934872ffe3942eaeed7c7e09096e67b53f095b81f39c7a819113 \ + --hash=sha256:2611bfaaadc5e8d43fb7967f9bbf1110c8beaa83aee2f2d812c76f11cfb56c6a \ + --hash=sha256:264ee7e9cb6c30dc78da4ecf71d74cf14ca122817c665d838eda8b4384bce1b0 \ + --hash=sha256:26f899cde0279e4b7d370716ff80320601c2bd93cdf3e774a42bdd44f65b41f8 \ + --hash=sha256:29fe35e3c6fe03204e75c86514f452591957a1e06b05d86e10d795455b71c355 \ + --hash=sha256:2afc675b831f7552da41116fffffca4340f387dc03f56d6ec0c7895ab0b59a10 \ + --hash=sha256:2b6da6e07359107c653a809b3cff2d9ccaeedbafe33c6f16434aef6f53ce4a2b \ + --hash=sha256:2b96da7e365d6488d2a75266a662cbe3cc14b28c23dd9b0c9aa04b5bc5c20192 \ + --hash=sha256:2f1c1b2e8f00b71e6214234d313f655a3a27cd4384b054126ce04073c1d47045 \ + --hash=sha256:304481241e081bc26f0778b2c2b99f9c43917e4e724a016dcc9439b7ab12c726 \ + --hash=sha256:318f772dd321404075d406825266e574ee0f4751be1831424c2ebd5722609398 \ + --hash=sha256:3586c8a5f56d34b9dddaaa9e76905f31933cac267251006adf86ec0eef7d0400 \ + --hash=sha256:3724f0e58c6ff76fd683429945491de71324ab1bc0ad943a8d68cb0932d24075 \ + --hash=sha256:3fb6573efa15a29c12c0c0f7170b14e7c1347fe4bb39b6a15b779f46015cc929 \ + --hash=sha256:40ae8a7041fcb328a6bc7202d8c4e6e0d38d434b2e3880b1ee8ed754f17cd836 \ + --hash=sha256:4106201cd052d9eabe3cb7b5a24b0fe37307792bda4fcb3cf6ddd72f697828e8 \ + --hash=sha256:439f9a5cc8f9519ce208a24cdebfa0440fef26aa682a40ba2c92acb10a53f5e0 \ + --hash=sha256:4479e36d263251dba8ab8ea81adf07e7f1163603c7102c5de1e130b83b4fad3b \ + --hash=sha256:487658e1db83c1ee9fbbac6a43039ea76957767a5987ffb16b590613f9e68297 \ + --hash=sha256:48ff424f8aa36aacd9fdaa68efeb27d2e8771f293af4305bdb15d92194ca6631 \ + --hash=sha256:4f7e242eab698ad0be5a4b2ec616fa856569c57455cc67c625fd567726290e5f \ + --hash=sha256:526db52e5234a9463520e960a509d6c1bd5128d1ab1b569cbf459fe39189e8ab \ + --hash=sha256:52d5641027d6731bc7b5e7d126a5158a99784a9f8c6de3d97ca89aca4969e9f8 \ + --hash=sha256:53148a4e21057541b6d8e493b2ea1b500037ddf34433c391970036f3cbce00e3 \ + --hash=sha256:583de2f16528e66081cbdfe510d8488c2de73039dc00aada7d22bd49d73a4a94 \ + --hash=sha256:5e55d90b431b0c6b64ae5a624208d4aea318566d31872e595ee723c0f5b9a79f \ + --hash=sha256:5f316cf2d0558f5027aab19dde7d7e4901c26c21fa95367bc37784e8f547bbf2 \ + --hash=sha256:60543f3b068b16a86e99ed96b7fdae71cdc1d8abdfe9b3f82032a555e52ece7e \ + --hash=sha256:62cc62284541bb2a86c898c7d5e8388661cade91c184cb862095ed547e80588f \ + --hash=sha256:65c05b79cb8366c123357b354a16f9fc3f7187159422f143638d1c26b7240ed4 \ + --hash=sha256:65f6ac06a9f0c32c254660ec6a9329d81d589e8f5d0a9837a941d5424a6be1ef \ + --hash=sha256:6d1434d0bcc1b3ef048bae53f26456405c08aeed9827e65b24094f5f3a6793f1 \ + --hash=sha256:6e2e1024f0a021777740cb7c633a0efb2c4a4bc570f508223a8dcbcf79f99ef9 \ + --hash=sha256:6ffa7ba2e2da1f806f3181b9730b3e87ba9dbfec884806725d4584055ba3faa6 \ + --hash=sha256:743b85bd6902856cac457ddd8cd7dd48c89c47d641b6016ff5e4d015bfbd4799 \ + --hash=sha256:77c5d2bebbc9d06691abb512a31d0f54e1562af0b872891463a67a949b5278ef \ + --hash=sha256:79cd03e7ff550c17758a7520bf437c156d3d4c8bb74214deeafa69cda49c85a4 \ + --hash=sha256:80aba5f85d6227faee628ae28d1c3b69c661806a0636548ac56c68782606454f \ + --hash=sha256:81a1669b6631976b1dc9d3d58ed1ab3333e9f52feb91a2a1fb8241101ac3b665 \ + --hash=sha256:8597c35c9e82f65fd5897c4a2188c65d7daf10607b102960137b23d261cd957b \ + --hash=sha256:8650158217b469d8b6087f490929211b0493a9121154c4efaafd1dec9e19319e \ + --hash=sha256:8887bf0f31e4b550bd988c8863b527b6587d200653e9375cd91eea2b944b7424 \ + --hash=sha256:8a52b24cd710690c4a7e191c7e300136ad2ecb3c68ffe7e95b598e76de166e5e \ + --hash=sha256:8e3754ce60e1b11b0afad9a053481ff184d2ee24bea47099107156d1b84a84aa \ + --hash=sha256:907f7b5501a534030738f0f27459a612d2266fd0507b007bb8f3e6de08167920 \ + --hash=sha256:90d6b9f2652303aefd2c5a26a5e14cb74a3a63d10faa642c08d790e99442a088 \ + --hash=sha256:98fd5b39410e9d69e10e90d0330e35650becaa5dd2548f509b9598f1f3c6124d \ + --hash=sha256:9bfdeff778d3f7ff449ca5922ab773899e7d31e26a576028b06a5e9cf0ed8c34 \ + --hash=sha256:9ebae74ce2b977c2fcb22d6a10aa0acb730022406977b2bcb6ddd6788f5c414a \ + --hash=sha256:a110d19881ca78a88583d3b07231e7c6864864f5f1f3491b638863ea45fa8708 \ + --hash=sha256:a1d190790ee39b8b7adeeb10fc4090dc4859eb4e75ed27bd8108710eef18f358 \ + --hash=sha256:a2f049c3f3c83e886cd1f53958e2a1ebb369be626bef9e50d8b24d79864f1df6 \ + --hash=sha256:a3af4e9f277d6b8acd369dc44a723a055752fca9d045094383af39f90a3e3729 \ + --hash=sha256:a42c7becd4c9ec4ab5769c754eb61112777bdc6e1c1525e2077389e193b5f5aa \ + --hash=sha256:a58a58cef0d911b1717154179a9ff47852249c536ea5966bde4370b6b20638ff \ + --hash=sha256:ab1f646ff531d70bfd25f01e60708dfa3d105eb458b7dedd9fe9a443039fd809 \ + --hash=sha256:ad940dc2db545dc978cb41cb9a683e2ff328f3ef581230b9ca40ff6c3d01d542 \ + --hash=sha256:afe3c3863f16704fb5d7c2c6ff56aaf9e054f6d269f7b4c9074c5476178d1aba \ + --hash=sha256:b1e3b9f4bf9a4120510ba77a77b2fb674893cd6795653545152bb11a79eecfcb \ + --hash=sha256:b2390ad81c03d93ef1d5afd18ffcf5935de827f1a2b96b2c829437968bdabccb \ + --hash=sha256:b37df4b10cb15dedfc203f69312d8eedd617b941c21df58c13af59496c53ad0f \ + --hash=sha256:b3df9447f9209f9aa0434ca74050e9509670c1ad99398fe5807abb90e5f3a014 \ + --hash=sha256:b4fe7f38aa8956fcc1cea270e62601e0e11066aff78e384be70fd283d30293b6 \ + --hash=sha256:c1d68c6980d4690a4550bd3db6c03146f7be68ef5d08d38bb1fb68b3e9c32fe3 \ + --hash=sha256:c24c1460486b6b36083252c2db21a814becf8495ccd0e76b7286623e37239b63 \ + --hash=sha256:c25132902d3eff38781e0d54f27a0942ec849e3c07dbdce83c4d92b7e43c8dce \ + --hash=sha256:c74bd9926954e7e575f9cd9890f63defd90cd8f812dfbf8e1efb72acc9355456 \ + --hash=sha256:c8139e9011117822391c5bcfd674c5948fb1e4b8cb9adf6f13d9890859ee3a1a \ + --hash=sha256:ce334915f5d31048f76a42c607bf26687cf045eb1bc852b7340f09729c6a64fc \ + --hash=sha256:d14229beaa76e66c3a25f9477d973336441ca820df853679a98796256813316f \ + --hash=sha256:d42f3a13290f89191568fc113d95a3d2c8759cdd8c3672f021d8b7436f909e75 \ + --hash=sha256:d8e56e0d1fe607bfff422633f313aec9191c3859ab99d11ff097e3e6e068000c \ + --hash=sha256:da6f0302360e99d32bc2869772692797ebadd536e1b826d0103c72ba49d38698 \ + --hash=sha256:db46baf157feefd88724e6a7f145fe996a5990a8604ed9292b45d563360e513b \ + --hash=sha256:dcea8c3f53674ae68e44b12e853b844a1d315250ca6677b11ec0c06aff85e86c \ + --hash=sha256:de94b409f49eb6a588ebdd5872e826caec417cd77c17af0fb94f2128427f1a2a \ + --hash=sha256:e0356561b4a97c83b9ee3de657a41b8d1a1781226853adaf47b550bb988fda6f \ + --hash=sha256:e0db44cf81e4d7b94f3776b9f89111f74ed6bbdbfd42a22bc4a5ce0644d3e060 \ + --hash=sha256:e31e92b61d56244047ad600812e16f7587a6172f74810fd919ff993af12b9149 \ + --hash=sha256:e89dabf436ee79b358fd970dcbed6333a36d91db73f27069ca24a02fb138a404 \ + --hash=sha256:eddeb9a153795cf6e615f9f3cef66a1d573ff3b6ee16df2b10d1d1c2f2baeaa8 \ + --hash=sha256:ee11fd431f83d8a5b29d370b9d79a814d3218d30113bdcd44657e9bdf715fc92 \ + --hash=sha256:ee37fe8cf081b72dea72f96a0ee604f492ec02252eb77dc26ff6eec3f997b580 \ + --hash=sha256:f19ee7dc1ef8a6497570d91fa4057ba910ad98297a50b8c44ff37589f7c89d17 \ + --hash=sha256:f2f94355affd51088f57f8674b0e294704c3c7c3d7d3b1545310f5b135d4843b \ + --hash=sha256:f525734382a47f9828c9d6a1501522c78d5935466d8e2be1a41ba40ca5bb922b \ + --hash=sha256:f915a34fb742e23d0d61573349aa45d6f74037fde9d58a9f340435eff8d62736 # via feast (pyproject.toml) httpcore==1.0.9 \ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ @@ -1228,9 +1245,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.13 \ + --hash=sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242 \ + --hash=sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 # via # anyio # httpx @@ -1272,97 +1289,97 @@ kubernetes==35.0.0 \ --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee # 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.9.0 \ + --hash=sha256:07cf11f769831186eeac424376e6189f20ace4f7263e2134bdb9757340d84d4d \ + --hash=sha256:0a09c2f5869649101738653a9b7ab70cf045a1105ac66cbb8f4055e61df78f2d \ + --hash=sha256:0a1be03168b2691ba61927e299b352a6315189199ca18a57b733f86cb3cc8d38 \ + --hash=sha256:0b73e4266307e51c95e09c0750b7ec383c561d2e97d58e473f6f6a209952fbb8 \ + --hash=sha256:15cb151e52a044f06e54ac7f7b47adbfc89b5c8e2b63e1175a9d587c43e8942a \ + --hash=sha256:194fc1a32e1e21fe809d38b5faea66cc65eaa00217c8901fbdb99866938adbdb \ + --hash=sha256:1bf465d1e5b0a27713862441f6467b5ab76385f4ecf8f1f3a44f8aa3c695b4b6 \ + --hash=sha256:1c587494461ebd42229d0f1739f3aa34237dd9980623ecf1be8d3bcba79f4499 \ + --hash=sha256:224b9727eb8bc188bc3bcf29d969dba0cd61b01d9bac80c41575520cc4baabb2 \ + --hash=sha256:22a904cbdb678f7cb348c90d543d3c52f581663d687992fee47fd566dcbf5285 \ + --hash=sha256:2b8f5d00b49818f4e2b1667db994488b045835e0ac16fe2f924f3871bd2b8ac5 \ + --hash=sha256:2c3786f0f4490a5cd87f1ed6cefae833ad6b1060d52044ce0434a2e85893afd0 \ + --hash=sha256:2d03fa4fd277a7974c1978c92c374c57f44edeee163d147b477b143446ad1bf6 \ + --hash=sha256:2f8e12706dcb8ff6b3ed57514a19e45c49ad00bcd423e87b2b2e4b5f64578443 \ + --hash=sha256:3be322a15ee5e70b93b7a59cfd074614f22cc8c9ff18bd27f474e79137ea8d3b \ + --hash=sha256:3cc2917258e131ae5f958a4d872e07555b51cb7466a43433218061c74ef33745 \ + --hash=sha256:3f05d145df35dca5056a8bc3838e940efebd893a54b3e19b2dda39ceaa299bcb \ + --hash=sha256:3fe56e80badb66fdcde06bef81bbaa5bfcf6fbd7aefb86222d9e369c38c6b228 \ + --hash=sha256:42ff8a962554c350d4a83cf47d9b7b78b0e6ff7943e87df7cdfc97c07f3c016f \ + --hash=sha256:451daa98463b7695b0a30aa56bf637831ea559e7b8101ac2ef6382e8eb15e29c \ + --hash=sha256:465814ab157986acb9dfa5ccd7df944be5eefc0d08d31ec6e8d88bc71251d845 \ + --hash=sha256:4c4d0440a3a8e31d962340c3e1cc3fc9ee7febd34c8d8f770d06adb947779ea5 \ + --hash=sha256:4e3dda8345307fd7306db0ed0cb109a63a2c85ba780eb9dc2d09b2049a931f9c \ + --hash=sha256:5093043afb226ecfa1400120d1ebd4442b4f99977783e4f4f7248879009b227f \ + --hash=sha256:5112c2fb7c2eefefaeaf5c97fec81343ef44ee86a30dcfaa8223822fba6467b4 \ + --hash=sha256:527b5b820b47a09e09829051452bb0d1dd2122261254e2a6f674d12f1d793d54 \ + --hash=sha256:54d412e47c21b85865676ed0724e37a89e9593c2eee1e7367adf85bfad56ffb1 \ + --hash=sha256:56d65b583cf43b8cf4c8fbe1e1da20fa3076cc32a1149a141507af1062718236 \ + --hash=sha256:5ca8e133d799c948db2ab1afc081c333a825b5540475164726dcbf73537e5c2f \ + --hash=sha256:603138ee838ee1583f1b960b62d5d0007845c5c423feb68e44648b1359014e27 \ + --hash=sha256:63c12efcd160e1d14da11af0c46c0217473e1e0d2ae1acbccc83f561ea4c2a7b \ + --hash=sha256:657f8ba7b9eaaa82759a104137aed2a3ef7bc46ccfd43e0d89b04005b3e0a4cc \ + --hash=sha256:66b58fed90a545328e80d575467244de3741e088c1af928f0b489ebec3ef3858 \ + --hash=sha256:6788207daa0c19955d2b668f3294a368d19f67d9b5f274553fd073c1260cbb9f \ + --hash=sha256:703f4ae36d6240bfe24f542bac784c7e4194ec49c3ba5a994d02891649e2d85b \ + --hash=sha256:7202bdcac47d3a708271c4304a474a8605a4a9a4a709e954bf2d3241140aa938 \ + --hash=sha256:756775d25ec8345b837ab52effee3ad2f3b2dfd6bbee3e3f029c517bd5d8f05a \ + --hash=sha256:78042f6facfd98ecb25e9829c7e37cce23363d9d7c83bc5f72702c5059eb082b \ + --hash=sha256:789fff71757facc0738e8d89e3b84e4f0251c1c975e85e81b152cdaca927cc2d \ + --hash=sha256:7bc30ad339f4e1a01d4917d645e522a0bc0030644d8973f6346397c93ba1503f \ + --hash=sha256:7d429bdd4ac0ab17c8e4a8af0ed2a7440b16eba474909ab357131018fe8c7e71 \ + --hash=sha256:7d5c8a5929ac325729f6119802070b561f4db793dffc45e9ac750992a4ed4d22 \ + --hash=sha256:7e6274fd33fc5b2a14d41c9119629d3ff395849d8bcbc80cf637d9e8d2034da8 \ + --hash=sha256:80b25c7b570a86c03b5da69e665809deb39265476e8e21d96a9328f9762f9990 \ + --hash=sha256:81107843ed1836874b46b310f9b1816abcb89912af627868522461c3b7333c0f \ + --hash=sha256:8494cfc61e03542f2d381e71804990b3931175a29b9278fdb4a5459948778dc2 \ + --hash=sha256:850d6d03177e52700af605fd60db7f37dcb89782049a149674d1a9649c2138fd \ + --hash=sha256:8c6bc1384d9738781cfd41d09ad7f6e8af13cfea2c75ece6bd6d2566cdea2076 \ + --hash=sha256:90904fac73c478f4b83f4ed96c99c8208b75e6f9a8a1910548f69a00f1eaa671 \ + --hash=sha256:90e6d5420fc8a300518d4d2288154ff45005e920425c22cbbfe8330f3f754bd9 \ + --hash=sha256:928bd06eca2c2bbf4349e5b817f837509b0604342e65a502de1d50a7570afd15 \ + --hash=sha256:9b3e3bc363f71bda1639a4ee593cb78f7fbfeacc73411ec0d4c92f00730010a4 \ + --hash=sha256:9edcc35d1cae9fd5320171b1a838c7da8a5c968af31e82ecc3dff30b4be0957f \ + --hash=sha256:9fcb461fbf70654a52a7cc670e606f04449e2374c199b1825f754e16dacfedd8 \ + --hash=sha256:a0951822531e7aee6e0dfb556b30d5ee36bbe234faf60c20a16c01be3530869d \ + --hash=sha256:a361c9434a64d70a7dbb771d1de302c0cc9f13c0bffe1cf7e642152814b35265 \ + --hash=sha256:a4b25c6c25cac5d0d9d6d6da855195b254e0021e513e0249f0e3b444dc6e0e61 \ + --hash=sha256:a5af136bfba820d592f86c67affcef9b3ff4d4360ac3255e341e964489b48519 \ + --hash=sha256:a81eea9b999b985e4bacc650c4312805ea7008fd5e45e1bf221310176a7bcb3a \ + --hash=sha256:a9c63e04d003bc0fb6a03b348018b9a3002f98268200e22cc80f146beac5dc40 \ + --hash=sha256:aa95738a68cedd3a6f5492feddc513e2e166b50602958139e47bbdd82da0f5a7 \ + --hash=sha256:b0a2040f801406b93657a70b72fa12311063a319fee72ce98e1524da7200171f \ + --hash=sha256:b8bd70d5d816566a580d193326912f4a76ec2d28a97dc4cd4cc831c0af8e330e \ + --hash=sha256:b8da9f8035bb417770b1e1610526d87ad4fc58a2804dc4d79c53f6d2cf5a6eb9 \ + --hash=sha256:bc5518873822d2faa8ebdd2c1a4d7c8ef47b01a058495ab7924cb65bdbf5fc9a \ + --hash=sha256:c0d620e74897f8c2613b3c4e2e9c1e422eb46d2ddd07df540784d44117836af3 \ + --hash=sha256:c2640e23d2b7c98796f123ffd95cf2022c7777aa8a4a3b98b36c570d37e85eee \ + --hash=sha256:c81aef782380f0f13ead670aae01825eb653b44b046aa0e5ebbb79f76ed4aa11 \ + --hash=sha256:d4d16b608a1c43d7e33142099a75cd93af482dadce0bf82421e91cad077157f4 \ + --hash=sha256:d69fc39e627908f4c03297d5a88d9284b73f4d90b424461e32e8c2485e21c283 \ + --hash=sha256:d9da80e5b04acce03ced8ba6479a71c2a2edf535c2acc0d09c80d2f80f3bad15 \ + --hash=sha256:dd2c7e082b0b92e1baa4da28163a808672485617bc855cc22a2fd06978fa9084 \ + --hash=sha256:de7dac64e3eb832ffc7b840eb8f52f76420cde1b845be51b2a0f6b870890645e \ + --hash=sha256:e0785c2fb4a81e1aece366aa3e2e039f4a4d7d21aaaded5227d7f3c703427882 \ + --hash=sha256:e306d956cfa027fe041585f02a1602c32bfa6bb8ebea4899d373383295a6c62f \ + --hash=sha256:e78fb7419e07d98c2af4b8567b72b3eaf8cb05caad642e9963465569c8b2d87e \ + --hash=sha256:e9002e98dcb1c0a66723592520decd86238ddcef168b37ff6cfb559200b4b774 \ + --hash=sha256:e94cbc6ad9a6aeea46d775cbb11f361022f778a9cc8cc90af653d3a594b057ce \ + --hash=sha256:eea1b54943475f51698f85fa230c65ccac769f1e603b981be060ac5763d90927 \ + --hash=sha256:f100bfe2acf8a3689af9d0cc660d89f17286c9c795f9f18f7b62dd1a6b247ae6 \ + --hash=sha256:f162af66a2ed3f7d1d161a82ca584efd15acd9c1cff190a373458c32f7d42118 \ + --hash=sha256:f24b90b0e0c8cc9491fb1693ae91fe17cb7963153a1946395acdbdd5818429a4 \ + --hash=sha256:f29b68cd9714531672db62cc54f6e8ff981900f824d13fa0e00749189e13778e \ + --hash=sha256:f38bc489037eca88d6ebefc9c4d41a4e07c8e8b4de5188a9e6d290273ad7ebb1 \ + --hash=sha256:f3fd278f5e6bf7c75ccd6d12344eb686cc020712683363b66f46ac79d37c799f \ + --hash=sha256:f4003f70c56a5addd6aa0897f200dd59afd3bf7bcd5b3cce46dd21f925743bc2 \ + --hash=sha256:f48c963a76d71b9d7927eb817b543d0dccd52ab6648b99d37bd54f4cd475d856 \ + --hash=sha256:f819e0c6413e259a17a7c0d49f97f405abadd3c2a316a3b46c6440b7dbbedbb1 \ + --hash=sha256:fc5758e2b7a56532dc33e3c544d78cbaa9ecf0a0f2a2da2df882c1d6b99a317f \ + --hash=sha256:fcbdf2a9ca24e87bbebb47f1fe34e531ef06f104f98c9ccfc953a3f3344c567a # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ @@ -1741,51 +1758,51 @@ multidict==6.7.1 \ # aiobotocore # aiohttp # yarl -mypy==1.20.0 \ - --hash=sha256:002b613ae19f4ac7d18b7e168ffe1cb9013b37c57f7411984abbd3b817b0a214 \ - --hash=sha256:00e047c74d3ec6e71a2eb88e9ea551a2edb90c21f993aefa9e0d2a898e0bb732 \ - --hash=sha256:02cca0761c75b42a20a2757ae58713276605eb29a08dd8a6e092aa347c4115ca \ - --hash=sha256:0ecd63f75fdd30327e4ad8b5704bd6d91fc6c1b2e029f8ee14705e1207212489 \ - --hash=sha256:0f42dfaab7ec1baff3b383ad7af562ab0de573c5f6edb44b2dab016082b89948 \ - --hash=sha256:1973868d2adbb4584a3835780b27436f06d1dc606af5be09f187aaa25be1070f \ - --hash=sha256:26c8b52627b6552f47ff11adb4e1509605f094e29815323e487fc0053ebe93d1 \ - --hash=sha256:2721f0ce49cb74a38f00c50da67cb7d36317b5eda38877a49614dc018e91c787 \ - --hash=sha256:2fcedb16d456106e545b2bfd7ef9d24e70b38ec252d2a629823a4d07ebcdb69e \ - --hash=sha256:31b5dbb55293c1bd27c0fc813a0d2bb5ceef9d65ac5afa2e58f829dab7921fd5 \ - --hash=sha256:34506397dbf40c15dc567635d18a21d33827e9ab29014fb83d292a8f4f8953b6 \ - --hash=sha256:367e5c993ba34d5054d11937d0485ad6dfc60ba760fa326c01090fc256adf15c \ - --hash=sha256:379edf079ce44ac8d2805bcf9b3dd7340d4f97aad3a5e0ebabbf9d125b84b442 \ - --hash=sha256:39362cdb4ba5f916e7976fccecaab1ba3a83e35f60fa68b64e9a70e221bb2436 \ - --hash=sha256:4525e7010b1b38334516181c5b81e16180b8e149e6684cee5a727c78186b4e3b \ - --hash=sha256:47781555a7aa5fedcc2d16bcd72e0dc83eb272c10dd657f9fb3f9cc08e2e6abb \ - --hash=sha256:49d11c6f573a5a08f77fad13faff2139f6d0730ebed2cfa9b3d2702671dd7188 \ - --hash=sha256:555493c44a4f5a1b58d611a43333e71a9981c6dbe26270377b6f8174126a0526 \ - --hash=sha256:555658c611099455b2da507582ea20d2043dfdfe7f5ad0add472b1c6238b433f \ - --hash=sha256:697f102c5c1d526bdd761a69f17c6070f9892eebcb94b1a5963d679288c09e78 \ - --hash=sha256:76a70bf840495729be47510856b978f1b0ec7d08f257ca38c9d932720bf6b43e \ - --hash=sha256:7d3243c406773185144527f83be0e0aefc7bf4601b0b2b956665608bf7c98a83 \ - --hash=sha256:931a7630bba591593dcf6e97224a21ff80fb357e7982628d25e3c618e7f598ef \ - --hash=sha256:9804c3ad27f78e54e58b32e7cb532d128b43dbfb9f3f9f06262b821a0f6bd3f5 \ - --hash=sha256:a17c5d0bdcca61ce24a35beb828a2d0d323d3fcf387d7512206888c900193367 \ - --hash=sha256:a6e0641147cbfa7e4e94efdb95c2dab1aff8cfc159ded13e07f308ddccc8c48e \ - --hash=sha256:a79c1eba7ac4209f2d850f0edd0a2f8bba88cbfdfefe6fb76a19e9d4fe5e71a2 \ - --hash=sha256:a9336b5e6712f4adaf5afc3203a99a40b379049104349d747eb3e5a3aa23ac2e \ - --hash=sha256:b20c8b0fd5877abdf402e79a3af987053de07e6fb208c18df6659f708b535134 \ - --hash=sha256:b3a49064504be59e59da664c5e149edc1f26c67c4f8e8456f6ba6aba55033018 \ - --hash=sha256:b503ab55a836136b619b5fc21c8803d810c5b87551af8600b72eecafb0059cb0 \ - --hash=sha256:bd0212976dc57a5bfeede7c219e7cd66568a32c05c9129686dd487c059c1b88a \ - --hash=sha256:c70380fe5d64010f79fb863b9081c7004dd65225d2277333c219d93a10dad4dd \ - --hash=sha256:d99f515f95fd03a90875fdb2cca12ff074aa04490db4d190905851bdf8a549a8 \ - --hash=sha256:e80cf77847d0d3e6e3111b7b25db32a7f8762fd4b9a3a72ce53fe16a2863b281 \ - --hash=sha256:eb96c84efcc33f0b5e0e04beacf00129dd963b67226b01c00b9dfc8affb464c3 \ - --hash=sha256:ebea00201737ad4391142808ed16e875add5c17f676e0912b387739f84991e13 \ - --hash=sha256:efe8d70949c3023698c3fca1e94527e7e790a361ab8116f90d11221421cd8726 \ - --hash=sha256:f13b3e41bce9d257eded794c0f12878af3129d80aacd8a3ee0dee51f3a978651 \ - --hash=sha256:f194db59657c58593a3c47c6dfd7bad4ef4ac12dbc94d01b3a95521f78177e33 \ - --hash=sha256:f49590891d2c2f8a9de15614e32e459a794bcba84693c2394291a2038bbaaa69 \ - --hash=sha256:f75ff57defcd0f1d6e006d721ccdec6c88d4f6a7816eb92f1c4890d979d9ee62 \ - --hash=sha256:f799d9db89fc00446f03281f84a221e50018fc40113a3ba9864b132895619ebe \ - --hash=sha256:f8426d4d75d68714abc17a4292d922f6ba2cfb984b72c2278c437f6dae797865 +mypy==1.20.2 \ + --hash=sha256:0c64e5973df366b747646fc98da921f9d6eba9716d57d1db94a83c026a08e0fb \ + --hash=sha256:0deb80d062b2479f2c87ae568f89845afc71d11bc41b04179e58165fd9f31e98 \ + --hash=sha256:1e1c12f6d2db3d78b909b5f77513c11eb7f2dd2782b96a3ab6dffc7d44575c99 \ + --hash=sha256:20175a1c0f49863946ec20b7f63255768058ac4f07d2b9ded6a6b46cfb5a9100 \ + --hash=sha256:29752dbbf8cc53f89f6ac096d363314333045c257c9c75cbd189ca2de0455744 \ + --hash=sha256:2a4102b03bb7481d9a91a6da8d174740c9c8c4401024684b9ca3b7cc5e49852f \ + --hash=sha256:2de3dcea53babc1c3237a19002bc3d228ce1833278f093b8d619e06e7cc79609 \ + --hash=sha256:34397cdced6b90b836e38182076049fdb41424322e0b0728c946b0939ebdf9f6 \ + --hash=sha256:4077797a273e56e8843d001e9dfe4ba10e33323d6ade647ff260e5cd97d9758c \ + --hash=sha256:419413398fe250aae057fd2fe50166b61077083c9b82754c341cf4fd73038f30 \ + --hash=sha256:4b6481b228d072315b053210b01ac320e1be243dc17f9e5887ef167f23f5fae4 \ + --hash=sha256:4dbfcf869f6b0517f70cf0030ba6ea1d6645e132337a7d5204a18d8d5636c02b \ + --hash=sha256:4fef51b01e638974a6e69885687e9bd40c8d1e09a6cd291cca0619625cf1f558 \ + --hash=sha256:52b176444e2e5054dfcbcb8c75b0b719865c96247b37407184bbfca5c353f2c2 \ + --hash=sha256:56908d7e08318d39f85b1f0c6cfd47b0cac1a130da677630dac0de3e0623e102 \ + --hash=sha256:5a65aa591af023864fd08a97da9974e919452cfe19cb146c8a5dc692626445dc \ + --hash=sha256:688c3312e5dadb573a2c69c82af3a298d43ecf9e6d264e0f95df960b5f6ac19c \ + --hash=sha256:6e2b469efd811707bc530fd1effef0f5d6eebcb7fe376affae69025da4b979a2 \ + --hash=sha256:7488448de6007cd5177c6cea0517ac33b4c0f5ee9b5e9f2be51ce75511a85517 \ + --hash=sha256:785b08db19c9f214dc37d65f7c165d19a30fcecb48abfa30f31b01b5acaabb58 \ + --hash=sha256:7b0e817b518bff7facd7f85ea05b643ad8bdcce684cf29784987b0a7c8e1f997 \ + --hash=sha256:803203d2b6ea644982c644895c2f78b28d0e208bba7b27d9b921e0ec5eb207c6 \ + --hash=sha256:89dce27e142d25ffbc154c1819383b69f2e9234dc4ed4766f42e0e8cb264ab5c \ + --hash=sha256:913485a03f1bcf5d279409a9d2b9ed565c151f61c09f29991e5faa14033da4c8 \ + --hash=sha256:97d7b9a485b40f8ca425460e89bf1da2814625b2da627c0dcc6aa46c92631d14 \ + --hash=sha256:9bcb8aa397ff0093c824182fd76a935a9ba7ad097fcbef80ae89bf6c1731d8ec \ + --hash=sha256:9d56a78b646f2e3daa865bc70cd5ec5a46c50045801ca8ff17a0c43abc97e3ee \ + --hash=sha256:a5da6976f20cae27059ea8d0c86e7cef3de720e04c4bb9ee18e3690fdb792066 \ + --hash=sha256:a94c5a76ab46c5e6257c7972b6c8cff0574201ca7dc05647e33e795d78680563 \ + --hash=sha256:a95a9248b0c6fd933a442c03c3b113c3b61320086b88e2c444676d3fd1ca3330 \ + --hash=sha256:baf593f2765fa3a6b1ef95807dbaa3d25b594f6a52adcc506a6b9cb115e1be67 \ + --hash=sha256:bb9c2fa06887e21d6a3a868762acb82aec34e2c6fd0174064f27c93ede68ad15 \ + --hash=sha256:bba9ad231e92a3e424b3e56b65aa17704993425bba97e302c832f9466bb85bac \ + --hash=sha256:c3bae4f855d965b5453784300c12ffc63a548304ac7f99e55d4dc7c898673aa3 \ + --hash=sha256:c566c3a88b6ece59b3d70f65bedef17304f48eb52ff040a6a18214e1917b3254 \ + --hash=sha256:cdecf62abcc4292500d7858aeae87a1f8f1150f4c4dd08fb0b336ee79b2a6df3 \ + --hash=sha256:cf5a4db6dca263010e2c7bff081c89383c72d187ba2cf4c44759aac970e2f0c4 \ + --hash=sha256:d52ad8d78522da1d308789df651ee5379088e77c76cb1994858d40a426b343b9 \ + --hash=sha256:e061b58443f1736f8a37c48978d7ab581636d6ab03e3d4f99e3fa90463bb9382 \ + --hash=sha256:e2877a02380adfcdbc69071a0f74d6e9dbbf593c0dc9d174e1f223ffd5281943 \ + --hash=sha256:e73c07f23009962885c197ccb9b41356a30cc0e5a1d0c2ea8fd8fb1362d7f924 \ + --hash=sha256:e8222c26daaafd9e8626dec58ae36029f82585890589576f769a650dd20fd665 \ + --hash=sha256:edfbfca868cdd6bd8d974a60f8a3682f5565d3f5c99b327640cedd24c4264026 \ + --hash=sha256:f376e37f9bf2a946872fc5fd1199c99310748e3c26c7a26683f13f8bdb756cbd # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ @@ -1875,9 +1892,9 @@ oauthlib==3.3.1 \ --hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \ --hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1 # via requests-oauthlib -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # db-dtypes @@ -1957,9 +1974,9 @@ pandas==2.3.3 \ # pandas-gbq # pymilvus # snowflake-connector-python -pandas-gbq==0.34.1 \ - --hash=sha256:6bea5b85937251b976cf9db38151ea59abbff98771179183488d4614694bff67 \ - --hash=sha256:b74932c6ee35dfc81582f39c792e3a68c9ef9bee8c85f25667d9d05dfadd0daf +pandas-gbq==0.35.0 \ + --hash=sha256:258de481019566611031919997bf9c1ece4ca30a4dd02d3fc3664b251d446182 \ + --hash=sha256:596c908487ef0649a161e86ef272c00c267e581b95dc5ee0dc3518545b33bcfc # via google-cloud-bigquery parsy==2.2 \ --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ @@ -1980,24 +1997,24 @@ 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.9.6 \ + --hash=sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a \ + --hash=sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917 # via snowflake-connector-python pluggy==1.6.0 \ --hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \ --hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # via hatchling -prometheus-client==0.24.1 \ - --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ - --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 +prometheus-client==0.25.0 \ + --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ + --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 # via feast (pyproject.toml) propcache==0.4.1 \ --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ @@ -2193,57 +2210,57 @@ psycopg-pool==3.3.0 \ --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 # 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 @@ -2272,141 +2289,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.3 \ + --hash=sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927 \ + --hash=sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d # 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.3 \ + --hash=sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba \ + --hash=sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35 \ + --hash=sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4 \ + --hash=sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505 \ + --hash=sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7 \ + --hash=sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8 \ + --hash=sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4 \ + --hash=sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37 \ + --hash=sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25 \ + --hash=sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022 \ + --hash=sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1 \ + --hash=sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7 \ + --hash=sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c \ + --hash=sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3 \ + --hash=sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb \ + --hash=sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3 \ + --hash=sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976 \ + --hash=sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c \ + --hash=sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab \ + --hash=sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa \ + --hash=sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6 \ + --hash=sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396 \ + --hash=sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c \ + --hash=sha256:3d08782c4045f90724b44c95d35ebec0d67edb8a957a2ac81d5a8e4b8a200495 \ + --hash=sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c \ + --hash=sha256:4335e87c7afa436a0dfa899e138d57a72f8aad542e2cf19c36fb428461caabd0 \ + --hash=sha256:4b068543bdb707f5d935dab765d99227aa2545ef2820935f2e5dd801795c7dbd \ + --hash=sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf \ + --hash=sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531 \ + --hash=sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5 \ + --hash=sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda \ + --hash=sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d \ + --hash=sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e \ + --hash=sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df \ + --hash=sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6 \ + --hash=sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c \ + --hash=sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13 \ + --hash=sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536 \ + --hash=sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287 \ + --hash=sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0 \ + --hash=sha256:68ef2f623dda6d5a9067ac014e406c020c780b2a358930a7e5c1b73702900720 \ + --hash=sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050 \ + --hash=sha256:6dff8cc884679df229ebc6d8eb2321ea6f8e091bc7d4886d4dc2e0e71452843c \ + --hash=sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1 \ + --hash=sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8 \ + --hash=sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0 \ + --hash=sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374 \ + --hash=sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807 \ + --hash=sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6 \ + --hash=sha256:831eb19aa789a97356979e94c981e5667759301fb708d1c0d5adf1bc0098b873 \ + --hash=sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57 \ + --hash=sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f \ + --hash=sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c \ + --hash=sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad \ + --hash=sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e \ + --hash=sha256:91249bcb7c165c2fb2a2f852dbc5c91636e2e218e75d96dfdd517e4078e173dd \ + --hash=sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23 \ + --hash=sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46 \ + --hash=sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1 \ + --hash=sha256:99421e7684a60f7f3550a1d159ade5fdff1954baedb6bdd407cba6a307c9f27d \ + --hash=sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1 \ + --hash=sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee \ + --hash=sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c \ + --hash=sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874 \ + --hash=sha256:9f247596366f4221af52beddd65af1218797771d6989bc891a0b86ccaa019168 \ + --hash=sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a \ + --hash=sha256:a35cc284c8dd7edae8a31533713b4d2467dfe7c4f1b5587dd4031f28f90d1d13 \ + --hash=sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f \ + --hash=sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a \ + --hash=sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789 \ + --hash=sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe \ + --hash=sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f \ + --hash=sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5 \ + --hash=sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943 \ + --hash=sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b \ + --hash=sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089 \ + --hash=sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b \ + --hash=sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff \ + --hash=sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67 \ + --hash=sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803 \ + --hash=sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045 \ + --hash=sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8 \ + --hash=sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346 \ + --hash=sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2 \ + --hash=sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f \ + --hash=sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687 \ + --hash=sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76 \ + --hash=sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1 \ + --hash=sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f \ + --hash=sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2 \ + --hash=sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c \ + --hash=sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018 \ + --hash=sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba \ + --hash=sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c \ + --hash=sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf \ + --hash=sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7 \ + --hash=sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47 \ + --hash=sha256:d56bdb4af1767cc15b0386b3c581fdfe659bb9ee4a4f776e92c1cd9d074000d6 \ + --hash=sha256:dcda6583921c05a40533f982321532f2d8db29326c7b95c4026941fa5074bd79 \ + --hash=sha256:dd81f6907932ebac3abbe41378dac64b2380db1287e2aa64d8d88f78d170f51a \ + --hash=sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e \ + --hash=sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a \ + --hash=sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34 \ + --hash=sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b \ + --hash=sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85 \ + --hash=sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca \ + --hash=sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f \ + --hash=sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3 \ + --hash=sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64 \ + --hash=sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22 \ + --hash=sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72 \ + --hash=sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec \ + --hash=sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d \ + --hash=sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3 \ + --hash=sha256:fa3eb7c2995aa443687a825bc30395c8521b7c6ec201966e55debfd1128bcceb \ + --hash=sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395 \ + --hash=sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb \ + --hash=sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4 \ + --hash=sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127 \ + --hash=sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56 # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.0 \ + --hash=sha256:24285fd4b0e0c06507dd9fdfd331ee23794305352aaec8fc4eb92d4047aeb67d \ + --hash=sha256:fc8d5d692eb7092e43c8647c1c35a3ecd00e040fcf02ed86f4cb5458ca62182e # via # fastapi-mcp # mcp @@ -2432,13 +2448,13 @@ pymilvus==2.5.18 \ --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d # via feast (pyproject.toml) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 +pymysql==1.1.3 \ + --hash=sha256:8164ba62c552f6105f3b11753352d0f16b90d1703ba67d81923d5a8a5d1c5289 \ + --hash=sha256:e70ebf2047a4edf6138cf79c68ad418ef620af65900aa585c5e8bfc95044d43a # via feast (pyproject.toml) -pyopenssl==26.0.0 \ - --hash=sha256:df94d28498848b98cc1c0ffb8ef1e71e40210d3b0a8064c9d29571ed2904bf81 \ - --hash=sha256:f293934e52936f2e3413b89c6ce36df66a0b34ae1ea3a053b8c5020ff2f513fc +pyopenssl==26.1.0 \ + --hash=sha256:115563879b2c8ccb207975705d3e491434d8c9d7c79667c902ecbf5f3bbd2ece \ + --hash=sha256:737f0a2275c5bc54f3b02137687e1a765931fb3949b9a92a825e4d33b9eec08b # via snowflake-connector-python pyproject-metadata==0.11.0 \ --hash=sha256:85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 \ @@ -2461,9 +2477,9 @@ python-dotenv==1.2.2 \ # pydantic-settings # pymilvus # uvicorn -python-multipart==0.0.22 \ - --hash=sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155 \ - --hash=sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58 +python-multipart==0.0.27 \ + --hash=sha256:6fccfad17a27334bd0193681b369f476eda3409f17381a2d65aa7df3f7275645 \ + --hash=sha256:9870a6a8c5a20a5bf4f07c017bd1489006ff8836cff097b6933355ee2b49b602 # via mcp pytz==2026.1.post1 \ --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ @@ -2550,9 +2566,9 @@ pyyaml==6.0.3 \ # dask # kubernetes # uvicorn -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.0 \ + --hash=sha256:64a6ea7bf567ad43c964d2c30d82853f8df927c5c9017766c55a1d1ed95d18ad \ + --hash=sha256:a9c74a5c893a5ef8455a5adb793a31bb70feb821c86eccb62eebef5a19c429ec # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -2579,9 +2595,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 @@ -2803,78 +2819,78 @@ 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.49 \ + --hash=sha256:01146546d84185f12721a1d2ce0c6673451a7894d1460b592d378ca4871a0c72 \ + --hash=sha256:059d7151fff513c53a4638da8778be7fce81a0c4854c7348ebd0c4078ddf28fe \ + --hash=sha256:0c98c59075b890df8abfcc6ad632879540f5791c68baebacb4f833713b510e75 \ + --hash=sha256:0f2fa354ba106eafff2c14b0cc51f22801d1e8b2e4149342023bd6f0955de5f5 \ + --hash=sha256:12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148 \ + --hash=sha256:22d8798819f86720bc646ab015baff5ea4c971d68121cb36e2ebc2ee43ead2b7 \ + --hash=sha256:233088b4b99ebcbc5258c755a097aa52fbf90727a03a5a80781c4b9c54347a2e \ + --hash=sha256:24bd94bb301ec672d8f0623eba9226cc90d775d25a0c92b5f8e4965d7f3a1518 \ + --hash=sha256:275424295f4256fd301744b8f335cff367825d270f155d522b30c7bf49903ee7 \ + --hash=sha256:32fe6a41ad97302db2931f05bb91abbcc65b5ce4c675cd44b972428dd2947700 \ + --hash=sha256:334edbcff10514ad1d66e3a70b339c0a29886394892490119dbb669627b17717 \ + --hash=sha256:3bb9ec6436a820a4c006aad1ac351f12de2f2dbdaad171692ee457a02429b672 \ + --hash=sha256:3ddcb27fb39171de36e207600116ac9dfd4ae46f86c82a9bf3934043e80ebb88 \ + --hash=sha256:42e8804962f9e6f4be2cbaedc0c3718f08f60a16910fa3d86da5a1e3b1bfe60f \ + --hash=sha256:43d044780732d9e0381ac8d5316f95d7f02ef04d6e4ef6dc82379f09795d993f \ + --hash=sha256:46796877b47034b559a593d7e4b549aba151dae73f9e78212a3478161c12ab08 \ + --hash=sha256:46d51518d53edfbe0563662c96954dc8fcace9832332b914375f45a99b77cc9a \ + --hash=sha256:47604cb2159f8bbd5a1ab48a714557156320f20871ee64d550d8bf2683d980d3 \ + --hash=sha256:4bbccb45260e4ff1b7db0be80a9025bb1e6698bdb808b83fff0000f7a90b2c0b \ + --hash=sha256:4d4e5a0ceba319942fa6b585cf82539288a61e314ef006c1209f734551ab9536 \ + --hash=sha256:55250fe61d6ebfd6934a272ee16ef1244e0f16b7af6cd18ab5b1fc9f08631db0 \ + --hash=sha256:566df36fd0e901625523a5a1835032f1ebdd7f7886c54584143fa6c668b4df3b \ + --hash=sha256:57ca426a48eb2c682dae8204cd89ea8ab7031e2675120a47924fabc7caacbc2a \ + --hash=sha256:5e61abbec255be7b122aa461021daa7c3f310f3e743411a67079f9b3cc91ece3 \ + --hash=sha256:618a308215b6cececb6240b9abde545e3acdabac7ae3e1d4e666896bf5ba44b4 \ + --hash=sha256:62557958002b69699bdb7f5137c6714ca1133f045f97b3903964f47db97ea339 \ + --hash=sha256:6270d717b11c5476b0cbb21eedc8d4dbb7d1a956fd6c15a23e96f197a6193158 \ + --hash=sha256:685e93e9c8f399b0c96a624799820176312f5ceef958c0f88215af4013d29066 \ + --hash=sha256:69469ce8ce7a8df4d37620e3163b71238719e1e2e5048d114a1b6ce0fbf8c662 \ + --hash=sha256:6eb188b84269f357669b62cb576b5b918de10fb7c728a005fa0ebb0b758adce1 \ + --hash=sha256:74ab4ee7794d7ed1b0c37e7333640e0f0a626fc7b398c07a7aef52f484fddde3 \ + --hash=sha256:77641d299179c37b89cf2343ca9972c88bb6eef0d5fc504a2f86afd15cd5adf5 \ + --hash=sha256:7c821c47ecfe05cc32140dcf8dc6fd5d21971c86dbd56eabfe5ba07a64910c01 \ + --hash=sha256:7d6be30b2a75362325176c036d7fb8d19e8846c77e87683ffaa8177b35135613 \ + --hash=sha256:7f605a456948c35260e7b2a39f8952a26f077fd25653c37740ed186b90aaa68a \ + --hash=sha256:83101a6930332b87653886c01d1ee7e294b1fe46a07dd9a2d2b4f91bcc88eec0 \ + --hash=sha256:88690f4e1f0fbf5339bedbb127e240fec1fd3070e9934c0b7bef83432f779d2f \ + --hash=sha256:8a97ac839c2c6672c4865e48f3cbad7152cee85f4233fb4ca6291d775b9b954a \ + --hash=sha256:8d6efc136f44a7e8bc8088507eaabbb8c2b55b3dbb63fe102c690da0ddebe55e \ + --hash=sha256:8e20e511dc15265fb433571391ba313e10dd8ea7e509d51686a51313b4ac01a2 \ + --hash=sha256:951d4a210744813be63019f3df343bf233b7432aadf0db54c75802247330d3af \ + --hash=sha256:9ac7a3e245fd0310fd31495eb61af772e637bdf7d88ee81e7f10a3f271bff014 \ + --hash=sha256:9b1c058c171b739e7c330760044803099c7fff11511e3ab3573e5327116a9c33 \ + --hash=sha256:9c04bff9a5335eb95c6ecf1c117576a0aa560def274876fd156cfe5510fccc61 \ + --hash=sha256:9c4969a86e41454f2858256c39bdfb966a20961e9b58bf8749b65abf447e9a8d \ + --hash=sha256:9e0400fa22f79acc334d9a6b185dc00a44a8e6578aa7e12d0ddcd8434152b187 \ + --hash=sha256:a05977bffe9bffd2229f477fa75eabe3192b1b05f408961d1bebff8d1cd4d401 \ + --hash=sha256:a143af2ea6672f2af3f44ed8f9cd020e9cc34c56f0e8db12019d5d9ecf41cb3b \ + --hash=sha256:a51d3db74ba489266ef55c7a4534eb0b8db9a326553df481c11e5d7660c8364d \ + --hash=sha256:b95b2f470c1b2683febd2e7eab1d3f0e078c91dbdd0b00e9c645d07a413bb99f \ + --hash=sha256:b9870d15ef00e4d0559ae10ee5bc71b654d1f20076dbe8bc7ed19b4c0625ceba \ + --hash=sha256:c1dc3368794d522f43914e03312202523cc89692f5389c32bea0233924f8d977 \ + --hash=sha256:c338ec6ec01c0bc8e735c58b9f5d51e75bacb6ff23296658826d7cfdfdb8678a \ + --hash=sha256:c5070135e1b7409c4161133aa525419b0062088ed77c92b1da95366ec5cbebbe \ + --hash=sha256:cc992c6ed024c8c3c592c5fc9846a03dd68a425674900c70122c77ea16c5fb0b \ + --hash=sha256:d15950a57a210e36dd4cec1aac22787e2a4d57ba9318233e2ef8b2daf9ff2d5f \ + --hash=sha256:d898cc2c76c135ef65517f4ddd7a3512fb41f23087b0650efb3418b8389a3cd1 \ + --hash=sha256:d99945830a6f3e9638d89a28ed130b1eb24c91255e4f24366fbe699b983f29e4 \ + --hash=sha256:da9b91bca419dc9b9267ffadde24eae9b1a6bffcd09d0a207e5e3af99a03ce0d \ + --hash=sha256:df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120 \ + --hash=sha256:e06e617e3d4fd9e51d385dfe45b077a41e9d1b033a7702551e3278ac597dc750 \ + --hash=sha256:ec44cfa7ef1a728e88ad41674de50f6db8cfdb3e2af84af86e0041aaf02d43d0 \ + --hash=sha256:fb37f15714ec2652d574f021d479e78cd4eb9d04396dca36568fdfffb3487982 # via feast (pyproject.toml) -sqlglot==30.2.1 \ - --hash=sha256:ef4a67cc6f66a8043085eb8ea95fa9541c1625dffa9145ad4e9815a7ba60a199 \ - --hash=sha256:f23d9ee9427ef9d20df15f9b0ffa57d9eb45e52b012219a349d1e6b50ed926d1 +sqlglot==30.6.0 \ + --hash=sha256:246d34d39927422a50a3fa155f37b2f6346fba85f1a755b13c941eb32ef93361 \ + --hash=sha256:e005fc2f47994f90d7d8df341f1cbe937518497b0b7b1507d4c03c4c9dfd2778 # via ibis-framework -sse-starlette==3.3.4 \ - --hash=sha256:84bb06e58939a8b38d8341f1bc9792f06c2b53f48c608dd207582b664fc8f3c1 \ - --hash=sha256:aaf92fc067af8a5427192895ac028e947b484ac01edbc3caf00e7e7137c7bef1 +sse-starlette==3.4.1 \ + --hash=sha256:6b43cf21f1d574d582a6e1b0cfbde1c94dc86a32a701a7168c99c4475c6bd1d0 \ + --hash=sha256:f780bebcf6c8997fe514e3bd8e8c648d8284976b391c8bed0bcb1f611632b555 # via mcp starlette==1.0.0 \ --hash=sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149 \ @@ -2961,25 +2977,25 @@ tqdm==4.67.3 \ # via # feast (pyproject.toml) # milvus-lite -trove-classifiers==2026.1.14.14 \ - --hash=sha256:00492545a1402b09d4858605ba190ea33243d361e2b01c9c296ce06b5c3325f3 \ - --hash=sha256:1f9553927f18d0513d8e5ff80ab8980b8202ce37ecae0e3274ed2ef11880e74d +trove-classifiers==2026.4.28.13 \ + --hash=sha256:8f4b1eb4e16296b57d612965444f87a83861cc989a0451ac97fe4265ddef03b8 \ + --hash=sha256:c85bb8a53c3de7330d1699b844ed9fb809a602a09ac15dc79ad6d1a509be0676 # via hatchling typeguard==4.5.1 \ --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 # via feast (pyproject.toml) -typer==0.24.1 \ - --hash=sha256:112c1f0ce578bfb4cab9ffdabc68f031416ebcc216536611ba21f04e9aa84c9e \ - --hash=sha256:e39b4732d65fbdcde189ae76cf7cd48aeae72919dea1fdfc16593be016256b45 +typer==0.25.1 \ + --hash=sha256:75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89 \ + --hash=sha256:9616eb8853a09ffeabab1698952f33c6f29ffdbceb4eaeecf571880e8d7664cc # 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.20260408 \ + --hash=sha256:b784dc37908479e3767e2d794ab507b3674adb1c686ca3d13fc9e2960dbcb9ec \ + --hash=sha256:da630647eaaa7a926a3907794f4067f269cd245b2c202c74aa3c6a3bd660a9db # via feast (pyproject.toml) typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ @@ -3010,9 +3026,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 # ibis-framework # pandas @@ -3561,9 +3577,9 @@ yarl==1.23.0 \ --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d # via aiohttp -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==3.23.1 \ + --hash=sha256:0b3596c50a5c700c9cb40ba8d86d9f2cc4807e9bedb06bcdf7fac85633e444dc \ + --hash=sha256:32120e378d32cd9714ad503c1d024619063ec28aad2248dc6672ad13edfa5110 # via importlib-metadata # The following packages were excluded from the output: diff --git a/sdk/python/requirements/py3.11-requirements.txt b/sdk/python/requirements/py3.11-requirements.txt index ec293cec030..706d85f5ec6 100644 --- a/sdk/python/requirements/py3.11-requirements.txt +++ b/sdk/python/requirements/py3.11-requirements.txt @@ -24,9 +24,9 @@ bigtree==1.4.0 \ --hash=sha256:d0d99550ae64ce4529f132602ab875c2ab472c96c942f5704f8c72a17450d3ea \ --hash=sha256:e5ae2e948168da671d99601c9ed87ab3b48d9d4ea8a98f111e5748e98064c31c # via feast (pyproject.toml) -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +certifi==2026.4.22 \ + --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ + --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 # via requests charset-normalizer==3.4.7 \ --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ @@ -159,9 +159,9 @@ charset-normalizer==3.4.7 \ --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 # via requests -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.3.3 \ + --hash=sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2 \ + --hash=sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 # via # feast (pyproject.toml) # dask @@ -182,13 +182,13 @@ dill==0.3.9 \ --hash=sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a \ --hash=sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c # via feast (pyproject.toml) -fastapi==0.135.3 \ - --hash=sha256:9b0f590c813acd13d0ab43dd8494138eb58e484bfac405db1f3187cfc5810d98 \ - --hash=sha256:bd6d7caf1a2bdd8d676843cdcd2287729572a1ef524fc4d65c17ae002a1be654 +fastapi==0.136.1 \ + --hash=sha256:7af665ad7acfa0a3baf8983d393b6b471b9da10ede59c60045f49fbc89a0fa7f \ + --hash=sha256:a6e9d7eeada96c93a4d69cb03836b44fa34e2854accb7244a1ece36cd4781c3f # via feast (pyproject.toml) -fsspec==2026.3.0 \ - --hash=sha256:1ee6a0e28677557f8c2f994e3eea77db6392b4de9cd1f5d7a9e87a0ae9d01b41 \ - --hash=sha256:d2ceafaad1b3457968ed14efa28798162f1638dbb5d2a6868a2db002a5ee39a4 +fsspec==2026.4.0 \ + --hash=sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 \ + --hash=sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4 # via dask gunicorn==25.3.0 \ --hash=sha256:cacea387dab08cd6776501621c295a904fe8e3b7aae9a1a3cbb26f4e7ed54660 \ @@ -245,9 +245,9 @@ httptools==0.7.1 \ --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 # via uvicorn -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.13 \ + --hash=sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242 \ + --hash=sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 # via # anyio # requests @@ -267,97 +267,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.9.0 \ + --hash=sha256:07cf11f769831186eeac424376e6189f20ace4f7263e2134bdb9757340d84d4d \ + --hash=sha256:0a09c2f5869649101738653a9b7ab70cf045a1105ac66cbb8f4055e61df78f2d \ + --hash=sha256:0a1be03168b2691ba61927e299b352a6315189199ca18a57b733f86cb3cc8d38 \ + --hash=sha256:0b73e4266307e51c95e09c0750b7ec383c561d2e97d58e473f6f6a209952fbb8 \ + --hash=sha256:15cb151e52a044f06e54ac7f7b47adbfc89b5c8e2b63e1175a9d587c43e8942a \ + --hash=sha256:194fc1a32e1e21fe809d38b5faea66cc65eaa00217c8901fbdb99866938adbdb \ + --hash=sha256:1bf465d1e5b0a27713862441f6467b5ab76385f4ecf8f1f3a44f8aa3c695b4b6 \ + --hash=sha256:1c587494461ebd42229d0f1739f3aa34237dd9980623ecf1be8d3bcba79f4499 \ + --hash=sha256:224b9727eb8bc188bc3bcf29d969dba0cd61b01d9bac80c41575520cc4baabb2 \ + --hash=sha256:22a904cbdb678f7cb348c90d543d3c52f581663d687992fee47fd566dcbf5285 \ + --hash=sha256:2b8f5d00b49818f4e2b1667db994488b045835e0ac16fe2f924f3871bd2b8ac5 \ + --hash=sha256:2c3786f0f4490a5cd87f1ed6cefae833ad6b1060d52044ce0434a2e85893afd0 \ + --hash=sha256:2d03fa4fd277a7974c1978c92c374c57f44edeee163d147b477b143446ad1bf6 \ + --hash=sha256:2f8e12706dcb8ff6b3ed57514a19e45c49ad00bcd423e87b2b2e4b5f64578443 \ + --hash=sha256:3be322a15ee5e70b93b7a59cfd074614f22cc8c9ff18bd27f474e79137ea8d3b \ + --hash=sha256:3cc2917258e131ae5f958a4d872e07555b51cb7466a43433218061c74ef33745 \ + --hash=sha256:3f05d145df35dca5056a8bc3838e940efebd893a54b3e19b2dda39ceaa299bcb \ + --hash=sha256:3fe56e80badb66fdcde06bef81bbaa5bfcf6fbd7aefb86222d9e369c38c6b228 \ + --hash=sha256:42ff8a962554c350d4a83cf47d9b7b78b0e6ff7943e87df7cdfc97c07f3c016f \ + --hash=sha256:451daa98463b7695b0a30aa56bf637831ea559e7b8101ac2ef6382e8eb15e29c \ + --hash=sha256:465814ab157986acb9dfa5ccd7df944be5eefc0d08d31ec6e8d88bc71251d845 \ + --hash=sha256:4c4d0440a3a8e31d962340c3e1cc3fc9ee7febd34c8d8f770d06adb947779ea5 \ + --hash=sha256:4e3dda8345307fd7306db0ed0cb109a63a2c85ba780eb9dc2d09b2049a931f9c \ + --hash=sha256:5093043afb226ecfa1400120d1ebd4442b4f99977783e4f4f7248879009b227f \ + --hash=sha256:5112c2fb7c2eefefaeaf5c97fec81343ef44ee86a30dcfaa8223822fba6467b4 \ + --hash=sha256:527b5b820b47a09e09829051452bb0d1dd2122261254e2a6f674d12f1d793d54 \ + --hash=sha256:54d412e47c21b85865676ed0724e37a89e9593c2eee1e7367adf85bfad56ffb1 \ + --hash=sha256:56d65b583cf43b8cf4c8fbe1e1da20fa3076cc32a1149a141507af1062718236 \ + --hash=sha256:5ca8e133d799c948db2ab1afc081c333a825b5540475164726dcbf73537e5c2f \ + --hash=sha256:603138ee838ee1583f1b960b62d5d0007845c5c423feb68e44648b1359014e27 \ + --hash=sha256:63c12efcd160e1d14da11af0c46c0217473e1e0d2ae1acbccc83f561ea4c2a7b \ + --hash=sha256:657f8ba7b9eaaa82759a104137aed2a3ef7bc46ccfd43e0d89b04005b3e0a4cc \ + --hash=sha256:66b58fed90a545328e80d575467244de3741e088c1af928f0b489ebec3ef3858 \ + --hash=sha256:6788207daa0c19955d2b668f3294a368d19f67d9b5f274553fd073c1260cbb9f \ + --hash=sha256:703f4ae36d6240bfe24f542bac784c7e4194ec49c3ba5a994d02891649e2d85b \ + --hash=sha256:7202bdcac47d3a708271c4304a474a8605a4a9a4a709e954bf2d3241140aa938 \ + --hash=sha256:756775d25ec8345b837ab52effee3ad2f3b2dfd6bbee3e3f029c517bd5d8f05a \ + --hash=sha256:78042f6facfd98ecb25e9829c7e37cce23363d9d7c83bc5f72702c5059eb082b \ + --hash=sha256:789fff71757facc0738e8d89e3b84e4f0251c1c975e85e81b152cdaca927cc2d \ + --hash=sha256:7bc30ad339f4e1a01d4917d645e522a0bc0030644d8973f6346397c93ba1503f \ + --hash=sha256:7d429bdd4ac0ab17c8e4a8af0ed2a7440b16eba474909ab357131018fe8c7e71 \ + --hash=sha256:7d5c8a5929ac325729f6119802070b561f4db793dffc45e9ac750992a4ed4d22 \ + --hash=sha256:7e6274fd33fc5b2a14d41c9119629d3ff395849d8bcbc80cf637d9e8d2034da8 \ + --hash=sha256:80b25c7b570a86c03b5da69e665809deb39265476e8e21d96a9328f9762f9990 \ + --hash=sha256:81107843ed1836874b46b310f9b1816abcb89912af627868522461c3b7333c0f \ + --hash=sha256:8494cfc61e03542f2d381e71804990b3931175a29b9278fdb4a5459948778dc2 \ + --hash=sha256:850d6d03177e52700af605fd60db7f37dcb89782049a149674d1a9649c2138fd \ + --hash=sha256:8c6bc1384d9738781cfd41d09ad7f6e8af13cfea2c75ece6bd6d2566cdea2076 \ + --hash=sha256:90904fac73c478f4b83f4ed96c99c8208b75e6f9a8a1910548f69a00f1eaa671 \ + --hash=sha256:90e6d5420fc8a300518d4d2288154ff45005e920425c22cbbfe8330f3f754bd9 \ + --hash=sha256:928bd06eca2c2bbf4349e5b817f837509b0604342e65a502de1d50a7570afd15 \ + --hash=sha256:9b3e3bc363f71bda1639a4ee593cb78f7fbfeacc73411ec0d4c92f00730010a4 \ + --hash=sha256:9edcc35d1cae9fd5320171b1a838c7da8a5c968af31e82ecc3dff30b4be0957f \ + --hash=sha256:9fcb461fbf70654a52a7cc670e606f04449e2374c199b1825f754e16dacfedd8 \ + --hash=sha256:a0951822531e7aee6e0dfb556b30d5ee36bbe234faf60c20a16c01be3530869d \ + --hash=sha256:a361c9434a64d70a7dbb771d1de302c0cc9f13c0bffe1cf7e642152814b35265 \ + --hash=sha256:a4b25c6c25cac5d0d9d6d6da855195b254e0021e513e0249f0e3b444dc6e0e61 \ + --hash=sha256:a5af136bfba820d592f86c67affcef9b3ff4d4360ac3255e341e964489b48519 \ + --hash=sha256:a81eea9b999b985e4bacc650c4312805ea7008fd5e45e1bf221310176a7bcb3a \ + --hash=sha256:a9c63e04d003bc0fb6a03b348018b9a3002f98268200e22cc80f146beac5dc40 \ + --hash=sha256:aa95738a68cedd3a6f5492feddc513e2e166b50602958139e47bbdd82da0f5a7 \ + --hash=sha256:b0a2040f801406b93657a70b72fa12311063a319fee72ce98e1524da7200171f \ + --hash=sha256:b8bd70d5d816566a580d193326912f4a76ec2d28a97dc4cd4cc831c0af8e330e \ + --hash=sha256:b8da9f8035bb417770b1e1610526d87ad4fc58a2804dc4d79c53f6d2cf5a6eb9 \ + --hash=sha256:bc5518873822d2faa8ebdd2c1a4d7c8ef47b01a058495ab7924cb65bdbf5fc9a \ + --hash=sha256:c0d620e74897f8c2613b3c4e2e9c1e422eb46d2ddd07df540784d44117836af3 \ + --hash=sha256:c2640e23d2b7c98796f123ffd95cf2022c7777aa8a4a3b98b36c570d37e85eee \ + --hash=sha256:c81aef782380f0f13ead670aae01825eb653b44b046aa0e5ebbb79f76ed4aa11 \ + --hash=sha256:d4d16b608a1c43d7e33142099a75cd93af482dadce0bf82421e91cad077157f4 \ + --hash=sha256:d69fc39e627908f4c03297d5a88d9284b73f4d90b424461e32e8c2485e21c283 \ + --hash=sha256:d9da80e5b04acce03ced8ba6479a71c2a2edf535c2acc0d09c80d2f80f3bad15 \ + --hash=sha256:dd2c7e082b0b92e1baa4da28163a808672485617bc855cc22a2fd06978fa9084 \ + --hash=sha256:de7dac64e3eb832ffc7b840eb8f52f76420cde1b845be51b2a0f6b870890645e \ + --hash=sha256:e0785c2fb4a81e1aece366aa3e2e039f4a4d7d21aaaded5227d7f3c703427882 \ + --hash=sha256:e306d956cfa027fe041585f02a1602c32bfa6bb8ebea4899d373383295a6c62f \ + --hash=sha256:e78fb7419e07d98c2af4b8567b72b3eaf8cb05caad642e9963465569c8b2d87e \ + --hash=sha256:e9002e98dcb1c0a66723592520decd86238ddcef168b37ff6cfb559200b4b774 \ + --hash=sha256:e94cbc6ad9a6aeea46d775cbb11f361022f778a9cc8cc90af653d3a594b057ce \ + --hash=sha256:eea1b54943475f51698f85fa230c65ccac769f1e603b981be060ac5763d90927 \ + --hash=sha256:f100bfe2acf8a3689af9d0cc660d89f17286c9c795f9f18f7b62dd1a6b247ae6 \ + --hash=sha256:f162af66a2ed3f7d1d161a82ca584efd15acd9c1cff190a373458c32f7d42118 \ + --hash=sha256:f24b90b0e0c8cc9491fb1693ae91fe17cb7963153a1946395acdbdd5818429a4 \ + --hash=sha256:f29b68cd9714531672db62cc54f6e8ff981900f824d13fa0e00749189e13778e \ + --hash=sha256:f38bc489037eca88d6ebefc9c4d41a4e07c8e8b4de5188a9e6d290273ad7ebb1 \ + --hash=sha256:f3fd278f5e6bf7c75ccd6d12344eb686cc020712683363b66f46ac79d37c799f \ + --hash=sha256:f4003f70c56a5addd6aa0897f200dd59afd3bf7bcd5b3cce46dd21f925743bc2 \ + --hash=sha256:f48c963a76d71b9d7927eb817b543d0dccd52ab6648b99d37bd54f4cd475d856 \ + --hash=sha256:f819e0c6413e259a17a7c0d49f97f405abadd3c2a316a3b46c6440b7dbbedbb1 \ + --hash=sha256:fc5758e2b7a56532dc33e3c544d78cbaa9ecf0a0f2a2da2df882c1d6b99a317f \ + --hash=sha256:fcbdf2a9ca24e87bbebb47f1fe34e531ef06f104f98c9ccfc953a3f3344c567a # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ @@ -563,51 +563,51 @@ mmh3==5.2.1 \ --hash=sha256:fceef7fe67c81e1585198215e42ad3fdba3a25644beda8fbdaf85f4d7b93175a \ --hash=sha256:fd96476f04db5ceba1cfa0f21228f67c1f7402296f0e73fee3513aa680ad237b # via feast (pyproject.toml) -mypy==1.20.0 \ - --hash=sha256:002b613ae19f4ac7d18b7e168ffe1cb9013b37c57f7411984abbd3b817b0a214 \ - --hash=sha256:00e047c74d3ec6e71a2eb88e9ea551a2edb90c21f993aefa9e0d2a898e0bb732 \ - --hash=sha256:02cca0761c75b42a20a2757ae58713276605eb29a08dd8a6e092aa347c4115ca \ - --hash=sha256:0ecd63f75fdd30327e4ad8b5704bd6d91fc6c1b2e029f8ee14705e1207212489 \ - --hash=sha256:0f42dfaab7ec1baff3b383ad7af562ab0de573c5f6edb44b2dab016082b89948 \ - --hash=sha256:1973868d2adbb4584a3835780b27436f06d1dc606af5be09f187aaa25be1070f \ - --hash=sha256:26c8b52627b6552f47ff11adb4e1509605f094e29815323e487fc0053ebe93d1 \ - --hash=sha256:2721f0ce49cb74a38f00c50da67cb7d36317b5eda38877a49614dc018e91c787 \ - --hash=sha256:2fcedb16d456106e545b2bfd7ef9d24e70b38ec252d2a629823a4d07ebcdb69e \ - --hash=sha256:31b5dbb55293c1bd27c0fc813a0d2bb5ceef9d65ac5afa2e58f829dab7921fd5 \ - --hash=sha256:34506397dbf40c15dc567635d18a21d33827e9ab29014fb83d292a8f4f8953b6 \ - --hash=sha256:367e5c993ba34d5054d11937d0485ad6dfc60ba760fa326c01090fc256adf15c \ - --hash=sha256:379edf079ce44ac8d2805bcf9b3dd7340d4f97aad3a5e0ebabbf9d125b84b442 \ - --hash=sha256:39362cdb4ba5f916e7976fccecaab1ba3a83e35f60fa68b64e9a70e221bb2436 \ - --hash=sha256:4525e7010b1b38334516181c5b81e16180b8e149e6684cee5a727c78186b4e3b \ - --hash=sha256:47781555a7aa5fedcc2d16bcd72e0dc83eb272c10dd657f9fb3f9cc08e2e6abb \ - --hash=sha256:49d11c6f573a5a08f77fad13faff2139f6d0730ebed2cfa9b3d2702671dd7188 \ - --hash=sha256:555493c44a4f5a1b58d611a43333e71a9981c6dbe26270377b6f8174126a0526 \ - --hash=sha256:555658c611099455b2da507582ea20d2043dfdfe7f5ad0add472b1c6238b433f \ - --hash=sha256:697f102c5c1d526bdd761a69f17c6070f9892eebcb94b1a5963d679288c09e78 \ - --hash=sha256:76a70bf840495729be47510856b978f1b0ec7d08f257ca38c9d932720bf6b43e \ - --hash=sha256:7d3243c406773185144527f83be0e0aefc7bf4601b0b2b956665608bf7c98a83 \ - --hash=sha256:931a7630bba591593dcf6e97224a21ff80fb357e7982628d25e3c618e7f598ef \ - --hash=sha256:9804c3ad27f78e54e58b32e7cb532d128b43dbfb9f3f9f06262b821a0f6bd3f5 \ - --hash=sha256:a17c5d0bdcca61ce24a35beb828a2d0d323d3fcf387d7512206888c900193367 \ - --hash=sha256:a6e0641147cbfa7e4e94efdb95c2dab1aff8cfc159ded13e07f308ddccc8c48e \ - --hash=sha256:a79c1eba7ac4209f2d850f0edd0a2f8bba88cbfdfefe6fb76a19e9d4fe5e71a2 \ - --hash=sha256:a9336b5e6712f4adaf5afc3203a99a40b379049104349d747eb3e5a3aa23ac2e \ - --hash=sha256:b20c8b0fd5877abdf402e79a3af987053de07e6fb208c18df6659f708b535134 \ - --hash=sha256:b3a49064504be59e59da664c5e149edc1f26c67c4f8e8456f6ba6aba55033018 \ - --hash=sha256:b503ab55a836136b619b5fc21c8803d810c5b87551af8600b72eecafb0059cb0 \ - --hash=sha256:bd0212976dc57a5bfeede7c219e7cd66568a32c05c9129686dd487c059c1b88a \ - --hash=sha256:c70380fe5d64010f79fb863b9081c7004dd65225d2277333c219d93a10dad4dd \ - --hash=sha256:d99f515f95fd03a90875fdb2cca12ff074aa04490db4d190905851bdf8a549a8 \ - --hash=sha256:e80cf77847d0d3e6e3111b7b25db32a7f8762fd4b9a3a72ce53fe16a2863b281 \ - --hash=sha256:eb96c84efcc33f0b5e0e04beacf00129dd963b67226b01c00b9dfc8affb464c3 \ - --hash=sha256:ebea00201737ad4391142808ed16e875add5c17f676e0912b387739f84991e13 \ - --hash=sha256:efe8d70949c3023698c3fca1e94527e7e790a361ab8116f90d11221421cd8726 \ - --hash=sha256:f13b3e41bce9d257eded794c0f12878af3129d80aacd8a3ee0dee51f3a978651 \ - --hash=sha256:f194db59657c58593a3c47c6dfd7bad4ef4ac12dbc94d01b3a95521f78177e33 \ - --hash=sha256:f49590891d2c2f8a9de15614e32e459a794bcba84693c2394291a2038bbaaa69 \ - --hash=sha256:f75ff57defcd0f1d6e006d721ccdec6c88d4f6a7816eb92f1c4890d979d9ee62 \ - --hash=sha256:f799d9db89fc00446f03281f84a221e50018fc40113a3ba9864b132895619ebe \ - --hash=sha256:f8426d4d75d68714abc17a4292d922f6ba2cfb984b72c2278c437f6dae797865 +mypy==1.20.2 \ + --hash=sha256:0c64e5973df366b747646fc98da921f9d6eba9716d57d1db94a83c026a08e0fb \ + --hash=sha256:0deb80d062b2479f2c87ae568f89845afc71d11bc41b04179e58165fd9f31e98 \ + --hash=sha256:1e1c12f6d2db3d78b909b5f77513c11eb7f2dd2782b96a3ab6dffc7d44575c99 \ + --hash=sha256:20175a1c0f49863946ec20b7f63255768058ac4f07d2b9ded6a6b46cfb5a9100 \ + --hash=sha256:29752dbbf8cc53f89f6ac096d363314333045c257c9c75cbd189ca2de0455744 \ + --hash=sha256:2a4102b03bb7481d9a91a6da8d174740c9c8c4401024684b9ca3b7cc5e49852f \ + --hash=sha256:2de3dcea53babc1c3237a19002bc3d228ce1833278f093b8d619e06e7cc79609 \ + --hash=sha256:34397cdced6b90b836e38182076049fdb41424322e0b0728c946b0939ebdf9f6 \ + --hash=sha256:4077797a273e56e8843d001e9dfe4ba10e33323d6ade647ff260e5cd97d9758c \ + --hash=sha256:419413398fe250aae057fd2fe50166b61077083c9b82754c341cf4fd73038f30 \ + --hash=sha256:4b6481b228d072315b053210b01ac320e1be243dc17f9e5887ef167f23f5fae4 \ + --hash=sha256:4dbfcf869f6b0517f70cf0030ba6ea1d6645e132337a7d5204a18d8d5636c02b \ + --hash=sha256:4fef51b01e638974a6e69885687e9bd40c8d1e09a6cd291cca0619625cf1f558 \ + --hash=sha256:52b176444e2e5054dfcbcb8c75b0b719865c96247b37407184bbfca5c353f2c2 \ + --hash=sha256:56908d7e08318d39f85b1f0c6cfd47b0cac1a130da677630dac0de3e0623e102 \ + --hash=sha256:5a65aa591af023864fd08a97da9974e919452cfe19cb146c8a5dc692626445dc \ + --hash=sha256:688c3312e5dadb573a2c69c82af3a298d43ecf9e6d264e0f95df960b5f6ac19c \ + --hash=sha256:6e2b469efd811707bc530fd1effef0f5d6eebcb7fe376affae69025da4b979a2 \ + --hash=sha256:7488448de6007cd5177c6cea0517ac33b4c0f5ee9b5e9f2be51ce75511a85517 \ + --hash=sha256:785b08db19c9f214dc37d65f7c165d19a30fcecb48abfa30f31b01b5acaabb58 \ + --hash=sha256:7b0e817b518bff7facd7f85ea05b643ad8bdcce684cf29784987b0a7c8e1f997 \ + --hash=sha256:803203d2b6ea644982c644895c2f78b28d0e208bba7b27d9b921e0ec5eb207c6 \ + --hash=sha256:89dce27e142d25ffbc154c1819383b69f2e9234dc4ed4766f42e0e8cb264ab5c \ + --hash=sha256:913485a03f1bcf5d279409a9d2b9ed565c151f61c09f29991e5faa14033da4c8 \ + --hash=sha256:97d7b9a485b40f8ca425460e89bf1da2814625b2da627c0dcc6aa46c92631d14 \ + --hash=sha256:9bcb8aa397ff0093c824182fd76a935a9ba7ad097fcbef80ae89bf6c1731d8ec \ + --hash=sha256:9d56a78b646f2e3daa865bc70cd5ec5a46c50045801ca8ff17a0c43abc97e3ee \ + --hash=sha256:a5da6976f20cae27059ea8d0c86e7cef3de720e04c4bb9ee18e3690fdb792066 \ + --hash=sha256:a94c5a76ab46c5e6257c7972b6c8cff0574201ca7dc05647e33e795d78680563 \ + --hash=sha256:a95a9248b0c6fd933a442c03c3b113c3b61320086b88e2c444676d3fd1ca3330 \ + --hash=sha256:baf593f2765fa3a6b1ef95807dbaa3d25b594f6a52adcc506a6b9cb115e1be67 \ + --hash=sha256:bb9c2fa06887e21d6a3a868762acb82aec34e2c6fd0174064f27c93ede68ad15 \ + --hash=sha256:bba9ad231e92a3e424b3e56b65aa17704993425bba97e302c832f9466bb85bac \ + --hash=sha256:c3bae4f855d965b5453784300c12ffc63a548304ac7f99e55d4dc7c898673aa3 \ + --hash=sha256:c566c3a88b6ece59b3d70f65bedef17304f48eb52ff040a6a18214e1917b3254 \ + --hash=sha256:cdecf62abcc4292500d7858aeae87a1f8f1150f4c4dd08fb0b336ee79b2a6df3 \ + --hash=sha256:cf5a4db6dca263010e2c7bff081c89383c72d187ba2cf4c44759aac970e2f0c4 \ + --hash=sha256:d52ad8d78522da1d308789df651ee5379088e77c76cb1994858d40a426b343b9 \ + --hash=sha256:e061b58443f1736f8a37c48978d7ab581636d6ab03e3d4f99e3fa90463bb9382 \ + --hash=sha256:e2877a02380adfcdbc69071a0f74d6e9dbbf593c0dc9d174e1f223ffd5281943 \ + --hash=sha256:e73c07f23009962885c197ccb9b41356a30cc0e5a1d0c2ea8fd8fb1362d7f924 \ + --hash=sha256:e8222c26daaafd9e8626dec58ae36029f82585890589576f769a650dd20fd665 \ + --hash=sha256:edfbfca868cdd6bd8d974a60f8a3682f5565d3f5c99b327640cedd24c4264026 \ + --hash=sha256:f376e37f9bf2a946872fc5fd1199c99310748e3c26c7a26683f13f8bdb756cbd # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ @@ -690,9 +690,9 @@ numpy==2.4.4 \ # feast (pyproject.toml) # dask # pandas -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # gunicorn @@ -759,13 +759,13 @@ 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 +prometheus-client==0.25.0 \ + --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ + --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 # via feast (pyproject.toml) protobuf==7.34.1 \ --hash=sha256:34b84ce27680df7cca9f231043ada0daa55d0c44a2ddfaa58ec1d0d89d8bf60a \ @@ -800,188 +800,187 @@ 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.3 \ + --hash=sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927 \ + --hash=sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d # 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.3 \ + --hash=sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba \ + --hash=sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35 \ + --hash=sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4 \ + --hash=sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505 \ + --hash=sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7 \ + --hash=sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8 \ + --hash=sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4 \ + --hash=sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37 \ + --hash=sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25 \ + --hash=sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022 \ + --hash=sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1 \ + --hash=sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7 \ + --hash=sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c \ + --hash=sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3 \ + --hash=sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb \ + --hash=sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3 \ + --hash=sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976 \ + --hash=sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c \ + --hash=sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab \ + --hash=sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa \ + --hash=sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6 \ + --hash=sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396 \ + --hash=sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c \ + --hash=sha256:3d08782c4045f90724b44c95d35ebec0d67edb8a957a2ac81d5a8e4b8a200495 \ + --hash=sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c \ + --hash=sha256:4335e87c7afa436a0dfa899e138d57a72f8aad542e2cf19c36fb428461caabd0 \ + --hash=sha256:4b068543bdb707f5d935dab765d99227aa2545ef2820935f2e5dd801795c7dbd \ + --hash=sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf \ + --hash=sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531 \ + --hash=sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5 \ + --hash=sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda \ + --hash=sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d \ + --hash=sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e \ + --hash=sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df \ + --hash=sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6 \ + --hash=sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c \ + --hash=sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13 \ + --hash=sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536 \ + --hash=sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287 \ + --hash=sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0 \ + --hash=sha256:68ef2f623dda6d5a9067ac014e406c020c780b2a358930a7e5c1b73702900720 \ + --hash=sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050 \ + --hash=sha256:6dff8cc884679df229ebc6d8eb2321ea6f8e091bc7d4886d4dc2e0e71452843c \ + --hash=sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1 \ + --hash=sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8 \ + --hash=sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0 \ + --hash=sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374 \ + --hash=sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807 \ + --hash=sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6 \ + --hash=sha256:831eb19aa789a97356979e94c981e5667759301fb708d1c0d5adf1bc0098b873 \ + --hash=sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57 \ + --hash=sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f \ + --hash=sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c \ + --hash=sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad \ + --hash=sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e \ + --hash=sha256:91249bcb7c165c2fb2a2f852dbc5c91636e2e218e75d96dfdd517e4078e173dd \ + --hash=sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23 \ + --hash=sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46 \ + --hash=sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1 \ + --hash=sha256:99421e7684a60f7f3550a1d159ade5fdff1954baedb6bdd407cba6a307c9f27d \ + --hash=sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1 \ + --hash=sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee \ + --hash=sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c \ + --hash=sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874 \ + --hash=sha256:9f247596366f4221af52beddd65af1218797771d6989bc891a0b86ccaa019168 \ + --hash=sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a \ + --hash=sha256:a35cc284c8dd7edae8a31533713b4d2467dfe7c4f1b5587dd4031f28f90d1d13 \ + --hash=sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f \ + --hash=sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a \ + --hash=sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789 \ + --hash=sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe \ + --hash=sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f \ + --hash=sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5 \ + --hash=sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943 \ + --hash=sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b \ + --hash=sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089 \ + --hash=sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b \ + --hash=sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff \ + --hash=sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67 \ + --hash=sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803 \ + --hash=sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045 \ + --hash=sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8 \ + --hash=sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346 \ + --hash=sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2 \ + --hash=sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f \ + --hash=sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687 \ + --hash=sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76 \ + --hash=sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1 \ + --hash=sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f \ + --hash=sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2 \ + --hash=sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c \ + --hash=sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018 \ + --hash=sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba \ + --hash=sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c \ + --hash=sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf \ + --hash=sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7 \ + --hash=sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47 \ + --hash=sha256:d56bdb4af1767cc15b0386b3c581fdfe659bb9ee4a4f776e92c1cd9d074000d6 \ + --hash=sha256:dcda6583921c05a40533f982321532f2d8db29326c7b95c4026941fa5074bd79 \ + --hash=sha256:dd81f6907932ebac3abbe41378dac64b2380db1287e2aa64d8d88f78d170f51a \ + --hash=sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e \ + --hash=sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a \ + --hash=sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34 \ + --hash=sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b \ + --hash=sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85 \ + --hash=sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca \ + --hash=sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f \ + --hash=sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3 \ + --hash=sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64 \ + --hash=sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22 \ + --hash=sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72 \ + --hash=sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec \ + --hash=sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d \ + --hash=sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3 \ + --hash=sha256:fa3eb7c2995aa443687a825bc30395c8521b7c6ec201966e55debfd1128bcceb \ + --hash=sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395 \ + --hash=sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb \ + --hash=sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4 \ + --hash=sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127 \ + --hash=sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56 # via pydantic pygments==2.20.0 \ --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ @@ -1214,70 +1213,70 @@ 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.49 \ + --hash=sha256:01146546d84185f12721a1d2ce0c6673451a7894d1460b592d378ca4871a0c72 \ + --hash=sha256:059d7151fff513c53a4638da8778be7fce81a0c4854c7348ebd0c4078ddf28fe \ + --hash=sha256:0c98c59075b890df8abfcc6ad632879540f5791c68baebacb4f833713b510e75 \ + --hash=sha256:0f2fa354ba106eafff2c14b0cc51f22801d1e8b2e4149342023bd6f0955de5f5 \ + --hash=sha256:12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148 \ + --hash=sha256:22d8798819f86720bc646ab015baff5ea4c971d68121cb36e2ebc2ee43ead2b7 \ + --hash=sha256:233088b4b99ebcbc5258c755a097aa52fbf90727a03a5a80781c4b9c54347a2e \ + --hash=sha256:24bd94bb301ec672d8f0623eba9226cc90d775d25a0c92b5f8e4965d7f3a1518 \ + --hash=sha256:275424295f4256fd301744b8f335cff367825d270f155d522b30c7bf49903ee7 \ + --hash=sha256:32fe6a41ad97302db2931f05bb91abbcc65b5ce4c675cd44b972428dd2947700 \ + --hash=sha256:334edbcff10514ad1d66e3a70b339c0a29886394892490119dbb669627b17717 \ + --hash=sha256:3bb9ec6436a820a4c006aad1ac351f12de2f2dbdaad171692ee457a02429b672 \ + --hash=sha256:3ddcb27fb39171de36e207600116ac9dfd4ae46f86c82a9bf3934043e80ebb88 \ + --hash=sha256:42e8804962f9e6f4be2cbaedc0c3718f08f60a16910fa3d86da5a1e3b1bfe60f \ + --hash=sha256:43d044780732d9e0381ac8d5316f95d7f02ef04d6e4ef6dc82379f09795d993f \ + --hash=sha256:46796877b47034b559a593d7e4b549aba151dae73f9e78212a3478161c12ab08 \ + --hash=sha256:46d51518d53edfbe0563662c96954dc8fcace9832332b914375f45a99b77cc9a \ + --hash=sha256:47604cb2159f8bbd5a1ab48a714557156320f20871ee64d550d8bf2683d980d3 \ + --hash=sha256:4bbccb45260e4ff1b7db0be80a9025bb1e6698bdb808b83fff0000f7a90b2c0b \ + --hash=sha256:4d4e5a0ceba319942fa6b585cf82539288a61e314ef006c1209f734551ab9536 \ + --hash=sha256:55250fe61d6ebfd6934a272ee16ef1244e0f16b7af6cd18ab5b1fc9f08631db0 \ + --hash=sha256:566df36fd0e901625523a5a1835032f1ebdd7f7886c54584143fa6c668b4df3b \ + --hash=sha256:57ca426a48eb2c682dae8204cd89ea8ab7031e2675120a47924fabc7caacbc2a \ + --hash=sha256:5e61abbec255be7b122aa461021daa7c3f310f3e743411a67079f9b3cc91ece3 \ + --hash=sha256:618a308215b6cececb6240b9abde545e3acdabac7ae3e1d4e666896bf5ba44b4 \ + --hash=sha256:62557958002b69699bdb7f5137c6714ca1133f045f97b3903964f47db97ea339 \ + --hash=sha256:6270d717b11c5476b0cbb21eedc8d4dbb7d1a956fd6c15a23e96f197a6193158 \ + --hash=sha256:685e93e9c8f399b0c96a624799820176312f5ceef958c0f88215af4013d29066 \ + --hash=sha256:69469ce8ce7a8df4d37620e3163b71238719e1e2e5048d114a1b6ce0fbf8c662 \ + --hash=sha256:6eb188b84269f357669b62cb576b5b918de10fb7c728a005fa0ebb0b758adce1 \ + --hash=sha256:74ab4ee7794d7ed1b0c37e7333640e0f0a626fc7b398c07a7aef52f484fddde3 \ + --hash=sha256:77641d299179c37b89cf2343ca9972c88bb6eef0d5fc504a2f86afd15cd5adf5 \ + --hash=sha256:7c821c47ecfe05cc32140dcf8dc6fd5d21971c86dbd56eabfe5ba07a64910c01 \ + --hash=sha256:7d6be30b2a75362325176c036d7fb8d19e8846c77e87683ffaa8177b35135613 \ + --hash=sha256:7f605a456948c35260e7b2a39f8952a26f077fd25653c37740ed186b90aaa68a \ + --hash=sha256:83101a6930332b87653886c01d1ee7e294b1fe46a07dd9a2d2b4f91bcc88eec0 \ + --hash=sha256:88690f4e1f0fbf5339bedbb127e240fec1fd3070e9934c0b7bef83432f779d2f \ + --hash=sha256:8a97ac839c2c6672c4865e48f3cbad7152cee85f4233fb4ca6291d775b9b954a \ + --hash=sha256:8d6efc136f44a7e8bc8088507eaabbb8c2b55b3dbb63fe102c690da0ddebe55e \ + --hash=sha256:8e20e511dc15265fb433571391ba313e10dd8ea7e509d51686a51313b4ac01a2 \ + --hash=sha256:951d4a210744813be63019f3df343bf233b7432aadf0db54c75802247330d3af \ + --hash=sha256:9ac7a3e245fd0310fd31495eb61af772e637bdf7d88ee81e7f10a3f271bff014 \ + --hash=sha256:9b1c058c171b739e7c330760044803099c7fff11511e3ab3573e5327116a9c33 \ + --hash=sha256:9c04bff9a5335eb95c6ecf1c117576a0aa560def274876fd156cfe5510fccc61 \ + --hash=sha256:9c4969a86e41454f2858256c39bdfb966a20961e9b58bf8749b65abf447e9a8d \ + --hash=sha256:9e0400fa22f79acc334d9a6b185dc00a44a8e6578aa7e12d0ddcd8434152b187 \ + --hash=sha256:a05977bffe9bffd2229f477fa75eabe3192b1b05f408961d1bebff8d1cd4d401 \ + --hash=sha256:a143af2ea6672f2af3f44ed8f9cd020e9cc34c56f0e8db12019d5d9ecf41cb3b \ + --hash=sha256:a51d3db74ba489266ef55c7a4534eb0b8db9a326553df481c11e5d7660c8364d \ + --hash=sha256:b95b2f470c1b2683febd2e7eab1d3f0e078c91dbdd0b00e9c645d07a413bb99f \ + --hash=sha256:b9870d15ef00e4d0559ae10ee5bc71b654d1f20076dbe8bc7ed19b4c0625ceba \ + --hash=sha256:c1dc3368794d522f43914e03312202523cc89692f5389c32bea0233924f8d977 \ + --hash=sha256:c338ec6ec01c0bc8e735c58b9f5d51e75bacb6ff23296658826d7cfdfdb8678a \ + --hash=sha256:c5070135e1b7409c4161133aa525419b0062088ed77c92b1da95366ec5cbebbe \ + --hash=sha256:cc992c6ed024c8c3c592c5fc9846a03dd68a425674900c70122c77ea16c5fb0b \ + --hash=sha256:d15950a57a210e36dd4cec1aac22787e2a4d57ba9318233e2ef8b2daf9ff2d5f \ + --hash=sha256:d898cc2c76c135ef65517f4ddd7a3512fb41f23087b0650efb3418b8389a3cd1 \ + --hash=sha256:d99945830a6f3e9638d89a28ed130b1eb24c91255e4f24366fbe699b983f29e4 \ + --hash=sha256:da9b91bca419dc9b9267ffadde24eae9b1a6bffcd09d0a207e5e3af99a03ce0d \ + --hash=sha256:df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120 \ + --hash=sha256:e06e617e3d4fd9e51d385dfe45b077a41e9d1b033a7702551e3278ac597dc750 \ + --hash=sha256:ec44cfa7ef1a728e88ad41674de50f6db8cfdb3e2af84af86e0041aaf02d43d0 \ + --hash=sha256:fb37f15714ec2652d574f021d479e78cd4eb9d04396dca36568fdfffb3487982 # via feast (pyproject.toml) starlette==1.0.0 \ --hash=sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149 \ @@ -1329,9 +1328,9 @@ 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 \ @@ -1572,7 +1571,7 @@ websockets==16.0 \ --hash=sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da \ --hash=sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4 # via uvicorn -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==3.23.1 \ + --hash=sha256:0b3596c50a5c700c9cb40ba8d86d9f2cc4807e9bedb06bcdf7fac85633e444dc \ + --hash=sha256:32120e378d32cd9714ad503c1d024619063ec28aad2248dc6672ad13edfa5110 # via importlib-metadata diff --git a/sdk/python/requirements/py3.12-ci-requirements.txt b/sdk/python/requirements/py3.12-ci-requirements.txt index 8fe44b610b6..fd43a7b70a9 100644 --- a/sdk/python/requirements/py3.12-ci-requirements.txt +++ b/sdk/python/requirements/py3.12-ci-requirements.txt @@ -251,9 +251,9 @@ attrs==26.1.0 \ # jsonschema # openlineage-python # referencing -azure-core==1.39.0 \ - --hash=sha256:4ac7b70fab5438c3f68770649a78daf97833caa83827f91df9c14e0e0ea7d34f \ - --hash=sha256:8a90a562998dd44ce84597590fff6249701b98c0e8797c95fcdd695b54c35d74 +azure-core==1.40.0 \ + --hash=sha256:7f3ea02579b1bb1d34e45043423b650621d11d7c2ea3b05e5554010080b78dfd \ + --hash=sha256:ecf5b6ddf2564471fae9d576147b7e77a4da285958b2d9f4fd6c3af104f3e9d7 # via # azure-identity # azure-storage-blob @@ -366,49 +366,44 @@ botocore==1.38.46 \ # moto # s3transfer # snowflake-connector-python -build==1.4.2 \ - --hash=sha256:35b14e1ee329c186d3f08466003521ed7685ec15ecffc07e68d706090bf161d1 \ - --hash=sha256:7a4d8651ea877cb2a89458b1b198f2e69f536c95e89129dbf5d448045d60db88 +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 +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.4.22 \ + --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ + --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 # via # clickhouse-connect # docling @@ -646,9 +641,9 @@ charset-normalizer==3.4.7 \ # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.3.3 \ + --hash=sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2 \ + --hash=sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 # via # feast (pyproject.toml) # dask @@ -996,9 +991,9 @@ dask[dataframe]==2026.3.0 \ --hash=sha256:be614b9242b0b38288060fb2d7696125946469c98a1c30e174883fd199e0428d \ --hash=sha256:f7d96c8274e8a900d217c1ff6ea8d1bbf0b4c2c21e74a409644498d925eb8f85 # via feast (pyproject.toml) -datasets==4.8.4 \ - --hash=sha256:a1429ed853275ce7943a01c6d2e25475b4501eb758934362106a280470df3a52 \ - --hash=sha256:cdc8bee4698e549d78bf1fed6aea2eebc760b22b084f07e6fc020c6577a6ce6d +datasets==4.8.5 \ + --hash=sha256:0f0c1c3d56ffff2c93b2f4c63c95bac94f3d7e8621aea2a2a576275233bba772 \ + --hash=sha256:5079900781719c0e063a8efdd2cd95a31ad0c63209178669cd23cf1b926149ff # via feast (pyproject.toml) db-dtypes==1.5.1 \ --hash=sha256:901099b807c9312bc61a5bddbfb07512884e6c6d5a9edacf24d50bcf303aa5f7 \ @@ -1006,9 +1001,9 @@ db-dtypes==1.5.1 \ # via # google-cloud-bigquery # pandas-gbq -dbt-artifacts-parser==0.13.0 \ - --hash=sha256:304f2b857650566fed4ed8b976ed3582332eda3cedfe7167158dbbcfced3fe47 \ - --hash=sha256:55498e8bd0d9064d56617f9c714ced8607d94ccb61e70d4b49dcfd8a28a030d8 +dbt-artifacts-parser==0.13.1 \ + --hash=sha256:c341730fa34ebb38cc7d2de0282e8b713e2fc65fc6577f0d944f8abee8949dc4 \ + --hash=sha256:c7a3c4e309ae2d7d566a615e92043b0d346a77998203b0cc466234717b806e40 # via feast (pyproject.toml) debugpy==1.8.20 \ --hash=sha256:077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad \ @@ -1061,6 +1056,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 @@ -1076,6 +1075,12 @@ distlib==0.4.0 \ --hash=sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 \ --hash=sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d # 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 @@ -1084,16 +1089,16 @@ docling==2.27.0 \ --hash=sha256:1288ed75b27e33bf94daff34faffc6d11b7d7ccc13e3df84fb24adad3991f72d \ --hash=sha256:faba35662612a2c687a3a463e501d95f645316436084af92a0442ce162429a3d # via feast (pyproject.toml) -docling-core[chunking]==2.71.0 \ - --hash=sha256:4761857816853b2b35263b5b4518e1ea6214e0565db0bbf1d929fb976665d1a0 \ - --hash=sha256:4caa9f50c68b9dd332584ae16170b36db05d773532b14d7078b580d89d8bd2a4 +docling-core[chunking]==2.74.1 \ + --hash=sha256:46bf298686f2c51ddd69b6935a27dff1cc80838f2f5f1a8823492d99cf1a357b \ + --hash=sha256:e6464078012b3d45f4e0accd101fcb277063903f355eabbb9aee8de00527a789 # via # docling # docling-ibm-models # docling-parse -docling-ibm-models==3.13.0 \ - --hash=sha256:a11acc6034b06e0bed8dc0ca1fa700615b8246eacce411619168e1f6562b0d0d \ - --hash=sha256:f402effae8a63b0e5c3b5ce13120601baa2cd8098beef1d53ab5a056443758d3 +docling-ibm-models==3.13.2 \ + --hash=sha256:195e02dd119df34d2ce5f76ac614da82825851013e4898db7b0468cdf8740a3d \ + --hash=sha256:5fa0838bf15a4e06d2fcb686d756a6f4c329ea0a8820d085f06d07abe96269ed # via docling docling-parse==4.7.3 \ --hash=sha256:1790e7e4ae202d67875c1c48fd6f8ef5c51d10b0c23157e4989b8673f2f31308 \ @@ -1128,42 +1133,42 @@ docutils==0.19 \ --hash=sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6 \ --hash=sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc # via sphinx -duckdb==1.5.1 \ - --hash=sha256:054ad424b051b334052afac58cb216f3b1ebb8579fc8c641e60f0182e8725ea9 \ - --hash=sha256:05fc91767d0cfc4cf2fa68966ab5b479ac07561752e42dd0ae30327bd160f64a \ - --hash=sha256:0a6acc2040bec1f05de62a2f3f68f4c12f3ec7d6012b4317d0ab1a195af26225 \ - --hash=sha256:26e56b5f0c96189e3288d83cf7b476e23615987902f801e5788dee15ee9f24a9 \ - --hash=sha256:36e8e32621a9e2a9abe75dc15a4b54a3997f2d8b1e53ad754bae48a083c91130 \ - --hash=sha256:40c5220ec93790b18ec6278da9c6ac2608d997ee6d6f7cd44c5c3992764e8e71 \ - --hash=sha256:446d500a2977c6ae2077f340c510a25956da5c77597175c316edfa87248ceda3 \ - --hash=sha256:46f92ada9023e59f27edc048167b31ac9a03911978b1296c845a34462a27f096 \ - --hash=sha256:482f8a13f2600f527e427f73c42b5aa75536f9892868068f0aaf573055a0135f \ - --hash=sha256:553c273a6a8f140adaa6da6a6135c7f95bdc8c2e5f95252fcdf9832d758e2141 \ - --hash=sha256:5ae7c0d744d64e2753149634787cc4ab60f05ef1e542b060eeab719f3cdb7723 \ - --hash=sha256:5d4147422d91ccdc2d2abf6ed24196025e020259d1d267970ae20c13c2ce84b1 \ - --hash=sha256:6af347debc8b721aa72e48671166282da979d5e5ae52dbc660ab417282b48e23 \ - --hash=sha256:6ba302115f63f6482c000ccfd62efdb6c41d9d182a5bcd4a90e7ab8cd13856eb \ - --hash=sha256:6f7361d66cc801d9eb4df734b139cd7b0e3c257a16f3573ebd550ddb255549e6 \ - --hash=sha256:715f05ea198d20d7f8b407b9b84e0023d17f2b9096c194cea702b7840e74f1f7 \ - --hash=sha256:71dddcebbc5a70e946a06c30b59b5dd7999c9833d307168f90fb4e4b672ab63e \ - --hash=sha256:8150c569b2aa4573b51ba8475e814aa41fd53a3d510c1ffb96f1139f46faf611 \ - --hash=sha256:8843bd9594e1387f1e601439e19ad73abdf57356104fd1e53a708255bb95a13d \ - --hash=sha256:8c0088765747ae5d6c9f89987bb36f9fb83564f07090d721344ce8e1abedffea \ - --hash=sha256:972d0dbf283508f9bc446ee09c3838cb7c7f114b5bdceee41753288c97fe2f7c \ - --hash=sha256:a28531cee2a5a42d89f9ba4da53bfeb15681f12acc0263476c8705380dadce07 \ - --hash=sha256:a3be2072315982e232bfe49c9d3db0a59ba67b2240a537ef42656cc772a887c7 \ - --hash=sha256:ac2804043bd1bc10b5da18f8f4c706877197263a510c41be9b4c0062f5783dcc \ - --hash=sha256:afab8b4b1f4469c3879bb049dd039f8fce402712050324e9524a43d7324c5e87 \ - --hash=sha256:b370d1620a34a4538ef66524fcee9de8171fa263c701036a92bc0b4c1f2f9c6d \ - --hash=sha256:b8b0808dba0c63b7633bdaefb34e08fe0612622224f9feb0e7518904b1615101 \ - --hash=sha256:bc7ca6a1a40e7e4c933017e6c09ef18032add793df4e42624c6c0c87e0bebdad \ - --hash=sha256:caa65e1f5bf007430bf657c37cab7ab81a4ddf8d337e3062bcc5085d17ef038b \ - --hash=sha256:d68c5a01a283cb13b79eafe016fe5869aa11bff8c46e7141c70aa0aac808010f \ - --hash=sha256:da137802688190835b4c863cafa77fd7e29dff662ee6d905a9ffc14f00299c91 \ - --hash=sha256:e56a20ab6cdb90a95b0c99652e28de3504ce77129087319c03c9098266183ae5 \ - --hash=sha256:e878ccb7d20872065e1597935fdb5e65efa43220c8edd0d9c4a1a7ff1f3eb277 \ - --hash=sha256:eba81e0b3011c1f23df7ea47ef4ffaa8239817959ae291515b6efd068bde2161 \ - --hash=sha256:ed6d23a3f806898e69c77430ebd8da0c79c219f97b9acbc9a29a653e09740c59 +duckdb==1.5.2 \ + --hash=sha256:0b291786014df1133f8f18b9df4d004484613146e858d71a21791e0fcca16cf4 \ + --hash=sha256:2323c1195c10fb2bb982fc0218c730b43d1b92a355d61e68e3c5f3ac9d44c34f \ + --hash=sha256:2a1de4f4d454b8c97aec546c82003fc834d3422ce4bc6a19902f3462ef293bed \ + --hash=sha256:35579b8e3a064b5eaf15b0eafc558056a13f79a0a62e34cc4baf57119daecfec \ + --hash=sha256:376856066c65ccd55fcb3a380bbe33a71ce089fc4623d229ffc6e82251afdb6d \ + --hash=sha256:411ad438bd4140f189a10e7f515781335962c5d18bd07837dc6d202e3985253d \ + --hash=sha256:4420b3f47027a7849d0e1815532007f377fa95ee5810b47ea717d35525c12f79 \ + --hash=sha256:486c862bf7f163c0110b6d85b3e5c031d224a671cca468f12ebb1d3a348f6b39 \ + --hash=sha256:52a21823f3fbb52f0f0e5425e20b07391ad882464b955879499b5ff0b45a376b \ + --hash=sha256:5596bbfc31b1b259db69c8d847b42d036ce2c4804f9ccb28f9fc46a16de7bc53 \ + --hash=sha256:56d38b3c4e0ef2abb58898d0fd423933999ed535c45e75e9d9f72e1d5fed69b8 \ + --hash=sha256:638da0d5102b6cb6f7d47f83d0600708ac1d3cb46c5e9aaabc845f9ba4d69246 \ + --hash=sha256:63bf8687feefeed51adf45fa3b062ab8b1b1c350492b7518491b86bae68b1da1 \ + --hash=sha256:6b0fe75c148000f060aa1a27b293cacc0ea08cc1cad724fbf2143d56070a3785 \ + --hash=sha256:70631c847ca918ee710ec874241b00cf9d2e5be90762cbb2a0389f17823c08f7 \ + --hash=sha256:7f69164b048e498b9e9140a24343108a5ae5f17bfb3485185f55fdf9b1aa924d \ + --hash=sha256:81fc4fbf0b5e25840b39ba2a10b78c6953c0314d5d0434191e7898f34ab1bba3 \ + --hash=sha256:84b193aca20565dedb3172de15f843c659c3a6c773bf14843a9bd781c850e7db \ + --hash=sha256:8d599758b4e48bf12e18c9b960cf491d219f0c4972d19a45489c05cc5ab36f83 \ + --hash=sha256:8dbd7e31e5dc157bfe8803fa7d2652336265c6c19926c5a4a9b40f8222868d08 \ + --hash=sha256:98c0535cd6d901f61a5ea3c2e26a1fd28482953d794deb183daf568e3aa5dda6 \ + --hash=sha256:a9cd5e71702d446613750405cde03f66ed268f4c321da071b0472759dad19536 \ + --hash=sha256:bb42e6ed543902e14eae647850da24103a89f0bc2587dec5601b1c1f213bd2ed \ + --hash=sha256:be37680ddb380015cb37318e378c53511c45c4f0d8fac5599d22b7d092b9217a \ + --hash=sha256:c69907354ffee94ba8cf782daf0480dab7557f21ce27fffa6c0ea8f74ed4b8e2 \ + --hash=sha256:c99ef73a277c8921bc0a1f16dee38d924484251d9cfd20951748c20fcd5ed855 \ + --hash=sha256:c9f3e0b71b8a50fccfb42794899285d9d318ce2503782b9dd54868e5ecd0ad31 \ + --hash=sha256:ce0b8141a10d37ecef729c45bc41d334854013f4389f1488bd6035c5579aaac1 \ + --hash=sha256:ce17670bb392ea1b3650537db02bd720908776b5b95f6d2472d31a7de59d1dc1 \ + --hash=sha256:d72b8856b1839d35648f38301b058f6232f4d36b463fe4dc8f4d3fdff2df1a2e \ + --hash=sha256:d9b4f5430bf4f05d4c0dc4c55c75def3a5af4be0343be20fa2bfc577343fbfc9 \ + --hash=sha256:e6495b00cad16888384119842797c49316a96ae1cb132bb03856d980d95afee1 \ + --hash=sha256:ea58ff5b0880593a280cf5511734b17711b32ee1f58b47d726e8600848358160 \ + --hash=sha256:ef461bca07313412dc09961c4a4757a851f56b95ac01c58fac6007632b7b94f2 \ + --hash=sha256:fc85a5dbcbe6eccac1113c72370d1d3aacfdd49198d63950bdf7d8638a307f00 # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ @@ -1225,9 +1230,9 @@ faiss-cpu==1.10.0 \ --hash=sha256:e71f7e24d5b02d3a51df47b77bd10f394a1b48a8331d5c817e71e9e27a8a75ac \ --hash=sha256:f71c5860c860df2320299f9e4f2ca1725beb559c04acb1cf961ed24e6218277a # via feast (pyproject.toml) -fastapi==0.135.3 \ - --hash=sha256:9b0f590c813acd13d0ab43dd8494138eb58e484bfac405db1f3187cfc5810d98 \ - --hash=sha256:bd6d7caf1a2bdd8d676843cdcd2287729572a1ef524fc4d65c17ae002a1be654 +fastapi==0.136.1 \ + --hash=sha256:7af665ad7acfa0a3baf8983d393b6b471b9da10ede59c60045f49fbc89a0fa7f \ + --hash=sha256:a6e9d7eeada96c93a4d69cb03836b44fa34e2854accb7244a1ece36cd4781c3f # via # feast (pyproject.toml) # fastapi-mcp @@ -1239,9 +1244,9 @@ fastjsonschema==2.21.2 \ --hash=sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463 \ --hash=sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de # via nbformat -filelock==3.25.2 \ - --hash=sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694 \ - --hash=sha256:ca8afb0da15f229774c9ad1b455ed96e85a81373065fb10446672f64444ddf70 +filelock==3.29.0 \ + --hash=sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90 \ + --hash=sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258 # via # datasets # huggingface-hub @@ -1406,9 +1411,9 @@ geomet==1.1.0 \ --hash=sha256:4372fe4e286a34acc6f2e9308284850bd8c4aa5bc12065e2abbd4995900db12f \ --hash=sha256:51e92231a0ef6aaa63ac20c443377ba78a303fd2ecd179dc3567de79f3c11605 # via cassandra-driver -google-api-core[grpc]==2.30.2 \ - --hash=sha256:9a8113e1a88bdc09a7ff629707f2214d98d61c7f6ceb0ea38c42a095d02dc0f9 \ - --hash=sha256:a4c226766d6af2580577db1f1a51bf53cd262f722b49731ce7414c43068a9594 +google-api-core[grpc]==2.30.3 \ + --hash=sha256:a85761ba72c444dad5d611c2220633480b2b6be2521eca69cca2dbb3ffd6bfe8 \ + --hash=sha256:e601a37f148585319b26db36e219df68c5d07b6382cff2d580e83404e44d641b # via # feast (pyproject.toml) # google-cloud-bigquery @@ -1419,9 +1424,9 @@ google-api-core[grpc]==2.30.2 \ # google-cloud-storage # opencensus # pandas-gbq -google-auth==2.49.1 \ - --hash=sha256:16d40da1c3c5a0533f57d268fe72e0ebb0ae1cc3b567024122651c045d879b64 \ - --hash=sha256:195ebe3dca18eddd1b3db5edc5189b76c13e96f29e73043b923ebcf3f1a860f7 +google-auth==2.50.0 \ + --hash=sha256:04382175e28b94f49694977f0a792688b59a668def1499e9d8de996dc9ce5b15 \ + --hash=sha256:f35eafb191195328e8ce10a7883970877e7aeb49c2bfaa54aa0e394316d353d0 # via # google-api-core # google-auth-oauthlib @@ -1717,101 +1722,112 @@ hf-xet==1.4.3 \ --hash=sha256:e23717ce4186b265f69afa66e6f0069fe7efbf331546f5c313d00e123dc84583 \ --hash=sha256:fc360b70c815bf340ed56c7b8c63aacf11762a4b099b2fe2c9bd6d6068668c08 # 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.3.1 \ + --hash=sha256:002fc0201b9af1cc8960e27cdc501ad1f8cdd6dbadb2091c6ddbd4e5ace6cb77 \ + --hash=sha256:011a9071c3df4885cac7f58a2623feac6c8e2ad30e6ba93c55195af05ce61ff5 \ + --hash=sha256:01cf82a514bc4fd145b99333c28523e61b7a9ad051a245804323ebf4e7b1c6a6 \ + --hash=sha256:027ce4fabfeff5af5b9869d5524770877f9061d118bc36b85703ae3faf5aad8e \ + --hash=sha256:03baa381964b8df356d19ec4e3a6ae656044249a87b0def257fe1e08dbaf6094 \ + --hash=sha256:042e57de8a2cae91e3e7c0af32960ea2c5107b2f27f68a740295861e68780a8a \ + --hash=sha256:09d41a3a965f7c261223d516ebda607aee4d8440dd7637f01af9a4c05872f0c4 \ + --hash=sha256:09f5e510f637f2c72d2a79fb3ad05f7b6211e057e367ca5c4f97bb3d8c9d71f4 \ + --hash=sha256:0b5ff2f643f4b452b0597b7fe6aa35d398cb31d8806801acfafb1558610ea2aa \ + --hash=sha256:0caf3fc8af0767794b335753781c3fa35f2a3e975c098edbc8f733d35d6a95e4 \ + --hash=sha256:0fac4af8515e6cca74fc701169ae4dc9a71a90e9319c9d21006ec9454b43aa2f \ + --hash=sha256:113e098e4a6b3cc5500e05e7cb1548ba9e83de5fe755941b11f6020a76e6c03a \ + --hash=sha256:137c14905ea6f2933967200bc7b2a0c8ec9387888b273fd0004f25b994fd0343 \ + --hash=sha256:156be6a0c736ee145cfe0fb155d0e96cec8d4872cf8b4f76ad6a2ee6ab391d0a \ + --hash=sha256:17ec8b524055a88b80d76c177dbbbe475a25c17c5bf4b67bdbdbd0629bcae838 \ + --hash=sha256:1ac7697365dbe45109273b34227fee6826b276ead9a4a007e0877e1d3f0fcf21 \ + --hash=sha256:1b46e96b50dad03495447860510daebd2c96fd44ed25ba8ccb03e9f89eaa9d34 \ + --hash=sha256:1ebc307a87b099d0877dbd2bdc0bae427258e7ec67f60a951e89027f8dc2568f \ + --hash=sha256:1f7bceb03a1b934872ffe3942eaeed7c7e09096e67b53f095b81f39c7a819113 \ + --hash=sha256:2611bfaaadc5e8d43fb7967f9bbf1110c8beaa83aee2f2d812c76f11cfb56c6a \ + --hash=sha256:264ee7e9cb6c30dc78da4ecf71d74cf14ca122817c665d838eda8b4384bce1b0 \ + --hash=sha256:26f899cde0279e4b7d370716ff80320601c2bd93cdf3e774a42bdd44f65b41f8 \ + --hash=sha256:29fe35e3c6fe03204e75c86514f452591957a1e06b05d86e10d795455b71c355 \ + --hash=sha256:2afc675b831f7552da41116fffffca4340f387dc03f56d6ec0c7895ab0b59a10 \ + --hash=sha256:2b6da6e07359107c653a809b3cff2d9ccaeedbafe33c6f16434aef6f53ce4a2b \ + --hash=sha256:2b96da7e365d6488d2a75266a662cbe3cc14b28c23dd9b0c9aa04b5bc5c20192 \ + --hash=sha256:2f1c1b2e8f00b71e6214234d313f655a3a27cd4384b054126ce04073c1d47045 \ + --hash=sha256:304481241e081bc26f0778b2c2b99f9c43917e4e724a016dcc9439b7ab12c726 \ + --hash=sha256:318f772dd321404075d406825266e574ee0f4751be1831424c2ebd5722609398 \ + --hash=sha256:3586c8a5f56d34b9dddaaa9e76905f31933cac267251006adf86ec0eef7d0400 \ + --hash=sha256:3724f0e58c6ff76fd683429945491de71324ab1bc0ad943a8d68cb0932d24075 \ + --hash=sha256:3fb6573efa15a29c12c0c0f7170b14e7c1347fe4bb39b6a15b779f46015cc929 \ + --hash=sha256:40ae8a7041fcb328a6bc7202d8c4e6e0d38d434b2e3880b1ee8ed754f17cd836 \ + --hash=sha256:4106201cd052d9eabe3cb7b5a24b0fe37307792bda4fcb3cf6ddd72f697828e8 \ + --hash=sha256:439f9a5cc8f9519ce208a24cdebfa0440fef26aa682a40ba2c92acb10a53f5e0 \ + --hash=sha256:4479e36d263251dba8ab8ea81adf07e7f1163603c7102c5de1e130b83b4fad3b \ + --hash=sha256:487658e1db83c1ee9fbbac6a43039ea76957767a5987ffb16b590613f9e68297 \ + --hash=sha256:48ff424f8aa36aacd9fdaa68efeb27d2e8771f293af4305bdb15d92194ca6631 \ + --hash=sha256:4f7e242eab698ad0be5a4b2ec616fa856569c57455cc67c625fd567726290e5f \ + --hash=sha256:526db52e5234a9463520e960a509d6c1bd5128d1ab1b569cbf459fe39189e8ab \ + --hash=sha256:52d5641027d6731bc7b5e7d126a5158a99784a9f8c6de3d97ca89aca4969e9f8 \ + --hash=sha256:53148a4e21057541b6d8e493b2ea1b500037ddf34433c391970036f3cbce00e3 \ + --hash=sha256:583de2f16528e66081cbdfe510d8488c2de73039dc00aada7d22bd49d73a4a94 \ + --hash=sha256:5e55d90b431b0c6b64ae5a624208d4aea318566d31872e595ee723c0f5b9a79f \ + --hash=sha256:5f316cf2d0558f5027aab19dde7d7e4901c26c21fa95367bc37784e8f547bbf2 \ + --hash=sha256:60543f3b068b16a86e99ed96b7fdae71cdc1d8abdfe9b3f82032a555e52ece7e \ + --hash=sha256:62cc62284541bb2a86c898c7d5e8388661cade91c184cb862095ed547e80588f \ + --hash=sha256:65c05b79cb8366c123357b354a16f9fc3f7187159422f143638d1c26b7240ed4 \ + --hash=sha256:65f6ac06a9f0c32c254660ec6a9329d81d589e8f5d0a9837a941d5424a6be1ef \ + --hash=sha256:6d1434d0bcc1b3ef048bae53f26456405c08aeed9827e65b24094f5f3a6793f1 \ + --hash=sha256:6e2e1024f0a021777740cb7c633a0efb2c4a4bc570f508223a8dcbcf79f99ef9 \ + --hash=sha256:6ffa7ba2e2da1f806f3181b9730b3e87ba9dbfec884806725d4584055ba3faa6 \ + --hash=sha256:743b85bd6902856cac457ddd8cd7dd48c89c47d641b6016ff5e4d015bfbd4799 \ + --hash=sha256:77c5d2bebbc9d06691abb512a31d0f54e1562af0b872891463a67a949b5278ef \ + --hash=sha256:79cd03e7ff550c17758a7520bf437c156d3d4c8bb74214deeafa69cda49c85a4 \ + --hash=sha256:80aba5f85d6227faee628ae28d1c3b69c661806a0636548ac56c68782606454f \ + --hash=sha256:81a1669b6631976b1dc9d3d58ed1ab3333e9f52feb91a2a1fb8241101ac3b665 \ + --hash=sha256:8597c35c9e82f65fd5897c4a2188c65d7daf10607b102960137b23d261cd957b \ + --hash=sha256:8650158217b469d8b6087f490929211b0493a9121154c4efaafd1dec9e19319e \ + --hash=sha256:8887bf0f31e4b550bd988c8863b527b6587d200653e9375cd91eea2b944b7424 \ + --hash=sha256:8a52b24cd710690c4a7e191c7e300136ad2ecb3c68ffe7e95b598e76de166e5e \ + --hash=sha256:8e3754ce60e1b11b0afad9a053481ff184d2ee24bea47099107156d1b84a84aa \ + --hash=sha256:907f7b5501a534030738f0f27459a612d2266fd0507b007bb8f3e6de08167920 \ + --hash=sha256:90d6b9f2652303aefd2c5a26a5e14cb74a3a63d10faa642c08d790e99442a088 \ + --hash=sha256:98fd5b39410e9d69e10e90d0330e35650becaa5dd2548f509b9598f1f3c6124d \ + --hash=sha256:9bfdeff778d3f7ff449ca5922ab773899e7d31e26a576028b06a5e9cf0ed8c34 \ + --hash=sha256:9ebae74ce2b977c2fcb22d6a10aa0acb730022406977b2bcb6ddd6788f5c414a \ + --hash=sha256:a110d19881ca78a88583d3b07231e7c6864864f5f1f3491b638863ea45fa8708 \ + --hash=sha256:a1d190790ee39b8b7adeeb10fc4090dc4859eb4e75ed27bd8108710eef18f358 \ + --hash=sha256:a2f049c3f3c83e886cd1f53958e2a1ebb369be626bef9e50d8b24d79864f1df6 \ + --hash=sha256:a3af4e9f277d6b8acd369dc44a723a055752fca9d045094383af39f90a3e3729 \ + --hash=sha256:a42c7becd4c9ec4ab5769c754eb61112777bdc6e1c1525e2077389e193b5f5aa \ + --hash=sha256:a58a58cef0d911b1717154179a9ff47852249c536ea5966bde4370b6b20638ff \ + --hash=sha256:ab1f646ff531d70bfd25f01e60708dfa3d105eb458b7dedd9fe9a443039fd809 \ + --hash=sha256:ad940dc2db545dc978cb41cb9a683e2ff328f3ef581230b9ca40ff6c3d01d542 \ + --hash=sha256:afe3c3863f16704fb5d7c2c6ff56aaf9e054f6d269f7b4c9074c5476178d1aba \ + --hash=sha256:b1e3b9f4bf9a4120510ba77a77b2fb674893cd6795653545152bb11a79eecfcb \ + --hash=sha256:b2390ad81c03d93ef1d5afd18ffcf5935de827f1a2b96b2c829437968bdabccb \ + --hash=sha256:b37df4b10cb15dedfc203f69312d8eedd617b941c21df58c13af59496c53ad0f \ + --hash=sha256:b3df9447f9209f9aa0434ca74050e9509670c1ad99398fe5807abb90e5f3a014 \ + --hash=sha256:b4fe7f38aa8956fcc1cea270e62601e0e11066aff78e384be70fd283d30293b6 \ + --hash=sha256:c1d68c6980d4690a4550bd3db6c03146f7be68ef5d08d38bb1fb68b3e9c32fe3 \ + --hash=sha256:c24c1460486b6b36083252c2db21a814becf8495ccd0e76b7286623e37239b63 \ + --hash=sha256:c25132902d3eff38781e0d54f27a0942ec849e3c07dbdce83c4d92b7e43c8dce \ + --hash=sha256:c74bd9926954e7e575f9cd9890f63defd90cd8f812dfbf8e1efb72acc9355456 \ + --hash=sha256:c8139e9011117822391c5bcfd674c5948fb1e4b8cb9adf6f13d9890859ee3a1a \ + --hash=sha256:ce334915f5d31048f76a42c607bf26687cf045eb1bc852b7340f09729c6a64fc \ + --hash=sha256:d14229beaa76e66c3a25f9477d973336441ca820df853679a98796256813316f \ + --hash=sha256:d42f3a13290f89191568fc113d95a3d2c8759cdd8c3672f021d8b7436f909e75 \ + --hash=sha256:d8e56e0d1fe607bfff422633f313aec9191c3859ab99d11ff097e3e6e068000c \ + --hash=sha256:da6f0302360e99d32bc2869772692797ebadd536e1b826d0103c72ba49d38698 \ + --hash=sha256:db46baf157feefd88724e6a7f145fe996a5990a8604ed9292b45d563360e513b \ + --hash=sha256:dcea8c3f53674ae68e44b12e853b844a1d315250ca6677b11ec0c06aff85e86c \ + --hash=sha256:de94b409f49eb6a588ebdd5872e826caec417cd77c17af0fb94f2128427f1a2a \ + --hash=sha256:e0356561b4a97c83b9ee3de657a41b8d1a1781226853adaf47b550bb988fda6f \ + --hash=sha256:e0db44cf81e4d7b94f3776b9f89111f74ed6bbdbfd42a22bc4a5ce0644d3e060 \ + --hash=sha256:e31e92b61d56244047ad600812e16f7587a6172f74810fd919ff993af12b9149 \ + --hash=sha256:e89dabf436ee79b358fd970dcbed6333a36d91db73f27069ca24a02fb138a404 \ + --hash=sha256:eddeb9a153795cf6e615f9f3cef66a1d573ff3b6ee16df2b10d1d1c2f2baeaa8 \ + --hash=sha256:ee11fd431f83d8a5b29d370b9d79a814d3218d30113bdcd44657e9bdf715fc92 \ + --hash=sha256:ee37fe8cf081b72dea72f96a0ee604f492ec02252eb77dc26ff6eec3f997b580 \ + --hash=sha256:f19ee7dc1ef8a6497570d91fa4057ba910ad98297a50b8c44ff37589f7c89d17 \ + --hash=sha256:f2f94355affd51088f57f8674b0e294704c3c7c3d7d3b1545310f5b135d4843b \ + --hash=sha256:f525734382a47f9828c9d6a1501522c78d5935466d8e2be1a41ba40ca5bb922b \ + --hash=sha256:f915a34fb742e23d0d61573349aa45d6f74037fde9d58a9f340435eff8d62736 # via feast (pyproject.toml) hpack==4.1.0 \ --hash=sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496 \ @@ -1902,13 +1918,13 @@ ibis-framework[duckdb, mssql, oracle]==12.0.0 \ --hash=sha256:0bbd790f268da9cb87926d5eaad2b827a573927113c4ed3be5095efa89b9e512 \ --hash=sha256:238624f2c14fdab8382ca2f4f667c3cdb81e29844cd5f8db8a325d0743767c61 # via feast (pyproject.toml) -identify==2.6.18 \ - --hash=sha256:873ac56a5e3fd63e7438a7ecbc4d91aca692eb3fefa4534db2b7913f3fc352fd \ - --hash=sha256:8db9d3c8ea9079db92cafb0ebf97abdc09d52e97f4dcf773a2e694048b7cd737 +identify==2.6.19 \ + --hash=sha256:20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a \ + --hash=sha256:6be5020c38fcb07da56c53733538a3081ea5aa70d36a156f83044bfbf9173842 # via pre-commit -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.13 \ + --hash=sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242 \ + --hash=sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 # via # anyio # httpx @@ -1928,17 +1944,17 @@ 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-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 \ @@ -2055,9 +2071,9 @@ 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.1 \ --hash=sha256:71b954d834e85ff3096400554f2eefaf7fe37053036f9a782b0f7c5e42dadb81 \ @@ -2076,9 +2092,9 @@ jupyter-server-terminals==0.5.4 \ --hash=sha256:55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14 \ --hash=sha256:bbda128ed41d0be9020349f9f1f2a4ab9952a73ed5f5ac9f1419794761fb87f5 # via jupyter-server -jupyterlab==4.5.6 \ - --hash=sha256:642fe2cfe7f0f5922a8a558ba7a0d246c7bc133b708dfe43f7b3a826d163cf42 \ - --hash=sha256:d6b3dac883aa4d9993348e0f8e95b24624f75099aed64eab6a4351a9cdd1e580 +jupyterlab==4.5.7 \ + --hash=sha256:55a9822c4754da305f41e113452c68383e214dcf96de760146af89ce5d5117b0 \ + --hash=sha256:fba4cb0e2c44a52859669d8c98b45de029d5e515f8407bf8534d2a8fc5f0964d # via notebook jupyterlab-pygments==0.3.0 \ --hash=sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d \ @@ -2094,9 +2110,9 @@ 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 kube-authkit==0.4.0 \ --hash=sha256:1df61ac392fca96c8f5ae8c3d6e9918f1e1655d212434b3c3da5f92cc23b660d \ @@ -2113,9 +2129,9 @@ lark==1.3.1 \ --hash=sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905 \ --hash=sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12 # via rfc3987-syntax -latex2mathml==3.79.0 \ - --hash=sha256:11bde318c2d2d6fcdd105a07509d867cee2208f653278eb80243dec7ea77a0ce \ - --hash=sha256:9f10720d4fcf6b22d1b81f6628237832419a7a29783c13aa92fa8d680165e63d +latex2mathml==3.81.0 \ + --hash=sha256:4b959cdc3cac8686bc0e3e5aece8127dfb1b81ca1241bed8e00ef31b82bb4022 \ + --hash=sha256:d317710393fe20579aea39cfe8928fa2ad9b8780896e585326c75e89c1d1d1a4 # via docling-core lazy-loader==0.5 \ --hash=sha256:717f9179a0dbed357012ddad50a5ad3d5e4d9a0b8712680d4e687f5e6e6ed9b3 \ @@ -2590,9 +2606,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.36.0 \ + --hash=sha256:36ecac30e2ff4322d956029aabce3c82301c29f0acb1ad89b94edcabb0e58ec4 \ + --hash=sha256:3f6a4af2b036b476a4215111c4297b4e6e236ed186cd804faefba23e4990978b # via # azure-identity # msal-extensions @@ -2878,9 +2894,9 @@ nbclient==0.10.4 \ --hash=sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9 \ --hash=sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440 # 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 \ @@ -2925,9 +2941,9 @@ nodeenv==1.10.0 \ --hash=sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 \ --hash=sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb # via pre-commit -notebook==7.5.5 \ - --hash=sha256:a7c14dbeefa6592e87f72290ca982e0c10f5bbf3786be2a600fda9da2764a2b8 \ - --hash=sha256:dc0bfab0f2372c8278c457423d3256c34154ac2cc76bf20e9925260c461013c3 +notebook==7.5.6 \ + --hash=sha256:4dde3f8fb55fa8fb7946d58c6e869ce9baf46d00fc070664f62604569d0faca0 \ + --hash=sha256:621174aade80108f0020b0f00738000b215f75fa3cd90771ad7aa0f24536a4e1 # via great-expectations notebook-shim==0.2.4 \ --hash=sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef \ @@ -3057,8 +3073,8 @@ opencv-python-headless==4.13.0.92 \ --hash=sha256:a7cf08e5b191f4ebb530791acc0825a7986e0d0dee2a3c491184bd8599848a4b \ --hash=sha256:eb60e36b237b1ebd40a912da5384b348df8ed534f6f644d8e0b4f103e272ba7d # via easyocr -openlineage-python==1.45.0 \ - --hash=sha256:cf66e7d517d3c8b510b39ad646d8fd0ca2f0cc92d7d6d601d93b2a859783f380 +openlineage-python==1.46.0 \ + --hash=sha256:f6228a01d34990e76ede5b55b3f99169e54e2e624814c4493f064b9cb1bfba37 # via feast (pyproject.toml) openpyxl==3.1.5 \ --hash=sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2 \ @@ -3068,30 +3084,30 @@ 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.41.1 \ + --hash=sha256:0ad1814d73b875f84494387dae86ce0b12c68556331ce6ce8fe789197c949621 \ + --hash=sha256:a22df900e75c76dc08440710e51f52f1aa6b451b429298896023e60db5b3139f # via # opentelemetry-exporter-prometheus # opentelemetry-sdk # opentelemetry-semantic-conventions -opentelemetry-exporter-prometheus==0.61b0 \ - --hash=sha256:3013b41f4370143d48d219a2351473761423e5882fa4c213811eaefacba39cb7 \ - --hash=sha256:7c4919bd8e79abd62b610767e80f42c9c3a06c5183f4dd9141eedeb57aea284b +opentelemetry-exporter-prometheus==0.62b1 \ + --hash=sha256:7a0b8a6402e107e1f93e38f074a668797e1103936b189561959531a67ffeba55 \ + --hash=sha256:7ecbac9aa76e7abb44082ab0ff2983e0a573e4091c4653f7db483b02bae03506 # 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-sdk==1.41.1 \ + --hash=sha256:724b615e1215b5aeacda0abb8a6a8922c9a1853068948bd0bd225a56d0c792e6 \ + --hash=sha256:edee379c126c1bce952b0c812b48fe8ff35b30df0eecf17e98afa4d598b7d85d # via # opentelemetry-exporter-prometheus # ray -opentelemetry-semantic-conventions==0.61b0 \ - --hash=sha256:072f65473c5d7c6dc0355b27d6c9d1a679d63b6d4b4b16a9773062cb7e31192a \ - --hash=sha256:fa530a96be229795f8cef353739b618148b0fe2b4b3f005e60e262926c4d38e2 +opentelemetry-semantic-conventions==0.62b1 \ + --hash=sha256:c5cc6e04a7f8c7cdd30be2ed81499fa4e75bfbd52c9cb70d40af1f9cd3619802 \ + --hash=sha256:cf506938103d331fbb78eded0d9788095f7fd59016f2bda813c3324e5a74a93c # via opentelemetry-sdk oracledb==3.4.2 \ --hash=sha256:00c79448017f367bb7ab6900efe0706658a53768abea2b4519a4c9b2d5743890 \ @@ -3202,9 +3218,9 @@ orjson==3.11.8 \ --hash=sha256:fe0b8c83e0f36247fc9431ce5425a5d95f9b3a689133d494831bdbd6f0bceb13 \ --hash=sha256:ff51f9d657d1afb6f410cb435792ce4e1fe427aab23d2fcd727a2876e21d4cb6 # via trino -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # accelerate # build @@ -3461,9 +3477,9 @@ pillow==11.3.0 \ # python-pptx # scikit-image # torchvision -pip==26.0.1 \ - --hash=sha256:bdb1b08f4274833d62c1aa29e20907365a2ceb950410df15fc9521bad440122b \ - --hash=sha256:c4037d8a277c89b320abe636d59f91e6d0922d08a05b60e85e53b296613346d8 +pip==26.1 \ + --hash=sha256:4e8486d821d814b77319acb7b9e8bf5a4ee7590a643e7cb21029f209be8573c1 \ + --hash=sha256:81e13ebcca3ffa8cc85e4deff5c27e1ee26dea0aa7fc2f294a073ac208806ff3 # via pip-tools pip-tools==7.5.3 \ --hash=sha256:3aac0c473240ae90db7213c033401f345b05197293ccbdd2704e52e7a783785e \ @@ -3495,9 +3511,9 @@ pre-commit==3.3.1 \ --hash=sha256:218e9e3f7f7f3271ebc355a15598a4d3893ad9fc7b57fe446db75644543323b9 \ --hash=sha256:733f78c9a056cdd169baa6cd4272d51ecfda95346ef8a89bf93712706021b907 # via feast (pyproject.toml) -prometheus-client==0.24.1 \ - --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ - --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 +prometheus-client==0.25.0 \ + --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ + --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 # via # feast (pyproject.toml) # jupyter-server @@ -3802,71 +3818,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 @@ -3979,9 +3995,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.3 \ + --hash=sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927 \ + --hash=sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d # via # feast (pyproject.toml) # codeflare-sdk @@ -3997,134 +4013,134 @@ pydantic==2.12.5 \ # 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.3 \ + --hash=sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba \ + --hash=sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35 \ + --hash=sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4 \ + --hash=sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505 \ + --hash=sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7 \ + --hash=sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8 \ + --hash=sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4 \ + --hash=sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37 \ + --hash=sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25 \ + --hash=sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022 \ + --hash=sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1 \ + --hash=sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7 \ + --hash=sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c \ + --hash=sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3 \ + --hash=sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb \ + --hash=sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3 \ + --hash=sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976 \ + --hash=sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c \ + --hash=sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab \ + --hash=sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa \ + --hash=sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6 \ + --hash=sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396 \ + --hash=sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c \ + --hash=sha256:3d08782c4045f90724b44c95d35ebec0d67edb8a957a2ac81d5a8e4b8a200495 \ + --hash=sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c \ + --hash=sha256:4335e87c7afa436a0dfa899e138d57a72f8aad542e2cf19c36fb428461caabd0 \ + --hash=sha256:4b068543bdb707f5d935dab765d99227aa2545ef2820935f2e5dd801795c7dbd \ + --hash=sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf \ + --hash=sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531 \ + --hash=sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5 \ + --hash=sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda \ + --hash=sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d \ + --hash=sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e \ + --hash=sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df \ + --hash=sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6 \ + --hash=sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c \ + --hash=sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13 \ + --hash=sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536 \ + --hash=sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287 \ + --hash=sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0 \ + --hash=sha256:68ef2f623dda6d5a9067ac014e406c020c780b2a358930a7e5c1b73702900720 \ + --hash=sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050 \ + --hash=sha256:6dff8cc884679df229ebc6d8eb2321ea6f8e091bc7d4886d4dc2e0e71452843c \ + --hash=sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1 \ + --hash=sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8 \ + --hash=sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0 \ + --hash=sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374 \ + --hash=sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807 \ + --hash=sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6 \ + --hash=sha256:831eb19aa789a97356979e94c981e5667759301fb708d1c0d5adf1bc0098b873 \ + --hash=sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57 \ + --hash=sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f \ + --hash=sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c \ + --hash=sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad \ + --hash=sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e \ + --hash=sha256:91249bcb7c165c2fb2a2f852dbc5c91636e2e218e75d96dfdd517e4078e173dd \ + --hash=sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23 \ + --hash=sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46 \ + --hash=sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1 \ + --hash=sha256:99421e7684a60f7f3550a1d159ade5fdff1954baedb6bdd407cba6a307c9f27d \ + --hash=sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1 \ + --hash=sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee \ + --hash=sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c \ + --hash=sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874 \ + --hash=sha256:9f247596366f4221af52beddd65af1218797771d6989bc891a0b86ccaa019168 \ + --hash=sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a \ + --hash=sha256:a35cc284c8dd7edae8a31533713b4d2467dfe7c4f1b5587dd4031f28f90d1d13 \ + --hash=sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f \ + --hash=sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a \ + --hash=sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789 \ + --hash=sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe \ + --hash=sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f \ + --hash=sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5 \ + --hash=sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943 \ + --hash=sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b \ + --hash=sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089 \ + --hash=sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b \ + --hash=sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff \ + --hash=sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67 \ + --hash=sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803 \ + --hash=sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045 \ + --hash=sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8 \ + --hash=sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346 \ + --hash=sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2 \ + --hash=sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f \ + --hash=sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687 \ + --hash=sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76 \ + --hash=sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1 \ + --hash=sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f \ + --hash=sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2 \ + --hash=sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c \ + --hash=sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018 \ + --hash=sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba \ + --hash=sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c \ + --hash=sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf \ + --hash=sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7 \ + --hash=sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47 \ + --hash=sha256:d56bdb4af1767cc15b0386b3c581fdfe659bb9ee4a4f776e92c1cd9d074000d6 \ + --hash=sha256:dcda6583921c05a40533f982321532f2d8db29326c7b95c4026941fa5074bd79 \ + --hash=sha256:dd81f6907932ebac3abbe41378dac64b2380db1287e2aa64d8d88f78d170f51a \ + --hash=sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e \ + --hash=sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a \ + --hash=sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34 \ + --hash=sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b \ + --hash=sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85 \ + --hash=sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca \ + --hash=sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f \ + --hash=sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3 \ + --hash=sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64 \ + --hash=sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22 \ + --hash=sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72 \ + --hash=sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec \ + --hash=sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d \ + --hash=sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3 \ + --hash=sha256:fa3eb7c2995aa443687a825bc30395c8521b7c6ec201966e55debfd1128bcceb \ + --hash=sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395 \ + --hash=sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb \ + --hash=sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4 \ + --hash=sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127 \ + --hash=sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56 # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.0 \ + --hash=sha256:24285fd4b0e0c06507dd9fdfd331ee23794305352aaec8fc4eb92d4047aeb67d \ + --hash=sha256:fc8d5d692eb7092e43c8647c1c35a3ecd00e040fcf02ed86f4cb5458ca62182e # via # docling + # docling-core # fastapi-mcp # mcp pydata-google-auth==1.9.1 \ @@ -4159,6 +4175,79 @@ pymilvus==2.5.18 \ --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d # 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 \ --hash=sha256:0768d90f96ae3267d7561d3bcfe94dd671d107489e870388b12570c3debbc552 \ @@ -4219,9 +4308,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.1.3 \ + --hash=sha256:8164ba62c552f6105f3b11753352d0f16b90d1703ba67d81923d5a8a5d1c5289 \ + --hash=sha256:e70ebf2047a4edf6138cf79c68ad418ef620af65900aa585c5e8bfc95044d43a # via feast (pyproject.toml) pynacl==1.6.2 \ --hash=sha256:018494d6d696ae03c7e656e5e74cdfd8ea1326962cc401bcf018f1ed8436811c \ @@ -4318,9 +4407,9 @@ pyodbc==5.3.0 \ # via # feast (pyproject.toml) # ibis-framework -pyopenssl==26.0.0 \ - --hash=sha256:df94d28498848b98cc1c0ffb8ef1e71e40210d3b0a8064c9d29571ed2904bf81 \ - --hash=sha256:f293934e52936f2e3413b89c6ce36df66a0b34ae1ea3a053b8c5020ff2f513fc +pyopenssl==26.1.0 \ + --hash=sha256:115563879b2c8ccb207975705d3e491434d8c9d7c79667c902ecbf5f3bbd2ece \ + --hash=sha256:737f0a2275c5bc54f3b02137687e1a765931fb3949b9a92a825e4d33b9eec08b # via snowflake-connector-python pyparsing==3.3.2 \ --hash=sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d \ @@ -4546,9 +4635,9 @@ 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.27 \ + --hash=sha256:6fccfad17a27334bd0193681b369f476eda3409f17381a2d65aa7df3f7275645 \ + --hash=sha256:9870a6a8c5a20a5bf4f07c017bd1489006ff8836cff097b6933355ee2b49b602 # via mcp python-pptx==1.0.2 \ --hash=sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba \ @@ -4773,9 +4862,9 @@ ray[data, default]==2.53.0 \ --hash=sha256:d8b95d047d947493803fb8417aea31225dcacdab15afdc75b8a238901949d457 \ --hash=sha256:eb000c17f7301071fdd15c44c4cd3ac0f7953bb4c7c227e61719fe7048195bcd # via codeflare-sdk -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.0 \ + --hash=sha256:64a6ea7bf567ad43c964d2c30d82853f8df927c5c9017766c55a1d1ed95d18ad \ + --hash=sha256:a9c74a5c893a5ef8455a5adb793a31bb70feb821c86eccb62eebef5a19c429ec # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -4784,121 +4873,121 @@ referencing==0.37.0 \ # jsonschema # jsonschema-specifications # jupyter-events -regex==2026.3.32 \ - --hash=sha256:03c2ebd15ff51e7b13bb3dc28dd5ac18cd39e59ebb40430b14ae1a19e833cff1 \ - --hash=sha256:09e26cad1544d856da85881ad292797289e4406338afe98163f3db9f7fac816c \ - --hash=sha256:0cec365d44835b043d7b3266487797639d07d621bec9dc0ea224b00775797cc1 \ - --hash=sha256:0d7855f5e59fcf91d0c9f4a51dc5d8847813832a2230c3e8e35912ccf20baaa2 \ - --hash=sha256:0f21ae18dfd15752cdd98d03cbd7a3640be826bfd58482a93f730dbd24d7b9fb \ - --hash=sha256:10fb2aaae1aaadf7d43c9f3c2450404253697bf8b9ce360bd5418d1d16292298 \ - --hash=sha256:110ba4920721374d16c4c8ea7ce27b09546d43e16aea1d7f43681b5b8f80ba61 \ - --hash=sha256:12917c6c6813ffcdfb11680a04e4d63c5532b88cf089f844721c5f41f41a63ad \ - --hash=sha256:18eb45f711e942c27dbed4109830bd070d8d618e008d0db39705f3f57070a4c6 \ - --hash=sha256:1a6ac1ed758902e664e0d95c1ee5991aa6fb355423f378ed184c6ec47a1ec0e9 \ - --hash=sha256:1ca02ff0ef33e9d8276a1fcd6d90ff6ea055a32c9149c0050b5b67e26c6d2c51 \ - --hash=sha256:1cb22fa9ee6a0acb22fc9aecce5f9995fe4d2426ed849357d499d62608fbd7f9 \ - --hash=sha256:1e0f6648fd48f4c73d801c55ab976cd602e2da87de99c07bff005b131f269c6a \ - --hash=sha256:245667ad430745bae6a1e41081872d25819d86fbd9e0eec485ba00d9f78ad43d \ - --hash=sha256:2820d2231885e97aff0fcf230a19ebd5d2b5b8a1ba338c20deb34f16db1c7897 \ - --hash=sha256:2c8d402ea3dfe674288fe3962016affd33b5b27213d2b5db1823ffa4de524c57 \ - --hash=sha256:2dcca2bceb823c9cc610e57b86a265d7ffc30e9fe98548c609eba8bd3c0c2488 \ - --hash=sha256:2ffbadc647325dd4e3118269bda93ded1eb5f5b0c3b7ba79a3da9fbd04f248e9 \ - --hash=sha256:34c905a721ddee0f84c99e3e3b59dd4a5564a6fe338222bc89dd4d4df166115c \ - --hash=sha256:3c054e39a9f85a3d76c62a1d50c626c5e9306964eaa675c53f61ff7ec1204bbb \ - --hash=sha256:3c0bbfbd38506e1ea96a85da6782577f06239cb9fcf9696f1ea537c980c0680b \ - --hash=sha256:3e221b615f83b15887636fcb90ed21f1a19541366f8b7ba14ba1ad8304f4ded4 \ - --hash=sha256:3ea568832eca219c2be1721afa073c1c9eb8f98a9733fdedd0a9747639fc22a5 \ - --hash=sha256:3f5747501b69299c6b0b047853771e4ed390510bada68cb16da9c9c2078343f7 \ - --hash=sha256:462a041d2160090553572f6bb0be417ab9bb912a08de54cb692829c871ee88c1 \ - --hash=sha256:4bc32b4dbdb4f9f300cf9f38f8ea2ce9511a068ffaa45ac1373ee7a943f1d810 \ - --hash=sha256:4d082be64e51671dd5ee1c208c92da2ddda0f2f20d8ef387e57634f7e97b6aae \ - --hash=sha256:4f9ae4755fa90f1dc2d0d393d572ebc134c0fe30fcfc0ab7e67c1db15f192041 \ - --hash=sha256:51a93452034d671b0e21b883d48ea66c5d6a05620ee16a9d3f229e828568f3f0 \ - --hash=sha256:51fb7e26f91f9091fd8ec6a946f99b15d3bc3667cb5ddc73dd6cb2222dd4a1cc \ - --hash=sha256:5336b1506142eb0f23c96fb4a34b37c4fefd4fed2a7042069f3c8058efe17855 \ - --hash=sha256:567b57eb987547a23306444e4f6f85d4314f83e65c71d320d898aa7550550443 \ - --hash=sha256:5aa78c857c1731bdd9863923ffadc816d823edf475c7db6d230c28b53b7bdb5e \ - --hash=sha256:5bf2f3c2c5bd8360d335c7dcd4a9006cf1dabae063ee2558ee1b07bbc8a20d88 \ - --hash=sha256:5c35d097f509cf7e40d20d5bee548d35d6049b36eb9965e8d43e4659923405b9 \ - --hash=sha256:5d86e3fb08c94f084a625c8dc2132a79a3a111c8bf6e2bc59351fa61753c2f6e \ - --hash=sha256:6062c4ef581a3e9e503dccf4e1b7f2d33fdc1c13ad510b287741ac73bc4c6b27 \ - --hash=sha256:6128dd0793a87287ea1d8bf16b4250dd96316c464ee15953d5b98875a284d41e \ - --hash=sha256:631f7d95c83f42bccfe18946a38ad27ff6b6717fb4807e60cf24860b5eb277fc \ - --hash=sha256:66a5083c3ffe5a5a95f8281ea47a88072d4f24001d562d1d9d28d4cdc005fec5 \ - --hash=sha256:66d3126afe7eac41759cd5f0b3b246598086e88e70527c0d68c9e615b81771c4 \ - --hash=sha256:67015a8162d413af9e3309d9a24e385816666fbf09e48e3ec43342c8536f7df6 \ - --hash=sha256:6980ceb5c1049d4878632f08ba0bf7234c30e741b0dc9081da0f86eca13189d3 \ - --hash=sha256:69a847a6ffaa86e8af7b9e7037606e05a6f663deec516ad851e8e05d9908d16a \ - --hash=sha256:6ada7bd5bb6511d12177a7b00416ce55caee49fbf8c268f26b909497b534cacb \ - --hash=sha256:70c634e39c5cda0da05c93d6747fdc957599f7743543662b6dbabdd8d3ba8a96 \ - --hash=sha256:7cdd508664430dd51b8888deb6c5b416d8de046b2e11837254378d31febe4a98 \ - --hash=sha256:844d88509c968dd44b30daeefac72b038b1bf31ac372d5106358ab01d393c48b \ - --hash=sha256:847087abe98b3c1ebf1eb49d6ef320dbba75a83ee4f83c94704580f1df007dd4 \ - --hash=sha256:85c9b0c131427470a6423baa0a9330be6fd8c3630cc3ee6fdee03360724cbec5 \ - --hash=sha256:879ae91f2928a13f01a55cfa168acedd2b02b11b4cd8b5bb9223e8cde777ca52 \ - --hash=sha256:887a9fa74418d74d645281ee0edcf60694053bd1bc2ebc49eb5e66bfffc6d107 \ - --hash=sha256:88ebc0783907468f17fca3d7821b30f9c21865a721144eb498cb0ff99a67bcac \ - --hash=sha256:89e50667e7e8c0e7903e4d644a2764fffe9a3a5d6578f72ab7a7b4205bf204b7 \ - --hash=sha256:8a4a3189a99ecdd1c13f42513ab3fc7fa8311b38ba7596dd98537acb8cd9acc3 \ - --hash=sha256:8aaf8ee8f34b677f90742ca089b9c83d64bdc410528767273c816a863ed57327 \ - --hash=sha256:8e4c8fa46aad1a11ae2f8fcd1c90b9d55e18925829ac0d98c5bb107f93351745 \ - --hash=sha256:8fc918cd003ba0d066bf0003deb05a259baaaab4dc9bd4f1207bbbe64224857a \ - --hash=sha256:8fe14e24124ef41220e5992a0f09432f890037df6f93fd3d6b7a0feff2db16b2 \ - --hash=sha256:918db4e34a7ef3d0beee913fa54b34231cc3424676f1c19bdb85f01828d3cd37 \ - --hash=sha256:987cdfcfb97a249abc3601ad53c7de5c370529f1981e4c8c46793e4a1e1bfe8e \ - --hash=sha256:9b9118a78e031a2e4709cd2fcc3028432e89b718db70073a8da574c249b5b249 \ - --hash=sha256:9cf7036dfa2370ccc8651521fcbb40391974841119e9982fa312b552929e6c85 \ - --hash=sha256:a094e9dcafedfb9d333db5cf880304946683f43a6582bb86688f123335122929 \ - --hash=sha256:a416ee898ecbc5d8b283223b4cf4d560f93244f6f7615c1bd67359744b00c166 \ - --hash=sha256:a5d88fa37ba5e8a80ca8d956b9ea03805cfa460223ac94b7d4854ee5e30f3173 \ - --hash=sha256:ace48c5e157c1e58b7de633c5e257285ce85e567ac500c833349c363b3df69d4 \ - --hash=sha256:ad5c53f2e8fcae9144009435ebe3d9832003508cf8935c04542a1b3b8deefa15 \ - --hash=sha256:ad8d372587e659940568afd009afeb72be939c769c552c9b28773d0337251391 \ - --hash=sha256:b193ed199848aa96618cd5959c1582a0bf23cd698b0b900cb0ffe81b02c8659c \ - --hash=sha256:b2e9c2ea2e93223579308263f359eab8837dc340530b860cb59b713651889f14 \ - --hash=sha256:b3aa21bad31db904e0b9055e12c8282df62d43169c4a9d2929407060066ebc74 \ - --hash=sha256:b565f25171e04d4fad950d1fa837133e3af6ea6f509d96166eed745eb0cf63bc \ - --hash=sha256:b56993a7aeb4140c4770f4f7965c9e5af4f024457d06e23c01b0d47501cb18ed \ - --hash=sha256:b6acb765e7c1f2fa08ac9057a33595e26104d7d67046becae184a8f100932dd9 \ - --hash=sha256:b6f366a5ef66a2df4d9e68035cfe9f0eb8473cdfb922c37fac1d169b468607b0 \ - --hash=sha256:b7836aa13721dbdef658aebd11f60d00de633a95726521860fe1f6be75fa225a \ - --hash=sha256:b8fca73e16c49dd972ce3a88278dfa5b93bf91ddef332a46e9443abe21ca2f7c \ - --hash=sha256:b953d9d496d19786f4d46e6ba4b386c6e493e81e40f9c5392332458183b0599d \ - --hash=sha256:bbc458a292aee57d572075f22c035fa32969cdb7987d454e3e34d45a40a0a8b4 \ - --hash=sha256:c1cecea3e477af105f32ef2119b8d895f297492e41d317e60d474bc4bffd62ff \ - --hash=sha256:c1d7fa44aece1fa02b8927441614c96520253a5cad6a96994e3a81e060feed55 \ - --hash=sha256:c1ed17104d1be7f807fdec35ec99777168dd793a09510d753f8710590ba54cdd \ - --hash=sha256:c3c6f6b027d10f84bfe65049028892b5740878edd9eae5fea0d1710b09b1d257 \ - --hash=sha256:c5e0fdb5744caf1036dec5510f543164f2144cb64932251f6dfd42fa872b7f9c \ - --hash=sha256:c60f1de066eb5a0fd8ee5974de4194bb1c2e7692941458807162ffbc39887303 \ - --hash=sha256:c6d9c6e783b348f719b6118bb3f187b2e138e3112576c9679eb458cc8b2e164b \ - --hash=sha256:c940e00e8d3d10932c929d4b8657c2ea47d2560f31874c3e174c0d3488e8b865 \ - --hash=sha256:c9f261ad3cd97257dc1d9355bfbaa7dd703e06574bffa0fa8fe1e31da915ee38 \ - --hash=sha256:d21a07edddb3e0ca12a8b8712abc8452481c3d3db19ae87fc94e9842d005964b \ - --hash=sha256:d363660f9ef8c734495598d2f3e527fb41f745c73159dc0d743402f049fb6836 \ - --hash=sha256:d478a2ca902b6ef28ffc9521e5f0f728d036abe35c0b250ee8ae78cfe7c5e44e \ - --hash=sha256:d571f0b2eec3513734ea31a16ce0f7840c0b85a98e7edfa0e328ed144f9ef78f \ - --hash=sha256:d6b39a2cc5625bbc4fda18919a891eab9aab934eecf83660a90ce20c53621a9a \ - --hash=sha256:d76d62909bfb14521c3f7cfd5b94c0c75ec94b0a11f647d2f604998962ec7b6c \ - --hash=sha256:dab4178a0bc1ef13178832b12db7bc7f562e8f028b2b5be186e370090dc50652 \ - --hash=sha256:db976be51375bca900e008941639448d148c655c9545071965d0571ecc04f5d0 \ - --hash=sha256:ded4fc0edf3de792850cb8b04bbf3c5bd725eeaf9df4c27aad510f6eed9c4e19 \ - --hash=sha256:e006ea703d5c0f3d112b51ba18af73b58209b954acfe3d8da42eacc9a00e4be6 \ - --hash=sha256:e3e5d1802cba785210a4a800e63fcee7a228649a880f3bf7f2aadccb151a834b \ - --hash=sha256:e480d3dac06c89bc2e0fd87524cc38c546ac8b4a38177650745e64acbbcfdeba \ - --hash=sha256:e50af656c15e2723eeb7279c0837e07accc594b95ec18b86821a4d44b51b24bf \ - --hash=sha256:e83ce8008b48762be296f1401f19afd9ea29f3d035d1974e0cecb74e9afbd1df \ - --hash=sha256:ed3b8281c5d0944d939c82db4ec2300409dd69ee087f7a75a94f2e301e855fb4 \ - --hash=sha256:ef250a3f5e93182193f5c927c5e9575b2cb14b80d03e258bc0b89cc5de076b60 \ - --hash=sha256:f1574566457161678297a116fa5d1556c5a4159d64c5ff7c760e7c564bf66f16 \ - --hash=sha256:f26262900edd16272b6360014495e8d68379c6c6e95983f9b7b322dc928a1194 \ - --hash=sha256:f28eac18a8733a124444643a66ac96fef2c0ad65f50034e0a043b90333dc677f \ - --hash=sha256:f54840bea73541652f1170dc63402a5b776fc851ad36a842da9e5163c1f504a0 \ - --hash=sha256:f785f44a44702dea89b28bce5bc82552490694ce4e144e21a4f0545e364d2150 \ - --hash=sha256:f7cc00089b4c21847852c0ad76fb3680f9833b855a0d30bcec94211c435bff6b \ - --hash=sha256:f95bd07f301135771559101c060f558e2cf896c7df00bec050ca7f93bf11585a \ - --hash=sha256:fc8ced733d6cd9af5e412f256a32f7c61cd2d7371280a65c689939ac4572499f \ - --hash=sha256:fd03e38068faeef937cc6761a250a4aaa015564bd0d61481fefcf15586d31825 +regex==2026.4.4 \ + --hash=sha256:011bb48bffc1b46553ac704c975b3348717f4e4aa7a67522b51906f99da1820c \ + --hash=sha256:04bb679bc0bde8a7bfb71e991493d47314e7b98380b083df2447cda4b6edb60f \ + --hash=sha256:0540e5b733618a2f84e9cb3e812c8afa82e151ca8e19cf6c4e95c5a65198236f \ + --hash=sha256:05568c4fbf3cb4fa9e28e3af198c40d3237cf6041608a9022285fe567ec3ad62 \ + --hash=sha256:0709f22a56798457ae317bcce42aacee33c680068a8f14097430d9f9ba364bee \ + --hash=sha256:0734f63afe785138549fbe822a8cfeaccd1bae814c5057cc0ed5b9f2de4fc883 \ + --hash=sha256:07edca1ba687998968f7db5bc355288d0c6505caa7374f013d27356d93976d13 \ + --hash=sha256:07f190d65f5a72dcb9cf7106bfc3d21e7a49dd2879eda2207b683f32165e4d99 \ + --hash=sha256:08c55c13d2eef54f73eeadc33146fb0baaa49e7335eb1aff6ae1324bf0ddbe4a \ + --hash=sha256:0a51cdb3c1e9161154f976cb2bef9894bc063ac82f31b733087ffb8e880137d0 \ + --hash=sha256:1371c2ccbb744d66ee63631cc9ca12aa233d5749972626b68fe1a649dd98e566 \ + --hash=sha256:173a66f3651cdb761018078e2d9487f4cf971232c990035ec0eb1cdc6bf929a9 \ + --hash=sha256:1b1ce5c81c9114f1ce2f9288a51a8fd3aeea33a0cc440c415bf02da323aa0a76 \ + --hash=sha256:1b9a00b83f3a40e09859c78920571dcb83293c8004079653dd22ec14bbfa98c7 \ + --hash=sha256:21e5eb86179b4c67b5759d452ea7c48eb135cd93308e7a260aa489ed2eb423a4 \ + --hash=sha256:261c015b3e2ed0919157046d768774ecde57f03d8fa4ba78d29793447f70e717 \ + --hash=sha256:2895506ebe32cc63eeed8f80e6eae453171cfccccab35b70dc3129abec35a5b8 \ + --hash=sha256:298c3ec2d53225b3bf91142eb9691025bab610e0c0c51592dde149db679b3d17 \ + --hash=sha256:2a5d273181b560ef8397c8825f2b9d57013de744da9e8257b8467e5da8599351 \ + --hash=sha256:2b69102a743e7569ebee67e634a69c4cb7e59d6fa2e1aa7d3bdbf3f61435f62d \ + --hash=sha256:2c785939dc023a1ce4ec09599c032cc9933d258a998d16ca6f2b596c010940eb \ + --hash=sha256:2da82d643fa698e5e5210e54af90181603d5853cf469f5eedf9bfc8f59b4b8c7 \ + --hash=sha256:2e19e18c568d2866d8b6a6dfad823db86193503f90823a8f66689315ba28fbe8 \ + --hash=sha256:312ec9dd1ae7d96abd8c5a36a552b2139931914407d26fba723f9e53c8186f86 \ + --hash=sha256:33424f5188a7db12958246a54f59a435b6cb62c5cf9c8d71f7cc49475a5fdada \ + --hash=sha256:3384df51ed52db0bea967e21458ab0a414f67cdddfd94401688274e55147bb81 \ + --hash=sha256:33bfda9684646d323414df7abe5692c61d297dbb0530b28ec66442e768813c59 \ + --hash=sha256:349d7310eddff40429a099c08d995c6d4a4bfaf3ff40bd3b5e5cb5a5a3c7d453 \ + --hash=sha256:36bcb9d6d1307ab629edc553775baada2aefa5c50ccc0215fbfd2afcfff43141 \ + --hash=sha256:3790ba9fb5dd76715a7afe34dbe603ba03f8820764b1dc929dd08106214ed031 \ + --hash=sha256:385edaebde5db5be103577afc8699fea73a0e36a734ba24870be7ffa61119d74 \ + --hash=sha256:39d8de85a08e32632974151ba59c6e9140646dcc36c80423962b1c5c0a92e244 \ + --hash=sha256:415a994b536440f5011aa77e50a4274d15da3245e876e5c7f19da349caaedd87 \ + --hash=sha256:421439d1bee44b19f4583ccf42670ca464ffb90e9fdc38d37f39d1ddd1e44f1f \ + --hash=sha256:475e50f3f73f73614f7cba5524d6de49dee269df00272a1b85e3d19f6d498465 \ + --hash=sha256:4ce255cc05c1947a12989c6db801c96461947adb7a59990f1360b5983fab4983 \ + --hash=sha256:504ffa8a03609a087cad81277a629b6ce884b51a24bd388a7980ad61748618ff \ + --hash=sha256:50a766ee2010d504554bfb5f578ed2e066898aa26411d57e6296230627cdefa0 \ + --hash=sha256:54170b3e95339f415d54651f97df3bff7434a663912f9358237941bbf9143f55 \ + --hash=sha256:54a1189ad9d9357760557c91103d5e421f0a2dabe68a5cdf9103d0dcf4e00752 \ + --hash=sha256:55d9304e0e7178dfb1e106c33edf834097ddf4a890e2f676f6c5118f84390f73 \ + --hash=sha256:586b89cdadf7d67bf86ae3342a4dcd2b8d70a832d90c18a0ae955105caf34dbe \ + --hash=sha256:59968142787042db793348a3f5b918cf24ced1f23247328530e063f89c128a95 \ + --hash=sha256:59efe72d37fd5a91e373e5146f187f921f365f4abc1249a5ab446a60f30dd5f8 \ + --hash=sha256:59f67cd0a0acaf0e564c20bbd7f767286f23e91e2572c5703bf3e56ea7557edb \ + --hash=sha256:5d354b18839328927832e2fa5f7c95b7a3ccc39e7a681529e1685898e6436d45 \ + --hash=sha256:62f5519042c101762509b1d717b45a69c0139d60414b3c604b81328c01bd1943 \ + --hash=sha256:6780f008ee81381c737634e75c24e5a6569cc883c4f8e37a37917ee79efcafd9 \ + --hash=sha256:6a50ab11b7779b849472337191f3a043e27e17f71555f98d0092fa6d73364520 \ + --hash=sha256:6aa809ed4dc3706cc38594d67e641601bd2f36d5555b2780ff074edfcb136cf8 \ + --hash=sha256:6c1818f37be3ca02dcb76d63f2c7aaba4b0dc171b579796c6fbe00148dfec6b1 \ + --hash=sha256:6dac006c8b6dda72d86ea3d1333d45147de79a3a3f26f10c1cf9287ca4ca0ac3 \ + --hash=sha256:7088fcdcb604a4417c208e2169715800d28838fefd7455fbe40416231d1d47c1 \ + --hash=sha256:70aadc6ff12e4b444586e57fc30771f86253f9f0045b29016b9605b4be5f7dfb \ + --hash=sha256:7429f4e6192c11d659900c0648ba8776243bf396ab95558b8c51a345afeddde6 \ + --hash=sha256:74fa82dcc8143386c7c0392e18032009d1db715c25f4ba22d23dc2e04d02a20f \ + --hash=sha256:760ef21c17d8e6a4fe8cf406a97cf2806a4df93416ccc82fc98d25b1c20425be \ + --hash=sha256:7698a6f38730fd1385d390d1ed07bb13dce39aa616aca6a6d89bea178464b9a4 \ + --hash=sha256:76d67d5afb1fe402d10a6403bae668d000441e2ab115191a804287d53b772951 \ + --hash=sha256:773d1dfd652bbffb09336abf890bfd64785c7463716bf766d0eb3bc19c8b7f27 \ + --hash=sha256:7d346fccdde28abba117cc9edc696b9518c3307fbfcb689e549d9b5979018c6d \ + --hash=sha256:8512fcdb43f1bf18582698a478b5ab73f9c1667a5b7548761329ef410cd0a760 \ + --hash=sha256:867bddc63109a0276f5a31999e4c8e0eb7bbbad7d6166e28d969a2c1afeb97f9 \ + --hash=sha256:88e9b048345c613f253bea4645b2fe7e579782b82cac99b1daad81e29cc2ed8e \ + --hash=sha256:8fae3c6e795d7678963f2170152b0d892cf6aee9ee8afc8c45e6be38d5107fe7 \ + --hash=sha256:9542ccc1e689e752594309444081582f7be2fdb2df75acafea8a075108566735 \ + --hash=sha256:9776b85f510062f5a75ef112afe5f494ef1635607bf1cc220c1391e9ac2f5e81 \ + --hash=sha256:97850d0638391bdc7d35dc1c1039974dcb921eaafa8cc935ae4d7f272b1d60b3 \ + --hash=sha256:993f657a7c1c6ec51b5e0ba97c9817d06b84ea5fa8d82e43b9405de0defdc2b9 \ + --hash=sha256:9a2741ce5a29d3c84b0b94261ba630ab459a1b847a0d6beca7d62d188175c790 \ + --hash=sha256:9e2f5217648f68e3028c823df58663587c1507a5ba8419f4fdfc8a461be76043 \ + --hash=sha256:a0d2b28aa1354c7cd7f71b7658c4326f7facac106edd7f40eda984424229fd59 \ + --hash=sha256:a152560af4f9742b96f3827090f866eeec5becd4765c8e0d3473d9d280e76a5a \ + --hash=sha256:a1c0c7d67b64d85ac2e1879923bad2f08a08f3004055f2f406ef73c850114bd4 \ + --hash=sha256:a7a5bb6aa0cf62208bb4fa079b0c756734f8ad0e333b425732e8609bd51ee22f \ + --hash=sha256:a85b620a388d6c9caa12189233109e236b3da3deffe4ff11b84ae84e218a274f \ + --hash=sha256:acd38177bd2c8e69a411d6521760806042e244d0ef94e2dd03ecdaa8a3c99427 \ + --hash=sha256:ae3e764bd4c5ff55035dc82a8d49acceb42a5298edf6eb2fc4d328ee5dd7afae \ + --hash=sha256:ae5266a82596114e41fb5302140e9630204c1b5f325c770bec654b95dd54b0aa \ + --hash=sha256:af0384cb01a33600c49505c27c6c57ab0b27bf84a74e28524c92ca897ebdac9d \ + --hash=sha256:b15b88b0d52b179712632832c1d6e58e5774f93717849a41096880442da41ab0 \ + --hash=sha256:b26c30df3a28fd9793113dac7385a4deb7294a06c0f760dd2b008bd49a9139bc \ + --hash=sha256:b40379b53ecbc747fd9bdf4a0ea14eb8188ca1bd0f54f78893a39024b28f4863 \ + --hash=sha256:b4c36a85b00fadb85db9d9e90144af0a980e1a3d2ef9cd0f8a5bef88054657c6 \ + --hash=sha256:b5f9fb784824a042be3455b53d0b112655686fdb7a91f88f095f3fee1e2a2a54 \ + --hash=sha256:be061028481186ba62a0f4c5f1cc1e3d5ab8bce70c89236ebe01023883bc903b \ + --hash=sha256:c07ab8794fa929e58d97a0e1796b8b76f70943fa39df225ac9964615cf1f9d52 \ + --hash=sha256:c228cf65b4a54583763645dcd73819b3b381ca8b4bb1b349dee1c135f4112c07 \ + --hash=sha256:c4ee50606cb1967db7e523224e05f32089101945f859928e65657a2cbb3d278b \ + --hash=sha256:c882cd92ec68585e9c1cf36c447ec846c0d94edd706fe59e0c198e65822fd23b \ + --hash=sha256:cf9b1b2e692d4877880388934ac746c99552ce6bf40792a767fd42c8c99f136d \ + --hash=sha256:d2228c02b368d69b724c36e96d3d1da721561fb9cc7faa373d7bf65e07d75cb5 \ + --hash=sha256:d51d20befd5275d092cdffba57ded05f3c436317ee56466c8928ac32d960edaf \ + --hash=sha256:db0ac18435a40a2543dbb3d21e161a6c78e33e8159bd2e009343d224bb03bb1b \ + --hash=sha256:dc4f10fbd5dd13dcf4265b4cc07d69ca70280742870c97ae10093e3d66000359 \ + --hash=sha256:dcb5453ecf9cd58b562967badd1edbf092b0588a3af9e32ee3d05c985077ce87 \ + --hash=sha256:dd2630faeb6876fb0c287f664d93ddce4d50cd46c6e88e60378c05c9047e08ca \ + --hash=sha256:e014a797de43d1847df957c0a2a8e861d1c17547ee08467d1db2c370b7568baa \ + --hash=sha256:e08270659717f6973523ce3afbafa53515c4dc5dcad637dc215b6fd50f689423 \ + --hash=sha256:e0aab3ff447845049d676827d2ff714aab4f73f340e155b7de7458cf53baa5a4 \ + --hash=sha256:e355be718caf838aa089870259cf1776dc2a4aa980514af9d02c59544d9a8b22 \ + --hash=sha256:e7ab63e9fe45a9ec3417509e18116b367e89c9ceb6219222a3396fa30b147f80 \ + --hash=sha256:e7cd3e4ee8d80447a83bbc9ab0c8459781fa77087f856c3e740d7763be0df27f \ + --hash=sha256:e9638791082eaf5b3ac112c587518ee78e083a11c4b28012d8fe2a0f536dfb17 \ + --hash=sha256:eb59c65069498dbae3c0ef07bbe224e1eaa079825a437fb47a479f0af11f774f \ + --hash=sha256:ee7337f88f2a580679f7bbfe69dc86c043954f9f9c541012f49abc554a962f2e \ + --hash=sha256:ee9627de8587c1a22201cb16d0296ab92b4df5cdcb5349f4e9744d61db7c7c98 \ + --hash=sha256:f4f83781191007b6ef43b03debc35435f10cad9b96e16d147efe84a1d48bdde4 \ + --hash=sha256:f56ebf9d70305307a707911b88469213630aba821e77de7d603f9d2f0730687d \ + --hash=sha256:f5bfc2741d150d0be3e4a0401a5c22b06e60acb9aa4daa46d9e79a6dcd0f135b \ + --hash=sha256:f94a11a9d05afcfcfa640e096319720a19cc0c9f7768e1a61fceee6a3afc6c7c \ + --hash=sha256:fa7922bbb2cc84fa062d37723f199d4c0cd200245ce269c05db82d904db66b83 \ + --hash=sha256:fe896e07a5a2462308297e515c0054e9ec2dd18dfdc9427b19900b37dfe6f40b \ + --hash=sha256:ffa81f81b80047ba89a3c69ae6a0f78d06f4a42ce5126b0eb2a0a10ad44e0b2e # via # feast (pyproject.toml) # parsimonious @@ -4964,9 +5053,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==14.3.4 \ + --hash=sha256:07e7adb4690f68864777b1450859253bed81a99a31ac321ac1817b2313558952 \ + --hash=sha256:817e02727f2b25b40ef56f5aa2217f400c8489f79ca8f46ea2b70dd5e14558a9 # via # codeflare-sdk # fastapi-mcp @@ -5108,25 +5197,25 @@ ruamel-yaml==0.17.17 \ --hash=sha256:9751de4cbb57d4bfbf8fc394e125ed4a2f170fbff3dc3d78abf50be85924f8be \ --hash=sha256:9af3ec5d7f8065582f3aa841305465025d0afd26c5fb54e15b964e11838fc74f # via great-expectations -ruff==0.15.9 \ - --hash=sha256:058d8e99e1bfe79d8a0def0b481c56059ee6716214f7e425d8e737e412d69677 \ - --hash=sha256:0694e601c028fd97dc5c6ee244675bc241aeefced7ef80cd9c6935a871078f53 \ - --hash=sha256:29cbb1255a9797903f6dde5ba0188c707907ff44a9006eb273b5a17bfa0739a2 \ - --hash=sha256:2b0c7c341f68adb01c488c3b7d4b49aa8ea97409eae6462d860a79cf55f431b6 \ - --hash=sha256:45a70921b80e1c10cf0b734ef09421f71b5aa11d27404edc89d7e8a69505e43d \ - --hash=sha256:4965bac6ac9ea86772f4e23587746f0b7a395eccabb823eb8bfacc3fa06069f7 \ - --hash=sha256:55cc15eee27dc0eebdfcb0d185a6153420efbedc15eb1d38fe5e685657b0f840 \ - --hash=sha256:6d3fcbca7388b066139c523bda744c822258ebdcfbba7d24410c3f454cc9af71 \ - --hash=sha256:6efbe303983441c51975c243e26dff328aca11f94b70992f35b093c2e71801e1 \ - --hash=sha256:7b34a9766aeec27a222373d0b055722900fbc0582b24f39661aa96f3fe6ad901 \ - --hash=sha256:89dd695bc72ae76ff484ae54b7e8b0f6b50f49046e198355e44ea656e521fef9 \ - --hash=sha256:8e1ddb11dbd61d5983fa2d7d6370ef3eb210951e443cace19594c01c72abab4c \ - --hash=sha256:9439a342adb8725f32f92732e2bafb6d5246bd7a5021101166b223d312e8fc59 \ - --hash=sha256:9c5e6faf9d97c8edc43877c3f406f47446fc48c40e1442d58cfcdaba2acea745 \ - --hash=sha256:a6537f6eed5cda688c81073d46ffdfb962a5f29ecb6f7e770b2dc920598997ed \ - --hash=sha256:bde6ff36eaf72b700f32b7196088970bf8fdb2b917b7accd8c371bfc0fd573ec \ - --hash=sha256:ce187224ef1de1bd225bc9a152ac7102a6171107f026e81f317e4257052916d5 \ - --hash=sha256:eaf05aad70ca5b5a0a4b0e080df3a6b699803916d88f006efd1f5b46302daab8 +ruff==0.15.12 \ + --hash=sha256:01da3988d225628b709493d7dc67c3b9b12c0210016b08690ef9bd27970b262b \ + --hash=sha256:2849ea9f3484c3aca43a82f484210370319e7170df4dfe4843395ddf6c57bc33 \ + --hash=sha256:83b2f4f2f3b1026b5fb449b467d9264bf22067b600f7b6f41fc5958909f449d0 \ + --hash=sha256:84a1630093121375a3e2a95b4a6dc7b59e2b4ee76216e32d81aae550a832d002 \ + --hash=sha256:9ba3b8f1afd7e2e43d8943e55f249e13f9682fde09711644a6e7290eb4f3e339 \ + --hash=sha256:9cae0f92bd5700d1213188b31cd3bdd2b315361296d10b96b8e2337d3d11f53e \ + --hash=sha256:9e77c7e51c07fe396826d5969a5b846d9cd4c402535835fb6e21ce8b28fef847 \ + --hash=sha256:a538f7a82d061cee7be55542aca1d86d1393d55d81d4fcc314370f4340930d4f \ + --hash=sha256:b0c862b172d695db7598426b8af465e7e9ac00a3ea2a3630ee67eb82e366aaa6 \ + --hash=sha256:c87a162d61ab3adca47c03f7f717c68672edec7d1b5499e652331780fe74950d \ + --hash=sha256:d0185894e038d7043ba8fd6aee7499ece6462dc0ea9f1e260c7451807c714c20 \ + --hash=sha256:dd8aed930da53780d22fc70bdf84452c843cf64f8cb4eb38984319c24c5cd5fd \ + --hash=sha256:e3bcd123364c3770b8e1b7baaf343cc99a35f197c5c6e8af79015c666c423a6c \ + --hash=sha256:e852ba9fdc890655e1d78f2df1499efbe0e54126bd405362154a75e2bde159c5 \ + --hash=sha256:ecea26adb26b4232c0c2ca19ccbc0083a68344180bba2a600605538ce51a40a6 \ + --hash=sha256:f86f176e188e94d6bdbc09f09bfd9dc729059ad93d0e7390b5a73efe19f8861c \ + --hash=sha256:fb129f40f114f089ebe0ca56c0d251cf2061b17651d464bb6478dc01e69f11f5 \ + --hash=sha256:fe87510d000220aa1ed530d4448a7c696a0cae1213e5ec30e5874287b66557b5 # via feast (pyproject.toml) s3transfer==0.13.1 \ --hash=sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724 \ @@ -5330,9 +5419,9 @@ send2trash==2.1.0 \ --hash=sha256:0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c \ --hash=sha256:1c72b39f09457db3c05ce1d19158c2cbef4c32b8bedd02c155e49282b7ea7459 # via jupyter-server -sentence-transformers==5.3.0 \ - --hash=sha256:414a0a881f53a4df0e6cbace75f823bfcb6b94d674c42a384b498959b7c065e2 \ - --hash=sha256:dca6b98db790274a68185d27a65801b58b4caf653a4e556b5f62827509347c7d +sentence-transformers==5.4.1 \ + --hash=sha256:436bcb1182a0ff42a8fb2b1c43498a70d0a75b688d182f2cd0d1dd115af61ddc \ + --hash=sha256:a6d640fc363849b63affb8e140e9d328feabab86f83d58ac3e16b1c28140b790 # via feast (pyproject.toml) setuptools==80.10.2 \ --hash=sha256:8b0e9d10c784bf7d262c4e5ec5d4ec94127ce206e8738f29a437945fbc219b70 \ @@ -5432,9 +5521,9 @@ six==1.17.0 \ # python-dateutil # rfc3339-validator # thriftpy2 -smart-open==7.5.1 \ - --hash=sha256:3e07cbbd9c8a908bcb8e25d48becf1a5cbb4886fa975e9f34c672ed171df2318 \ - --hash=sha256:3f08e16827c4733699e6b2cc40328a3568f900cb12ad9a3ad233ba6c872d9fe7 +smart-open==7.6.0 \ + --hash=sha256:2a78f454610a826aa688065b54b4a0a9b12a5599fa61d5190e9bac2df5e5f53f \ + --hash=sha256:44717f46b5ff276fac03b88e5d13d1c416f064f3b7b081381b0fa8889004bd7e # via ray sniffio==1.3.1 \ --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ @@ -5510,103 +5599,103 @@ 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.49 \ + --hash=sha256:01146546d84185f12721a1d2ce0c6673451a7894d1460b592d378ca4871a0c72 \ + --hash=sha256:059d7151fff513c53a4638da8778be7fce81a0c4854c7348ebd0c4078ddf28fe \ + --hash=sha256:0c98c59075b890df8abfcc6ad632879540f5791c68baebacb4f833713b510e75 \ + --hash=sha256:0f2fa354ba106eafff2c14b0cc51f22801d1e8b2e4149342023bd6f0955de5f5 \ + --hash=sha256:12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148 \ + --hash=sha256:22d8798819f86720bc646ab015baff5ea4c971d68121cb36e2ebc2ee43ead2b7 \ + --hash=sha256:233088b4b99ebcbc5258c755a097aa52fbf90727a03a5a80781c4b9c54347a2e \ + --hash=sha256:24bd94bb301ec672d8f0623eba9226cc90d775d25a0c92b5f8e4965d7f3a1518 \ + --hash=sha256:275424295f4256fd301744b8f335cff367825d270f155d522b30c7bf49903ee7 \ + --hash=sha256:32fe6a41ad97302db2931f05bb91abbcc65b5ce4c675cd44b972428dd2947700 \ + --hash=sha256:334edbcff10514ad1d66e3a70b339c0a29886394892490119dbb669627b17717 \ + --hash=sha256:3bb9ec6436a820a4c006aad1ac351f12de2f2dbdaad171692ee457a02429b672 \ + --hash=sha256:3ddcb27fb39171de36e207600116ac9dfd4ae46f86c82a9bf3934043e80ebb88 \ + --hash=sha256:42e8804962f9e6f4be2cbaedc0c3718f08f60a16910fa3d86da5a1e3b1bfe60f \ + --hash=sha256:43d044780732d9e0381ac8d5316f95d7f02ef04d6e4ef6dc82379f09795d993f \ + --hash=sha256:46796877b47034b559a593d7e4b549aba151dae73f9e78212a3478161c12ab08 \ + --hash=sha256:46d51518d53edfbe0563662c96954dc8fcace9832332b914375f45a99b77cc9a \ + --hash=sha256:47604cb2159f8bbd5a1ab48a714557156320f20871ee64d550d8bf2683d980d3 \ + --hash=sha256:4bbccb45260e4ff1b7db0be80a9025bb1e6698bdb808b83fff0000f7a90b2c0b \ + --hash=sha256:4d4e5a0ceba319942fa6b585cf82539288a61e314ef006c1209f734551ab9536 \ + --hash=sha256:55250fe61d6ebfd6934a272ee16ef1244e0f16b7af6cd18ab5b1fc9f08631db0 \ + --hash=sha256:566df36fd0e901625523a5a1835032f1ebdd7f7886c54584143fa6c668b4df3b \ + --hash=sha256:57ca426a48eb2c682dae8204cd89ea8ab7031e2675120a47924fabc7caacbc2a \ + --hash=sha256:5e61abbec255be7b122aa461021daa7c3f310f3e743411a67079f9b3cc91ece3 \ + --hash=sha256:618a308215b6cececb6240b9abde545e3acdabac7ae3e1d4e666896bf5ba44b4 \ + --hash=sha256:62557958002b69699bdb7f5137c6714ca1133f045f97b3903964f47db97ea339 \ + --hash=sha256:6270d717b11c5476b0cbb21eedc8d4dbb7d1a956fd6c15a23e96f197a6193158 \ + --hash=sha256:685e93e9c8f399b0c96a624799820176312f5ceef958c0f88215af4013d29066 \ + --hash=sha256:69469ce8ce7a8df4d37620e3163b71238719e1e2e5048d114a1b6ce0fbf8c662 \ + --hash=sha256:6eb188b84269f357669b62cb576b5b918de10fb7c728a005fa0ebb0b758adce1 \ + --hash=sha256:74ab4ee7794d7ed1b0c37e7333640e0f0a626fc7b398c07a7aef52f484fddde3 \ + --hash=sha256:77641d299179c37b89cf2343ca9972c88bb6eef0d5fc504a2f86afd15cd5adf5 \ + --hash=sha256:7c821c47ecfe05cc32140dcf8dc6fd5d21971c86dbd56eabfe5ba07a64910c01 \ + --hash=sha256:7d6be30b2a75362325176c036d7fb8d19e8846c77e87683ffaa8177b35135613 \ + --hash=sha256:7f605a456948c35260e7b2a39f8952a26f077fd25653c37740ed186b90aaa68a \ + --hash=sha256:83101a6930332b87653886c01d1ee7e294b1fe46a07dd9a2d2b4f91bcc88eec0 \ + --hash=sha256:88690f4e1f0fbf5339bedbb127e240fec1fd3070e9934c0b7bef83432f779d2f \ + --hash=sha256:8a97ac839c2c6672c4865e48f3cbad7152cee85f4233fb4ca6291d775b9b954a \ + --hash=sha256:8d6efc136f44a7e8bc8088507eaabbb8c2b55b3dbb63fe102c690da0ddebe55e \ + --hash=sha256:8e20e511dc15265fb433571391ba313e10dd8ea7e509d51686a51313b4ac01a2 \ + --hash=sha256:951d4a210744813be63019f3df343bf233b7432aadf0db54c75802247330d3af \ + --hash=sha256:9ac7a3e245fd0310fd31495eb61af772e637bdf7d88ee81e7f10a3f271bff014 \ + --hash=sha256:9b1c058c171b739e7c330760044803099c7fff11511e3ab3573e5327116a9c33 \ + --hash=sha256:9c04bff9a5335eb95c6ecf1c117576a0aa560def274876fd156cfe5510fccc61 \ + --hash=sha256:9c4969a86e41454f2858256c39bdfb966a20961e9b58bf8749b65abf447e9a8d \ + --hash=sha256:9e0400fa22f79acc334d9a6b185dc00a44a8e6578aa7e12d0ddcd8434152b187 \ + --hash=sha256:a05977bffe9bffd2229f477fa75eabe3192b1b05f408961d1bebff8d1cd4d401 \ + --hash=sha256:a143af2ea6672f2af3f44ed8f9cd020e9cc34c56f0e8db12019d5d9ecf41cb3b \ + --hash=sha256:a51d3db74ba489266ef55c7a4534eb0b8db9a326553df481c11e5d7660c8364d \ + --hash=sha256:b95b2f470c1b2683febd2e7eab1d3f0e078c91dbdd0b00e9c645d07a413bb99f \ + --hash=sha256:b9870d15ef00e4d0559ae10ee5bc71b654d1f20076dbe8bc7ed19b4c0625ceba \ + --hash=sha256:c1dc3368794d522f43914e03312202523cc89692f5389c32bea0233924f8d977 \ + --hash=sha256:c338ec6ec01c0bc8e735c58b9f5d51e75bacb6ff23296658826d7cfdfdb8678a \ + --hash=sha256:c5070135e1b7409c4161133aa525419b0062088ed77c92b1da95366ec5cbebbe \ + --hash=sha256:cc992c6ed024c8c3c592c5fc9846a03dd68a425674900c70122c77ea16c5fb0b \ + --hash=sha256:d15950a57a210e36dd4cec1aac22787e2a4d57ba9318233e2ef8b2daf9ff2d5f \ + --hash=sha256:d898cc2c76c135ef65517f4ddd7a3512fb41f23087b0650efb3418b8389a3cd1 \ + --hash=sha256:d99945830a6f3e9638d89a28ed130b1eb24c91255e4f24366fbe699b983f29e4 \ + --hash=sha256:da9b91bca419dc9b9267ffadde24eae9b1a6bffcd09d0a207e5e3af99a03ce0d \ + --hash=sha256:df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120 \ + --hash=sha256:e06e617e3d4fd9e51d385dfe45b077a41e9d1b033a7702551e3278ac597dc750 \ + --hash=sha256:ec44cfa7ef1a728e88ad41674de50f6db8cfdb3e2af84af86e0041aaf02d43d0 \ + --hash=sha256:fb37f15714ec2652d574f021d479e78cd4eb9d04396dca36568fdfffb3487982 # via feast (pyproject.toml) -sqlglot[rs]==30.2.1 \ - --hash=sha256:ef4a67cc6f66a8043085eb8ea95fa9541c1625dffa9145ad4e9815a7ba60a199 \ - --hash=sha256:f23d9ee9427ef9d20df15f9b0ffa57d9eb45e52b012219a349d1e6b50ed926d1 +sqlglot[rs]==30.6.0 \ + --hash=sha256:246d34d39927422a50a3fa155f37b2f6346fba85f1a755b13c941eb32ef93361 \ + --hash=sha256:e005fc2f47994f90d7d8df341f1cbe937518497b0b7b1507d4c03c4c9dfd2778 # via # feast (pyproject.toml) # ibis-framework -sqlglotc==30.2.1 \ - --hash=sha256:052cd7bb41fc9b841eb268d4dd601eb6b5954b7c6d5656795d4350a0f8020d53 \ - --hash=sha256:058f0e9aed2b8dff87dc893b8793e514204c8dfef699b7d3d1704dfbdd949f2b \ - --hash=sha256:0e6be524252894c0fa98d25d4e60dfae6485ba66ca1abd40bf05f16a9cf26baf \ - --hash=sha256:13f8f68808777ba7d845bc908bf09f72a0c9899a19811483dc52f0fa48b38d5a \ - --hash=sha256:1a004086ab871be0cc97766f7b6fb8866729f09dd7272254fd31c05107f3fdc8 \ - --hash=sha256:25c6f62f31cd3a051285635c3f6a01d2f3c73ca2baaa26970815166928042ace \ - --hash=sha256:2b5fe8adc1a1e2fb819e014e94974a274f30dbf9684ceed9f171fb0889f80f0b \ - --hash=sha256:2ffe527bc8664b03cc936bae7ebf965f482beb4acee7a815c2ec2d9aea720b4e \ - --hash=sha256:4aa90e08f53409b1857572836e57a31835ed20e32521c6fafdc6af96199baff7 \ - --hash=sha256:507935a971e0a9e5d4ac7ca14df479f8e270502b44904f71d95c0aaed066006f \ - --hash=sha256:515e092ab8fb522b256fa8a34f471e9b187bb8a50a7c0226a65b036a07d6d188 \ - --hash=sha256:585bb610fde3e3dd1d7e5ff3cce14f70fbd53ced6769cd104679adf8b5c4ab5b \ - --hash=sha256:850e7517dd4739cad9af65bcb9699825f9202e5971407bf955e3248fe4814f96 \ - --hash=sha256:8f063af733cbcc51686380470e7f3f80b589b8c58084baa138efb3b8ca821597 \ - --hash=sha256:b17e3002ed10747388367621b2ecf39c06d5fdc6b3c31a8c32be2f5ef546fc0b \ - --hash=sha256:d577e1635e127febb7012bc42fa1c3b958076e59a1a116ade20048c572a1be42 \ - --hash=sha256:dc292cd73e0c447253877c27f00454a2d09b71324a130ad4c58c145ab753889e \ - --hash=sha256:de168df756a21a028cf1f917f92da2f77bb135f3b6cdd960914460942a5eca10 \ - --hash=sha256:de884dd224220002c3e940ca5bdceb27ef9638e5f02493db133ffb8ae88b5610 \ - --hash=sha256:f33c7d1646ff6531cb9b07f0740b2939f3ecaa31efebfbec8adb6b275f1a45f2 \ - --hash=sha256:f9a1fc7b1ff3b51d0d03a391768a79964f68541b4c2f294a25a6f14e6670ffab \ - --hash=sha256:fae4edad0b7c5f9f963bd63452f722f0d7f77a436c2d334b555b31722f9573ad \ - --hash=sha256:fdc19623a1c7659918c3cee18ea8849fc4af9eaeb87247acf37e0393295d32b7 \ - --hash=sha256:feefc0ab7606d1fe284d23bef09ea4829ce4fad679936959c29324310f23e081 \ - --hash=sha256:ff19b7ecb931aef6c7c6168af5530c07e67915102b701d45ae80446f0695ba54 +sqlglotc==30.6.0 \ + --hash=sha256:003b15bbe3f3a4a63313baeb3f090906cf0172fe007ab24974c612a577f56c61 \ + --hash=sha256:05861b5d74ae4b0a5a6e6a9309a8a975d9572c2bf1eb9634a33af9189eb7d333 \ + --hash=sha256:0b907206ef36fd8f0c28da4c5b8c8f896bd67826da0d765616e6c950689ac849 \ + --hash=sha256:0e1aae195008c1d87ed1b1543bceed1408ae8ecf146571b3029e98b23a19c59c \ + --hash=sha256:16291ee3da0276df2689cc139df41d8723cf6014aca979f307fb75a898b0d3e8 \ + --hash=sha256:27d6c22375395f1fdfe8a5d80b5fb781ca7849e29c7db7dfb11edb466a5b7a4d \ + --hash=sha256:2b50aba396d4622c201a9dd933b51cd6858b5af5ebbcf7db1af35db7e83ece48 \ + --hash=sha256:4a5beba24625bc14070992fdddc7aed22df912007882f31f27b0e88d7b7d9445 \ + --hash=sha256:4c84a933816374b6167d9347e488fb4a357bb0e3be2e8e820dafeb3c9948feab \ + --hash=sha256:4d45ee83e1f72ee94045ccfd13e51fa7d822548f50e9d20d3d42e127bcd9f453 \ + --hash=sha256:4eb6f349c21d5a3e39733db5416e57ec171ca3b1c17b02badfdbe55d9a3666a5 \ + --hash=sha256:61a1e4f533955db0bfd4219883bfab1f2030753ffaebc9cbb4e950dfbcae3db7 \ + --hash=sha256:63b02231cc2f10d63df373fa02f3e03b4216e94c6f32ccdfd11adc770dc95fb7 \ + --hash=sha256:6e8dab3b9f84c9b591ecd1fb0920b800c08dd6c38eda3be91176fc239d3c94bc \ + --hash=sha256:7acdb7b15f060bacea01e1c68d1dd70471f03bda89478ca0ee96bac3df03d0a7 \ + --hash=sha256:87437d4f32c1dc61c3ef046dc39b9fe119ac2e2e5253e33351f1a62ba802942a \ + --hash=sha256:875c6925f3d70aa1bc4bcc405090a12deec01de71193e7229f114c5ecf39f725 \ + --hash=sha256:949f5d457c8c98998ed06d060873370d7553077ab3c2db9569acda5887cd6ce7 \ + --hash=sha256:c69c9dbe4dfab74329294d07b2956ca9a03123089a1923f3d299a21d4b66898d \ + --hash=sha256:cb4b5a532fb35ce415aea6d360fe202278b46cc59c07318b97401930a1584e35 \ + --hash=sha256:cfba6244f52bcdffe22a35334d48d741aed3077c20bb7aa9bb511c21fd766438 \ + --hash=sha256:dd781790c3fc6cb82e6c00836f7f9ab33941cf2b9dca173d7b9f41c37c78d114 \ + --hash=sha256:e397befde3d08d870a8f1c7bd80d7abc68ee119c472143ab196709319e205af4 \ + --hash=sha256:f0a37ad865b106005cb5d36efd537a412912477c83cbca1579ee45f17d73fe54 \ + --hash=sha256:fb977d427a196a620aa60b71d4b66d60c3d015c9004e7393162d4771fb435406 # via sqlglot sqlglotrs==0.13.0 \ --hash=sha256:6b934a244b16f26fca50974328a2ebc7689583c59f06203cebb46e2e6e8d93a7 \ @@ -5623,9 +5712,9 @@ sqlparams==6.2.0 \ --hash=sha256:3744a2ad16f71293db6505b21fd5229b4757489a9b09f3553656a1ae97ba7ca5 \ --hash=sha256:63b32ed9051bdc52e7e8b38bc4f78aed51796cdd9135e730f4c6a7db1048dedf # via singlestoredb -sse-starlette==3.3.4 \ - --hash=sha256:84bb06e58939a8b38d8341f1bc9792f06c2b53f48c608dd207582b664fc8f3c1 \ - --hash=sha256:aaf92fc067af8a5427192895ac028e947b484ac01edbc3caf00e7e7137c7bef1 +sse-starlette==3.4.1 \ + --hash=sha256:6b43cf21f1d574d582a6e1b0cfbde1c94dc86a32a701a7168c99c4475c6bd1d0 \ + --hash=sha256:f780bebcf6c8997fe514e3bd8e8c648d8284976b391c8bed0bcb1f611632b555 # via mcp stack-data==0.6.3 \ --hash=sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9 \ @@ -5659,9 +5748,9 @@ terminado==0.18.1 \ # via # jupyter-server # jupyter-server-terminals -testcontainers==4.9.0 \ - --hash=sha256:2cd6af070109ff68c1ab5389dc89c86c2dc3ab30a21ca734b2cb8f0f80ad479e \ - --hash=sha256:c6fee929990972c40bf6b91b7072c94064ff3649b405a14fde0274c8b2479d32 +testcontainers==4.15.0rc2 \ + --hash=sha256:4764016e73da0fa960eb8360687d22710cd68bcc01a4d03189fbe1da896a805d \ + --hash=sha256:e55b9045842c5bdfdd295e0d0b09aeafb3c1fb9d6f30bd8e718df8fd48dcdc41 # via feast (pyproject.toml) threadpoolctl==3.6.0 \ --hash=sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb \ @@ -5734,9 +5823,9 @@ thriftpy2==0.6.0 \ --hash=sha256:f6b86112cca7bd04151ce248d781763ea5f74cc18d148476c6d16cee32db81ac \ --hash=sha256:f837ab85ae93b118766b8b28a1cec47a1daddee303e1f986a595c56379062a5c # via happybase -tifffile==2026.3.3 \ - --hash=sha256:d9a1266bed6f2ee1dd0abde2018a38b4f8b2935cb843df381d70ac4eac5458b7 \ - --hash=sha256:e8be15c94273113d31ecb7aa3a39822189dd11c4967e3cc88c178f1ad2fd1170 +tifffile==2026.4.11 \ + --hash=sha256:17758ff0c0d4db385792a083ad3ca51fcb0f4d942642f4d8f8bc1287fdcf17bc \ + --hash=sha256:9b94ffeddb39e97601af646345e8808f885773de01b299e480ed6d3a41509ec9 # via scikit-image timm==1.0.26 \ --hash=sha256:985c330de5ccc3a2aa0224eb7272e6a336084702390bb7e3801f3c91603d3683 \ @@ -6004,15 +6093,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 \ @@ -6061,9 +6151,9 @@ typer==0.12.5 \ # docling # docling-core # fastapi-mcp -types-cffi==2.0.0.20260402 \ - --hash=sha256:47e1320c009f630c59c55c8e3d2b8c501e280babf52e92f6109cbfb0864ba367 \ - --hash=sha256:f647a400fba0a31d603479169d82ee5359db79bd1136e41dc7e6489296e3a2b2 +types-cffi==2.0.0.20260429 \ + --hash=sha256:6a4237bfdbd50e4d0726929070d8b9983bde541726a5a6fe0e8e24e78c1b3826 \ + --hash=sha256:afe7d9777a2921139623af0b94647637a5bd0b938b77ec125e5e5e068a1727bd # via types-pyopenssl types-protobuf==3.19.22 \ --hash=sha256:d291388678af91bb045fafa864f142dc4ac22f5d4cdca097c7d8d8a32fa9b3ab \ @@ -6071,25 +6161,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.20260408 \ + --hash=sha256:b784dc37908479e3767e2d794ab507b3674adb1c686ca3d13fc9e2960dbcb9ec \ + --hash=sha256:da630647eaaa7a926a3907794f4067f269cd245b2c202c74aa3c6a3bd660a9db # 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.20260402 \ - --hash=sha256:7827e6a9c93587cc18e766944254d1351a2396262e4abe1510cbbd7601c5e01f \ - --hash=sha256:a980142b9966713acb382c467e35c5cc4208a2f91b10b8d785a0ae6765df6c0b +types-python-dateutil==2.9.0.20260408 \ + --hash=sha256:473139d514a71c9d1fbd8bb328974bedcb1cc3dba57aad04ffa4157f483c216f \ + --hash=sha256:8b056ec01568674235f64ecbcef928972a5fac412f5aab09c516dfa2acfbb582 # via feast (pyproject.toml) -types-pytz==2026.1.1.20260402 \ - --hash=sha256:0d9a60ed1c6ad4fce7c6395b5bd2d9827db41d4b83de7c0322cf85869c2bfda3 \ - --hash=sha256:79209aa51dc003a4a6a764234d92b14e5c09a1b7f24e0f00c493929fd33618e8 +types-pytz==2026.1.1.20260408 \ + --hash=sha256:89b6a34b9198ea2a4b98a9d15cbca987053f52a105fd44f7ce3789cae4349408 \ + --hash=sha256:c7e4dec76221fb7d0c97b91ad8561d689bebe39b6bcb7b728387e7ffd8cde788 # via feast (pyproject.toml) -types-pyyaml==6.0.12.20250915 \ - --hash=sha256:0f8b54a528c303f0e6f7165687dd33fafa81c807fcac23f632b63aa624ced1d3 \ - --hash=sha256:e7d4d9e064e89a3b3cae120b4990cd370874d2bf12fa5f46c97018dd5d3c9ab6 +types-pyyaml==6.0.12.20260408 \ + --hash=sha256:92a73f2b8d7f39ef392a38131f76b970f8c66e4c42b3125ae872b7c93b556307 \ + --hash=sha256:fbc42037d12159d9c801ebfcc79ebd28335a7c13b08a4cfbc6916df78fee9384 # via feast (pyproject.toml) types-redis==4.6.0.20241004 \ --hash=sha256:5f17d2b3f9091ab75384153bfa276619ffa1cf6a38da60e10d5e6749cc5b902e \ @@ -6099,15 +6189,15 @@ types-requests==2.30.0.0 \ --hash=sha256:c6cf08e120ca9f0dc4fa4e32c3f953c3fba222bcc1db6b97695bce8da1ba9864 \ --hash=sha256:dec781054324a70ba64430ae9e62e7e9c8e4618c185a5cb3f87a6738251b5a31 # via feast (pyproject.toml) -types-setuptools==82.0.0.20260402 \ - --hash=sha256:4b9a9f6c3c4c65107a3956ad6a6acbccec38e398ff6d5f78d5df7f103dadb8d6 \ - --hash=sha256:63d2b10ba7958396ad79bbc24d2f6311484e452daad4637ffd40407983a27069 +types-setuptools==82.0.0.20260408 \ + --hash=sha256:036c68caf7e672a699f5ebbf914708d40644c14e05298bc49f7272be91cf43d3 \ + --hash=sha256:ece0a215cdfa6463a65fd6f68bd940f39e455729300ddfe61cab1147ed1d2462 # via # feast (pyproject.toml) # types-cffi -types-tabulate==0.10.0.20260308 \ - --hash=sha256:724dcb1330ffba5f46d3cf6e29f45089fccb8e85801e6e7ac9efb1195bf7bea1 \ - --hash=sha256:94a9795965bc6290f844d61e8680a1270040664b88fd12014624090fd847e13c +types-tabulate==0.10.0.20260408 \ + --hash=sha256:2b19d193603d38c34645de53c0c1087e2364487d518d4a2f44268db2366723cc \ + --hash=sha256:903d62fdf7e5a0ff659fd5d629df716232f7658c6d30e98f0374488d06ffacf4 # via feast (pyproject.toml) types-urllib3==1.26.25.14 \ --hash=sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f \ @@ -6162,9 +6252,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 @@ -6544,9 +6634,9 @@ werkzeug==3.1.8 \ --hash=sha256:63a77fb8892bf28ebc3178683445222aa500e48ebad5ec77b0ad80f8726b1f50 \ --hash=sha256:9bad61a4268dac112f1c5cd4630a56ede601b6ed420300677a869083d70a4c44 # via moto -wheel==0.46.3 \ - --hash=sha256:4b399d56c9d9338230118d705d9737a2a468ccca63d5e813e2a4fc7815d8bc4d \ - --hash=sha256:e3e79874b07d776c40bd6033f8ddf76a7dad46a7b8aa1b2787a83083519a1803 +wheel==0.47.0 \ + --hash=sha256:212281cab4dff978f6cedd499cd893e1f620791ca6ff7107cf270781e587eced \ + --hash=sha256:cc72bd1009ba0cf63922e28f94d9d83b920aa2bb28f798a31d0691b02fa3c9b3 # via # pip-tools # singlestoredb @@ -6638,6 +6728,7 @@ wrapt==1.17.3 \ --hash=sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c # via # aiobotocore + # deprecated # smart-open # testcontainers xlsxwriter==3.2.9 \ @@ -6648,147 +6739,194 @@ 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 \ @@ -6920,9 +7058,9 @@ yarl==1.23.0 \ --hash=sha256:fe8f8f5e70e6dbdfca9882cd9deaac058729bcf323cf7a58660901e55c9c94f6 \ --hash=sha256:fffc45637bcd6538de8b85f51e3df3223e4ad89bccbfca0481c08c7fc8b7ed7d # via aiohttp -zipp==3.23.0 \ - --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ - --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 +zipp==3.23.1 \ + --hash=sha256:0b3596c50a5c700c9cb40ba8d86d9f2cc4807e9bedb06bcdf7fac85633e444dc \ + --hash=sha256:32120e378d32cd9714ad503c1d024619063ec28aad2248dc6672ad13edfa5110 # 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 71c61613cb2..d06134cb36e 100644 --- a/sdk/python/requirements/py3.12-minimal-requirements.txt +++ b/sdk/python/requirements/py3.12-minimal-requirements.txt @@ -190,9 +190,9 @@ botocore==1.38.46 \ # boto3 # s3transfer # snowflake-connector-python -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +certifi==2026.4.22 \ + --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ + --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 # via # httpcore # httpx @@ -420,9 +420,9 @@ charset-normalizer==3.4.7 \ # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.3.3 \ + --hash=sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2 \ + --hash=sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 # via # feast (pyproject.toml) # dask @@ -436,56 +436,56 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via feast (pyproject.toml) -cryptography==46.0.6 \ - --hash=sha256:02fad249cb0e090b574e30b276a3da6a149e04ee2f049725b1f69e7b8351ec70 \ - --hash=sha256:063b67749f338ca9c5a0b7fe438a52c25f9526b851e24e6c9310e7195aad3b4d \ - --hash=sha256:12cae594e9473bca1a7aceb90536060643128bb274fcea0fc459ab90f7d1ae7a \ - --hash=sha256:12f0fa16cc247b13c43d56d7b35287ff1569b5b1f4c5e87e92cc4fcc00cd10c0 \ - --hash=sha256:22259338084d6ae497a19bae5d4c66b7ca1387d3264d1c2c0e72d9e9b6a77b97 \ - --hash=sha256:26031f1e5ca62fcb9d1fcb34b2b60b390d1aacaa15dc8b895a9ed00968b97b30 \ - --hash=sha256:27550628a518c5c6c903d84f637fbecf287f6cb9ced3804838a1295dc1fd0759 \ - --hash=sha256:2b417edbe8877cda9022dde3a008e2deb50be9c407eef034aeeb3a8b11d9db3c \ - --hash=sha256:2ea0f37e9a9cf0df2952893ad145fd9627d326a59daec9b0802480fa3bcd2ead \ - --hash=sha256:2ef9e69886cbb137c2aef9772c2e7138dc581fad4fcbcf13cc181eb5a3ab6275 \ - --hash=sha256:341359d6c9e68834e204ceaf25936dffeafea3829ab80e9503860dcc4f4dac58 \ - --hash=sha256:380343e0653b1c9d7e1f55b52aaa2dbb2fdf2730088d48c43ca1c7c0abb7cc2f \ - --hash=sha256:3c21d92ed15e9cfc6eb64c1f5a0326db22ca9c2566ca46d845119b45b4400361 \ - --hash=sha256:3dfa6567f2e9e4c5dceb8ccb5a708158a2a871052fa75c8b78cb0977063f1507 \ - --hash=sha256:456b3215172aeefb9284550b162801d62f5f264a081049a3e94307fe20792cfa \ - --hash=sha256:4668298aef7cddeaf5c6ecc244c2302a2b8e40f384255505c22875eebb47888b \ - --hash=sha256:50575a76e2951fe7dbd1f56d181f8c5ceeeb075e9ff88e7ad997d2f42af06e7b \ - --hash=sha256:639301950939d844a9e1c4464d7e07f902fe9a7f6b215bb0d4f28584729935d8 \ - --hash=sha256:64235194bad039a10bb6d2d930ab3323baaec67e2ce36215fd0952fad0930ca8 \ - --hash=sha256:6617f67b1606dfd9fe4dbfa354a9508d4a6d37afe30306fe6c101b7ce3274b72 \ - --hash=sha256:67177e8a9f421aa2d3a170c3e56eca4e0128883cf52a071a7cbf53297f18b175 \ - --hash=sha256:6728c49e3b2c180ef26f8e9f0a883a2c585638db64cf265b49c9ba10652d430e \ - --hash=sha256:6739d56300662c468fddb0e5e291f9b4d084bead381667b9e654c7dd81705124 \ - --hash=sha256:69cf0056d6947edc6e6760e5f17afe4bea06b56a9ac8a06de9d2bd6b532d4f3a \ - --hash=sha256:760997a4b950ff00d418398ad73fbc91aa2894b5c1db7ccb45b4f68b42a63b3c \ - --hash=sha256:79e865c642cfc5c0b3eb12af83c35c5aeff4fa5c672dc28c43721c2c9fdd2f0f \ - --hash=sha256:7e6142674f2a9291463e5e150090b95a8519b2fb6e6aaec8917dd8d094ce750d \ - --hash=sha256:7f417f034f91dcec1cb6c5c35b07cdbb2ef262557f701b4ecd803ee8cefed4f4 \ - --hash=sha256:7f6690b6c55e9c5332c0b59b9c8a3fb232ebf059094c17f9019a51e9827df91c \ - --hash=sha256:8927ccfbe967c7df312ade694f987e7e9e22b2425976ddbf28271d7e58845290 \ - --hash=sha256:8ce35b77aaf02f3b59c90b2c8a05c73bac12cea5b4e8f3fbece1f5fddea5f0ca \ - --hash=sha256:8e7304c4f4e9490e11efe56af6713983460ee0780f16c63f219984dab3af9d2d \ - --hash=sha256:90e5f0a7b3be5f40c3a0a0eafb32c681d8d2c181fc2a1bdabe9b3f611d9f6b1a \ - --hash=sha256:97c8115b27e19e592a05c45d0dd89c57f81f841cc9880e353e0d3bf25b2139ed \ - --hash=sha256:9a693028b9cbe51b5a1136232ee8f2bc242e4e19d456ded3fa7c86e43c713b4a \ - --hash=sha256:9a9c42a2723999a710445bc0d974e345c32adfd8d2fac6d8a251fa829ad31cfb \ - --hash=sha256:a3e84d5ec9ba01f8fd03802b2147ba77f0c8f2617b2aff254cedd551844209c8 \ - --hash=sha256:aad75154a7ac9039936d50cf431719a2f8d4ed3d3c277ac03f3339ded1a5e707 \ - --hash=sha256:b12c6b1e1651e42ab5de8b1e00dc3b6354fdfd778e7fa60541ddacc27cd21410 \ - --hash=sha256:b928a3ca837c77a10e81a814a693f2295200adb3352395fad024559b7be7a736 \ - --hash=sha256:bcb87663e1f7b075e48c3be3ecb5f0b46c8fc50b50a97cf264e7f60242dca3f2 \ - --hash=sha256:c797e2517cb7880f8297e2c0f43bb910e91381339336f75d2c1c2cbf811b70b4 \ - --hash=sha256:c89eb37fae9216985d8734c1afd172ba4927f5a05cfd9bf0e4863c6d5465b013 \ - --hash=sha256:cdcd3edcbc5d55757e5f5f3d330dd00007ae463a7e7aa5bf132d1f22a4b62b19 \ - --hash=sha256:d24c13369e856b94892a89ddf70b332e0b70ad4a5c43cf3e9cb71d6d7ffa1f7b \ - --hash=sha256:d4e4aadb7fc1f88687f47ca20bb7227981b03afaae69287029da08096853b738 \ - --hash=sha256:d9528b535a6c4f8ff37847144b8986a9a143585f0540fbcb1a98115b543aa463 \ - --hash=sha256:ed3775295fb91f70b4027aeba878d79b3e55c0b3e97eaa4de71f8f23a9f2eb77 \ - --hash=sha256:ed418c37d095aeddf5336898a132fba01091f0ac5844e3e8018506f014b6d2c4 +cryptography==47.0.0 \ + --hash=sha256:0024b87d47ae2399165a6bfb20d24888881eeab83ae2566d62467c5ff0030ce7 \ + --hash=sha256:07efe86201817e7d3c18781ca9770bc0db04e1e48c994be384e4602bc38f8f27 \ + --hash=sha256:09f6d7bf6724f8db8b32f11eccf23efc8e759924bc5603800335cf8859a3ddbd \ + --hash=sha256:11438c7518132d95f354fa01a4aa2f806d172a061a7bed18cf18cbdacdb204d7 \ + --hash=sha256:11dbb9f50a0f1bb9757b3d8c27c1101780efb8f0bdecfb12439c22a74d64c001 \ + --hash=sha256:14432c8a9bcb37009784f9594a62fae211a2ae9543e96c92b2a8e4c3cd5cd0c4 \ + --hash=sha256:1581aef4219f7ca2849d0250edaa3866212fb74bf5667284f46aa92f9e65c1ca \ + --hash=sha256:160ad728f128972d362e714054f6ba0067cab7fb350c5202a9ae8ae4ce3ef1a0 \ + --hash=sha256:1a405c08857258c11016777e11c02bacbe7ef596faf259305d282272a3a05cbe \ + --hash=sha256:1e47422b5557bb82d3fff997e8d92cff4e28b9789576984f08c248d2b3535d93 \ + --hash=sha256:20fdbe3e38fb67c385d233c89371fa27f9909f6ebca1cecc20c13518dae65475 \ + --hash=sha256:2207a498b03275d0051589e326b79d4cf59985c99031b05bb292ac52631c37fe \ + --hash=sha256:256d07c78a04d6b276f5df935a9923275f53bd1522f214447fdf365494e2d515 \ + --hash=sha256:2b45761c6ec22b7c726d6a829558777e32d0f1c8be7c3f3480f9c912d5ee8a10 \ + --hash=sha256:2ebd84adf0728c039a3be2700289378e1c164afc6748df1a5ed456767bef9ba7 \ + --hash=sha256:34b4358b925a5ea3e14384ca781a2c0ef7ac219b57bb9eacc4457078e2b19f92 \ + --hash=sha256:3fb8fa48075fad7193f2e5496135c6a76ac4b2aa5a38433df0a539296b377829 \ + --hash=sha256:4e1de79e047e25d6e9f8cea71c86b4a53aced64134f0f003bbcbf3655fd172c8 \ + --hash=sha256:4f7722c97826770bab8ae92959a2e7b20a5e9e9bf4deae68fd86c3ca457bab52 \ + --hash=sha256:51c9313e90bd1690ec5a75ed047c27c0b8e6c570029712943d6116ef9a90620b \ + --hash=sha256:5d0e362ff51041b0c0d219cc7d6924d7b8996f57ce5712bdcef71eb3c65a59cc \ + --hash=sha256:6651d32eff255423503aa276739da98c30f26c40cbeffcc6048e0d54ef704c0c \ + --hash=sha256:6eebcaf0df1d21ce1f90605c9b432dd2c4f4ab665ac29a40d5e3fc68f51b5e63 \ + --hash=sha256:6f29f36582e6151d9686235e586dd35bb67491f024767d10b842e520dc6a07ac \ + --hash=sha256:7a02675e2fabd0c0fc04c868b8781863cbf1967691543c22f5470500ff840b31 \ + --hash=sha256:7f1207974a904e005f762869996cf620e9bf79ecb4622f148550bb48e0eb35a7 \ + --hash=sha256:7f68d6fbc7fbbcfb0939fea72c3b96a9f9a6edfc0e1b1d29778a2066030418b1 \ + --hash=sha256:7fda2f02c9015db3f42bb8a22324a454516ed10a8c29ca6ece6cdbb5efe2a203 \ + --hash=sha256:80887c5cbd1774683cb126f0ab4184567f080071d5acf62205acb354b4b753b7 \ + --hash=sha256:835d2d7f47cdc53b3224e90810fb1d36ca94ea29cc1801fb4c1bc43876735769 \ + --hash=sha256:8c1a736bbb3288005796c3f7ccb9453360d7fed483b13b9f468aea5171432923 \ + --hash=sha256:9af828c0d5a65c70ec729cd7495a4bf1a67ecb66417b8f02ff125ab8a6326a74 \ + --hash=sha256:9c59ab0e0fa3a180a5a9c59f3a5abe3ef90d474bc56d7fadfbe80359491b615b \ + --hash=sha256:9f8e55fe4e63613a5e1cc5819030f27b97742d720203a087802ce4ce9ceb52bb \ + --hash=sha256:9fe6b7c64926c765f9dff301f9c1b867febcda5768868ca084e18589113732ab \ + --hash=sha256:a49a3eb5341b9503fa3000a9a0db033161db90d47285291f53c2a9d2cd1b7f76 \ + --hash=sha256:a9b761f012a943b7de0e828843c5688d0de94a0578d44d6c85a1bae32f87791f \ + --hash=sha256:b1c76fca783aa7698eb21eb14f9c4aa09452248ee54a627d125025a43f83e7a7 \ + --hash=sha256:b9a8943e359b7615db1a3ba587994618e094ff3d6fa5a390c73d079ce18b3973 \ + --hash=sha256:be12cb6a204f77ed968bcefe68086eb061695b540a3dd05edac507a3111b25f0 \ + --hash=sha256:cffbba3392df0fa8629bb7f43454ee2925059ee158e23c54620b9063912b86c8 \ + --hash=sha256:ed67ea4e0cfb5faa5bc7ecb6e2b8838f3807a03758eec239d6c21c8769355310 \ + --hash=sha256:edd4da498015da5b9f26d38d3bfc2e90257bfa9cbed1f6767c282a0025ae649b \ + --hash=sha256:ef6b3634087f18d2155b1e8ce264e5345a753da2c5fa9815e7d41315c90f8318 \ + --hash=sha256:f1557695e5c2b86e204f6ce9470497848634100787935ab7adc5397c54abd7ab \ + --hash=sha256:f5c15764f261394b22aef6b00252f5195f46f2ca300bec57149474e2538b31f8 \ + --hash=sha256:f5c3296dab66202f1b18a91fa266be93d6aa0c2806ea3d67762c69f60adc71aa \ + --hash=sha256:f7db373287273d8af1414cf95dc4118b13ffdc62be521997b0f2b270771fef50 \ + --hash=sha256:f9a034b642b960767fb343766ae5ba6ad653f2e890ddd82955aef288ffea8736 # via # google-auth # pyjwt @@ -505,50 +505,50 @@ dill==0.3.9 \ --hash=sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a \ --hash=sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c # via feast (pyproject.toml) -duckdb==1.5.1 \ - --hash=sha256:054ad424b051b334052afac58cb216f3b1ebb8579fc8c641e60f0182e8725ea9 \ - --hash=sha256:05fc91767d0cfc4cf2fa68966ab5b479ac07561752e42dd0ae30327bd160f64a \ - --hash=sha256:0a6acc2040bec1f05de62a2f3f68f4c12f3ec7d6012b4317d0ab1a195af26225 \ - --hash=sha256:26e56b5f0c96189e3288d83cf7b476e23615987902f801e5788dee15ee9f24a9 \ - --hash=sha256:36e8e32621a9e2a9abe75dc15a4b54a3997f2d8b1e53ad754bae48a083c91130 \ - --hash=sha256:40c5220ec93790b18ec6278da9c6ac2608d997ee6d6f7cd44c5c3992764e8e71 \ - --hash=sha256:446d500a2977c6ae2077f340c510a25956da5c77597175c316edfa87248ceda3 \ - --hash=sha256:46f92ada9023e59f27edc048167b31ac9a03911978b1296c845a34462a27f096 \ - --hash=sha256:482f8a13f2600f527e427f73c42b5aa75536f9892868068f0aaf573055a0135f \ - --hash=sha256:553c273a6a8f140adaa6da6a6135c7f95bdc8c2e5f95252fcdf9832d758e2141 \ - --hash=sha256:5ae7c0d744d64e2753149634787cc4ab60f05ef1e542b060eeab719f3cdb7723 \ - --hash=sha256:5d4147422d91ccdc2d2abf6ed24196025e020259d1d267970ae20c13c2ce84b1 \ - --hash=sha256:6af347debc8b721aa72e48671166282da979d5e5ae52dbc660ab417282b48e23 \ - --hash=sha256:6ba302115f63f6482c000ccfd62efdb6c41d9d182a5bcd4a90e7ab8cd13856eb \ - --hash=sha256:6f7361d66cc801d9eb4df734b139cd7b0e3c257a16f3573ebd550ddb255549e6 \ - --hash=sha256:715f05ea198d20d7f8b407b9b84e0023d17f2b9096c194cea702b7840e74f1f7 \ - --hash=sha256:71dddcebbc5a70e946a06c30b59b5dd7999c9833d307168f90fb4e4b672ab63e \ - --hash=sha256:8150c569b2aa4573b51ba8475e814aa41fd53a3d510c1ffb96f1139f46faf611 \ - --hash=sha256:8843bd9594e1387f1e601439e19ad73abdf57356104fd1e53a708255bb95a13d \ - --hash=sha256:8c0088765747ae5d6c9f89987bb36f9fb83564f07090d721344ce8e1abedffea \ - --hash=sha256:972d0dbf283508f9bc446ee09c3838cb7c7f114b5bdceee41753288c97fe2f7c \ - --hash=sha256:a28531cee2a5a42d89f9ba4da53bfeb15681f12acc0263476c8705380dadce07 \ - --hash=sha256:a3be2072315982e232bfe49c9d3db0a59ba67b2240a537ef42656cc772a887c7 \ - --hash=sha256:ac2804043bd1bc10b5da18f8f4c706877197263a510c41be9b4c0062f5783dcc \ - --hash=sha256:afab8b4b1f4469c3879bb049dd039f8fce402712050324e9524a43d7324c5e87 \ - --hash=sha256:b370d1620a34a4538ef66524fcee9de8171fa263c701036a92bc0b4c1f2f9c6d \ - --hash=sha256:b8b0808dba0c63b7633bdaefb34e08fe0612622224f9feb0e7518904b1615101 \ - --hash=sha256:bc7ca6a1a40e7e4c933017e6c09ef18032add793df4e42624c6c0c87e0bebdad \ - --hash=sha256:caa65e1f5bf007430bf657c37cab7ab81a4ddf8d337e3062bcc5085d17ef038b \ - --hash=sha256:d68c5a01a283cb13b79eafe016fe5869aa11bff8c46e7141c70aa0aac808010f \ - --hash=sha256:da137802688190835b4c863cafa77fd7e29dff662ee6d905a9ffc14f00299c91 \ - --hash=sha256:e56a20ab6cdb90a95b0c99652e28de3504ce77129087319c03c9098266183ae5 \ - --hash=sha256:e878ccb7d20872065e1597935fdb5e65efa43220c8edd0d9c4a1a7ff1f3eb277 \ - --hash=sha256:eba81e0b3011c1f23df7ea47ef4ffaa8239817959ae291515b6efd068bde2161 \ - --hash=sha256:ed6d23a3f806898e69c77430ebd8da0c79c219f97b9acbc9a29a653e09740c59 +duckdb==1.5.2 \ + --hash=sha256:0b291786014df1133f8f18b9df4d004484613146e858d71a21791e0fcca16cf4 \ + --hash=sha256:2323c1195c10fb2bb982fc0218c730b43d1b92a355d61e68e3c5f3ac9d44c34f \ + --hash=sha256:2a1de4f4d454b8c97aec546c82003fc834d3422ce4bc6a19902f3462ef293bed \ + --hash=sha256:35579b8e3a064b5eaf15b0eafc558056a13f79a0a62e34cc4baf57119daecfec \ + --hash=sha256:376856066c65ccd55fcb3a380bbe33a71ce089fc4623d229ffc6e82251afdb6d \ + --hash=sha256:411ad438bd4140f189a10e7f515781335962c5d18bd07837dc6d202e3985253d \ + --hash=sha256:4420b3f47027a7849d0e1815532007f377fa95ee5810b47ea717d35525c12f79 \ + --hash=sha256:486c862bf7f163c0110b6d85b3e5c031d224a671cca468f12ebb1d3a348f6b39 \ + --hash=sha256:52a21823f3fbb52f0f0e5425e20b07391ad882464b955879499b5ff0b45a376b \ + --hash=sha256:5596bbfc31b1b259db69c8d847b42d036ce2c4804f9ccb28f9fc46a16de7bc53 \ + --hash=sha256:56d38b3c4e0ef2abb58898d0fd423933999ed535c45e75e9d9f72e1d5fed69b8 \ + --hash=sha256:638da0d5102b6cb6f7d47f83d0600708ac1d3cb46c5e9aaabc845f9ba4d69246 \ + --hash=sha256:63bf8687feefeed51adf45fa3b062ab8b1b1c350492b7518491b86bae68b1da1 \ + --hash=sha256:6b0fe75c148000f060aa1a27b293cacc0ea08cc1cad724fbf2143d56070a3785 \ + --hash=sha256:70631c847ca918ee710ec874241b00cf9d2e5be90762cbb2a0389f17823c08f7 \ + --hash=sha256:7f69164b048e498b9e9140a24343108a5ae5f17bfb3485185f55fdf9b1aa924d \ + --hash=sha256:81fc4fbf0b5e25840b39ba2a10b78c6953c0314d5d0434191e7898f34ab1bba3 \ + --hash=sha256:84b193aca20565dedb3172de15f843c659c3a6c773bf14843a9bd781c850e7db \ + --hash=sha256:8d599758b4e48bf12e18c9b960cf491d219f0c4972d19a45489c05cc5ab36f83 \ + --hash=sha256:8dbd7e31e5dc157bfe8803fa7d2652336265c6c19926c5a4a9b40f8222868d08 \ + --hash=sha256:98c0535cd6d901f61a5ea3c2e26a1fd28482953d794deb183daf568e3aa5dda6 \ + --hash=sha256:a9cd5e71702d446613750405cde03f66ed268f4c321da071b0472759dad19536 \ + --hash=sha256:bb42e6ed543902e14eae647850da24103a89f0bc2587dec5601b1c1f213bd2ed \ + --hash=sha256:be37680ddb380015cb37318e378c53511c45c4f0d8fac5599d22b7d092b9217a \ + --hash=sha256:c69907354ffee94ba8cf782daf0480dab7557f21ce27fffa6c0ea8f74ed4b8e2 \ + --hash=sha256:c99ef73a277c8921bc0a1f16dee38d924484251d9cfd20951748c20fcd5ed855 \ + --hash=sha256:c9f3e0b71b8a50fccfb42794899285d9d318ce2503782b9dd54868e5ecd0ad31 \ + --hash=sha256:ce0b8141a10d37ecef729c45bc41d334854013f4389f1488bd6035c5579aaac1 \ + --hash=sha256:ce17670bb392ea1b3650537db02bd720908776b5b95f6d2472d31a7de59d1dc1 \ + --hash=sha256:d72b8856b1839d35648f38301b058f6232f4d36b463fe4dc8f4d3fdff2df1a2e \ + --hash=sha256:d9b4f5430bf4f05d4c0dc4c55c75def3a5af4be0343be20fa2bfc577343fbfc9 \ + --hash=sha256:e6495b00cad16888384119842797c49316a96ae1cb132bb03856d980d95afee1 \ + --hash=sha256:ea58ff5b0880593a280cf5511734b17711b32ee1f58b47d726e8600848358160 \ + --hash=sha256:ef461bca07313412dc09961c4a4757a851f56b95ac01c58fac6007632b7b94f2 \ + --hash=sha256:fc85a5dbcbe6eccac1113c72370d1d3aacfdd49198d63950bdf7d8638a307f00 # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ --hash=sha256:3b41e1b601234296b4fb368338fdcd3e13e0b4fb5b67345948f4f2bf9868b286 # via kubernetes -fastapi==0.135.3 \ - --hash=sha256:9b0f590c813acd13d0ab43dd8494138eb58e484bfac405db1f3187cfc5810d98 \ - --hash=sha256:bd6d7caf1a2bdd8d676843cdcd2287729572a1ef524fc4d65c17ae002a1be654 +fastapi==0.136.1 \ + --hash=sha256:7af665ad7acfa0a3baf8983d393b6b471b9da10ede59c60045f49fbc89a0fa7f \ + --hash=sha256:a6e9d7eeada96c93a4d69cb03836b44fa34e2854accb7244a1ece36cd4781c3f # via # feast (pyproject.toml) # fastapi-mcp @@ -556,9 +556,9 @@ fastapi-mcp==0.4.0 \ --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d # via feast (pyproject.toml) -filelock==3.25.2 \ - --hash=sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694 \ - --hash=sha256:ca8afb0da15f229774c9ad1b455ed96e85a81373065fb10446672f64444ddf70 +filelock==3.29.0 \ + --hash=sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90 \ + --hash=sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258 # via snowflake-connector-python frozenlist==1.8.0 \ --hash=sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686 \ @@ -700,9 +700,9 @@ fsspec==2024.9.0 \ # via # feast (pyproject.toml) # dask -google-api-core[grpc]==2.30.2 \ - --hash=sha256:9a8113e1a88bdc09a7ff629707f2214d98d61c7f6ceb0ea38c42a095d02dc0f9 \ - --hash=sha256:a4c226766d6af2580577db1f1a51bf53cd262f722b49731ce7414c43068a9594 +google-api-core[grpc]==2.30.3 \ + --hash=sha256:a85761ba72c444dad5d611c2220633480b2b6be2521eca69cca2dbb3ffd6bfe8 \ + --hash=sha256:e601a37f148585319b26db36e219df68c5d07b6382cff2d580e83404e44d641b # via # feast (pyproject.toml) # google-cloud-bigquery @@ -712,9 +712,9 @@ google-api-core[grpc]==2.30.2 \ # google-cloud-datastore # google-cloud-storage # pandas-gbq -google-auth==2.49.1 \ - --hash=sha256:16d40da1c3c5a0533f57d268fe72e0ebb0ae1cc3b567024122651c045d879b64 \ - --hash=sha256:195ebe3dca18eddd1b3db5edc5189b76c13e96f29e73043b923ebcf3f1a860f7 +google-auth==2.50.0 \ + --hash=sha256:04382175e28b94f49694977f0a792688b59a668def1499e9d8de996dc9ce5b15 \ + --hash=sha256:f35eafb191195328e8ce10a7883970877e7aeb49c2bfaa54aa0e394316d353d0 # via # google-api-core # google-auth-oauthlib @@ -909,101 +909,112 @@ 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.3.1 \ + --hash=sha256:002fc0201b9af1cc8960e27cdc501ad1f8cdd6dbadb2091c6ddbd4e5ace6cb77 \ + --hash=sha256:011a9071c3df4885cac7f58a2623feac6c8e2ad30e6ba93c55195af05ce61ff5 \ + --hash=sha256:01cf82a514bc4fd145b99333c28523e61b7a9ad051a245804323ebf4e7b1c6a6 \ + --hash=sha256:027ce4fabfeff5af5b9869d5524770877f9061d118bc36b85703ae3faf5aad8e \ + --hash=sha256:03baa381964b8df356d19ec4e3a6ae656044249a87b0def257fe1e08dbaf6094 \ + --hash=sha256:042e57de8a2cae91e3e7c0af32960ea2c5107b2f27f68a740295861e68780a8a \ + --hash=sha256:09d41a3a965f7c261223d516ebda607aee4d8440dd7637f01af9a4c05872f0c4 \ + --hash=sha256:09f5e510f637f2c72d2a79fb3ad05f7b6211e057e367ca5c4f97bb3d8c9d71f4 \ + --hash=sha256:0b5ff2f643f4b452b0597b7fe6aa35d398cb31d8806801acfafb1558610ea2aa \ + --hash=sha256:0caf3fc8af0767794b335753781c3fa35f2a3e975c098edbc8f733d35d6a95e4 \ + --hash=sha256:0fac4af8515e6cca74fc701169ae4dc9a71a90e9319c9d21006ec9454b43aa2f \ + --hash=sha256:113e098e4a6b3cc5500e05e7cb1548ba9e83de5fe755941b11f6020a76e6c03a \ + --hash=sha256:137c14905ea6f2933967200bc7b2a0c8ec9387888b273fd0004f25b994fd0343 \ + --hash=sha256:156be6a0c736ee145cfe0fb155d0e96cec8d4872cf8b4f76ad6a2ee6ab391d0a \ + --hash=sha256:17ec8b524055a88b80d76c177dbbbe475a25c17c5bf4b67bdbdbd0629bcae838 \ + --hash=sha256:1ac7697365dbe45109273b34227fee6826b276ead9a4a007e0877e1d3f0fcf21 \ + --hash=sha256:1b46e96b50dad03495447860510daebd2c96fd44ed25ba8ccb03e9f89eaa9d34 \ + --hash=sha256:1ebc307a87b099d0877dbd2bdc0bae427258e7ec67f60a951e89027f8dc2568f \ + --hash=sha256:1f7bceb03a1b934872ffe3942eaeed7c7e09096e67b53f095b81f39c7a819113 \ + --hash=sha256:2611bfaaadc5e8d43fb7967f9bbf1110c8beaa83aee2f2d812c76f11cfb56c6a \ + --hash=sha256:264ee7e9cb6c30dc78da4ecf71d74cf14ca122817c665d838eda8b4384bce1b0 \ + --hash=sha256:26f899cde0279e4b7d370716ff80320601c2bd93cdf3e774a42bdd44f65b41f8 \ + --hash=sha256:29fe35e3c6fe03204e75c86514f452591957a1e06b05d86e10d795455b71c355 \ + --hash=sha256:2afc675b831f7552da41116fffffca4340f387dc03f56d6ec0c7895ab0b59a10 \ + --hash=sha256:2b6da6e07359107c653a809b3cff2d9ccaeedbafe33c6f16434aef6f53ce4a2b \ + --hash=sha256:2b96da7e365d6488d2a75266a662cbe3cc14b28c23dd9b0c9aa04b5bc5c20192 \ + --hash=sha256:2f1c1b2e8f00b71e6214234d313f655a3a27cd4384b054126ce04073c1d47045 \ + --hash=sha256:304481241e081bc26f0778b2c2b99f9c43917e4e724a016dcc9439b7ab12c726 \ + --hash=sha256:318f772dd321404075d406825266e574ee0f4751be1831424c2ebd5722609398 \ + --hash=sha256:3586c8a5f56d34b9dddaaa9e76905f31933cac267251006adf86ec0eef7d0400 \ + --hash=sha256:3724f0e58c6ff76fd683429945491de71324ab1bc0ad943a8d68cb0932d24075 \ + --hash=sha256:3fb6573efa15a29c12c0c0f7170b14e7c1347fe4bb39b6a15b779f46015cc929 \ + --hash=sha256:40ae8a7041fcb328a6bc7202d8c4e6e0d38d434b2e3880b1ee8ed754f17cd836 \ + --hash=sha256:4106201cd052d9eabe3cb7b5a24b0fe37307792bda4fcb3cf6ddd72f697828e8 \ + --hash=sha256:439f9a5cc8f9519ce208a24cdebfa0440fef26aa682a40ba2c92acb10a53f5e0 \ + --hash=sha256:4479e36d263251dba8ab8ea81adf07e7f1163603c7102c5de1e130b83b4fad3b \ + --hash=sha256:487658e1db83c1ee9fbbac6a43039ea76957767a5987ffb16b590613f9e68297 \ + --hash=sha256:48ff424f8aa36aacd9fdaa68efeb27d2e8771f293af4305bdb15d92194ca6631 \ + --hash=sha256:4f7e242eab698ad0be5a4b2ec616fa856569c57455cc67c625fd567726290e5f \ + --hash=sha256:526db52e5234a9463520e960a509d6c1bd5128d1ab1b569cbf459fe39189e8ab \ + --hash=sha256:52d5641027d6731bc7b5e7d126a5158a99784a9f8c6de3d97ca89aca4969e9f8 \ + --hash=sha256:53148a4e21057541b6d8e493b2ea1b500037ddf34433c391970036f3cbce00e3 \ + --hash=sha256:583de2f16528e66081cbdfe510d8488c2de73039dc00aada7d22bd49d73a4a94 \ + --hash=sha256:5e55d90b431b0c6b64ae5a624208d4aea318566d31872e595ee723c0f5b9a79f \ + --hash=sha256:5f316cf2d0558f5027aab19dde7d7e4901c26c21fa95367bc37784e8f547bbf2 \ + --hash=sha256:60543f3b068b16a86e99ed96b7fdae71cdc1d8abdfe9b3f82032a555e52ece7e \ + --hash=sha256:62cc62284541bb2a86c898c7d5e8388661cade91c184cb862095ed547e80588f \ + --hash=sha256:65c05b79cb8366c123357b354a16f9fc3f7187159422f143638d1c26b7240ed4 \ + --hash=sha256:65f6ac06a9f0c32c254660ec6a9329d81d589e8f5d0a9837a941d5424a6be1ef \ + --hash=sha256:6d1434d0bcc1b3ef048bae53f26456405c08aeed9827e65b24094f5f3a6793f1 \ + --hash=sha256:6e2e1024f0a021777740cb7c633a0efb2c4a4bc570f508223a8dcbcf79f99ef9 \ + --hash=sha256:6ffa7ba2e2da1f806f3181b9730b3e87ba9dbfec884806725d4584055ba3faa6 \ + --hash=sha256:743b85bd6902856cac457ddd8cd7dd48c89c47d641b6016ff5e4d015bfbd4799 \ + --hash=sha256:77c5d2bebbc9d06691abb512a31d0f54e1562af0b872891463a67a949b5278ef \ + --hash=sha256:79cd03e7ff550c17758a7520bf437c156d3d4c8bb74214deeafa69cda49c85a4 \ + --hash=sha256:80aba5f85d6227faee628ae28d1c3b69c661806a0636548ac56c68782606454f \ + --hash=sha256:81a1669b6631976b1dc9d3d58ed1ab3333e9f52feb91a2a1fb8241101ac3b665 \ + --hash=sha256:8597c35c9e82f65fd5897c4a2188c65d7daf10607b102960137b23d261cd957b \ + --hash=sha256:8650158217b469d8b6087f490929211b0493a9121154c4efaafd1dec9e19319e \ + --hash=sha256:8887bf0f31e4b550bd988c8863b527b6587d200653e9375cd91eea2b944b7424 \ + --hash=sha256:8a52b24cd710690c4a7e191c7e300136ad2ecb3c68ffe7e95b598e76de166e5e \ + --hash=sha256:8e3754ce60e1b11b0afad9a053481ff184d2ee24bea47099107156d1b84a84aa \ + --hash=sha256:907f7b5501a534030738f0f27459a612d2266fd0507b007bb8f3e6de08167920 \ + --hash=sha256:90d6b9f2652303aefd2c5a26a5e14cb74a3a63d10faa642c08d790e99442a088 \ + --hash=sha256:98fd5b39410e9d69e10e90d0330e35650becaa5dd2548f509b9598f1f3c6124d \ + --hash=sha256:9bfdeff778d3f7ff449ca5922ab773899e7d31e26a576028b06a5e9cf0ed8c34 \ + --hash=sha256:9ebae74ce2b977c2fcb22d6a10aa0acb730022406977b2bcb6ddd6788f5c414a \ + --hash=sha256:a110d19881ca78a88583d3b07231e7c6864864f5f1f3491b638863ea45fa8708 \ + --hash=sha256:a1d190790ee39b8b7adeeb10fc4090dc4859eb4e75ed27bd8108710eef18f358 \ + --hash=sha256:a2f049c3f3c83e886cd1f53958e2a1ebb369be626bef9e50d8b24d79864f1df6 \ + --hash=sha256:a3af4e9f277d6b8acd369dc44a723a055752fca9d045094383af39f90a3e3729 \ + --hash=sha256:a42c7becd4c9ec4ab5769c754eb61112777bdc6e1c1525e2077389e193b5f5aa \ + --hash=sha256:a58a58cef0d911b1717154179a9ff47852249c536ea5966bde4370b6b20638ff \ + --hash=sha256:ab1f646ff531d70bfd25f01e60708dfa3d105eb458b7dedd9fe9a443039fd809 \ + --hash=sha256:ad940dc2db545dc978cb41cb9a683e2ff328f3ef581230b9ca40ff6c3d01d542 \ + --hash=sha256:afe3c3863f16704fb5d7c2c6ff56aaf9e054f6d269f7b4c9074c5476178d1aba \ + --hash=sha256:b1e3b9f4bf9a4120510ba77a77b2fb674893cd6795653545152bb11a79eecfcb \ + --hash=sha256:b2390ad81c03d93ef1d5afd18ffcf5935de827f1a2b96b2c829437968bdabccb \ + --hash=sha256:b37df4b10cb15dedfc203f69312d8eedd617b941c21df58c13af59496c53ad0f \ + --hash=sha256:b3df9447f9209f9aa0434ca74050e9509670c1ad99398fe5807abb90e5f3a014 \ + --hash=sha256:b4fe7f38aa8956fcc1cea270e62601e0e11066aff78e384be70fd283d30293b6 \ + --hash=sha256:c1d68c6980d4690a4550bd3db6c03146f7be68ef5d08d38bb1fb68b3e9c32fe3 \ + --hash=sha256:c24c1460486b6b36083252c2db21a814becf8495ccd0e76b7286623e37239b63 \ + --hash=sha256:c25132902d3eff38781e0d54f27a0942ec849e3c07dbdce83c4d92b7e43c8dce \ + --hash=sha256:c74bd9926954e7e575f9cd9890f63defd90cd8f812dfbf8e1efb72acc9355456 \ + --hash=sha256:c8139e9011117822391c5bcfd674c5948fb1e4b8cb9adf6f13d9890859ee3a1a \ + --hash=sha256:ce334915f5d31048f76a42c607bf26687cf045eb1bc852b7340f09729c6a64fc \ + --hash=sha256:d14229beaa76e66c3a25f9477d973336441ca820df853679a98796256813316f \ + --hash=sha256:d42f3a13290f89191568fc113d95a3d2c8759cdd8c3672f021d8b7436f909e75 \ + --hash=sha256:d8e56e0d1fe607bfff422633f313aec9191c3859ab99d11ff097e3e6e068000c \ + --hash=sha256:da6f0302360e99d32bc2869772692797ebadd536e1b826d0103c72ba49d38698 \ + --hash=sha256:db46baf157feefd88724e6a7f145fe996a5990a8604ed9292b45d563360e513b \ + --hash=sha256:dcea8c3f53674ae68e44b12e853b844a1d315250ca6677b11ec0c06aff85e86c \ + --hash=sha256:de94b409f49eb6a588ebdd5872e826caec417cd77c17af0fb94f2128427f1a2a \ + --hash=sha256:e0356561b4a97c83b9ee3de657a41b8d1a1781226853adaf47b550bb988fda6f \ + --hash=sha256:e0db44cf81e4d7b94f3776b9f89111f74ed6bbdbfd42a22bc4a5ce0644d3e060 \ + --hash=sha256:e31e92b61d56244047ad600812e16f7587a6172f74810fd919ff993af12b9149 \ + --hash=sha256:e89dabf436ee79b358fd970dcbed6333a36d91db73f27069ca24a02fb138a404 \ + --hash=sha256:eddeb9a153795cf6e615f9f3cef66a1d573ff3b6ee16df2b10d1d1c2f2baeaa8 \ + --hash=sha256:ee11fd431f83d8a5b29d370b9d79a814d3218d30113bdcd44657e9bdf715fc92 \ + --hash=sha256:ee37fe8cf081b72dea72f96a0ee604f492ec02252eb77dc26ff6eec3f997b580 \ + --hash=sha256:f19ee7dc1ef8a6497570d91fa4057ba910ad98297a50b8c44ff37589f7c89d17 \ + --hash=sha256:f2f94355affd51088f57f8674b0e294704c3c7c3d7d3b1545310f5b135d4843b \ + --hash=sha256:f525734382a47f9828c9d6a1501522c78d5935466d8e2be1a41ba40ca5bb922b \ + --hash=sha256:f915a34fb742e23d0d61573349aa45d6f74037fde9d58a9f340435eff8d62736 # via feast (pyproject.toml) httpcore==1.0.9 \ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ @@ -1068,9 +1079,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.13 \ + --hash=sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242 \ + --hash=sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 # via # anyio # httpx @@ -1102,97 +1113,97 @@ kubernetes==35.0.0 \ --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee # 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.9.0 \ + --hash=sha256:07cf11f769831186eeac424376e6189f20ace4f7263e2134bdb9757340d84d4d \ + --hash=sha256:0a09c2f5869649101738653a9b7ab70cf045a1105ac66cbb8f4055e61df78f2d \ + --hash=sha256:0a1be03168b2691ba61927e299b352a6315189199ca18a57b733f86cb3cc8d38 \ + --hash=sha256:0b73e4266307e51c95e09c0750b7ec383c561d2e97d58e473f6f6a209952fbb8 \ + --hash=sha256:15cb151e52a044f06e54ac7f7b47adbfc89b5c8e2b63e1175a9d587c43e8942a \ + --hash=sha256:194fc1a32e1e21fe809d38b5faea66cc65eaa00217c8901fbdb99866938adbdb \ + --hash=sha256:1bf465d1e5b0a27713862441f6467b5ab76385f4ecf8f1f3a44f8aa3c695b4b6 \ + --hash=sha256:1c587494461ebd42229d0f1739f3aa34237dd9980623ecf1be8d3bcba79f4499 \ + --hash=sha256:224b9727eb8bc188bc3bcf29d969dba0cd61b01d9bac80c41575520cc4baabb2 \ + --hash=sha256:22a904cbdb678f7cb348c90d543d3c52f581663d687992fee47fd566dcbf5285 \ + --hash=sha256:2b8f5d00b49818f4e2b1667db994488b045835e0ac16fe2f924f3871bd2b8ac5 \ + --hash=sha256:2c3786f0f4490a5cd87f1ed6cefae833ad6b1060d52044ce0434a2e85893afd0 \ + --hash=sha256:2d03fa4fd277a7974c1978c92c374c57f44edeee163d147b477b143446ad1bf6 \ + --hash=sha256:2f8e12706dcb8ff6b3ed57514a19e45c49ad00bcd423e87b2b2e4b5f64578443 \ + --hash=sha256:3be322a15ee5e70b93b7a59cfd074614f22cc8c9ff18bd27f474e79137ea8d3b \ + --hash=sha256:3cc2917258e131ae5f958a4d872e07555b51cb7466a43433218061c74ef33745 \ + --hash=sha256:3f05d145df35dca5056a8bc3838e940efebd893a54b3e19b2dda39ceaa299bcb \ + --hash=sha256:3fe56e80badb66fdcde06bef81bbaa5bfcf6fbd7aefb86222d9e369c38c6b228 \ + --hash=sha256:42ff8a962554c350d4a83cf47d9b7b78b0e6ff7943e87df7cdfc97c07f3c016f \ + --hash=sha256:451daa98463b7695b0a30aa56bf637831ea559e7b8101ac2ef6382e8eb15e29c \ + --hash=sha256:465814ab157986acb9dfa5ccd7df944be5eefc0d08d31ec6e8d88bc71251d845 \ + --hash=sha256:4c4d0440a3a8e31d962340c3e1cc3fc9ee7febd34c8d8f770d06adb947779ea5 \ + --hash=sha256:4e3dda8345307fd7306db0ed0cb109a63a2c85ba780eb9dc2d09b2049a931f9c \ + --hash=sha256:5093043afb226ecfa1400120d1ebd4442b4f99977783e4f4f7248879009b227f \ + --hash=sha256:5112c2fb7c2eefefaeaf5c97fec81343ef44ee86a30dcfaa8223822fba6467b4 \ + --hash=sha256:527b5b820b47a09e09829051452bb0d1dd2122261254e2a6f674d12f1d793d54 \ + --hash=sha256:54d412e47c21b85865676ed0724e37a89e9593c2eee1e7367adf85bfad56ffb1 \ + --hash=sha256:56d65b583cf43b8cf4c8fbe1e1da20fa3076cc32a1149a141507af1062718236 \ + --hash=sha256:5ca8e133d799c948db2ab1afc081c333a825b5540475164726dcbf73537e5c2f \ + --hash=sha256:603138ee838ee1583f1b960b62d5d0007845c5c423feb68e44648b1359014e27 \ + --hash=sha256:63c12efcd160e1d14da11af0c46c0217473e1e0d2ae1acbccc83f561ea4c2a7b \ + --hash=sha256:657f8ba7b9eaaa82759a104137aed2a3ef7bc46ccfd43e0d89b04005b3e0a4cc \ + --hash=sha256:66b58fed90a545328e80d575467244de3741e088c1af928f0b489ebec3ef3858 \ + --hash=sha256:6788207daa0c19955d2b668f3294a368d19f67d9b5f274553fd073c1260cbb9f \ + --hash=sha256:703f4ae36d6240bfe24f542bac784c7e4194ec49c3ba5a994d02891649e2d85b \ + --hash=sha256:7202bdcac47d3a708271c4304a474a8605a4a9a4a709e954bf2d3241140aa938 \ + --hash=sha256:756775d25ec8345b837ab52effee3ad2f3b2dfd6bbee3e3f029c517bd5d8f05a \ + --hash=sha256:78042f6facfd98ecb25e9829c7e37cce23363d9d7c83bc5f72702c5059eb082b \ + --hash=sha256:789fff71757facc0738e8d89e3b84e4f0251c1c975e85e81b152cdaca927cc2d \ + --hash=sha256:7bc30ad339f4e1a01d4917d645e522a0bc0030644d8973f6346397c93ba1503f \ + --hash=sha256:7d429bdd4ac0ab17c8e4a8af0ed2a7440b16eba474909ab357131018fe8c7e71 \ + --hash=sha256:7d5c8a5929ac325729f6119802070b561f4db793dffc45e9ac750992a4ed4d22 \ + --hash=sha256:7e6274fd33fc5b2a14d41c9119629d3ff395849d8bcbc80cf637d9e8d2034da8 \ + --hash=sha256:80b25c7b570a86c03b5da69e665809deb39265476e8e21d96a9328f9762f9990 \ + --hash=sha256:81107843ed1836874b46b310f9b1816abcb89912af627868522461c3b7333c0f \ + --hash=sha256:8494cfc61e03542f2d381e71804990b3931175a29b9278fdb4a5459948778dc2 \ + --hash=sha256:850d6d03177e52700af605fd60db7f37dcb89782049a149674d1a9649c2138fd \ + --hash=sha256:8c6bc1384d9738781cfd41d09ad7f6e8af13cfea2c75ece6bd6d2566cdea2076 \ + --hash=sha256:90904fac73c478f4b83f4ed96c99c8208b75e6f9a8a1910548f69a00f1eaa671 \ + --hash=sha256:90e6d5420fc8a300518d4d2288154ff45005e920425c22cbbfe8330f3f754bd9 \ + --hash=sha256:928bd06eca2c2bbf4349e5b817f837509b0604342e65a502de1d50a7570afd15 \ + --hash=sha256:9b3e3bc363f71bda1639a4ee593cb78f7fbfeacc73411ec0d4c92f00730010a4 \ + --hash=sha256:9edcc35d1cae9fd5320171b1a838c7da8a5c968af31e82ecc3dff30b4be0957f \ + --hash=sha256:9fcb461fbf70654a52a7cc670e606f04449e2374c199b1825f754e16dacfedd8 \ + --hash=sha256:a0951822531e7aee6e0dfb556b30d5ee36bbe234faf60c20a16c01be3530869d \ + --hash=sha256:a361c9434a64d70a7dbb771d1de302c0cc9f13c0bffe1cf7e642152814b35265 \ + --hash=sha256:a4b25c6c25cac5d0d9d6d6da855195b254e0021e513e0249f0e3b444dc6e0e61 \ + --hash=sha256:a5af136bfba820d592f86c67affcef9b3ff4d4360ac3255e341e964489b48519 \ + --hash=sha256:a81eea9b999b985e4bacc650c4312805ea7008fd5e45e1bf221310176a7bcb3a \ + --hash=sha256:a9c63e04d003bc0fb6a03b348018b9a3002f98268200e22cc80f146beac5dc40 \ + --hash=sha256:aa95738a68cedd3a6f5492feddc513e2e166b50602958139e47bbdd82da0f5a7 \ + --hash=sha256:b0a2040f801406b93657a70b72fa12311063a319fee72ce98e1524da7200171f \ + --hash=sha256:b8bd70d5d816566a580d193326912f4a76ec2d28a97dc4cd4cc831c0af8e330e \ + --hash=sha256:b8da9f8035bb417770b1e1610526d87ad4fc58a2804dc4d79c53f6d2cf5a6eb9 \ + --hash=sha256:bc5518873822d2faa8ebdd2c1a4d7c8ef47b01a058495ab7924cb65bdbf5fc9a \ + --hash=sha256:c0d620e74897f8c2613b3c4e2e9c1e422eb46d2ddd07df540784d44117836af3 \ + --hash=sha256:c2640e23d2b7c98796f123ffd95cf2022c7777aa8a4a3b98b36c570d37e85eee \ + --hash=sha256:c81aef782380f0f13ead670aae01825eb653b44b046aa0e5ebbb79f76ed4aa11 \ + --hash=sha256:d4d16b608a1c43d7e33142099a75cd93af482dadce0bf82421e91cad077157f4 \ + --hash=sha256:d69fc39e627908f4c03297d5a88d9284b73f4d90b424461e32e8c2485e21c283 \ + --hash=sha256:d9da80e5b04acce03ced8ba6479a71c2a2edf535c2acc0d09c80d2f80f3bad15 \ + --hash=sha256:dd2c7e082b0b92e1baa4da28163a808672485617bc855cc22a2fd06978fa9084 \ + --hash=sha256:de7dac64e3eb832ffc7b840eb8f52f76420cde1b845be51b2a0f6b870890645e \ + --hash=sha256:e0785c2fb4a81e1aece366aa3e2e039f4a4d7d21aaaded5227d7f3c703427882 \ + --hash=sha256:e306d956cfa027fe041585f02a1602c32bfa6bb8ebea4899d373383295a6c62f \ + --hash=sha256:e78fb7419e07d98c2af4b8567b72b3eaf8cb05caad642e9963465569c8b2d87e \ + --hash=sha256:e9002e98dcb1c0a66723592520decd86238ddcef168b37ff6cfb559200b4b774 \ + --hash=sha256:e94cbc6ad9a6aeea46d775cbb11f361022f778a9cc8cc90af653d3a594b057ce \ + --hash=sha256:eea1b54943475f51698f85fa230c65ccac769f1e603b981be060ac5763d90927 \ + --hash=sha256:f100bfe2acf8a3689af9d0cc660d89f17286c9c795f9f18f7b62dd1a6b247ae6 \ + --hash=sha256:f162af66a2ed3f7d1d161a82ca584efd15acd9c1cff190a373458c32f7d42118 \ + --hash=sha256:f24b90b0e0c8cc9491fb1693ae91fe17cb7963153a1946395acdbdd5818429a4 \ + --hash=sha256:f29b68cd9714531672db62cc54f6e8ff981900f824d13fa0e00749189e13778e \ + --hash=sha256:f38bc489037eca88d6ebefc9c4d41a4e07c8e8b4de5188a9e6d290273ad7ebb1 \ + --hash=sha256:f3fd278f5e6bf7c75ccd6d12344eb686cc020712683363b66f46ac79d37c799f \ + --hash=sha256:f4003f70c56a5addd6aa0897f200dd59afd3bf7bcd5b3cce46dd21f925743bc2 \ + --hash=sha256:f48c963a76d71b9d7927eb817b543d0dccd52ab6648b99d37bd54f4cd475d856 \ + --hash=sha256:f819e0c6413e259a17a7c0d49f97f405abadd3c2a316a3b46c6440b7dbbedbb1 \ + --hash=sha256:fc5758e2b7a56532dc33e3c544d78cbaa9ecf0a0f2a2da2df882c1d6b99a317f \ + --hash=sha256:fcbdf2a9ca24e87bbebb47f1fe34e531ef06f104f98c9ccfc953a3f3344c567a # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ @@ -1569,51 +1580,51 @@ multidict==6.7.1 \ # aiobotocore # aiohttp # yarl -mypy==1.20.0 \ - --hash=sha256:002b613ae19f4ac7d18b7e168ffe1cb9013b37c57f7411984abbd3b817b0a214 \ - --hash=sha256:00e047c74d3ec6e71a2eb88e9ea551a2edb90c21f993aefa9e0d2a898e0bb732 \ - --hash=sha256:02cca0761c75b42a20a2757ae58713276605eb29a08dd8a6e092aa347c4115ca \ - --hash=sha256:0ecd63f75fdd30327e4ad8b5704bd6d91fc6c1b2e029f8ee14705e1207212489 \ - --hash=sha256:0f42dfaab7ec1baff3b383ad7af562ab0de573c5f6edb44b2dab016082b89948 \ - --hash=sha256:1973868d2adbb4584a3835780b27436f06d1dc606af5be09f187aaa25be1070f \ - --hash=sha256:26c8b52627b6552f47ff11adb4e1509605f094e29815323e487fc0053ebe93d1 \ - --hash=sha256:2721f0ce49cb74a38f00c50da67cb7d36317b5eda38877a49614dc018e91c787 \ - --hash=sha256:2fcedb16d456106e545b2bfd7ef9d24e70b38ec252d2a629823a4d07ebcdb69e \ - --hash=sha256:31b5dbb55293c1bd27c0fc813a0d2bb5ceef9d65ac5afa2e58f829dab7921fd5 \ - --hash=sha256:34506397dbf40c15dc567635d18a21d33827e9ab29014fb83d292a8f4f8953b6 \ - --hash=sha256:367e5c993ba34d5054d11937d0485ad6dfc60ba760fa326c01090fc256adf15c \ - --hash=sha256:379edf079ce44ac8d2805bcf9b3dd7340d4f97aad3a5e0ebabbf9d125b84b442 \ - --hash=sha256:39362cdb4ba5f916e7976fccecaab1ba3a83e35f60fa68b64e9a70e221bb2436 \ - --hash=sha256:4525e7010b1b38334516181c5b81e16180b8e149e6684cee5a727c78186b4e3b \ - --hash=sha256:47781555a7aa5fedcc2d16bcd72e0dc83eb272c10dd657f9fb3f9cc08e2e6abb \ - --hash=sha256:49d11c6f573a5a08f77fad13faff2139f6d0730ebed2cfa9b3d2702671dd7188 \ - --hash=sha256:555493c44a4f5a1b58d611a43333e71a9981c6dbe26270377b6f8174126a0526 \ - --hash=sha256:555658c611099455b2da507582ea20d2043dfdfe7f5ad0add472b1c6238b433f \ - --hash=sha256:697f102c5c1d526bdd761a69f17c6070f9892eebcb94b1a5963d679288c09e78 \ - --hash=sha256:76a70bf840495729be47510856b978f1b0ec7d08f257ca38c9d932720bf6b43e \ - --hash=sha256:7d3243c406773185144527f83be0e0aefc7bf4601b0b2b956665608bf7c98a83 \ - --hash=sha256:931a7630bba591593dcf6e97224a21ff80fb357e7982628d25e3c618e7f598ef \ - --hash=sha256:9804c3ad27f78e54e58b32e7cb532d128b43dbfb9f3f9f06262b821a0f6bd3f5 \ - --hash=sha256:a17c5d0bdcca61ce24a35beb828a2d0d323d3fcf387d7512206888c900193367 \ - --hash=sha256:a6e0641147cbfa7e4e94efdb95c2dab1aff8cfc159ded13e07f308ddccc8c48e \ - --hash=sha256:a79c1eba7ac4209f2d850f0edd0a2f8bba88cbfdfefe6fb76a19e9d4fe5e71a2 \ - --hash=sha256:a9336b5e6712f4adaf5afc3203a99a40b379049104349d747eb3e5a3aa23ac2e \ - --hash=sha256:b20c8b0fd5877abdf402e79a3af987053de07e6fb208c18df6659f708b535134 \ - --hash=sha256:b3a49064504be59e59da664c5e149edc1f26c67c4f8e8456f6ba6aba55033018 \ - --hash=sha256:b503ab55a836136b619b5fc21c8803d810c5b87551af8600b72eecafb0059cb0 \ - --hash=sha256:bd0212976dc57a5bfeede7c219e7cd66568a32c05c9129686dd487c059c1b88a \ - --hash=sha256:c70380fe5d64010f79fb863b9081c7004dd65225d2277333c219d93a10dad4dd \ - --hash=sha256:d99f515f95fd03a90875fdb2cca12ff074aa04490db4d190905851bdf8a549a8 \ - --hash=sha256:e80cf77847d0d3e6e3111b7b25db32a7f8762fd4b9a3a72ce53fe16a2863b281 \ - --hash=sha256:eb96c84efcc33f0b5e0e04beacf00129dd963b67226b01c00b9dfc8affb464c3 \ - --hash=sha256:ebea00201737ad4391142808ed16e875add5c17f676e0912b387739f84991e13 \ - --hash=sha256:efe8d70949c3023698c3fca1e94527e7e790a361ab8116f90d11221421cd8726 \ - --hash=sha256:f13b3e41bce9d257eded794c0f12878af3129d80aacd8a3ee0dee51f3a978651 \ - --hash=sha256:f194db59657c58593a3c47c6dfd7bad4ef4ac12dbc94d01b3a95521f78177e33 \ - --hash=sha256:f49590891d2c2f8a9de15614e32e459a794bcba84693c2394291a2038bbaaa69 \ - --hash=sha256:f75ff57defcd0f1d6e006d721ccdec6c88d4f6a7816eb92f1c4890d979d9ee62 \ - --hash=sha256:f799d9db89fc00446f03281f84a221e50018fc40113a3ba9864b132895619ebe \ - --hash=sha256:f8426d4d75d68714abc17a4292d922f6ba2cfb984b72c2278c437f6dae797865 +mypy==1.20.2 \ + --hash=sha256:0c64e5973df366b747646fc98da921f9d6eba9716d57d1db94a83c026a08e0fb \ + --hash=sha256:0deb80d062b2479f2c87ae568f89845afc71d11bc41b04179e58165fd9f31e98 \ + --hash=sha256:1e1c12f6d2db3d78b909b5f77513c11eb7f2dd2782b96a3ab6dffc7d44575c99 \ + --hash=sha256:20175a1c0f49863946ec20b7f63255768058ac4f07d2b9ded6a6b46cfb5a9100 \ + --hash=sha256:29752dbbf8cc53f89f6ac096d363314333045c257c9c75cbd189ca2de0455744 \ + --hash=sha256:2a4102b03bb7481d9a91a6da8d174740c9c8c4401024684b9ca3b7cc5e49852f \ + --hash=sha256:2de3dcea53babc1c3237a19002bc3d228ce1833278f093b8d619e06e7cc79609 \ + --hash=sha256:34397cdced6b90b836e38182076049fdb41424322e0b0728c946b0939ebdf9f6 \ + --hash=sha256:4077797a273e56e8843d001e9dfe4ba10e33323d6ade647ff260e5cd97d9758c \ + --hash=sha256:419413398fe250aae057fd2fe50166b61077083c9b82754c341cf4fd73038f30 \ + --hash=sha256:4b6481b228d072315b053210b01ac320e1be243dc17f9e5887ef167f23f5fae4 \ + --hash=sha256:4dbfcf869f6b0517f70cf0030ba6ea1d6645e132337a7d5204a18d8d5636c02b \ + --hash=sha256:4fef51b01e638974a6e69885687e9bd40c8d1e09a6cd291cca0619625cf1f558 \ + --hash=sha256:52b176444e2e5054dfcbcb8c75b0b719865c96247b37407184bbfca5c353f2c2 \ + --hash=sha256:56908d7e08318d39f85b1f0c6cfd47b0cac1a130da677630dac0de3e0623e102 \ + --hash=sha256:5a65aa591af023864fd08a97da9974e919452cfe19cb146c8a5dc692626445dc \ + --hash=sha256:688c3312e5dadb573a2c69c82af3a298d43ecf9e6d264e0f95df960b5f6ac19c \ + --hash=sha256:6e2b469efd811707bc530fd1effef0f5d6eebcb7fe376affae69025da4b979a2 \ + --hash=sha256:7488448de6007cd5177c6cea0517ac33b4c0f5ee9b5e9f2be51ce75511a85517 \ + --hash=sha256:785b08db19c9f214dc37d65f7c165d19a30fcecb48abfa30f31b01b5acaabb58 \ + --hash=sha256:7b0e817b518bff7facd7f85ea05b643ad8bdcce684cf29784987b0a7c8e1f997 \ + --hash=sha256:803203d2b6ea644982c644895c2f78b28d0e208bba7b27d9b921e0ec5eb207c6 \ + --hash=sha256:89dce27e142d25ffbc154c1819383b69f2e9234dc4ed4766f42e0e8cb264ab5c \ + --hash=sha256:913485a03f1bcf5d279409a9d2b9ed565c151f61c09f29991e5faa14033da4c8 \ + --hash=sha256:97d7b9a485b40f8ca425460e89bf1da2814625b2da627c0dcc6aa46c92631d14 \ + --hash=sha256:9bcb8aa397ff0093c824182fd76a935a9ba7ad097fcbef80ae89bf6c1731d8ec \ + --hash=sha256:9d56a78b646f2e3daa865bc70cd5ec5a46c50045801ca8ff17a0c43abc97e3ee \ + --hash=sha256:a5da6976f20cae27059ea8d0c86e7cef3de720e04c4bb9ee18e3690fdb792066 \ + --hash=sha256:a94c5a76ab46c5e6257c7972b6c8cff0574201ca7dc05647e33e795d78680563 \ + --hash=sha256:a95a9248b0c6fd933a442c03c3b113c3b61320086b88e2c444676d3fd1ca3330 \ + --hash=sha256:baf593f2765fa3a6b1ef95807dbaa3d25b594f6a52adcc506a6b9cb115e1be67 \ + --hash=sha256:bb9c2fa06887e21d6a3a868762acb82aec34e2c6fd0174064f27c93ede68ad15 \ + --hash=sha256:bba9ad231e92a3e424b3e56b65aa17704993425bba97e302c832f9466bb85bac \ + --hash=sha256:c3bae4f855d965b5453784300c12ffc63a548304ac7f99e55d4dc7c898673aa3 \ + --hash=sha256:c566c3a88b6ece59b3d70f65bedef17304f48eb52ff040a6a18214e1917b3254 \ + --hash=sha256:cdecf62abcc4292500d7858aeae87a1f8f1150f4c4dd08fb0b336ee79b2a6df3 \ + --hash=sha256:cf5a4db6dca263010e2c7bff081c89383c72d187ba2cf4c44759aac970e2f0c4 \ + --hash=sha256:d52ad8d78522da1d308789df651ee5379088e77c76cb1994858d40a426b343b9 \ + --hash=sha256:e061b58443f1736f8a37c48978d7ab581636d6ab03e3d4f99e3fa90463bb9382 \ + --hash=sha256:e2877a02380adfcdbc69071a0f74d6e9dbbf593c0dc9d174e1f223ffd5281943 \ + --hash=sha256:e73c07f23009962885c197ccb9b41356a30cc0e5a1d0c2ea8fd8fb1362d7f924 \ + --hash=sha256:e8222c26daaafd9e8626dec58ae36029f82585890589576f769a650dd20fd665 \ + --hash=sha256:edfbfca868cdd6bd8d974a60f8a3682f5565d3f5c99b327640cedd24c4264026 \ + --hash=sha256:f376e37f9bf2a946872fc5fd1199c99310748e3c26c7a26683f13f8bdb756cbd # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ @@ -1703,9 +1714,9 @@ oauthlib==3.3.1 \ --hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \ --hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1 # via requests-oauthlib -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # db-dtypes @@ -1779,9 +1790,9 @@ pandas==2.3.3 \ # pandas-gbq # pymilvus # snowflake-connector-python -pandas-gbq==0.34.1 \ - --hash=sha256:6bea5b85937251b976cf9db38151ea59abbff98771179183488d4614694bff67 \ - --hash=sha256:b74932c6ee35dfc81582f39c792e3a68c9ef9bee8c85f25667d9d05dfadd0daf +pandas-gbq==0.35.0 \ + --hash=sha256:258de481019566611031919997bf9c1ece4ca30a4dd02d3fc3664b251d446182 \ + --hash=sha256:596c908487ef0649a161e86ef272c00c267e581b95dc5ee0dc3518545b33bcfc # via google-cloud-bigquery parsy==2.2 \ --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ @@ -1791,17 +1802,17 @@ 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.9.6 \ + --hash=sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a \ + --hash=sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917 # via snowflake-connector-python -prometheus-client==0.24.1 \ - --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ - --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 +prometheus-client==0.25.0 \ + --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ + --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 # via feast (pyproject.toml) propcache==0.4.1 \ --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ @@ -1997,57 +2008,57 @@ psycopg-pool==3.3.0 \ --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 # 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 @@ -2072,141 +2083,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.3 \ + --hash=sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927 \ + --hash=sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d # 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.3 \ + --hash=sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba \ + --hash=sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35 \ + --hash=sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4 \ + --hash=sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505 \ + --hash=sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7 \ + --hash=sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8 \ + --hash=sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4 \ + --hash=sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37 \ + --hash=sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25 \ + --hash=sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022 \ + --hash=sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1 \ + --hash=sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7 \ + --hash=sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c \ + --hash=sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3 \ + --hash=sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb \ + --hash=sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3 \ + --hash=sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976 \ + --hash=sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c \ + --hash=sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab \ + --hash=sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa \ + --hash=sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6 \ + --hash=sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396 \ + --hash=sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c \ + --hash=sha256:3d08782c4045f90724b44c95d35ebec0d67edb8a957a2ac81d5a8e4b8a200495 \ + --hash=sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c \ + --hash=sha256:4335e87c7afa436a0dfa899e138d57a72f8aad542e2cf19c36fb428461caabd0 \ + --hash=sha256:4b068543bdb707f5d935dab765d99227aa2545ef2820935f2e5dd801795c7dbd \ + --hash=sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf \ + --hash=sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531 \ + --hash=sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5 \ + --hash=sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda \ + --hash=sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d \ + --hash=sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e \ + --hash=sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df \ + --hash=sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6 \ + --hash=sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c \ + --hash=sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13 \ + --hash=sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536 \ + --hash=sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287 \ + --hash=sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0 \ + --hash=sha256:68ef2f623dda6d5a9067ac014e406c020c780b2a358930a7e5c1b73702900720 \ + --hash=sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050 \ + --hash=sha256:6dff8cc884679df229ebc6d8eb2321ea6f8e091bc7d4886d4dc2e0e71452843c \ + --hash=sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1 \ + --hash=sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8 \ + --hash=sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0 \ + --hash=sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374 \ + --hash=sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807 \ + --hash=sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6 \ + --hash=sha256:831eb19aa789a97356979e94c981e5667759301fb708d1c0d5adf1bc0098b873 \ + --hash=sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57 \ + --hash=sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f \ + --hash=sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c \ + --hash=sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad \ + --hash=sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e \ + --hash=sha256:91249bcb7c165c2fb2a2f852dbc5c91636e2e218e75d96dfdd517e4078e173dd \ + --hash=sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23 \ + --hash=sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46 \ + --hash=sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1 \ + --hash=sha256:99421e7684a60f7f3550a1d159ade5fdff1954baedb6bdd407cba6a307c9f27d \ + --hash=sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1 \ + --hash=sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee \ + --hash=sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c \ + --hash=sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874 \ + --hash=sha256:9f247596366f4221af52beddd65af1218797771d6989bc891a0b86ccaa019168 \ + --hash=sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a \ + --hash=sha256:a35cc284c8dd7edae8a31533713b4d2467dfe7c4f1b5587dd4031f28f90d1d13 \ + --hash=sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f \ + --hash=sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a \ + --hash=sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789 \ + --hash=sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe \ + --hash=sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f \ + --hash=sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5 \ + --hash=sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943 \ + --hash=sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b \ + --hash=sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089 \ + --hash=sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b \ + --hash=sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff \ + --hash=sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67 \ + --hash=sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803 \ + --hash=sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045 \ + --hash=sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8 \ + --hash=sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346 \ + --hash=sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2 \ + --hash=sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f \ + --hash=sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687 \ + --hash=sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76 \ + --hash=sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1 \ + --hash=sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f \ + --hash=sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2 \ + --hash=sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c \ + --hash=sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018 \ + --hash=sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba \ + --hash=sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c \ + --hash=sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf \ + --hash=sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7 \ + --hash=sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47 \ + --hash=sha256:d56bdb4af1767cc15b0386b3c581fdfe659bb9ee4a4f776e92c1cd9d074000d6 \ + --hash=sha256:dcda6583921c05a40533f982321532f2d8db29326c7b95c4026941fa5074bd79 \ + --hash=sha256:dd81f6907932ebac3abbe41378dac64b2380db1287e2aa64d8d88f78d170f51a \ + --hash=sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e \ + --hash=sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a \ + --hash=sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34 \ + --hash=sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b \ + --hash=sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85 \ + --hash=sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca \ + --hash=sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f \ + --hash=sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3 \ + --hash=sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64 \ + --hash=sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22 \ + --hash=sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72 \ + --hash=sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec \ + --hash=sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d \ + --hash=sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3 \ + --hash=sha256:fa3eb7c2995aa443687a825bc30395c8521b7c6ec201966e55debfd1128bcceb \ + --hash=sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395 \ + --hash=sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb \ + --hash=sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4 \ + --hash=sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127 \ + --hash=sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56 # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.0 \ + --hash=sha256:24285fd4b0e0c06507dd9fdfd331ee23794305352aaec8fc4eb92d4047aeb67d \ + --hash=sha256:fc8d5d692eb7092e43c8647c1c35a3ecd00e040fcf02ed86f4cb5458ca62182e # via # fastapi-mcp # mcp @@ -2231,13 +2241,13 @@ pymilvus==2.5.18 \ --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d # via feast (pyproject.toml) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 +pymysql==1.1.3 \ + --hash=sha256:8164ba62c552f6105f3b11753352d0f16b90d1703ba67d81923d5a8a5d1c5289 \ + --hash=sha256:e70ebf2047a4edf6138cf79c68ad418ef620af65900aa585c5e8bfc95044d43a # via feast (pyproject.toml) -pyopenssl==26.0.0 \ - --hash=sha256:df94d28498848b98cc1c0ffb8ef1e71e40210d3b0a8064c9d29571ed2904bf81 \ - --hash=sha256:f293934e52936f2e3413b89c6ce36df66a0b34ae1ea3a053b8c5020ff2f513fc +pyopenssl==26.1.0 \ + --hash=sha256:115563879b2c8ccb207975705d3e491434d8c9d7c79667c902ecbf5f3bbd2ece \ + --hash=sha256:737f0a2275c5bc54f3b02137687e1a765931fb3949b9a92a825e4d33b9eec08b # via snowflake-connector-python python-dateutil==2.9.0.post0 \ --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ @@ -2256,9 +2266,9 @@ python-dotenv==1.2.2 \ # pydantic-settings # pymilvus # uvicorn -python-multipart==0.0.22 \ - --hash=sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155 \ - --hash=sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58 +python-multipart==0.0.27 \ + --hash=sha256:6fccfad17a27334bd0193681b369f476eda3409f17381a2d65aa7df3f7275645 \ + --hash=sha256:9870a6a8c5a20a5bf4f07c017bd1489006ff8836cff097b6933355ee2b49b602 # via mcp pytz==2026.1.post1 \ --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ @@ -2345,9 +2355,9 @@ pyyaml==6.0.3 \ # dask # kubernetes # uvicorn -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.0 \ + --hash=sha256:64a6ea7bf567ad43c964d2c30d82853f8df927c5c9017766c55a1d1ed95d18ad \ + --hash=sha256:a9c74a5c893a5ef8455a5adb793a31bb70feb821c86eccb62eebef5a19c429ec # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -2373,9 +2383,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,78 +2562,78 @@ 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.49 \ + --hash=sha256:01146546d84185f12721a1d2ce0c6673451a7894d1460b592d378ca4871a0c72 \ + --hash=sha256:059d7151fff513c53a4638da8778be7fce81a0c4854c7348ebd0c4078ddf28fe \ + --hash=sha256:0c98c59075b890df8abfcc6ad632879540f5791c68baebacb4f833713b510e75 \ + --hash=sha256:0f2fa354ba106eafff2c14b0cc51f22801d1e8b2e4149342023bd6f0955de5f5 \ + --hash=sha256:12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148 \ + --hash=sha256:22d8798819f86720bc646ab015baff5ea4c971d68121cb36e2ebc2ee43ead2b7 \ + --hash=sha256:233088b4b99ebcbc5258c755a097aa52fbf90727a03a5a80781c4b9c54347a2e \ + --hash=sha256:24bd94bb301ec672d8f0623eba9226cc90d775d25a0c92b5f8e4965d7f3a1518 \ + --hash=sha256:275424295f4256fd301744b8f335cff367825d270f155d522b30c7bf49903ee7 \ + --hash=sha256:32fe6a41ad97302db2931f05bb91abbcc65b5ce4c675cd44b972428dd2947700 \ + --hash=sha256:334edbcff10514ad1d66e3a70b339c0a29886394892490119dbb669627b17717 \ + --hash=sha256:3bb9ec6436a820a4c006aad1ac351f12de2f2dbdaad171692ee457a02429b672 \ + --hash=sha256:3ddcb27fb39171de36e207600116ac9dfd4ae46f86c82a9bf3934043e80ebb88 \ + --hash=sha256:42e8804962f9e6f4be2cbaedc0c3718f08f60a16910fa3d86da5a1e3b1bfe60f \ + --hash=sha256:43d044780732d9e0381ac8d5316f95d7f02ef04d6e4ef6dc82379f09795d993f \ + --hash=sha256:46796877b47034b559a593d7e4b549aba151dae73f9e78212a3478161c12ab08 \ + --hash=sha256:46d51518d53edfbe0563662c96954dc8fcace9832332b914375f45a99b77cc9a \ + --hash=sha256:47604cb2159f8bbd5a1ab48a714557156320f20871ee64d550d8bf2683d980d3 \ + --hash=sha256:4bbccb45260e4ff1b7db0be80a9025bb1e6698bdb808b83fff0000f7a90b2c0b \ + --hash=sha256:4d4e5a0ceba319942fa6b585cf82539288a61e314ef006c1209f734551ab9536 \ + --hash=sha256:55250fe61d6ebfd6934a272ee16ef1244e0f16b7af6cd18ab5b1fc9f08631db0 \ + --hash=sha256:566df36fd0e901625523a5a1835032f1ebdd7f7886c54584143fa6c668b4df3b \ + --hash=sha256:57ca426a48eb2c682dae8204cd89ea8ab7031e2675120a47924fabc7caacbc2a \ + --hash=sha256:5e61abbec255be7b122aa461021daa7c3f310f3e743411a67079f9b3cc91ece3 \ + --hash=sha256:618a308215b6cececb6240b9abde545e3acdabac7ae3e1d4e666896bf5ba44b4 \ + --hash=sha256:62557958002b69699bdb7f5137c6714ca1133f045f97b3903964f47db97ea339 \ + --hash=sha256:6270d717b11c5476b0cbb21eedc8d4dbb7d1a956fd6c15a23e96f197a6193158 \ + --hash=sha256:685e93e9c8f399b0c96a624799820176312f5ceef958c0f88215af4013d29066 \ + --hash=sha256:69469ce8ce7a8df4d37620e3163b71238719e1e2e5048d114a1b6ce0fbf8c662 \ + --hash=sha256:6eb188b84269f357669b62cb576b5b918de10fb7c728a005fa0ebb0b758adce1 \ + --hash=sha256:74ab4ee7794d7ed1b0c37e7333640e0f0a626fc7b398c07a7aef52f484fddde3 \ + --hash=sha256:77641d299179c37b89cf2343ca9972c88bb6eef0d5fc504a2f86afd15cd5adf5 \ + --hash=sha256:7c821c47ecfe05cc32140dcf8dc6fd5d21971c86dbd56eabfe5ba07a64910c01 \ + --hash=sha256:7d6be30b2a75362325176c036d7fb8d19e8846c77e87683ffaa8177b35135613 \ + --hash=sha256:7f605a456948c35260e7b2a39f8952a26f077fd25653c37740ed186b90aaa68a \ + --hash=sha256:83101a6930332b87653886c01d1ee7e294b1fe46a07dd9a2d2b4f91bcc88eec0 \ + --hash=sha256:88690f4e1f0fbf5339bedbb127e240fec1fd3070e9934c0b7bef83432f779d2f \ + --hash=sha256:8a97ac839c2c6672c4865e48f3cbad7152cee85f4233fb4ca6291d775b9b954a \ + --hash=sha256:8d6efc136f44a7e8bc8088507eaabbb8c2b55b3dbb63fe102c690da0ddebe55e \ + --hash=sha256:8e20e511dc15265fb433571391ba313e10dd8ea7e509d51686a51313b4ac01a2 \ + --hash=sha256:951d4a210744813be63019f3df343bf233b7432aadf0db54c75802247330d3af \ + --hash=sha256:9ac7a3e245fd0310fd31495eb61af772e637bdf7d88ee81e7f10a3f271bff014 \ + --hash=sha256:9b1c058c171b739e7c330760044803099c7fff11511e3ab3573e5327116a9c33 \ + --hash=sha256:9c04bff9a5335eb95c6ecf1c117576a0aa560def274876fd156cfe5510fccc61 \ + --hash=sha256:9c4969a86e41454f2858256c39bdfb966a20961e9b58bf8749b65abf447e9a8d \ + --hash=sha256:9e0400fa22f79acc334d9a6b185dc00a44a8e6578aa7e12d0ddcd8434152b187 \ + --hash=sha256:a05977bffe9bffd2229f477fa75eabe3192b1b05f408961d1bebff8d1cd4d401 \ + --hash=sha256:a143af2ea6672f2af3f44ed8f9cd020e9cc34c56f0e8db12019d5d9ecf41cb3b \ + --hash=sha256:a51d3db74ba489266ef55c7a4534eb0b8db9a326553df481c11e5d7660c8364d \ + --hash=sha256:b95b2f470c1b2683febd2e7eab1d3f0e078c91dbdd0b00e9c645d07a413bb99f \ + --hash=sha256:b9870d15ef00e4d0559ae10ee5bc71b654d1f20076dbe8bc7ed19b4c0625ceba \ + --hash=sha256:c1dc3368794d522f43914e03312202523cc89692f5389c32bea0233924f8d977 \ + --hash=sha256:c338ec6ec01c0bc8e735c58b9f5d51e75bacb6ff23296658826d7cfdfdb8678a \ + --hash=sha256:c5070135e1b7409c4161133aa525419b0062088ed77c92b1da95366ec5cbebbe \ + --hash=sha256:cc992c6ed024c8c3c592c5fc9846a03dd68a425674900c70122c77ea16c5fb0b \ + --hash=sha256:d15950a57a210e36dd4cec1aac22787e2a4d57ba9318233e2ef8b2daf9ff2d5f \ + --hash=sha256:d898cc2c76c135ef65517f4ddd7a3512fb41f23087b0650efb3418b8389a3cd1 \ + --hash=sha256:d99945830a6f3e9638d89a28ed130b1eb24c91255e4f24366fbe699b983f29e4 \ + --hash=sha256:da9b91bca419dc9b9267ffadde24eae9b1a6bffcd09d0a207e5e3af99a03ce0d \ + --hash=sha256:df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120 \ + --hash=sha256:e06e617e3d4fd9e51d385dfe45b077a41e9d1b033a7702551e3278ac597dc750 \ + --hash=sha256:ec44cfa7ef1a728e88ad41674de50f6db8cfdb3e2af84af86e0041aaf02d43d0 \ + --hash=sha256:fb37f15714ec2652d574f021d479e78cd4eb9d04396dca36568fdfffb3487982 # via feast (pyproject.toml) -sqlglot==30.2.1 \ - --hash=sha256:ef4a67cc6f66a8043085eb8ea95fa9541c1625dffa9145ad4e9815a7ba60a199 \ - --hash=sha256:f23d9ee9427ef9d20df15f9b0ffa57d9eb45e52b012219a349d1e6b50ed926d1 +sqlglot==30.6.0 \ + --hash=sha256:246d34d39927422a50a3fa155f37b2f6346fba85f1a755b13c941eb32ef93361 \ + --hash=sha256:e005fc2f47994f90d7d8df341f1cbe937518497b0b7b1507d4c03c4c9dfd2778 # via ibis-framework -sse-starlette==3.3.4 \ - --hash=sha256:84bb06e58939a8b38d8341f1bc9792f06c2b53f48c608dd207582b664fc8f3c1 \ - --hash=sha256:aaf92fc067af8a5427192895ac028e947b484ac01edbc3caf00e7e7137c7bef1 +sse-starlette==3.4.1 \ + --hash=sha256:6b43cf21f1d574d582a6e1b0cfbde1c94dc86a32a701a7168c99c4475c6bd1d0 \ + --hash=sha256:f780bebcf6c8997fe514e3bd8e8c648d8284976b391c8bed0bcb1f611632b555 # via mcp starlette==1.0.0 \ --hash=sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149 \ @@ -2714,13 +2724,13 @@ typeguard==4.5.1 \ --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 # via feast (pyproject.toml) -typer==0.24.1 \ - --hash=sha256:112c1f0ce578bfb4cab9ffdabc68f031416ebcc216536611ba21f04e9aa84c9e \ - --hash=sha256:e39b4732d65fbdcde189ae76cf7cd48aeae72919dea1fdfc16593be016256b45 +typer==0.25.1 \ + --hash=sha256:75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89 \ + --hash=sha256:9616eb8853a09ffeabab1698952f33c6f29ffdbceb4eaeecf571880e8d7664cc # via fastapi-mcp -types-pymysql==1.1.0.20251220 \ - --hash=sha256:ae1c3df32a777489431e2e9963880a0df48f6591e0aa2fd3a6fabd9dee6eca54 \ - --hash=sha256:fa1082af7dea6c53b6caa5784241924b1296ea3a8d3bd060417352c5e10c0618 +types-pymysql==1.1.0.20260408 \ + --hash=sha256:b784dc37908479e3767e2d794ab507b3674adb1c686ca3d13fc9e2960dbcb9ec \ + --hash=sha256:da630647eaaa7a926a3907794f4067f269cd245b2c202c74aa3c6a3bd660a9db # via feast (pyproject.toml) typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ @@ -2751,9 +2761,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 # ibis-framework # pandas 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 15c53b6ba7e..ae10670be7c 100644 --- a/sdk/python/requirements/py3.12-minimal-sdist-requirements-build.txt +++ b/sdk/python/requirements/py3.12-minimal-sdist-requirements-build.txt @@ -208,9 +208,9 @@ cython==3.2.4 \ # 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 \ @@ -250,9 +250,9 @@ gitdb==4.0.12 \ --hash=sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571 \ --hash=sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf # via gitpython -gitpython==3.1.46 \ - --hash=sha256:400124c7d0ef4ea03f7310ac2fbf7151e09ff97f2a3288d64a440c584a29c37f \ - --hash=sha256:79812ed143d9d25b6d176a10bb511de0f9c67b1fa641d82097b0ab90398a2058 +gitpython==3.1.49 \ + --hash=sha256:024b0422d7f84d15cd794844e029ffebd4c5d42a7eb9b936b458697ef550a02c \ + --hash=sha256:42f9399c9eb33fc581014bedd76049dfbaf6375aa2a5754575966387280315e1 # via pymilvus hatch-fancy-pypi-readme==25.1.0 \ --hash=sha256:9c58ed3dff90d51f43414ce37009ad1d5b0f08ffc9fc216998a06380f01c0045 \ @@ -307,6 +307,7 @@ hatchling==1.29.0 \ # pydantic-settings # pygments # python-multipart + # redis # referencing # scikit-build-core # starlette @@ -319,97 +320,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.9.0 \ + --hash=sha256:07cf11f769831186eeac424376e6189f20ace4f7263e2134bdb9757340d84d4d \ + --hash=sha256:0a09c2f5869649101738653a9b7ab70cf045a1105ac66cbb8f4055e61df78f2d \ + --hash=sha256:0a1be03168b2691ba61927e299b352a6315189199ca18a57b733f86cb3cc8d38 \ + --hash=sha256:0b73e4266307e51c95e09c0750b7ec383c561d2e97d58e473f6f6a209952fbb8 \ + --hash=sha256:15cb151e52a044f06e54ac7f7b47adbfc89b5c8e2b63e1175a9d587c43e8942a \ + --hash=sha256:194fc1a32e1e21fe809d38b5faea66cc65eaa00217c8901fbdb99866938adbdb \ + --hash=sha256:1bf465d1e5b0a27713862441f6467b5ab76385f4ecf8f1f3a44f8aa3c695b4b6 \ + --hash=sha256:1c587494461ebd42229d0f1739f3aa34237dd9980623ecf1be8d3bcba79f4499 \ + --hash=sha256:224b9727eb8bc188bc3bcf29d969dba0cd61b01d9bac80c41575520cc4baabb2 \ + --hash=sha256:22a904cbdb678f7cb348c90d543d3c52f581663d687992fee47fd566dcbf5285 \ + --hash=sha256:2b8f5d00b49818f4e2b1667db994488b045835e0ac16fe2f924f3871bd2b8ac5 \ + --hash=sha256:2c3786f0f4490a5cd87f1ed6cefae833ad6b1060d52044ce0434a2e85893afd0 \ + --hash=sha256:2d03fa4fd277a7974c1978c92c374c57f44edeee163d147b477b143446ad1bf6 \ + --hash=sha256:2f8e12706dcb8ff6b3ed57514a19e45c49ad00bcd423e87b2b2e4b5f64578443 \ + --hash=sha256:3be322a15ee5e70b93b7a59cfd074614f22cc8c9ff18bd27f474e79137ea8d3b \ + --hash=sha256:3cc2917258e131ae5f958a4d872e07555b51cb7466a43433218061c74ef33745 \ + --hash=sha256:3f05d145df35dca5056a8bc3838e940efebd893a54b3e19b2dda39ceaa299bcb \ + --hash=sha256:3fe56e80badb66fdcde06bef81bbaa5bfcf6fbd7aefb86222d9e369c38c6b228 \ + --hash=sha256:42ff8a962554c350d4a83cf47d9b7b78b0e6ff7943e87df7cdfc97c07f3c016f \ + --hash=sha256:451daa98463b7695b0a30aa56bf637831ea559e7b8101ac2ef6382e8eb15e29c \ + --hash=sha256:465814ab157986acb9dfa5ccd7df944be5eefc0d08d31ec6e8d88bc71251d845 \ + --hash=sha256:4c4d0440a3a8e31d962340c3e1cc3fc9ee7febd34c8d8f770d06adb947779ea5 \ + --hash=sha256:4e3dda8345307fd7306db0ed0cb109a63a2c85ba780eb9dc2d09b2049a931f9c \ + --hash=sha256:5093043afb226ecfa1400120d1ebd4442b4f99977783e4f4f7248879009b227f \ + --hash=sha256:5112c2fb7c2eefefaeaf5c97fec81343ef44ee86a30dcfaa8223822fba6467b4 \ + --hash=sha256:527b5b820b47a09e09829051452bb0d1dd2122261254e2a6f674d12f1d793d54 \ + --hash=sha256:54d412e47c21b85865676ed0724e37a89e9593c2eee1e7367adf85bfad56ffb1 \ + --hash=sha256:56d65b583cf43b8cf4c8fbe1e1da20fa3076cc32a1149a141507af1062718236 \ + --hash=sha256:5ca8e133d799c948db2ab1afc081c333a825b5540475164726dcbf73537e5c2f \ + --hash=sha256:603138ee838ee1583f1b960b62d5d0007845c5c423feb68e44648b1359014e27 \ + --hash=sha256:63c12efcd160e1d14da11af0c46c0217473e1e0d2ae1acbccc83f561ea4c2a7b \ + --hash=sha256:657f8ba7b9eaaa82759a104137aed2a3ef7bc46ccfd43e0d89b04005b3e0a4cc \ + --hash=sha256:66b58fed90a545328e80d575467244de3741e088c1af928f0b489ebec3ef3858 \ + --hash=sha256:6788207daa0c19955d2b668f3294a368d19f67d9b5f274553fd073c1260cbb9f \ + --hash=sha256:703f4ae36d6240bfe24f542bac784c7e4194ec49c3ba5a994d02891649e2d85b \ + --hash=sha256:7202bdcac47d3a708271c4304a474a8605a4a9a4a709e954bf2d3241140aa938 \ + --hash=sha256:756775d25ec8345b837ab52effee3ad2f3b2dfd6bbee3e3f029c517bd5d8f05a \ + --hash=sha256:78042f6facfd98ecb25e9829c7e37cce23363d9d7c83bc5f72702c5059eb082b \ + --hash=sha256:789fff71757facc0738e8d89e3b84e4f0251c1c975e85e81b152cdaca927cc2d \ + --hash=sha256:7bc30ad339f4e1a01d4917d645e522a0bc0030644d8973f6346397c93ba1503f \ + --hash=sha256:7d429bdd4ac0ab17c8e4a8af0ed2a7440b16eba474909ab357131018fe8c7e71 \ + --hash=sha256:7d5c8a5929ac325729f6119802070b561f4db793dffc45e9ac750992a4ed4d22 \ + --hash=sha256:7e6274fd33fc5b2a14d41c9119629d3ff395849d8bcbc80cf637d9e8d2034da8 \ + --hash=sha256:80b25c7b570a86c03b5da69e665809deb39265476e8e21d96a9328f9762f9990 \ + --hash=sha256:81107843ed1836874b46b310f9b1816abcb89912af627868522461c3b7333c0f \ + --hash=sha256:8494cfc61e03542f2d381e71804990b3931175a29b9278fdb4a5459948778dc2 \ + --hash=sha256:850d6d03177e52700af605fd60db7f37dcb89782049a149674d1a9649c2138fd \ + --hash=sha256:8c6bc1384d9738781cfd41d09ad7f6e8af13cfea2c75ece6bd6d2566cdea2076 \ + --hash=sha256:90904fac73c478f4b83f4ed96c99c8208b75e6f9a8a1910548f69a00f1eaa671 \ + --hash=sha256:90e6d5420fc8a300518d4d2288154ff45005e920425c22cbbfe8330f3f754bd9 \ + --hash=sha256:928bd06eca2c2bbf4349e5b817f837509b0604342e65a502de1d50a7570afd15 \ + --hash=sha256:9b3e3bc363f71bda1639a4ee593cb78f7fbfeacc73411ec0d4c92f00730010a4 \ + --hash=sha256:9edcc35d1cae9fd5320171b1a838c7da8a5c968af31e82ecc3dff30b4be0957f \ + --hash=sha256:9fcb461fbf70654a52a7cc670e606f04449e2374c199b1825f754e16dacfedd8 \ + --hash=sha256:a0951822531e7aee6e0dfb556b30d5ee36bbe234faf60c20a16c01be3530869d \ + --hash=sha256:a361c9434a64d70a7dbb771d1de302c0cc9f13c0bffe1cf7e642152814b35265 \ + --hash=sha256:a4b25c6c25cac5d0d9d6d6da855195b254e0021e513e0249f0e3b444dc6e0e61 \ + --hash=sha256:a5af136bfba820d592f86c67affcef9b3ff4d4360ac3255e341e964489b48519 \ + --hash=sha256:a81eea9b999b985e4bacc650c4312805ea7008fd5e45e1bf221310176a7bcb3a \ + --hash=sha256:a9c63e04d003bc0fb6a03b348018b9a3002f98268200e22cc80f146beac5dc40 \ + --hash=sha256:aa95738a68cedd3a6f5492feddc513e2e166b50602958139e47bbdd82da0f5a7 \ + --hash=sha256:b0a2040f801406b93657a70b72fa12311063a319fee72ce98e1524da7200171f \ + --hash=sha256:b8bd70d5d816566a580d193326912f4a76ec2d28a97dc4cd4cc831c0af8e330e \ + --hash=sha256:b8da9f8035bb417770b1e1610526d87ad4fc58a2804dc4d79c53f6d2cf5a6eb9 \ + --hash=sha256:bc5518873822d2faa8ebdd2c1a4d7c8ef47b01a058495ab7924cb65bdbf5fc9a \ + --hash=sha256:c0d620e74897f8c2613b3c4e2e9c1e422eb46d2ddd07df540784d44117836af3 \ + --hash=sha256:c2640e23d2b7c98796f123ffd95cf2022c7777aa8a4a3b98b36c570d37e85eee \ + --hash=sha256:c81aef782380f0f13ead670aae01825eb653b44b046aa0e5ebbb79f76ed4aa11 \ + --hash=sha256:d4d16b608a1c43d7e33142099a75cd93af482dadce0bf82421e91cad077157f4 \ + --hash=sha256:d69fc39e627908f4c03297d5a88d9284b73f4d90b424461e32e8c2485e21c283 \ + --hash=sha256:d9da80e5b04acce03ced8ba6479a71c2a2edf535c2acc0d09c80d2f80f3bad15 \ + --hash=sha256:dd2c7e082b0b92e1baa4da28163a808672485617bc855cc22a2fd06978fa9084 \ + --hash=sha256:de7dac64e3eb832ffc7b840eb8f52f76420cde1b845be51b2a0f6b870890645e \ + --hash=sha256:e0785c2fb4a81e1aece366aa3e2e039f4a4d7d21aaaded5227d7f3c703427882 \ + --hash=sha256:e306d956cfa027fe041585f02a1602c32bfa6bb8ebea4899d373383295a6c62f \ + --hash=sha256:e78fb7419e07d98c2af4b8567b72b3eaf8cb05caad642e9963465569c8b2d87e \ + --hash=sha256:e9002e98dcb1c0a66723592520decd86238ddcef168b37ff6cfb559200b4b774 \ + --hash=sha256:e94cbc6ad9a6aeea46d775cbb11f361022f778a9cc8cc90af653d3a594b057ce \ + --hash=sha256:eea1b54943475f51698f85fa230c65ccac769f1e603b981be060ac5763d90927 \ + --hash=sha256:f100bfe2acf8a3689af9d0cc660d89f17286c9c795f9f18f7b62dd1a6b247ae6 \ + --hash=sha256:f162af66a2ed3f7d1d161a82ca584efd15acd9c1cff190a373458c32f7d42118 \ + --hash=sha256:f24b90b0e0c8cc9491fb1693ae91fe17cb7963153a1946395acdbdd5818429a4 \ + --hash=sha256:f29b68cd9714531672db62cc54f6e8ff981900f824d13fa0e00749189e13778e \ + --hash=sha256:f38bc489037eca88d6ebefc9c4d41a4e07c8e8b4de5188a9e6d290273ad7ebb1 \ + --hash=sha256:f3fd278f5e6bf7c75ccd6d12344eb686cc020712683363b66f46ac79d37c799f \ + --hash=sha256:f4003f70c56a5addd6aa0897f200dd59afd3bf7bcd5b3cce46dd21f925743bc2 \ + --hash=sha256:f48c963a76d71b9d7927eb817b543d0dccd52ab6648b99d37bd54f4cd475d856 \ + --hash=sha256:f819e0c6413e259a17a7c0d49f97f405abadd3c2a316a3b46c6440b7dbbedbb1 \ + --hash=sha256:fc5758e2b7a56532dc33e3c544d78cbaa9ecf0a0f2a2da2df882c1d6b99a317f \ + --hash=sha256:fcbdf2a9ca24e87bbebb47f1fe34e531ef06f104f98c9ccfc953a3f3344c567a # via mypy markupsafe==3.0.3 \ --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ @@ -502,21 +570,21 @@ 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.1 \ + --hash=sha256:001741c6cff56aa8ea59a0d78ae990c0550d0e3e82b00b683eedb4158a8ef7e6 \ + --hash=sha256:01c845825c917c07c1d0b2c9032c59c16a7d383d1e649a46481d3e5693c2750f \ + --hash=sha256:2839024dcd65776abb4759e5bca29941971e095574162a4d335191da4be9ff24 \ + --hash=sha256:3da18cccf2f683c0977bff9146a0908d6ffce836d600665736ac01679f588cb9 \ + --hash=sha256:416e4e01cb88b798e606ee43929df897e42c1647b722ef68283816cca99a8742 \ + --hash=sha256:6b1e5916a253243e8f5f9e847b62bbc98420eec48c9ce2e2e8724c6da89d359b \ + --hash=sha256:72888e87819ce546d0d2df900e4b385e4ef299077d92ee37b48923a5602dae94 \ + --hash=sha256:98b5fcf1a186c217830a8295ecc2989c6b1cf50945417adfc15252107b9475b7 \ + --hash=sha256:9a87ff3b8e4d1c6eac33ebfe8e261e8236516d98d45c0323550621819b5a1a2f \ + --hash=sha256:a2017d2281203d0c6570240e7d746564d766d756105823b7de68bda6ae722711 \ + --hash=sha256:c1490584f3c70af45466ee99065b49e6657ebdccac6b10571bb44681309c9396 \ + --hash=sha256:c6a720b252c99de072922dbe4432ab19662b6f80045b0355fec23bdfccb450da \ + --hash=sha256:dc91031e0619c1e28730279ef9ee5f106c9b9ec806b013f888676b242f892eb7 \ + --hash=sha256:f69093ed4a0e6464e52a7fc26d714f859ce15630ec8070743398c6bf41f38a9e # via # cryptography # pydantic-core @@ -616,9 +684,9 @@ numpy==2.4.4 \ # 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 @@ -628,9 +696,9 @@ packaging==26.0 \ # 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 @@ -659,13 +727,13 @@ poetry-core==2.3.2 \ # pkgconfig # rich # tomlkit -pybind11-global==3.0.3 \ - --hash=sha256:141adb150fdb84f6eba3e27241da886f4582574a3d1c30568bf33c1ed3ec8b82 \ - --hash=sha256:7a75ee81e903ea15bdf05db1342c37400751a72316b6620c800b66d70be45632 +pybind11-global==3.0.4 \ + --hash=sha256:95b693c3d646c6b7217a97156a36b6d40305505d4a5a728082da6fe75ada29f5 \ + --hash=sha256:a73e2ebd29f4ee5d7c754b495d555cd703f2cd26c84abe360ee56411dcd7834d # via pybind11 -pybind11==3.0.3 \ - --hash=sha256:00471cdb816882c484708bc5dde80815c8c11cea540ab2cc6410f5ddea434755 \ - --hash=sha256:fb5f8e4a64946b4dcc0451c83a8c384f803bc0a62dd1ba02f199e97dbc9aad4c +pybind11==3.0.4 \ + --hash=sha256:3286b59c8a774b9ee650169302dd5a4eedc30a8617905a0560dd8ee44775130c \ + --hash=sha256:961720ee652da51d531b7b2451a6bd2bc042b0106e6d9baa48ecb7d58034ce63 # via duckdb pycparser==3.0 \ --hash=sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29 \ @@ -675,12 +743,88 @@ 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 \ @@ -694,7 +838,9 @@ setuptools-git-versioning==3.0.1 \ setuptools-rust==1.12.1 \ --hash=sha256:85ae70989d96c9cfeb5ef79cf3bac2d5200bc5564f720a06edceedbdf6664640 \ --hash=sha256:b7ebd6a182e7aefa97a072e880530c9b0ec8fcca8617e0bb8ff299c1a064f693 - # via maturin + # via + # libcst + # maturin setuptools-scm==10.0.5 \ --hash=sha256:bbba8fe754516cdefd017f4456721775e6ef9662bd7887fb52ae26813d4838c3 \ --hash=sha256:f611037d8aae618221503b8fa89319f073438252ae3420e01c9ceec249131a0a @@ -704,6 +850,7 @@ setuptools-scm==10.0.5 \ # duckdb # hatch-vcs # httpx-sse + # libcst # pluggy # pyarrow # pybindgen @@ -782,17 +929,17 @@ tomlkit==0.14.0 \ --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 # via uv-dynamic-versioning -trove-classifiers==2026.1.14.14 \ - --hash=sha256:00492545a1402b09d4858605ba190ea33243d361e2b01c9c296ce06b5c3325f3 \ - --hash=sha256:1f9553927f18d0513d8e5ff80ab8980b8202ce37ecae0e3274ed2ef11880e74d +trove-classifiers==2026.4.28.13 \ + --hash=sha256:8f4b1eb4e16296b57d612965444f87a83861cc989a0451ac97fe4265ddef03b8 \ + --hash=sha256:c85bb8a53c3de7330d1699b844ed9fb809a602a09ac15dc79ad6d1a509be0676 # via hatchling types-psutil==7.0.0.20250218 \ --hash=sha256:1447a30c282aafefcf8941ece854e1100eee7b0296a9d9be9977292f0269b121 \ --hash=sha256:1e642cdafe837b240295b23b1cbd4691d80b08a07d29932143cbbae30eb0db9c # via mypy -types-setuptools==82.0.0.20260402 \ - --hash=sha256:4b9a9f6c3c4c65107a3956ad6a6acbccec38e398ff6d5f78d5df7f103dadb8d6 \ - --hash=sha256:63d2b10ba7958396ad79bbc24d2f6311484e452daad4637ffd40407983a27069 +types-setuptools==82.0.0.20260408 \ + --hash=sha256:036c68caf7e672a699f5ebbf914708d40644c14e05298bc49f7272be91cf43d3 \ + --hash=sha256:ece0a215cdfa6463a65fd6f68bd940f39e455729300ddfe61cab1147ed1d2462 # via mypy typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ @@ -814,12 +961,13 @@ versioneer==0.29 \ # 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 # httpx-sse + # libcst # meson # mmh3 # pandas @@ -861,6 +1009,7 @@ setuptools==80.10.2 \ # grpc-google-iam-v1 # gunicorn # httpx-sse + # libcst # librt # markupsafe # maturin @@ -879,7 +1028,6 @@ setuptools==80.10.2 \ # psycopg # psycopg-c # psycopg-pool - # pyarrow # pyasn1 # pyasn1-modules # pycparser @@ -903,7 +1051,6 @@ setuptools==80.10.2 \ # tqdm # trove-classifiers # typeguard - # types-pymysql # tzdata # ujson # uvloop @@ -921,4 +1068,5 @@ setuptools==82.0.1 \ --hash=sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb # via # python-dateutil + # types-pymysql # types-setuptools diff --git a/sdk/python/requirements/py3.12-minimal-sdist-requirements.txt b/sdk/python/requirements/py3.12-minimal-sdist-requirements.txt index e24f4ca749b..c5231d0fd24 100644 --- a/sdk/python/requirements/py3.12-minimal-sdist-requirements.txt +++ b/sdk/python/requirements/py3.12-minimal-sdist-requirements.txt @@ -202,9 +202,9 @@ 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.4.22 \ + --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ + --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 # via # httpcore # httpx @@ -432,9 +432,9 @@ charset-normalizer==3.4.7 \ # via # requests # snowflake-connector-python -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.3.3 \ + --hash=sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2 \ + --hash=sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 # via # feast (pyproject.toml) # dask @@ -448,56 +448,56 @@ colorama==0.4.6 \ --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 # via feast (pyproject.toml) -cryptography==46.0.6 \ - --hash=sha256:02fad249cb0e090b574e30b276a3da6a149e04ee2f049725b1f69e7b8351ec70 \ - --hash=sha256:063b67749f338ca9c5a0b7fe438a52c25f9526b851e24e6c9310e7195aad3b4d \ - --hash=sha256:12cae594e9473bca1a7aceb90536060643128bb274fcea0fc459ab90f7d1ae7a \ - --hash=sha256:12f0fa16cc247b13c43d56d7b35287ff1569b5b1f4c5e87e92cc4fcc00cd10c0 \ - --hash=sha256:22259338084d6ae497a19bae5d4c66b7ca1387d3264d1c2c0e72d9e9b6a77b97 \ - --hash=sha256:26031f1e5ca62fcb9d1fcb34b2b60b390d1aacaa15dc8b895a9ed00968b97b30 \ - --hash=sha256:27550628a518c5c6c903d84f637fbecf287f6cb9ced3804838a1295dc1fd0759 \ - --hash=sha256:2b417edbe8877cda9022dde3a008e2deb50be9c407eef034aeeb3a8b11d9db3c \ - --hash=sha256:2ea0f37e9a9cf0df2952893ad145fd9627d326a59daec9b0802480fa3bcd2ead \ - --hash=sha256:2ef9e69886cbb137c2aef9772c2e7138dc581fad4fcbcf13cc181eb5a3ab6275 \ - --hash=sha256:341359d6c9e68834e204ceaf25936dffeafea3829ab80e9503860dcc4f4dac58 \ - --hash=sha256:380343e0653b1c9d7e1f55b52aaa2dbb2fdf2730088d48c43ca1c7c0abb7cc2f \ - --hash=sha256:3c21d92ed15e9cfc6eb64c1f5a0326db22ca9c2566ca46d845119b45b4400361 \ - --hash=sha256:3dfa6567f2e9e4c5dceb8ccb5a708158a2a871052fa75c8b78cb0977063f1507 \ - --hash=sha256:456b3215172aeefb9284550b162801d62f5f264a081049a3e94307fe20792cfa \ - --hash=sha256:4668298aef7cddeaf5c6ecc244c2302a2b8e40f384255505c22875eebb47888b \ - --hash=sha256:50575a76e2951fe7dbd1f56d181f8c5ceeeb075e9ff88e7ad997d2f42af06e7b \ - --hash=sha256:639301950939d844a9e1c4464d7e07f902fe9a7f6b215bb0d4f28584729935d8 \ - --hash=sha256:64235194bad039a10bb6d2d930ab3323baaec67e2ce36215fd0952fad0930ca8 \ - --hash=sha256:6617f67b1606dfd9fe4dbfa354a9508d4a6d37afe30306fe6c101b7ce3274b72 \ - --hash=sha256:67177e8a9f421aa2d3a170c3e56eca4e0128883cf52a071a7cbf53297f18b175 \ - --hash=sha256:6728c49e3b2c180ef26f8e9f0a883a2c585638db64cf265b49c9ba10652d430e \ - --hash=sha256:6739d56300662c468fddb0e5e291f9b4d084bead381667b9e654c7dd81705124 \ - --hash=sha256:69cf0056d6947edc6e6760e5f17afe4bea06b56a9ac8a06de9d2bd6b532d4f3a \ - --hash=sha256:760997a4b950ff00d418398ad73fbc91aa2894b5c1db7ccb45b4f68b42a63b3c \ - --hash=sha256:79e865c642cfc5c0b3eb12af83c35c5aeff4fa5c672dc28c43721c2c9fdd2f0f \ - --hash=sha256:7e6142674f2a9291463e5e150090b95a8519b2fb6e6aaec8917dd8d094ce750d \ - --hash=sha256:7f417f034f91dcec1cb6c5c35b07cdbb2ef262557f701b4ecd803ee8cefed4f4 \ - --hash=sha256:7f6690b6c55e9c5332c0b59b9c8a3fb232ebf059094c17f9019a51e9827df91c \ - --hash=sha256:8927ccfbe967c7df312ade694f987e7e9e22b2425976ddbf28271d7e58845290 \ - --hash=sha256:8ce35b77aaf02f3b59c90b2c8a05c73bac12cea5b4e8f3fbece1f5fddea5f0ca \ - --hash=sha256:8e7304c4f4e9490e11efe56af6713983460ee0780f16c63f219984dab3af9d2d \ - --hash=sha256:90e5f0a7b3be5f40c3a0a0eafb32c681d8d2c181fc2a1bdabe9b3f611d9f6b1a \ - --hash=sha256:97c8115b27e19e592a05c45d0dd89c57f81f841cc9880e353e0d3bf25b2139ed \ - --hash=sha256:9a693028b9cbe51b5a1136232ee8f2bc242e4e19d456ded3fa7c86e43c713b4a \ - --hash=sha256:9a9c42a2723999a710445bc0d974e345c32adfd8d2fac6d8a251fa829ad31cfb \ - --hash=sha256:a3e84d5ec9ba01f8fd03802b2147ba77f0c8f2617b2aff254cedd551844209c8 \ - --hash=sha256:aad75154a7ac9039936d50cf431719a2f8d4ed3d3c277ac03f3339ded1a5e707 \ - --hash=sha256:b12c6b1e1651e42ab5de8b1e00dc3b6354fdfd778e7fa60541ddacc27cd21410 \ - --hash=sha256:b928a3ca837c77a10e81a814a693f2295200adb3352395fad024559b7be7a736 \ - --hash=sha256:bcb87663e1f7b075e48c3be3ecb5f0b46c8fc50b50a97cf264e7f60242dca3f2 \ - --hash=sha256:c797e2517cb7880f8297e2c0f43bb910e91381339336f75d2c1c2cbf811b70b4 \ - --hash=sha256:c89eb37fae9216985d8734c1afd172ba4927f5a05cfd9bf0e4863c6d5465b013 \ - --hash=sha256:cdcd3edcbc5d55757e5f5f3d330dd00007ae463a7e7aa5bf132d1f22a4b62b19 \ - --hash=sha256:d24c13369e856b94892a89ddf70b332e0b70ad4a5c43cf3e9cb71d6d7ffa1f7b \ - --hash=sha256:d4e4aadb7fc1f88687f47ca20bb7227981b03afaae69287029da08096853b738 \ - --hash=sha256:d9528b535a6c4f8ff37847144b8986a9a143585f0540fbcb1a98115b543aa463 \ - --hash=sha256:ed3775295fb91f70b4027aeba878d79b3e55c0b3e97eaa4de71f8f23a9f2eb77 \ - --hash=sha256:ed418c37d095aeddf5336898a132fba01091f0ac5844e3e8018506f014b6d2c4 +cryptography==47.0.0 \ + --hash=sha256:0024b87d47ae2399165a6bfb20d24888881eeab83ae2566d62467c5ff0030ce7 \ + --hash=sha256:07efe86201817e7d3c18781ca9770bc0db04e1e48c994be384e4602bc38f8f27 \ + --hash=sha256:09f6d7bf6724f8db8b32f11eccf23efc8e759924bc5603800335cf8859a3ddbd \ + --hash=sha256:11438c7518132d95f354fa01a4aa2f806d172a061a7bed18cf18cbdacdb204d7 \ + --hash=sha256:11dbb9f50a0f1bb9757b3d8c27c1101780efb8f0bdecfb12439c22a74d64c001 \ + --hash=sha256:14432c8a9bcb37009784f9594a62fae211a2ae9543e96c92b2a8e4c3cd5cd0c4 \ + --hash=sha256:1581aef4219f7ca2849d0250edaa3866212fb74bf5667284f46aa92f9e65c1ca \ + --hash=sha256:160ad728f128972d362e714054f6ba0067cab7fb350c5202a9ae8ae4ce3ef1a0 \ + --hash=sha256:1a405c08857258c11016777e11c02bacbe7ef596faf259305d282272a3a05cbe \ + --hash=sha256:1e47422b5557bb82d3fff997e8d92cff4e28b9789576984f08c248d2b3535d93 \ + --hash=sha256:20fdbe3e38fb67c385d233c89371fa27f9909f6ebca1cecc20c13518dae65475 \ + --hash=sha256:2207a498b03275d0051589e326b79d4cf59985c99031b05bb292ac52631c37fe \ + --hash=sha256:256d07c78a04d6b276f5df935a9923275f53bd1522f214447fdf365494e2d515 \ + --hash=sha256:2b45761c6ec22b7c726d6a829558777e32d0f1c8be7c3f3480f9c912d5ee8a10 \ + --hash=sha256:2ebd84adf0728c039a3be2700289378e1c164afc6748df1a5ed456767bef9ba7 \ + --hash=sha256:34b4358b925a5ea3e14384ca781a2c0ef7ac219b57bb9eacc4457078e2b19f92 \ + --hash=sha256:3fb8fa48075fad7193f2e5496135c6a76ac4b2aa5a38433df0a539296b377829 \ + --hash=sha256:4e1de79e047e25d6e9f8cea71c86b4a53aced64134f0f003bbcbf3655fd172c8 \ + --hash=sha256:4f7722c97826770bab8ae92959a2e7b20a5e9e9bf4deae68fd86c3ca457bab52 \ + --hash=sha256:51c9313e90bd1690ec5a75ed047c27c0b8e6c570029712943d6116ef9a90620b \ + --hash=sha256:5d0e362ff51041b0c0d219cc7d6924d7b8996f57ce5712bdcef71eb3c65a59cc \ + --hash=sha256:6651d32eff255423503aa276739da98c30f26c40cbeffcc6048e0d54ef704c0c \ + --hash=sha256:6eebcaf0df1d21ce1f90605c9b432dd2c4f4ab665ac29a40d5e3fc68f51b5e63 \ + --hash=sha256:6f29f36582e6151d9686235e586dd35bb67491f024767d10b842e520dc6a07ac \ + --hash=sha256:7a02675e2fabd0c0fc04c868b8781863cbf1967691543c22f5470500ff840b31 \ + --hash=sha256:7f1207974a904e005f762869996cf620e9bf79ecb4622f148550bb48e0eb35a7 \ + --hash=sha256:7f68d6fbc7fbbcfb0939fea72c3b96a9f9a6edfc0e1b1d29778a2066030418b1 \ + --hash=sha256:7fda2f02c9015db3f42bb8a22324a454516ed10a8c29ca6ece6cdbb5efe2a203 \ + --hash=sha256:80887c5cbd1774683cb126f0ab4184567f080071d5acf62205acb354b4b753b7 \ + --hash=sha256:835d2d7f47cdc53b3224e90810fb1d36ca94ea29cc1801fb4c1bc43876735769 \ + --hash=sha256:8c1a736bbb3288005796c3f7ccb9453360d7fed483b13b9f468aea5171432923 \ + --hash=sha256:9af828c0d5a65c70ec729cd7495a4bf1a67ecb66417b8f02ff125ab8a6326a74 \ + --hash=sha256:9c59ab0e0fa3a180a5a9c59f3a5abe3ef90d474bc56d7fadfbe80359491b615b \ + --hash=sha256:9f8e55fe4e63613a5e1cc5819030f27b97742d720203a087802ce4ce9ceb52bb \ + --hash=sha256:9fe6b7c64926c765f9dff301f9c1b867febcda5768868ca084e18589113732ab \ + --hash=sha256:a49a3eb5341b9503fa3000a9a0db033161db90d47285291f53c2a9d2cd1b7f76 \ + --hash=sha256:a9b761f012a943b7de0e828843c5688d0de94a0578d44d6c85a1bae32f87791f \ + --hash=sha256:b1c76fca783aa7698eb21eb14f9c4aa09452248ee54a627d125025a43f83e7a7 \ + --hash=sha256:b9a8943e359b7615db1a3ba587994618e094ff3d6fa5a390c73d079ce18b3973 \ + --hash=sha256:be12cb6a204f77ed968bcefe68086eb061695b540a3dd05edac507a3111b25f0 \ + --hash=sha256:cffbba3392df0fa8629bb7f43454ee2925059ee158e23c54620b9063912b86c8 \ + --hash=sha256:ed67ea4e0cfb5faa5bc7ecb6e2b8838f3807a03758eec239d6c21c8769355310 \ + --hash=sha256:edd4da498015da5b9f26d38d3bfc2e90257bfa9cbed1f6767c282a0025ae649b \ + --hash=sha256:ef6b3634087f18d2155b1e8ce264e5345a753da2c5fa9815e7d41315c90f8318 \ + --hash=sha256:f1557695e5c2b86e204f6ce9470497848634100787935ab7adc5397c54abd7ab \ + --hash=sha256:f5c15764f261394b22aef6b00252f5195f46f2ca300bec57149474e2538b31f8 \ + --hash=sha256:f5c3296dab66202f1b18a91fa266be93d6aa0c2806ea3d67762c69f60adc71aa \ + --hash=sha256:f7db373287273d8af1414cf95dc4118b13ffdc62be521997b0f2b270771fef50 \ + --hash=sha256:f9a034b642b960767fb343766ae5ba6ad653f2e890ddd82955aef288ffea8736 # via # google-auth # pyjwt @@ -587,50 +587,50 @@ docutils==0.22.4 \ --hash=sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968 \ --hash=sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # via sphinx -duckdb==1.5.1 \ - --hash=sha256:054ad424b051b334052afac58cb216f3b1ebb8579fc8c641e60f0182e8725ea9 \ - --hash=sha256:05fc91767d0cfc4cf2fa68966ab5b479ac07561752e42dd0ae30327bd160f64a \ - --hash=sha256:0a6acc2040bec1f05de62a2f3f68f4c12f3ec7d6012b4317d0ab1a195af26225 \ - --hash=sha256:26e56b5f0c96189e3288d83cf7b476e23615987902f801e5788dee15ee9f24a9 \ - --hash=sha256:36e8e32621a9e2a9abe75dc15a4b54a3997f2d8b1e53ad754bae48a083c91130 \ - --hash=sha256:40c5220ec93790b18ec6278da9c6ac2608d997ee6d6f7cd44c5c3992764e8e71 \ - --hash=sha256:446d500a2977c6ae2077f340c510a25956da5c77597175c316edfa87248ceda3 \ - --hash=sha256:46f92ada9023e59f27edc048167b31ac9a03911978b1296c845a34462a27f096 \ - --hash=sha256:482f8a13f2600f527e427f73c42b5aa75536f9892868068f0aaf573055a0135f \ - --hash=sha256:553c273a6a8f140adaa6da6a6135c7f95bdc8c2e5f95252fcdf9832d758e2141 \ - --hash=sha256:5ae7c0d744d64e2753149634787cc4ab60f05ef1e542b060eeab719f3cdb7723 \ - --hash=sha256:5d4147422d91ccdc2d2abf6ed24196025e020259d1d267970ae20c13c2ce84b1 \ - --hash=sha256:6af347debc8b721aa72e48671166282da979d5e5ae52dbc660ab417282b48e23 \ - --hash=sha256:6ba302115f63f6482c000ccfd62efdb6c41d9d182a5bcd4a90e7ab8cd13856eb \ - --hash=sha256:6f7361d66cc801d9eb4df734b139cd7b0e3c257a16f3573ebd550ddb255549e6 \ - --hash=sha256:715f05ea198d20d7f8b407b9b84e0023d17f2b9096c194cea702b7840e74f1f7 \ - --hash=sha256:71dddcebbc5a70e946a06c30b59b5dd7999c9833d307168f90fb4e4b672ab63e \ - --hash=sha256:8150c569b2aa4573b51ba8475e814aa41fd53a3d510c1ffb96f1139f46faf611 \ - --hash=sha256:8843bd9594e1387f1e601439e19ad73abdf57356104fd1e53a708255bb95a13d \ - --hash=sha256:8c0088765747ae5d6c9f89987bb36f9fb83564f07090d721344ce8e1abedffea \ - --hash=sha256:972d0dbf283508f9bc446ee09c3838cb7c7f114b5bdceee41753288c97fe2f7c \ - --hash=sha256:a28531cee2a5a42d89f9ba4da53bfeb15681f12acc0263476c8705380dadce07 \ - --hash=sha256:a3be2072315982e232bfe49c9d3db0a59ba67b2240a537ef42656cc772a887c7 \ - --hash=sha256:ac2804043bd1bc10b5da18f8f4c706877197263a510c41be9b4c0062f5783dcc \ - --hash=sha256:afab8b4b1f4469c3879bb049dd039f8fce402712050324e9524a43d7324c5e87 \ - --hash=sha256:b370d1620a34a4538ef66524fcee9de8171fa263c701036a92bc0b4c1f2f9c6d \ - --hash=sha256:b8b0808dba0c63b7633bdaefb34e08fe0612622224f9feb0e7518904b1615101 \ - --hash=sha256:bc7ca6a1a40e7e4c933017e6c09ef18032add793df4e42624c6c0c87e0bebdad \ - --hash=sha256:caa65e1f5bf007430bf657c37cab7ab81a4ddf8d337e3062bcc5085d17ef038b \ - --hash=sha256:d68c5a01a283cb13b79eafe016fe5869aa11bff8c46e7141c70aa0aac808010f \ - --hash=sha256:da137802688190835b4c863cafa77fd7e29dff662ee6d905a9ffc14f00299c91 \ - --hash=sha256:e56a20ab6cdb90a95b0c99652e28de3504ce77129087319c03c9098266183ae5 \ - --hash=sha256:e878ccb7d20872065e1597935fdb5e65efa43220c8edd0d9c4a1a7ff1f3eb277 \ - --hash=sha256:eba81e0b3011c1f23df7ea47ef4ffaa8239817959ae291515b6efd068bde2161 \ - --hash=sha256:ed6d23a3f806898e69c77430ebd8da0c79c219f97b9acbc9a29a653e09740c59 +duckdb==1.5.2 \ + --hash=sha256:0b291786014df1133f8f18b9df4d004484613146e858d71a21791e0fcca16cf4 \ + --hash=sha256:2323c1195c10fb2bb982fc0218c730b43d1b92a355d61e68e3c5f3ac9d44c34f \ + --hash=sha256:2a1de4f4d454b8c97aec546c82003fc834d3422ce4bc6a19902f3462ef293bed \ + --hash=sha256:35579b8e3a064b5eaf15b0eafc558056a13f79a0a62e34cc4baf57119daecfec \ + --hash=sha256:376856066c65ccd55fcb3a380bbe33a71ce089fc4623d229ffc6e82251afdb6d \ + --hash=sha256:411ad438bd4140f189a10e7f515781335962c5d18bd07837dc6d202e3985253d \ + --hash=sha256:4420b3f47027a7849d0e1815532007f377fa95ee5810b47ea717d35525c12f79 \ + --hash=sha256:486c862bf7f163c0110b6d85b3e5c031d224a671cca468f12ebb1d3a348f6b39 \ + --hash=sha256:52a21823f3fbb52f0f0e5425e20b07391ad882464b955879499b5ff0b45a376b \ + --hash=sha256:5596bbfc31b1b259db69c8d847b42d036ce2c4804f9ccb28f9fc46a16de7bc53 \ + --hash=sha256:56d38b3c4e0ef2abb58898d0fd423933999ed535c45e75e9d9f72e1d5fed69b8 \ + --hash=sha256:638da0d5102b6cb6f7d47f83d0600708ac1d3cb46c5e9aaabc845f9ba4d69246 \ + --hash=sha256:63bf8687feefeed51adf45fa3b062ab8b1b1c350492b7518491b86bae68b1da1 \ + --hash=sha256:6b0fe75c148000f060aa1a27b293cacc0ea08cc1cad724fbf2143d56070a3785 \ + --hash=sha256:70631c847ca918ee710ec874241b00cf9d2e5be90762cbb2a0389f17823c08f7 \ + --hash=sha256:7f69164b048e498b9e9140a24343108a5ae5f17bfb3485185f55fdf9b1aa924d \ + --hash=sha256:81fc4fbf0b5e25840b39ba2a10b78c6953c0314d5d0434191e7898f34ab1bba3 \ + --hash=sha256:84b193aca20565dedb3172de15f843c659c3a6c773bf14843a9bd781c850e7db \ + --hash=sha256:8d599758b4e48bf12e18c9b960cf491d219f0c4972d19a45489c05cc5ab36f83 \ + --hash=sha256:8dbd7e31e5dc157bfe8803fa7d2652336265c6c19926c5a4a9b40f8222868d08 \ + --hash=sha256:98c0535cd6d901f61a5ea3c2e26a1fd28482953d794deb183daf568e3aa5dda6 \ + --hash=sha256:a9cd5e71702d446613750405cde03f66ed268f4c321da071b0472759dad19536 \ + --hash=sha256:bb42e6ed543902e14eae647850da24103a89f0bc2587dec5601b1c1f213bd2ed \ + --hash=sha256:be37680ddb380015cb37318e378c53511c45c4f0d8fac5599d22b7d092b9217a \ + --hash=sha256:c69907354ffee94ba8cf782daf0480dab7557f21ce27fffa6c0ea8f74ed4b8e2 \ + --hash=sha256:c99ef73a277c8921bc0a1f16dee38d924484251d9cfd20951748c20fcd5ed855 \ + --hash=sha256:c9f3e0b71b8a50fccfb42794899285d9d318ce2503782b9dd54868e5ecd0ad31 \ + --hash=sha256:ce0b8141a10d37ecef729c45bc41d334854013f4389f1488bd6035c5579aaac1 \ + --hash=sha256:ce17670bb392ea1b3650537db02bd720908776b5b95f6d2472d31a7de59d1dc1 \ + --hash=sha256:d72b8856b1839d35648f38301b058f6232f4d36b463fe4dc8f4d3fdff2df1a2e \ + --hash=sha256:d9b4f5430bf4f05d4c0dc4c55c75def3a5af4be0343be20fa2bfc577343fbfc9 \ + --hash=sha256:e6495b00cad16888384119842797c49316a96ae1cb132bb03856d980d95afee1 \ + --hash=sha256:ea58ff5b0880593a280cf5511734b17711b32ee1f58b47d726e8600848358160 \ + --hash=sha256:ef461bca07313412dc09961c4a4757a851f56b95ac01c58fac6007632b7b94f2 \ + --hash=sha256:fc85a5dbcbe6eccac1113c72370d1d3aacfdd49198d63950bdf7d8638a307f00 # via ibis-framework durationpy==0.10 \ --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ --hash=sha256:3b41e1b601234296b4fb368338fdcd3e13e0b4fb5b67345948f4f2bf9868b286 # via kubernetes -fastapi==0.135.3 \ - --hash=sha256:9b0f590c813acd13d0ab43dd8494138eb58e484bfac405db1f3187cfc5810d98 \ - --hash=sha256:bd6d7caf1a2bdd8d676843cdcd2287729572a1ef524fc4d65c17ae002a1be654 +fastapi==0.136.1 \ + --hash=sha256:7af665ad7acfa0a3baf8983d393b6b471b9da10ede59c60045f49fbc89a0fa7f \ + --hash=sha256:a6e9d7eeada96c93a4d69cb03836b44fa34e2854accb7244a1ece36cd4781c3f # via # feast (pyproject.toml) # fastapi-mcp @@ -638,9 +638,9 @@ fastapi-mcp==0.4.0 \ --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d # via feast (pyproject.toml) -filelock==3.25.2 \ - --hash=sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694 \ - --hash=sha256:ca8afb0da15f229774c9ad1b455ed96e85a81373065fb10446672f64444ddf70 +filelock==3.29.0 \ + --hash=sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90 \ + --hash=sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258 # via snowflake-connector-python flit-core==3.12.0 \ --hash=sha256:18f63100d6f94385c6ed57a72073443e1a71a4acb4339491615d0f16d6ff01b2 \ @@ -786,9 +786,9 @@ fsspec==2024.9.0 \ # via # feast (pyproject.toml) # dask -google-api-core[grpc]==2.30.2 \ - --hash=sha256:9a8113e1a88bdc09a7ff629707f2214d98d61c7f6ceb0ea38c42a095d02dc0f9 \ - --hash=sha256:a4c226766d6af2580577db1f1a51bf53cd262f722b49731ce7414c43068a9594 +google-api-core[grpc]==2.30.3 \ + --hash=sha256:a85761ba72c444dad5d611c2220633480b2b6be2521eca69cca2dbb3ffd6bfe8 \ + --hash=sha256:e601a37f148585319b26db36e219df68c5d07b6382cff2d580e83404e44d641b # via # feast (pyproject.toml) # google-cloud-bigquery @@ -798,9 +798,9 @@ google-api-core[grpc]==2.30.2 \ # google-cloud-datastore # google-cloud-storage # pandas-gbq -google-auth==2.49.1 \ - --hash=sha256:16d40da1c3c5a0533f57d268fe72e0ebb0ae1cc3b567024122651c045d879b64 \ - --hash=sha256:195ebe3dca18eddd1b3db5edc5189b76c13e96f29e73043b923ebcf3f1a860f7 +google-auth==2.50.0 \ + --hash=sha256:04382175e28b94f49694977f0a792688b59a668def1499e9d8de996dc9ce5b15 \ + --hash=sha256:f35eafb191195328e8ce10a7883970877e7aeb49c2bfaa54aa0e394316d353d0 # via # google-api-core # google-auth-oauthlib @@ -900,60 +900,66 @@ googleapis-common-protos[grpc]==1.74.0 \ # 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.0 \ + --hash=sha256:0ecec963079cd58cbd14723582384f11f166fd58883c15dcbfb342e0bc9b5846 \ + --hash=sha256:0ed006e4b86c59de7467eb2601cd1b77b5a7d657d1ee55e30fe30d76451edba4 \ + --hash=sha256:0ff251e9a0279522e62f6176412869395a64ddf2b5c5f782ff609a8216a4e662 \ + --hash=sha256:1aa4ce8debcd4ea7fb2e150f3036588c41493d1d52c43538924ae1819003f4ce \ + --hash=sha256:1bae92a1dd94c5f9d9493c3a212dd874c202442047cf96446412c862feca83a2 \ + --hash=sha256:1eb67d5adefb5bd2e182d42678a328979a209e4e82eb93575708185d31d1f588 \ + --hash=sha256:2094acd54b272cb6eae8c03dd87b3fa1820a4cef18d6889c378d503500a1dc13 \ + --hash=sha256:2628d6c86f6cb0cb45e0c3c54058bbec559f57eaae699447748cb3928150577e \ + --hash=sha256:29ea813b2e1f45fa9649a17853b2b5465c4072fbcb072e5af6cd3a288216574a \ + --hash=sha256:362624e6a8e5bca3b8233e45eef33903a100e9539a2b995c364d595dbc4018b3 \ + --hash=sha256:3a717fbc46d8a354fa675f7c1e813485b6ba3885f9bef0cd56e5ba27d758ff5b \ + --hash=sha256:3bc59be3945ae9750b9e7d45067d01ae3fe90ea5f9ade99239dabdd6e28a5033 \ + --hash=sha256:3ec9ea74e7268ace7f9aab1b1a4e730193fc661b39a993cd91c606c32d4a3628 \ + --hash=sha256:41353ec2ecedf7aa8f682753a41919f8718031a6edac46b8d3dc7ed9e1ceb136 \ + --hash=sha256:47422135b1d308c14b2c6e758beedb1acd33bb91679f5670edf77bf46244722b \ + --hash=sha256:4964101b8585c144cbda5532b1aa644255126c08a265dae90c16e7a0e63aaa9d \ + --hash=sha256:4a448128607be0de65342dc9b31be7f948ef4cc0bc8832069350abefd310a8f2 \ + --hash=sha256:4b28037cb07768933c54d81bfe47a85f9f402f57d7d69743b991a713b63954eb \ + --hash=sha256:4d0eadc7e4d9ffb2af4247b606cae307be8e448911e5a0d0b16d72fc3d224cfd \ + --hash=sha256:54d243512da35485fc7a6bf3c178fdda6327a9d6506fcdd62b1abd1e41b2927b \ + --hash=sha256:55fa7ea52771be44af0de27d8b80c02cd18c2c3cddde6c847ecebdf72418b6a1 \ + --hash=sha256:57a43c6079a89713522bc4bcb9f75070ecf5d3dbad7792bfe42239362cbf2a16 \ + --hash=sha256:58c1c374fe2b3d852f9b6b11a7dff4c85404e51b9a596fd9e89cf904eb09866d \ + --hash=sha256:5a5ed18de6a0f6cc7087f1563f6bd93fc7df1c19165ca01e9bde5a5dc281d106 \ + --hash=sha256:5e05ba267789ea87b5a155cf0e810b1ab88bf18e9e8740813945ceb8ee4350ba \ + --hash=sha256:5ecd83806b0f4c2f53b1018e0005cd82269ea01d42befc0368730028d850ed1c \ + --hash=sha256:64d6ac45f7271f48e45f67c95b54ef73534c52ec041fcda8edf520c6d811f4bc \ + --hash=sha256:680bd0e7ad5e8daa8a4aa89f68fd6adc834b8a8036dc256533f7e08f4a4b01f7 \ + --hash=sha256:6c18dfb59c70f5a94acd271c72e90128c3c776e41e5f07767908c8c1b74ad339 \ + --hash=sha256:6d874e79afd41a96e11ff4c5d0bc90a80973e476fda1c2c64985667397df432b \ + --hash=sha256:7022615368890680e67b9965d33f5773aade330d5343bbe25560135aaa849eae \ + --hash=sha256:703cb211b820dbffbbc55a16bfc6e4583a6e6e990f33a119d2cc8b83211119c8 \ + --hash=sha256:728a73687e39ae9ca34e4694cbf2f049d3fbc7174639468d0f67200a97d8f9e2 \ + --hash=sha256:728d9667d8f2f586644b748dbd9bb67e50d6a9381767d1357714ea6825bb3bf5 \ + --hash=sha256:762612baf1161ccb8437c0161c668a688223cba28e1bf038f4eb47b13e39ccdf \ + --hash=sha256:7fc391b1566f2907d17aaebe78f8855dc45675159a775fcf9e61f8ee0078e87f \ + --hash=sha256:804a70b328e706b785c6ef16187051c394a63dd1a906d89be24b6ad77759f13f \ + --hash=sha256:83ed9f27f1680b50e89f40f6df348a290ea234b249a4003d366663a12eab94f2 \ + --hash=sha256:884f649de075b84739713d41dd4dfd41e2b910bfb769c4a3ea02ec1da52cd9bb \ + --hash=sha256:8f1cc966c126639cd152fdaa52624d2655f492faa79e013fea161de3e6dda082 \ + --hash=sha256:8f52a464e4ed91780bdfbbdd2b97197f3accaa629b98c200f4dffada759f3ae7 \ + --hash=sha256:9c615f869163e14bb1ced20322d8038fb680b08236521ac3f30cd4c1288785a0 \ + --hash=sha256:9d280a7f5c331622c69f97eb167f33577ff2d1df282c41cd15907fc0a3ca198c \ + --hash=sha256:a10a732421ab4fec934783ce3e54763470d0181db6e3468f9103a275c3ed1853 \ + --hash=sha256:a96fcee45e03fe30a62669fd16ab5c9d3c172660d3085605cb1e2d1280d3c988 \ + --hash=sha256:a97e4821aa710603f94de0da25f25096454d78ffdace5dc77f3a006bc01abba3 \ + --hash=sha256:ba8f0bdc2fae6ce915dfd0c16d2d00bca7e4247c1eae4416e06430e522137858 \ + --hash=sha256:bf2d8a80bec89ab46221ae45c5373d5ba0bd36c19aa8508e85c6cd7e5106cd37 \ + --hash=sha256:cda05425526240807408156b6960a17a79a0c760b813573b67027823be760977 \ + --hash=sha256:d419647372241bc68e957bf38d5c1f98852155e4146bd1e4121adea81f4f01e4 \ + --hash=sha256:d4d9f0624c775f2dfc56ba54d515a8c771044346852a918b405914f6b19d7fd8 \ + --hash=sha256:d60097128cb0a1cab9ea541186ea13cd7b847b8449a7787c2e2350da0cb82d86 \ + --hash=sha256:db2910d3c809444e0a20147361f343fe2798e106af8d9d8506f5305302655a9f \ + --hash=sha256:ddb36c7d6c9c0a65f18c7258634e0c416c6ab59caac8c987b96f80c2ebda0112 \ + --hash=sha256:ddc090c5c1792b10246a78e8c2163ebbe04cf877f9d785c230a7b27b39ad038e \ + --hash=sha256:e5ddf316ced87539144621453c3aef229575825fe60c604e62bedc4003f372b2 \ + --hash=sha256:f35807464c4c58c55f0d31dfa83c541a5615d825c2fe3d2b95360cf7c4e3c0a8 \ + --hash=sha256:f8c30c2225f40dd76c50790f0eb3b5c7c18431efb299e2782083e1981feed243 \ + --hash=sha256:fa94cb2288681e3a11645958f1871d48ee9211bd2f66628fdace505927d6e564 # via feast (pyproject.toml) grpc-google-iam-v1==0.14.4 \ --hash=sha256:392b3796947ed6334e61171d9ab06bf7eb357f554e5fc7556ad7aab6d0e17038 \ @@ -1065,101 +1071,112 @@ hatchling==1.29.0 \ # 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.3.1 \ + --hash=sha256:002fc0201b9af1cc8960e27cdc501ad1f8cdd6dbadb2091c6ddbd4e5ace6cb77 \ + --hash=sha256:011a9071c3df4885cac7f58a2623feac6c8e2ad30e6ba93c55195af05ce61ff5 \ + --hash=sha256:01cf82a514bc4fd145b99333c28523e61b7a9ad051a245804323ebf4e7b1c6a6 \ + --hash=sha256:027ce4fabfeff5af5b9869d5524770877f9061d118bc36b85703ae3faf5aad8e \ + --hash=sha256:03baa381964b8df356d19ec4e3a6ae656044249a87b0def257fe1e08dbaf6094 \ + --hash=sha256:042e57de8a2cae91e3e7c0af32960ea2c5107b2f27f68a740295861e68780a8a \ + --hash=sha256:09d41a3a965f7c261223d516ebda607aee4d8440dd7637f01af9a4c05872f0c4 \ + --hash=sha256:09f5e510f637f2c72d2a79fb3ad05f7b6211e057e367ca5c4f97bb3d8c9d71f4 \ + --hash=sha256:0b5ff2f643f4b452b0597b7fe6aa35d398cb31d8806801acfafb1558610ea2aa \ + --hash=sha256:0caf3fc8af0767794b335753781c3fa35f2a3e975c098edbc8f733d35d6a95e4 \ + --hash=sha256:0fac4af8515e6cca74fc701169ae4dc9a71a90e9319c9d21006ec9454b43aa2f \ + --hash=sha256:113e098e4a6b3cc5500e05e7cb1548ba9e83de5fe755941b11f6020a76e6c03a \ + --hash=sha256:137c14905ea6f2933967200bc7b2a0c8ec9387888b273fd0004f25b994fd0343 \ + --hash=sha256:156be6a0c736ee145cfe0fb155d0e96cec8d4872cf8b4f76ad6a2ee6ab391d0a \ + --hash=sha256:17ec8b524055a88b80d76c177dbbbe475a25c17c5bf4b67bdbdbd0629bcae838 \ + --hash=sha256:1ac7697365dbe45109273b34227fee6826b276ead9a4a007e0877e1d3f0fcf21 \ + --hash=sha256:1b46e96b50dad03495447860510daebd2c96fd44ed25ba8ccb03e9f89eaa9d34 \ + --hash=sha256:1ebc307a87b099d0877dbd2bdc0bae427258e7ec67f60a951e89027f8dc2568f \ + --hash=sha256:1f7bceb03a1b934872ffe3942eaeed7c7e09096e67b53f095b81f39c7a819113 \ + --hash=sha256:2611bfaaadc5e8d43fb7967f9bbf1110c8beaa83aee2f2d812c76f11cfb56c6a \ + --hash=sha256:264ee7e9cb6c30dc78da4ecf71d74cf14ca122817c665d838eda8b4384bce1b0 \ + --hash=sha256:26f899cde0279e4b7d370716ff80320601c2bd93cdf3e774a42bdd44f65b41f8 \ + --hash=sha256:29fe35e3c6fe03204e75c86514f452591957a1e06b05d86e10d795455b71c355 \ + --hash=sha256:2afc675b831f7552da41116fffffca4340f387dc03f56d6ec0c7895ab0b59a10 \ + --hash=sha256:2b6da6e07359107c653a809b3cff2d9ccaeedbafe33c6f16434aef6f53ce4a2b \ + --hash=sha256:2b96da7e365d6488d2a75266a662cbe3cc14b28c23dd9b0c9aa04b5bc5c20192 \ + --hash=sha256:2f1c1b2e8f00b71e6214234d313f655a3a27cd4384b054126ce04073c1d47045 \ + --hash=sha256:304481241e081bc26f0778b2c2b99f9c43917e4e724a016dcc9439b7ab12c726 \ + --hash=sha256:318f772dd321404075d406825266e574ee0f4751be1831424c2ebd5722609398 \ + --hash=sha256:3586c8a5f56d34b9dddaaa9e76905f31933cac267251006adf86ec0eef7d0400 \ + --hash=sha256:3724f0e58c6ff76fd683429945491de71324ab1bc0ad943a8d68cb0932d24075 \ + --hash=sha256:3fb6573efa15a29c12c0c0f7170b14e7c1347fe4bb39b6a15b779f46015cc929 \ + --hash=sha256:40ae8a7041fcb328a6bc7202d8c4e6e0d38d434b2e3880b1ee8ed754f17cd836 \ + --hash=sha256:4106201cd052d9eabe3cb7b5a24b0fe37307792bda4fcb3cf6ddd72f697828e8 \ + --hash=sha256:439f9a5cc8f9519ce208a24cdebfa0440fef26aa682a40ba2c92acb10a53f5e0 \ + --hash=sha256:4479e36d263251dba8ab8ea81adf07e7f1163603c7102c5de1e130b83b4fad3b \ + --hash=sha256:487658e1db83c1ee9fbbac6a43039ea76957767a5987ffb16b590613f9e68297 \ + --hash=sha256:48ff424f8aa36aacd9fdaa68efeb27d2e8771f293af4305bdb15d92194ca6631 \ + --hash=sha256:4f7e242eab698ad0be5a4b2ec616fa856569c57455cc67c625fd567726290e5f \ + --hash=sha256:526db52e5234a9463520e960a509d6c1bd5128d1ab1b569cbf459fe39189e8ab \ + --hash=sha256:52d5641027d6731bc7b5e7d126a5158a99784a9f8c6de3d97ca89aca4969e9f8 \ + --hash=sha256:53148a4e21057541b6d8e493b2ea1b500037ddf34433c391970036f3cbce00e3 \ + --hash=sha256:583de2f16528e66081cbdfe510d8488c2de73039dc00aada7d22bd49d73a4a94 \ + --hash=sha256:5e55d90b431b0c6b64ae5a624208d4aea318566d31872e595ee723c0f5b9a79f \ + --hash=sha256:5f316cf2d0558f5027aab19dde7d7e4901c26c21fa95367bc37784e8f547bbf2 \ + --hash=sha256:60543f3b068b16a86e99ed96b7fdae71cdc1d8abdfe9b3f82032a555e52ece7e \ + --hash=sha256:62cc62284541bb2a86c898c7d5e8388661cade91c184cb862095ed547e80588f \ + --hash=sha256:65c05b79cb8366c123357b354a16f9fc3f7187159422f143638d1c26b7240ed4 \ + --hash=sha256:65f6ac06a9f0c32c254660ec6a9329d81d589e8f5d0a9837a941d5424a6be1ef \ + --hash=sha256:6d1434d0bcc1b3ef048bae53f26456405c08aeed9827e65b24094f5f3a6793f1 \ + --hash=sha256:6e2e1024f0a021777740cb7c633a0efb2c4a4bc570f508223a8dcbcf79f99ef9 \ + --hash=sha256:6ffa7ba2e2da1f806f3181b9730b3e87ba9dbfec884806725d4584055ba3faa6 \ + --hash=sha256:743b85bd6902856cac457ddd8cd7dd48c89c47d641b6016ff5e4d015bfbd4799 \ + --hash=sha256:77c5d2bebbc9d06691abb512a31d0f54e1562af0b872891463a67a949b5278ef \ + --hash=sha256:79cd03e7ff550c17758a7520bf437c156d3d4c8bb74214deeafa69cda49c85a4 \ + --hash=sha256:80aba5f85d6227faee628ae28d1c3b69c661806a0636548ac56c68782606454f \ + --hash=sha256:81a1669b6631976b1dc9d3d58ed1ab3333e9f52feb91a2a1fb8241101ac3b665 \ + --hash=sha256:8597c35c9e82f65fd5897c4a2188c65d7daf10607b102960137b23d261cd957b \ + --hash=sha256:8650158217b469d8b6087f490929211b0493a9121154c4efaafd1dec9e19319e \ + --hash=sha256:8887bf0f31e4b550bd988c8863b527b6587d200653e9375cd91eea2b944b7424 \ + --hash=sha256:8a52b24cd710690c4a7e191c7e300136ad2ecb3c68ffe7e95b598e76de166e5e \ + --hash=sha256:8e3754ce60e1b11b0afad9a053481ff184d2ee24bea47099107156d1b84a84aa \ + --hash=sha256:907f7b5501a534030738f0f27459a612d2266fd0507b007bb8f3e6de08167920 \ + --hash=sha256:90d6b9f2652303aefd2c5a26a5e14cb74a3a63d10faa642c08d790e99442a088 \ + --hash=sha256:98fd5b39410e9d69e10e90d0330e35650becaa5dd2548f509b9598f1f3c6124d \ + --hash=sha256:9bfdeff778d3f7ff449ca5922ab773899e7d31e26a576028b06a5e9cf0ed8c34 \ + --hash=sha256:9ebae74ce2b977c2fcb22d6a10aa0acb730022406977b2bcb6ddd6788f5c414a \ + --hash=sha256:a110d19881ca78a88583d3b07231e7c6864864f5f1f3491b638863ea45fa8708 \ + --hash=sha256:a1d190790ee39b8b7adeeb10fc4090dc4859eb4e75ed27bd8108710eef18f358 \ + --hash=sha256:a2f049c3f3c83e886cd1f53958e2a1ebb369be626bef9e50d8b24d79864f1df6 \ + --hash=sha256:a3af4e9f277d6b8acd369dc44a723a055752fca9d045094383af39f90a3e3729 \ + --hash=sha256:a42c7becd4c9ec4ab5769c754eb61112777bdc6e1c1525e2077389e193b5f5aa \ + --hash=sha256:a58a58cef0d911b1717154179a9ff47852249c536ea5966bde4370b6b20638ff \ + --hash=sha256:ab1f646ff531d70bfd25f01e60708dfa3d105eb458b7dedd9fe9a443039fd809 \ + --hash=sha256:ad940dc2db545dc978cb41cb9a683e2ff328f3ef581230b9ca40ff6c3d01d542 \ + --hash=sha256:afe3c3863f16704fb5d7c2c6ff56aaf9e054f6d269f7b4c9074c5476178d1aba \ + --hash=sha256:b1e3b9f4bf9a4120510ba77a77b2fb674893cd6795653545152bb11a79eecfcb \ + --hash=sha256:b2390ad81c03d93ef1d5afd18ffcf5935de827f1a2b96b2c829437968bdabccb \ + --hash=sha256:b37df4b10cb15dedfc203f69312d8eedd617b941c21df58c13af59496c53ad0f \ + --hash=sha256:b3df9447f9209f9aa0434ca74050e9509670c1ad99398fe5807abb90e5f3a014 \ + --hash=sha256:b4fe7f38aa8956fcc1cea270e62601e0e11066aff78e384be70fd283d30293b6 \ + --hash=sha256:c1d68c6980d4690a4550bd3db6c03146f7be68ef5d08d38bb1fb68b3e9c32fe3 \ + --hash=sha256:c24c1460486b6b36083252c2db21a814becf8495ccd0e76b7286623e37239b63 \ + --hash=sha256:c25132902d3eff38781e0d54f27a0942ec849e3c07dbdce83c4d92b7e43c8dce \ + --hash=sha256:c74bd9926954e7e575f9cd9890f63defd90cd8f812dfbf8e1efb72acc9355456 \ + --hash=sha256:c8139e9011117822391c5bcfd674c5948fb1e4b8cb9adf6f13d9890859ee3a1a \ + --hash=sha256:ce334915f5d31048f76a42c607bf26687cf045eb1bc852b7340f09729c6a64fc \ + --hash=sha256:d14229beaa76e66c3a25f9477d973336441ca820df853679a98796256813316f \ + --hash=sha256:d42f3a13290f89191568fc113d95a3d2c8759cdd8c3672f021d8b7436f909e75 \ + --hash=sha256:d8e56e0d1fe607bfff422633f313aec9191c3859ab99d11ff097e3e6e068000c \ + --hash=sha256:da6f0302360e99d32bc2869772692797ebadd536e1b826d0103c72ba49d38698 \ + --hash=sha256:db46baf157feefd88724e6a7f145fe996a5990a8604ed9292b45d563360e513b \ + --hash=sha256:dcea8c3f53674ae68e44b12e853b844a1d315250ca6677b11ec0c06aff85e86c \ + --hash=sha256:de94b409f49eb6a588ebdd5872e826caec417cd77c17af0fb94f2128427f1a2a \ + --hash=sha256:e0356561b4a97c83b9ee3de657a41b8d1a1781226853adaf47b550bb988fda6f \ + --hash=sha256:e0db44cf81e4d7b94f3776b9f89111f74ed6bbdbfd42a22bc4a5ce0644d3e060 \ + --hash=sha256:e31e92b61d56244047ad600812e16f7587a6172f74810fd919ff993af12b9149 \ + --hash=sha256:e89dabf436ee79b358fd970dcbed6333a36d91db73f27069ca24a02fb138a404 \ + --hash=sha256:eddeb9a153795cf6e615f9f3cef66a1d573ff3b6ee16df2b10d1d1c2f2baeaa8 \ + --hash=sha256:ee11fd431f83d8a5b29d370b9d79a814d3218d30113bdcd44657e9bdf715fc92 \ + --hash=sha256:ee37fe8cf081b72dea72f96a0ee604f492ec02252eb77dc26ff6eec3f997b580 \ + --hash=sha256:f19ee7dc1ef8a6497570d91fa4057ba910ad98297a50b8c44ff37589f7c89d17 \ + --hash=sha256:f2f94355affd51088f57f8674b0e294704c3c7c3d7d3b1545310f5b135d4843b \ + --hash=sha256:f525734382a47f9828c9d6a1501522c78d5935466d8e2be1a41ba40ca5bb922b \ + --hash=sha256:f915a34fb742e23d0d61573349aa45d6f74037fde9d58a9f340435eff8d62736 # via feast (pyproject.toml) httpcore==1.0.9 \ --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ @@ -1224,9 +1241,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.13 \ + --hash=sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242 \ + --hash=sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 # via # anyio # httpx @@ -1264,97 +1281,97 @@ kubernetes==35.0.0 \ --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee # 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.9.0 \ + --hash=sha256:07cf11f769831186eeac424376e6189f20ace4f7263e2134bdb9757340d84d4d \ + --hash=sha256:0a09c2f5869649101738653a9b7ab70cf045a1105ac66cbb8f4055e61df78f2d \ + --hash=sha256:0a1be03168b2691ba61927e299b352a6315189199ca18a57b733f86cb3cc8d38 \ + --hash=sha256:0b73e4266307e51c95e09c0750b7ec383c561d2e97d58e473f6f6a209952fbb8 \ + --hash=sha256:15cb151e52a044f06e54ac7f7b47adbfc89b5c8e2b63e1175a9d587c43e8942a \ + --hash=sha256:194fc1a32e1e21fe809d38b5faea66cc65eaa00217c8901fbdb99866938adbdb \ + --hash=sha256:1bf465d1e5b0a27713862441f6467b5ab76385f4ecf8f1f3a44f8aa3c695b4b6 \ + --hash=sha256:1c587494461ebd42229d0f1739f3aa34237dd9980623ecf1be8d3bcba79f4499 \ + --hash=sha256:224b9727eb8bc188bc3bcf29d969dba0cd61b01d9bac80c41575520cc4baabb2 \ + --hash=sha256:22a904cbdb678f7cb348c90d543d3c52f581663d687992fee47fd566dcbf5285 \ + --hash=sha256:2b8f5d00b49818f4e2b1667db994488b045835e0ac16fe2f924f3871bd2b8ac5 \ + --hash=sha256:2c3786f0f4490a5cd87f1ed6cefae833ad6b1060d52044ce0434a2e85893afd0 \ + --hash=sha256:2d03fa4fd277a7974c1978c92c374c57f44edeee163d147b477b143446ad1bf6 \ + --hash=sha256:2f8e12706dcb8ff6b3ed57514a19e45c49ad00bcd423e87b2b2e4b5f64578443 \ + --hash=sha256:3be322a15ee5e70b93b7a59cfd074614f22cc8c9ff18bd27f474e79137ea8d3b \ + --hash=sha256:3cc2917258e131ae5f958a4d872e07555b51cb7466a43433218061c74ef33745 \ + --hash=sha256:3f05d145df35dca5056a8bc3838e940efebd893a54b3e19b2dda39ceaa299bcb \ + --hash=sha256:3fe56e80badb66fdcde06bef81bbaa5bfcf6fbd7aefb86222d9e369c38c6b228 \ + --hash=sha256:42ff8a962554c350d4a83cf47d9b7b78b0e6ff7943e87df7cdfc97c07f3c016f \ + --hash=sha256:451daa98463b7695b0a30aa56bf637831ea559e7b8101ac2ef6382e8eb15e29c \ + --hash=sha256:465814ab157986acb9dfa5ccd7df944be5eefc0d08d31ec6e8d88bc71251d845 \ + --hash=sha256:4c4d0440a3a8e31d962340c3e1cc3fc9ee7febd34c8d8f770d06adb947779ea5 \ + --hash=sha256:4e3dda8345307fd7306db0ed0cb109a63a2c85ba780eb9dc2d09b2049a931f9c \ + --hash=sha256:5093043afb226ecfa1400120d1ebd4442b4f99977783e4f4f7248879009b227f \ + --hash=sha256:5112c2fb7c2eefefaeaf5c97fec81343ef44ee86a30dcfaa8223822fba6467b4 \ + --hash=sha256:527b5b820b47a09e09829051452bb0d1dd2122261254e2a6f674d12f1d793d54 \ + --hash=sha256:54d412e47c21b85865676ed0724e37a89e9593c2eee1e7367adf85bfad56ffb1 \ + --hash=sha256:56d65b583cf43b8cf4c8fbe1e1da20fa3076cc32a1149a141507af1062718236 \ + --hash=sha256:5ca8e133d799c948db2ab1afc081c333a825b5540475164726dcbf73537e5c2f \ + --hash=sha256:603138ee838ee1583f1b960b62d5d0007845c5c423feb68e44648b1359014e27 \ + --hash=sha256:63c12efcd160e1d14da11af0c46c0217473e1e0d2ae1acbccc83f561ea4c2a7b \ + --hash=sha256:657f8ba7b9eaaa82759a104137aed2a3ef7bc46ccfd43e0d89b04005b3e0a4cc \ + --hash=sha256:66b58fed90a545328e80d575467244de3741e088c1af928f0b489ebec3ef3858 \ + --hash=sha256:6788207daa0c19955d2b668f3294a368d19f67d9b5f274553fd073c1260cbb9f \ + --hash=sha256:703f4ae36d6240bfe24f542bac784c7e4194ec49c3ba5a994d02891649e2d85b \ + --hash=sha256:7202bdcac47d3a708271c4304a474a8605a4a9a4a709e954bf2d3241140aa938 \ + --hash=sha256:756775d25ec8345b837ab52effee3ad2f3b2dfd6bbee3e3f029c517bd5d8f05a \ + --hash=sha256:78042f6facfd98ecb25e9829c7e37cce23363d9d7c83bc5f72702c5059eb082b \ + --hash=sha256:789fff71757facc0738e8d89e3b84e4f0251c1c975e85e81b152cdaca927cc2d \ + --hash=sha256:7bc30ad339f4e1a01d4917d645e522a0bc0030644d8973f6346397c93ba1503f \ + --hash=sha256:7d429bdd4ac0ab17c8e4a8af0ed2a7440b16eba474909ab357131018fe8c7e71 \ + --hash=sha256:7d5c8a5929ac325729f6119802070b561f4db793dffc45e9ac750992a4ed4d22 \ + --hash=sha256:7e6274fd33fc5b2a14d41c9119629d3ff395849d8bcbc80cf637d9e8d2034da8 \ + --hash=sha256:80b25c7b570a86c03b5da69e665809deb39265476e8e21d96a9328f9762f9990 \ + --hash=sha256:81107843ed1836874b46b310f9b1816abcb89912af627868522461c3b7333c0f \ + --hash=sha256:8494cfc61e03542f2d381e71804990b3931175a29b9278fdb4a5459948778dc2 \ + --hash=sha256:850d6d03177e52700af605fd60db7f37dcb89782049a149674d1a9649c2138fd \ + --hash=sha256:8c6bc1384d9738781cfd41d09ad7f6e8af13cfea2c75ece6bd6d2566cdea2076 \ + --hash=sha256:90904fac73c478f4b83f4ed96c99c8208b75e6f9a8a1910548f69a00f1eaa671 \ + --hash=sha256:90e6d5420fc8a300518d4d2288154ff45005e920425c22cbbfe8330f3f754bd9 \ + --hash=sha256:928bd06eca2c2bbf4349e5b817f837509b0604342e65a502de1d50a7570afd15 \ + --hash=sha256:9b3e3bc363f71bda1639a4ee593cb78f7fbfeacc73411ec0d4c92f00730010a4 \ + --hash=sha256:9edcc35d1cae9fd5320171b1a838c7da8a5c968af31e82ecc3dff30b4be0957f \ + --hash=sha256:9fcb461fbf70654a52a7cc670e606f04449e2374c199b1825f754e16dacfedd8 \ + --hash=sha256:a0951822531e7aee6e0dfb556b30d5ee36bbe234faf60c20a16c01be3530869d \ + --hash=sha256:a361c9434a64d70a7dbb771d1de302c0cc9f13c0bffe1cf7e642152814b35265 \ + --hash=sha256:a4b25c6c25cac5d0d9d6d6da855195b254e0021e513e0249f0e3b444dc6e0e61 \ + --hash=sha256:a5af136bfba820d592f86c67affcef9b3ff4d4360ac3255e341e964489b48519 \ + --hash=sha256:a81eea9b999b985e4bacc650c4312805ea7008fd5e45e1bf221310176a7bcb3a \ + --hash=sha256:a9c63e04d003bc0fb6a03b348018b9a3002f98268200e22cc80f146beac5dc40 \ + --hash=sha256:aa95738a68cedd3a6f5492feddc513e2e166b50602958139e47bbdd82da0f5a7 \ + --hash=sha256:b0a2040f801406b93657a70b72fa12311063a319fee72ce98e1524da7200171f \ + --hash=sha256:b8bd70d5d816566a580d193326912f4a76ec2d28a97dc4cd4cc831c0af8e330e \ + --hash=sha256:b8da9f8035bb417770b1e1610526d87ad4fc58a2804dc4d79c53f6d2cf5a6eb9 \ + --hash=sha256:bc5518873822d2faa8ebdd2c1a4d7c8ef47b01a058495ab7924cb65bdbf5fc9a \ + --hash=sha256:c0d620e74897f8c2613b3c4e2e9c1e422eb46d2ddd07df540784d44117836af3 \ + --hash=sha256:c2640e23d2b7c98796f123ffd95cf2022c7777aa8a4a3b98b36c570d37e85eee \ + --hash=sha256:c81aef782380f0f13ead670aae01825eb653b44b046aa0e5ebbb79f76ed4aa11 \ + --hash=sha256:d4d16b608a1c43d7e33142099a75cd93af482dadce0bf82421e91cad077157f4 \ + --hash=sha256:d69fc39e627908f4c03297d5a88d9284b73f4d90b424461e32e8c2485e21c283 \ + --hash=sha256:d9da80e5b04acce03ced8ba6479a71c2a2edf535c2acc0d09c80d2f80f3bad15 \ + --hash=sha256:dd2c7e082b0b92e1baa4da28163a808672485617bc855cc22a2fd06978fa9084 \ + --hash=sha256:de7dac64e3eb832ffc7b840eb8f52f76420cde1b845be51b2a0f6b870890645e \ + --hash=sha256:e0785c2fb4a81e1aece366aa3e2e039f4a4d7d21aaaded5227d7f3c703427882 \ + --hash=sha256:e306d956cfa027fe041585f02a1602c32bfa6bb8ebea4899d373383295a6c62f \ + --hash=sha256:e78fb7419e07d98c2af4b8567b72b3eaf8cb05caad642e9963465569c8b2d87e \ + --hash=sha256:e9002e98dcb1c0a66723592520decd86238ddcef168b37ff6cfb559200b4b774 \ + --hash=sha256:e94cbc6ad9a6aeea46d775cbb11f361022f778a9cc8cc90af653d3a594b057ce \ + --hash=sha256:eea1b54943475f51698f85fa230c65ccac769f1e603b981be060ac5763d90927 \ + --hash=sha256:f100bfe2acf8a3689af9d0cc660d89f17286c9c795f9f18f7b62dd1a6b247ae6 \ + --hash=sha256:f162af66a2ed3f7d1d161a82ca584efd15acd9c1cff190a373458c32f7d42118 \ + --hash=sha256:f24b90b0e0c8cc9491fb1693ae91fe17cb7963153a1946395acdbdd5818429a4 \ + --hash=sha256:f29b68cd9714531672db62cc54f6e8ff981900f824d13fa0e00749189e13778e \ + --hash=sha256:f38bc489037eca88d6ebefc9c4d41a4e07c8e8b4de5188a9e6d290273ad7ebb1 \ + --hash=sha256:f3fd278f5e6bf7c75ccd6d12344eb686cc020712683363b66f46ac79d37c799f \ + --hash=sha256:f4003f70c56a5addd6aa0897f200dd59afd3bf7bcd5b3cce46dd21f925743bc2 \ + --hash=sha256:f48c963a76d71b9d7927eb817b543d0dccd52ab6648b99d37bd54f4cd475d856 \ + --hash=sha256:f819e0c6413e259a17a7c0d49f97f405abadd3c2a316a3b46c6440b7dbbedbb1 \ + --hash=sha256:fc5758e2b7a56532dc33e3c544d78cbaa9ecf0a0f2a2da2df882c1d6b99a317f \ + --hash=sha256:fcbdf2a9ca24e87bbebb47f1fe34e531ef06f104f98c9ccfc953a3f3344c567a # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ @@ -1733,51 +1750,51 @@ multidict==6.7.1 \ # aiobotocore # aiohttp # yarl -mypy==1.20.0 \ - --hash=sha256:002b613ae19f4ac7d18b7e168ffe1cb9013b37c57f7411984abbd3b817b0a214 \ - --hash=sha256:00e047c74d3ec6e71a2eb88e9ea551a2edb90c21f993aefa9e0d2a898e0bb732 \ - --hash=sha256:02cca0761c75b42a20a2757ae58713276605eb29a08dd8a6e092aa347c4115ca \ - --hash=sha256:0ecd63f75fdd30327e4ad8b5704bd6d91fc6c1b2e029f8ee14705e1207212489 \ - --hash=sha256:0f42dfaab7ec1baff3b383ad7af562ab0de573c5f6edb44b2dab016082b89948 \ - --hash=sha256:1973868d2adbb4584a3835780b27436f06d1dc606af5be09f187aaa25be1070f \ - --hash=sha256:26c8b52627b6552f47ff11adb4e1509605f094e29815323e487fc0053ebe93d1 \ - --hash=sha256:2721f0ce49cb74a38f00c50da67cb7d36317b5eda38877a49614dc018e91c787 \ - --hash=sha256:2fcedb16d456106e545b2bfd7ef9d24e70b38ec252d2a629823a4d07ebcdb69e \ - --hash=sha256:31b5dbb55293c1bd27c0fc813a0d2bb5ceef9d65ac5afa2e58f829dab7921fd5 \ - --hash=sha256:34506397dbf40c15dc567635d18a21d33827e9ab29014fb83d292a8f4f8953b6 \ - --hash=sha256:367e5c993ba34d5054d11937d0485ad6dfc60ba760fa326c01090fc256adf15c \ - --hash=sha256:379edf079ce44ac8d2805bcf9b3dd7340d4f97aad3a5e0ebabbf9d125b84b442 \ - --hash=sha256:39362cdb4ba5f916e7976fccecaab1ba3a83e35f60fa68b64e9a70e221bb2436 \ - --hash=sha256:4525e7010b1b38334516181c5b81e16180b8e149e6684cee5a727c78186b4e3b \ - --hash=sha256:47781555a7aa5fedcc2d16bcd72e0dc83eb272c10dd657f9fb3f9cc08e2e6abb \ - --hash=sha256:49d11c6f573a5a08f77fad13faff2139f6d0730ebed2cfa9b3d2702671dd7188 \ - --hash=sha256:555493c44a4f5a1b58d611a43333e71a9981c6dbe26270377b6f8174126a0526 \ - --hash=sha256:555658c611099455b2da507582ea20d2043dfdfe7f5ad0add472b1c6238b433f \ - --hash=sha256:697f102c5c1d526bdd761a69f17c6070f9892eebcb94b1a5963d679288c09e78 \ - --hash=sha256:76a70bf840495729be47510856b978f1b0ec7d08f257ca38c9d932720bf6b43e \ - --hash=sha256:7d3243c406773185144527f83be0e0aefc7bf4601b0b2b956665608bf7c98a83 \ - --hash=sha256:931a7630bba591593dcf6e97224a21ff80fb357e7982628d25e3c618e7f598ef \ - --hash=sha256:9804c3ad27f78e54e58b32e7cb532d128b43dbfb9f3f9f06262b821a0f6bd3f5 \ - --hash=sha256:a17c5d0bdcca61ce24a35beb828a2d0d323d3fcf387d7512206888c900193367 \ - --hash=sha256:a6e0641147cbfa7e4e94efdb95c2dab1aff8cfc159ded13e07f308ddccc8c48e \ - --hash=sha256:a79c1eba7ac4209f2d850f0edd0a2f8bba88cbfdfefe6fb76a19e9d4fe5e71a2 \ - --hash=sha256:a9336b5e6712f4adaf5afc3203a99a40b379049104349d747eb3e5a3aa23ac2e \ - --hash=sha256:b20c8b0fd5877abdf402e79a3af987053de07e6fb208c18df6659f708b535134 \ - --hash=sha256:b3a49064504be59e59da664c5e149edc1f26c67c4f8e8456f6ba6aba55033018 \ - --hash=sha256:b503ab55a836136b619b5fc21c8803d810c5b87551af8600b72eecafb0059cb0 \ - --hash=sha256:bd0212976dc57a5bfeede7c219e7cd66568a32c05c9129686dd487c059c1b88a \ - --hash=sha256:c70380fe5d64010f79fb863b9081c7004dd65225d2277333c219d93a10dad4dd \ - --hash=sha256:d99f515f95fd03a90875fdb2cca12ff074aa04490db4d190905851bdf8a549a8 \ - --hash=sha256:e80cf77847d0d3e6e3111b7b25db32a7f8762fd4b9a3a72ce53fe16a2863b281 \ - --hash=sha256:eb96c84efcc33f0b5e0e04beacf00129dd963b67226b01c00b9dfc8affb464c3 \ - --hash=sha256:ebea00201737ad4391142808ed16e875add5c17f676e0912b387739f84991e13 \ - --hash=sha256:efe8d70949c3023698c3fca1e94527e7e790a361ab8116f90d11221421cd8726 \ - --hash=sha256:f13b3e41bce9d257eded794c0f12878af3129d80aacd8a3ee0dee51f3a978651 \ - --hash=sha256:f194db59657c58593a3c47c6dfd7bad4ef4ac12dbc94d01b3a95521f78177e33 \ - --hash=sha256:f49590891d2c2f8a9de15614e32e459a794bcba84693c2394291a2038bbaaa69 \ - --hash=sha256:f75ff57defcd0f1d6e006d721ccdec6c88d4f6a7816eb92f1c4890d979d9ee62 \ - --hash=sha256:f799d9db89fc00446f03281f84a221e50018fc40113a3ba9864b132895619ebe \ - --hash=sha256:f8426d4d75d68714abc17a4292d922f6ba2cfb984b72c2278c437f6dae797865 +mypy==1.20.2 \ + --hash=sha256:0c64e5973df366b747646fc98da921f9d6eba9716d57d1db94a83c026a08e0fb \ + --hash=sha256:0deb80d062b2479f2c87ae568f89845afc71d11bc41b04179e58165fd9f31e98 \ + --hash=sha256:1e1c12f6d2db3d78b909b5f77513c11eb7f2dd2782b96a3ab6dffc7d44575c99 \ + --hash=sha256:20175a1c0f49863946ec20b7f63255768058ac4f07d2b9ded6a6b46cfb5a9100 \ + --hash=sha256:29752dbbf8cc53f89f6ac096d363314333045c257c9c75cbd189ca2de0455744 \ + --hash=sha256:2a4102b03bb7481d9a91a6da8d174740c9c8c4401024684b9ca3b7cc5e49852f \ + --hash=sha256:2de3dcea53babc1c3237a19002bc3d228ce1833278f093b8d619e06e7cc79609 \ + --hash=sha256:34397cdced6b90b836e38182076049fdb41424322e0b0728c946b0939ebdf9f6 \ + --hash=sha256:4077797a273e56e8843d001e9dfe4ba10e33323d6ade647ff260e5cd97d9758c \ + --hash=sha256:419413398fe250aae057fd2fe50166b61077083c9b82754c341cf4fd73038f30 \ + --hash=sha256:4b6481b228d072315b053210b01ac320e1be243dc17f9e5887ef167f23f5fae4 \ + --hash=sha256:4dbfcf869f6b0517f70cf0030ba6ea1d6645e132337a7d5204a18d8d5636c02b \ + --hash=sha256:4fef51b01e638974a6e69885687e9bd40c8d1e09a6cd291cca0619625cf1f558 \ + --hash=sha256:52b176444e2e5054dfcbcb8c75b0b719865c96247b37407184bbfca5c353f2c2 \ + --hash=sha256:56908d7e08318d39f85b1f0c6cfd47b0cac1a130da677630dac0de3e0623e102 \ + --hash=sha256:5a65aa591af023864fd08a97da9974e919452cfe19cb146c8a5dc692626445dc \ + --hash=sha256:688c3312e5dadb573a2c69c82af3a298d43ecf9e6d264e0f95df960b5f6ac19c \ + --hash=sha256:6e2b469efd811707bc530fd1effef0f5d6eebcb7fe376affae69025da4b979a2 \ + --hash=sha256:7488448de6007cd5177c6cea0517ac33b4c0f5ee9b5e9f2be51ce75511a85517 \ + --hash=sha256:785b08db19c9f214dc37d65f7c165d19a30fcecb48abfa30f31b01b5acaabb58 \ + --hash=sha256:7b0e817b518bff7facd7f85ea05b643ad8bdcce684cf29784987b0a7c8e1f997 \ + --hash=sha256:803203d2b6ea644982c644895c2f78b28d0e208bba7b27d9b921e0ec5eb207c6 \ + --hash=sha256:89dce27e142d25ffbc154c1819383b69f2e9234dc4ed4766f42e0e8cb264ab5c \ + --hash=sha256:913485a03f1bcf5d279409a9d2b9ed565c151f61c09f29991e5faa14033da4c8 \ + --hash=sha256:97d7b9a485b40f8ca425460e89bf1da2814625b2da627c0dcc6aa46c92631d14 \ + --hash=sha256:9bcb8aa397ff0093c824182fd76a935a9ba7ad097fcbef80ae89bf6c1731d8ec \ + --hash=sha256:9d56a78b646f2e3daa865bc70cd5ec5a46c50045801ca8ff17a0c43abc97e3ee \ + --hash=sha256:a5da6976f20cae27059ea8d0c86e7cef3de720e04c4bb9ee18e3690fdb792066 \ + --hash=sha256:a94c5a76ab46c5e6257c7972b6c8cff0574201ca7dc05647e33e795d78680563 \ + --hash=sha256:a95a9248b0c6fd933a442c03c3b113c3b61320086b88e2c444676d3fd1ca3330 \ + --hash=sha256:baf593f2765fa3a6b1ef95807dbaa3d25b594f6a52adcc506a6b9cb115e1be67 \ + --hash=sha256:bb9c2fa06887e21d6a3a868762acb82aec34e2c6fd0174064f27c93ede68ad15 \ + --hash=sha256:bba9ad231e92a3e424b3e56b65aa17704993425bba97e302c832f9466bb85bac \ + --hash=sha256:c3bae4f855d965b5453784300c12ffc63a548304ac7f99e55d4dc7c898673aa3 \ + --hash=sha256:c566c3a88b6ece59b3d70f65bedef17304f48eb52ff040a6a18214e1917b3254 \ + --hash=sha256:cdecf62abcc4292500d7858aeae87a1f8f1150f4c4dd08fb0b336ee79b2a6df3 \ + --hash=sha256:cf5a4db6dca263010e2c7bff081c89383c72d187ba2cf4c44759aac970e2f0c4 \ + --hash=sha256:d52ad8d78522da1d308789df651ee5379088e77c76cb1994858d40a426b343b9 \ + --hash=sha256:e061b58443f1736f8a37c48978d7ab581636d6ab03e3d4f99e3fa90463bb9382 \ + --hash=sha256:e2877a02380adfcdbc69071a0f74d6e9dbbf593c0dc9d174e1f223ffd5281943 \ + --hash=sha256:e73c07f23009962885c197ccb9b41356a30cc0e5a1d0c2ea8fd8fb1362d7f924 \ + --hash=sha256:e8222c26daaafd9e8626dec58ae36029f82585890589576f769a650dd20fd665 \ + --hash=sha256:edfbfca868cdd6bd8d974a60f8a3682f5565d3f5c99b327640cedd24c4264026 \ + --hash=sha256:f376e37f9bf2a946872fc5fd1199c99310748e3c26c7a26683f13f8bdb756cbd # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ @@ -1867,9 +1884,9 @@ oauthlib==3.3.1 \ --hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \ --hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1 # via requests-oauthlib -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # db-dtypes @@ -1949,9 +1966,9 @@ pandas==2.3.3 \ # pandas-gbq # pymilvus # snowflake-connector-python -pandas-gbq==0.34.1 \ - --hash=sha256:6bea5b85937251b976cf9db38151ea59abbff98771179183488d4614694bff67 \ - --hash=sha256:b74932c6ee35dfc81582f39c792e3a68c9ef9bee8c85f25667d9d05dfadd0daf +pandas-gbq==0.35.0 \ + --hash=sha256:258de481019566611031919997bf9c1ece4ca30a4dd02d3fc3664b251d446182 \ + --hash=sha256:596c908487ef0649a161e86ef272c00c267e581b95dc5ee0dc3518545b33bcfc # via google-cloud-bigquery parsy==2.2 \ --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ @@ -1972,24 +1989,24 @@ 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.9.6 \ + --hash=sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a \ + --hash=sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917 # via snowflake-connector-python pluggy==1.6.0 \ --hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \ --hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # via hatchling -prometheus-client==0.24.1 \ - --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ - --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 +prometheus-client==0.25.0 \ + --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ + --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 # via feast (pyproject.toml) propcache==0.4.1 \ --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ @@ -2185,57 +2202,57 @@ psycopg-pool==3.3.0 \ --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 # 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 @@ -2264,141 +2281,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.3 \ + --hash=sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927 \ + --hash=sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d # 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.3 \ + --hash=sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba \ + --hash=sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35 \ + --hash=sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4 \ + --hash=sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505 \ + --hash=sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7 \ + --hash=sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8 \ + --hash=sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4 \ + --hash=sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37 \ + --hash=sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25 \ + --hash=sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022 \ + --hash=sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1 \ + --hash=sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7 \ + --hash=sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c \ + --hash=sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3 \ + --hash=sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb \ + --hash=sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3 \ + --hash=sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976 \ + --hash=sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c \ + --hash=sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab \ + --hash=sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa \ + --hash=sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6 \ + --hash=sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396 \ + --hash=sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c \ + --hash=sha256:3d08782c4045f90724b44c95d35ebec0d67edb8a957a2ac81d5a8e4b8a200495 \ + --hash=sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c \ + --hash=sha256:4335e87c7afa436a0dfa899e138d57a72f8aad542e2cf19c36fb428461caabd0 \ + --hash=sha256:4b068543bdb707f5d935dab765d99227aa2545ef2820935f2e5dd801795c7dbd \ + --hash=sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf \ + --hash=sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531 \ + --hash=sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5 \ + --hash=sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda \ + --hash=sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d \ + --hash=sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e \ + --hash=sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df \ + --hash=sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6 \ + --hash=sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c \ + --hash=sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13 \ + --hash=sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536 \ + --hash=sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287 \ + --hash=sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0 \ + --hash=sha256:68ef2f623dda6d5a9067ac014e406c020c780b2a358930a7e5c1b73702900720 \ + --hash=sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050 \ + --hash=sha256:6dff8cc884679df229ebc6d8eb2321ea6f8e091bc7d4886d4dc2e0e71452843c \ + --hash=sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1 \ + --hash=sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8 \ + --hash=sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0 \ + --hash=sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374 \ + --hash=sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807 \ + --hash=sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6 \ + --hash=sha256:831eb19aa789a97356979e94c981e5667759301fb708d1c0d5adf1bc0098b873 \ + --hash=sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57 \ + --hash=sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f \ + --hash=sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c \ + --hash=sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad \ + --hash=sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e \ + --hash=sha256:91249bcb7c165c2fb2a2f852dbc5c91636e2e218e75d96dfdd517e4078e173dd \ + --hash=sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23 \ + --hash=sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46 \ + --hash=sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1 \ + --hash=sha256:99421e7684a60f7f3550a1d159ade5fdff1954baedb6bdd407cba6a307c9f27d \ + --hash=sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1 \ + --hash=sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee \ + --hash=sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c \ + --hash=sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874 \ + --hash=sha256:9f247596366f4221af52beddd65af1218797771d6989bc891a0b86ccaa019168 \ + --hash=sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a \ + --hash=sha256:a35cc284c8dd7edae8a31533713b4d2467dfe7c4f1b5587dd4031f28f90d1d13 \ + --hash=sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f \ + --hash=sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a \ + --hash=sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789 \ + --hash=sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe \ + --hash=sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f \ + --hash=sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5 \ + --hash=sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943 \ + --hash=sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b \ + --hash=sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089 \ + --hash=sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b \ + --hash=sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff \ + --hash=sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67 \ + --hash=sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803 \ + --hash=sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045 \ + --hash=sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8 \ + --hash=sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346 \ + --hash=sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2 \ + --hash=sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f \ + --hash=sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687 \ + --hash=sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76 \ + --hash=sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1 \ + --hash=sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f \ + --hash=sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2 \ + --hash=sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c \ + --hash=sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018 \ + --hash=sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba \ + --hash=sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c \ + --hash=sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf \ + --hash=sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7 \ + --hash=sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47 \ + --hash=sha256:d56bdb4af1767cc15b0386b3c581fdfe659bb9ee4a4f776e92c1cd9d074000d6 \ + --hash=sha256:dcda6583921c05a40533f982321532f2d8db29326c7b95c4026941fa5074bd79 \ + --hash=sha256:dd81f6907932ebac3abbe41378dac64b2380db1287e2aa64d8d88f78d170f51a \ + --hash=sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e \ + --hash=sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a \ + --hash=sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34 \ + --hash=sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b \ + --hash=sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85 \ + --hash=sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca \ + --hash=sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f \ + --hash=sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3 \ + --hash=sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64 \ + --hash=sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22 \ + --hash=sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72 \ + --hash=sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec \ + --hash=sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d \ + --hash=sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3 \ + --hash=sha256:fa3eb7c2995aa443687a825bc30395c8521b7c6ec201966e55debfd1128bcceb \ + --hash=sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395 \ + --hash=sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb \ + --hash=sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4 \ + --hash=sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127 \ + --hash=sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56 # via pydantic -pydantic-settings==2.13.1 \ - --hash=sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025 \ - --hash=sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237 +pydantic-settings==2.14.0 \ + --hash=sha256:24285fd4b0e0c06507dd9fdfd331ee23794305352aaec8fc4eb92d4047aeb67d \ + --hash=sha256:fc8d5d692eb7092e43c8647c1c35a3ecd00e040fcf02ed86f4cb5458ca62182e # via # fastapi-mcp # mcp @@ -2424,13 +2440,13 @@ pymilvus==2.5.18 \ --hash=sha256:1b78badcfa8d62db7d0b29193fc0422e4676873ff1c745a9d75c2c885d7a7e32 \ --hash=sha256:9e517076068e98dac51c018bc0dfe1f651d936154e2e2d9ad6c7b3dab1164e2d # via feast (pyproject.toml) -pymysql==1.1.2 \ - --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ - --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 +pymysql==1.1.3 \ + --hash=sha256:8164ba62c552f6105f3b11753352d0f16b90d1703ba67d81923d5a8a5d1c5289 \ + --hash=sha256:e70ebf2047a4edf6138cf79c68ad418ef620af65900aa585c5e8bfc95044d43a # via feast (pyproject.toml) -pyopenssl==26.0.0 \ - --hash=sha256:df94d28498848b98cc1c0ffb8ef1e71e40210d3b0a8064c9d29571ed2904bf81 \ - --hash=sha256:f293934e52936f2e3413b89c6ce36df66a0b34ae1ea3a053b8c5020ff2f513fc +pyopenssl==26.1.0 \ + --hash=sha256:115563879b2c8ccb207975705d3e491434d8c9d7c79667c902ecbf5f3bbd2ece \ + --hash=sha256:737f0a2275c5bc54f3b02137687e1a765931fb3949b9a92a825e4d33b9eec08b # via snowflake-connector-python pyproject-metadata==0.11.0 \ --hash=sha256:85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 \ @@ -2453,9 +2469,9 @@ python-dotenv==1.2.2 \ # pydantic-settings # pymilvus # uvicorn -python-multipart==0.0.22 \ - --hash=sha256:2b2cd894c83d21bf49d702499531c7bafd057d730c201782048f7945d82de155 \ - --hash=sha256:7340bef99a7e0032613f56dc36027b959fd3b30a787ed62d310e951f7c3a3a58 +python-multipart==0.0.27 \ + --hash=sha256:6fccfad17a27334bd0193681b369f476eda3409f17381a2d65aa7df3f7275645 \ + --hash=sha256:9870a6a8c5a20a5bf4f07c017bd1489006ff8836cff097b6933355ee2b49b602 # via mcp pytz==2026.1.post1 \ --hash=sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1 \ @@ -2542,9 +2558,9 @@ pyyaml==6.0.3 \ # dask # kubernetes # uvicorn -redis==4.6.0 \ - --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ - --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c +redis==7.4.0 \ + --hash=sha256:64a6ea7bf567ad43c964d2c30d82853f8df927c5c9017766c55a1d1ed95d18ad \ + --hash=sha256:a9c74a5c893a5ef8455a5adb793a31bb70feb821c86eccb62eebef5a19c429ec # via feast (pyproject.toml) referencing==0.37.0 \ --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ @@ -2571,9 +2587,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 @@ -2795,78 +2811,78 @@ 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.49 \ + --hash=sha256:01146546d84185f12721a1d2ce0c6673451a7894d1460b592d378ca4871a0c72 \ + --hash=sha256:059d7151fff513c53a4638da8778be7fce81a0c4854c7348ebd0c4078ddf28fe \ + --hash=sha256:0c98c59075b890df8abfcc6ad632879540f5791c68baebacb4f833713b510e75 \ + --hash=sha256:0f2fa354ba106eafff2c14b0cc51f22801d1e8b2e4149342023bd6f0955de5f5 \ + --hash=sha256:12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148 \ + --hash=sha256:22d8798819f86720bc646ab015baff5ea4c971d68121cb36e2ebc2ee43ead2b7 \ + --hash=sha256:233088b4b99ebcbc5258c755a097aa52fbf90727a03a5a80781c4b9c54347a2e \ + --hash=sha256:24bd94bb301ec672d8f0623eba9226cc90d775d25a0c92b5f8e4965d7f3a1518 \ + --hash=sha256:275424295f4256fd301744b8f335cff367825d270f155d522b30c7bf49903ee7 \ + --hash=sha256:32fe6a41ad97302db2931f05bb91abbcc65b5ce4c675cd44b972428dd2947700 \ + --hash=sha256:334edbcff10514ad1d66e3a70b339c0a29886394892490119dbb669627b17717 \ + --hash=sha256:3bb9ec6436a820a4c006aad1ac351f12de2f2dbdaad171692ee457a02429b672 \ + --hash=sha256:3ddcb27fb39171de36e207600116ac9dfd4ae46f86c82a9bf3934043e80ebb88 \ + --hash=sha256:42e8804962f9e6f4be2cbaedc0c3718f08f60a16910fa3d86da5a1e3b1bfe60f \ + --hash=sha256:43d044780732d9e0381ac8d5316f95d7f02ef04d6e4ef6dc82379f09795d993f \ + --hash=sha256:46796877b47034b559a593d7e4b549aba151dae73f9e78212a3478161c12ab08 \ + --hash=sha256:46d51518d53edfbe0563662c96954dc8fcace9832332b914375f45a99b77cc9a \ + --hash=sha256:47604cb2159f8bbd5a1ab48a714557156320f20871ee64d550d8bf2683d980d3 \ + --hash=sha256:4bbccb45260e4ff1b7db0be80a9025bb1e6698bdb808b83fff0000f7a90b2c0b \ + --hash=sha256:4d4e5a0ceba319942fa6b585cf82539288a61e314ef006c1209f734551ab9536 \ + --hash=sha256:55250fe61d6ebfd6934a272ee16ef1244e0f16b7af6cd18ab5b1fc9f08631db0 \ + --hash=sha256:566df36fd0e901625523a5a1835032f1ebdd7f7886c54584143fa6c668b4df3b \ + --hash=sha256:57ca426a48eb2c682dae8204cd89ea8ab7031e2675120a47924fabc7caacbc2a \ + --hash=sha256:5e61abbec255be7b122aa461021daa7c3f310f3e743411a67079f9b3cc91ece3 \ + --hash=sha256:618a308215b6cececb6240b9abde545e3acdabac7ae3e1d4e666896bf5ba44b4 \ + --hash=sha256:62557958002b69699bdb7f5137c6714ca1133f045f97b3903964f47db97ea339 \ + --hash=sha256:6270d717b11c5476b0cbb21eedc8d4dbb7d1a956fd6c15a23e96f197a6193158 \ + --hash=sha256:685e93e9c8f399b0c96a624799820176312f5ceef958c0f88215af4013d29066 \ + --hash=sha256:69469ce8ce7a8df4d37620e3163b71238719e1e2e5048d114a1b6ce0fbf8c662 \ + --hash=sha256:6eb188b84269f357669b62cb576b5b918de10fb7c728a005fa0ebb0b758adce1 \ + --hash=sha256:74ab4ee7794d7ed1b0c37e7333640e0f0a626fc7b398c07a7aef52f484fddde3 \ + --hash=sha256:77641d299179c37b89cf2343ca9972c88bb6eef0d5fc504a2f86afd15cd5adf5 \ + --hash=sha256:7c821c47ecfe05cc32140dcf8dc6fd5d21971c86dbd56eabfe5ba07a64910c01 \ + --hash=sha256:7d6be30b2a75362325176c036d7fb8d19e8846c77e87683ffaa8177b35135613 \ + --hash=sha256:7f605a456948c35260e7b2a39f8952a26f077fd25653c37740ed186b90aaa68a \ + --hash=sha256:83101a6930332b87653886c01d1ee7e294b1fe46a07dd9a2d2b4f91bcc88eec0 \ + --hash=sha256:88690f4e1f0fbf5339bedbb127e240fec1fd3070e9934c0b7bef83432f779d2f \ + --hash=sha256:8a97ac839c2c6672c4865e48f3cbad7152cee85f4233fb4ca6291d775b9b954a \ + --hash=sha256:8d6efc136f44a7e8bc8088507eaabbb8c2b55b3dbb63fe102c690da0ddebe55e \ + --hash=sha256:8e20e511dc15265fb433571391ba313e10dd8ea7e509d51686a51313b4ac01a2 \ + --hash=sha256:951d4a210744813be63019f3df343bf233b7432aadf0db54c75802247330d3af \ + --hash=sha256:9ac7a3e245fd0310fd31495eb61af772e637bdf7d88ee81e7f10a3f271bff014 \ + --hash=sha256:9b1c058c171b739e7c330760044803099c7fff11511e3ab3573e5327116a9c33 \ + --hash=sha256:9c04bff9a5335eb95c6ecf1c117576a0aa560def274876fd156cfe5510fccc61 \ + --hash=sha256:9c4969a86e41454f2858256c39bdfb966a20961e9b58bf8749b65abf447e9a8d \ + --hash=sha256:9e0400fa22f79acc334d9a6b185dc00a44a8e6578aa7e12d0ddcd8434152b187 \ + --hash=sha256:a05977bffe9bffd2229f477fa75eabe3192b1b05f408961d1bebff8d1cd4d401 \ + --hash=sha256:a143af2ea6672f2af3f44ed8f9cd020e9cc34c56f0e8db12019d5d9ecf41cb3b \ + --hash=sha256:a51d3db74ba489266ef55c7a4534eb0b8db9a326553df481c11e5d7660c8364d \ + --hash=sha256:b95b2f470c1b2683febd2e7eab1d3f0e078c91dbdd0b00e9c645d07a413bb99f \ + --hash=sha256:b9870d15ef00e4d0559ae10ee5bc71b654d1f20076dbe8bc7ed19b4c0625ceba \ + --hash=sha256:c1dc3368794d522f43914e03312202523cc89692f5389c32bea0233924f8d977 \ + --hash=sha256:c338ec6ec01c0bc8e735c58b9f5d51e75bacb6ff23296658826d7cfdfdb8678a \ + --hash=sha256:c5070135e1b7409c4161133aa525419b0062088ed77c92b1da95366ec5cbebbe \ + --hash=sha256:cc992c6ed024c8c3c592c5fc9846a03dd68a425674900c70122c77ea16c5fb0b \ + --hash=sha256:d15950a57a210e36dd4cec1aac22787e2a4d57ba9318233e2ef8b2daf9ff2d5f \ + --hash=sha256:d898cc2c76c135ef65517f4ddd7a3512fb41f23087b0650efb3418b8389a3cd1 \ + --hash=sha256:d99945830a6f3e9638d89a28ed130b1eb24c91255e4f24366fbe699b983f29e4 \ + --hash=sha256:da9b91bca419dc9b9267ffadde24eae9b1a6bffcd09d0a207e5e3af99a03ce0d \ + --hash=sha256:df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120 \ + --hash=sha256:e06e617e3d4fd9e51d385dfe45b077a41e9d1b033a7702551e3278ac597dc750 \ + --hash=sha256:ec44cfa7ef1a728e88ad41674de50f6db8cfdb3e2af84af86e0041aaf02d43d0 \ + --hash=sha256:fb37f15714ec2652d574f021d479e78cd4eb9d04396dca36568fdfffb3487982 # via feast (pyproject.toml) -sqlglot==30.2.1 \ - --hash=sha256:ef4a67cc6f66a8043085eb8ea95fa9541c1625dffa9145ad4e9815a7ba60a199 \ - --hash=sha256:f23d9ee9427ef9d20df15f9b0ffa57d9eb45e52b012219a349d1e6b50ed926d1 +sqlglot==30.6.0 \ + --hash=sha256:246d34d39927422a50a3fa155f37b2f6346fba85f1a755b13c941eb32ef93361 \ + --hash=sha256:e005fc2f47994f90d7d8df341f1cbe937518497b0b7b1507d4c03c4c9dfd2778 # via ibis-framework -sse-starlette==3.3.4 \ - --hash=sha256:84bb06e58939a8b38d8341f1bc9792f06c2b53f48c608dd207582b664fc8f3c1 \ - --hash=sha256:aaf92fc067af8a5427192895ac028e947b484ac01edbc3caf00e7e7137c7bef1 +sse-starlette==3.4.1 \ + --hash=sha256:6b43cf21f1d574d582a6e1b0cfbde1c94dc86a32a701a7168c99c4475c6bd1d0 \ + --hash=sha256:f780bebcf6c8997fe514e3bd8e8c648d8284976b391c8bed0bcb1f611632b555 # via mcp starlette==1.0.0 \ --hash=sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149 \ @@ -2953,25 +2969,25 @@ tqdm==4.67.3 \ # via # feast (pyproject.toml) # milvus-lite -trove-classifiers==2026.1.14.14 \ - --hash=sha256:00492545a1402b09d4858605ba190ea33243d361e2b01c9c296ce06b5c3325f3 \ - --hash=sha256:1f9553927f18d0513d8e5ff80ab8980b8202ce37ecae0e3274ed2ef11880e74d +trove-classifiers==2026.4.28.13 \ + --hash=sha256:8f4b1eb4e16296b57d612965444f87a83861cc989a0451ac97fe4265ddef03b8 \ + --hash=sha256:c85bb8a53c3de7330d1699b844ed9fb809a602a09ac15dc79ad6d1a509be0676 # via hatchling typeguard==4.5.1 \ --hash=sha256:44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40 \ --hash=sha256:f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274 # via feast (pyproject.toml) -typer==0.24.1 \ - --hash=sha256:112c1f0ce578bfb4cab9ffdabc68f031416ebcc216536611ba21f04e9aa84c9e \ - --hash=sha256:e39b4732d65fbdcde189ae76cf7cd48aeae72919dea1fdfc16593be016256b45 +typer==0.25.1 \ + --hash=sha256:75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89 \ + --hash=sha256:9616eb8853a09ffeabab1698952f33c6f29ffdbceb4eaeecf571880e8d7664cc # 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.20260408 \ + --hash=sha256:b784dc37908479e3767e2d794ab507b3674adb1c686ca3d13fc9e2960dbcb9ec \ + --hash=sha256:da630647eaaa7a926a3907794f4067f269cd245b2c202c74aa3c6a3bd660a9db # via feast (pyproject.toml) typing-extensions==4.15.0 \ --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ @@ -3002,9 +3018,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 # ibis-framework # pandas diff --git a/sdk/python/requirements/py3.12-requirements.txt b/sdk/python/requirements/py3.12-requirements.txt index bd0810289bc..de90b34c05d 100644 --- a/sdk/python/requirements/py3.12-requirements.txt +++ b/sdk/python/requirements/py3.12-requirements.txt @@ -24,9 +24,9 @@ bigtree==1.4.0 \ --hash=sha256:d0d99550ae64ce4529f132602ab875c2ab472c96c942f5704f8c72a17450d3ea \ --hash=sha256:e5ae2e948168da671d99601c9ed87ab3b48d9d4ea8a98f111e5748e98064c31c # via feast (pyproject.toml) -certifi==2026.2.25 \ - --hash=sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa \ - --hash=sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7 +certifi==2026.4.22 \ + --hash=sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a \ + --hash=sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580 # via requests charset-normalizer==3.4.7 \ --hash=sha256:007d05ec7321d12a40227aae9e2bc6dca73f3cb21058999a1df9e193555a9dcc \ @@ -159,9 +159,9 @@ charset-normalizer==3.4.7 \ --hash=sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79 \ --hash=sha256:fea24543955a6a729c45a73fe90e08c743f0b3334bbf3201e6c4bc1b0c7fa464 # via requests -click==8.3.1 \ - --hash=sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a \ - --hash=sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6 +click==8.3.3 \ + --hash=sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2 \ + --hash=sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613 # via # feast (pyproject.toml) # dask @@ -182,13 +182,13 @@ dill==0.3.9 \ --hash=sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a \ --hash=sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c # via feast (pyproject.toml) -fastapi==0.135.3 \ - --hash=sha256:9b0f590c813acd13d0ab43dd8494138eb58e484bfac405db1f3187cfc5810d98 \ - --hash=sha256:bd6d7caf1a2bdd8d676843cdcd2287729572a1ef524fc4d65c17ae002a1be654 +fastapi==0.136.1 \ + --hash=sha256:7af665ad7acfa0a3baf8983d393b6b471b9da10ede59c60045f49fbc89a0fa7f \ + --hash=sha256:a6e9d7eeada96c93a4d69cb03836b44fa34e2854accb7244a1ece36cd4781c3f # via feast (pyproject.toml) -fsspec==2026.3.0 \ - --hash=sha256:1ee6a0e28677557f8c2f994e3eea77db6392b4de9cd1f5d7a9e87a0ae9d01b41 \ - --hash=sha256:d2ceafaad1b3457968ed14efa28798162f1638dbb5d2a6868a2db002a5ee39a4 +fsspec==2026.4.0 \ + --hash=sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2 \ + --hash=sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4 # via dask gunicorn==25.3.0 \ --hash=sha256:cacea387dab08cd6776501621c295a904fe8e3b7aae9a1a3cbb26f4e7ed54660 \ @@ -245,9 +245,9 @@ httptools==0.7.1 \ --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 # via uvicorn -idna==3.11 \ - --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ - --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 +idna==3.13 \ + --hash=sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242 \ + --hash=sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 # via # anyio # requests @@ -263,97 +263,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.9.0 \ + --hash=sha256:07cf11f769831186eeac424376e6189f20ace4f7263e2134bdb9757340d84d4d \ + --hash=sha256:0a09c2f5869649101738653a9b7ab70cf045a1105ac66cbb8f4055e61df78f2d \ + --hash=sha256:0a1be03168b2691ba61927e299b352a6315189199ca18a57b733f86cb3cc8d38 \ + --hash=sha256:0b73e4266307e51c95e09c0750b7ec383c561d2e97d58e473f6f6a209952fbb8 \ + --hash=sha256:15cb151e52a044f06e54ac7f7b47adbfc89b5c8e2b63e1175a9d587c43e8942a \ + --hash=sha256:194fc1a32e1e21fe809d38b5faea66cc65eaa00217c8901fbdb99866938adbdb \ + --hash=sha256:1bf465d1e5b0a27713862441f6467b5ab76385f4ecf8f1f3a44f8aa3c695b4b6 \ + --hash=sha256:1c587494461ebd42229d0f1739f3aa34237dd9980623ecf1be8d3bcba79f4499 \ + --hash=sha256:224b9727eb8bc188bc3bcf29d969dba0cd61b01d9bac80c41575520cc4baabb2 \ + --hash=sha256:22a904cbdb678f7cb348c90d543d3c52f581663d687992fee47fd566dcbf5285 \ + --hash=sha256:2b8f5d00b49818f4e2b1667db994488b045835e0ac16fe2f924f3871bd2b8ac5 \ + --hash=sha256:2c3786f0f4490a5cd87f1ed6cefae833ad6b1060d52044ce0434a2e85893afd0 \ + --hash=sha256:2d03fa4fd277a7974c1978c92c374c57f44edeee163d147b477b143446ad1bf6 \ + --hash=sha256:2f8e12706dcb8ff6b3ed57514a19e45c49ad00bcd423e87b2b2e4b5f64578443 \ + --hash=sha256:3be322a15ee5e70b93b7a59cfd074614f22cc8c9ff18bd27f474e79137ea8d3b \ + --hash=sha256:3cc2917258e131ae5f958a4d872e07555b51cb7466a43433218061c74ef33745 \ + --hash=sha256:3f05d145df35dca5056a8bc3838e940efebd893a54b3e19b2dda39ceaa299bcb \ + --hash=sha256:3fe56e80badb66fdcde06bef81bbaa5bfcf6fbd7aefb86222d9e369c38c6b228 \ + --hash=sha256:42ff8a962554c350d4a83cf47d9b7b78b0e6ff7943e87df7cdfc97c07f3c016f \ + --hash=sha256:451daa98463b7695b0a30aa56bf637831ea559e7b8101ac2ef6382e8eb15e29c \ + --hash=sha256:465814ab157986acb9dfa5ccd7df944be5eefc0d08d31ec6e8d88bc71251d845 \ + --hash=sha256:4c4d0440a3a8e31d962340c3e1cc3fc9ee7febd34c8d8f770d06adb947779ea5 \ + --hash=sha256:4e3dda8345307fd7306db0ed0cb109a63a2c85ba780eb9dc2d09b2049a931f9c \ + --hash=sha256:5093043afb226ecfa1400120d1ebd4442b4f99977783e4f4f7248879009b227f \ + --hash=sha256:5112c2fb7c2eefefaeaf5c97fec81343ef44ee86a30dcfaa8223822fba6467b4 \ + --hash=sha256:527b5b820b47a09e09829051452bb0d1dd2122261254e2a6f674d12f1d793d54 \ + --hash=sha256:54d412e47c21b85865676ed0724e37a89e9593c2eee1e7367adf85bfad56ffb1 \ + --hash=sha256:56d65b583cf43b8cf4c8fbe1e1da20fa3076cc32a1149a141507af1062718236 \ + --hash=sha256:5ca8e133d799c948db2ab1afc081c333a825b5540475164726dcbf73537e5c2f \ + --hash=sha256:603138ee838ee1583f1b960b62d5d0007845c5c423feb68e44648b1359014e27 \ + --hash=sha256:63c12efcd160e1d14da11af0c46c0217473e1e0d2ae1acbccc83f561ea4c2a7b \ + --hash=sha256:657f8ba7b9eaaa82759a104137aed2a3ef7bc46ccfd43e0d89b04005b3e0a4cc \ + --hash=sha256:66b58fed90a545328e80d575467244de3741e088c1af928f0b489ebec3ef3858 \ + --hash=sha256:6788207daa0c19955d2b668f3294a368d19f67d9b5f274553fd073c1260cbb9f \ + --hash=sha256:703f4ae36d6240bfe24f542bac784c7e4194ec49c3ba5a994d02891649e2d85b \ + --hash=sha256:7202bdcac47d3a708271c4304a474a8605a4a9a4a709e954bf2d3241140aa938 \ + --hash=sha256:756775d25ec8345b837ab52effee3ad2f3b2dfd6bbee3e3f029c517bd5d8f05a \ + --hash=sha256:78042f6facfd98ecb25e9829c7e37cce23363d9d7c83bc5f72702c5059eb082b \ + --hash=sha256:789fff71757facc0738e8d89e3b84e4f0251c1c975e85e81b152cdaca927cc2d \ + --hash=sha256:7bc30ad339f4e1a01d4917d645e522a0bc0030644d8973f6346397c93ba1503f \ + --hash=sha256:7d429bdd4ac0ab17c8e4a8af0ed2a7440b16eba474909ab357131018fe8c7e71 \ + --hash=sha256:7d5c8a5929ac325729f6119802070b561f4db793dffc45e9ac750992a4ed4d22 \ + --hash=sha256:7e6274fd33fc5b2a14d41c9119629d3ff395849d8bcbc80cf637d9e8d2034da8 \ + --hash=sha256:80b25c7b570a86c03b5da69e665809deb39265476e8e21d96a9328f9762f9990 \ + --hash=sha256:81107843ed1836874b46b310f9b1816abcb89912af627868522461c3b7333c0f \ + --hash=sha256:8494cfc61e03542f2d381e71804990b3931175a29b9278fdb4a5459948778dc2 \ + --hash=sha256:850d6d03177e52700af605fd60db7f37dcb89782049a149674d1a9649c2138fd \ + --hash=sha256:8c6bc1384d9738781cfd41d09ad7f6e8af13cfea2c75ece6bd6d2566cdea2076 \ + --hash=sha256:90904fac73c478f4b83f4ed96c99c8208b75e6f9a8a1910548f69a00f1eaa671 \ + --hash=sha256:90e6d5420fc8a300518d4d2288154ff45005e920425c22cbbfe8330f3f754bd9 \ + --hash=sha256:928bd06eca2c2bbf4349e5b817f837509b0604342e65a502de1d50a7570afd15 \ + --hash=sha256:9b3e3bc363f71bda1639a4ee593cb78f7fbfeacc73411ec0d4c92f00730010a4 \ + --hash=sha256:9edcc35d1cae9fd5320171b1a838c7da8a5c968af31e82ecc3dff30b4be0957f \ + --hash=sha256:9fcb461fbf70654a52a7cc670e606f04449e2374c199b1825f754e16dacfedd8 \ + --hash=sha256:a0951822531e7aee6e0dfb556b30d5ee36bbe234faf60c20a16c01be3530869d \ + --hash=sha256:a361c9434a64d70a7dbb771d1de302c0cc9f13c0bffe1cf7e642152814b35265 \ + --hash=sha256:a4b25c6c25cac5d0d9d6d6da855195b254e0021e513e0249f0e3b444dc6e0e61 \ + --hash=sha256:a5af136bfba820d592f86c67affcef9b3ff4d4360ac3255e341e964489b48519 \ + --hash=sha256:a81eea9b999b985e4bacc650c4312805ea7008fd5e45e1bf221310176a7bcb3a \ + --hash=sha256:a9c63e04d003bc0fb6a03b348018b9a3002f98268200e22cc80f146beac5dc40 \ + --hash=sha256:aa95738a68cedd3a6f5492feddc513e2e166b50602958139e47bbdd82da0f5a7 \ + --hash=sha256:b0a2040f801406b93657a70b72fa12311063a319fee72ce98e1524da7200171f \ + --hash=sha256:b8bd70d5d816566a580d193326912f4a76ec2d28a97dc4cd4cc831c0af8e330e \ + --hash=sha256:b8da9f8035bb417770b1e1610526d87ad4fc58a2804dc4d79c53f6d2cf5a6eb9 \ + --hash=sha256:bc5518873822d2faa8ebdd2c1a4d7c8ef47b01a058495ab7924cb65bdbf5fc9a \ + --hash=sha256:c0d620e74897f8c2613b3c4e2e9c1e422eb46d2ddd07df540784d44117836af3 \ + --hash=sha256:c2640e23d2b7c98796f123ffd95cf2022c7777aa8a4a3b98b36c570d37e85eee \ + --hash=sha256:c81aef782380f0f13ead670aae01825eb653b44b046aa0e5ebbb79f76ed4aa11 \ + --hash=sha256:d4d16b608a1c43d7e33142099a75cd93af482dadce0bf82421e91cad077157f4 \ + --hash=sha256:d69fc39e627908f4c03297d5a88d9284b73f4d90b424461e32e8c2485e21c283 \ + --hash=sha256:d9da80e5b04acce03ced8ba6479a71c2a2edf535c2acc0d09c80d2f80f3bad15 \ + --hash=sha256:dd2c7e082b0b92e1baa4da28163a808672485617bc855cc22a2fd06978fa9084 \ + --hash=sha256:de7dac64e3eb832ffc7b840eb8f52f76420cde1b845be51b2a0f6b870890645e \ + --hash=sha256:e0785c2fb4a81e1aece366aa3e2e039f4a4d7d21aaaded5227d7f3c703427882 \ + --hash=sha256:e306d956cfa027fe041585f02a1602c32bfa6bb8ebea4899d373383295a6c62f \ + --hash=sha256:e78fb7419e07d98c2af4b8567b72b3eaf8cb05caad642e9963465569c8b2d87e \ + --hash=sha256:e9002e98dcb1c0a66723592520decd86238ddcef168b37ff6cfb559200b4b774 \ + --hash=sha256:e94cbc6ad9a6aeea46d775cbb11f361022f778a9cc8cc90af653d3a594b057ce \ + --hash=sha256:eea1b54943475f51698f85fa230c65ccac769f1e603b981be060ac5763d90927 \ + --hash=sha256:f100bfe2acf8a3689af9d0cc660d89f17286c9c795f9f18f7b62dd1a6b247ae6 \ + --hash=sha256:f162af66a2ed3f7d1d161a82ca584efd15acd9c1cff190a373458c32f7d42118 \ + --hash=sha256:f24b90b0e0c8cc9491fb1693ae91fe17cb7963153a1946395acdbdd5818429a4 \ + --hash=sha256:f29b68cd9714531672db62cc54f6e8ff981900f824d13fa0e00749189e13778e \ + --hash=sha256:f38bc489037eca88d6ebefc9c4d41a4e07c8e8b4de5188a9e6d290273ad7ebb1 \ + --hash=sha256:f3fd278f5e6bf7c75ccd6d12344eb686cc020712683363b66f46ac79d37c799f \ + --hash=sha256:f4003f70c56a5addd6aa0897f200dd59afd3bf7bcd5b3cce46dd21f925743bc2 \ + --hash=sha256:f48c963a76d71b9d7927eb817b543d0dccd52ab6648b99d37bd54f4cd475d856 \ + --hash=sha256:f819e0c6413e259a17a7c0d49f97f405abadd3c2a316a3b46c6440b7dbbedbb1 \ + --hash=sha256:fc5758e2b7a56532dc33e3c544d78cbaa9ecf0a0f2a2da2df882c1d6b99a317f \ + --hash=sha256:fcbdf2a9ca24e87bbebb47f1fe34e531ef06f104f98c9ccfc953a3f3344c567a # via mypy locket==1.0.0 \ --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ @@ -559,51 +559,51 @@ mmh3==5.2.1 \ --hash=sha256:fceef7fe67c81e1585198215e42ad3fdba3a25644beda8fbdaf85f4d7b93175a \ --hash=sha256:fd96476f04db5ceba1cfa0f21228f67c1f7402296f0e73fee3513aa680ad237b # via feast (pyproject.toml) -mypy==1.20.0 \ - --hash=sha256:002b613ae19f4ac7d18b7e168ffe1cb9013b37c57f7411984abbd3b817b0a214 \ - --hash=sha256:00e047c74d3ec6e71a2eb88e9ea551a2edb90c21f993aefa9e0d2a898e0bb732 \ - --hash=sha256:02cca0761c75b42a20a2757ae58713276605eb29a08dd8a6e092aa347c4115ca \ - --hash=sha256:0ecd63f75fdd30327e4ad8b5704bd6d91fc6c1b2e029f8ee14705e1207212489 \ - --hash=sha256:0f42dfaab7ec1baff3b383ad7af562ab0de573c5f6edb44b2dab016082b89948 \ - --hash=sha256:1973868d2adbb4584a3835780b27436f06d1dc606af5be09f187aaa25be1070f \ - --hash=sha256:26c8b52627b6552f47ff11adb4e1509605f094e29815323e487fc0053ebe93d1 \ - --hash=sha256:2721f0ce49cb74a38f00c50da67cb7d36317b5eda38877a49614dc018e91c787 \ - --hash=sha256:2fcedb16d456106e545b2bfd7ef9d24e70b38ec252d2a629823a4d07ebcdb69e \ - --hash=sha256:31b5dbb55293c1bd27c0fc813a0d2bb5ceef9d65ac5afa2e58f829dab7921fd5 \ - --hash=sha256:34506397dbf40c15dc567635d18a21d33827e9ab29014fb83d292a8f4f8953b6 \ - --hash=sha256:367e5c993ba34d5054d11937d0485ad6dfc60ba760fa326c01090fc256adf15c \ - --hash=sha256:379edf079ce44ac8d2805bcf9b3dd7340d4f97aad3a5e0ebabbf9d125b84b442 \ - --hash=sha256:39362cdb4ba5f916e7976fccecaab1ba3a83e35f60fa68b64e9a70e221bb2436 \ - --hash=sha256:4525e7010b1b38334516181c5b81e16180b8e149e6684cee5a727c78186b4e3b \ - --hash=sha256:47781555a7aa5fedcc2d16bcd72e0dc83eb272c10dd657f9fb3f9cc08e2e6abb \ - --hash=sha256:49d11c6f573a5a08f77fad13faff2139f6d0730ebed2cfa9b3d2702671dd7188 \ - --hash=sha256:555493c44a4f5a1b58d611a43333e71a9981c6dbe26270377b6f8174126a0526 \ - --hash=sha256:555658c611099455b2da507582ea20d2043dfdfe7f5ad0add472b1c6238b433f \ - --hash=sha256:697f102c5c1d526bdd761a69f17c6070f9892eebcb94b1a5963d679288c09e78 \ - --hash=sha256:76a70bf840495729be47510856b978f1b0ec7d08f257ca38c9d932720bf6b43e \ - --hash=sha256:7d3243c406773185144527f83be0e0aefc7bf4601b0b2b956665608bf7c98a83 \ - --hash=sha256:931a7630bba591593dcf6e97224a21ff80fb357e7982628d25e3c618e7f598ef \ - --hash=sha256:9804c3ad27f78e54e58b32e7cb532d128b43dbfb9f3f9f06262b821a0f6bd3f5 \ - --hash=sha256:a17c5d0bdcca61ce24a35beb828a2d0d323d3fcf387d7512206888c900193367 \ - --hash=sha256:a6e0641147cbfa7e4e94efdb95c2dab1aff8cfc159ded13e07f308ddccc8c48e \ - --hash=sha256:a79c1eba7ac4209f2d850f0edd0a2f8bba88cbfdfefe6fb76a19e9d4fe5e71a2 \ - --hash=sha256:a9336b5e6712f4adaf5afc3203a99a40b379049104349d747eb3e5a3aa23ac2e \ - --hash=sha256:b20c8b0fd5877abdf402e79a3af987053de07e6fb208c18df6659f708b535134 \ - --hash=sha256:b3a49064504be59e59da664c5e149edc1f26c67c4f8e8456f6ba6aba55033018 \ - --hash=sha256:b503ab55a836136b619b5fc21c8803d810c5b87551af8600b72eecafb0059cb0 \ - --hash=sha256:bd0212976dc57a5bfeede7c219e7cd66568a32c05c9129686dd487c059c1b88a \ - --hash=sha256:c70380fe5d64010f79fb863b9081c7004dd65225d2277333c219d93a10dad4dd \ - --hash=sha256:d99f515f95fd03a90875fdb2cca12ff074aa04490db4d190905851bdf8a549a8 \ - --hash=sha256:e80cf77847d0d3e6e3111b7b25db32a7f8762fd4b9a3a72ce53fe16a2863b281 \ - --hash=sha256:eb96c84efcc33f0b5e0e04beacf00129dd963b67226b01c00b9dfc8affb464c3 \ - --hash=sha256:ebea00201737ad4391142808ed16e875add5c17f676e0912b387739f84991e13 \ - --hash=sha256:efe8d70949c3023698c3fca1e94527e7e790a361ab8116f90d11221421cd8726 \ - --hash=sha256:f13b3e41bce9d257eded794c0f12878af3129d80aacd8a3ee0dee51f3a978651 \ - --hash=sha256:f194db59657c58593a3c47c6dfd7bad4ef4ac12dbc94d01b3a95521f78177e33 \ - --hash=sha256:f49590891d2c2f8a9de15614e32e459a794bcba84693c2394291a2038bbaaa69 \ - --hash=sha256:f75ff57defcd0f1d6e006d721ccdec6c88d4f6a7816eb92f1c4890d979d9ee62 \ - --hash=sha256:f799d9db89fc00446f03281f84a221e50018fc40113a3ba9864b132895619ebe \ - --hash=sha256:f8426d4d75d68714abc17a4292d922f6ba2cfb984b72c2278c437f6dae797865 +mypy==1.20.2 \ + --hash=sha256:0c64e5973df366b747646fc98da921f9d6eba9716d57d1db94a83c026a08e0fb \ + --hash=sha256:0deb80d062b2479f2c87ae568f89845afc71d11bc41b04179e58165fd9f31e98 \ + --hash=sha256:1e1c12f6d2db3d78b909b5f77513c11eb7f2dd2782b96a3ab6dffc7d44575c99 \ + --hash=sha256:20175a1c0f49863946ec20b7f63255768058ac4f07d2b9ded6a6b46cfb5a9100 \ + --hash=sha256:29752dbbf8cc53f89f6ac096d363314333045c257c9c75cbd189ca2de0455744 \ + --hash=sha256:2a4102b03bb7481d9a91a6da8d174740c9c8c4401024684b9ca3b7cc5e49852f \ + --hash=sha256:2de3dcea53babc1c3237a19002bc3d228ce1833278f093b8d619e06e7cc79609 \ + --hash=sha256:34397cdced6b90b836e38182076049fdb41424322e0b0728c946b0939ebdf9f6 \ + --hash=sha256:4077797a273e56e8843d001e9dfe4ba10e33323d6ade647ff260e5cd97d9758c \ + --hash=sha256:419413398fe250aae057fd2fe50166b61077083c9b82754c341cf4fd73038f30 \ + --hash=sha256:4b6481b228d072315b053210b01ac320e1be243dc17f9e5887ef167f23f5fae4 \ + --hash=sha256:4dbfcf869f6b0517f70cf0030ba6ea1d6645e132337a7d5204a18d8d5636c02b \ + --hash=sha256:4fef51b01e638974a6e69885687e9bd40c8d1e09a6cd291cca0619625cf1f558 \ + --hash=sha256:52b176444e2e5054dfcbcb8c75b0b719865c96247b37407184bbfca5c353f2c2 \ + --hash=sha256:56908d7e08318d39f85b1f0c6cfd47b0cac1a130da677630dac0de3e0623e102 \ + --hash=sha256:5a65aa591af023864fd08a97da9974e919452cfe19cb146c8a5dc692626445dc \ + --hash=sha256:688c3312e5dadb573a2c69c82af3a298d43ecf9e6d264e0f95df960b5f6ac19c \ + --hash=sha256:6e2b469efd811707bc530fd1effef0f5d6eebcb7fe376affae69025da4b979a2 \ + --hash=sha256:7488448de6007cd5177c6cea0517ac33b4c0f5ee9b5e9f2be51ce75511a85517 \ + --hash=sha256:785b08db19c9f214dc37d65f7c165d19a30fcecb48abfa30f31b01b5acaabb58 \ + --hash=sha256:7b0e817b518bff7facd7f85ea05b643ad8bdcce684cf29784987b0a7c8e1f997 \ + --hash=sha256:803203d2b6ea644982c644895c2f78b28d0e208bba7b27d9b921e0ec5eb207c6 \ + --hash=sha256:89dce27e142d25ffbc154c1819383b69f2e9234dc4ed4766f42e0e8cb264ab5c \ + --hash=sha256:913485a03f1bcf5d279409a9d2b9ed565c151f61c09f29991e5faa14033da4c8 \ + --hash=sha256:97d7b9a485b40f8ca425460e89bf1da2814625b2da627c0dcc6aa46c92631d14 \ + --hash=sha256:9bcb8aa397ff0093c824182fd76a935a9ba7ad097fcbef80ae89bf6c1731d8ec \ + --hash=sha256:9d56a78b646f2e3daa865bc70cd5ec5a46c50045801ca8ff17a0c43abc97e3ee \ + --hash=sha256:a5da6976f20cae27059ea8d0c86e7cef3de720e04c4bb9ee18e3690fdb792066 \ + --hash=sha256:a94c5a76ab46c5e6257c7972b6c8cff0574201ca7dc05647e33e795d78680563 \ + --hash=sha256:a95a9248b0c6fd933a442c03c3b113c3b61320086b88e2c444676d3fd1ca3330 \ + --hash=sha256:baf593f2765fa3a6b1ef95807dbaa3d25b594f6a52adcc506a6b9cb115e1be67 \ + --hash=sha256:bb9c2fa06887e21d6a3a868762acb82aec34e2c6fd0174064f27c93ede68ad15 \ + --hash=sha256:bba9ad231e92a3e424b3e56b65aa17704993425bba97e302c832f9466bb85bac \ + --hash=sha256:c3bae4f855d965b5453784300c12ffc63a548304ac7f99e55d4dc7c898673aa3 \ + --hash=sha256:c566c3a88b6ece59b3d70f65bedef17304f48eb52ff040a6a18214e1917b3254 \ + --hash=sha256:cdecf62abcc4292500d7858aeae87a1f8f1150f4c4dd08fb0b336ee79b2a6df3 \ + --hash=sha256:cf5a4db6dca263010e2c7bff081c89383c72d187ba2cf4c44759aac970e2f0c4 \ + --hash=sha256:d52ad8d78522da1d308789df651ee5379088e77c76cb1994858d40a426b343b9 \ + --hash=sha256:e061b58443f1736f8a37c48978d7ab581636d6ab03e3d4f99e3fa90463bb9382 \ + --hash=sha256:e2877a02380adfcdbc69071a0f74d6e9dbbf593c0dc9d174e1f223ffd5281943 \ + --hash=sha256:e73c07f23009962885c197ccb9b41356a30cc0e5a1d0c2ea8fd8fb1362d7f924 \ + --hash=sha256:e8222c26daaafd9e8626dec58ae36029f82585890589576f769a650dd20fd665 \ + --hash=sha256:edfbfca868cdd6bd8d974a60f8a3682f5565d3f5c99b327640cedd24c4264026 \ + --hash=sha256:f376e37f9bf2a946872fc5fd1199c99310748e3c26c7a26683f13f8bdb756cbd # via sqlalchemy mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ @@ -686,9 +686,9 @@ numpy==2.4.4 \ # feast (pyproject.toml) # dask # pandas -packaging==26.0 \ - --hash=sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4 \ - --hash=sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +packaging==26.2 \ + --hash=sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e \ + --hash=sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661 # via # dask # gunicorn @@ -755,13 +755,13 @@ 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 +prometheus-client==0.25.0 \ + --hash=sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28 \ + --hash=sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1 # via feast (pyproject.toml) protobuf==7.34.1 \ --hash=sha256:34b84ce27680df7cca9f231043ada0daa55d0c44a2ddfaa58ec1d0d89d8bf60a \ @@ -796,188 +796,187 @@ 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.3 \ + --hash=sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927 \ + --hash=sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d # 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.3 \ + --hash=sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba \ + --hash=sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35 \ + --hash=sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4 \ + --hash=sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505 \ + --hash=sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7 \ + --hash=sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8 \ + --hash=sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4 \ + --hash=sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37 \ + --hash=sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25 \ + --hash=sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022 \ + --hash=sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1 \ + --hash=sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7 \ + --hash=sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c \ + --hash=sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3 \ + --hash=sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb \ + --hash=sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3 \ + --hash=sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976 \ + --hash=sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c \ + --hash=sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab \ + --hash=sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa \ + --hash=sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6 \ + --hash=sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396 \ + --hash=sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c \ + --hash=sha256:3d08782c4045f90724b44c95d35ebec0d67edb8a957a2ac81d5a8e4b8a200495 \ + --hash=sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c \ + --hash=sha256:4335e87c7afa436a0dfa899e138d57a72f8aad542e2cf19c36fb428461caabd0 \ + --hash=sha256:4b068543bdb707f5d935dab765d99227aa2545ef2820935f2e5dd801795c7dbd \ + --hash=sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf \ + --hash=sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531 \ + --hash=sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5 \ + --hash=sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda \ + --hash=sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d \ + --hash=sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e \ + --hash=sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df \ + --hash=sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6 \ + --hash=sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c \ + --hash=sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13 \ + --hash=sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536 \ + --hash=sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287 \ + --hash=sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0 \ + --hash=sha256:68ef2f623dda6d5a9067ac014e406c020c780b2a358930a7e5c1b73702900720 \ + --hash=sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050 \ + --hash=sha256:6dff8cc884679df229ebc6d8eb2321ea6f8e091bc7d4886d4dc2e0e71452843c \ + --hash=sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1 \ + --hash=sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8 \ + --hash=sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0 \ + --hash=sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374 \ + --hash=sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807 \ + --hash=sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6 \ + --hash=sha256:831eb19aa789a97356979e94c981e5667759301fb708d1c0d5adf1bc0098b873 \ + --hash=sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57 \ + --hash=sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f \ + --hash=sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c \ + --hash=sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad \ + --hash=sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e \ + --hash=sha256:91249bcb7c165c2fb2a2f852dbc5c91636e2e218e75d96dfdd517e4078e173dd \ + --hash=sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23 \ + --hash=sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46 \ + --hash=sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1 \ + --hash=sha256:99421e7684a60f7f3550a1d159ade5fdff1954baedb6bdd407cba6a307c9f27d \ + --hash=sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1 \ + --hash=sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee \ + --hash=sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c \ + --hash=sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874 \ + --hash=sha256:9f247596366f4221af52beddd65af1218797771d6989bc891a0b86ccaa019168 \ + --hash=sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a \ + --hash=sha256:a35cc284c8dd7edae8a31533713b4d2467dfe7c4f1b5587dd4031f28f90d1d13 \ + --hash=sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f \ + --hash=sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a \ + --hash=sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789 \ + --hash=sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe \ + --hash=sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f \ + --hash=sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5 \ + --hash=sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943 \ + --hash=sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b \ + --hash=sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089 \ + --hash=sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b \ + --hash=sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff \ + --hash=sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67 \ + --hash=sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803 \ + --hash=sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045 \ + --hash=sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8 \ + --hash=sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346 \ + --hash=sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2 \ + --hash=sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f \ + --hash=sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687 \ + --hash=sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76 \ + --hash=sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1 \ + --hash=sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f \ + --hash=sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2 \ + --hash=sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c \ + --hash=sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018 \ + --hash=sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba \ + --hash=sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c \ + --hash=sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf \ + --hash=sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7 \ + --hash=sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47 \ + --hash=sha256:d56bdb4af1767cc15b0386b3c581fdfe659bb9ee4a4f776e92c1cd9d074000d6 \ + --hash=sha256:dcda6583921c05a40533f982321532f2d8db29326c7b95c4026941fa5074bd79 \ + --hash=sha256:dd81f6907932ebac3abbe41378dac64b2380db1287e2aa64d8d88f78d170f51a \ + --hash=sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e \ + --hash=sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a \ + --hash=sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34 \ + --hash=sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b \ + --hash=sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85 \ + --hash=sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca \ + --hash=sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f \ + --hash=sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3 \ + --hash=sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64 \ + --hash=sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22 \ + --hash=sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72 \ + --hash=sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec \ + --hash=sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d \ + --hash=sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3 \ + --hash=sha256:fa3eb7c2995aa443687a825bc30395c8521b7c6ec201966e55debfd1128bcceb \ + --hash=sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395 \ + --hash=sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb \ + --hash=sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4 \ + --hash=sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127 \ + --hash=sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56 # via pydantic pygments==2.20.0 \ --hash=sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f \ @@ -1210,70 +1209,70 @@ 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.49 \ + --hash=sha256:01146546d84185f12721a1d2ce0c6673451a7894d1460b592d378ca4871a0c72 \ + --hash=sha256:059d7151fff513c53a4638da8778be7fce81a0c4854c7348ebd0c4078ddf28fe \ + --hash=sha256:0c98c59075b890df8abfcc6ad632879540f5791c68baebacb4f833713b510e75 \ + --hash=sha256:0f2fa354ba106eafff2c14b0cc51f22801d1e8b2e4149342023bd6f0955de5f5 \ + --hash=sha256:12b04d1db2663b421fe072d638a138460a51d5a862403295671c4f3987fb9148 \ + --hash=sha256:22d8798819f86720bc646ab015baff5ea4c971d68121cb36e2ebc2ee43ead2b7 \ + --hash=sha256:233088b4b99ebcbc5258c755a097aa52fbf90727a03a5a80781c4b9c54347a2e \ + --hash=sha256:24bd94bb301ec672d8f0623eba9226cc90d775d25a0c92b5f8e4965d7f3a1518 \ + --hash=sha256:275424295f4256fd301744b8f335cff367825d270f155d522b30c7bf49903ee7 \ + --hash=sha256:32fe6a41ad97302db2931f05bb91abbcc65b5ce4c675cd44b972428dd2947700 \ + --hash=sha256:334edbcff10514ad1d66e3a70b339c0a29886394892490119dbb669627b17717 \ + --hash=sha256:3bb9ec6436a820a4c006aad1ac351f12de2f2dbdaad171692ee457a02429b672 \ + --hash=sha256:3ddcb27fb39171de36e207600116ac9dfd4ae46f86c82a9bf3934043e80ebb88 \ + --hash=sha256:42e8804962f9e6f4be2cbaedc0c3718f08f60a16910fa3d86da5a1e3b1bfe60f \ + --hash=sha256:43d044780732d9e0381ac8d5316f95d7f02ef04d6e4ef6dc82379f09795d993f \ + --hash=sha256:46796877b47034b559a593d7e4b549aba151dae73f9e78212a3478161c12ab08 \ + --hash=sha256:46d51518d53edfbe0563662c96954dc8fcace9832332b914375f45a99b77cc9a \ + --hash=sha256:47604cb2159f8bbd5a1ab48a714557156320f20871ee64d550d8bf2683d980d3 \ + --hash=sha256:4bbccb45260e4ff1b7db0be80a9025bb1e6698bdb808b83fff0000f7a90b2c0b \ + --hash=sha256:4d4e5a0ceba319942fa6b585cf82539288a61e314ef006c1209f734551ab9536 \ + --hash=sha256:55250fe61d6ebfd6934a272ee16ef1244e0f16b7af6cd18ab5b1fc9f08631db0 \ + --hash=sha256:566df36fd0e901625523a5a1835032f1ebdd7f7886c54584143fa6c668b4df3b \ + --hash=sha256:57ca426a48eb2c682dae8204cd89ea8ab7031e2675120a47924fabc7caacbc2a \ + --hash=sha256:5e61abbec255be7b122aa461021daa7c3f310f3e743411a67079f9b3cc91ece3 \ + --hash=sha256:618a308215b6cececb6240b9abde545e3acdabac7ae3e1d4e666896bf5ba44b4 \ + --hash=sha256:62557958002b69699bdb7f5137c6714ca1133f045f97b3903964f47db97ea339 \ + --hash=sha256:6270d717b11c5476b0cbb21eedc8d4dbb7d1a956fd6c15a23e96f197a6193158 \ + --hash=sha256:685e93e9c8f399b0c96a624799820176312f5ceef958c0f88215af4013d29066 \ + --hash=sha256:69469ce8ce7a8df4d37620e3163b71238719e1e2e5048d114a1b6ce0fbf8c662 \ + --hash=sha256:6eb188b84269f357669b62cb576b5b918de10fb7c728a005fa0ebb0b758adce1 \ + --hash=sha256:74ab4ee7794d7ed1b0c37e7333640e0f0a626fc7b398c07a7aef52f484fddde3 \ + --hash=sha256:77641d299179c37b89cf2343ca9972c88bb6eef0d5fc504a2f86afd15cd5adf5 \ + --hash=sha256:7c821c47ecfe05cc32140dcf8dc6fd5d21971c86dbd56eabfe5ba07a64910c01 \ + --hash=sha256:7d6be30b2a75362325176c036d7fb8d19e8846c77e87683ffaa8177b35135613 \ + --hash=sha256:7f605a456948c35260e7b2a39f8952a26f077fd25653c37740ed186b90aaa68a \ + --hash=sha256:83101a6930332b87653886c01d1ee7e294b1fe46a07dd9a2d2b4f91bcc88eec0 \ + --hash=sha256:88690f4e1f0fbf5339bedbb127e240fec1fd3070e9934c0b7bef83432f779d2f \ + --hash=sha256:8a97ac839c2c6672c4865e48f3cbad7152cee85f4233fb4ca6291d775b9b954a \ + --hash=sha256:8d6efc136f44a7e8bc8088507eaabbb8c2b55b3dbb63fe102c690da0ddebe55e \ + --hash=sha256:8e20e511dc15265fb433571391ba313e10dd8ea7e509d51686a51313b4ac01a2 \ + --hash=sha256:951d4a210744813be63019f3df343bf233b7432aadf0db54c75802247330d3af \ + --hash=sha256:9ac7a3e245fd0310fd31495eb61af772e637bdf7d88ee81e7f10a3f271bff014 \ + --hash=sha256:9b1c058c171b739e7c330760044803099c7fff11511e3ab3573e5327116a9c33 \ + --hash=sha256:9c04bff9a5335eb95c6ecf1c117576a0aa560def274876fd156cfe5510fccc61 \ + --hash=sha256:9c4969a86e41454f2858256c39bdfb966a20961e9b58bf8749b65abf447e9a8d \ + --hash=sha256:9e0400fa22f79acc334d9a6b185dc00a44a8e6578aa7e12d0ddcd8434152b187 \ + --hash=sha256:a05977bffe9bffd2229f477fa75eabe3192b1b05f408961d1bebff8d1cd4d401 \ + --hash=sha256:a143af2ea6672f2af3f44ed8f9cd020e9cc34c56f0e8db12019d5d9ecf41cb3b \ + --hash=sha256:a51d3db74ba489266ef55c7a4534eb0b8db9a326553df481c11e5d7660c8364d \ + --hash=sha256:b95b2f470c1b2683febd2e7eab1d3f0e078c91dbdd0b00e9c645d07a413bb99f \ + --hash=sha256:b9870d15ef00e4d0559ae10ee5bc71b654d1f20076dbe8bc7ed19b4c0625ceba \ + --hash=sha256:c1dc3368794d522f43914e03312202523cc89692f5389c32bea0233924f8d977 \ + --hash=sha256:c338ec6ec01c0bc8e735c58b9f5d51e75bacb6ff23296658826d7cfdfdb8678a \ + --hash=sha256:c5070135e1b7409c4161133aa525419b0062088ed77c92b1da95366ec5cbebbe \ + --hash=sha256:cc992c6ed024c8c3c592c5fc9846a03dd68a425674900c70122c77ea16c5fb0b \ + --hash=sha256:d15950a57a210e36dd4cec1aac22787e2a4d57ba9318233e2ef8b2daf9ff2d5f \ + --hash=sha256:d898cc2c76c135ef65517f4ddd7a3512fb41f23087b0650efb3418b8389a3cd1 \ + --hash=sha256:d99945830a6f3e9638d89a28ed130b1eb24c91255e4f24366fbe699b983f29e4 \ + --hash=sha256:da9b91bca419dc9b9267ffadde24eae9b1a6bffcd09d0a207e5e3af99a03ce0d \ + --hash=sha256:df2d441bacf97022e81ad047e1597552eb3f83ca8a8f1a1fdd43cd7fe3898120 \ + --hash=sha256:e06e617e3d4fd9e51d385dfe45b077a41e9d1b033a7702551e3278ac597dc750 \ + --hash=sha256:ec44cfa7ef1a728e88ad41674de50f6db8cfdb3e2af84af86e0041aaf02d43d0 \ + --hash=sha256:fb37f15714ec2652d574f021d479e78cd4eb9d04396dca36568fdfffb3487982 # via feast (pyproject.toml) starlette==1.0.0 \ --hash=sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149 \ @@ -1325,9 +1324,9 @@ 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 \ 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/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/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/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_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 index d1d132681c5..d7353cd4a08 100644 --- a/sdk/python/tests/integration/online_store/test_mysql_versioning.py +++ b/sdk/python/tests/integration/online_store/test_mysql_versioning.py @@ -77,6 +77,7 @@ def setup_mysql(self): 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) 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 0c27585139e..f72ac64586c 100644 --- a/sdk/python/tests/integration/online_store/test_universal_online.py +++ b/sdk/python/tests/integration/online_store/test_universal_online.py @@ -921,13 +921,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 +962,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"]) diff --git a/sdk/python/tests/integration/registration/test_universal_registry.py b/sdk/python/tests/integration/registration/test_universal_registry.py index fb09395d789..d8322e55636 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 @@ -284,6 +285,39 @@ def sqlite_registry(): yield SqlRegistry(registry_config, "project", None) +@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") def hdfs_registry(): HADOOP_NAMENODE_IMAGE = "bde2020/hadoop-namenode:2.0.0-hadoop3.2.1-java8" @@ -412,6 +446,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 +937,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/rest_api/resource/redis.yaml b/sdk/python/tests/integration/rest_api/resource/redis.yaml index 8701cf7fcdd..df8187daeec 100644 --- a/sdk/python/tests/integration/rest_api/resource/redis.yaml +++ b/sdk/python/tests/integration/rest_api/resource/redis.yaml @@ -16,6 +16,7 @@ spec: containers: - name: redis 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/unit/infra/compute_engines/local/test_nodes.py b/sdk/python/tests/unit/infra/compute_engines/local/test_nodes.py index 905ea65ae42..897211b374e 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(), @@ -213,4 +216,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_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/feast/loaders/__init__.py b/sdk/python/tests/unit/infra/offline_stores/contrib/mongodb_offline_store/__init__.py similarity index 100% rename from sdk/python/feast/loaders/__init__.py rename to sdk/python/tests/unit/infra/offline_stores/contrib/mongodb_offline_store/__init__.py 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/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..0bcc282ae83 --- /dev/null +++ b/sdk/python/tests/unit/infra/offline_stores/contrib/spark_offline_store/test_spark_bfv_compute_on_read.py @@ -0,0 +1,222 @@ +""" +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, + ) + + +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/test_bigquery.py b/sdk/python/tests/unit/infra/offline_stores/test_bigquery.py index 7dbf06e94a8..969a9679971 100644 --- a/sdk/python/tests/unit/infra/offline_stores/test_bigquery.py +++ b/sdk/python/tests/unit/infra/offline_stores/test_bigquery.py @@ -152,3 +152,51 @@ def test_pull_all_from_table_or_query_partition_pruning(mock_get_bigquery_client ) assert "partition_date >= '2021-01-01'" in actual_query assert "partition_date <= '2021-01-02'" in actual_query + + +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" 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_milvus_versioning.py b/sdk/python/tests/unit/infra/online_store/test_milvus_versioning.py new file mode 100644 index 00000000000..c2979d37690 --- /dev/null +++ b/sdk/python/tests/unit/infra/online_store/test_milvus_versioning.py @@ -0,0 +1,180 @@ +"""Unit tests for Milvus 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 + + +class TestTableId: + """Test _table_id with versioning enabled/disabled.""" + + def test_no_versioning(self): + from feast.infra.online_stores.milvus_online_store.milvus import _table_id + + fv = _make_feature_view() + config = _make_config(versioning=False) + assert _table_id(config.project, fv) == "test_project_driver_stats" + + def test_versioning_enabled_with_version(self): + from feast.infra.online_stores.milvus_online_store.milvus import _table_id + + fv = _make_feature_view(version_number=2) + config = _make_config(versioning=True) + assert ( + _table_id(config.project, fv, enable_versioning=True) + == "test_project_driver_stats_v2" + ) + + def test_projection_version_tag_takes_priority(self): + from feast.infra.online_stores.milvus_online_store.milvus import _table_id + + fv = _make_feature_view(version_number=1, version_tag=3) + config = _make_config(versioning=True) + assert ( + _table_id(config.project, fv, enable_versioning=True) + == "test_project_driver_stats_v3" + ) + + def test_version_zero_no_suffix(self): + from feast.infra.online_stores.milvus_online_store.milvus import _table_id + + fv = _make_feature_view(version_number=0) + config = _make_config(versioning=True) + assert ( + _table_id(config.project, fv, enable_versioning=True) + == "test_project_driver_stats" + ) + + def test_versioning_enabled_no_version_set(self): + from feast.infra.online_stores.milvus_online_store.milvus import _table_id + + fv = _make_feature_view() + config = _make_config(versioning=True) + assert ( + _table_id(config.project, fv, enable_versioning=True) + == "test_project_driver_stats" + ) + + def test_versioning_disabled_ignores_version(self): + from feast.infra.online_stores.milvus_online_store.milvus import _table_id + + fv = _make_feature_view(version_number=5) + config = _make_config(versioning=False) + assert _table_id(config.project, fv) == "test_project_driver_stats" + + +class TestMilvusVersionedReadSupport: + """Test that MilvusOnlineStore passes _check_versioned_read_support.""" + + def test_allowed_with_version_tag(self): + from feast.infra.online_stores.milvus_online_store.milvus import ( + MilvusOnlineStore, + ) + + store = MilvusOnlineStore() + fv = _make_feature_view() + fv.projection.version_tag = 2 + store._check_versioned_read_support([(fv, ["trips_today"])]) + + def test_allowed_without_version_tag(self): + from feast.infra.online_stores.milvus_online_store.milvus import ( + MilvusOnlineStore, + ) + + store = MilvusOnlineStore() + fv = _make_feature_view() + store._check_versioned_read_support([(fv, ["trips_today"])]) + + +class TestTeardownDropsAllVersions: + """Teardown should drop the base collection AND all versioned collections.""" + + def _build_store_with_collections(self, existing_collections): + from feast.infra.online_stores.milvus_online_store.milvus import ( + MilvusOnlineStore, + ) + + store = MilvusOnlineStore() + store.client = MagicMock() + store.client.list_collections.return_value = existing_collections + store._connect = MagicMock(return_value=store.client) + store._collections = {name: MagicMock() for name in existing_collections} + return store + + def test_teardown_drops_base_and_all_versioned_collections(self): + fv = _make_feature_view() + config = _make_config(versioning=True) + existing = [ + "test_project_driver_stats", + "test_project_driver_stats_v1", + "test_project_driver_stats_v2", + "test_project_other_view", # unrelated, must not be dropped + ] + store = self._build_store_with_collections(existing) + + store.teardown(config, [fv], []) + + dropped = {call.args[0] for call in store.client.drop_collection.call_args_list} + assert dropped == { + "test_project_driver_stats", + "test_project_driver_stats_v1", + "test_project_driver_stats_v2", + } + assert "test_project_other_view" not in dropped + + def test_update_drops_all_versions_for_deleted_table(self): + fv = _make_feature_view() + config = _make_config(versioning=True) + existing = [ + "test_project_driver_stats", + "test_project_driver_stats_v3", + "test_project_driver_stats_v4", + ] + store = self._build_store_with_collections(existing) + + store.update( + config=config, + tables_to_delete=[fv], + tables_to_keep=[], + entities_to_delete=[], + entities_to_keep=[], + partial=False, + ) + + dropped = {call.args[0] for call in store.client.drop_collection.call_args_list} + assert dropped == { + "test_project_driver_stats", + "test_project_driver_stats_v3", + "test_project_driver_stats_v4", + } diff --git a/sdk/python/tests/unit/infra/online_store/test_redis.py b/sdk/python/tests/unit/infra/online_store/test_redis.py index 0d9f2cd8739..b9b5dd3e97e 100644 --- a/sdk/python/tests/unit/infra/online_store/test_redis.py +++ b/sdk/python/tests/unit/infra/online_store/test_redis.py @@ -1,8 +1,12 @@ +import asyncio +from datetime import datetime, timezone +from unittest.mock import AsyncMock, MagicMock, patch + import pytest from google.protobuf.timestamp_pb2 import Timestamp from feast import Entity, FeatureView, Field, FileSource, RepoConfig -from feast.infra.online_stores.redis import RedisOnlineStore +from feast.infra.online_stores.redis import RedisOnlineStore, RedisOnlineStoreConfig 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 Int32 @@ -252,3 +256,229 @@ def test_get_features_for_entity_with_all_none_values( assert features is not None assert "feature_view_1:feature_10" in features assert features["feature_view_1:feature_10"].WhichOneof("val") is None + + +def _make_pipe_mock(hkeys_results): + """Return a MagicMock pipeline whose execute() yields hkeys_results then does nothing.""" + pipe = MagicMock() + pipe.__enter__ = MagicMock(return_value=pipe) + pipe.__exit__ = MagicMock(return_value=False) + pipe.execute = MagicMock(side_effect=[hkeys_results, None]) + return pipe + + +def test_delete_table_does_not_call_hgetall( + redis_online_store: RedisOnlineStore, repo_config, feature_view +): + """delete_table must not call hgetall directly (old N+1 pattern).""" + fv_name = feature_view.name + fv_bytes = fv_name.encode("utf8") + + mock_client = MagicMock() + mock_client.scan_iter.return_value = iter([b"key1", b"key2"]) + + pipe = _make_pipe_mock( + [ + [b"_ts:" + fv_bytes], # key1: only this FV → DEL + [b"_ts:" + fv_bytes, b"_ts:other_fv"], # key2: shared → HDEL + ] + ) + mock_client.pipeline.return_value = pipe + + with patch.object(redis_online_store, "_get_client", return_value=mock_client): + redis_online_store.delete_table(repo_config, feature_view) + + mock_client.hgetall.assert_not_called() + # Two pipeline context managers: one for hkeys, one for deletions + assert mock_client.pipeline.call_count == 2 + # hkeys was queued for both keys + assert pipe.hkeys.call_count == 2 + + +def test_delete_table_skips_unrelated_keys( + redis_online_store: RedisOnlineStore, repo_config, feature_view +): + """delete_table must not issue delete/hdel for keys that don't have this FV.""" + mock_client = MagicMock() + mock_client.scan_iter.return_value = iter([b"key1"]) + + pipe = _make_pipe_mock( + [ + [b"_ts:other_fv"], # key1 belongs to a different FV → skip + ] + ) + mock_client.pipeline.return_value = pipe + + with patch.object(redis_online_store, "_get_client", return_value=mock_client): + redis_online_store.delete_table(repo_config, feature_view) + + pipe.delete.assert_not_called() + pipe.hdel.assert_not_called() + + +def test_delete_table_no_keys_skips_pipelines( + redis_online_store: RedisOnlineStore, repo_config, feature_view +): + """When scan finds no keys, no pipeline should be opened.""" + mock_client = MagicMock() + mock_client.scan_iter.return_value = iter([]) + + with patch.object(redis_online_store, "_get_client", return_value=mock_client): + redis_online_store.delete_table(repo_config, feature_view) + + mock_client.pipeline.assert_not_called() + + +def test_skip_dedup_default_is_false(): + """skip_dedup must default to False for backward compatibility.""" + cfg = RedisOnlineStoreConfig() + assert cfg.skip_dedup is False + + +def test_skip_dedup_can_be_enabled(): + """skip_dedup can be set to True via config.""" + cfg = RedisOnlineStoreConfig(skip_dedup=True) + assert cfg.skip_dedup is True + + +def test_online_write_batch_skip_dedup_single_pipeline( + redis_online_store: RedisOnlineStore, repo_config, feature_view +): + """When skip_dedup=True, online_write_batch must use exactly 1 pipeline execution + (no initial timestamp read pipeline).""" + online_store_cfg = RedisOnlineStoreConfig(skip_dedup=True) + config = RepoConfig( + provider="local", + project="test", + entity_key_serialization_version=3, + registry="dummy_registry.db", + online_store=online_store_cfg, + ) + + mock_client = MagicMock() + pipe = MagicMock() + pipe.__enter__ = MagicMock(return_value=pipe) + pipe.__exit__ = MagicMock(return_value=False) + pipe.execute.return_value = [] + mock_client.pipeline.return_value = pipe + + data = [ + ( + EntityKeyProto( + join_keys=["entity"], entity_values=[ValueProto(int32_val=1)] + ), + {"feature_10": ValueProto(int32_val=100)}, + datetime.now(tz=timezone.utc), + None, + ) + ] + + with patch.object(redis_online_store, "_get_client", return_value=mock_client): + redis_online_store.online_write_batch(config, feature_view, data, progress=None) + + # Only 1 pipeline context opened (no read pipeline for timestamps) + assert mock_client.pipeline.call_count == 1 + # No hmget (timestamp reads) issued + pipe.hmget.assert_not_called() + # hset was called to write the data + pipe.hset.assert_called_once() + + +def test_online_write_batch_with_dedup_uses_two_pipelines( + redis_online_store: RedisOnlineStore, feature_view +): + """When skip_dedup=False (default), online_write_batch reads timestamps first + then writes in the same pipeline context (hmget + hset in one `with` block).""" + config = RepoConfig( + provider="local", + project="test", + entity_key_serialization_version=3, + registry="dummy_registry.db", + online_store=RedisOnlineStoreConfig(), # default: skip_dedup=False + ) + + mock_client = MagicMock() + pipe = MagicMock() + pipe.__enter__ = MagicMock(return_value=pipe) + pipe.__exit__ = MagicMock(return_value=False) + # hmget returns a list per field queried; execute() returns one list per pipeline command. + # For one entity querying one ts_key: [[None]] (one hmget result, value is None) + pipe.execute.side_effect = [[[None]], []] + mock_client.pipeline.return_value = pipe + + data = [ + ( + EntityKeyProto( + join_keys=["entity"], entity_values=[ValueProto(int32_val=1)] + ), + {"feature_10": ValueProto(int32_val=100)}, + datetime.now(tz=timezone.utc), + None, + ) + ] + + with patch.object(redis_online_store, "_get_client", return_value=mock_client): + redis_online_store.online_write_batch(config, feature_view, data, progress=None) + + # pipeline context opened once (both read and write phases use the same `with` block) + assert mock_client.pipeline.call_count == 1 + # hmget was issued for the timestamp check + pipe.hmget.assert_called_once() + + +def test_online_write_batch_async_skip_dedup_single_pipeline( + redis_online_store: RedisOnlineStore, feature_view +): + """online_write_batch_async with skip_dedup=True must use exactly 1 pipeline.""" + online_store_cfg = RedisOnlineStoreConfig(skip_dedup=True) + config = RepoConfig( + provider="local", + project="test", + entity_key_serialization_version=3, + registry="dummy_registry.db", + online_store=online_store_cfg, + ) + + async_pipe = AsyncMock() + async_pipe.__aenter__ = AsyncMock(return_value=async_pipe) + async_pipe.__aexit__ = AsyncMock(return_value=False) + async_pipe.execute = AsyncMock(return_value=[]) + + mock_async_client = AsyncMock() + mock_async_client.pipeline = MagicMock(return_value=async_pipe) + + data = [ + ( + EntityKeyProto( + join_keys=["entity"], entity_values=[ValueProto(int32_val=1)] + ), + {"feature_10": ValueProto(int32_val=100)}, + datetime.now(tz=timezone.utc), + None, + ) + ] + + async def _run(): + with patch.object( + redis_online_store, + "_get_client_async", + AsyncMock(return_value=mock_async_client), + ): + await redis_online_store.online_write_batch_async( + config, feature_view, data, progress=None + ) + + asyncio.get_event_loop().run_until_complete(_run()) + + assert mock_async_client.pipeline.call_count == 1 + async_pipe.hmget.assert_not_called() + async_pipe.hset.assert_called_once() + + +def test_online_write_batch_async_exists_and_is_coroutine(): + """online_write_batch_async must exist and be an async method (not raise NotImplementedError).""" + import inspect + + store = RedisOnlineStore() + assert hasattr(store, "online_write_batch_async") + assert inspect.iscoroutinefunction(store.online_write_batch_async) diff --git a/sdk/python/tests/unit/infra/online_store/test_redis_versioning.py b/sdk/python/tests/unit/infra/online_store/test_redis_versioning.py new file mode 100644 index 00000000000..caf3216cb4d --- /dev/null +++ b/sdk/python/tests/unit/infra/online_store/test_redis_versioning.py @@ -0,0 +1,145 @@ +"""Unit tests for Redis 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.infra.online_stores.helpers import _mmh3 +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 + + +class TestVersionedFvName: + """Test _versioned_fv_name produces correct versioned names.""" + + def test_no_versioning(self): + from feast.infra.online_stores.redis import _versioned_fv_name + + fv = _make_feature_view() + config = _make_config(versioning=False) + assert _versioned_fv_name(fv, config) == "driver_stats" + + def test_versioning_disabled_ignores_version(self): + from feast.infra.online_stores.redis import _versioned_fv_name + + fv = _make_feature_view(version_number=3) + config = _make_config(versioning=False) + assert _versioned_fv_name(fv, config) == "driver_stats" + + def test_versioning_enabled_no_version_set(self): + from feast.infra.online_stores.redis import _versioned_fv_name + + fv = _make_feature_view() + config = _make_config(versioning=True) + assert _versioned_fv_name(fv, config) == "driver_stats" + + def test_versioning_enabled_with_current_version_number(self): + from feast.infra.online_stores.redis import _versioned_fv_name + + fv = _make_feature_view(version_number=2) + config = _make_config(versioning=True) + assert _versioned_fv_name(fv, config) == "driver_stats_v2" + + def test_version_zero_no_suffix(self): + from feast.infra.online_stores.redis import _versioned_fv_name + + fv = _make_feature_view(version_number=0) + config = _make_config(versioning=True) + assert _versioned_fv_name(fv, config) == "driver_stats" + + def test_projection_version_tag_takes_priority(self): + from feast.infra.online_stores.redis import _versioned_fv_name + + fv = _make_feature_view(version_number=1, version_tag=3) + config = _make_config(versioning=True) + assert _versioned_fv_name(fv, config) == "driver_stats_v3" + + def test_projection_version_tag_zero_no_suffix(self): + from feast.infra.online_stores.redis import _versioned_fv_name + + fv = _make_feature_view(version_tag=0, version_number=3) + config = _make_config(versioning=True) + assert _versioned_fv_name(fv, config) == "driver_stats" + + +class TestHsetKeysVersioning: + """Test that _generate_hset_keys_for_features produces different keys for different versions.""" + + def test_different_versions_produce_different_hset_keys(self): + from feast.infra.online_stores.redis import RedisOnlineStore + + store = RedisOnlineStore() + fv = _make_feature_view() + + _, hset_keys_v1 = store._generate_hset_keys_for_features( + fv, ["trips_today"], fv_name_override="driver_stats_v1" + ) + _, hset_keys_v2 = store._generate_hset_keys_for_features( + fv, ["trips_today"], fv_name_override="driver_stats_v2" + ) + + # The mmh3 hash keys should differ + assert hset_keys_v1[0] != hset_keys_v2[0] + # The timestamp keys should also differ + assert hset_keys_v1[1] != hset_keys_v2[1] + + def test_no_override_uses_fv_name(self): + from feast.infra.online_stores.redis import RedisOnlineStore + + store = RedisOnlineStore() + fv = _make_feature_view() + + _, hset_keys = store._generate_hset_keys_for_features(fv, ["trips_today"]) + + expected_feature_key = _mmh3("driver_stats:trips_today") + expected_ts_key = "_ts:driver_stats" + assert hset_keys[0] == expected_feature_key + assert hset_keys[1] == expected_ts_key + + +class TestRedisVersionedReadSupport: + """Test that RedisOnlineStore passes _check_versioned_read_support.""" + + def test_allowed_with_version_tag(self): + from feast.infra.online_stores.redis import RedisOnlineStore + + store = RedisOnlineStore() + 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.redis import RedisOnlineStore + + store = RedisOnlineStore() + fv = _make_feature_view() + store._check_versioned_read_support([(fv, ["trips_today"])]) 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/utils/snowflake/test_snowflake_utils.py b/sdk/python/tests/unit/infra/utils/snowflake/test_snowflake_utils.py index 8ae6ec63ba5..14b42c9783b 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,15 @@ import tempfile from typing import Optional +from unittest.mock import MagicMock 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 ( + execute_snowflake_statement, + parse_private_key_path, +) PRIVATE_KEY_PASSPHRASE = "test" @@ -69,3 +73,38 @@ def test_parse_private_key_path_key_path_encrypted(encrypted_private_key): f.name, None, ) + + +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/local_feast_tests/test_e2e_local.py b/sdk/python/tests/unit/local_feast_tests/test_e2e_local.py index 9019f577fc5..ef11c8cccfa 100644 --- a/sdk/python/tests/unit/local_feast_tests/test_e2e_local.py +++ b/sdk/python/tests/unit/local_feast_tests/test_e2e_local.py @@ -23,6 +23,7 @@ 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/unit/online_store/test_mongodb_online_retrieval.py b/sdk/python/tests/unit/online_store/test_mongodb_online_retrieval.py index cfadc3151fd..029746cf442 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 @@ -11,13 +11,13 @@ 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.types import Array, Float32, Int64, String 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 @@ -303,3 +303,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/test_doc_embedder.py b/sdk/python/tests/unit/test_doc_embedder.py index 2a9e324e0c4..10f72c82d02 100644 --- a/sdk/python/tests/unit/test_doc_embedder.py +++ b/sdk/python/tests/unit/test_doc_embedder.py @@ -6,7 +6,11 @@ import pytest from feast.chunker import BaseChunker, ChunkingConfig, TextChunker -from feast.doc_embedder import DocEmbedder, LogicalLayerFn, default_logical_layer_fn +from feast.doc_embedder import ( + DocEmbedder, + SchemaTransformFn, + default_schema_transform_fn, +) from feast.embedder import BaseEmbedder, EmbeddingConfig, MultiModalEmbedder @@ -230,17 +234,17 @@ def test_embed_dataframe(self): embedder.embed.assert_called_once_with(["hello", "world"], "text") -def test_logical_layer_fn_protocol_check(): - """A matching function is recognized as LogicalLayerFn.""" +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, LogicalLayerFn) + assert isinstance(my_fn, SchemaTransformFn) -def test_default_logical_layer_fn_output(): - """default_logical_layer_fn transforms columns correctly.""" +def test_default_schema_transform_fn_output(): + """default_schema_transform_fn transforms columns correctly.""" input_df = pd.DataFrame( { "chunk_id": ["c1", "c2"], @@ -250,7 +254,7 @@ def test_default_logical_layer_fn_output(): } ) - result = default_logical_layer_fn(input_df) + result = default_schema_transform_fn(input_df) assert list(result.columns) == [ "passage_id", @@ -288,7 +292,7 @@ def test_init_no_feature_view(self, mock_load_config, mock_apply_total, 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.logical_layer_fn is default_logical_layer_fn + assert doc_embedder.schema_transform_fn is default_schema_transform_fn @patch("feast.repo_operations.apply_total") @patch("feast.repo_config.load_repo_config") @@ -374,7 +378,7 @@ def test_init_creates_feature_view_auto_detects_vector_length( def test_embed_documents_full_chain( self, mock_fs_cls, mock_load_config, mock_apply_total, tmp_path ): - """embed_documents wires chunk -> embed -> logical_layer -> save correctly.""" + """embed_documents wires chunk -> embed -> schema_transform -> save correctly.""" mock_chunker = MagicMock(spec=BaseChunker) chunked_df = pd.DataFrame( { @@ -409,7 +413,7 @@ def mock_logical_fn(df: pd.DataFrame) -> pd.DataFrame: repo_path=str(tmp_path), chunker=mock_chunker, embedder=mock_embedder, - logical_layer_fn=mock_logical_fn, + schema_transform_fn=mock_logical_fn, create_feature_view=False, ) @@ -528,7 +532,7 @@ def mock_logical_fn(df: pd.DataFrame) -> pd.DataFrame: repo_path=str(tmp_path), chunker=mock_chunker, embedder=mock_embedder, - logical_layer_fn=mock_logical_fn, + schema_transform_fn=mock_logical_fn, create_feature_view=False, ) @@ -599,7 +603,7 @@ def test_save_to_online_store( @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 logical layer.""" + """Full pipeline: real TextChunker + mocked embedder + default schema transform.""" chunker = TextChunker( config=ChunkingConfig( chunk_size=10, @@ -623,7 +627,7 @@ def fake_embed_dataframe(df, column_mapping): repo_path=str(tmp_path), chunker=chunker, embedder=mock_embedder, - logical_layer_fn=default_logical_layer_fn, + schema_transform_fn=default_schema_transform_fn, create_feature_view=False, ) 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_metrics.py b/sdk/python/tests/unit/test_metrics.py index 17aaa5d1337..bffde73dd91 100644 --- a/sdk/python/tests/unit/test_metrics.py +++ b/sdk/python/tests/unit/test_metrics.py @@ -23,10 +23,12 @@ materialization_result_total, 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, @@ -435,6 +437,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( @@ -493,9 +560,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) @@ -504,6 +578,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" @@ -512,6 +591,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) @@ -525,6 +605,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) diff --git a/sdk/python/tests/unit/test_offline_server.py b/sdk/python/tests/unit/test_offline_server.py index f30c3aef037..efa2aaa6af4 100644 --- a/sdk/python/tests/unit/test_offline_server.py +++ b/sdk/python/tests/unit/test_offline_server.py @@ -1,7 +1,7 @@ import os import tempfile from datetime import datetime, timedelta -from unittest.mock import patch +from unittest.mock import MagicMock, patch import assertpy import pandas as pd @@ -15,6 +15,7 @@ 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 @@ -348,6 +349,87 @@ def _test_pull_all_from_table_or_query(temp_dir, fs: FeatureStore): ).to_df() +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(metadata.features).is_equal_to( + ["driver_hourly_stats:conv_rate"] + ) + 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 must move a SQL string into + api_parameters['entity_df_sql'] and pass entity_df=None to RemoteRetrievalJob.""" + 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, + ) + + 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_server_get_historical_features_passes_sql_to_store(): + """OfflineServer.get_historical_features must forward entity_df_sql from the + command dict as a SQL string 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 + + mock_store = MagicMock() + mock_store.config.project = "test" + + 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, + } + + # Call the real method with the mock server as self + result = OfflineServer.get_historical_features(server, command, key=None) + + 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) + + def test_get_feature_view_by_name_propagates_transient_errors(): """Transient registry errors must not be swallowed and misreported as FeatureViewNotFoundException.""" 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 07e9e6a0b94..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 @@ -590,3 +591,160 @@ def test_eq_considers_track_metrics(): 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_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 8ec854d64a0..4f87aa46f19 100644 --- a/sdk/python/tests/unit/test_type_map.py +++ b/sdk/python/tests/unit/test_type_map.py @@ -1845,3 +1845,111 @@ def test_pa_to_feast_value_type_nested(self): 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()) diff --git a/sdk/python/tests/universal/feature_repos/repo_configuration.py b/sdk/python/tests/universal/feature_repos/repo_configuration.py index ddd952f71dc..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: 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 b9fda20d26a..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", 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/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 index 475854c0674..b3e0c27c5a2 100644 --- a/skills/feast-dev/SKILL.md +++ b/skills/feast-dev/SKILL.md @@ -58,8 +58,11 @@ make lint-python # Run all precommit checks (format + lint) make precommit-check -# Type checking -cd sdk/python && python -m mypy feast +# 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 @@ -71,11 +74,44 @@ cd sdk/python && python -m mypy feast - 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 reference documentation (concepts, how-tos, reference pages) goes under `docs/`. +- 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 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/ui/package.json b/ui/package.json index 4faafffe731..354334df406 100644 --- a/ui/package.json +++ b/ui/package.json @@ -1,6 +1,6 @@ { "name": "@feast-dev/feast-ui", - "version": "0.62.0", + "version": "0.63.0", "private": false, "files": [ "dist"