From 67d79f7dd4ff64563daa81b49de09e64b086cae9 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Tue, 20 Jan 2026 15:48:23 -0500 Subject: [PATCH 01/47] Initial commit on INTPYTHON-297-MongoDB-Feast-Integration Signed-off-by: Casey Clements --- .../contrib/mongodb_offline_store/__init__.py | 1 + .../mongodb_offline_store/tests/__init__.py | 1 + .../mongodb_online_store/__init__.py | 1 + .../mongodb_online_store/mongodb.py | 515 ++++++++++++++ .../mongodb_online_store/tests/__init__.py | 1 + .../tests/test_mongodb_online.py | 629 ++++++++++++++++++ .../feast/infra/utils/mongodb/__init__.py | 1 + .../infra/utils/mongodb/connection_utils.py | 222 +++++++ .../utils/mongodb/test_connection_utils.py | 240 +++++++ sdk/python/feast/repo_config.py | 2 + test_registry | 1 + 11 files changed, 1614 insertions(+) create mode 100644 sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/__init__.py create mode 100644 sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/tests/__init__.py create mode 100644 sdk/python/feast/infra/online_stores/mongodb_online_store/__init__.py create mode 100644 sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py create mode 100644 sdk/python/feast/infra/online_stores/mongodb_online_store/tests/__init__.py create mode 100644 sdk/python/feast/infra/online_stores/mongodb_online_store/tests/test_mongodb_online.py create mode 100644 sdk/python/feast/infra/utils/mongodb/__init__.py create mode 100644 sdk/python/feast/infra/utils/mongodb/connection_utils.py create mode 100644 sdk/python/feast/infra/utils/mongodb/test_connection_utils.py create mode 100644 test_registry 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..5ebb589a558 --- /dev/null +++ b/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/__init__.py @@ -0,0 +1 @@ +# MongoDB Offline Store for Feast diff --git a/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/tests/__init__.py b/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/tests/__init__.py new file mode 100644 index 00000000000..0a2efb5c552 --- /dev/null +++ b/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/tests/__init__.py @@ -0,0 +1 @@ +# Tests for MongoDB Offline Store diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/__init__.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/__init__.py new file mode 100644 index 00000000000..c7b38f213ab --- /dev/null +++ b/sdk/python/feast/infra/online_stores/mongodb_online_store/__init__.py @@ -0,0 +1 @@ +# MongoDB Online Store for Feast 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 new file mode 100644 index 00000000000..c46ecd0932b --- /dev/null +++ b/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py @@ -0,0 +1,515 @@ +# 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. + +""" +MongoDB Online Store implementation for Feast. + +This module provides an online store implementation using MongoDB, with support for: +- MongoDB Atlas (primary target) +- Core MongoDB (for basic functionality) +- Async operations using PyMongo's AsyncMongoClient +- Vector search via Atlas Vector Search +- TTL-based feature expiration +""" + +import hashlib +import logging +from datetime import datetime, timedelta +from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple + +from pydantic import StrictBool, StrictInt, StrictStr + +from feast import Entity, FeatureView, RepoConfig +from feast.infra.key_encoding_utils import serialize_entity_key +from feast.infra.online_stores.helpers import _to_naive_utc +from feast.infra.online_stores.online_store import OnlineStore, SupportedAsyncMethods +from feast.infra.online_stores.vector_store import VectorStoreConfig +from feast.infra.utils.mongodb.connection_utils import ( + get_async_mongo_client, + get_collection_name, + get_mongo_client, + is_atlas, + is_atlas_async, +) +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 + +try: + from pymongo import MongoClient + from pymongo.errors import OperationFailure + from pymongo import AsyncMongoClient +except ImportError as e: + from feast.errors import FeastExtrasDependencyImportError + + raise FeastExtrasDependencyImportError("mongodb", str(e)) + +logger = logging.getLogger(__name__) + + +class MongoDBOnlineStoreConfig(FeastConfigBaseModel, VectorStoreConfig): + """ + Configuration for MongoDB Online Store. + + Supports both MongoDB Atlas and core MongoDB deployments. + """ + + type: Literal[ + "mongodb", "feast.infra.online_stores.mongodb_online_store.mongodb.MongoDBOnlineStore" + ] = "mongodb" + """Online store type selector""" + + # Connection settings + connection_string: StrictStr + """MongoDB connection URI (mongodb:// or mongodb+srv:// for Atlas)""" + + database: StrictStr = "feast" + """Database name for online store""" + + # Performance settings + max_pool_size: StrictInt = 50 + """Maximum connection pool size""" + + min_pool_size: StrictInt = 10 + """Minimum connection pool size""" + + # TTL settings + ttl_seconds: Optional[StrictInt] = None + """Optional TTL for documents in seconds (uses MongoDB TTL index)""" + + # Atlas-specific features + atlas_vector_search_enabled: StrictBool = False + """Enable Atlas Vector Search for retrieve_online_documents_v2""" + + vector_index_name: StrictStr = "vector_index" + """Name of the Atlas vector search index""" + + vector_similarity_metric: StrictStr = "cosine" + """Similarity metric: 'cosine', 'euclidean', or 'dotProduct'""" + + # Write concern + write_concern_w: StrictInt = 1 + """Write concern w parameter (1=primary, 'majority'=majority, etc.)""" + + # Read preference + read_preference: StrictStr = "primaryPreferred" + """Read preference: 'primary', 'primaryPreferred', 'secondary', etc.""" + + +class MongoDBOnlineStore(OnlineStore): + """ + MongoDB implementation of the Feast online store interface. + + This implementation supports: + - Synchronous and asynchronous operations + - MongoDB Atlas Vector Search for similarity search + - TTL-based feature expiration + - Connection pooling for performance + + Document structure: + { + _id: ObjectId, + entity_key_hash: "md5_hash", + features: { + "feature1": , + "feature2": + }, + event_timestamp: ISODate, + created_timestamp: ISODate (optional), + vector_embedding: [float, ...] (optional, for vector search), + expire_at: ISODate (optional, for TTL) + } + """ + + _client: Optional[MongoClient] = None + _client_async: Optional[AsyncMongoClient] = None + + def _get_client(self, config: MongoDBOnlineStoreConfig) -> MongoClient: + """Get or create synchronous MongoDB client.""" + if not self._client: + self._client = get_mongo_client( + connection_string=config.connection_string, + max_pool_size=config.max_pool_size, + min_pool_size=config.min_pool_size, + write_concern_w=config.write_concern_w, + read_preference=config.read_preference, + ) + return self._client + + def _get_client_async(self, config: MongoDBOnlineStoreConfig) -> AsyncMongoClient: + """Get or create asynchronous MongoDB client.""" + if not self._client_async: + self._client_async = get_async_mongo_client( + connection_string=config.connection_string, + max_pool_size=config.max_pool_size, + min_pool_size=config.min_pool_size, + write_concern_w=config.write_concern_w, + read_preference=config.read_preference, + ) + return self._client_async + + @staticmethod + def _compute_entity_key_hash(entity_key_bin: bytes) -> str: + """Compute MD5 hash of entity key for efficient indexing.""" + return hashlib.md5(entity_key_bin).hexdigest() + + @property + def async_supported(self) -> SupportedAsyncMethods: + """Indicate that this online store supports async operations.""" + return SupportedAsyncMethods(read=True, write=True) + + def online_write_batch( + self, + config: RepoConfig, + table: FeatureView, + data: List[ + Tuple[EntityKeyProto, Dict[str, ValueProto], datetime, Optional[datetime]] + ], + progress: Optional[Callable[[int], Any]], + ) -> None: + """ + Write a batch of feature rows to MongoDB. + + Args: + config: Feast repository configuration + table: Feature view to write to + data: List of (entity_key, features, event_timestamp, created_timestamp) tuples + progress: Optional progress callback + """ + assert config.online_store.type == "mongodb" + online_config: MongoDBOnlineStoreConfig = config.online_store + + client = self._get_client(online_config) + db = client[online_config.database] + collection_name = get_collection_name(config.project, table.name) + collection = db[collection_name] + + bulk_operations = [] + for entity_key, values, timestamp, created_ts in data: + # Serialize entity key + entity_key_bin = serialize_entity_key( + entity_key, + entity_key_serialization_version=config.entity_key_serialization_version, + ) + entity_key_hash = self._compute_entity_key_hash(entity_key_bin) + + # Convert timestamps to naive UTC + timestamp = _to_naive_utc(timestamp) + created_ts = _to_naive_utc(created_ts) if created_ts else None + + # Serialize feature values + features_dict = {} + for feature_name, val in values.items(): + features_dict[feature_name] = val.SerializeToString() + + # Build document + document = { + "entity_key_hash": entity_key_hash, + "features": features_dict, + "event_timestamp": timestamp, + } + + if created_ts: + document["created_timestamp"] = created_ts + + # Add TTL field if configured + if online_config.ttl_seconds: + expire_at = timestamp + timedelta(seconds=online_config.ttl_seconds) + document["expire_at"] = expire_at + + # Upsert operation + bulk_operations.append({ + "filter": {"entity_key_hash": entity_key_hash}, + "update": {"$set": document}, + "upsert": True, + }) + + if progress: + progress(1) + + # Execute bulk write if there are operations + if bulk_operations: + from pymongo import UpdateOne + collection.bulk_write([ + UpdateOne(op["filter"], op["update"], upsert=op["upsert"]) + for op in bulk_operations + ]) + + 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.""" + assert config.online_store.type == "mongodb" + online_config: MongoDBOnlineStoreConfig = config.online_store + + client = self._get_client_async(online_config) + db = client[online_config.database] + collection_name = get_collection_name(config.project, table.name) + collection = db[collection_name] + + bulk_operations = [] + for entity_key, values, timestamp, created_ts in data: + entity_key_bin = serialize_entity_key( + entity_key, + entity_key_serialization_version=config.entity_key_serialization_version, + ) + entity_key_hash = self._compute_entity_key_hash(entity_key_bin) + timestamp = _to_naive_utc(timestamp) + created_ts = _to_naive_utc(created_ts) if created_ts else None + + features_dict = { + feature_name: val.SerializeToString() + for feature_name, val in values.items() + } + + document = { + "entity_key_hash": entity_key_hash, + "features": features_dict, + "event_timestamp": timestamp, + } + + if created_ts: + document["created_timestamp"] = created_ts + + if online_config.ttl_seconds: + expire_at = timestamp + timedelta(seconds=online_config.ttl_seconds) + document["expire_at"] = expire_at + + bulk_operations.append({ + "filter": {"entity_key_hash": entity_key_hash}, + "update": {"$set": document}, + "upsert": True, + }) + + if progress: + progress(1) + + if bulk_operations: + from pymongo import UpdateOne + await collection.bulk_write([ + UpdateOne(op["filter"], op["update"], upsert=op["upsert"]) + for op in bulk_operations + ]) + + def online_read( + self, + config: RepoConfig, + table: FeatureView, + entity_keys: List[EntityKeyProto], + requested_features: Optional[List[str]] = None, + ) -> List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]]: + """ + Read feature values from MongoDB. + + Args: + config: Feast repository configuration + table: Feature view to read from + entity_keys: List of entity keys to read + requested_features: Optional list of specific features to retrieve + + Returns: + List of (event_timestamp, features_dict) tuples, one per entity key + """ + assert config.online_store.type == "mongodb" + online_config: MongoDBOnlineStoreConfig = config.online_store + + client = self._get_client(online_config) + db = client[online_config.database] + collection_name = get_collection_name(config.project, table.name) + collection = db[collection_name] + + # Compute entity key hashes + entity_key_hashes = [ + self._compute_entity_key_hash( + serialize_entity_key( + key, + entity_key_serialization_version=config.entity_key_serialization_version, + ) + ) + for key in entity_keys + ] + + # Query MongoDB + documents = list(collection.find({"entity_key_hash": {"$in": entity_key_hashes}})) + + # Build lookup map + doc_map = {doc["entity_key_hash"]: doc for doc in documents} + + # Build results in order of entity_keys + results = [] + for entity_key_hash in entity_key_hashes: + doc = doc_map.get(entity_key_hash) + + if not doc: + results.append((None, None)) + continue + + event_ts = doc.get("event_timestamp") + features_dict = {} + + for feature_name, feature_bin in doc.get("features", {}).items(): + if requested_features is None or feature_name in requested_features: + val = ValueProto() + val.ParseFromString(feature_bin) + features_dict[feature_name] = val + + results.append((event_ts, features_dict if features_dict else None)) + + return results + + async def online_read_async( + self, + config: RepoConfig, + table: FeatureView, + entity_keys: List[EntityKeyProto], + requested_features: Optional[List[str]] = None, + ) -> List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]]: + """Async version of online_read.""" + assert config.online_store.type == "mongodb" + online_config: MongoDBOnlineStoreConfig = config.online_store + + client = self._get_client_async(online_config) + db = client[online_config.database] + collection_name = get_collection_name(config.project, table.name) + collection = db[collection_name] + + entity_key_hashes = [ + self._compute_entity_key_hash( + serialize_entity_key( + key, + entity_key_serialization_version=config.entity_key_serialization_version, + ) + ) + for key in entity_keys + ] + + cursor = collection.find({"entity_key_hash": {"$in": entity_key_hashes}}) + documents = await cursor.to_list(length=len(entity_key_hashes)) + + doc_map = {doc["entity_key_hash"]: doc for doc in documents} + + results = [] + for entity_key_hash in entity_key_hashes: + doc = doc_map.get(entity_key_hash) + + if not doc: + results.append((None, None)) + continue + + event_ts = doc.get("event_timestamp") + features_dict = {} + + for feature_name, feature_bin in doc.get("features", {}).items(): + if requested_features is None or feature_name in requested_features: + val = ValueProto() + val.ParseFromString(feature_bin) + features_dict[feature_name] = val + + results.append((event_ts, features_dict if features_dict else None)) + + return results + + def update( + self, + config: RepoConfig, + tables_to_delete: Sequence[FeatureView], + tables_to_keep: Sequence[FeatureView], + entities_to_delete: Sequence[Entity], + entities_to_keep: Sequence[Entity], + partial: bool, + ): + """ + Update MongoDB resources (create/delete collections and indexes). + + Args: + config: Feast repository configuration + tables_to_delete: Feature views whose collections should be deleted + tables_to_keep: Feature views whose collections should be created/updated + entities_to_delete: Entities to delete (unused for MongoDB) + entities_to_keep: Entities to keep (unused for MongoDB) + partial: Whether this is a partial update + """ + assert config.online_store.type == "mongodb" + online_config: MongoDBOnlineStoreConfig = config.online_store + + client = self._get_client(online_config) + db = client[online_config.database] + + # Delete collections for removed feature views + for table in tables_to_delete: + collection_name = get_collection_name(config.project, table.name) + db[collection_name].drop() + logger.info(f"Dropped MongoDB collection: {collection_name}") + + # Create/update collections and indexes for feature views + for table in tables_to_keep: + collection_name = get_collection_name(config.project, table.name) + collection = db[collection_name] + + # Create unique index on entity_key_hash + try: + collection.create_index("entity_key_hash", unique=True, name="idx_entity_key_hash") + logger.info(f"Created index on entity_key_hash for {collection_name}") + except OperationFailure as e: + if "already exists" not in str(e): + raise + + # Create TTL index if configured + if online_config.ttl_seconds: + try: + collection.create_index( + "expire_at", + expireAfterSeconds=0, # TTL is encoded in the expire_at field + name="idx_ttl" + ) + logger.info(f"Created TTL index for {collection_name}") + except OperationFailure as e: + if "already exists" not in str(e): + raise + + def teardown( + self, + config: RepoConfig, + tables: Sequence[FeatureView], + entities: Sequence[Entity], + ): + """ + Tear down MongoDB resources (drop collections). + + Args: + config: Feast repository configuration + tables: Feature views whose collections should be dropped + entities: Entities (unused for MongoDB) + """ + assert config.online_store.type == "mongodb" + online_config: MongoDBOnlineStoreConfig = config.online_store + + client = self._get_client(online_config) + db = client[online_config.database] + + for table in tables: + collection_name = get_collection_name(config.project, table.name) + db[collection_name].drop() + logger.info(f"Dropped MongoDB collection during teardown: {collection_name}") + + # TODO: Implement vector search methods in next iteration + # def retrieve_online_documents_v2(...) + # async def initialize(...) + # async def close(...) diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/__init__.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/__init__.py new file mode 100644 index 00000000000..092b88538ea --- /dev/null +++ b/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/__init__.py @@ -0,0 +1 @@ +# Tests for MongoDB Online Store diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/test_mongodb_online.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/test_mongodb_online.py new file mode 100644 index 00000000000..ba0e48e4536 --- /dev/null +++ b/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/test_mongodb_online.py @@ -0,0 +1,629 @@ +# Copyright 2025 The Feast Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Unit and integration tests for MongoDB Online Store. + +These tests cover: +- Configuration validation +- CRUD operations (sync and async) +- Index creation +- TTL functionality +- Connection management +""" + +import os +from datetime import datetime, timedelta +from unittest.mock import Mock, patch, MagicMock + +import pytest + +from feast import Entity, FeatureView, Field, FileSource, RepoConfig +from feast.infra.online_stores.mongodb_online_store.mongodb import ( + MongoDBOnlineStore, + MongoDBOnlineStoreConfig, +) +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, String, Float32 +from feast.value_type import ValueType + + +class TestMongoDBOnlineStoreConfig: + """Test suite for MongoDBOnlineStoreConfig.""" + + def test_default_config(self): + """Test default configuration values.""" + config = MongoDBOnlineStoreConfig( + connection_string="mongodb://localhost:27017" + ) + + assert config.type == "mongodb" + assert config.database == "feast" + assert config.max_pool_size == 50 + assert config.min_pool_size == 10 + assert config.ttl_seconds is None + assert config.atlas_vector_search_enabled is False + assert config.vector_index_name == "vector_index" + assert config.vector_similarity_metric == "cosine" + assert config.write_concern_w == 1 + assert config.read_preference == "primaryPreferred" + + def test_custom_config(self): + """Test custom configuration values.""" + config = MongoDBOnlineStoreConfig( + connection_string="mongodb+srv://user:pass@cluster.mongodb.net", + database="custom_db", + max_pool_size=100, + min_pool_size=20, + ttl_seconds=86400, + atlas_vector_search_enabled=True, + vector_similarity_metric="euclidean", + write_concern_w=2, + read_preference="primary", + ) + + assert config.database == "custom_db" + assert config.max_pool_size == 100 + assert config.min_pool_size == 20 + assert config.ttl_seconds == 86400 + assert config.atlas_vector_search_enabled is True + assert config.vector_similarity_metric == "euclidean" + assert config.write_concern_w == 2 + assert config.read_preference == "primary" + + def test_atlas_connection_string(self): + """Test Atlas connection string format.""" + config = MongoDBOnlineStoreConfig( + connection_string="mongodb+srv://cluster.mongodb.net" + ) + assert "mongodb+srv://" in config.connection_string + + +class TestMongoDBOnlineStore: + """Test suite for MongoDBOnlineStore implementation.""" + + @pytest.fixture + def mock_config(self): + """Create a mock RepoConfig for testing.""" + return RepoConfig( + project="test_project", + online_store=MongoDBOnlineStoreConfig( + connection_string="mongodb://localhost:27017", + database="feast_test", + ), + registry="dummy_registry", + ) + + @pytest.fixture + def mock_config_with_ttl(self): + """Create a mock RepoConfig with TTL enabled.""" + return RepoConfig( + project="test_project", + online_store=MongoDBOnlineStoreConfig( + connection_string="mongodb://localhost:27017", + database="feast_test", + ttl_seconds=86400, + ), + registry="dummy_registry", + ) + + @pytest.fixture + def feature_view(self): + """Create a test FeatureView.""" + entity = Entity( + name="user_id", description="User ID", value_type=ValueType.INT64 + ) + source = FileSource(path="test.parquet", timestamp_field="event_timestamp") + return FeatureView( + name="test_features", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="user_id", dtype=Int64), + Field(name="feature1", dtype=String), + Field(name="feature2", dtype=Float32), + ], + source=source, + ) + + @pytest.fixture + def entity_keys(self): + """Create test entity keys.""" + keys = [] + for i in range(3): + key = EntityKeyProto() + key.join_keys.append(f"user_{i}") + key.entity_values.append( + ValueProto(int64_val=i) + ) + keys.append(key) + return keys + + @pytest.fixture + def feature_data(self, entity_keys): + """Create test feature data.""" + data = [] + timestamp = datetime.utcnow() + + for i, key in enumerate(entity_keys): + features = { + "feature1": ValueProto(string_val=f"value_{i}"), + "feature2": ValueProto(float_val=float(i) * 1.5), + } + data.append((key, features, timestamp, None)) + + return data + + def test_compute_entity_key_hash(self): + """Test entity key hashing.""" + store = MongoDBOnlineStore() + + # Test consistent hashing + key_bin = b"test_entity_key" + hash1 = store._compute_entity_key_hash(key_bin) + hash2 = store._compute_entity_key_hash(key_bin) + + assert hash1 == hash2 + assert isinstance(hash1, str) + assert len(hash1) == 32 # MD5 hash length + + def test_async_supported(self): + """Test that async operations are supported.""" + store = MongoDBOnlineStore() + async_methods = store.async_supported + + assert async_methods.read is True + assert async_methods.write is True + + @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") + def test_online_write_batch(self, mock_get_client, mock_config, feature_view, feature_data): + """Test synchronous write batch operation.""" + # Mock MongoDB client and collection + mock_client = MagicMock() + mock_db = MagicMock() + mock_collection = MagicMock() + + mock_client.__getitem__.return_value = mock_db + mock_db.__getitem__.return_value = mock_collection + mock_get_client.return_value = mock_client + + # Create store and write data + store = MongoDBOnlineStore() + store.online_write_batch( + config=mock_config, + table=feature_view, + data=feature_data, + progress=None, + ) + + # Verify client was created + mock_get_client.assert_called_once() + + # Verify bulk_write was called + mock_collection.bulk_write.assert_called_once() + + # Get the bulk operations + call_args = mock_collection.bulk_write.call_args + operations = call_args[0][0] + + # Verify we have the right number of operations + assert len(operations) == len(feature_data) + + @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") + def test_online_write_batch_with_ttl( + self, mock_get_client, mock_config_with_ttl, feature_view, feature_data + ): + """Test write batch with TTL enabled.""" + mock_client = MagicMock() + mock_db = MagicMock() + mock_collection = MagicMock() + + mock_client.__getitem__.return_value = mock_db + mock_db.__getitem__.return_value = mock_collection + mock_get_client.return_value = mock_client + + store = MongoDBOnlineStore() + store.online_write_batch( + config=mock_config_with_ttl, + table=feature_view, + data=feature_data, + progress=None, + ) + + # Verify bulk_write was called + assert mock_collection.bulk_write.called + + @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") + def test_online_read(self, mock_get_client, mock_config, feature_view, entity_keys): + """Test synchronous read operation.""" + # Mock MongoDB client and collection + mock_client = MagicMock() + mock_db = MagicMock() + mock_collection = MagicMock() + + mock_client.__getitem__.return_value = mock_db + mock_db.__getitem__.return_value = mock_collection + mock_get_client.return_value = mock_client + + # Mock find result + mock_doc = { + "entity_key_hash": "test_hash", + "event_timestamp": datetime.utcnow(), + "features": { + "feature1": ValueProto(string_val="test").SerializeToString(), + "feature2": ValueProto(float_val=1.5).SerializeToString(), + }, + } + mock_collection.find.return_value = [mock_doc] + + # Create store and read data + store = MongoDBOnlineStore() + results = store.online_read( + config=mock_config, + table=feature_view, + entity_keys=entity_keys, + requested_features=None, + ) + + # Verify results + assert len(results) == len(entity_keys) + assert mock_collection.find.called + + @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") + def test_online_read_with_missing_entities( + self, mock_get_client, mock_config, feature_view, entity_keys + ): + """Test read operation with some missing entities.""" + mock_client = MagicMock() + mock_db = MagicMock() + mock_collection = MagicMock() + + mock_client.__getitem__.return_value = mock_db + mock_db.__getitem__.return_value = mock_collection + mock_get_client.return_value = mock_client + + # Return empty list (no documents found) + mock_collection.find.return_value = [] + + store = MongoDBOnlineStore() + results = store.online_read( + config=mock_config, + table=feature_view, + entity_keys=entity_keys, + requested_features=None, + ) + + # All results should be (None, None) for missing entities + assert len(results) == len(entity_keys) + for event_ts, features in results: + assert event_ts is None + assert features is None + + @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") + def test_update_creates_indexes(self, mock_get_client, mock_config, feature_view): + """Test that update creates necessary indexes.""" + mock_client = MagicMock() + mock_db = MagicMock() + mock_collection = MagicMock() + + mock_client.__getitem__.return_value = mock_db + mock_db.__getitem__.return_value = mock_collection + mock_get_client.return_value = mock_client + + store = MongoDBOnlineStore() + store.update( + config=mock_config, + tables_to_delete=[], + tables_to_keep=[feature_view], + entities_to_delete=[], + entities_to_keep=[], + partial=False, + ) + + # Verify create_index was called for entity_key_hash + assert mock_collection.create_index.called + call_args_list = mock_collection.create_index.call_args_list + + # Should have at least one create_index call + assert len(call_args_list) >= 1 + + @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") + def test_update_creates_ttl_index( + self, mock_get_client, mock_config_with_ttl, feature_view + ): + """Test that update creates TTL index when TTL is configured.""" + mock_client = MagicMock() + mock_db = MagicMock() + mock_collection = MagicMock() + + mock_client.__getitem__.return_value = mock_db + mock_db.__getitem__.return_value = mock_collection + mock_get_client.return_value = mock_client + + store = MongoDBOnlineStore() + store.update( + config=mock_config_with_ttl, + tables_to_delete=[], + tables_to_keep=[feature_view], + entities_to_delete=[], + entities_to_keep=[], + partial=False, + ) + + # Verify create_index was called + assert mock_collection.create_index.called + + @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") + def test_update_deletes_collections(self, mock_get_client, mock_config, feature_view): + """Test that update deletes collections for removed feature views.""" + mock_client = MagicMock() + mock_db = MagicMock() + mock_collection = MagicMock() + + mock_client.__getitem__.return_value = mock_db + mock_db.__getitem__.return_value = mock_collection + mock_get_client.return_value = mock_client + + store = MongoDBOnlineStore() + store.update( + config=mock_config, + tables_to_delete=[feature_view], + tables_to_keep=[], + entities_to_delete=[], + entities_to_keep=[], + partial=False, + ) + + # Verify collection.drop was called + assert mock_collection.drop.called + + @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") + def test_teardown(self, mock_get_client, mock_config, feature_view): + """Test teardown operation.""" + mock_client = MagicMock() + mock_db = MagicMock() + mock_collection = MagicMock() + + mock_client.__getitem__.return_value = mock_db + mock_db.__getitem__.return_value = mock_collection + mock_get_client.return_value = mock_client + + store = MongoDBOnlineStore() + store.teardown( + config=mock_config, + tables=[feature_view], + entities=[], + ) + + # Verify collection.drop was called + assert mock_collection.drop.called + + +class TestMongoDBOnlineStoreAsync: + """Test suite for async operations.""" + + @pytest.fixture + def mock_config(self): + """Create a mock RepoConfig for testing.""" + return RepoConfig( + project="test_project", + online_store=MongoDBOnlineStoreConfig( + connection_string="mongodb://localhost:27017", + database="feast_test", + ), + registry="dummy_registry", + ) + + @pytest.fixture + def feature_view(self): + """Create a test FeatureView.""" + entity = Entity( + name="user_id", description="User ID", value_type=ValueType.INT64 + ) + source = FileSource(path="test.parquet", timestamp_field="event_timestamp") + return FeatureView( + name="test_features", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="user_id", dtype=Int64), + Field(name="feature1", dtype=String), + ], + source=source, + ) + + @pytest.mark.asyncio + @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_async_mongo_client") + async def test_online_write_batch_async( + self, mock_get_client_async, mock_config, feature_view + ): + """Test async write batch operation.""" + # Mock async MongoDB client + mock_client = MagicMock() + mock_db = MagicMock() + mock_collection = MagicMock() + mock_collection.bulk_write = MagicMock(return_value=None) + + mock_client.__getitem__.return_value = mock_db + mock_db.__getitem__.return_value = mock_collection + mock_get_client_async.return_value = mock_client + + # Create test data + entity_key = EntityKeyProto() + entity_key.join_keys.append("user_id") + entity_key.entity_values.append(ValueProto(int64_val=123)) + + features = { + "feature1": ValueProto(string_val="test"), + } + + data = [(entity_key, features, datetime.utcnow(), None)] + + # Write data + store = MongoDBOnlineStore() + await store.online_write_batch_async( + config=mock_config, + table=feature_view, + data=data, + progress=None, + ) + + # Verify client was created + mock_get_client_async.assert_called_once() + + @pytest.mark.asyncio + @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_async_mongo_client") + async def test_online_read_async( + self, mock_get_client_async, mock_config, feature_view + ): + """Test async read operation.""" + # Mock async MongoDB client + mock_client = MagicMock() + mock_db = MagicMock() + mock_collection = MagicMock() + + # Mock cursor + mock_cursor = MagicMock() + mock_cursor.to_list = MagicMock(return_value=[]) + mock_collection.find.return_value = mock_cursor + + mock_client.__getitem__.return_value = mock_db + mock_db.__getitem__.return_value = mock_collection + mock_get_client_async.return_value = mock_client + + # Create test entity key + entity_key = EntityKeyProto() + entity_key.join_keys.append("user_id") + entity_key.entity_values.append(ValueProto(int64_val=123)) + + # Read data + store = MongoDBOnlineStore() + results = await store.online_read_async( + config=mock_config, + table=feature_view, + entity_keys=[entity_key], + requested_features=None, + ) + + # Verify results + assert len(results) == 1 + mock_collection.find.assert_called_once() + + +@pytest.mark.integration +@pytest.mark.skipif( + os.getenv("MONGODB_CONNECTION_STRING") is None, + reason="MongoDB connection string not provided. Set MONGODB_CONNECTION_STRING env var to run integration tests.", +) +class TestMongoDBOnlineStoreIntegration: + """ + Integration tests for MongoDB Online Store. + + These tests require a running MongoDB instance. + Set MONGODB_CONNECTION_STRING environment variable to run these tests. + Example: export MONGODB_CONNECTION_STRING="mongodb://localhost:27017" + """ + + @pytest.fixture + def mongodb_config(self): + """Create configuration using real MongoDB connection.""" + return RepoConfig( + project="integration_test", + online_store=MongoDBOnlineStoreConfig( + connection_string=os.getenv("MONGODB_CONNECTION_STRING"), + database="feast_integration_test", + ), + registry="dummy_registry", + ) + + @pytest.fixture + def feature_view(self): + """Create a test FeatureView.""" + entity = Entity( + name="user_id", description="User ID", value_type=ValueType.INT64 + ) + source = FileSource(path="test.parquet", timestamp_field="event_timestamp") + return FeatureView( + name="test_integration_features", + entities=[entity], + ttl=timedelta(days=1), + schema=[ + Field(name="user_id", dtype=Int64), + Field(name="feature1", dtype=String), + Field(name="feature2", dtype=Float32), + ], + source=source, + ) + + def test_full_write_read_cycle(self, mongodb_config, feature_view): + """Test a complete write and read cycle with real MongoDB.""" + store = MongoDBOnlineStore() + + # Setup: Create indexes + store.update( + config=mongodb_config, + tables_to_delete=[], + tables_to_keep=[feature_view], + entities_to_delete=[], + entities_to_keep=[], + partial=False, + ) + + # Create test data + entity_key = EntityKeyProto() + entity_key.join_keys.append("user_id") + entity_key.entity_values.append(ValueProto(int64_val=123)) + + features = { + "feature1": ValueProto(string_val="integration_test_value"), + "feature2": ValueProto(float_val=42.5), + } + + timestamp = datetime.utcnow() + data = [(entity_key, features, timestamp, None)] + + # Write data + store.online_write_batch( + config=mongodb_config, + table=feature_view, + data=data, + progress=None, + ) + + # Read data back + results = store.online_read( + config=mongodb_config, + table=feature_view, + entity_keys=[entity_key], + requested_features=None, + ) + + # Verify results + assert len(results) == 1 + event_ts, feature_dict = results[0] + + assert event_ts is not None + assert feature_dict is not None + assert "feature1" in feature_dict + assert "feature2" in feature_dict + assert feature_dict["feature1"].string_val == "integration_test_value" + assert abs(feature_dict["feature2"].float_val - 42.5) < 0.01 + + # Cleanup + store.teardown( + config=mongodb_config, + tables=[feature_view], + entities=[], + ) diff --git a/sdk/python/feast/infra/utils/mongodb/__init__.py b/sdk/python/feast/infra/utils/mongodb/__init__.py new file mode 100644 index 00000000000..327a4330cb7 --- /dev/null +++ b/sdk/python/feast/infra/utils/mongodb/__init__.py @@ -0,0 +1 @@ +# MongoDB utilities for Feast diff --git a/sdk/python/feast/infra/utils/mongodb/connection_utils.py b/sdk/python/feast/infra/utils/mongodb/connection_utils.py new file mode 100644 index 00000000000..210fa444e42 --- /dev/null +++ b/sdk/python/feast/infra/utils/mongodb/connection_utils.py @@ -0,0 +1,222 @@ +# 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. + +""" +MongoDB connection utilities for Feast. + +This module provides helper functions for creating and managing MongoDB connections +for both the online and offline stores. +""" + +import logging +from typing import Any, Union + +try: + from pymongo import MongoClient + from pymongo.mongo_client import AsyncMongoClient + from pymongo.read_preferences import ReadPreference +except ImportError as e: + from feast.errors import FeastExtrasDependencyImportError + + raise FeastExtrasDependencyImportError("mongodb", str(e)) + +logger = logging.getLogger(__name__) + + +def get_mongo_client( + connection_string: str, + max_pool_size: int = 50, + min_pool_size: int = 10, + write_concern_w: Union[int, str] = 1, + read_preference: str = "primaryPreferred", + **kwargs: Any, +) -> MongoClient: + """ + Create a synchronous MongoDB client with connection pooling. + + Args: + connection_string: MongoDB connection URI (mongodb:// or mongodb+srv://) + max_pool_size: Maximum number of connections in the pool + min_pool_size: Minimum number of connections in the pool + write_concern_w: Write concern level (1, 'majority', etc.) + read_preference: Read preference ('primary', 'primaryPreferred', 'secondary', etc.) + **kwargs: Additional keyword arguments to pass to MongoClient + + Returns: + MongoClient instance configured with connection pooling + + Raises: + ConnectionError: If connection to MongoDB fails + """ + read_pref = _parse_read_preference(read_preference) + + try: + client = MongoClient( + connection_string, + maxPoolSize=max_pool_size, + minPoolSize=min_pool_size, + w=write_concern_w, + readPreference=read_pref, + **kwargs, + ) + # Test the connection + client.admin.command("ping") + logger.info( + f"Successfully connected to MongoDB (pool size: {min_pool_size}-{max_pool_size})" + ) + return client + except Exception as e: + logger.error(f"Failed to connect to MongoDB: {e}") + raise ConnectionError(f"Failed to connect to MongoDB: {e}") from e + + +def get_async_mongo_client( + connection_string: str, + max_pool_size: int = 50, + min_pool_size: int = 10, + write_concern_w: Union[int, str] = 1, + read_preference: str = "primaryPreferred", + **kwargs: Any, +) -> AsyncMongoClient: + """ + Create an asynchronous MongoDB client with connection pooling. + + Args: + connection_string: MongoDB connection URI (mongodb:// or mongodb+srv://) + max_pool_size: Maximum number of connections in the pool + min_pool_size: Minimum number of connections in the pool + write_concern_w: Write concern level (1, 'majority', etc.) + read_preference: Read preference ('primary', 'primaryPreferred', 'secondary', etc.) + **kwargs: Additional keyword arguments to pass to AsyncMongoClient + + Returns: + AsyncMongoClient instance configured with connection pooling + + Raises: + ConnectionError: If connection to MongoDB fails + """ + read_pref = _parse_read_preference(read_preference) + + try: + client = AsyncMongoClient( + connection_string, + maxPoolSize=max_pool_size, + minPoolSize=min_pool_size, + w=write_concern_w, + readPreference=read_pref, + **kwargs, + ) + logger.info( + f"Async MongoDB client created (pool size: {min_pool_size}-{max_pool_size})" + ) + return client + except Exception as e: + logger.error(f"Failed to create async MongoDB client: {e}") + raise ConnectionError(f"Failed to create async MongoDB client: {e}") from e + + +def is_atlas(client: MongoClient) -> bool: + """ + Detect if the MongoDB client is connected to MongoDB Atlas. + + Args: + client: MongoDB client instance + + Returns: + True if connected to Atlas, False otherwise + """ + try: + build_info = client.admin.command("buildInfo") + modules = build_info.get("modules", []) + is_atlas_deployment = "enterprise" in modules or "atlas" in str( + build_info + ).lower() + logger.debug(f"Atlas detection: {is_atlas_deployment} (modules: {modules})") + return is_atlas_deployment + except Exception as e: + logger.warning(f"Failed to detect Atlas deployment: {e}") + return False + + +async def is_atlas_async(client: AsyncMongoClient) -> bool: + """ + Async version: Detect if the MongoDB client is connected to MongoDB Atlas. + + Args: + client: Async MongoDB client instance + + Returns: + True if connected to Atlas, False otherwise + """ + try: + build_info = await client.admin.command("buildInfo") + modules = build_info.get("modules", []) + is_atlas_deployment = "enterprise" in modules or "atlas" in str( + build_info + ).lower() + logger.debug(f"Atlas detection: {is_atlas_deployment} (modules: {modules})") + return is_atlas_deployment + except Exception as e: + logger.warning(f"Failed to detect Atlas deployment: {e}") + return False + + +def _parse_read_preference(read_preference: str) -> ReadPreference: + """ + Convert string read preference to PyMongo ReadPreference enum. + + Args: + read_preference: String representation of read preference + + Returns: + ReadPreference enum value + + Raises: + ValueError: If read_preference is not valid + """ + preference_map = { + "primary": ReadPreference.PRIMARY, + "primaryPreferred": ReadPreference.PRIMARY_PREFERRED, + "secondary": ReadPreference.SECONDARY, + "secondaryPreferred": ReadPreference.SECONDARY_PREFERRED, + "nearest": ReadPreference.NEAREST, + } + + if read_preference not in preference_map: + raise ValueError( + f"Invalid read preference: {read_preference}. " + f"Valid options: {list(preference_map.keys())}" + ) + + return preference_map[read_preference] + + +def get_collection_name(project: str, table_name: str) -> str: + """ + Generate a MongoDB collection name from Feast project and table name. + + Args: + project: Feast project name + table_name: Feature view or table name + + Returns: + Collection name in format: {project}_{table_name} + """ + # Sanitize names to ensure valid MongoDB collection names + # MongoDB collection names cannot contain: $ or null character + # and should not start with "system." + safe_project = project.replace("$", "_").replace("\x00", "") + safe_table = table_name.replace("$", "_").replace("\x00", "") + + return f"{safe_project}_{safe_table}" diff --git a/sdk/python/feast/infra/utils/mongodb/test_connection_utils.py b/sdk/python/feast/infra/utils/mongodb/test_connection_utils.py new file mode 100644 index 00000000000..68491de9fd0 --- /dev/null +++ b/sdk/python/feast/infra/utils/mongodb/test_connection_utils.py @@ -0,0 +1,240 @@ +# Copyright 2025 The Feast Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Unit tests for MongoDB connection utilities. +""" + +import pytest +from unittest.mock import MagicMock, patch + +from feast.infra.utils.mongodb.connection_utils import ( + get_mongo_client, + get_async_mongo_client, + is_atlas, + _parse_read_preference, + get_collection_name, +) + +try: + from pymongo.read_preferences import ReadPreference +except ImportError: + pytest.skip("pymongo not installed", allow_module_level=True) + + +class TestReadPreferenceParsing: + """Test read preference parsing.""" + + def test_primary(self): + """Test parsing 'primary' read preference.""" + result = _parse_read_preference("primary") + assert result == ReadPreference.PRIMARY + + def test_primary_preferred(self): + """Test parsing 'primaryPreferred' read preference.""" + result = _parse_read_preference("primaryPreferred") + assert result == ReadPreference.PRIMARY_PREFERRED + + def test_secondary(self): + """Test parsing 'secondary' read preference.""" + result = _parse_read_preference("secondary") + assert result == ReadPreference.SECONDARY + + def test_secondary_preferred(self): + """Test parsing 'secondaryPreferred' read preference.""" + result = _parse_read_preference("secondaryPreferred") + assert result == ReadPreference.SECONDARY_PREFERRED + + def test_nearest(self): + """Test parsing 'nearest' read preference.""" + result = _parse_read_preference("nearest") + assert result == ReadPreference.NEAREST + + def test_invalid_preference(self): + """Test that invalid preference raises ValueError.""" + with pytest.raises(ValueError, match="Invalid read preference"): + _parse_read_preference("invalid_preference") + + +class TestCollectionNameGeneration: + """Test collection name generation.""" + + def test_basic_names(self): + """Test basic project and table names.""" + result = get_collection_name("my_project", "my_table") + assert result == "my_project_my_table" + + def test_sanitizes_dollar_sign(self): + """Test that dollar signs are replaced.""" + result = get_collection_name("project$name", "table$name") + assert result == "project_name_table_name" + assert "$" not in result + + def test_sanitizes_null_character(self): + """Test that null characters are removed.""" + result = get_collection_name("project\x00name", "table\x00name") + assert result == "projectname_tablename" + assert "\x00" not in result + + def test_handles_underscores(self): + """Test that underscores are preserved.""" + result = get_collection_name("my_project", "my_table") + assert result == "my_project_my_table" + + +class TestMongoClientCreation: + """Test MongoDB client creation.""" + + @patch("feast.infra.utils.mongodb.connection_utils.MongoClient") + def test_get_mongo_client_default_params(self, mock_mongo_client): + """Test client creation with default parameters.""" + mock_client_instance = MagicMock() + mock_mongo_client.return_value = mock_client_instance + + connection_string = "mongodb://localhost:27017" + client = get_mongo_client(connection_string) + + # Verify MongoClient was called with correct parameters + mock_mongo_client.assert_called_once() + call_kwargs = mock_mongo_client.call_args[1] + + assert call_kwargs["maxPoolSize"] == 50 + assert call_kwargs["minPoolSize"] == 10 + assert call_kwargs["w"] == 1 + + # Verify ping was called to test connection + mock_client_instance.admin.command.assert_called_once_with("ping") + + @patch("feast.infra.utils.mongodb.connection_utils.MongoClient") + def test_get_mongo_client_custom_params(self, mock_mongo_client): + """Test client creation with custom parameters.""" + mock_client_instance = MagicMock() + mock_mongo_client.return_value = mock_client_instance + + connection_string = "mongodb://localhost:27017" + client = get_mongo_client( + connection_string, + max_pool_size=100, + min_pool_size=20, + write_concern_w=2, + read_preference="primary", + ) + + # Verify MongoClient was called with custom parameters + mock_mongo_client.assert_called_once() + call_kwargs = mock_mongo_client.call_args[1] + + assert call_kwargs["maxPoolSize"] == 100 + assert call_kwargs["minPoolSize"] == 20 + assert call_kwargs["w"] == 2 + assert call_kwargs["readPreference"] == ReadPreference.PRIMARY + + @patch("feast.infra.utils.mongodb.connection_utils.MongoClient") + def test_get_mongo_client_connection_failure(self, mock_mongo_client): + """Test that connection failures raise ConnectionError.""" + mock_client_instance = MagicMock() + mock_client_instance.admin.command.side_effect = Exception("Connection failed") + mock_mongo_client.return_value = mock_client_instance + + connection_string = "mongodb://invalid:27017" + + with pytest.raises(ConnectionError, match="Failed to connect to MongoDB"): + get_mongo_client(connection_string) + + @patch("feast.infra.utils.mongodb.connection_utils.AsyncMongoClient") + def test_get_async_mongo_client(self, mock_async_mongo_client): + """Test async client creation.""" + mock_client_instance = MagicMock() + mock_async_mongo_client.return_value = mock_client_instance + + connection_string = "mongodb://localhost:27017" + client = get_async_mongo_client(connection_string) + + # Verify AsyncMongoClient was called + mock_async_mongo_client.assert_called_once() + call_kwargs = mock_async_mongo_client.call_args[1] + + assert call_kwargs["maxPoolSize"] == 50 + assert call_kwargs["minPoolSize"] == 10 + + @patch("feast.infra.utils.mongodb.connection_utils.AsyncMongoClient") + def test_get_async_mongo_client_connection_failure(self, mock_async_mongo_client): + """Test that async client creation failures raise ConnectionError.""" + mock_async_mongo_client.side_effect = Exception("Connection failed") + + connection_string = "mongodb://invalid:27017" + + with pytest.raises(ConnectionError, match="Failed to create async MongoDB client"): + get_async_mongo_client(connection_string) + + +class TestAtlasDetection: + """Test MongoDB Atlas detection.""" + + def test_is_atlas_with_enterprise_module(self): + """Test Atlas detection with enterprise module.""" + mock_client = MagicMock() + mock_client.admin.command.return_value = { + "version": "5.0.0", + "modules": ["enterprise"], + } + + result = is_atlas(mock_client) + assert result is True + + def test_is_atlas_with_atlas_in_build_info(self): + """Test Atlas detection with 'atlas' in build info.""" + mock_client = MagicMock() + mock_client.admin.command.return_value = { + "version": "5.0.0-atlas", + "modules": [], + } + + result = is_atlas(mock_client) + assert result is True + + def test_is_not_atlas(self): + """Test non-Atlas deployment detection.""" + mock_client = MagicMock() + mock_client.admin.command.return_value = { + "version": "5.0.0", + "modules": [], + } + + result = is_atlas(mock_client) + assert result is False + + def test_is_atlas_exception_handling(self): + """Test that exceptions in Atlas detection return False.""" + mock_client = MagicMock() + mock_client.admin.command.side_effect = Exception("Command failed") + + result = is_atlas(mock_client) + assert result is False + + @pytest.mark.asyncio + async def test_is_atlas_async(self): + """Test async Atlas detection.""" + from feast.infra.utils.mongodb.connection_utils import is_atlas_async + + mock_client = MagicMock() + mock_client.admin.command = MagicMock( + return_value={ + "version": "5.0.0", + "modules": ["enterprise"], + } + ) + + result = await is_atlas_async(mock_client) + assert result is True diff --git a/sdk/python/feast/repo_config.py b/sdk/python/feast/repo_config.py index 56ed9e26996..2ca2616bff1 100644 --- a/sdk/python/feast/repo_config.py +++ b/sdk/python/feast/repo_config.py @@ -82,6 +82,7 @@ "qdrant": "feast.infra.online_stores.qdrant_online_store.qdrant.QdrantOnlineStore", "couchbase.online": "feast.infra.online_stores.couchbase_online_store.couchbase.CouchbaseOnlineStore", "milvus": "feast.infra.online_stores.milvus_online_store.milvus.MilvusOnlineStore", + "mongodb": "feast.infra.online_stores.mongodb_online_store.mongodb.MongoDBOnlineStore", "hybrid": "feast.infra.online_stores.hybrid_online_store.hybrid_online_store.HybridOnlineStore", **LEGACY_ONLINE_STORE_CLASS_FOR_TYPE, } @@ -101,6 +102,7 @@ "remote": "feast.infra.offline_stores.remote.RemoteOfflineStore", "couchbase.offline": "feast.infra.offline_stores.contrib.couchbase_offline_store.couchbase.CouchbaseColumnarOfflineStore", "clickhouse": "feast.infra.offline_stores.contrib.clickhouse_offline_store.clickhouse.ClickhouseOfflineStore", + "mongodb.offline": "feast.infra.offline_stores.contrib.mongodb_offline_store.mongodb.MongoDBOfflineStore", "ray": "feast.infra.offline_stores.contrib.ray_offline_store.ray.RayOfflineStore", } diff --git a/test_registry b/test_registry new file mode 100644 index 00000000000..9757347d5b4 --- /dev/null +++ b/test_registry @@ -0,0 +1 @@ +1"$558ef025-a9ab-4dc8-9679-6fa37dd8320f* ôˆšË˜×³™ \ No newline at end of file From 4d0f066d941b9d5761e4d3e437080a5027d1d6a6 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Tue, 20 Jan 2026 15:50:03 -0500 Subject: [PATCH 02/47] Added mongodb to project.optional-dependencies in pyproject.toml. Now pymongo is found as extra Signed-off-by: Casey Clements --- pyproject.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 21d57bed6ae..e991d5b4bf1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -97,10 +97,13 @@ milvus = [ "milvus-lite==2.4.12", "feast[setuptools]" ] +mongodb = [ + "pymongo>=4.6.0,<5.0.0", + "dnspython>=2.0.0", +] mssql = ["ibis-framework[mssql]>=10.0.0"] mysql = ["pymysql", "types-PyMySQL"] opentelemetry = ["prometheus_client", "psutil"] -openlineage = ["openlineage-python>=1.40.0"] spark = ["pyspark>=4.0.0"] trino = ["trino>=0.305.0,<0.400.0", "regex"] postgres = ["psycopg[binary,pool]==3.2.5"] From 18b16b958865e74ac0dc8553b5490cd0034efcd0 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Thu, 12 Feb 2026 18:07:57 -0500 Subject: [PATCH 03/47] Checkpoint. Passing tests.unit.online_store.test_online_writes.TestOnlineWrites with default args of MongoDBOnlineStoreConfig. Lots to do. Signed-off-by: Casey Clements --- .../docs/point_in_time.md | 255 + .../{mongodb.py => mongodb_claude.py} | 45 +- .../mongodb_online_store/mongodb_openai.py | 398 + .../tests/test_mongodb_online.py | 27 +- .../infra/utils/mongodb/connection_utils.py | 10 +- .../py3.11-mongodb-dev-requirements.txt | 7078 +++++++++++++++++ .../unit/online_store/test_online_writes.py | 9 +- 7 files changed, 7777 insertions(+), 45 deletions(-) create mode 100644 sdk/python/feast/infra/online_stores/mongodb_online_store/docs/point_in_time.md rename sdk/python/feast/infra/online_stores/mongodb_online_store/{mongodb.py => mongodb_claude.py} (94%) create mode 100644 sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_openai.py create mode 100644 sdk/python/requirements/py3.11-mongodb-dev-requirements.txt diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/docs/point_in_time.md b/sdk/python/feast/infra/online_stores/mongodb_online_store/docs/point_in_time.md new file mode 100644 index 00000000000..8e62ce21d1b --- /dev/null +++ b/sdk/python/feast/infra/online_stores/mongodb_online_store/docs/point_in_time.md @@ -0,0 +1,255 @@ +# Point-in-Time Joins in the MongoDB Offline Store + +This document describes the point-in-time join semantics supported by the MongoDB Offline Store implementation for Feast. + +The join logic itself is not implemented inside the Offline Store. Instead, the store’s schema, indexing strategy, and query guarantees are explicitly designed to support Feast’s point-in-time correctness model. + +## 1. Conceptual Overview + +A point-in-time join answers the question: + +Given an event that occurred at time T for entity E, what were the feature values that existed at or before T? + +This prevents data leakage by ensuring that training data never observes future feature values. + +Within Feast: +* Point-in-time semantics are defined by Feast core +* Store implementations provide efficient access primitives +* Joins are orchestrated above the store layer + +The MongoDB Offline Store enables these joins without embedding join logic itself. + +## 2. Key Concepts + +### Training Events + +A training event represents an observation used for model training. + +Each training event must include: +* One or more entity keys +* An event timestamp + +Example (taxi ride): +``` +{ + "_id": ObjectId("..."), + "driver_id": 123, + "pickup_ts": ISODate("2026-01-20T12:00:30Z"), + "fare": 18.50, + "tip": 3.25, + "label": 1 +} +``` +Training events: +* Are not owned by Feast +* Are not mutated by the Offline Store +* May live in any domain-specific collection + +### Feature History (Offline Store) + +Feature data is stored in an append-only MongoDB collection. + +Each document represents: +* One entity +* One feature view +* One event timestamp + +``` +{ + "_id": ObjectId("..."), + "entity_key": { + "driver_id": 123 + }, + "feature_view": "driver_stats", + "event_timestamp": ISODate("2026-01-20T12:00:00Z"), + "features": { + "rating": 4.91, + "trips_last_7d": 132 + } +} +``` +Multiple rows may exist for the same entity and feature view, distinguished only by timestamp. + +## 3. Required Schema Guarantees + +The MongoDB Offline Store must guarantee the following properties: +* Append-only writes + Feature rows are never updated or deleted. +* Monotonically increasing timestamps per entity + Newer feature values always have later timestamps. +* One row per (entity, feature_view, event_timestamp) + This ensures deterministic joins. + +⸻ + +## 4. Required Indexes + +To support efficient point-in-time queries, the following index is required on the feature history collection: + +``` +db.feature_history.create_index({ + "entity_key.driver_id": 1, + "feature_view": 1, + "event_timestamp": -1 +}) +``` +This index enables efficient retrieval of the most recent feature row at or before a given timestamp. + +## 5. Point-in-Time Join Semantics + +For each training event E and each feature view FV: + 1. Match feature rows with the same entity key + 2. Filter rows where +feature.event_timestamp ≤ training.event_timestamp + 3. Select the row with the maximum event_timestamp + +Each feature view is joined independently to avoid cross-feature coupling. + +⸻ + +## 6. Example: Taxi Ride Training Join (MongoDB Aggregation) + +### Training Events Collection +``` +{ + "_id": ObjectId("..."), + "driver_id": 123, + "pickup_ts": ISODate("2026-01-20T12:00:30Z"), + "fare": 18.50, + "label": 1 +} +``` +### Feature History Collection +``` +[{ + "entity_key": { "driver_id": 123 }, + "feature_view": "driver_stats", + "event_timestamp": ISODate("2026-01-20T12:00:00Z"), + "features": { + "rating": 4.91, + "trips_last_7d": 132 + } +}, +{ + "entity_key": { "driver_id": 123 }, + "feature_view": "pricing", + "event_timestamp": ISODate("2026-01-20T12:01:00Z"), + "features": { + "surge_multiplier": 1.2 + } +}] +``` + +### Aggregation Pipeline (Single Pass, No Application Loops) + +The following aggregation performs point-in-time joins for multiple feature views in a single pipeline. + +```python +pipeline = [ + { + "$lookup": { + "from": "feature_history", + "let": { + "driver_id": "$driver_id", + "event_ts": "$pickup_ts" + }, + "pipeline": [ + { + "$match": { + "$expr": { + "$and": [ + { "$eq": ["$entity_key.driver_id", "$$driver_id"] }, + { "$lte": ["$event_timestamp", "$$event_ts"] } + ] + } + } + }, + { "$sort": { "event_timestamp": -1 } }, + { + "$group": { + "_id": "$feature_view", + "features": { "$first": "$features" }, + "event_timestamp": { "$first": "$event_timestamp" } + } + } + ], + "as": "joined_features" + } + }, + { + "$addFields": { + "features": { + "$arrayToObject": { + "$map": { + "input": "$joined_features", + "as": "fv", + "in": { + "k": "$$fv._id", + "v": "$$fv.features" + } + } + } + } + } + }, + { + "$project": { + "joined_features": 0 + } + } +] +``` +### Execution +```python +results = list(db.training_events.aggregate(pipeline)) +``` +### Resulting Document +``` +{ + "driver_id": 123, + "pickup_ts": ISODate("2026-01-20T12:00:30Z"), + "fare": 18.50, + "label": 1, + "features": { + "driver_stats": { + "rating": 4.91, + "trips_last_7d": 132 + }, + "pricing": { + "surge_multiplier": 1.2 + } + } +} +``` +Feast may flatten this structure into feature columns such as: +``` +driver_stats__rating +driver_stats__trips_last_7d +pricing__surge_multiplier +``` + +## 7. Responsibilities and Non-Goals + +### MongoDB Offline Store Responsibilities +* Store append-only feature history +* Support efficient temporal lookups +* Guarantee ordering and timestamp semantics + +### Explicit Non-Goals + +The MongoDB Offline Store does *not*: +* Join training events with features +* Merge feature views together +* Enforce point-in-time correctness rules + +These responsibilities belong to Feast core. + + +## 8. Summary + +The MongoDB Offline Store enables point-in-time joins by providing: +* A complete historical record of feature values +* Stable schemas and required indexes +* Efficient access patterns for time-aware queries + +The join logic is documented here as a semantic contract, ensuring correctness while keeping the store implementation simple, testable, and aligned with Feast’s architecture. \ No newline at end of file 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_claude.py similarity index 94% rename from sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py rename to sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_claude.py index c46ecd0932b..98489b492fc 100644 --- a/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py +++ b/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_claude.py @@ -32,24 +32,21 @@ from feast import Entity, FeatureView, RepoConfig from feast.infra.key_encoding_utils import serialize_entity_key -from feast.infra.online_stores.helpers import _to_naive_utc from feast.infra.online_stores.online_store import OnlineStore, SupportedAsyncMethods from feast.infra.online_stores.vector_store import VectorStoreConfig from feast.infra.utils.mongodb.connection_utils import ( get_async_mongo_client, get_collection_name, get_mongo_client, - is_atlas, - is_atlas_async, ) 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 feast.utils import to_naive_utc try: - from pymongo import MongoClient + from pymongo import AsyncMongoClient, MongoClient, UpdateOne from pymongo.errors import OperationFailure - from pymongo import AsyncMongoClient except ImportError as e: from feast.errors import FeastExtrasDependencyImportError @@ -123,7 +120,8 @@ class MongoDBOnlineStore(OnlineStore): entity_key_hash: "md5_hash", features: { "feature1": , - "feature2": + "feature2": , + ... }, event_timestamp: ISODate, created_timestamp: ISODate (optional), @@ -204,24 +202,20 @@ def online_write_batch( ) entity_key_hash = self._compute_entity_key_hash(entity_key_bin) - # Convert timestamps to naive UTC - timestamp = _to_naive_utc(timestamp) - created_ts = _to_naive_utc(created_ts) if created_ts else None - # Serialize feature values features_dict = {} for feature_name, val in values.items(): - features_dict[feature_name] = val.SerializeToString() + features_dict[feature_name] = val.SerializeToString() # TODO - This is not sufficient to convert ValProto to python object # Build document document = { - "entity_key_hash": entity_key_hash, + "_id": entity_key_bin, # TODO: What is entity_key_hash for? We don't need a string "features": features_dict, - "event_timestamp": timestamp, + "event_timestamp": to_naive_utc(timestamp), } if created_ts: - document["created_timestamp"] = created_ts + document["created_timestamp"] = to_naive_utc(created_ts) # Add TTL field if configured if online_config.ttl_seconds: @@ -229,22 +223,15 @@ def online_write_batch( document["expire_at"] = expire_at # Upsert operation - bulk_operations.append({ - "filter": {"entity_key_hash": entity_key_hash}, - "update": {"$set": document}, - "upsert": True, - }) + bulk_operations.append(UpdateOne(filter={"_id": entity_key_bin}, update={"$set": document}, upsert=True)) if progress: progress(1) # Execute bulk write if there are operations if bulk_operations: - from pymongo import UpdateOne - collection.bulk_write([ - UpdateOne(op["filter"], op["update"], upsert=op["upsert"]) - for op in bulk_operations - ]) + collection.bulk_write(bulk_operations) + async def online_write_batch_async( self, @@ -271,8 +258,8 @@ async def online_write_batch_async( entity_key_serialization_version=config.entity_key_serialization_version, ) entity_key_hash = self._compute_entity_key_hash(entity_key_bin) - timestamp = _to_naive_utc(timestamp) - created_ts = _to_naive_utc(created_ts) if created_ts else None + timestamp = to_naive_utc(timestamp) + created_ts = to_naive_utc(created_ts) if created_ts else None features_dict = { feature_name: val.SerializeToString() @@ -358,7 +345,7 @@ def online_read( doc = doc_map.get(entity_key_hash) if not doc: - results.append((None, None)) + results.append((None, None)) # todo - is this req'd? continue event_ts = doc.get("event_timestamp") @@ -513,3 +500,7 @@ def teardown( # def retrieve_online_documents_v2(...) # async def initialize(...) # async def close(...) + + + # TODO + # - Add unique index on entity_key hash. We need not convert to a string. We can keep as bson.binary diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_openai.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_openai.py new file mode 100644 index 00000000000..75581ac4bd3 --- /dev/null +++ b/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_openai.py @@ -0,0 +1,398 @@ +from __future__ import annotations + +import logging +from datetime import datetime +from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple + +from pymongo import MongoClient, UpdateOne +from pymongo.collection import Collection + +from feast.entity import Entity +from feast.feature_view import FeatureView +from feast.infra.key_encoding_utils import serialize_entity_key +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 +from feast.repo_config import FeastConfigBaseModel, RepoConfig +from feast.type_map import python_values_to_proto_values + +logger = logging.getLogger(__name__) + +class MongoDBOnlineStoreConfig(FeastConfigBaseModel): + """MongoDB configuration. + + For a description of kwargs that may be passed to MongoClient, + see https://pymongo.readthedocs.io/en/stable/api/pymongo/mongo_client.html + """ + + type: Literal[ + "mongodb", "feast.infra.online_stores.mongodb_online_store.mongodb.MongoDBOnlineStore" + ] = "mongodb" + """Online store type selector""" + connection_string: str = "mongodb://localhost:27017" + database_name: str = "project" # todo - consider changing to project_name? + collection_suffix: str = "features_latest" + client_kwargs: Dict[str, Any] = {} + + +def _store_name(project_name: str, collection_suffix: str) -> str: + """OnlineStore Collection's full name.""" + return f"{project_name}_{collection_suffix}" + + +class MongoDBOnlineStore(OnlineStore): + """ + MongoDB implementation of Feast OnlineStore. + + Schema: + _id: serialized_entity_key (bytes) + features: { .: } + event_timestamps: { "": datetime } + created_timestamp: datetime + + For example: + { + "_id": b"", + "features": { + "driver_stats": { + "rating": 4.91, + "trips_last_7d": 132, + }, + "pricing": { + "surge_multiplier": 1.2 + }, + }, + "event_timestamps": { + "driver_stats": 2026-01-01 12:00:00+00:00 } + "pricing":: 2026-01-21 12:00:00+00:00 } + "created_timestamp": 2026-01-21 12:00:00+00:00 + } + """ + + _client: Optional[MongoClient] = None + _collection: Optional[Collection] = None + + # ------------------------------------------------------------------ + # Lifecycle + # ------------------------------------------------------------------ + + def online_write_batch( + self, + config: RepoConfig, + table: FeatureView, + data: List[Tuple[EntityKeyProto, Dict[str, ValueProto], datetime, Optional[datetime]]], + progress: Optional[Callable[[int], Any]] = None, + ) -> None: + """ + Writes a batch of feature values to the online store. + + data: + [ + {(} + entity_key_bytes, + { feature_ref: ValueProto }, + { feature_view_name: event_timestamp_unix } + ) + ] + """ + clxn = self._get_collection(config) + ops = [] + for row in data: + entity_key, proto_values, event_timestamp, created_timestamp = row + entity_id = serialize_entity_key(entity_key) + feature_updates = { + f"features.{table.name}.{field}": value_proto_to_python(val) + for field, val in proto_values.items() + } + update = { + "$set": { + **feature_updates, + f"event_timestamps.{table.name}": event_timestamp, + "created_timestamp": created_timestamp, + }, + } + ops.append( + UpdateOne( + filter={"_id": entity_id}, + update=update, + upsert=True, + ) + ) + if ops: + clxn.bulk_write(ops, ordered=False) + if progress: + progress(1) + + # ------------------------------------------------------------------ + + def online_read( + self, + config: RepoConfig, + table: FeatureView, + entity_keys: List[EntityKeyProto], + requested_features: Optional[List[str]] = None, + ) -> List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]]: + """ + Read features for a batch of entities. + """ + clxn = self._get_collection(config) + + ids = [ + serialize_entity_key( + key, + entity_key_serialization_version=config.entity_key_serialization_version, + ) + for key in entity_keys + ] + + query_filter = {"_id": {"$in": ids}} + projection = { + "_id": 1, + f"event_timestamps.{table.name}": 1, + } + if requested_features: + projection.update({f"features.{table.name}.{x}": 1 for x in requested_features}) + else: + projection[f"features.{table.name}"] = 1 + + cursor = clxn.find(query_filter, projection=projection) + docs = {doc["_id"]: doc for doc in cursor} + + # Order and format output + results: List[Optional[Dict[str, ValueProto]]] = [] + for entity_id in ids: + doc = docs.get(entity_id) + if doc is None: + results.append((None, None)) + continue + + # Extract timestamp + ts = doc.get("event_timestamps", {}).get(table.name) + # Extract features + features_raw = doc.get("features", {}).get(table.name, {}) + + features_proto = {k: python_values_to_proto_values([v])[0] for k, v in features_raw.items()} # todo refactor: v inefficient + results.append((ts, features_proto)) + return results + + # todo v inefficient: the method below must infer types. additionally we're iterating over rows + # feature.dtype is held in table.feature.dtype. + """ + Feast’s online read is row-oriented in output, but type conversion is naturally column-oriented. + Instead of: + For each entity → convert each feature individually + You should: + 1. Gather values for a single feature across all entities. + 2. Convert them in one call. + 3. Then reassemble row-wise. + + Efficient Pattern + Assume: + • ids is ordered + • requested_features is defined (handle case) + • docs is your _id -> doc mapping + Step 1: Extract raw values column-wise + + + # Step 1: Extract raw values column-wise # (aligned by ordered ids column-wise) + raw_feature_columns = {feature: [] for feature in requested_features} + + for entity_id in ids: + doc = docs.get(entity_id) + feature_dict = ( + doc.get("features", {}).get(table.name, {}) + if doc else {} + ) + + for feature in requested_features: + raw_feature_columns[feature].append( + feature_dict.get(feature) + ) + + # Step 2: Convert per feature + # You need feature types. We can get these from the table! + # The following will map feature.name to its value type. This is across columns + # features_raw contains the columns for a single row (entity) + # feature_type_map is done outside the entity loop + feature_type_map = { + feature.name: feature.dtype.to_value_type() + for feature in table.features + } + proto_feature_columns = {} + for feature_name, raw_values in raw_feature_columns.items(): + proto_feature_columns[feature_name] = python_values_to_proto_values( + raw_values, + feature_type=feature_type_map[feature_name], + ) + + # Step 3: Reassemble row-wise + results = [] + + for i, entity_id in enumerate(ids): + doc = docs.get(entity_id) + + if doc is None: + results.append((None, None)) + continue + + ts = doc.get("event_timestamps", {}).get(table.name) + + row_features = { + feature_name: proto_feature_columns[feature_name][i] + for feature_name in requested_features + } + + results.append((ts, row_features)) + + return results + """ + # ------------------------------------------------------------------ + + def update( + self, + config: RepoConfig, + tables_to_delete: Sequence[FeatureView], + tables_to_keep: Sequence[FeatureView], + entities_to_delete: Sequence[Entity], + entities_to_keep: Sequence[Entity], + partial: bool, + ): + """Prepare or update online store. + + With MongoDB, we have a loose schema and lazy creation so there is little to do here. + Nothing needs to be pre-created for the entities and tables to keep. + + The OnlineStore is a single Collection with the following Document shape. + { + "_id": "", + "features": { + "": { + "": value + } + } + } + We remove any feature views named in tables_to_delete. + The Entities are serialized in the _id. No schema needs be adjusted. + """ + if config.online_store.type != "mongodb": + raise RuntimeError("config.online_store.type must be mongodb. Found ", config.online_store.type) + + clxn = self._get_collection(repo_config=config) + + 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}) + + # Delete specific entities + if entities_to_delete: + logger.warning(f"CHECK FORM. Can we call to_proto()?: {entities_to_delete = }") + ids = [serialize_entity_key(e.to_proto()) for e in entities_to_delete] + clxn.delete_many({"_id": {"$in": ids}}) + + + def teardown( + self, + config: RepoConfig, # TODO - Need to resolve configs (Repo and Store) + tables: Sequence[FeatureView], + entities: Sequence[Entity], + ): + """ + Tear down MongoDB resources (drop collections). + + Args: + config: Feast repository configuration + tables: Feature views whose collections should be dropped + entities: Entities (unused for MongoDB) + """ + assert config.online_store.type == "mongodb" + online_config: MongoDBOnlineStoreConfig = config.online_store + + clxn = self._get_collection(repo_config=config) + clxn.drop() + self._get_client(config) + client = MongoClient(config.online_store.uri) + client.close() + + # ------------------------------------------------------------------ + # Helpers + # ------------------------------------------------------------------ + + def _get_client(self, online_config: MongoDBOnlineStoreConfig): + """Returns a connection to the server.""" + if self._client is None: + assert isinstance(online_config, MongoDBOnlineStoreConfig) + self._client = MongoClient(online_config.connection_string, **online_config.client_kwargs) + return self._client + + def _get_collection(self, repo_config: RepoConfig) -> Collection: + """Returns a connection to the online store collection.""" + if self._collection is None: + online_config = repo_config.online_store + self._client = self._get_client(online_config) + db = self._client[online_config.database_name] + clxn_name = f"{repo_config.project}_{online_config.collection_suffix}" + if clxn_name not in db.list_collection_names(): + self._collection = db.create_collection(clxn_name) + self._collection = db[clxn_name] + return self._collection + +def value_proto_to_python(val: ValueProto): + """Utility to convert Value proto to plain form saved in MongoDB.""" + try: # hasattr(val, "val"): + typ = val.WhichOneof("val") + val = getattr(val, typ) + if isinstance(val, datetime): + val = val.replace(tzinfo=datetime.UTC) + return val + except: + raise ValueError(f"Unsupported ValueProto: {val}") + + +def value_proto_to_python_deprecated(val: ValueProto): + """Utility to convert Value proto to plain form saved in MongoDB.""" + # TODO + # - Check timestamp implementation + + val = val.WhichOneof("val") + if val == "int32_val": + return val.int32_val + if val == "float_int64_val": + return val.int32_list_val + if val == "int64_val": + return val.int64_val + if val == "int64_list_val": + return val.int64_list_val + if val == "float_val": + return val.float_val + if val == "float_list_val": + return val.float_list_val + if val == "double_val": + return val.double_val + if val == "double_list_val": + return val.double_list_val + if val == "bool_val": + return val.bool_val + if val == "bool_list_val": + return val.bool_list_val + if val == "string_val": + return val.string_val + if val == "bytes_val": + return val.bytes_val + if val == "timestamp_val": + return datetime.fromtimestamp( + val.timestamp_val.seconds + val.timestamp_val.nanos / 1e9, + tz=datetime.timezone.utc, + ) + if val == "null_val": + return None + + raise ValueError(f"Unsupported ValueProto val: {val}") + + + +# TODO +# - Implement async API diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/test_mongodb_online.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/test_mongodb_online.py index ba0e48e4536..984048bfa6f 100644 --- a/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/test_mongodb_online.py +++ b/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/test_mongodb_online.py @@ -24,8 +24,8 @@ """ import os -from datetime import datetime, timedelta -from unittest.mock import Mock, patch, MagicMock +from datetime import UTC, datetime, timedelta +from unittest.mock import MagicMock, patch import pytest @@ -36,9 +36,10 @@ ) 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, String, Float32 +from feast.types import Float32, Int64, String from feast.value_type import ValueType +MONGODB_URI = os.environ.get("MONGODB_URI", "mongodb://localhost:27017") class TestMongoDBOnlineStoreConfig: """Test suite for MongoDBOnlineStoreConfig.""" @@ -46,7 +47,7 @@ class TestMongoDBOnlineStoreConfig: def test_default_config(self): """Test default configuration values.""" config = MongoDBOnlineStoreConfig( - connection_string="mongodb://localhost:27017" + connection_string=MONGODB_URI ) assert config.type == "mongodb" @@ -100,7 +101,7 @@ def mock_config(self): return RepoConfig( project="test_project", online_store=MongoDBOnlineStoreConfig( - connection_string="mongodb://localhost:27017", + connection_string=MONGODB_URI, database="feast_test", ), registry="dummy_registry", @@ -112,7 +113,7 @@ def mock_config_with_ttl(self): return RepoConfig( project="test_project", online_store=MongoDBOnlineStoreConfig( - connection_string="mongodb://localhost:27017", + connection_string=MONGODB_URI, database="feast_test", ttl_seconds=86400, ), @@ -155,7 +156,7 @@ def entity_keys(self): def feature_data(self, entity_keys): """Create test feature data.""" data = [] - timestamp = datetime.utcnow() + timestamp = datetime.now(UTC) for i, key in enumerate(entity_keys): features = { @@ -195,9 +196,9 @@ def test_online_write_batch(self, mock_get_client, mock_config, feature_view, fe mock_db = MagicMock() mock_collection = MagicMock() - mock_client.__getitem__.return_value = mock_db - mock_db.__getitem__.return_value = mock_collection - mock_get_client.return_value = mock_client + # mock_client.__getitem__.return_value = mock_db + # mock_db.__getitem__.return_value = mock_collection + # mock_get_client.return_value = mock_client # Create store and write data store = MongoDBOnlineStore() @@ -260,7 +261,7 @@ def test_online_read(self, mock_get_client, mock_config, feature_view, entity_ke # Mock find result mock_doc = { "entity_key_hash": "test_hash", - "event_timestamp": datetime.utcnow(), + "event_timestamp": datetime.now(UTC), "features": { "feature1": ValueProto(string_val="test").SerializeToString(), "feature2": ValueProto(float_val=1.5).SerializeToString(), @@ -469,7 +470,7 @@ async def test_online_write_batch_async( "feature1": ValueProto(string_val="test"), } - data = [(entity_key, features, datetime.utcnow(), None)] + data = [(entity_key, features, datetime.now(UTC), None)] # Write data store = MongoDBOnlineStore() @@ -591,7 +592,7 @@ def test_full_write_read_cycle(self, mongodb_config, feature_view): "feature2": ValueProto(float_val=42.5), } - timestamp = datetime.utcnow() + timestamp = datetime.now(UTC) data = [(entity_key, features, timestamp, None)] # Write data diff --git a/sdk/python/feast/infra/utils/mongodb/connection_utils.py b/sdk/python/feast/infra/utils/mongodb/connection_utils.py index 210fa444e42..88b54e2a783 100644 --- a/sdk/python/feast/infra/utils/mongodb/connection_utils.py +++ b/sdk/python/feast/infra/utils/mongodb/connection_utils.py @@ -23,8 +23,7 @@ from typing import Any, Union try: - from pymongo import MongoClient - from pymongo.mongo_client import AsyncMongoClient + from pymongo import AsyncMongoClient, MongoClient from pymongo.read_preferences import ReadPreference except ImportError as e: from feast.errors import FeastExtrasDependencyImportError @@ -220,3 +219,10 @@ def get_collection_name(project: str, table_name: str) -> str: safe_table = table_name.replace("$", "_").replace("\x00", "") return f"{safe_project}_{safe_table}" + +# TODO +# - Consider removing this so that we don't create anything inside utils +# - get_collection_name, though safe, could easily be done manually by the user's specification of project and table name. Unless $ is often in project names +# - is_atlas methods. Are these accurate? +# - all the kwargs passed to get_client_connection are not needed. Just put in `connection_string` +# - _parse_read_preference is unneeded diff --git a/sdk/python/requirements/py3.11-mongodb-dev-requirements.txt b/sdk/python/requirements/py3.11-mongodb-dev-requirements.txt new file mode 100644 index 00000000000..cc38cfb316c --- /dev/null +++ b/sdk/python/requirements/py3.11-mongodb-dev-requirements.txt @@ -0,0 +1,7078 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile -p 3.11 --no-strip-extras setup.py --extra mongodb --extra ci --generate-hashes --output-file sdk/python/requirements/py3.11-mongodb-dev-requirements.txt +accelerate==1.12.0 \ + --hash=sha256:3e2091cd341423207e2f084a6654b1efcd250dc326f2a37d6dde446e07cabb11 \ + --hash=sha256:70988c352feb481887077d2ab845125024b2a137a5090d6d7a32b57d03a45df6 + # via docling-ibm-models +aiobotocore==2.23.1 \ + --hash=sha256:a59f2a78629b97d52f10936b79c73de64e481a8c44a62c1871f088df6c1afc4f \ + --hash=sha256:d81c54d2eae2406ea9a473fea518fed580cf37bc4fc51ce43ba81546e5305114 + # via feast (setup.py) +aiohappyeyeballs==2.6.1 \ + --hash=sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558 \ + --hash=sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8 + # via aiohttp +aiohttp==3.13.3 \ + --hash=sha256:01ad2529d4b5035578f5081606a465f3b814c542882804e2e8cda61adf5c71bf \ + --hash=sha256:042e9e0bcb5fba81886c8b4fbb9a09d6b8a00245fd8d88e4d989c1f96c74164c \ + --hash=sha256:05861afbbec40650d8a07ea324367cb93e9e8cc7762e04dd4405df99fa65159c \ + --hash=sha256:084911a532763e9d3dd95adf78a78f4096cd5f58cdc18e6fdbc1b58417a45423 \ + --hash=sha256:0add0900ff220d1d5c5ebbf99ed88b0c1bbf87aa7e4262300ed1376a6b13414f \ + --hash=sha256:0db318f7a6f065d84cb1e02662c526294450b314a02bd9e2a8e67f0d8564ce40 \ + --hash=sha256:10b47b7ba335d2e9b1239fa571131a87e2d8ec96b333e68b2a305e7a98b0bae2 \ + --hash=sha256:1449ceddcdbcf2e0446957863af03ebaaa03f94c090f945411b61269e2cb5daf \ + --hash=sha256:147e422fd1223005c22b4fe080f5d93ced44460f5f9c105406b753612b587821 \ + --hash=sha256:1cb93e166e6c28716c8c6aeb5f99dfb6d5ccf482d29fe9bf9a794110e6d0ab64 \ + --hash=sha256:215a685b6fbbfcf71dfe96e3eba7a6f58f10da1dfdf4889c7dd856abe430dca7 \ + --hash=sha256:2712039939ec963c237286113c68dbad80a82a4281543f3abf766d9d73228998 \ + --hash=sha256:27234ef6d85c914f9efeb77ff616dbf4ad2380be0cda40b4db086ffc7ddd1b7d \ + --hash=sha256:28e027cf2f6b641693a09f631759b4d9ce9165099d2b5d92af9bd4e197690eea \ + --hash=sha256:2b8d8ddba8f95ba17582226f80e2de99c7a7948e66490ef8d947e272a93e9463 \ + --hash=sha256:2ba0eea45eb5cc3172dbfc497c066f19c41bac70963ea1a67d51fc92e4cf9a80 \ + --hash=sha256:2be0e9ccf23e8a94f6f0650ce06042cefc6ac703d0d7ab6c7a917289f2539ad4 \ + --hash=sha256:2e41b18a58da1e474a057b3d35248d8320029f61d70a37629535b16a0c8f3767 \ + --hash=sha256:2eb752b102b12a76ca02dff751a801f028b4ffbbc478840b473597fc91a9ed43 \ + --hash=sha256:2fc82186fadc4a8316768d61f3722c230e2c1dcab4200d52d2ebdf2482e47592 \ + --hash=sha256:2fff83cfc93f18f215896e3a190e8e5cb413ce01553901aca925176e7568963a \ + --hash=sha256:31a83ea4aead760dfcb6962efb1d861db48c34379f2ff72db9ddddd4cda9ea2e \ + --hash=sha256:34749271508078b261c4abb1767d42b8d0c0cc9449c73a4df494777dc55f0687 \ + --hash=sha256:34bac00a67a812570d4a460447e1e9e06fae622946955f939051e7cc895cfab8 \ + --hash=sha256:37239e9f9a7ea9ac5bf6b92b0260b01f8a22281996da609206a84df860bc1261 \ + --hash=sha256:37da61e244d1749798c151421602884db5270faf479cf0ef03af0ff68954c9dd \ + --hash=sha256:3b61b7169ababd7802f9568ed96142616a9118dd2be0d1866e920e77ec8fa92a \ + --hash=sha256:3d9908a48eb7416dc1f4524e69f1d32e5d90e3981e4e37eb0aa1cd18f9cfa2a4 \ + --hash=sha256:3dd4dce1c718e38081c8f35f323209d4c1df7d4db4bab1b5c88a6b4d12b74587 \ + --hash=sha256:4021b51936308aeea0367b8f006dc999ca02bc118a0cc78c303f50a2ff6afb91 \ + --hash=sha256:40c5e40ecc29ba010656c18052b877a1c28f84344825efa106705e835c28530f \ + --hash=sha256:425c126c0dc43861e22cb1c14ba4c8e45d09516d0a3ae0a3f7494b79f5f233a3 \ + --hash=sha256:44531a36aa2264a1860089ffd4dce7baf875ee5a6079d5fb42e261c704ef7344 \ + --hash=sha256:48e377758516d262bde50c2584fc6c578af272559c409eecbdd2bae1601184d6 \ + --hash=sha256:49a03727c1bba9a97d3e93c9f93ca03a57300f484b6e935463099841261195d3 \ + --hash=sha256:4ae5b5a0e1926e504c81c5b84353e7a5516d8778fbbff00429fe7b05bb25cbce \ + --hash=sha256:4e239d501f73d6db1522599e14b9b321a7e3b1de66ce33d53a765d975e9f4808 \ + --hash=sha256:56339a36b9f1fc708260c76c87e593e2afb30d26de9ae1eb445b5e051b98a7a1 \ + --hash=sha256:568f416a4072fbfae453dcf9a99194bbb8bdeab718e08ee13dfa2ba0e4bebf29 \ + --hash=sha256:5b179331a481cb5529fca8b432d8d3c7001cb217513c94cd72d668d1248688a3 \ + --hash=sha256:5b6073099fb654e0a068ae678b10feff95c5cae95bbfcbfa7af669d361a8aa6b \ + --hash=sha256:5d2d94f1f5fcbe40838ac51a6ab5704a6f9ea42e72ceda48de5e6b898521da51 \ + --hash=sha256:5dff64413671b0d3e7d5918ea490bdccb97a4ad29b3f311ed423200b2203e01c \ + --hash=sha256:5e1d8c8b8f1d91cd08d8f4a3c2b067bfca6ec043d3ff36de0f3a715feeedf926 \ + --hash=sha256:5f8ca7f2bb6ba8348a3614c7918cc4bb73268c5ac2a207576b7afea19d3d9f64 \ + --hash=sha256:642f752c3eb117b105acbd87e2c143de710987e09860d674e068c4c2c441034f \ + --hash=sha256:65d2ccb7eabee90ce0503c17716fc77226be026dcc3e65cce859a30db715025b \ + --hash=sha256:693781c45a4033d31d4187d2436f5ac701e7bbfe5df40d917736108c1cc7436e \ + --hash=sha256:694976222c711d1d00ba131904beb60534f93966562f64440d0c9d41b8cdb440 \ + --hash=sha256:697753042d57f4bf7122cab985bf15d0cef23c770864580f5af4f52023a56bd6 \ + --hash=sha256:69c56fbc1993fa17043e24a546959c0178fe2b5782405ad4559e6c13975c15e3 \ + --hash=sha256:6de499a1a44e7de70735d0b39f67c8f25eb3d91eb3103be99ca0fa882cdd987d \ + --hash=sha256:6fc0e2337d1a4c3e6acafda6a78a39d4c14caea625124817420abceed36e2415 \ + --hash=sha256:75ca857eba4e20ce9f546cd59c7007b33906a4cd48f2ff6ccf1ccfc3b646f279 \ + --hash=sha256:7a4a94eb787e606d0a09404b9c38c113d3b099d508021faa615d70a0131907ce \ + --hash=sha256:7b5e8fe4de30df199155baaf64f2fcd604f4c678ed20910db8e2c66dc4b11603 \ + --hash=sha256:7bfdc049127717581866fa4708791220970ce291c23e28ccf3922c700740fdc0 \ + --hash=sha256:7e63f210bc1b57ef699035f2b4b6d9ce096b5914414a49b0997c839b2bd2223c \ + --hash=sha256:7f9120f7093c2a32d9647abcaf21e6ad275b4fbec5b55969f978b1a97c7c86bf \ + --hash=sha256:8057c98e0c8472d8846b9c79f56766bcc57e3e8ac7bfd510482332366c56c591 \ + --hash=sha256:80dd4c21b0f6237676449c6baaa1039abae86b91636b6c91a7f8e61c87f89540 \ + --hash=sha256:81e97251d9298386c2b7dbeb490d3d1badbdc69107fb8c9299dd04eb39bddc0e \ + --hash=sha256:82611aeec80eb144416956ec85b6ca45a64d76429c1ed46ae1b5f86c6e0c9a26 \ + --hash=sha256:8542f41a62bcc58fc7f11cf7c90e0ec324ce44950003feb70640fc2a9092c32a \ + --hash=sha256:859bd3f2156e81dd01432f5849fc73e2243d4a487c4fd26609b1299534ee1845 \ + --hash=sha256:87797e645d9d8e222e04160ee32aa06bc5c163e8499f24db719e7852ec23093a \ + --hash=sha256:87b9aab6d6ed88235aa2970294f496ff1a1f9adcd724d800e9b952395a80ffd9 \ + --hash=sha256:8a60e60746623925eab7d25823329941aee7242d559baa119ca2b253c88a7bd6 \ + --hash=sha256:90455115e5da1c3c51ab619ac57f877da8fd6d73c05aacd125c5ae9819582aba \ + --hash=sha256:90751b8eed69435bac9ff4e3d2f6b3af1f57e37ecb0fbeee59c0174c9e2d41df \ + --hash=sha256:947c26539750deeaee933b000fb6517cc770bbd064bad6033f1cff4803881e43 \ + --hash=sha256:96d604498a7c782cb15a51c406acaea70d8c027ee6b90c569baa6e7b93073679 \ + --hash=sha256:988a8c5e317544fdf0d39871559e67b6341065b87fceac641108c2096d5506b7 \ + --hash=sha256:9a9dc347e5a3dc7dfdbc1f82da0ef29e388ddb2ed281bfce9dd8248a313e62b7 \ + --hash=sha256:9ae8dd55c8e6c4257eae3a20fd2c8f41edaea5992ed67156642493b8daf3cecc \ + --hash=sha256:9af5e68ee47d6534d36791bbe9b646d2a7c7deb6fc24d7943628edfbb3581f29 \ + --hash=sha256:9b174f267b5cfb9a7dba9ee6859cecd234e9a681841eb85068059bc867fb8f02 \ + --hash=sha256:9bf9f7a65e7aa20dd764151fb3d616c81088f91f8df39c3893a536e279b4b984 \ + --hash=sha256:9d4c940f02f49483b18b079d1c27ab948721852b281f8b015c058100e9421dd1 \ + --hash=sha256:9ebf57d09e131f5323464bd347135a88622d1c0976e88ce15b670e7ad57e4bd6 \ + --hash=sha256:a19884d2ee70b06d9204b2727a7b9f983d0c684c650254679e716b0b77920632 \ + --hash=sha256:a1e53262fd202e4b40b70c3aff944a8155059beedc8a89bba9dc1f9ef06a1b56 \ + --hash=sha256:a2212ad43c0833a873d0fb3c63fa1bacedd4cf6af2fee62bf4b739ceec3ab239 \ + --hash=sha256:a45530014d7a1e09f4a55f4f43097ba0fd155089372e105e4bff4ca76cb1b168 \ + --hash=sha256:a949eee43d3782f2daae4f4a2819b2cb9b0c5d3b7f7a927067cc84dafdbb9f88 \ + --hash=sha256:add1da70de90a2569c5e15249ff76a631ccacfe198375eead4aadf3b8dc849dc \ + --hash=sha256:af71fff7bac6bb7508956696dce8f6eec2bbb045eceb40343944b1ae62b5ef11 \ + --hash=sha256:b04be762396457bef43f3597c991e192ee7da460a4953d7e647ee4b1c28e7046 \ + --hash=sha256:b0d95340658b9d2f11d9697f59b3814a9d3bb4b7a7c20b131df4bcef464037c0 \ + --hash=sha256:b1a6102b4d3ebc07dad44fbf07b45bb600300f15b552ddf1851b5390202ea2e3 \ + --hash=sha256:b46020d11d23fe16551466c77823df9cc2f2c1e63cc965daf67fa5eec6ca1877 \ + --hash=sha256:b556c85915d8efaed322bf1bdae9486aa0f3f764195a0fb6ee962e5c71ef5ce1 \ + --hash=sha256:b903a4dfee7d347e2d87697d0713be59e0b87925be030c9178c5faa58ea58d5c \ + --hash=sha256:b928f30fe49574253644b1ca44b1b8adbd903aa0da4b9054a6c20fc7f4092a25 \ + --hash=sha256:b99281b0704c103d4e11e72a76f1b543d4946fea7dd10767e7e1b5f00d4e5704 \ + --hash=sha256:bae5c2ed2eae26cc382020edad80d01f36cb8e746da40b292e68fec40421dc6a \ + --hash=sha256:bb4f7475e359992b580559e008c598091c45b5088f28614e855e42d39c2f1033 \ + --hash=sha256:bbe7d4cecacb439e2e2a8a1a7b935c25b812af7a5fd26503a66dadf428e79ec1 \ + --hash=sha256:bfc1cc2fe31a6026a8a88e4ecfb98d7f6b1fec150cfd708adbfd1d2f42257c29 \ + --hash=sha256:c014c7ea7fb775dd015b2d3137378b7be0249a448a1612268b5a90c2d81de04d \ + --hash=sha256:c048058117fd649334d81b4b526e94bde3ccaddb20463a815ced6ecbb7d11160 \ + --hash=sha256:c0e2d366af265797506f0283487223146af57815b388623f0357ef7eac9b209d \ + --hash=sha256:c19b90316ad3b24c69cd78d5c9b4f3aa4497643685901185b65166293d36a00f \ + --hash=sha256:c685f2d80bb67ca8c3837823ad76196b3694b0159d232206d1e461d3d434666f \ + --hash=sha256:c6b8568a3bb5819a0ad087f16d40e5a3fb6099f39ea1d5625a3edc1e923fc538 \ + --hash=sha256:d32764c6c9aafb7fb55366a224756387cd50bfa720f32b88e0e6fa45b27dcf29 \ + --hash=sha256:d5a372fd5afd301b3a89582817fdcdb6c34124787c70dbcc616f259013e7eef7 \ + --hash=sha256:d60ac9663f44168038586cab2157e122e46bdef09e9368b37f2d82d354c23f72 \ + --hash=sha256:dca68018bf48c251ba17c72ed479f4dafe9dbd5a73707ad8d28a38d11f3d42af \ + --hash=sha256:de2c184bb1fe2cbd2cefba613e9db29a5ab559323f994b6737e370d3da0ac455 \ + --hash=sha256:e3531d63d3bdfa7e3ac5e9b27b2dd7ec9df3206a98e0b3445fa906f233264c57 \ + --hash=sha256:e50a2e1404f063427c9d027378472316201a2290959a295169bcf25992d04558 \ + --hash=sha256:e636b3c5f61da31a92bf0d91da83e58fdfa96f178ba682f11d24f31944cdd28c \ + --hash=sha256:ea37047c6b367fd4bd632bff8077449b8fa034b69e812a18e0132a00fae6e808 \ + --hash=sha256:f33ed1a2bf1997a36661874b017f5c4b760f41266341af36febaf271d179f6d7 \ + --hash=sha256:f76c1e3fe7d7c8afad7ed193f89a292e1999608170dcc9751a7462a87dfd5bc0 \ + --hash=sha256:f9444f105664c4ce47a2a7171a2418bce5b7bae45fb610f4e2c36045d85911d3 \ + --hash=sha256:fc290605db2a917f6e81b0e1e0796469871f5af381ce15c604a3c5c7e51cb730 \ + --hash=sha256:fc353029f176fd2b3ec6cfc71be166aba1936fe5d73dd1992ce289ca6647a9aa \ + --hash=sha256:fee0c6bc7db1de362252affec009707a17478a00ec69f797d23ca256e36d5940 + # via + # aiobotocore + # aiohttp-cors + # fsspec + # ray +aiohttp-cors==0.8.1 \ + --hash=sha256:3180cf304c5c712d626b9162b195b1db7ddf976a2a25172b35bb2448b890a80d \ + --hash=sha256:ccacf9cb84b64939ea15f859a146af1f662a6b1d68175754a07315e305fb1403 + # via ray +aioitertools==0.13.0 \ + --hash=sha256:0be0292b856f08dfac90e31f4739432f4cb6d7520ab9eb73e143f4f2fa5259be \ + --hash=sha256:620bd241acc0bbb9ec819f1ab215866871b4bbd1f73836a55f799200ee86950c + # via aiobotocore +aiosignal==1.4.0 \ + --hash=sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e \ + --hash=sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7 + # via aiohttp +alabaster==0.7.16 \ + --hash=sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65 \ + --hash=sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92 + # via sphinx +altair==4.2.2 \ + --hash=sha256:39399a267c49b30d102c10411e67ab26374156a84b1aeb9fcd15140429ba49c5 \ + --hash=sha256:8b45ebeaf8557f2d760c5c77b79f02ae12aee7c46c27c06014febab6f849bc87 + # via great-expectations +annotated-doc==0.0.4 \ + --hash=sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320 \ + --hash=sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4 + # via fastapi +annotated-types==0.7.0 \ + --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ + --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 + # via pydantic +anyio==4.12.1 \ + --hash=sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703 \ + --hash=sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c + # via + # elasticsearch + # httpx + # jupyter-server + # mcp + # sse-starlette + # starlette + # watchfiles +appnope==0.1.4 \ + --hash=sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee \ + --hash=sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c + # via ipykernel +argon2-cffi==25.1.0 \ + --hash=sha256:694ae5cc8a42f4c4e2bf2ca0e64e51e23a040c6a517a85074683d3959e1346c1 \ + --hash=sha256:fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741 + # via + # jupyter-server + # minio +argon2-cffi-bindings==25.1.0 \ + --hash=sha256:1db89609c06afa1a214a69a462ea741cf735b29a57530478c06eb81dd403de99 \ + --hash=sha256:1e021e87faa76ae0d413b619fe2b65ab9a037f24c60a1e6cc43457ae20de6dc6 \ + --hash=sha256:21378b40e1b8d1655dd5310c84a40fc19a9aa5e6366e835ceb8576bf0fea716d \ + --hash=sha256:2630b6240b495dfab90aebe159ff784d08ea999aa4b0d17efa734055a07d2f44 \ + --hash=sha256:3c6702abc36bf3ccba3f802b799505def420a1b7039862014a65db3205967f5a \ + --hash=sha256:3d3f05610594151994ca9ccb3c771115bdb4daef161976a266f0dd8aa9996b8f \ + --hash=sha256:473bcb5f82924b1becbb637b63303ec8d10e84c8d241119419897a26116515d2 \ + --hash=sha256:5acb4e41090d53f17ca1110c3427f0a130f944b896fc8c83973219c97f57b690 \ + --hash=sha256:5d588dec224e2a83edbdc785a5e6f3c6cd736f46bfd4b441bbb5aa1f5085e584 \ + --hash=sha256:6dca33a9859abf613e22733131fc9194091c1fa7cb3e131c143056b4856aa47e \ + --hash=sha256:7aef0c91e2c0fbca6fc68e7555aa60ef7008a739cbe045541e438373bc54d2b0 \ + --hash=sha256:84a461d4d84ae1295871329b346a97f68eade8c53b6ed9a7ca2d7467f3c8ff6f \ + --hash=sha256:87c33a52407e4c41f3b70a9c2d3f6056d88b10dad7695be708c5021673f55623 \ + --hash=sha256:8b8efee945193e667a396cbc7b4fb7d357297d6234d30a489905d96caabde56b \ + --hash=sha256:a1c70058c6ab1e352304ac7e3b52554daadacd8d453c1752e547c76e9c99ac44 \ + --hash=sha256:a98cd7d17e9f7ce244c0803cad3c23a7d379c301ba618a5fa76a67d116618b98 \ + --hash=sha256:aecba1723ae35330a008418a91ea6cfcedf6d31e5fbaa056a166462ff066d500 \ + --hash=sha256:b0fdbcf513833809c882823f98dc2f931cf659d9a1429616ac3adebb49f5db94 \ + --hash=sha256:b55aec3565b65f56455eebc9b9f34130440404f27fe21c3b375bf1ea4d8fbae6 \ + --hash=sha256:b957f3e6ea4d55d820e40ff76f450952807013d361a65d7f28acc0acbf29229d \ + --hash=sha256:ba92837e4a9aa6a508c8d2d7883ed5a8f6c308c89a4790e1e447a220deb79a85 \ + --hash=sha256:c4f9665de60b1b0e99bcd6be4f17d90339698ce954cfd8d9cf4f91c995165a92 \ + --hash=sha256:c87b72589133f0346a1cb8d5ecca4b933e3c9b64656c9d175270a000e73b288d \ + --hash=sha256:d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a \ + --hash=sha256:da0c79c23a63723aa5d782250fbf51b768abca630285262fb5144ba5ae01e520 \ + --hash=sha256:e2fd3bfbff3c5d74fef31a722f729bf93500910db650c925c2d6ef879a7e51cb + # via argon2-cffi +arrow==1.4.0 \ + --hash=sha256:749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205 \ + --hash=sha256:ed0cc050e98001b8779e84d461b0098c4ac597e88704a655582b21d116e526d7 + # via isoduration +asn1crypto==1.5.1 \ + --hash=sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c \ + --hash=sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67 + # via snowflake-connector-python +assertpy==1.1 \ + --hash=sha256:acc64329934ad71a3221de185517a43af33e373bb44dc05b5a9b174394ef4833 + # via feast (setup.py) +asttokens==3.0.1 \ + --hash=sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a \ + --hash=sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7 + # via stack-data +async-lru==2.1.0 \ + --hash=sha256:9eeb2fecd3fe42cc8a787fc32ead53a3a7158cc43d039c3c55ab3e4e5b2a80ed \ + --hash=sha256:fa12dcf99a42ac1280bc16c634bbaf06883809790f6304d85cdab3f666f33a7e + # via jupyterlab +async-property==0.2.2 \ + --hash=sha256:17d9bd6ca67e27915a75d92549df64b5c7174e9dc806b30a3934dc4ff0506380 \ + --hash=sha256:8924d792b5843994537f8ed411165700b27b2bd966cefc4daeefc1253442a9d7 + # via python-keycloak +async-timeout==5.0.1 \ + --hash=sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c \ + --hash=sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3 + # via redis +atpublic==5.1 \ + --hash=sha256:135783dbd887fbddb6ef032d104da70c124f2b44b9e2d79df07b9da5334825e3 \ + --hash=sha256:abc1f4b3dbdd841cc3539e4b5e4f3ad41d658359de704e30cb36da4d4e9d3022 + # via ibis-framework +attrs==25.4.0 \ + --hash=sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11 \ + --hash=sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373 + # via + # aiohttp + # jsonlines + # jsonschema + # referencing +azure-core==1.38.0 \ + --hash=sha256:8194d2682245a3e4e3151a667c686464c3786fed7918b394d035bdcd61bb5993 \ + --hash=sha256:ab0c9b2cd71fecb1842d52c965c95285d3cfb38902f6766e4a471f1cd8905335 + # via + # azure-identity + # azure-storage-blob +azure-identity==1.25.1 \ + --hash=sha256:87ca8328883de6036443e1c37b40e8dc8fb74898240f61071e09d2e369361456 \ + --hash=sha256:e9edd720af03dff020223cd269fa3a61e8f345ea75443858273bcb44844ab651 + # via feast (setup.py) +azure-storage-blob==12.28.0 \ + --hash=sha256:00fb1db28bf6a7b7ecaa48e3b1d5c83bfadacc5a678b77826081304bd87d6461 \ + --hash=sha256:e7d98ea108258d29aa0efbfd591b2e2075fa1722a2fae8699f0b3c9de11eff41 + # via feast (setup.py) +babel==2.17.0 \ + --hash=sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d \ + --hash=sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 + # via + # jupyterlab-server + # sphinx +bcrypt==5.0.0 \ + --hash=sha256:046ad6db88edb3c5ece4369af997938fb1c19d6a699b9c1b27b0db432faae4c4 \ + --hash=sha256:0c418ca99fd47e9c59a301744d63328f17798b5947b0f791e9af3c1c499c2d0a \ + --hash=sha256:0c8e093ea2532601a6f686edbc2c6b2ec24131ff5c52f7610dd64fa4553b5464 \ + --hash=sha256:0cae4cb350934dfd74c020525eeae0a5f79257e8a201c0c176f4b84fdbf2a4b4 \ + --hash=sha256:137c5156524328a24b9fac1cb5db0ba618bc97d11970b39184c1d87dc4bf1746 \ + --hash=sha256:200af71bc25f22006f4069060c88ed36f8aa4ff7f53e67ff04d2ab3f1e79a5b2 \ + --hash=sha256:212139484ab3207b1f0c00633d3be92fef3c5f0af17cad155679d03ff2ee1e41 \ + --hash=sha256:2b732e7d388fa22d48920baa267ba5d97cca38070b69c0e2d37087b381c681fd \ + --hash=sha256:35a77ec55b541e5e583eb3436ffbbf53b0ffa1fa16ca6782279daf95d146dcd9 \ + --hash=sha256:38cac74101777a6a7d3b3e3cfefa57089b5ada650dce2baf0cbdd9d65db22a9e \ + --hash=sha256:3abeb543874b2c0524ff40c57a4e14e5d3a66ff33fb423529c88f180fd756538 \ + --hash=sha256:3ca8a166b1140436e058298a34d88032ab62f15aae1c598580333dc21d27ef10 \ + --hash=sha256:3cf67a804fc66fc217e6914a5635000259fbbbb12e78a99488e4d5ba445a71eb \ + --hash=sha256:4870a52610537037adb382444fefd3706d96d663ac44cbb2f37e3919dca3d7ef \ + --hash=sha256:48f753100931605686f74e27a7b49238122aa761a9aefe9373265b8b7aa43ea4 \ + --hash=sha256:4bfd2a34de661f34d0bda43c3e4e79df586e4716ef401fe31ea39d69d581ef23 \ + --hash=sha256:560ddb6ec730386e7b3b26b8b4c88197aaed924430e7b74666a586ac997249ef \ + --hash=sha256:5b1589f4839a0899c146e8892efe320c0fa096568abd9b95593efac50a87cb75 \ + --hash=sha256:5feebf85a9cefda32966d8171f5db7e3ba964b77fdfe31919622256f80f9cf42 \ + --hash=sha256:611f0a17aa4a25a69362dcc299fda5c8a3d4f160e2abb3831041feb77393a14a \ + --hash=sha256:61afc381250c3182d9078551e3ac3a41da14154fbff647ddf52a769f588c4172 \ + --hash=sha256:64d7ce196203e468c457c37ec22390f1a61c85c6f0b8160fd752940ccfb3a683 \ + --hash=sha256:64ee8434b0da054d830fa8e89e1c8bf30061d539044a39524ff7dec90481e5c2 \ + --hash=sha256:6b8f520b61e8781efee73cba14e3e8c9556ccfb375623f4f97429544734545b4 \ + --hash=sha256:741449132f64b3524e95cd30e5cd3343006ce146088f074f31ab26b94e6c75ba \ + --hash=sha256:744d3c6b164caa658adcb72cb8cc9ad9b4b75c7db507ab4bc2480474a51989da \ + --hash=sha256:79cfa161eda8d2ddf29acad370356b47f02387153b11d46042e93a0a95127493 \ + --hash=sha256:7aeef54b60ceddb6f30ee3db090351ecf0d40ec6e2abf41430997407a46d2254 \ + --hash=sha256:7edda91d5ab52b15636d9c30da87d2cc84f426c72b9dba7a9b4fe142ba11f534 \ + --hash=sha256:7f277a4b3390ab4bebe597800a90da0edae882c6196d3038a73adf446c4f969f \ + --hash=sha256:7f4c94dec1b5ab5d522750cb059bb9409ea8872d4494fd152b53cca99f1ddd8c \ + --hash=sha256:801cad5ccb6b87d1b430f183269b94c24f248dddbbc5c1f78b6ed231743e001c \ + --hash=sha256:83e787d7a84dbbfba6f250dd7a5efd689e935f03dd83b0f919d39349e1f23f83 \ + --hash=sha256:89042e61b5e808b67daf24a434d89bab164d4de1746b37a8d173b6b14f3db9ff \ + --hash=sha256:92864f54fb48b4c718fc92a32825d0e42265a627f956bc0361fe869f1adc3e7d \ + --hash=sha256:9d52ed507c2488eddd6a95bccee4e808d3234fa78dd370e24bac65a21212b861 \ + --hash=sha256:9fffdb387abe6aa775af36ef16f55e318dcda4194ddbf82007a6f21da29de8f5 \ + --hash=sha256:a28bc05039bdf3289d757f49d616ab3efe8cf40d8e8001ccdd621cd4f98f4fc9 \ + --hash=sha256:a5393eae5722bcef046a990b84dff02b954904c36a194f6cfc817d7dca6c6f0b \ + --hash=sha256:a71f70ee269671460b37a449f5ff26982a6f2ba493b3eabdd687b4bf35f875ac \ + --hash=sha256:b17366316c654e1ad0306a6858e189fc835eca39f7eb2cafd6aaca8ce0c40a2e \ + --hash=sha256:baade0a5657654c2984468efb7d6c110db87ea63ef5a4b54732e7e337253e44f \ + --hash=sha256:c2388ca94ffee269b6038d48747f4ce8df0ffbea43f31abfa18ac72f0218effb \ + --hash=sha256:c58b56cdfb03202b3bcc9fd8daee8e8e9b6d7e3163aa97c631dfcfcc24d36c86 \ + --hash=sha256:cde08734f12c6a4e28dc6755cd11d3bdfea608d93d958fffbe95a7026ebe4980 \ + --hash=sha256:d79e5c65dcc9af213594d6f7f1fa2c98ad3fc10431e7aa53c176b441943efbdd \ + --hash=sha256:d8d65b564ec849643d9f7ea05c6d9f0cd7ca23bdd4ac0c2dbef1104ab504543d \ + --hash=sha256:db99dca3b1fdc3db87d7c57eac0c82281242d1eabf19dcb8a6b10eb29a2e72d1 \ + --hash=sha256:dcd58e2b3a908b5ecc9b9df2f0085592506ac2d5110786018ee5e160f28e0911 \ + --hash=sha256:dd19cf5184a90c873009244586396a6a884d591a5323f0e8a5922560718d4993 \ + --hash=sha256:ddb4e1500f6efdd402218ffe34d040a1196c072e07929b9820f363a1fd1f4191 \ + --hash=sha256:e3cf5b2560c7b5a142286f69bde914494b6d8f901aaa71e453078388a50881c4 \ + --hash=sha256:ed2e1365e31fc73f1825fa830f1c8f8917ca1b3ca6185773b349c20fd606cec2 \ + --hash=sha256:edfcdcedd0d0f05850c52ba3127b1fce70b9f89e0fe5ff16517df7e81fa3cbb8 \ + --hash=sha256:f0ce778135f60799d89c9693b9b398819d15f1921ba15fe719acb3178215a7db \ + --hash=sha256:f2347d3534e76bf50bca5500989d6c1d05ed64b440408057a37673282c654927 \ + --hash=sha256:f3c08197f3039bec79cee59a606d62b96b16669cff3949f21e74796b6e3cd2be \ + --hash=sha256:f632fd56fc4e61564f78b46a2269153122db34988e78b6be8b32d28507b7eaeb \ + --hash=sha256:f6984a24db30548fd39a44360532898c33528b74aedf81c26cf29c51ee47057e \ + --hash=sha256:f70aadb7a809305226daedf75d90379c397b094755a710d7014b8b117df1ebbf \ + --hash=sha256:f748f7c2d6fd375cc93d3fba7ef4a9e3a092421b8dbf34d8d4dc06be9492dfdd \ + --hash=sha256:f8429e1c410b4073944f03bd778a9e066e7fad723564a52ff91841d278dfc822 \ + --hash=sha256:fc746432b951e92b58317af8e0ca746efe93e66555f1b40888865ef5bf56446b + # via paramiko +beautifulsoup4==4.14.3 \ + --hash=sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb \ + --hash=sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86 + # via + # docling + # nbconvert +bigtree==1.2.0 \ + --hash=sha256:157bab9492a644243563e63a5c9a730d51267c6653046986ad42d5268bedeef7 \ + --hash=sha256:86c09a4d5cc5597db057813205f34972b4db6aac4f99fe3b97d3f322ebc13030 + # via feast (setup.py) +bleach[css]==6.3.0 \ + --hash=sha256:6f3b91b1c0a02bb9a78b5a454c92506aa0fdf197e1d5e114d2e00c6f64306d22 \ + --hash=sha256:fe10ec77c93ddf3d13a73b035abaac7a9f5e436513864ccdad516693213c65d6 + # via nbconvert +boto3==1.38.27 \ + --hash=sha256:94bd7fdd92d5701b362d4df100d21e28f8307a67ff56b6a8b0398119cf22f859 \ + --hash=sha256:95f5fe688795303a8a15e8b7e7f255cadab35eae459d00cc281a4fd77252ea80 + # via + # feast (setup.py) + # ikvpy + # moto + # snowflake-connector-python +botocore==1.38.46 \ + --hash=sha256:8798e5a418c27cf93195b077153644aea44cb171fcd56edc1ecebaa1e49e226e \ + --hash=sha256:89ca782ffbf2e8769ca9c89234cfa5ca577f1987d07d913ee3c68c4776b1eb5b + # via + # aiobotocore + # boto3 + # moto + # s3transfer + # snowflake-connector-python +build==1.4.0 \ + --hash=sha256:6a07c1b8eb6f2b311b96fcbdbce5dab5fe637ffda0fd83c9cac622e927501596 \ + --hash=sha256:f1b91b925aa322be454f8330c6fb48b465da993d1e7e7e6fa35027ec49f3c936 + # via + # feast (setup.py) + # pip-tools + # singlestoredb +cassandra-driver==3.29.3 \ + --hash=sha256:064bf45d3ca87239e11168c0110676fc64f7fdbddb4bcba9be787b8ad5f6d734 \ + --hash=sha256:0785f6e0986089e922378ae3b64b5f696440aeb595fb84c2cf3ccef220c6ae91 \ + --hash=sha256:158f7e5cb894a76a592aa0ca659a8e7c2a57ef603e04c07bbbc289a70e9ac893 \ + --hash=sha256:1c241ba08473baf31a333feb59793190d01625541c2368d3bbb0f43a586f1d6a \ + --hash=sha256:26013d768b2ea4728c09144b08c0eb86ad692e85cb15f4e52e3107abca83683c \ + --hash=sha256:27adf8869937461ad08c5fefb47857532e467b408db496db4dbf8b132a4bd623 \ + --hash=sha256:281f67af1b8df88741eef551afbb49f78e4f366a7ab23e7060a1f0d6ba655752 \ + --hash=sha256:29fc241475801872dc27c3dd1a3976373536223dd4fd1c01868ff86bdbbfd48b \ + --hash=sha256:2b72312a8b62a905da6133effbba9b0731c8e30af96e10ca77fc5c34532c6827 \ + --hash=sha256:2cb72808dfc46c40a6ee352ace181ce3170adde1cfd1447da91709a8cf482e20 \ + --hash=sha256:38216e13d6f2e0d4513a5b8806e70ce4a8f28a82962793a67371582fc2c7141b \ + --hash=sha256:3f654b01d8d49f68deedfaff1edcff314e3103d29130b2a034df6c490c522351 \ + --hash=sha256:51d6a5390e2454b599500049f0a5c72aa701db155c1e542f9a1157c1c45814b1 \ + --hash=sha256:54afde4aaa5b55fbc2c075e1c55fb14a5739459428f3bb81f849ad020f7d5bcf \ + --hash=sha256:572bd5a01089ab92da12f4f52b32b878547bbc544a798d8cfd042e7fc2601c75 \ + --hash=sha256:5a0113020d86e8f61c7a2ae3d508720cd036df7462a55926b85dd97ada27e143 \ + --hash=sha256:5f9858b5ccdf75dd89c20d74474b59dd3a2e2f86c7251b310011c46acdef3874 \ + --hash=sha256:638047c1f70fb14c9d8f743931d4f4f42aff6793b47afded3097c002ef8c1165 \ + --hash=sha256:63adca0f9219be3fe8789f4aa7b77c5f6a7bf65d6442959db52c653140ca4185 \ + --hash=sha256:7552fb7189acd06161f8feac7045a387dc9e03b3b9f7dcb5675178906cee792e \ + --hash=sha256:7a2f371af54cd1d153ef373a733889ebfbcc9c30e00429fc12a2569bad9239e1 \ + --hash=sha256:84b24f69a7bbe76302330d47422a7fcc1998a6a96ffd414a795d7d95992b49cb \ + --hash=sha256:891a1b6a111a591ad9f1c9e088846848dc9e6be030a6086c8c3aa5d2d837f266 \ + --hash=sha256:96ad742f5cbfb771df512959ab5de36e248ce9aa2c487fd81c37d5c0a627c094 \ + --hash=sha256:9abedc832e9a6636741299aae46c032d8c1248b507d8cebbaa2f48ec202904bc \ + --hash=sha256:9b7032b44769c454e96aa11483bfd167a87ea341268f1075b0ff84f780c910a9 \ + --hash=sha256:c935431682557ffcd3efc1c7bcb01b0f6769a1c90751a7154d5e3c905a6a2042 \ + --hash=sha256:e1d09691d757f5b1900a98cc3b6cc7d8506683a2188c01eca86545f91edbbaf5 \ + --hash=sha256:facd488c2b9be8bffcad5903566581e96d2863d2ec4bcad7f114d1b2b2f39ad0 \ + --hash=sha256:fcf45725ae1751cb934b9b827a7d9cd899bbd09eb1ad28e2160b4584de35ba77 \ + --hash=sha256:ff6b82ee4533f6fd4474d833e693b44b984f58337173ee98ed76bce08721a636 + # via feast (setup.py) +certifi==2026.1.4 \ + --hash=sha256:9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c \ + --hash=sha256:ac726dd470482006e014ad384921ed6438c457018f4b3d204aea4281258b2120 + # via + # clickhouse-connect + # docling + # elastic-transport + # httpcore + # httpx + # kubernetes + # minio + # requests + # snowflake-connector-python +cffi==1.17.1 \ + --hash=sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8 \ + --hash=sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2 \ + --hash=sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1 \ + --hash=sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15 \ + --hash=sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36 \ + --hash=sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824 \ + --hash=sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8 \ + --hash=sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36 \ + --hash=sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17 \ + --hash=sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf \ + --hash=sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc \ + --hash=sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3 \ + --hash=sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed \ + --hash=sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702 \ + --hash=sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1 \ + --hash=sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8 \ + --hash=sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903 \ + --hash=sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6 \ + --hash=sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d \ + --hash=sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b \ + --hash=sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e \ + --hash=sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be \ + --hash=sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c \ + --hash=sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683 \ + --hash=sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9 \ + --hash=sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c \ + --hash=sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8 \ + --hash=sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1 \ + --hash=sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4 \ + --hash=sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655 \ + --hash=sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67 \ + --hash=sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595 \ + --hash=sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0 \ + --hash=sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65 \ + --hash=sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41 \ + --hash=sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6 \ + --hash=sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401 \ + --hash=sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6 \ + --hash=sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3 \ + --hash=sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16 \ + --hash=sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93 \ + --hash=sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e \ + --hash=sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4 \ + --hash=sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964 \ + --hash=sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c \ + --hash=sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576 \ + --hash=sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0 \ + --hash=sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3 \ + --hash=sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662 \ + --hash=sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3 \ + --hash=sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff \ + --hash=sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5 \ + --hash=sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd \ + --hash=sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f \ + --hash=sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5 \ + --hash=sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14 \ + --hash=sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d \ + --hash=sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9 \ + --hash=sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7 \ + --hash=sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382 \ + --hash=sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a \ + --hash=sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e \ + --hash=sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a \ + --hash=sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4 \ + --hash=sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99 \ + --hash=sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87 \ + --hash=sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b + # via + # feast (setup.py) + # argon2-cffi-bindings + # cryptography + # ikvpy + # pynacl + # snowflake-connector-python +cfgv==3.5.0 \ + --hash=sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0 \ + --hash=sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132 + # via pre-commit +charset-normalizer==3.4.4 \ + --hash=sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad \ + --hash=sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93 \ + --hash=sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394 \ + --hash=sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89 \ + --hash=sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc \ + --hash=sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86 \ + --hash=sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63 \ + --hash=sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d \ + --hash=sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f \ + --hash=sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8 \ + --hash=sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0 \ + --hash=sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505 \ + --hash=sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161 \ + --hash=sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af \ + --hash=sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152 \ + --hash=sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318 \ + --hash=sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72 \ + --hash=sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4 \ + --hash=sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e \ + --hash=sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3 \ + --hash=sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576 \ + --hash=sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c \ + --hash=sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1 \ + --hash=sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8 \ + --hash=sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1 \ + --hash=sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2 \ + --hash=sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44 \ + --hash=sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26 \ + --hash=sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88 \ + --hash=sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016 \ + --hash=sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede \ + --hash=sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf \ + --hash=sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a \ + --hash=sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc \ + --hash=sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0 \ + --hash=sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84 \ + --hash=sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db \ + --hash=sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1 \ + --hash=sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7 \ + --hash=sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed \ + --hash=sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8 \ + --hash=sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133 \ + --hash=sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e \ + --hash=sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef \ + --hash=sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14 \ + --hash=sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2 \ + --hash=sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0 \ + --hash=sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d \ + --hash=sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828 \ + --hash=sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f \ + --hash=sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf \ + --hash=sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6 \ + --hash=sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328 \ + --hash=sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090 \ + --hash=sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa \ + --hash=sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381 \ + --hash=sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c \ + --hash=sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb \ + --hash=sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc \ + --hash=sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a \ + --hash=sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec \ + --hash=sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc \ + --hash=sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac \ + --hash=sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e \ + --hash=sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313 \ + --hash=sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569 \ + --hash=sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3 \ + --hash=sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d \ + --hash=sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525 \ + --hash=sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894 \ + --hash=sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3 \ + --hash=sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9 \ + --hash=sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a \ + --hash=sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9 \ + --hash=sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14 \ + --hash=sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25 \ + --hash=sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50 \ + --hash=sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf \ + --hash=sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1 \ + --hash=sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3 \ + --hash=sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac \ + --hash=sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e \ + --hash=sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815 \ + --hash=sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c \ + --hash=sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6 \ + --hash=sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6 \ + --hash=sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e \ + --hash=sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4 \ + --hash=sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84 \ + --hash=sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69 \ + --hash=sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15 \ + --hash=sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191 \ + --hash=sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0 \ + --hash=sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897 \ + --hash=sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd \ + --hash=sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2 \ + --hash=sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794 \ + --hash=sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d \ + --hash=sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074 \ + --hash=sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3 \ + --hash=sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224 \ + --hash=sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 \ + --hash=sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a \ + --hash=sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d \ + --hash=sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d \ + --hash=sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f \ + --hash=sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8 \ + --hash=sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490 \ + --hash=sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966 \ + --hash=sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9 \ + --hash=sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3 \ + --hash=sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e \ + --hash=sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608 + # via + # requests + # snowflake-connector-python +click==8.2.1 \ + --hash=sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202 \ + --hash=sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b + # via + # feast (setup.py) + # dask + # geomet + # great-expectations + # pip-tools + # ray + # typer + # uvicorn +clickhouse-connect==0.10.0 \ + --hash=sha256:01e5ba7696789b445392816180910a6bc9b0995cb86f3d503179e2be13991919 \ + --hash=sha256:0b3bbb1efdb3d71b6a2a2dcd607b0899f3b1ffe1e8125662709ee2ebbc1503cc \ + --hash=sha256:1159ee2c33e7eca40b53dda917a8b6a2ed889cb4c54f3d83b303b31ddb4f351d \ + --hash=sha256:1246137a53fb270d4bb8b51e56816d5b3f5cc595a5b2d281393308a34d8a5f43 \ + --hash=sha256:1405057ae1b6225e2de7879f582afcf7049d2cde858d0bda32b615d5f82ed330 \ + --hash=sha256:185975081de4dbec4096210f0c5adf1cf89e4c03e92f5eab1afbb70cf0636c14 \ + --hash=sha256:195f1824405501b747b572e1365c6265bb1629eeb712ce91eda91da3c5794879 \ + --hash=sha256:19cb3af95721013a0f8e88276277e23e960b08f7c14613a325a14c418207f54f \ + --hash=sha256:21e9fe9fbca37724898ff15e29c5332682786e0b95ba0c15b5f3a9c628c83873 \ + --hash=sha256:225d052bd5b885e43dd13b3a3bb251f76fcdd429b160558d2abb50ebe958f921 \ + --hash=sha256:28f2666e59bf478461693e10e84acaa9a7e32b427d2d3d72843fd7e0a7415a77 \ + --hash=sha256:2c755df1791c779b3a0a54e0789f6f55cbedfc6d6aa49046223e62986886b90d \ + --hash=sha256:3646fc9184a5469b95cf4a0846e6954e6e9e85666f030a5d2acae58fa8afb37e \ + --hash=sha256:40b7cf86d016ae6c6c3af6a7b5786f41c18632bfbc9e58d0c4a21a4c5d50c674 \ + --hash=sha256:42a5101decf2d9b49cf95619486e9f4d192e08d05886c513001f6238a21f4c70 \ + --hash=sha256:48554e836c6b56fe0854d9a9f565569010583d4960094d60b68a53f9f83042f0 \ + --hash=sha256:51193dc39f4169b0dd6da13003bbea60527dea92eb2408aecae7f1fb4ad2c5a4 \ + --hash=sha256:57239e8f49fc31d5993cb6b3bc14c00f2704d6a4a73c96ad97496c6c00144da5 \ + --hash=sha256:5b20b3f8f93743f4dcc61dc2bd9e5c374de1e57d4a601f48e46dd06d2d4f7b97 \ + --hash=sha256:5fa4f3763d46b90dc28b1f38eba8de83fbf6c9928f071dd66074e7d6de80e21b \ + --hash=sha256:60772faa54d56f0fa34650460910752a583f5948f44dddeabfafaecbca21fc54 \ + --hash=sha256:6286832cc79affc6fddfbf5563075effa65f80e7cd1481cf2b771ce317c67d08 \ + --hash=sha256:63bbb5721bfece698e155c01b8fa95ce4377c584f4d04b43f383824e8a8fa129 \ + --hash=sha256:6db414cd78333c5430e95d21c75968ad5416a37662fb7ef5536ddae1e46283ee \ + --hash=sha256:71cafb1918ec41dd46d6ec943a1d8caa3bf1f9a59c5b3d73d2dfda065d4834b7 \ + --hash=sha256:75a91c5c29d1afad1f925037747200c2a57106665dc40234bfd5e92436588874 \ + --hash=sha256:75e9de32b9a9f3c39caf5c8837eb07512fa4e8de7a182bcdbb82f2ae551d7651 \ + --hash=sha256:7907624635fe7f28e1b85c7c8b125a72679a63ecdb0b9f4250b704106ef438f8 \ + --hash=sha256:7c72d7a0564fe8e3c393ad89f19cfdc31cd7bd8b2abd9ff1a4ea66a034180a70 \ + --hash=sha256:7e0d9ad118a398c269b45591077d496ee5472cf78f4e334a709e9e2aa064eedf \ + --hash=sha256:7fbdba6b414d52e21cccb23545e3562873318a898247e9b7108aec019911f1b4 \ + --hash=sha256:7fe2a6cd98517330c66afe703fb242c0d3aa2c91f2f7dc9fb97c122c5c60c34b \ + --hash=sha256:88b4890f13163e163bf6fa61f3a013bb974c95676853b7a4e63061faf33911ac \ + --hash=sha256:8a4f20ea756e0c019e06a51d23f41edf1f0c260615e0572cb7ab0f696dfec91c \ + --hash=sha256:8d70432f1dfb88f49d7d95f62c51d762cf1fb5867e7e52aeab1f97f1bebf678e \ + --hash=sha256:92b8b6691a92d2613ee35f5759317bd4be7ba66d39bf81c4deed620feb388ca6 \ + --hash=sha256:93bf4869d27d9e86469f8fa4f0f27a618e4e63a970c3084f531c0d4706efba49 \ + --hash=sha256:9c30c902da7eb01d60b61b566603ab2069e0813b8db60b7c75a4be34b62f63e8 \ + --hash=sha256:9d9b815ec685e143ba22fb6b6803a397da2daacccaa700ced998633ff0ef5e24 \ + --hash=sha256:9eb8df083e5fda78ac7249938691c2c369e8578b5df34c709467147e8289f1d9 \ + --hash=sha256:a0256328802c6e5580513e197cef7f9ba49a99fc98e9ba410922873427569564 \ + --hash=sha256:a22457d56570eea77618e30e2a250484a7d70594dc10d636b4d5a454bb405e9a \ + --hash=sha256:a2427d312bc3526520a0be8c648479af3f6353da7a33a62db2368d6203b08efd \ + --hash=sha256:a545a9a1ebbd8489bf81dfad43ae877ce54d51ed88b635a35df9f4ea42eba6a4 \ + --hash=sha256:aacaff01523192fd319f60440908b67ca5e26c762a74a00a7c32f9913fe59e12 \ + --hash=sha256:b090c7d8e602dd084b2795265cd30610461752284763d9ad93a5d619a0e0ff21 \ + --hash=sha256:b3e393dd95bcce02307f558f6aee53bf2a1bfc83f13030c9b4e47b2045de293f \ + --hash=sha256:b8a708d38b81dcc8c13bb85549c904817e304d2b7f461246fed2945524b7a31b \ + --hash=sha256:bd6e1870df82dd57a47bc2a2a6f39c57da8aee43cc291a44d04babfdec5986dc \ + --hash=sha256:c4cf7a2e62874f173b34c593941da1d7472c9db6ffdd6de0123ecc3cfecf6b8d \ + --hash=sha256:d0afc1b2fef342f4b077c66fb8bf87bbe7ec74547940357239d35c249d45f983 \ + --hash=sha256:d69b3f55a3a2f5414db7bed45afcca940e78ce1867cf5cc0c202f7be21cf48e9 \ + --hash=sha256:db8452ef4efe1948c180a7becb572fb4926dfc69f9f5cdd29e70841b7e97e8dd \ + --hash=sha256:e32ef05046558928728d577ff6e053495cb5bf870e1f61fd2ea0c980587fefb7 \ + --hash=sha256:ef58f431e2ef3c2a91a6d5535484186f2f57f50eff791410548b17017563784b \ + --hash=sha256:f50fe43ddd9161986cc881ce2276d665d99c3d77f5d595c9e9497f9f10e0270b \ + --hash=sha256:f798b9941490e9d6aa1b86c6f06a602d0568cc12c0589c8cfc406fb871f42062 \ + --hash=sha256:f927722c5e054cf833a4112cf82d633e37d3b329f01e232754cc2678be268020 \ + --hash=sha256:fe7e6be0f40a8a77a90482944f5cc2aa39084c1570899e8d2d1191f62460365b + # via feast (setup.py) +cloudpickle==3.1.2 \ + --hash=sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414 \ + --hash=sha256:9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a + # via dask +codeflare-sdk==0.33.1 \ + --hash=sha256:6622a73edde5042455ae7d76279a5279c55db4950533ea7f12aac2fc51d49bb8 \ + --hash=sha256:ad41ec5260217fd030904fb4b9fe62e26c3f51ac7999a5d607eb4b1359edd5e5 + # via feast (setup.py) +colorama==0.4.6 \ + --hash=sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44 \ + --hash=sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 + # via + # feast (setup.py) + # great-expectations +colorful==0.5.8 \ + --hash=sha256:a9381fdda3337fbaba5771991020abc69676afa102646650b759927892875992 \ + --hash=sha256:bb16502b198be2f1c42ba3c52c703d5f651d826076817185f0294c1a549a7445 + # via ray +comm==0.2.3 \ + --hash=sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971 \ + --hash=sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417 + # via + # ipykernel + # ipywidgets +couchbase==4.3.2 \ + --hash=sha256:032a180afd6621358b2c73543b9c5db9939b442fc3ad6d54417c36c8a8f65838 \ + --hash=sha256:11ce688ed46edf8387bf51866618c7b4e06399e7fb34a6df002764996c109d1f \ + --hash=sha256:1f0bf68a2a67958db87a81da4d30d63915f39598482d62cd7fe9752b625dcb19 \ + --hash=sha256:220fe6b75ebbda4651a8e0370642c0f5db5da7f3b0acd9fc8e2b5b31427f9fb1 \ + --hash=sha256:2841b86eb80454279548d8102ce6e71f5bc791eb4a83cb3575b7cf4104c374b2 \ + --hash=sha256:30115cde63fc18abe587d167bbb0d37e8c253f7430e08e69f64eaca2eb7e4ca0 \ + --hash=sha256:3fb88b9f52c2099a4e25fbc30f27734c3da5c86af930de1f4102d03a3df8e77a \ + --hash=sha256:401a7d5a442196bf805746b8354636753ec12c788fba918245345c32211bdf0c \ + --hash=sha256:419a79b2a98bf3d168b264e0dfc1a0949727a2c3ef455e2ffe8e734a2fdc6e7a \ + --hash=sha256:46e492814163162a43d5cbf867eac0d685ea73c803f3238f65c0068ea4a2ce61 \ + --hash=sha256:52cdcd65fb6565f51ea4540fe823143f0fb9d650136b96b904b1650b05a06746 \ + --hash=sha256:540545fd867de02985eb16733c1b16228b0e09461e44a9c2bfad0200fdf7d09a \ + --hash=sha256:5b4eccd4a0ac30d58ea0570a1882a8c0e367a9d54d80c0f6a288e348d1b2b41e \ + --hash=sha256:5b8ee78c7a4b7451db6fcd534dc24462f2cd0e863f16495e687a23b7aecf8296 \ + --hash=sha256:687cb157c89822f463fd5373356e38ee7ebecf6306c9da9cae5b54cedad2b66d \ + --hash=sha256:6a43ce67ffe90bbb5460da5c95d778e804bcd81c037cc8a347f2966afc6c4b5a \ + --hash=sha256:6dcff2c9907ee506e63814c417212e9b51760b914609771dff92508888031dfa \ + --hash=sha256:6f3c2fc874a8b6ca7e6c8b3aaebcbfa4e14937afdb470aaa9b16724c4746b8d5 \ + --hash=sha256:6f820249b9d71593b29fb0ab3eff66ba36914076e00486ca0b99ce6ac6fd1ce9 \ + --hash=sha256:841c59deff25a3185469726d96cce0e120e6b062e724cb6981d1a2c1e2a629e5 \ + --hash=sha256:85df43305f2646203192d67a9433abb5e1098390cba6adec8c4f675ba9ba7fdc \ + --hash=sha256:86e2713759b26ee279574d740151ba4b0ad859a45fc7ac1d13fcdd39d8ee2951 \ + --hash=sha256:a4b964dd2b804036c57b670734b7aa02985dc5cf6d1a8f9f7d4af8feaf012fef \ + --hash=sha256:aac415f89c38482ac076b4b766537701e99f728cc1c5b2de8c16fa28ce7caa53 \ + --hash=sha256:b12288e15326b6fae027a419467403d6c9f3f9641cd9cfee0ab0930a9d2315cd \ + --hash=sha256:bbefa6111be033587b04b2586f5fc8d6db9a76ec138fea5288c8698c8f294bc2 \ + --hash=sha256:bd93d352ccb35c86eec9e5b4d1de015c26c15b52c80204f75189bde627b8b529 \ + --hash=sha256:bf5814a8e9efe405c9c81145c8afca7e55b964543984c9d8dc340163597b09b2 \ + --hash=sha256:c139c594118e1df6932491c26b825ac777fd201f49cda303892065e607f9c3ef \ + --hash=sha256:c18b7c937e63e6d869371d9c4b0a0f9cc1a87dba48950a4276e294c091d76ce5 \ + --hash=sha256:c50ae993c81d81ed0f02a37cbe034825408195b9fe29980b3379e2e05b2e1bec + # via feast (setup.py) +couchbase-columnar==1.0.0 \ + --hash=sha256:08b0947ee67f8fb15949e9323d60e5dbb44fb2d86d09f6e997a0bdcde6cd2b15 \ + --hash=sha256:0f5ea6a24a73008a2f5a6e3aae51a49f4bb360b198a1f3d2ca4bb22044fe9671 \ + --hash=sha256:16d97e8d87a5cedc12771167860ddf02e0d9c66486ef26f83622284a2aff5de2 \ + --hash=sha256:1e516734b59f6994c8485ebb7d0070c0927f8bffa8bc7e58b7b8e0f81657c1d2 \ + --hash=sha256:2ba2be7e7e13032696f690f11841a895afcde70f1a9b2aa959c95663eacfddc3 \ + --hash=sha256:2be53deb619b9770a23433ca83146076c12e9f6fd59b74009f3afb5664339c7b \ + --hash=sha256:2fa7cfc9fb06f9c8911453a7e7c80ce115dd9f24e753eedbab9f2b9415aae45d \ + --hash=sha256:3835259a260faf3818db0612b11acf0e5db525ecea44ee8cc9164ce3d564f1a8 \ + --hash=sha256:4879c98941fbba04c50c24c8635827bbcf44259b35488456623b6e3448351533 \ + --hash=sha256:49624c174b2bb7d1350be4c6a8554de7461d5748d9ee4d7aea6f880bed35ca2f \ + --hash=sha256:51d6c64aa89bebc3a157b812387bfca9592ef5efb8fbe84ed85a6da8618e911e \ + --hash=sha256:5743193fe5314b34e4c7dc6b4fbe60b7678af6b401ba3b30f81c03bf3c2ff8ab \ + --hash=sha256:732d25b08acd8e30fd620920e788213c8b0edf3936c74ad21d89db911510b64b \ + --hash=sha256:7469365678072900e4d5498b0c744011135037a840ca8d0d2c33dd627508f2e0 \ + --hash=sha256:776c7a52a2253250d5a75ec1f395d2d919df4b7b417005700f241dfd2b074260 \ + --hash=sha256:7c2906720ac80d5b846a077f71ffaf955af41fddd319b3c50b4496e8eec875d9 \ + --hash=sha256:82b2591691d9a188c0319ae1a5b2d67928f0c541fefbf92421a7fc604372cfcf \ + --hash=sha256:85864666cbe8fd726df310a635a522a7c27134ff66cdce455bb314ab990a0839 \ + --hash=sha256:9612170835fd2668d9968eb87a8d85ebfa38ea997d697b4265a0632ffd107b90 \ + --hash=sha256:a698825b6eb7a611fcd76a314ff470d92101505731b9252bd211a1d24ad24a32 \ + --hash=sha256:ab95caa0e5008bb2fc6b90022c6e780ceb2cf21ace2f6306e09e386f19089c18 \ + --hash=sha256:aca0a4d3453857454919dfcd2c360f91a5894c7e522c1e115335c2d3ad0673ed \ + --hash=sha256:b7a949818efdea84bf050e821e81c6293c20b7ee2c55fd68a8e772c08cdb93ba \ + --hash=sha256:cbe66361da2dda11945fcfae584bbeda153300b2dec45ebb708ba9ff53ac8373 \ + --hash=sha256:dc934b033524a4353177a792a7b525e4d2e2f67ba654dacfa80921f48e7edc1c \ + --hash=sha256:e6301c5cba0803c819ab94330c0382805f546c06dbb16108ba28af5f65cc31ab \ + --hash=sha256:ebe16a763af54ebf6aaa21bddddc28089739e37c383c206dc51353399209278d \ + --hash=sha256:efaff88520c34babf243ab0429df5c141e0dbe0c952a24e091a6e5b1374352ab \ + --hash=sha256:fa8fbddf971a2391543bc7dafaf3b581ad1a69c1fa0a474295b38a6fd8aed54f \ + --hash=sha256:fc0fad2d386c5b5df7aaaccd8751e01caa886cc640cc8c92523dd07c4e7be519 \ + --hash=sha256:fc4efa3e15190c3731478006de494b046bc57785e9c8ae99ac8b375a91683e38 + # via feast (setup.py) +coverage[toml]==7.13.1 \ + --hash=sha256:0403f647055de2609be776965108447deb8e384fe4a553c119e3ff6bfbab4784 \ + --hash=sha256:0642eae483cc8c2902e4af7298bf886d605e80f26382124cddc3967c2a3df09e \ + --hash=sha256:0b609fc9cdbd1f02e51f67f51e5aee60a841ef58a68d00d5ee2c0faf357481a3 \ + --hash=sha256:0d2c11f3ea4db66b5cbded23b20185c35066892c67d80ec4be4bab257b9ad1e0 \ + --hash=sha256:0e42e0ec0cd3e0d851cb3c91f770c9301f48647cb2877cb78f74bdaa07639a79 \ + --hash=sha256:132718176cc723026d201e347f800cd1a9e4b62ccd3f82476950834dad501c75 \ + --hash=sha256:16cc1da46c04fb0fb128b4dc430b78fa2aba8a6c0c9f8eb391fd5103409a6ac6 \ + --hash=sha256:18be793c4c87de2965e1c0f060f03d9e5aff66cfeae8e1dbe6e5b88056ec153f \ + --hash=sha256:1a55d509a1dc5a5b708b5dad3b5334e07a16ad4c2185e27b40e4dba796ab7f88 \ + --hash=sha256:1dcb645d7e34dcbcc96cd7c132b1fc55c39263ca62eb961c064eb3928997363b \ + --hash=sha256:2016745cb3ba554469d02819d78958b571792bb68e31302610e898f80dd3a573 \ + --hash=sha256:228b90f613b25ba0019361e4ab81520b343b622fc657daf7e501c4ed6a2366c0 \ + --hash=sha256:309ef5706e95e62578cda256b97f5e097916a2c26247c287bbe74794e7150df2 \ + --hash=sha256:339dc63b3eba969067b00f41f15ad161bf2946613156fb131266d8debc8e44d0 \ + --hash=sha256:3820778ea1387c2b6a818caec01c63adc5b3750211af6447e8dcfb9b6f08dbba \ + --hash=sha256:3d42df8201e00384736f0df9be2ced39324c3907607d17d50d50116c989d84cd \ + --hash=sha256:3e7b8bd70c48ffb28461ebe092c2345536fb18bbbf19d287c8913699735f505c \ + --hash=sha256:3f2f725aa3e909b3c5fdb8192490bdd8e1495e85906af74fe6e34a2a77ba0673 \ + --hash=sha256:3fc6a169517ca0d7ca6846c3c5392ef2b9e38896f61d615cb75b9e7134d4ee1e \ + --hash=sha256:45980ea19277dc0a579e432aef6a504fe098ef3a9032ead15e446eb0f1191aee \ + --hash=sha256:4d010d080c4888371033baab27e47c9df7d6fb28d0b7b7adf85a4a49be9298b3 \ + --hash=sha256:4de84e71173d4dada2897e5a0e1b7877e5eefbfe0d6a44edee6ce31d9b8ec09e \ + --hash=sha256:549d195116a1ba1e1ae2f5ca143f9777800f6636eab917d4f02b5310d6d73461 \ + --hash=sha256:562ec27dfa3f311e0db1ba243ec6e5f6ab96b1edfcfc6cf86f28038bc4961ce6 \ + --hash=sha256:57dfc8048c72ba48a8c45e188d811e5efd7e49b387effc8fb17e97936dde5bf6 \ + --hash=sha256:5899d28b5276f536fcf840b18b61a9fce23cc3aec1d114c44c07fe94ebeaa500 \ + --hash=sha256:60cfb538fe9ef86e5b2ab0ca8fc8d62524777f6c611dcaf76dc16fbe9b8e698a \ + --hash=sha256:623dcc6d7a7ba450bbdbeedbaa0c42b329bdae16491af2282f12a7e809be7eb9 \ + --hash=sha256:67170979de0dacac3f3097d02b0ad188d8edcea44ccc44aaa0550af49150c7dc \ + --hash=sha256:6e73ebb44dca5f708dc871fe0b90cf4cff1a13f9956f747cc87b535a840386f5 \ + --hash=sha256:6f34591000f06e62085b1865c9bc5f7858df748834662a51edadfd2c3bfe0dd3 \ + --hash=sha256:724b1b270cb13ea2e6503476e34541a0b1f62280bc997eab443f87790202033d \ + --hash=sha256:75a6f4aa904301dab8022397a22c0039edc1f51e90b83dbd4464b8a38dc87842 \ + --hash=sha256:77545b5dcda13b70f872c3b5974ac64c21d05e65b1590b441c8560115dc3a0d1 \ + --hash=sha256:776483fd35b58d8afe3acbd9988d5de592ab6da2d2a865edfdbc9fdb43e7c486 \ + --hash=sha256:77cc258aeb29a3417062758975521eae60af6f79e930d6993555eeac6a8eac29 \ + --hash=sha256:794f7c05af0763b1bbd1b9e6eff0e52ad068be3b12cd96c87de037b01390c968 \ + --hash=sha256:868a2fae76dfb06e87291bcbd4dcbcc778a8500510b618d50496e520bd94d9b9 \ + --hash=sha256:8842af7f175078456b8b17f1b73a0d16a65dcbdc653ecefeb00a56b3c8c298c4 \ + --hash=sha256:8d9bc218650022a768f3775dd7fdac1886437325d8d295d923ebcfef4892ad5c \ + --hash=sha256:8f572d989142e0908e6acf57ad1b9b86989ff057c006d13b76c146ec6a20216a \ + --hash=sha256:90480b2134999301eea795b3a9dbf606c6fbab1b489150c501da84a959442465 \ + --hash=sha256:916abf1ac5cf7eb16bc540a5bf75c71c43a676f5c52fcb9fe75a2bd75fb944e8 \ + --hash=sha256:92f980729e79b5d16d221038dbf2e8f9a9136afa072f9d5d6ed4cb984b126a09 \ + --hash=sha256:933082f161bbb3e9f90d00990dc956120f608cdbcaeea15c4d897f56ef4fe416 \ + --hash=sha256:97ab3647280d458a1f9adb85244e81587505a43c0c7cff851f5116cd2814b894 \ + --hash=sha256:985b7836931d033570b94c94713c6dba5f9d3ff26045f72c3e5dbc5fe3361e5a \ + --hash=sha256:9e549d642426e3579b3f4b92d0431543b012dcb6e825c91619d4e93b7363c3f9 \ + --hash=sha256:9edd0e01a343766add6817bc448408858ba6b489039eaaa2018474e4001651a4 \ + --hash=sha256:9ee68b21909686eeb21dfcba2c3b81fee70dcf38b140dcd5aa70680995fa3aa5 \ + --hash=sha256:9f5e772ed5fef25b3de9f2008fe67b92d46831bd2bc5bdc5dd6bfd06b83b316f \ + --hash=sha256:a03a4f3a19a189919c7055098790285cc5c5b0b3976f8d227aea39dbf9f8bfdb \ + --hash=sha256:a4d240d260a1aed814790bbe1f10a5ff31ce6c21bc78f0da4a1e8268d6c80dbd \ + --hash=sha256:a5a68357f686f8c4d527a2dc04f52e669c2fc1cbde38f6f7eb6a0e58cbd17cae \ + --hash=sha256:a998cc0aeeea4c6d5622a3754da5a493055d2d95186bad877b0a34ea6e6dbe0a \ + --hash=sha256:b67e47c5595b9224599016e333f5ec25392597a89d5744658f837d204e16c63e \ + --hash=sha256:b6f3b96617e9852703f5b633ea01315ca45c77e879584f283c44127f0f1ec564 \ + --hash=sha256:b7593fe7eb5feaa3fbb461ac79aac9f9fc0387a5ca8080b0c6fe2ca27b091afd \ + --hash=sha256:bb3f6562e89bad0110afbe64e485aac2462efdce6232cdec7862a095dc3412f6 \ + --hash=sha256:bb4f8c3c9a9f34423dba193f241f617b08ffc63e27f67159f60ae6baf2dcfe0f \ + --hash=sha256:bd63e7b74661fed317212fab774e2a648bc4bb09b35f25474f8e3325d2945cd7 \ + --hash=sha256:be753b225d159feb397bd0bf91ae86f689bad0da09d3b301478cd39b878ab31a \ + --hash=sha256:bf100a3288f9bb7f919b87eb84f87101e197535b9bd0e2c2b5b3179633324fee \ + --hash=sha256:c223d078112e90dc0e5c4e35b98b9584164bea9fbbd221c0b21c5241f6d51b62 \ + --hash=sha256:c3d8c679607220979434f494b139dfb00131ebf70bb406553d69c1ff01a5c33d \ + --hash=sha256:c43257717611ff5e9a1d79dce8e47566235ebda63328718d9b65dd640bc832ef \ + --hash=sha256:c832ec92c4499ac463186af72f9ed4d8daec15499b16f0a879b0d1c8e5cf4a3b \ + --hash=sha256:c8e2706ceb622bc63bac98ebb10ef5da80ed70fbd8a7999a5076de3afaef0fb1 \ + --hash=sha256:cb237bfd0ef4d5eb6a19e29f9e528ac67ac3be932ea6b44fb6cc09b9f3ecff78 \ + --hash=sha256:ccd7a6fca48ca9c131d9b0a2972a581e28b13416fc313fb98b6d24a03ce9a398 \ + --hash=sha256:d10a2ed46386e850bb3de503a54f9fe8192e5917fcbb143bfef653a9355e9a53 \ + --hash=sha256:d1443ba9acbb593fa7c1c29e011d7c9761545fe35e7652e85ce7f51a16f7e08d \ + --hash=sha256:d2287ac9360dec3837bfdad969963a5d073a09a85d898bd86bea82aa8876ef3c \ + --hash=sha256:d3c9f051b028810f5a87c88e5d6e9af3c0ff32ef62763bf15d29f740453ca909 \ + --hash=sha256:d72140ccf8a147e94274024ff6fd8fb7811354cf7ef88b1f0a988ebaa5bc774f \ + --hash=sha256:d938b4a840fb1523b9dfbbb454f652967f18e197569c32266d4d13f37244c3d9 \ + --hash=sha256:db622b999ffe49cb891f2fff3b340cdc2f9797d01a0a202a0973ba2562501d90 \ + --hash=sha256:e09fbecc007f7b6afdfb3b07ce5bd9f8494b6856dd4f577d26c66c391b829851 \ + --hash=sha256:e1fa280b3ad78eea5be86f94f461c04943d942697e0dac889fa18fff8f5f9147 \ + --hash=sha256:e4f18eca6028ffa62adbd185a8f1e1dd242f2e68164dba5c2b74a5204850b4cf \ + --hash=sha256:e825dbb7f84dfa24663dd75835e7257f8882629fc11f03ecf77d84a75134b864 \ + --hash=sha256:eaecf47ef10c72ece9a2a92118257da87e460e113b83cc0d2905cbbe931792b4 \ + --hash=sha256:ef6688db9bf91ba111ae734ba6ef1a063304a881749726e0d3575f5c10a9facf \ + --hash=sha256:f398ba4df52d30b1763f62eed9de5620dcde96e6f491f4c62686736b155aa6e4 \ + --hash=sha256:f80e2bb21bfab56ed7405c2d79d34b5dc0bc96c2c1d2a067b643a09fb756c43a \ + --hash=sha256:f83351e0f7dcdb14d7326c3d8d8c4e915fa685cbfdc6281f9470d97a04e9dfe4 \ + --hash=sha256:f8dca5590fec7a89ed6826fce625595279e586ead52e9e958d3237821fbc750c \ + --hash=sha256:fa3edde1aa8807de1d05934982416cb3ec46d1d4d91e280bcce7cca01c507992 \ + --hash=sha256:fea07c1a39a22614acb762e3fbbb4011f65eedafcb2948feeef641ac78b4ee5c \ + --hash=sha256:ff10896fa55167371960c5908150b434b71c876dfab97b69478f22c8b445ea19 \ + --hash=sha256:ff86d4e85188bba72cfb876df3e11fa243439882c55957184af44a35bd5880b7 \ + --hash=sha256:ffed1e4980889765c84a5d1a566159e363b71d6b6fbaf0bebc9d3c30bc016766 + # via pytest-cov +cryptography==43.0.3 \ + --hash=sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362 \ + --hash=sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4 \ + --hash=sha256:1ec0bcf7e17c0c5669d881b1cd38c4972fade441b27bda1051665faaa89bdcaa \ + --hash=sha256:281c945d0e28c92ca5e5930664c1cefd85efe80e5c0d2bc58dd63383fda29f83 \ + --hash=sha256:2ce6fae5bdad59577b44e4dfed356944fbf1d925269114c28be377692643b4ff \ + --hash=sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805 \ + --hash=sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6 \ + --hash=sha256:4a02ded6cd4f0a5562a8887df8b3bd14e822a90f97ac5e544c162899bc467664 \ + --hash=sha256:53a583b6637ab4c4e3591a15bc9db855b8d9dee9a669b550f311480acab6eb08 \ + --hash=sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e \ + --hash=sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18 \ + --hash=sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f \ + --hash=sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73 \ + --hash=sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5 \ + --hash=sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984 \ + --hash=sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd \ + --hash=sha256:a2a431ee15799d6db9fe80c82b055bae5a752bef645bba795e8e52687c69efe3 \ + --hash=sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e \ + --hash=sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405 \ + --hash=sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2 \ + --hash=sha256:d03b5621a135bffecad2c73e9f4deb1a0f977b9a8ffe6f8e002bf6c9d07b918c \ + --hash=sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995 \ + --hash=sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73 \ + --hash=sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16 \ + --hash=sha256:f18c716be16bc1fea8e95def49edf46b82fccaa88587a45f8dc0ff6ab5d8e0a7 \ + --hash=sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd \ + --hash=sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7 + # via + # feast (setup.py) + # azure-identity + # azure-storage-blob + # codeflare-sdk + # great-expectations + # jwcrypto + # moto + # msal + # paramiko + # pyjwt + # pyopenssl + # snowflake-connector-python + # types-pyopenssl + # types-redis +dask[dataframe]==2026.1.1 \ + --hash=sha256:12b1dbb0d6e92f287feb4076871600b2fba3a843d35ff214776ada5e9e7a1529 \ + --hash=sha256:146b0ef2918eb581e06139183a88801b4a8c52d7c37758a91f8c3b75c54b0e15 + # via feast (setup.py) +datasets==4.0.0 \ + --hash=sha256:7ef95e62025fd122882dbce6cb904c8cd3fbc829de6669a5eb939c77d50e203d \ + --hash=sha256:9657e7140a9050db13443ba21cb5de185af8af944479b00e7ff1e00a61c8dbf1 + # via feast (setup.py) +db-dtypes==1.5.0 \ + --hash=sha256:abdbb2e4eb965800ed6f98af0c5c1cafff9063ace09114be2d26a7f046be2c8a \ + --hash=sha256:ad9e94243f53e104bc77dbf9ae44b580d83a770d3694483aba59c9767966daa5 + # via + # google-cloud-bigquery + # pandas-gbq +debugpy==1.8.19 \ + --hash=sha256:0601708223fe1cd0e27c6cce67a899d92c7d68e73690211e6788a4b0e1903f5b \ + --hash=sha256:14035cbdbb1fe4b642babcdcb5935c2da3b1067ac211c5c5a8fdc0bb31adbcaa \ + --hash=sha256:1e8c4d1bd230067bf1bbcdbd6032e5a57068638eb28b9153d008ecde288152af \ + --hash=sha256:327cb28c3ad9e17bc925efc7f7018195fd4787c2fe4b7af1eec11f1d19bdec62 \ + --hash=sha256:360ffd231a780abbc414ba0f005dad409e71c78637efe8f2bd75837132a41d38 \ + --hash=sha256:4468de0c30012d367944f0eab4ecb8371736e8ef9522a465f61214f344c11183 \ + --hash=sha256:6599cab8a783d1496ae9984c52cb13b7c4a3bd06a8e6c33446832a5d97ce0bee \ + --hash=sha256:66e3d2fd8f2035a8f111eb127fa508469dfa40928a89b460b41fd988684dc83d \ + --hash=sha256:76f566baaf7f3e06adbe67ffedccd2ee911d1e486f55931939ce3f0fe1090774 \ + --hash=sha256:783a519e6dfb1f3cd773a9bda592f4887a65040cb0c7bd38dde410f4e53c40d4 \ + --hash=sha256:7b62c0f015120ede25e5124a5f9d8a424e1208e3d96a36c89958f046ee21fff6 \ + --hash=sha256:806d6800246244004625d5222d7765874ab2d22f3ba5f615416cf1342d61c488 \ + --hash=sha256:85016a73ab84dea1c1f1dcd88ec692993bcbe4532d1b49ecb5f3c688ae50c606 \ + --hash=sha256:8e19a725f5d486f20e53a1dde2ab8bb2c9607c40c00a42ab646def962b41125f \ + --hash=sha256:91e35db2672a0abaf325f4868fcac9c1674a0d9ad9bb8a8c849c03a5ebba3e6d \ + --hash=sha256:a21bfdea088f713df05fa246ba0520f6ba44dd7eaec224742f51987a6979a648 \ + --hash=sha256:b1cb98e5325da3059ca24445fca48314bfddfdf65ce1b59ff07055e723f06bd2 \ + --hash=sha256:b605f17e89ba0ecee994391194285fada89cee111cfcd29d6f2ee11cbdc40976 \ + --hash=sha256:b7dd275cf2c99e53adb9654f5ae015f70415bbe2bacbe24cfee30d54b6aa03c5 \ + --hash=sha256:bccb1540a49cde77edc7ce7d9d075c1dbeb2414751bc0048c7a11e1b597a4c2e \ + --hash=sha256:c047177ab2d286451f242b855b650d313198c4a987140d4b35218b2855a64a4a \ + --hash=sha256:c30639998a9f9cd9699b4b621942c0179a6527f083c72351f95c6ab1728d5b73 \ + --hash=sha256:c5dcfa21de1f735a4f7ced4556339a109aa0f618d366ede9da0a3600f2516d8b \ + --hash=sha256:c9b9bf440141a36836bdbe4320a2b126bb38aafa85e1aed05d7bfbb0e2a278bf \ + --hash=sha256:d40c016c1f538dbf1762936e3aeb43a89b965069d9f60f9e39d35d9d25e6b809 \ + --hash=sha256:d9b6f633fd2865af2afba2beb0c1819b6ecd4aed1c8f90f5d1bbca3272306b10 \ + --hash=sha256:e24b1652a1df1ab04d81e7ead446a91c226de704ff5dde6bd0a0dbaab07aa3f2 \ + --hash=sha256:e9c68d9a382ec754dc05ed1d1b4ed5bd824b9f7c1a8cd1083adb84b3c93501de \ + --hash=sha256:eea7e5987445ab0b5ed258093722d5ecb8bb72217c5c9b1e21f64efe23ddebdb \ + --hash=sha256:fce6da15d73be5935b4438435c53adb512326a3e11e4f90793ea87cd9f018254 + # via ipykernel +decorator==5.2.1 \ + --hash=sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360 \ + --hash=sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a + # via ipython +defusedxml==0.7.1 \ + --hash=sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69 \ + --hash=sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61 + # via nbconvert +deltalake==0.25.5 \ + --hash=sha256:0b36afba5936f74c42920c06d140535e6efc8361f659770014944d8e69fbca09 \ + --hash=sha256:0ca70e824fd7bcd16aeaaf9a43800eb9dc6c5d05b7854328c4cb4a240643ef78 \ + --hash=sha256:173e4b83fcff10f26474ae117161c3f2bdd5f44c30c20463c24b6b8b520e7656 \ + --hash=sha256:4ea62150f9d7d37dce0d973e833b91b07139031cc416ba72ebddbdd1a748f270 \ + --hash=sha256:76be7e1ed8d13f2dc933361057a44a47a89e6112d4f5ea0a73fb510bedd96efc \ + --hash=sha256:cb1c7e826fd7c3bdd3676c7471d3b551e1a3674e44cd8e3747a0017a2c0292b7 \ + --hash=sha256:e8f0d24bf64455f702da8402307b22e01f91e0f76694f7c5e33c9513011e8d29 + # via feast (setup.py) +deprecation==2.1.0 \ + --hash=sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff \ + --hash=sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a + # via python-keycloak +dill==0.3.8 \ + --hash=sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca \ + --hash=sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7 + # via + # feast (setup.py) + # datasets + # multiprocess +distlib==0.4.0 \ + --hash=sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16 \ + --hash=sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d + # via virtualenv +dnspython==2.8.0 \ + --hash=sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af \ + --hash=sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f + # via + # feast (setup.py) + # pymongo +docker==7.1.0 \ + --hash=sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c \ + --hash=sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0 + # via testcontainers +docling==2.27.0 \ + --hash=sha256:1288ed75b27e33bf94daff34faffc6d11b7d7ccc13e3df84fb24adad3991f72d \ + --hash=sha256:faba35662612a2c687a3a463e501d95f645316436084af92a0442ce162429a3d + # via feast (setup.py) +docling-core[chunking]==2.60.0 \ + --hash=sha256:25499f43c9e894e6ff0be5c57a3c4fb78f87caa7808d0829fa11c056600cc2b6 \ + --hash=sha256:7703dfbad7e64fdf38bd3a9518ec80dd0162b5e7850a83fb572bfd88b62b8a39 + # via + # docling + # docling-ibm-models + # docling-parse +docling-ibm-models==3.10.3 \ + --hash=sha256:6be756e45df155a367087b93e0e5f2d65905e7e81a5f57c1d3ae57096631655a \ + --hash=sha256:e034d1398c99059998da18e38ef80af8a5d975f04de17f6e93efa075fb29cac4 + # via docling +docling-parse==4.7.3 \ + --hash=sha256:1790e7e4ae202d67875c1c48fd6f8ef5c51d10b0c23157e4989b8673f2f31308 \ + --hash=sha256:281347b3e937c1a5ffa6f8774ee603b64a0899fe8a6885573dec7eb48a3421d8 \ + --hash=sha256:29c91f78c877ae4637011efdb478f20a571e6794be924795b3469958a6401cd6 \ + --hash=sha256:32a2a8aedc56e82e2e3337b7afb83070db1fcfde86cbd93bba80ef2e331b6c13 \ + --hash=sha256:3b04459cc97a8a4929622e341b9981e23987a63af07db599afc5e1c4d389060b \ + --hash=sha256:45ec74bda63738c72e9f3989d19ef6ea7e3b1d61328ffc68d55b1b18eb6c4002 \ + --hash=sha256:53bd45241dca228715800afa0f96fdc826f7c234e9effcd5cefc86026ff19301 \ + --hash=sha256:5936e6bcb7969c2a13f38ecc75cada3b0919422dc845e96da4b0b7b3bbc394ce \ + --hash=sha256:5fc8f4770f9f6f90ba25f52451864a64394ddb158aea3a8fdda46a208c029cf6 \ + --hash=sha256:659234b800c094525476c6a97e771cd61491201e0c9f4af8ee6d39df9758bcae \ + --hash=sha256:65e0653d9617d38e73bab069dc3e7960668ff4a6b0ff45a7635c3790eeed8a08 \ + --hash=sha256:66896bbe925073e4d48f18ec29dcd611a390d6b2378fae72125e77b020cd5664 \ + --hash=sha256:6cb4fe8c62de06b70e6b38c4bd608f41ea3e9d7154a4e05f9a3c4d8944fe3a25 \ + --hash=sha256:75522790df921b6be5d86cf26d184a4af97c1c65e2d22698a9516bc049c398cf \ + --hash=sha256:91b9fbe8209922f46bbd8c6fd1a44193a4c364ff3fa398af7bcc8aaa404567d9 \ + --hash=sha256:978e7e7032760385264896871ae87cb3a04081766cc966c57e9750ce803162ac \ + --hash=sha256:9d18a5b1f7eecabed631c497a19f19d281a0d86f24bfe5d239e3df89bdc4df32 \ + --hash=sha256:a6e0f9e18d808c87ce0fe1900c74a3496a42743f4bba7ed4dd83a0e6e168644a \ + --hash=sha256:bd23eeb479355316fe807703220439fd1de1df4ca0145a49c35f71b184f87254 \ + --hash=sha256:c5a416ae2e1761914ee8d7dbfbe3858e106c876b5a7fccaa3917c038e2f126ec \ + --hash=sha256:ca64977a19ecd580a48f22137a30470d7ccf0995b2c25a74136c6facec7c617d \ + --hash=sha256:d3d86c51f9ce35a1b40b2f410f7271d9bd5fc58e7240f4cae7fdd2cef757e671 \ + --hash=sha256:d89231aa4fba3e38b80c11beb8edc07569e934c1f3935b51f57904fefe958ba5 \ + --hash=sha256:dc32b6f25a673e41b9a8112b6b841284f60dbac9427b7848a03b435460f74aee \ + --hash=sha256:dffd19ed373b0da5cea124606b183489a8686c3d18643e94485be1bdda5713ea \ + --hash=sha256:ef691045623863624f2cb7347572d0262a53cb84940ef7dd851d9f13a2eb8833 \ + --hash=sha256:f4a93f91f97055e19cade33bb957d83f8615f1d2a0103b89827aca16b31a3e22 + # via docling +docutils==0.19 \ + --hash=sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6 \ + --hash=sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc + # via sphinx +duckdb==1.1.3 \ + --hash=sha256:00cca22df96aa3473fe4584f84888e2cf1c516e8c2dd837210daec44eadba586 \ + --hash=sha256:08935700e49c187fe0e9b2b86b5aad8a2ccd661069053e38bfaed3b9ff795efd \ + --hash=sha256:0897f83c09356206ce462f62157ce064961a5348e31ccb2a557a7531d814e70e \ + --hash=sha256:09c68522c30fc38fc972b8a75e9201616b96ae6da3444585f14cf0d116008c95 \ + --hash=sha256:0a55169d2d2e2e88077d91d4875104b58de45eff6a17a59c7dc41562c73df4be \ + --hash=sha256:0ba6baa0af33ded836b388b09433a69b8bec00263247f6bf0a05c65c897108d3 \ + --hash=sha256:183ac743f21c6a4d6adfd02b69013d5fd78e5e2cd2b4db023bc8a95457d4bc5d \ + --hash=sha256:1aa3abec8e8995a03ff1a904b0e66282d19919f562dd0a1de02f23169eeec461 \ + --hash=sha256:1c0226dc43e2ee4cc3a5a4672fddb2d76fd2cf2694443f395c02dd1bea0b7fce \ + --hash=sha256:1d9ab6143e73bcf17d62566e368c23f28aa544feddfd2d8eb50ef21034286f24 \ + --hash=sha256:2141c6b28162199999075d6031b5d63efeb97c1e68fb3d797279d31c65676269 \ + --hash=sha256:252d9b17d354beb9057098d4e5d5698e091a4f4a0d38157daeea5fc0ec161670 \ + --hash=sha256:25fb02629418c0d4d94a2bc1776edaa33f6f6ccaa00bd84eb96ecb97ae4b50e9 \ + --hash=sha256:2f073d15d11a328f2e6d5964a704517e818e930800b7f3fa83adea47f23720d3 \ + --hash=sha256:35c420f58abc79a68a286a20fd6265636175fadeca1ce964fc8ef159f3acc289 \ + --hash=sha256:4ebf5f60ddbd65c13e77cddb85fe4af671d31b851f125a4d002a313696af43f1 \ + --hash=sha256:4f0e2e5a6f5a53b79aee20856c027046fba1d73ada6178ed8467f53c3877d5e0 \ + --hash=sha256:51c6d79e05b4a0933672b1cacd6338f882158f45ef9903aef350c4427d9fc898 \ + --hash=sha256:51e7dbd968b393343b226ab3f3a7b5a68dee6d3fe59be9d802383bf916775cb8 \ + --hash=sha256:5ace6e4b1873afdd38bd6cc8fcf90310fb2d454f29c39a61d0c0cf1a24ad6c8d \ + --hash=sha256:5d57776539211e79b11e94f2f6d63de77885f23f14982e0fac066f2885fcf3ff \ + --hash=sha256:6411e21a2128d478efbd023f2bdff12464d146f92bc3e9c49247240448ace5a6 \ + --hash=sha256:647f17bd126170d96a38a9a6f25fca47ebb0261e5e44881e3782989033c94686 \ + --hash=sha256:68c3a46ab08836fe041d15dcbf838f74a990d551db47cb24ab1c4576fc19351c \ + --hash=sha256:77f26884c7b807c7edd07f95cf0b00e6d47f0de4a534ac1706a58f8bc70d0d31 \ + --hash=sha256:7c71169fa804c0b65e49afe423ddc2dc83e198640e3b041028da8110f7cd16f7 \ + --hash=sha256:80158f4c7c7ada46245837d5b6869a336bbaa28436fbb0537663fa324a2750cd \ + --hash=sha256:872d38b65b66e3219d2400c732585c5b4d11b13d7a36cd97908d7981526e9898 \ + --hash=sha256:8ee97ec337794c162c0638dda3b4a30a483d0587deda22d45e1909036ff0b739 \ + --hash=sha256:911d58c22645bfca4a5a049ff53a0afd1537bc18fedb13bc440b2e5af3c46148 \ + --hash=sha256:9c619e4849837c8c83666f2cd5c6c031300cd2601e9564b47aa5de458ff6e69d \ + --hash=sha256:9d0767ada9f06faa5afcf63eb7ba1befaccfbcfdac5ff86f0168c673dd1f47aa \ + --hash=sha256:9e3f5cd604e7c39527e6060f430769b72234345baaa0987f9500988b2814f5e4 \ + --hash=sha256:a1f83c7217c188b7ab42e6a0963f42070d9aed114f6200e3c923c8899c090f16 \ + --hash=sha256:a1fa0c502f257fa9caca60b8b1478ec0f3295f34bb2efdc10776fc731b8a6c5f \ + --hash=sha256:a30dd599b8090ea6eafdfb5a9f1b872d78bac318b6914ada2d35c7974d643640 \ + --hash=sha256:a433ae9e72c5f397c44abdaa3c781d94f94f4065bcbf99ecd39433058c64cb38 \ + --hash=sha256:a4748635875fc3c19a7320a6ae7410f9295557450c0ebab6d6712de12640929a \ + --hash=sha256:b74e121ab65dbec5290f33ca92301e3a4e81797966c8d9feef6efdf05fc6dafd \ + --hash=sha256:c443d3d502335e69fc1e35295fcfd1108f72cb984af54c536adfd7875e79cee5 \ + --hash=sha256:c5336939d83837af52731e02b6a78a446794078590aa71fd400eb17f083dda3e \ + --hash=sha256:cddc6c1a3b91dcc5f32493231b3ba98f51e6d3a44fe02839556db2b928087378 \ + --hash=sha256:d08308e0a46c748d9c30f1d67ee1143e9c5ea3fbcccc27a47e115b19e7e78aa9 \ + --hash=sha256:d5724fd8a49e24d730be34846b814b98ba7c304ca904fbdc98b47fa95c0b0cee \ + --hash=sha256:e4ef7ba97a65bd39d66f2a7080e6fb60e7c3e41d4c1e19245f90f53b98e3ac32 \ + --hash=sha256:e59087dbbb63705f2483544e01cccf07d5b35afa58be8931b224f3221361d537 \ + --hash=sha256:e86006958e84c5c02f08f9b96f4bc26990514eab329b1b4f71049b3727ce5989 \ + --hash=sha256:ecb1dc9062c1cc4d2d88a5e5cd8cc72af7818ab5a3c0f796ef0ffd60cfd3efb4 \ + --hash=sha256:eeacb598120040e9591f5a4edecad7080853aa8ac27e62d280f151f8c862afa3 \ + --hash=sha256:f549af9f7416573ee48db1cf8c9d27aeed245cb015f4b4f975289418c6cf7320 \ + --hash=sha256:f58db1b65593ff796c8ea6e63e2e144c944dd3d51c8d8e40dffa7f41693d35d3 \ + --hash=sha256:f9b47036945e1db32d70e414a10b1593aec641bd4c5e2056873d971cc21e978b + # via ibis-framework +dunamai==1.25.0 \ + --hash=sha256:7f9dc687dd3256e613b6cc978d9daabfd2bb5deb8adc541fc135ee423ffa98ab \ + --hash=sha256:a7f8360ea286d3dbaf0b6a1473f9253280ac93d619836ad4514facb70c0719d1 + # via poetry-dynamic-versioning +durationpy==0.10 \ + --hash=sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba \ + --hash=sha256:3b41e1b601234296b4fb368338fdcd3e13e0b4fb5b67345948f4f2bf9868b286 + # via kubernetes +easyocr==1.7.2 \ + --hash=sha256:5be12f9b0e595d443c9c3d10b0542074b50f0ec2d98b141a109cd961fd1c177c + # via docling +elastic-transport==9.2.1 \ + --hash=sha256:39e1a25e486af34ce7aa1bc9005d1c736f1b6fb04c9b64ea0604ded5a61fc1d4 \ + --hash=sha256:97d9abd638ba8aa90faa4ca1bf1a18bde0fe2088fbc8757f2eb7b299f205773d + # via elasticsearch +elasticsearch==9.2.1 \ + --hash=sha256:8665f5a0b4d29a7c2772851c05ea8a09279abb7928b7d727524613bd61d75958 \ + --hash=sha256:97f473418e8976611349757287ac982acf12f4e305182863d985d5a031c36830 + # via feast (setup.py) +entrypoints==0.4 \ + --hash=sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4 \ + --hash=sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f + # via altair +et-xmlfile==2.0.0 \ + --hash=sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa \ + --hash=sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54 + # via openpyxl +execnet==2.1.2 \ + --hash=sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd \ + --hash=sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec + # via pytest-xdist +executing==1.2.0 \ + --hash=sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc \ + --hash=sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107 + # via + # codeflare-sdk + # stack-data +faiss-cpu==1.10.0 \ + --hash=sha256:035e4d797e2db7fc0d0c90531d4a655d089ad5d1382b7a49358c1f2307b3a309 \ + --hash=sha256:2aca486fe2d680ea64a18d356206c91ff85db99fd34c19a757298c67c23262b1 \ + --hash=sha256:2f15b7957d474391fc63f02bfb8011b95317a580e4d9bd70c276f4bc179a17b3 \ + --hash=sha256:3118b5d7680b0e0a3cd64b3d29389d8384de4298739504fc661b658109540b4b \ + --hash=sha256:345a52dbfa980d24b93c94410eadf82d1eef359c6a42e5e0768cca96539f1c3c \ + --hash=sha256:449f3eb778d6d937e01a16a3170de4bb8aabfe87c7cb479b458fb790276310c5 \ + --hash=sha256:473d158fbd638d6ad5fb64469ba79a9f09d3494b5f4e8dfb4f40ce2fc335dca4 \ + --hash=sha256:49b6647aa9e159a2c4603cbff2e1b313becd98ad6e851737ab325c74fe8e0278 \ + --hash=sha256:6693474be296a7142ade1051ea18e7d85cedbfdee4b7eac9c52f83fed0467855 \ + --hash=sha256:6f8c0ef8b615c12c7bf612bd1fc51cffa49c1ddaa6207c6981f01ab6782e6b3b \ + --hash=sha256:70ebe60a560414dc8dd6cfe8fed105c8f002c0d11f765f5adfe8d63d42c0467f \ + --hash=sha256:74c5712d4890f15c661ab7b1b75867812e9596e1469759956fad900999bedbb5 \ + --hash=sha256:7a9fef4039ed877d40e41d5563417b154c7f8cd57621487dad13c4eb4f32515f \ + --hash=sha256:82ca5098de694e7b8495c1a8770e2c08df6e834922546dad0ae1284ff519ced6 \ + --hash=sha256:8ff6924b0f00df278afe70940ae86302066466580724c2f3238860039e9946f1 \ + --hash=sha256:9899c340f92bd94071d6faf4bef0ccb5362843daea42144d4ba857a2a1f67511 \ + --hash=sha256:c1108a4059c66c37c403183e566ca1ed0974a6af7557c92d49207639aab661bc \ + --hash=sha256:cb77a6a5f304890c23ffb4c566bc819c0e0cf34370b20ddff02477f2bbbaf7a3 \ + --hash=sha256:cb80b530a9ded44a7d4031a7355a237aaa0ff1f150c1176df050e0254ea5f6f6 \ + --hash=sha256:cb8473d69c3964c1bf3f8eb3e04287bb3275f536e6d9635ef32242b5f506b45d \ + --hash=sha256:dadbbb834ddc34ca7e21411811833cebaae4c5a86198dd7c2a349dbe4e7e0398 \ + --hash=sha256:dcd0cb2ec84698cbe3df9ed247d2392f09bda041ad34b92d38fa916cd019ad4b \ + --hash=sha256:e02af3696a6b9e1f9072e502f48095a305de2163c42ceb1f6f6b1db9e7ffe574 \ + --hash=sha256:e71f7e24d5b02d3a51df47b77bd10f394a1b48a8331d5c817e71e9e27a8a75ac \ + --hash=sha256:f71c5860c860df2320299f9e4f2ca1725beb559c04acb1cf961ed24e6218277a + # via feast (setup.py) +fastapi==0.128.0 \ + --hash=sha256:1cc179e1cef10a6be60ffe429f79b829dce99d8de32d7acb7e6c8dfdf7f2645a \ + --hash=sha256:aebd93f9716ee3b4f4fcfe13ffb7cf308d99c9f3ab5622d8877441072561582d + # via + # feast (setup.py) + # fastapi-mcp +fastapi-mcp==0.4.0 \ + --hash=sha256:d4a3fe7966af24d44e4b412720561c95eb12bed999a4443a88221834b3b15aec \ + --hash=sha256:d4ca9410996f4c7b8ea0d7b20fdf79878dc359ebf89cbf3b222e0b675a55097d + # via feast (setup.py) +fastjsonschema==2.21.2 \ + --hash=sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463 \ + --hash=sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de + # via nbformat +filelock==3.20.3 \ + --hash=sha256:18c57ee915c7ec61cff0ecf7f0f869936c7c30191bb0cf406f1341778d0834e1 \ + --hash=sha256:4b0dda527ee31078689fc205ec4f1c1bf7d56cf88b6dc9426c4f230e46c2dce1 + # via + # datasets + # huggingface-hub + # ray + # snowflake-connector-python + # torch + # transformers + # virtualenv +filetype==1.2.0 \ + --hash=sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb \ + --hash=sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25 + # via docling +fqdn==1.5.1 \ + --hash=sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f \ + --hash=sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014 + # via jsonschema +frozenlist==1.8.0 \ + --hash=sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686 \ + --hash=sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0 \ + --hash=sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121 \ + --hash=sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd \ + --hash=sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7 \ + --hash=sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c \ + --hash=sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84 \ + --hash=sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d \ + --hash=sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b \ + --hash=sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79 \ + --hash=sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967 \ + --hash=sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f \ + --hash=sha256:13d23a45c4cebade99340c4165bd90eeb4a56c6d8a9d8aa49568cac19a6d0dc4 \ + --hash=sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7 \ + --hash=sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef \ + --hash=sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9 \ + --hash=sha256:1a7607e17ad33361677adcd1443edf6f5da0ce5e5377b798fba20fae194825f3 \ + --hash=sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd \ + --hash=sha256:1aa77cb5697069af47472e39612976ed05343ff2e84a3dcf15437b232cbfd087 \ + --hash=sha256:1b9290cf81e95e93fdf90548ce9d3c1211cf574b8e3f4b3b7cb0537cf2227068 \ + --hash=sha256:20e63c9493d33ee48536600d1a5c95eefc870cd71e7ab037763d1fbb89cc51e7 \ + --hash=sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed \ + --hash=sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b \ + --hash=sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f \ + --hash=sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25 \ + --hash=sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe \ + --hash=sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143 \ + --hash=sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e \ + --hash=sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930 \ + --hash=sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37 \ + --hash=sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128 \ + --hash=sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2 \ + --hash=sha256:332db6b2563333c5671fecacd085141b5800cb866be16d5e3eb15a2086476675 \ + --hash=sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f \ + --hash=sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746 \ + --hash=sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df \ + --hash=sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8 \ + --hash=sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c \ + --hash=sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0 \ + --hash=sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad \ + --hash=sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82 \ + --hash=sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29 \ + --hash=sha256:42145cd2748ca39f32801dad54aeea10039da6f86e303659db90db1c4b614c8c \ + --hash=sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30 \ + --hash=sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf \ + --hash=sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62 \ + --hash=sha256:48e6d3f4ec5c7273dfe83ff27c91083c6c9065af655dc2684d2c200c94308bb5 \ + --hash=sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383 \ + --hash=sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c \ + --hash=sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52 \ + --hash=sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d \ + --hash=sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1 \ + --hash=sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a \ + --hash=sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714 \ + --hash=sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65 \ + --hash=sha256:59a6a5876ca59d1b63af8cd5e7ffffb024c3dc1e9cf9301b21a2e76286505c95 \ + --hash=sha256:5a3a935c3a4e89c733303a2d5a7c257ea44af3a56c8202df486b7f5de40f37e1 \ + --hash=sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506 \ + --hash=sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888 \ + --hash=sha256:667c3777ca571e5dbeb76f331562ff98b957431df140b54c85fd4d52eea8d8f6 \ + --hash=sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41 \ + --hash=sha256:6dc4126390929823e2d2d9dc79ab4046ed74680360fc5f38b585c12c66cdf459 \ + --hash=sha256:7398c222d1d405e796970320036b1b563892b65809d9e5261487bb2c7f7b5c6a \ + --hash=sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608 \ + --hash=sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa \ + --hash=sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8 \ + --hash=sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1 \ + --hash=sha256:799345ab092bee59f01a915620b5d014698547afd011e691a208637312db9186 \ + --hash=sha256:7bf6cdf8e07c8151fba6fe85735441240ec7f619f935a5205953d58009aef8c6 \ + --hash=sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed \ + --hash=sha256:80f85f0a7cc86e7a54c46d99c9e1318ff01f4687c172ede30fd52d19d1da1c8e \ + --hash=sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52 \ + --hash=sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231 \ + --hash=sha256:8a76ea0f0b9dfa06f254ee06053d93a600865b3274358ca48a352ce4f0798450 \ + --hash=sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496 \ + --hash=sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a \ + --hash=sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3 \ + --hash=sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24 \ + --hash=sha256:940d4a017dbfed9daf46a3b086e1d2167e7012ee297fef9e1c545c4d022f5178 \ + --hash=sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695 \ + --hash=sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7 \ + --hash=sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4 \ + --hash=sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e \ + --hash=sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e \ + --hash=sha256:9ff15928d62a0b80bb875655c39bf517938c7d589554cbd2669be42d97c2cb61 \ + --hash=sha256:a6483e309ca809f1efd154b4d37dc6d9f61037d6c6a81c2dc7a15cb22c8c5dca \ + --hash=sha256:a88f062f072d1589b7b46e951698950e7da00442fc1cacbe17e19e025dc327ad \ + --hash=sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b \ + --hash=sha256:adbeebaebae3526afc3c96fad434367cafbfd1b25d72369a9e5858453b1bb71a \ + --hash=sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8 \ + --hash=sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51 \ + --hash=sha256:b37f6d31b3dcea7deb5e9696e529a6aa4a898adc33db82da12e4c60a7c4d2011 \ + --hash=sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8 \ + --hash=sha256:b4f3b365f31c6cd4af24545ca0a244a53688cad8834e32f56831c4923b50a103 \ + --hash=sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b \ + --hash=sha256:b9be22a69a014bc47e78072d0ecae716f5eb56c15238acca0f43d6eb8e4a5bda \ + --hash=sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806 \ + --hash=sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042 \ + --hash=sha256:c23c3ff005322a6e16f71bf8692fcf4d5a304aaafe1e262c98c6d4adc7be863e \ + --hash=sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b \ + --hash=sha256:c7366fe1418a6133d5aa824ee53d406550110984de7637d65a178010f759c6ef \ + --hash=sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d \ + --hash=sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567 \ + --hash=sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a \ + --hash=sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2 \ + --hash=sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0 \ + --hash=sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e \ + --hash=sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b \ + --hash=sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d \ + --hash=sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a \ + --hash=sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52 \ + --hash=sha256:d8b7138e5cd0647e4523d6685b0eac5d4be9a184ae9634492f25c6eb38c12a47 \ + --hash=sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1 \ + --hash=sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94 \ + --hash=sha256:e2de870d16a7a53901e41b64ffdf26f2fbb8917b3e6ebf398098d72c5b20bd7f \ + --hash=sha256:e4a3408834f65da56c83528fb52ce7911484f0d1eaf7b761fc66001db1646eff \ + --hash=sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822 \ + --hash=sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a \ + --hash=sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11 \ + --hash=sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581 \ + --hash=sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51 \ + --hash=sha256:ef2b7b394f208233e471abc541cc6991f907ffd47dc72584acee3147899d6565 \ + --hash=sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40 \ + --hash=sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92 \ + --hash=sha256:f57fb59d9f385710aa7060e89410aeb5058b99e62f4d16b08b91986b9a2140c2 \ + --hash=sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5 \ + --hash=sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4 \ + --hash=sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93 \ + --hash=sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027 \ + --hash=sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd + # via + # aiohttp + # aiosignal +fsspec[http]==2024.9.0 \ + --hash=sha256:4b0afb90c2f21832df142f292649035d80b421f60a9e1c027802e5a0da2b04e8 \ + --hash=sha256:a0947d552d8a6efa72cc2c730b12c41d043509156966cca4fb157b0f2a0c574b + # via + # feast (setup.py) + # dask + # datasets + # huggingface-hub + # ray + # torch +geomet==1.1.0 \ + --hash=sha256:4372fe4e286a34acc6f2e9308284850bd8c4aa5bc12065e2abbd4995900db12f \ + --hash=sha256:51e92231a0ef6aaa63ac20c443377ba78a303fd2ecd179dc3567de79f3c11605 + # via cassandra-driver +google-api-core[grpc]==2.29.0 \ + --hash=sha256:84181be0f8e6b04006df75ddfe728f24489f0af57c96a529ff7cf45bc28797f7 \ + --hash=sha256:d30bc60980daa36e314b5d5a3e5958b0200cb44ca8fa1be2b614e932b75a3ea9 + # via + # feast (setup.py) + # google-cloud-bigquery + # google-cloud-bigquery-storage + # google-cloud-bigtable + # google-cloud-core + # google-cloud-datastore + # google-cloud-storage + # opencensus + # pandas-gbq +google-auth==2.47.0 \ + --hash=sha256:833229070a9dfee1a353ae9877dcd2dec069a8281a4e72e72f77d4a70ff945da \ + --hash=sha256:c516d68336bfde7cf0da26aab674a36fedcf04b37ac4edd59c597178760c3498 + # via + # google-api-core + # google-auth-oauthlib + # google-cloud-bigquery + # google-cloud-bigquery-storage + # google-cloud-bigtable + # google-cloud-core + # google-cloud-datastore + # google-cloud-storage + # pandas-gbq + # pydata-google-auth +google-auth-oauthlib==1.2.4 \ + --hash=sha256:0e922eea5f2baacaf8867febb782e46e7b153236c21592ed76ab3ddb77ffd772 \ + --hash=sha256:3ca93859c6cc9003c8e12b2a0868915209d7953f05a70f4880ab57d57e56ee3e + # via + # pandas-gbq + # pydata-google-auth +google-cloud-bigquery[pandas]==3.40.0 \ + --hash=sha256:0469bcf9e3dad3cab65b67cce98180c8c0aacf3253d47f0f8e976f299b49b5ab \ + --hash=sha256:b3ccb11caf0029f15b29569518f667553fe08f6f1459b959020c83fbbd8f2e68 + # via + # feast (setup.py) + # pandas-gbq +google-cloud-bigquery-storage==2.36.0 \ + --hash=sha256:1769e568070db672302771d2aec18341de10712aa9c4a8c549f417503e0149f0 \ + --hash=sha256:d3c1ce9d2d3a4d7116259889dcbe3c7c70506f71f6ce6bbe54aa0a68bbba8f8f + # via feast (setup.py) +google-cloud-bigtable==2.35.0 \ + --hash=sha256:f355bfce1f239453ec2bb3839b0f4f9937cf34ef06ef29e1ca63d58fd38d0c50 \ + --hash=sha256:f5699012c5fea4bd4bdf7e80e5e3a812a847eb8f41bf8dc2f43095d6d876b83b + # via feast (setup.py) +google-cloud-core==2.5.0 \ + --hash=sha256:67d977b41ae6c7211ee830c7912e41003ea8194bff15ae7d72fd6f51e57acabc \ + --hash=sha256:7c1b7ef5c92311717bd05301aa1a91ffbc565673d3b0b4163a52d8413a186963 + # via + # google-cloud-bigquery + # google-cloud-bigtable + # google-cloud-datastore + # google-cloud-storage +google-cloud-datastore==2.23.0 \ + --hash=sha256:24a1b1d29b902148fe41b109699f76fd3aa60591e9d547c0f8b87d7bf9ff213f \ + --hash=sha256:80049883a4ae928fdcc661ba6803ec267665dc0e6f3ce2da91441079a6bb6387 + # via feast (setup.py) +google-cloud-storage==2.19.0 \ + --hash=sha256:aeb971b5c29cf8ab98445082cbfe7b161a1f48ed275822f59ed3f1524ea54fba \ + --hash=sha256:cd05e9e7191ba6cb68934d8eb76054d9be4562aa89dbc4236feee4d7d51342b2 + # via feast (setup.py) +google-crc32c==1.8.0 \ + --hash=sha256:014a7e68d623e9a4222d663931febc3033c5c7c9730785727de2a81f87d5bab8 \ + --hash=sha256:01f126a5cfddc378290de52095e2c7052be2ba7656a9f0caf4bcd1bfb1833f8a \ + --hash=sha256:0470b8c3d73b5f4e3300165498e4cf25221c7eb37f1159e221d1825b6df8a7ff \ + --hash=sha256:119fcd90c57c89f30040b47c211acee231b25a45d225e3225294386f5d258288 \ + --hash=sha256:14f87e04d613dfa218d6135e81b78272c3b904e2a7053b841481b38a7d901411 \ + --hash=sha256:17446feb05abddc187e5441a45971b8394ea4c1b6efd88ab0af393fd9e0a156a \ + --hash=sha256:19b40d637a54cb71e0829179f6cb41835f0fbd9e8eb60552152a8b52c36cbe15 \ + --hash=sha256:2a3dc3318507de089c5384cc74d54318401410f82aa65b2d9cdde9d297aca7cb \ + --hash=sha256:3b9776774b24ba76831609ffbabce8cdf6fa2bd5e9df37b594221c7e333a81fa \ + --hash=sha256:3cc0c8912038065eafa603b238abf252e204accab2a704c63b9e14837a854962 \ + --hash=sha256:3d488e98b18809f5e322978d4506373599c0c13e6c5ad13e53bb44758e18d215 \ + --hash=sha256:3ebb04528e83b2634857f43f9bb8ef5b2bbe7f10f140daeb01b58f972d04736b \ + --hash=sha256:450dc98429d3e33ed2926fc99ee81001928d63460f8538f21a5d6060912a8e27 \ + --hash=sha256:4b8286b659c1335172e39563ab0a768b8015e88e08329fa5321f774275fc3113 \ + --hash=sha256:57a50a9035b75643996fbf224d6661e386c7162d1dfdab9bc4ca790947d1007f \ + --hash=sha256:61f58b28e0b21fcb249a8247ad0db2e64114e201e2e9b4200af020f3b6242c9f \ + --hash=sha256:6f35aaffc8ccd81ba3162443fabb920e65b1f20ab1952a31b13173a67811467d \ + --hash=sha256:71734788a88f551fbd6a97be9668a0020698e07b2bf5b3aa26a36c10cdfb27b2 \ + --hash=sha256:864abafe7d6e2c4c66395c1eb0fe12dc891879769b52a3d56499612ca93b6092 \ + --hash=sha256:86cfc00fe45a0ac7359e5214a1704e51a99e757d0272554874f419f79838c5f7 \ + --hash=sha256:87b0072c4ecc9505cfa16ee734b00cd7721d20a0f595be4d40d3d21b41f65ae2 \ + --hash=sha256:87fa445064e7db928226b2e6f0d5304ab4cd0339e664a4e9a25029f384d9bb93 \ + --hash=sha256:89c17d53d75562edfff86679244830599ee0a48efc216200691de8b02ab6b2b8 \ + --hash=sha256:8b3f68782f3cbd1bce027e48768293072813469af6a61a86f6bb4977a4380f21 \ + --hash=sha256:a428e25fb7691024de47fecfbff7ff957214da51eddded0da0ae0e0f03a2cf79 \ + --hash=sha256:b0d1a7afc6e8e4635564ba8aa5c0548e3173e41b6384d7711a9123165f582de2 \ + --hash=sha256:ba6aba18daf4d36ad4412feede6221414692f44d17e5428bdd81ad3fc1eee5dc \ + --hash=sha256:cb5c869c2923d56cb0c8e6bcdd73c009c36ae39b652dbe46a05eb4ef0ad01454 \ + --hash=sha256:d511b3153e7011a27ab6ee6bb3a5404a55b994dc1a7322c0b87b29606d9790e2 \ + --hash=sha256:db3fe8eaf0612fc8b20fa21a5f25bd785bc3cd5be69f8f3412b0ac2ffd49e733 \ + --hash=sha256:e6584b12cb06796d285d09e33f63309a09368b9d806a551d8036a4207ea43697 \ + --hash=sha256:f4b51844ef67d6cf2e9425983274da75f18b1597bb2c998e1c0a0e8d46f8f651 \ + --hash=sha256:f639065ea2042d5c034bf258a9f085eaa7af0cd250667c0635a3118e8f92c69c + # via + # google-cloud-bigtable + # google-cloud-storage + # google-resumable-media +google-resumable-media==2.8.0 \ + --hash=sha256:dd14a116af303845a8d932ddae161a26e86cc229645bc98b39f026f9b1717582 \ + --hash=sha256:f1157ed8b46994d60a1bc432544db62352043113684d4e030ee02e77ebe9a1ae + # via + # google-cloud-bigquery + # google-cloud-storage +googleapis-common-protos[grpc]==1.72.0 \ + --hash=sha256:4299c5a82d5ae1a9702ada957347726b167f9f8d1fc352477702a1e851ff4038 \ + --hash=sha256:e55a601c1b32b52d7a3e65f43563e2aa61bcd737998ee672ac9b951cd49319f5 + # via + # feast (setup.py) + # google-api-core + # grpc-google-iam-v1 + # grpcio-status +great-expectations==0.18.8 \ + --hash=sha256:ab41cfa3de829a4f77bdcd4a23244684cbb67fdacc734d38910164cd02ec95b6 \ + --hash=sha256:c1205bede593f679e22e0b3826d6ae1623c439cafd553f9f0bc2b0fd441f6ed9 + # via feast (setup.py) +grpc-google-iam-v1==0.14.3 \ + --hash=sha256:7a7f697e017a067206a3dfef44e4c634a34d3dee135fe7d7a4613fe3e59217e6 \ + --hash=sha256:879ac4ef33136c5491a6300e27575a9ec760f6cdf9a2518798c1b8977a5dc389 + # via google-cloud-bigtable +grpcio==1.62.3 \ + --hash=sha256:059444f0ed5dba73ab7dd0ee7e8e6b606df4130d2b0a9f010f84da4ab9f6c2d8 \ + --hash=sha256:114f2a865886ff33f85d70670e971fe0e3d252a1209656fefa5470286e3fcc76 \ + --hash=sha256:13571a5b868dcc308a55d36669a2d17d9dcd6ec8335213f6c49cc68da7305abe \ + --hash=sha256:1ac0944e9e3ee3e20825226d1e17985e9f88487055c475986cf0922a7d806d8a \ + --hash=sha256:1de3d04d9a4ec31ebe848ae1fe61e4cbc367fb9495cbf6c54368e60609a998d9 \ + --hash=sha256:216740723fc5971429550c374a0c039723b9d4dcaf7ba05227b7e0a500b06417 \ + --hash=sha256:25cd75dc73c5269932413e517be778640402f18cf9a81147e68645bd8af18ab0 \ + --hash=sha256:325c56ce94d738c31059cf91376f625d3effdff8f85c96660a5fd6395d5a707f \ + --hash=sha256:3737e5ef0aa0fcdfeaf3b4ecc1a6be78b494549b28aec4b7f61b5dc357f7d8be \ + --hash=sha256:377babc817e8b4186aed7ed56e832867c513e4e9b6c3503565c344ffdef440d4 \ + --hash=sha256:3fb7d966a976d762a31346353a19fce4afcffbeda3027dd563bc8cb521fcf799 \ + --hash=sha256:43670a25b752b7ed960fcec3db50ae5886dc0df897269b3f5119cde9b731745f \ + --hash=sha256:4439bbd759636e37b66841117a66444b454937e27f0125205d2d117d7827c643 \ + --hash=sha256:454a6aed4ebd56198d37e1f3be6f1c70838e33dd62d1e2cea12f2bcb08efecc5 \ + --hash=sha256:4c9c1502c76cadbf2e145061b63af077b08d5677afcef91970d6db87b30e2f8b \ + --hash=sha256:4dab8b64c438e19c763a6332b55e5efdbecfb7c55ae59a42c38c81ed27955fa5 \ + --hash=sha256:56757d3e4cf5d4b98a30f2c5456151607261c891fa2298a4554848dcbf83083d \ + --hash=sha256:57823dc7299c4f258ae9c32fd327d29f729d359c34d7612b36e48ed45b3ab8d0 \ + --hash=sha256:582bd03e9c3d1bd1162eb51fa0f1a35633d66e73f4f36702d3b8484a8b45eda7 \ + --hash=sha256:620165df24aae3d5b3e84cb8dd6b98f6ed49aed04126186bbf43061e301d6a21 \ + --hash=sha256:646c14e9f3356d3f34a65b58b0f8d08daa741ba1d4fcd4966b79407543332154 \ + --hash=sha256:668211f3699bbee4deaf1d6e6b8df59328bf63f077bf2dc9b8bfa4a17df4a279 \ + --hash=sha256:6be243f3954b0ca709f56f9cae926c84ac96e1cce19844711e647a1f1db88b99 \ + --hash=sha256:6da20a1ae010a988bc4ed47850f1122de0a88e18cd2f901fcf56007be1fc6c30 \ + --hash=sha256:7349cd7445ac65fbe1b744dcab9cc1ec02dae2256941a2e67895926cbf7422b4 \ + --hash=sha256:74f3fc9b93290e58264844f5bc46df4c58a94c4287a277dbcf75344fc6c37ca4 \ + --hash=sha256:75a4e9ac7ff185cad529f35934c5d711b88aca48b90c70e195f5657da50ce321 \ + --hash=sha256:7b33c1807d4ac564a3027d06f21a2220c116ceacaaef614deb96b3341ee58896 \ + --hash=sha256:807176971c504c598976f5a9ea62363cffbbbb6c7509d9808c2342b020880fa2 \ + --hash=sha256:80a82fdee14dc27e9299248b7aabd5a8739a1cf6b76c78aa2b848158b44a99d5 \ + --hash=sha256:81b7c121c4e52a0749bf0759185b8d5cfa48a786cd7d411cdab08269813e0aab \ + --hash=sha256:8257cc9e55fb0e2149a652d9dc14c023720f9e73c9145776e07c97e0a553922e \ + --hash=sha256:8a5f00b2508937952d23a1767739e95bbbe1120f8a66d10187d5e971d56bb55c \ + --hash=sha256:8ae2e7a390b2cdd2a95d3bf3b3385245eeb48a5e853943cb46139666462c2d1a \ + --hash=sha256:940459d81685549afdfe13a6de102c52ea4cdda093477baa53056884aadf7c48 \ + --hash=sha256:9c4aae4e683776c319169d87e7891b67b75e3f1c0beeb877902ea148b0585164 \ + --hash=sha256:9d5f8e0050a179b3bce9189b522dc91008d44f08c757a7c310e0fd06b4d3d147 \ + --hash=sha256:a1b85d35a7d9638c03321dfe466645b87e23c30df1266f9e04bbb5f44e7579a9 \ + --hash=sha256:a82410d7620c07cb32624e38f2a106980564dfef9dbe78f5b295cda9ef217c03 \ + --hash=sha256:abfe64811177e681edc81d9d9d1bd23edc5f599bd9846650864769264ace30cd \ + --hash=sha256:ac9783d5679c8da612465168c820fd0b916e70ec5496c840bddba0be7f2d124c \ + --hash=sha256:b033d50bd41e506e3b579775f54a30c16c222e0d88847ac8098d2eca2a7454cc \ + --hash=sha256:b097347441b86a8c3ad9579abaf5e5f7f82b1d74a898f47360433b2bca0e4536 \ + --hash=sha256:b708401ede2c4cb8943e8a713988fcfe6cbea105b07cd7fa7c8a9f137c22bddb \ + --hash=sha256:bd900e666bb68fff49703084be14407cd73b8a5752a7590cea98ec22de24fb5d \ + --hash=sha256:c118cfc80e2402a5595be36e9245ffd9b0e146f426cc40bdf60015bf183f8373 \ + --hash=sha256:c175b252d063af388523a397dbe8edbc4319761f5ee892a8a0f5890acc067362 \ + --hash=sha256:c8bb1a7aa82af6c7713cdf9dcb8f4ea1024ac7ce82bb0a0a82a49aea5237da34 \ + --hash=sha256:c95a0b76a44c548e6bd8c5f7dbecf89c77e2e16d3965be817b57769c4a30bea2 \ + --hash=sha256:e202e3f963480ca067a261179b1ac610c0f0272cb4a7942d11b7e2b3fc99c3aa \ + --hash=sha256:e9ffdb7bc9ccd56ec201aec3eab3432e1e820335b5a16ad2b37e094218dcd7a6 \ + --hash=sha256:ea7ca66a58421411c6486fa5015fe7704e2816ff0b4ec4fb779ad5e1cbbdabf3 \ + --hash=sha256:f2ff8ac447765e173842b554b31307b98b3bb1852710903ebb936e7efb7df6e5 \ + --hash=sha256:f5def814c5a4c90c8fe389c526ab881f4a28b7e239b23ed8e02dd02934dfaa1a + # via + # feast (setup.py) + # google-api-core + # google-cloud-bigquery + # google-cloud-bigquery-storage + # google-cloud-datastore + # googleapis-common-protos + # grpc-google-iam-v1 + # grpcio-health-checking + # grpcio-reflection + # grpcio-status + # grpcio-testing + # grpcio-tools + # ikvpy + # pymilvus + # qdrant-client + # ray +grpcio-health-checking==1.62.3 \ + --hash=sha256:5074ba0ce8f0dcfe328408ec5c7551b2a835720ffd9b69dade7fa3e0dc1c7a93 \ + --hash=sha256:f29da7dd144d73b4465fe48f011a91453e9ff6c8af0d449254cf80021cab3e0d + # via feast (setup.py) +grpcio-reflection==1.62.3 \ + --hash=sha256:a48ef37df81a3bada78261fc92ef382f061112f989d1312398b945cc69838b9c \ + --hash=sha256:cb84682933c400bddf94dd94f928d1c6570f500b6dd255973d4bfb495b82585f + # via feast (setup.py) +grpcio-status==1.62.3 \ + --hash=sha256:289bdd7b2459794a12cf95dc0cb727bd4a1742c37bd823f760236c937e53a485 \ + --hash=sha256:f9049b762ba8de6b1086789d8315846e094edac2c50beaf462338b301a8fd4b8 + # via + # google-api-core + # ikvpy +grpcio-testing==1.62.3 \ + --hash=sha256:06a4d7eb30d22f91368aa7f48bfc33563da13b9d951314455ca8c9c987fb75bb \ + --hash=sha256:f63577f28aaa95ea525124a0fd63c3429d71f769f4179b13f5e6cbc54979bfab + # via feast (setup.py) +grpcio-tools==1.62.3 \ + --hash=sha256:0a52cc9444df978438b8d2332c0ca99000521895229934a59f94f37ed896b133 \ + --hash=sha256:0a8c0c4724ae9c2181b7dbc9b186df46e4f62cb18dc184e46d06c0ebeccf569e \ + --hash=sha256:0cb3a3436ac119cbd37a7d3331d9bdf85dad21a6ac233a3411dff716dcbf401e \ + --hash=sha256:11c625eebefd1fd40a228fc8bae385e448c7e32a6ae134e43cf13bbc23f902b7 \ + --hash=sha256:11f363570dea661dde99e04a51bd108a5807b5df32a6f8bdf4860e34e94a4dbf \ + --hash=sha256:141d028bf5762d4a97f981c501da873589df3f7e02f4c1260e1921e565b376fa \ + --hash=sha256:1c989246c2aebc13253f08be32538a4039a64e12d9c18f6d662d7aee641dc8b5 \ + --hash=sha256:1da38070738da53556a4b35ab67c1b9884a5dd48fa2f243db35dc14079ea3d0c \ + --hash=sha256:27cd9ef5c5d68d5ed104b6dcb96fe9c66b82050e546c9e255716903c3d8f0373 \ + --hash=sha256:2e02d3b96f2d0e4bab9ceaa30f37d4f75571e40c6272e95364bff3125a64d184 \ + --hash=sha256:2f968b049c2849540751ec2100ab05e8086c24bead769ca734fdab58698408c1 \ + --hash=sha256:350a80485e302daaa95d335a931f97b693e170e02d43767ab06552c708808950 \ + --hash=sha256:3eae6ea76d62fcac091e1f15c2dcedf1dc3f114f8df1a972a8a0745e89f4cf61 \ + --hash=sha256:47a5c093ab256dec5714a7a345f8cc89315cb57c298b276fa244f37a0ba507f0 \ + --hash=sha256:5782883a27d3fae8c425b29a9d3dcf5f47d992848a1b76970da3b5a28d424b26 \ + --hash=sha256:6a56d344b0bab30bf342a67e33d386b0b3c4e65868ffe93c341c51e1a8853ca5 \ + --hash=sha256:6c3064610826f50bd69410c63101954676edc703e03f9e8f978a135f1aaf97c1 \ + --hash=sha256:703f46e0012af83a36082b5f30341113474ed0d91e36640da713355cd0ea5d23 \ + --hash=sha256:710fecf6a171dcbfa263a0a3e7070e0df65ba73158d4c539cec50978f11dad5d \ + --hash=sha256:7c7136015c3d62c3eef493efabaf9e3380e3e66d24ee8e94c01cb71377f57833 \ + --hash=sha256:7cc83023acd8bc72cf74c2edbe85b52098501d5b74d8377bfa06f3e929803492 \ + --hash=sha256:7f2483ea232bd72d98a6dc6d7aefd97e5bc80b15cd909b9e356d6f3e326b6e43 \ + --hash=sha256:7ff7d58a45b75df67d25f8f144936a3e44aabd91afec833ee06826bd02b7fbe7 \ + --hash=sha256:8ad0473af5544f89fc5a1ece8676dd03bdf160fb3230f967e05d0f4bf89620e3 \ + --hash=sha256:8c5d22b252dcef11dd1e0fbbe5bbfb9b4ae048e8880d33338215e8ccbdb03edc \ + --hash=sha256:8e62cc7164b0b7c5128e637e394eb2ef3db0e61fc798e80c301de3b2379203ed \ + --hash=sha256:962c84b4da0f3b14b3cdb10bc3837ebc5f136b67d919aea8d7bb3fd3df39528a \ + --hash=sha256:ace43b26d88a58dcff16c20d23ff72b04d0a415f64d2820f4ff06b1166f50557 \ + --hash=sha256:b47d0dda1bdb0a0ba7a9a6de88e5a1ed61f07fad613964879954961e36d49193 \ + --hash=sha256:b77f9f9cee87cd798f0fe26b7024344d1b03a7cd2d2cba7035f8433b13986325 \ + --hash=sha256:b881fd9505a84457e9f7e99362eeedd86497b659030cf57c6f0070df6d9c2b9b \ + --hash=sha256:bfda6ee8990997a9df95c5606f3096dae65f09af7ca03a1e9ca28f088caca5cf \ + --hash=sha256:c3a1ac9d394f8e229eb28eec2e04b9a6f5433fa19c9d32f1cb6066e3c5114a1d \ + --hash=sha256:c8ad5cce554e2fcaf8842dee5d9462583b601a3a78f8b76a153c38c963f58c10 \ + --hash=sha256:ca246dffeca0498be9b4e1ee169b62e64694b0f92e6d0be2573e65522f39eea9 \ + --hash=sha256:ca4f5eeadbb57cf03317d6a2857823239a63a59cc935f5bd6cf6e8b7af7a7ecc \ + --hash=sha256:d102b9b21c4e1e40af9a2ab3c6d41afba6bd29c0aa50ca013bf85c99cdc44ac5 \ + --hash=sha256:db3bc9fa39afc5e4e2767da4459df82b095ef0cab2f257707be06c44a1c2c3e5 \ + --hash=sha256:dc9ad9950119d8ae27634e68b7663cc8d340ae535a0f80d85a55e56a6973ab1f \ + --hash=sha256:e02d7c1a02e3814c94ba0cfe43d93e872c758bd8fd5c2797f894d0c49b4a1dfc \ + --hash=sha256:e0898d412a434e768a0c7e365acabe13ff1558b767e400936e26b5b6ed1ee51f \ + --hash=sha256:e18e15287c31baf574fcdf8251fb7f997d64e96c6ecf467906e576da0a079af6 \ + --hash=sha256:ec279dcf3518201fc592c65002754f58a6b542798cd7f3ecd4af086422f33f29 \ + --hash=sha256:ec6fbded0c61afe6f84e3c2a43e6d656791d95747d6d28b73eff1af64108c434 \ + --hash=sha256:eec73a005443061f4759b71a056f745e3b000dc0dc125c9f20560232dfbcbd14 \ + --hash=sha256:f3d812daffd0c2d2794756bd45a353f89e55dc8f91eb2fc840c51b9f6be62667 \ + --hash=sha256:f4b1615adf67bd8bb71f3464146a6f9949972d06d21a4f5e87e73f6464d97f57 \ + --hash=sha256:f6831fdec2b853c9daa3358535c55eed3694325889aa714070528cf8f92d7d6d + # via feast (setup.py) +gunicorn==23.0.0 \ + --hash=sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d \ + --hash=sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec + # via + # feast (setup.py) + # uvicorn-worker +h11==0.16.0 \ + --hash=sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1 \ + --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 + # via + # httpcore + # uvicorn +h2==4.3.0 \ + --hash=sha256:6c59efe4323fa18b47a632221a1888bd7fde6249819beda254aeca909f221bf1 \ + --hash=sha256:c438f029a25f7945c69e0ccf0fb951dc3f73a5f6412981daee861431b70e2bdd + # via httpx +happybase==1.3.0 \ + --hash=sha256:43b6275d2865fc1364680a03f085491cd85d8b84db3c5aa94d25186685dfd87e \ + --hash=sha256:f2644cf1ef9d662fbe6f709fcfd66bf13e949f3efd4745a3230cf5f904fb7839 + # via feast (setup.py) +hazelcast-python-client==5.6.0 \ + --hash=sha256:834b87076a47c781ef80bdcb522b86abc75ff28992dfe384e47f669f06cabb18 \ + --hash=sha256:e2cec409068990ca9b4381fe97160cc2375412334782bef45ab4c8fe4d10536c + # via feast (setup.py) +hf-xet==1.2.0 \ + --hash=sha256:10bfab528b968c70e062607f663e21e34e2bba349e8038db546646875495179e \ + --hash=sha256:210d577732b519ac6ede149d2f2f34049d44e8622bf14eb3d63bbcd2d4b332dc \ + --hash=sha256:27df617a076420d8845bea087f59303da8be17ed7ec0cd7ee3b9b9f579dff0e4 \ + --hash=sha256:293a7a3787e5c95d7be1857358a9130694a9c6021de3f27fa233f37267174382 \ + --hash=sha256:29c8fc913a529ec0a91867ce3d119ac1aac966e098cf49501800c870328cc090 \ + --hash=sha256:2a212e842647b02eb6a911187dc878e79c4aa0aa397e88dd3b26761676e8c1f8 \ + --hash=sha256:30e06daccb3a7d4c065f34fc26c14c74f4653069bb2b194e7f18f17cbe9939c0 \ + --hash=sha256:3651fd5bfe0281951b988c0facbe726aa5e347b103a675f49a3fa8144c7968fd \ + --hash=sha256:46740d4ac024a7ca9b22bebf77460ff43332868b661186a8e46c227fdae01848 \ + --hash=sha256:4c1428c9ae73ec0939410ec73023c4f842927f39db09b063b9482dac5a3bb737 \ + --hash=sha256:66e159cbfcfbb29f920db2c09ed8b660eb894640d284f102ada929b6e3dc410a \ + --hash=sha256:6de1fc44f58f6dd937956c8d304d8c2dea264c80680bcfa61ca4a15e7b76780f \ + --hash=sha256:7d40b18769bb9a8bc82a9ede575ce1a44c75eb80e7375a01d76259089529b5dc \ + --hash=sha256:9c91d5ae931510107f148874e9e2de8a16052b6f1b3ca3c1b12f15ccb491390f \ + --hash=sha256:a55558084c16b09b5ed32ab9ed38421e2d87cf3f1f89815764d1177081b99865 \ + --hash=sha256:a8c27070ca547293b6890c4bf389f713f80e8c478631432962bb7f4bc0bd7d7f \ + --hash=sha256:b70218dd548e9840224df5638fdc94bd033552963cfa97f9170829381179c813 \ + --hash=sha256:cd3a6027d59cfb60177c12d6424e31f4b5ff13d8e3a1247b3a584bf8977e6df5 \ + --hash=sha256:ceeefcd1b7aed4956ae8499e2199607765fbd1c60510752003b6cc0b8413b649 \ + --hash=sha256:d06fa97c8562fb3ee7a378dd9b51e343bc5bc8190254202c9771029152f5e08c \ + --hash=sha256:e6584a52253f72c9f52f9e549d5895ca7a471608495c4ecaa6cc73dba2b24d69 \ + --hash=sha256:f182f264ed2acd566c514e45da9f2119110e48a87a327ca271027904c70c5832 + # via huggingface-hub +hiredis==2.4.0 \ + --hash=sha256:06815c3b9bf7225c4dcc9dd9dfb5a9fa91b4f680104443ef3fcd78410d7eb027 \ + --hash=sha256:070a0198401bc567709b9edff7f01e94c136dcca69d0ded4747b116bb0b8b577 \ + --hash=sha256:082ba6a3189d59f44bf75ca2c0467cdbc67c860eacd4bf564b9a927471888603 \ + --hash=sha256:0a87a249124666db2b795a0eb77cea5b8af8b148566616a681304826b4405869 \ + --hash=sha256:1537d13eefe4f48cb979362264851ee90d2bb7a221c8c350e9ceeda9f0392228 \ + --hash=sha256:168de1672bd73f7f3cdf0097084b4a71651ac35f7d99d0229ea8f223358d3a79 \ + --hash=sha256:1bfa50491d3222e3c2297b52c14e835ac52702ac8a91ec3fc1ff5201912623bb \ + --hash=sha256:1c0e706e0c3d1ec54d8243410e0fd5974b1c7b69db5c54cd9ae6a3a4b64fae33 \ + --hash=sha256:1d16f5023c1d9971f284231eb7036a25d4d123138a5adc4512c92a73d83b9a77 \ + --hash=sha256:2a21e2740c33347740dceb106b64b8a384e91da49aac7e8b3f2a25a9b33714b9 \ + --hash=sha256:2b76a5600047387c73c1b3d950e4ae3feffaefd442b20ba2f5fea773881d9bcd \ + --hash=sha256:2b90d9861673b0ba04651ade62e0fe568df71bbff8468657406848e9abf3650a \ + --hash=sha256:2d7715598c9034369cf739475ccc2db53a8ca895ff398fef6b9c597c30960ea8 \ + --hash=sha256:339f29542be968153afd6c6495c1222681c4b66b9a5a5573c11512378b7167c9 \ + --hash=sha256:38dd931f1124bd9781d3027a0cd6fb6f5a75b5c4ba4fe5540584105239b1f901 \ + --hash=sha256:39e1c7212dea1bbed0b075574808bc7c3192b324f54ea5d9ee522f6c35014ce7 \ + --hash=sha256:3abc0936c1efc59b510c7eab3799119a6ce8da94cea1f891854a6c3678d711f0 \ + --hash=sha256:3ced14fbec28fbabda7cb9f9094f2578c154c14f1a820a91c30fc8ee0bea1a0d \ + --hash=sha256:400a42b8d16206e45c8223cdaf5acc35839e10c35383b3fba3f43e7eb315c213 \ + --hash=sha256:468efdcbad7349a44aace693aed8324a01de180fcd4ef5513199eedb9b4341c8 \ + --hash=sha256:469c1a85017abf11d854fb16eca9a4093ebe1f2dacf777fed869d726f02b1389 \ + --hash=sha256:48baae8fbebf3b11660db6e51a55ff51516ed32edcd44a57f51ea9b373aca330 \ + --hash=sha256:4bf4b8513cea6e04ddee1b578ab306fb8bfa84b2f7e92ee3dbaf65652abb07d1 \ + --hash=sha256:4da6d881033a1bcb31bba152ea0925344127f0a98f86a6cf2ceb01cf6ecd29e2 \ + --hash=sha256:52d92df0eb5bba7f31f302a08174d628956d7216453da9d96498da9341179288 \ + --hash=sha256:54409fbefebe26274170c1c54e1852d310d84b85e405258aea6a78bec03b3eba \ + --hash=sha256:5598afad9e2f8e4fc9a456d281a9cc80315b0e18f5064437223dbfe67f49bded \ + --hash=sha256:5b0b2463906cc4119187dfaad493c48a7b2e17120946feb3eb7c2328c8cb4bca \ + --hash=sha256:5bdb223e7c3b9470f126bb77879ee2593fd79b28e1e8b11ad9edd3f866556109 \ + --hash=sha256:5cc3c59dd0cd67d0aa0481a43392848a60f1a81d12b38ce8d56d6a5d6c190de8 \ + --hash=sha256:5e45171fd046bbed2ce6ac485071cd0575d18ae98b5bbcf6533356e443ec47ea \ + --hash=sha256:6033cc6caaf056969af9ce372282a6ef2838559f2eadffe7ddb73bf65dcb27d6 \ + --hash=sha256:605fe35ebb482b7c8d5daadcf3d264dc5edd205a352d89ee3a983861ef73cda8 \ + --hash=sha256:6494120d0a0f46a1d7dfc7def55782782856bdd5acb2f6039fb1eafecea2c2c0 \ + --hash=sha256:668b02556d12046e7ce94ded5bfe0ad9989d26e6977ecc55941b9a1a4a49d7d5 \ + --hash=sha256:68e39d2c0beed53e5361caacd0de98f864b3532344edb79e27e62efba2262de5 \ + --hash=sha256:6c3f8e0c3a0744d843e3044ea76db8aa996a6cc7541693111acc2c9c30a05182 \ + --hash=sha256:6ceaf7c6b593bf62e0567fd16547727f502ed704352392708a57c65bfd2feb73 \ + --hash=sha256:6dac8a5be01d92707409feec61b98721b7b5c3e77fe7e9e5c7cfb9fdd28385af \ + --hash=sha256:6e38f66dd7fd07a9306ed37d6d02bc584b67e5945f2ddc98e5c78420cc66dbac \ + --hash=sha256:7236b26828e005435fb3013894eed6a40c6f9b1b11a48391a904eee693ded204 \ + --hash=sha256:737585b122fca03273bbf1f4e98909254dba6f8cd85f1cb566d6c890d0389277 \ + --hash=sha256:764032f2222d70a130445fd332cf45d46d8226f4b3a7bf8abc314aa93d5a8212 \ + --hash=sha256:76503a0edaf3d1557518127511e69e5d9fa37b6ff15598b0d9d9c2db18b08a41 \ + --hash=sha256:83538638a788b7b4a0b02de0eedcf0e71ae27474b031276e4c8ca88285281a2e \ + --hash=sha256:8767cae1474f8102ec3d362976f80c8dd4eafd4109c6072adee0a15e37ba919c \ + --hash=sha256:87a8ece3e893f45354395c6b9dc0479744c1c8c6ee4471b60945d96c9b5ce6c2 \ + --hash=sha256:8b88390a5e31572e05e8eab476ed3176cc3d2f9622ccc059398ffdb02aaefec4 \ + --hash=sha256:90d7af678056c7889d86821344d79fec3932a6a1480ebba3d644cb29a3135348 \ + --hash=sha256:98148ecaa7836f76ed33429e84a23253ac00acbad90c62b8b4ad0f61de31da2b \ + --hash=sha256:9aabc6098ef00e158598489db5a8b9e12d57a55ea5a4ec35ba3b527dfb88d16e \ + --hash=sha256:9ae4b19cab270fae77d7f944d56bbb308c9886d9577891b347a8deea75563995 \ + --hash=sha256:9b4039cd40335f66e55a8bee314b6a795f169fb02d70215d482023ec74613371 \ + --hash=sha256:9fc1a6c78197eff8b4d125bb98410b661e732f3ec563c03264d2d7378cf9e613 \ + --hash=sha256:a40f1d985047fe4654a1afb4702cbe0daeacde3868d52be9e4652615d387e05b \ + --hash=sha256:a459b7ff3d802792254d6fc6a622e53ca9cf9f002ed79db7e4dee536b2e20e5d \ + --hash=sha256:a4f733882b67407d4b667eafd61fce86e8e204b158258cc1d0cb0843f6bb4708 \ + --hash=sha256:a56a35e2e0b7eda39957ccd33059b79bb2fc57f54c501a917d1092c895f56d08 \ + --hash=sha256:a5c3a32af789b0ec413a606c99b55579abbcb6c86220610a5c5041da8688e7ca \ + --hash=sha256:a5d2776c7cd6a338cd9338fb50f2a38a7ca3e16250b40ab2d0c41eb1697ebc12 \ + --hash=sha256:a816f732f695261798a8a0fc1e0232a3638933b8ddfc574c00f9ef70d9f34cb8 \ + --hash=sha256:a9d559775a95aee0ff06c0aaac638691619d6342b7cde85c62ad228804f82829 \ + --hash=sha256:ac9d91b4d9c306e66a1abd224524fada07684a57f7da72a675e4b8bee9302b38 \ + --hash=sha256:ae340c41024b9be566f600f364c8d286217f2975fd765fb3fb4dd6dfbdbec825 \ + --hash=sha256:aeb60452d5b6150075974bc36e1cc74a46bd4b125cd5e72a86a04f4d6abf4e67 \ + --hash=sha256:aee6c4e8f670ea685345ce4ca01c574a52e0a4318af2b8cdd563de9567731056 \ + --hash=sha256:b027b53adb1df11923753d85587e3ab611fe70bc69596e9eb3269acab809c376 \ + --hash=sha256:b0adbe8f33f57f2b6bfa8a2ea18f3e4ed91676503673f70f796bfbd06a1a2214 \ + --hash=sha256:b30dcfbc5ab2fc932a723a39c2cb52d4f5c8b1705aa05a0bae23f28f70e06982 \ + --hash=sha256:b385fc7fc7b0811c3fcac4b0a35e5606eca693efba0d1446623ef0158a078034 \ + --hash=sha256:b4e5e9d1f84bbc01bf6a32a4704920c72e37d9090b3e0e29bd1574d06b3249f1 \ + --hash=sha256:b50ad622d8a71c8b72582dc84a990f3f079775edc1bcf0f43ed59bb2277fca2f \ + --hash=sha256:b544a1a78e0812134572cc13f5ee330bfb6bfe6dda58d2e26c20557bb0e0cec9 \ + --hash=sha256:b8472151e6f7ae90d7fd231a1ac16d2e628b93ce20d0f8063da25bd8bfdeb9e5 \ + --hash=sha256:b868b7fc24dd8ab4762b59a533bdbd096ebba7eabc853c7f78af8edce46d1390 \ + --hash=sha256:b8eee5d25efee64e172ed0d60ebcf6bca92b0b26a7fd048bb946b32fb90dbdc0 \ + --hash=sha256:bae7f07731c6c285b87111c7d5c5efa65f8b48016a98bcc57eebc24a3c7d854d \ + --hash=sha256:beb0f7f8371d933072e9bdc00c6df7eb5fdf76b93f08bfe73094f60c3f011f57 \ + --hash=sha256:c2676e2a934e046200faf0dc26ffa48c4989c3561c9bb97832e79969a41b2afe \ + --hash=sha256:c77113fbdbd7ca5de72dd3b7d113856609a1b878f6164de09dd95d12e6a51de2 \ + --hash=sha256:c85110f536e59fe19ea4b002d04228f57f55462add1630a0785cd6ec62e70415 \ + --hash=sha256:c9f8827cd7a84f5344779754ebb633bca71c470e028f92ecc959e666ef5c5e3c \ + --hash=sha256:cb62c82a2518b8446be1cc5eb4319e282776bf96fdb2964e81ff2c15d632248b \ + --hash=sha256:d5c711c8ca8d5767ed8ecd5fb5602c12eaf8fb256a5f4308ae36f2dc79e6f853 \ + --hash=sha256:d851b7ff732ebc9d823de3c7cc95a5ed4261a0226acd46861a18369ac9568f36 \ + --hash=sha256:e2a917ab420cd88b040ec85b5abc1244ab82b34d56461e2ffff58e0c7d018bae \ + --hash=sha256:e3215b43632a23b5b99165097949ce51dd093ab33d410bcf8aa901cdbc64d9cd \ + --hash=sha256:e71386f89dc2db805b4c9518dee6d81abddb8e79e4d9313cecdb702c924b8187 \ + --hash=sha256:f34b39057956305935c71f51a0860709b6124c92281dc03841587dd45a86322c \ + --hash=sha256:f44715d6a3313d614ff7550e52ecff67a283776909d960f338701b57e6013542 \ + --hash=sha256:f74bfa9f1b91718d6664d4708d092f7d44e2f0f825a5fab82819d43d41e0302d \ + --hash=sha256:f76fcf2867d19259b53680c08314435b46f632d20a4d7b9f0ccbb5dd3e925e79 \ + --hash=sha256:fa4842977924209ae653e856238a30b1c68e579ecde5cf1c16c4de471b35cec7 \ + --hash=sha256:fc8d3edbc9f32da930da6ea33d43ce0c3239e6b2018a77907fbf4e9836bd6def + # via feast (setup.py) +hpack==4.1.0 \ + --hash=sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496 \ + --hash=sha256:ec5eca154f7056aa06f196a557655c5b009b382873ac8d1e66e79e87535f1dca + # via h2 +httpcore==1.0.9 \ + --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 \ + --hash=sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8 + # via httpx +httptools==0.7.1 \ + --hash=sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c \ + --hash=sha256:0d92b10dbf0b3da4823cde6a96d18e6ae358a9daa741c71448975f6a2c339cad \ + --hash=sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1 \ + --hash=sha256:11d01b0ff1fe02c4c32d60af61a4d613b74fad069e47e06e9067758c01e9ac78 \ + --hash=sha256:135fbe974b3718eada677229312e97f3b31f8a9c8ffa3ae6f565bf808d5b6bcb \ + --hash=sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03 \ + --hash=sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6 \ + --hash=sha256:379b479408b8747f47f3b253326183d7c009a3936518cdb70db58cffd369d9df \ + --hash=sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5 \ + --hash=sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321 \ + --hash=sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346 \ + --hash=sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650 \ + --hash=sha256:474d3b7ab469fefcca3697a10d11a32ee2b9573250206ba1e50d5980910da657 \ + --hash=sha256:49794f9250188a57fa73c706b46cb21a313edb00d337ca4ce1a011fe3c760b28 \ + --hash=sha256:5ddbd045cfcb073db2449563dd479057f2c2b681ebc232380e63ef15edc9c023 \ + --hash=sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca \ + --hash=sha256:654968cb6b6c77e37b832a9be3d3ecabb243bbe7a0b8f65fbc5b6b04c8fcabed \ + --hash=sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66 \ + --hash=sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3 \ + --hash=sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca \ + --hash=sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3 \ + --hash=sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2 \ + --hash=sha256:84d86c1e5afdc479a6fdabf570be0d3eb791df0ae727e8dbc0259ed1249998d4 \ + --hash=sha256:a3c3b7366bb6c7b96bd72d0dbe7f7d5eead261361f013be5f6d9590465ea1c70 \ + --hash=sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9 \ + --hash=sha256:ac50afa68945df63ec7a2707c506bd02239272288add34539a2ef527254626a4 \ + --hash=sha256:aeefa0648362bb97a7d6b5ff770bfb774930a327d7f65f8208394856862de517 \ + --hash=sha256:b580968316348b474b020edf3988eecd5d6eec4634ee6561e72ae3a2a0e00a8a \ + --hash=sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270 \ + --hash=sha256:c8c751014e13d88d2be5f5f14fc8b89612fcfa92a9cc480f2bc1598357a23a05 \ + --hash=sha256:cad6b591a682dcc6cf1397c3900527f9affef1e55a06c4547264796bbd17cf5e \ + --hash=sha256:cbf8317bfccf0fed3b5680c559d3459cccf1abe9039bfa159e62e391c7270568 \ + --hash=sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96 \ + --hash=sha256:d169162803a24425eb5e4d51d79cbf429fd7a491b9e570a55f495ea55b26f0bf \ + --hash=sha256:d496e2f5245319da9d764296e86c5bb6fcf0cf7a8806d3d000717a889c8c0b7b \ + --hash=sha256:de987bb4e7ac95b99b805b99e0aae0ad51ae61df4263459d36e07cf4052d8b3a \ + --hash=sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b \ + --hash=sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c \ + --hash=sha256:eb844698d11433d2139bbeeb56499102143beb582bd6c194e3ba69c22f25c274 \ + --hash=sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60 \ + --hash=sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5 \ + --hash=sha256:f65744d7a8bdb4bda5e1fa23e4ba16832860606fcc09d674d56e425e991539ec \ + --hash=sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362 + # via uvicorn +httpx[http2]==0.27.2 \ + --hash=sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0 \ + --hash=sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2 + # via + # feast (setup.py) + # fastapi-mcp + # jupyterlab + # mcp + # python-keycloak + # qdrant-client +httpx-sse==0.4.3 \ + --hash=sha256:0ac1c9fe3c0afad2e0ebb25a934a59f4c7823b60792691f779fad2c5568830fc \ + --hash=sha256:9b1ed0127459a66014aec3c56bebd93da3c1bc8bb6618c8082039a44889a755d + # via mcp +huggingface-hub==0.36.0 \ + --hash=sha256:47b3f0e2539c39bf5cde015d63b72ec49baff67b6931c3d97f3f84532e2b8d25 \ + --hash=sha256:7bcc9ad17d5b3f07b57c78e79d527102d08313caa278a641993acddcb894548d + # via + # accelerate + # datasets + # docling + # docling-ibm-models + # timm + # tokenizers + # transformers +hyperframe==6.1.0 \ + --hash=sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5 \ + --hash=sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08 + # via h2 +ibis-framework[duckdb, mssql]==9.5.0 \ + --hash=sha256:145fe30d94f111cff332580c275ce77725c5ff7086eede93af0b371649d009c0 \ + --hash=sha256:1c8a29277e63ee0dfc289bc8f550164b5e3bdaec1b76b62436c37d331bb4ef84 + # via + # feast (setup.py) + # ibis-substrait +ibis-substrait==4.0.1 \ + --hash=sha256:107ca49383a3cca2fdc88f67ea2f0172620c16fa8f39c9c52305af85dd6180b4 \ + --hash=sha256:614810a173d096fbc49d87a9b419e2162a3c25d8efda1a4d57a389ce56b9041f + # via feast (setup.py) +identify==2.6.16 \ + --hash=sha256:391ee4d77741d994189522896270b787aed8670389bfd60f326d677d64a6dfb0 \ + --hash=sha256:846857203b5511bbe94d5a352a48ef2359532bc8f6727b5544077a0dcfb24980 + # via pre-commit +idna==3.11 \ + --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea \ + --hash=sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902 + # via + # anyio + # httpx + # jsonschema + # requests + # snowflake-connector-python + # yarl +ikvpy==0.0.36 \ + --hash=sha256:b0edf6fb6482877940f6c2b5d59a7fabe30cb554b13b88ca52805f043cfda5b3 \ + --hash=sha256:c0ce7dfb61456c283c9ba2cdeb68b3647f245c3905bca652ca2a1068804939d1 + # via feast (setup.py) +imageio==2.37.2 \ + --hash=sha256:0212ef2727ac9caa5ca4b2c75ae89454312f440a756fcfc8ef1993e718f50f8a \ + --hash=sha256:ad9adfb20335d718c03de457358ed69f141021a333c40a53e57273d8a5bd0b9b + # via scikit-image +imagesize==1.4.1 \ + --hash=sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b \ + --hash=sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a + # via sphinx +importlib-metadata==8.7.1 \ + --hash=sha256:49fef1ae6440c182052f407c8d34a68f72efc36db9ca90dc0113398f2fdde8bb \ + --hash=sha256:5a1f80bf1daa489495071efbb095d75a634cf28a8bc299581244063b53176151 + # via + # dask + # opentelemetry-api +importlib-resources==6.5.2 \ + --hash=sha256:185f87adef5bcc288449d98fb4fba07cea78bc036455dd44c5fc4a2fe78fed2c \ + --hash=sha256:789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec + # via happybase +iniconfig==2.3.0 \ + --hash=sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730 \ + --hash=sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 + # via pytest +invoke==2.2.1 \ + --hash=sha256:2413bc441b376e5cd3f55bb5d364f973ad8bdd7bf87e53c79de3c11bf3feecc8 \ + --hash=sha256:515bf49b4a48932b79b024590348da22f39c4942dff991ad1fb8b8baea1be707 + # via paramiko +ipykernel==7.1.0 \ + --hash=sha256:58a3fc88533d5930c3546dc7eac66c6d288acde4f801e2001e65edc5dc9cf0db \ + --hash=sha256:763b5ec6c5b7776f6a8d7ce09b267693b4e5ce75cb50ae696aaefb3c85e1ea4c + # via jupyterlab +ipython==9.9.0 \ + --hash=sha256:48fbed1b2de5e2c7177eefa144aba7fcb82dac514f09b57e2ac9da34ddb54220 \ + --hash=sha256:b457fe9165df2b84e8ec909a97abcf2ed88f565970efba16b1f7229c283d252b + # via + # great-expectations + # ipykernel + # ipywidgets +ipython-pygments-lexers==1.1.1 \ + --hash=sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81 \ + --hash=sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c + # via ipython +ipywidgets==8.1.2 \ + --hash=sha256:bbe43850d79fb5e906b14801d6c01402857996864d1e5b6fa62dd2ee35559f60 \ + --hash=sha256:d0b9b41e49bae926a866e613a39b0f0097745d2b9f1f3dd406641b4a57ec42c9 + # via + # codeflare-sdk + # great-expectations +isodate==0.7.2 \ + --hash=sha256:28009937d8031054830160fce6d409ed342816b543597cece116d966c6d99e15 \ + --hash=sha256:4cd1aa0f43ca76f4a6c6c0292a85f40b35ec2e43e315b59f06e6d32171a953e6 + # via azure-storage-blob +isoduration==20.11.0 \ + --hash=sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9 \ + --hash=sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042 + # via jsonschema +jedi==0.19.2 \ + --hash=sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0 \ + --hash=sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9 + # via ipython +jinja2==3.1.6 \ + --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ + --hash=sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 + # via + # feast (setup.py) + # altair + # great-expectations + # jupyter-server + # jupyterlab + # jupyterlab-server + # moto + # nbconvert + # poetry-dynamic-versioning + # sphinx + # torch +jmespath==1.0.1 \ + --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ + --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe + # via + # aiobotocore + # boto3 + # botocore +joblib==1.5.3 \ + --hash=sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713 \ + --hash=sha256:8561a3269e6801106863fd0d6d84bb737be9e7631e33aaed3fb9ce5953688da3 + # via scikit-learn +json5==0.13.0 \ + --hash=sha256:9a08e1dd65f6a4d4c6fa82d216cf2477349ec2346a38fd70cc11d2557499fbcc \ + --hash=sha256:b1edf8d487721c0bf64d83c28e91280781f6e21f4a797d3261c7c828d4c165bf + # via jupyterlab-server +jsonlines==4.0.0 \ + --hash=sha256:0c6d2c09117550c089995247f605ae4cf77dd1533041d366351f6f298822ea74 \ + --hash=sha256:185b334ff2ca5a91362993f42e83588a360cf95ce4b71a73548502bda52a7c55 + # via docling-ibm-models +jsonpatch==1.33 \ + --hash=sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade \ + --hash=sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c + # via great-expectations +jsonpointer==3.0.0 \ + --hash=sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942 \ + --hash=sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef + # via + # jsonpatch + # jsonschema +jsonref==1.1.0 \ + --hash=sha256:32fe8e1d85af0fdefbebce950af85590b22b60f9e95443176adbde4e1ecea552 \ + --hash=sha256:590dc7773df6c21cbf948b5dac07a72a251db28b0238ceecce0a2abfa8ec30a9 + # via docling-core +jsonschema[format-nongpl]==4.26.0 \ + --hash=sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326 \ + --hash=sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce + # via + # feast (setup.py) + # altair + # docling-core + # great-expectations + # jupyter-events + # jupyterlab-server + # mcp + # nbformat + # ray +jsonschema-specifications==2025.9.1 \ + --hash=sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe \ + --hash=sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d + # via jsonschema +jupyter-client==8.8.0 \ + --hash=sha256:d556811419a4f2d96c869af34e854e3f059b7cc2d6d01a9cd9c85c267691be3e \ + --hash=sha256:f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a + # via + # ipykernel + # jupyter-server + # nbclient +jupyter-core==5.9.1 \ + --hash=sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508 \ + --hash=sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407 + # via + # ipykernel + # jupyter-client + # jupyter-server + # jupyterlab + # nbclient + # nbconvert + # nbformat +jupyter-events==0.12.0 \ + --hash=sha256:6464b2fa5ad10451c3d35fabc75eab39556ae1e2853ad0c0cc31b656731a97fb \ + --hash=sha256:fc3fce98865f6784c9cd0a56a20644fc6098f21c8c33834a8d9fe383c17e554b + # via jupyter-server +jupyter-lsp==2.3.0 \ + --hash=sha256:458aa59339dc868fb784d73364f17dbce8836e906cd75fd471a325cba02e0245 \ + --hash=sha256:e914a3cb2addf48b1c7710914771aaf1819d46b2e5a79b0f917b5478ec93f34f + # via jupyterlab +jupyter-server==2.17.0 \ + --hash=sha256:c38ea898566964c888b4772ae1ed58eca84592e88251d2cfc4d171f81f7e99d5 \ + --hash=sha256:e8cb9c7db4251f51ed307e329b81b72ccf2056ff82d50524debde1ee1870e13f + # via + # jupyter-lsp + # jupyterlab + # jupyterlab-server + # notebook + # notebook-shim +jupyter-server-terminals==0.5.4 \ + --hash=sha256:55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14 \ + --hash=sha256:bbda128ed41d0be9020349f9f1f2a4ab9952a73ed5f5ac9f1419794761fb87f5 + # via jupyter-server +jupyterlab==4.5.2 \ + --hash=sha256:76466ebcfdb7a9bb7e2fbd6459c0e2c032ccf75be673634a84bee4b3e6b13ab6 \ + --hash=sha256:c80a6b9f6dace96a566d590c65ee2785f61e7cd4aac5b4d453dcc7d0d5e069b7 + # via notebook +jupyterlab-pygments==0.3.0 \ + --hash=sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d \ + --hash=sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780 + # via nbconvert +jupyterlab-server==2.28.0 \ + --hash=sha256:35baa81898b15f93573e2deca50d11ac0ae407ebb688299d3a5213265033712c \ + --hash=sha256:e4355b148fdcf34d312bbbc80f22467d6d20460e8b8736bf235577dd18506968 + # via + # jupyterlab + # notebook +jupyterlab-widgets==3.0.16 \ + --hash=sha256:423da05071d55cf27a9e602216d35a3a65a3e41cdf9c5d3b643b814ce38c19e0 \ + --hash=sha256:45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8 + # via ipywidgets +jwcrypto==1.5.6 \ + --hash=sha256:150d2b0ebbdb8f40b77f543fb44ffd2baeff48788be71f67f03566692fd55789 \ + --hash=sha256:771a87762a0c081ae6166958a954f80848820b2ab066937dc8b8379d65b1b039 + # via python-keycloak +kubernetes==35.0.0 \ + --hash=sha256:39e2b33b46e5834ef6c3985ebfe2047ab39135d41de51ce7641a7ca5b372a13d \ + --hash=sha256:3d00d344944239821458b9efd484d6df9f011da367ecb155dadf9513f05f09ee + # via + # feast (setup.py) + # codeflare-sdk +lark==1.3.1 \ + --hash=sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905 \ + --hash=sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12 + # via rfc3987-syntax +latex2mathml==3.78.1 \ + --hash=sha256:f089b6d75e85b937f99693c93e8c16c0804008672c3dd2a3d25affd36f238100 \ + --hash=sha256:f941db80bf41db33f31df87b304e8b588f8166b813b0257c11c98f7a9d0aac71 + # via docling-core +lazy-loader==0.4 \ + --hash=sha256:342aa8e14d543a154047afb4ba8ef17f5563baad3fc610d7b15b213b0f119efc \ + --hash=sha256:47c75182589b91a4e1a85a136c074285a5ad4d9f39c63e0d7fb76391c4574cd1 + # via scikit-image +locket==1.0.0 \ + --hash=sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632 \ + --hash=sha256:b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3 + # via partd +lxml==5.4.0 \ + --hash=sha256:00b8686694423ddae324cf614e1b9659c2edb754de617703c3d29ff568448df5 \ + --hash=sha256:073eb6dcdf1f587d9b88c8c93528b57eccda40209cf9be549d469b942b41d70b \ + --hash=sha256:09846782b1ef650b321484ad429217f5154da4d6e786636c38e434fa32e94e49 \ + --hash=sha256:0a01ce7d8479dce84fc03324e3b0c9c90b1ece9a9bb6a1b6c9025e7e4520e78c \ + --hash=sha256:0be91891bdb06ebe65122aa6bf3fc94489960cf7e03033c6f83a90863b23c58b \ + --hash=sha256:0cef4feae82709eed352cd7e97ae062ef6ae9c7b5dbe3663f104cd2c0e8d94ba \ + --hash=sha256:0e108352e203c7afd0eb91d782582f00a0b16a948d204d4dec8565024fafeea5 \ + --hash=sha256:0ea0252b51d296a75f6118ed0d8696888e7403408ad42345d7dfd0d1e93309a7 \ + --hash=sha256:0fce1294a0497edb034cb416ad3e77ecc89b313cff7adbee5334e4dc0d11f422 \ + --hash=sha256:1320091caa89805df7dcb9e908add28166113dcd062590668514dbd510798c88 \ + --hash=sha256:142accb3e4d1edae4b392bd165a9abdee8a3c432a2cca193df995bc3886249c8 \ + --hash=sha256:14479c2ad1cb08b62bb941ba8e0e05938524ee3c3114644df905d2331c76cd57 \ + --hash=sha256:151d6c40bc9db11e960619d2bf2ec5829f0aaffb10b41dcf6ad2ce0f3c0b2325 \ + --hash=sha256:15a665ad90054a3d4f397bc40f73948d48e36e4c09f9bcffc7d90c87410e478a \ + --hash=sha256:1a42b3a19346e5601d1b8296ff6ef3d76038058f311902edd574461e9c036982 \ + --hash=sha256:1af80c6316ae68aded77e91cd9d80648f7dd40406cef73df841aa3c36f6907c8 \ + --hash=sha256:1b717b00a71b901b4667226bba282dd462c42ccf618ade12f9ba3674e1fabc55 \ + --hash=sha256:1dc4ca99e89c335a7ed47d38964abcb36c5910790f9bd106f2a8fa2ee0b909d2 \ + --hash=sha256:20e16c08254b9b6466526bc1828d9370ee6c0d60a4b64836bc3ac2917d1e16df \ + --hash=sha256:226046e386556a45ebc787871d6d2467b32c37ce76c2680f5c608e25823ffc84 \ + --hash=sha256:24974f774f3a78ac12b95e3a20ef0931795ff04dbb16db81a90c37f589819551 \ + --hash=sha256:24f6df5f24fc3385f622c0c9d63fe34604893bc1a5bdbb2dbf5870f85f9a404a \ + --hash=sha256:27a9ded0f0b52098ff89dd4c418325b987feed2ea5cc86e8860b0f844285d740 \ + --hash=sha256:29f451a4b614a7b5b6c2e043d7b64a15bd8304d7e767055e8ab68387a8cacf4e \ + --hash=sha256:2b31a3a77501d86d8ade128abb01082724c0dfd9524f542f2f07d693c9f1175f \ + --hash=sha256:2c62891b1ea3094bb12097822b3d44b93fc6c325f2043c4d2736a8ff09e65f60 \ + --hash=sha256:2dc191e60425ad70e75a68c9fd90ab284df64d9cd410ba8d2b641c0c45bc006e \ + --hash=sha256:31e63621e073e04697c1b2d23fcb89991790eef370ec37ce4d5d469f40924ed6 \ + --hash=sha256:32697d2ea994e0db19c1df9e40275ffe84973e4232b5c274f47e7c1ec9763cdd \ + --hash=sha256:3a3178b4873df8ef9457a4875703488eb1622632a9cee6d76464b60e90adbfcd \ + --hash=sha256:3b9c2754cef6963f3408ab381ea55f47dabc6f78f4b8ebb0f0b25cf1ac1f7609 \ + --hash=sha256:3d3c30ba1c9b48c68489dc1829a6eede9873f52edca1dda900066542528d6b20 \ + --hash=sha256:3e6d5557989cdc3ebb5302bbdc42b439733a841891762ded9514e74f60319ad6 \ + --hash=sha256:4025bf2884ac4370a3243c5aa8d66d3cb9e15d3ddd0af2d796eccc5f0244390e \ + --hash=sha256:4291d3c409a17febf817259cb37bc62cb7eb398bcc95c1356947e2871911ae61 \ + --hash=sha256:4329422de653cdb2b72afa39b0aa04252fca9071550044904b2e7036d9d97fe4 \ + --hash=sha256:43d549b876ce64aa18b2328faff70f5877f8c6dede415f80a2f799d31644d776 \ + --hash=sha256:460508a4b07364d6abf53acaa0a90b6d370fafde5693ef37602566613a9b0779 \ + --hash=sha256:47fb24cc0f052f0576ea382872b3fc7e1f7e3028e53299ea751839418ade92a6 \ + --hash=sha256:48b4afaf38bf79109bb060d9016fad014a9a48fb244e11b94f74ae366a64d252 \ + --hash=sha256:497cab4d8254c2a90bf988f162ace2ddbfdd806fce3bda3f581b9d24c852e03c \ + --hash=sha256:4aa412a82e460571fad592d0f93ce9935a20090029ba08eca05c614f99b0cc92 \ + --hash=sha256:4b7ce10634113651d6f383aa712a194179dcd496bd8c41e191cec2099fa09de5 \ + --hash=sha256:4cd915c0fb1bed47b5e6d6edd424ac25856252f09120e3e8ba5154b6b921860e \ + --hash=sha256:4d885698f5019abe0de3d352caf9466d5de2baded00a06ef3f1216c1a58ae78f \ + --hash=sha256:4f5322cf38fe0e21c2d73901abf68e6329dc02a4994e483adbcf92b568a09a54 \ + --hash=sha256:50441c9de951a153c698b9b99992e806b71c1f36d14b154592580ff4a9d0d877 \ + --hash=sha256:529024ab3a505fed78fe3cc5ddc079464e709f6c892733e3f5842007cec8ac6e \ + --hash=sha256:53370c26500d22b45182f98847243efb518d268374a9570409d2e2276232fd37 \ + --hash=sha256:53d9469ab5460402c19553b56c3648746774ecd0681b1b27ea74d5d8a3ef5590 \ + --hash=sha256:56dbdbab0551532bb26c19c914848d7251d73edb507c3079d6805fa8bba5b706 \ + --hash=sha256:5a99d86351f9c15e4a901fc56404b485b1462039db59288b203f8c629260a142 \ + --hash=sha256:5cca36a194a4eb4e2ed6be36923d3cffd03dcdf477515dea687185506583d4c9 \ + --hash=sha256:5f11a1526ebd0dee85e7b1e39e39a0cc0d9d03fb527f56d8457f6df48a10dc0c \ + --hash=sha256:61c7bbf432f09ee44b1ccaa24896d21075e533cd01477966a5ff5a71d88b2f56 \ + --hash=sha256:639978bccb04c42677db43c79bdaa23785dc7f9b83bfd87570da8207872f1ce5 \ + --hash=sha256:63e7968ff83da2eb6fdda967483a7a023aa497d85ad8f05c3ad9b1f2e8c84987 \ + --hash=sha256:664cdc733bc87449fe781dbb1f309090966c11cc0c0cd7b84af956a02a8a4729 \ + --hash=sha256:67ed8a40665b84d161bae3181aa2763beea3747f748bca5874b4af4d75998f87 \ + --hash=sha256:67f779374c6b9753ae0a0195a892a1c234ce8416e4448fe1e9f34746482070a7 \ + --hash=sha256:6854f8bd8a1536f8a1d9a3655e6354faa6406621cf857dc27b681b69860645c7 \ + --hash=sha256:696ea9e87442467819ac22394ca36cb3d01848dad1be6fac3fb612d3bd5a12cf \ + --hash=sha256:6ef80aeac414f33c24b3815ecd560cee272786c3adfa5f31316d8b349bfade28 \ + --hash=sha256:72ac9762a9f8ce74c9eed4a4e74306f2f18613a6b71fa065495a67ac227b3056 \ + --hash=sha256:75133890e40d229d6c5837b0312abbe5bac1c342452cf0e12523477cd3aa21e7 \ + --hash=sha256:7605c1c32c3d6e8c990dd28a0970a3cbbf1429d5b92279e37fda05fb0c92190e \ + --hash=sha256:773e27b62920199c6197130632c18fb7ead3257fce1ffb7d286912e56ddb79e0 \ + --hash=sha256:795f61bcaf8770e1b37eec24edf9771b307df3af74d1d6f27d812e15a9ff3872 \ + --hash=sha256:79d5bfa9c1b455336f52343130b2067164040604e41f6dc4d8313867ed540079 \ + --hash=sha256:7a62cc23d754bb449d63ff35334acc9f5c02e6dae830d78dab4dd12b78a524f4 \ + --hash=sha256:7be701c24e7f843e6788353c055d806e8bd8466b52907bafe5d13ec6a6dbaecd \ + --hash=sha256:7ca56ebc2c474e8f3d5761debfd9283b8b18c76c4fc0967b74aeafba1f5647f9 \ + --hash=sha256:7ce1a171ec325192c6a636b64c94418e71a1964f56d002cc28122fceff0b6121 \ + --hash=sha256:891f7f991a68d20c75cb13c5c9142b2a3f9eb161f1f12a9489c82172d1f133c0 \ + --hash=sha256:8f82125bc7203c5ae8633a7d5d20bcfdff0ba33e436e4ab0abc026a53a8960b7 \ + --hash=sha256:91505d3ddebf268bb1588eb0f63821f738d20e1e7f05d3c647a5ca900288760b \ + --hash=sha256:942a5d73f739ad7c452bf739a62a0f83e2578afd6b8e5406308731f4ce78b16d \ + --hash=sha256:9454b8d8200ec99a224df8854786262b1bd6461f4280064c807303c642c05e76 \ + --hash=sha256:9459e6892f59ecea2e2584ee1058f5d8f629446eab52ba2305ae13a32a059530 \ + --hash=sha256:9776af1aad5a4b4a1317242ee2bea51da54b2a7b7b48674be736d463c999f37d \ + --hash=sha256:97dac543661e84a284502e0cf8a67b5c711b0ad5fb661d1bd505c02f8cf716d7 \ + --hash=sha256:98a3912194c079ef37e716ed228ae0dcb960992100461b704aea4e93af6b0bb9 \ + --hash=sha256:9b4a3bd174cc9cdaa1afbc4620c049038b441d6ba07629d89a83b408e54c35cd \ + --hash=sha256:9c886b481aefdf818ad44846145f6eaf373a20d200b5ce1a5c8e1bc2d8745410 \ + --hash=sha256:9ceaf423b50ecfc23ca00b7f50b64baba85fb3fb91c53e2c9d00bc86150c7e40 \ + --hash=sha256:a11a96c3b3f7551c8a8109aa65e8594e551d5a84c76bf950da33d0fb6dfafab7 \ + --hash=sha256:a3bcdde35d82ff385f4ede021df801b5c4a5bcdfb61ea87caabcebfc4945dc1b \ + --hash=sha256:a7fb111eef4d05909b82152721a59c1b14d0f365e2be4c742a473c5d7372f4f5 \ + --hash=sha256:a81e1196f0a5b4167a8dafe3a66aa67c4addac1b22dc47947abd5d5c7a3f24b5 \ + --hash=sha256:a8c9b7f16b63e65bbba889acb436a1034a82d34fa09752d754f88d708eca80e1 \ + --hash=sha256:a8ef956fce64c8551221f395ba21d0724fed6b9b6242ca4f2f7beb4ce2f41997 \ + --hash=sha256:ab339536aa798b1e17750733663d272038bf28069761d5be57cb4a9b0137b4f8 \ + --hash=sha256:ac7ba71f9561cd7d7b55e1ea5511543c0282e2b6450f122672a2694621d63b7e \ + --hash=sha256:aea53d51859b6c64e7c51d522c03cc2c48b9b5d6172126854cc7f01aa11f52bc \ + --hash=sha256:aea7c06667b987787c7d1f5e1dfcd70419b711cdb47d6b4bb4ad4b76777a0563 \ + --hash=sha256:aefe1a7cb852fa61150fcb21a8c8fcea7b58c4cb11fbe59c97a0a4b31cae3c8c \ + --hash=sha256:b0989737a3ba6cf2a16efb857fb0dfa20bc5c542737fddb6d893fde48be45433 \ + --hash=sha256:b108134b9667bcd71236c5a02aad5ddd073e372fb5d48ea74853e009fe38acb6 \ + --hash=sha256:b12cb6527599808ada9eb2cd6e0e7d3d8f13fe7bbb01c6311255a15ded4c7ab4 \ + --hash=sha256:b5aff6f3e818e6bdbbb38e5967520f174b18f539c2b9de867b1e7fde6f8d95a4 \ + --hash=sha256:b67319b4aef1a6c56576ff544b67a2a6fbd7eaee485b241cabf53115e8908b8f \ + --hash=sha256:b7c86884ad23d61b025989d99bfdd92a7351de956e01c61307cb87035960bcb1 \ + --hash=sha256:b92b69441d1bd39f4940f9eadfa417a25862242ca2c396b406f9272ef09cdcaa \ + --hash=sha256:bcb7a1096b4b6b24ce1ac24d4942ad98f983cd3810f9711bcd0293f43a9d8b9f \ + --hash=sha256:bda3ea44c39eb74e2488297bb39d47186ed01342f0022c8ff407c250ac3f498e \ + --hash=sha256:be2ba4c3c5b7900246a8f866580700ef0d538f2ca32535e991027bdaba944063 \ + --hash=sha256:c5681160758d3f6ac5b4fea370495c48aac0989d6a0f01bb9a72ad8ef5ab75c4 \ + --hash=sha256:c5d32f5284012deaccd37da1e2cd42f081feaa76981f0eaa474351b68df813c5 \ + --hash=sha256:c6364038c519dffdbe07e3cf42e6a7f8b90c275d4d1617a69bb59734c1a2d571 \ + --hash=sha256:c70e93fba207106cb16bf852e421c37bbded92acd5964390aad07cb50d60f5cf \ + --hash=sha256:ca755eebf0d9e62d6cb013f1261e510317a41bf4650f22963474a663fdfe02aa \ + --hash=sha256:cccd007d5c95279e529c146d095f1d39ac05139de26c098166c4beb9374b0f4d \ + --hash=sha256:ce31158630a6ac85bddd6b830cffd46085ff90498b397bd0a259f59d27a12188 \ + --hash=sha256:ce9c671845de9699904b1e9df95acfe8dfc183f2310f163cdaa91a3535af95de \ + --hash=sha256:d12832e1dbea4be280b22fd0ea7c9b87f0d8fc51ba06e92dc62d52f804f78ebd \ + --hash=sha256:d2ed1b3cb9ff1c10e6e8b00941bb2e5bb568b307bfc6b17dffbbe8be5eecba86 \ + --hash=sha256:d5663bc1b471c79f5c833cffbc9b87d7bf13f87e055a5c86c363ccd2348d7e82 \ + --hash=sha256:d90b729fd2732df28130c064aac9bb8aff14ba20baa4aee7bd0795ff1187545f \ + --hash=sha256:dc0af80267edc68adf85f2a5d9be1cdf062f973db6790c1d065e45025fa26140 \ + --hash=sha256:de5b4e1088523e2b6f730d0509a9a813355b7f5659d70eb4f319c76beea2e250 \ + --hash=sha256:de6f6bb8a7840c7bf216fb83eec4e2f79f7325eca8858167b68708b929ab2172 \ + --hash=sha256:df53330a3bff250f10472ce96a9af28628ff1f4efc51ccba351a8820bca2a8ba \ + --hash=sha256:e094ec83694b59d263802ed03a8384594fcce477ce484b0cbcd0008a211ca751 \ + --hash=sha256:e794f698ae4c5084414efea0f5cc9f4ac562ec02d66e1484ff822ef97c2cadff \ + --hash=sha256:e7bc6df34d42322c5289e37e9971d6ed114e3776b45fa879f734bded9d1fea9c \ + --hash=sha256:eaf24066ad0b30917186420d51e2e3edf4b0e2ea68d8cd885b14dc8afdcf6556 \ + --hash=sha256:ecf4c4b83f1ab3d5a7ace10bafcb6f11df6156857a3c418244cef41ca9fa3e44 \ + --hash=sha256:ef5a7178fcc73b7d8c07229e89f8eb45b2908a9238eb90dcfc46571ccf0383b8 \ + --hash=sha256:f5cb182f6396706dc6cc1896dd02b1c889d644c081b0cdec38747573db88a7d7 \ + --hash=sha256:fa0e294046de09acd6146be0ed6727d1f42ded4ce3ea1e9a19c11b6774eea27c \ + --hash=sha256:fb54f7c6bafaa808f27166569b1511fc42701a7713858dddc08afdde9746849e \ + --hash=sha256:fd3be6481ef54b8cfd0e1e953323b7aa9d9789b94842d0e5b142ef4bb7999539 + # via + # docling + # python-docx + # python-pptx +lz4==4.4.5 \ + --hash=sha256:0846e6e78f374156ccf21c631de80967e03cc3c01c373c665789dc0c5431e7fc \ + --hash=sha256:0bba042ec5a61fa77c7e380351a61cb768277801240249841defd2ff0a10742f \ + --hash=sha256:12233624f1bc2cebc414f9efb3113a03e89acce3ab6f72035577bc61b270d24d \ + --hash=sha256:13254bd78fef50105872989a2dc3418ff09aefc7d0765528adc21646a7288294 \ + --hash=sha256:15551280f5656d2206b9b43262799c89b25a25460416ec554075a8dc568e4397 \ + --hash=sha256:1dd4d91d25937c2441b9fc0f4af01704a2d09f30a38c5798bc1d1b5a15ec9581 \ + --hash=sha256:214e37cfe270948ea7eb777229e211c601a3e0875541c1035ab408fbceaddf50 \ + --hash=sha256:216ca0c6c90719731c64f41cfbd6f27a736d7e50a10b70fad2a9c9b262ec923d \ + --hash=sha256:24092635f47538b392c4eaeff14c7270d2c8e806bf4be2a6446a378591c5e69e \ + --hash=sha256:28ccaeb7c5222454cd5f60fcd152564205bcb801bd80e125949d2dfbadc76bbd \ + --hash=sha256:2a2b7504d2dffed3fd19d4085fe1cc30cf221263fd01030819bdd8d2bb101cf1 \ + --hash=sha256:2c3ea562c3af274264444819ae9b14dbbf1ab070aff214a05e97db6896c7597e \ + --hash=sha256:33dd86cea8375d8e5dd001e41f321d0a4b1eb7985f39be1b6a4f466cd480b8a7 \ + --hash=sha256:3b84a42da86e8ad8537aabef062e7f661f4a877d1c74d65606c49d835d36d668 \ + --hash=sha256:451039b609b9a88a934800b5fc6ee401c89ad9c175abf2f4d9f8b2e4ef1afc64 \ + --hash=sha256:533298d208b58b651662dd972f52d807d48915176e5b032fb4f8c3b6f5fe535c \ + --hash=sha256:5f0b9e53c1e82e88c10d7c180069363980136b9d7a8306c4dca4f760d60c39f0 \ + --hash=sha256:609a69c68e7cfcfa9d894dc06be13f2e00761485b62df4e2472f1b66f7b405fb \ + --hash=sha256:61d0ee03e6c616f4a8b69987d03d514e8896c8b1b7cc7598ad029e5c6aedfd43 \ + --hash=sha256:66c5de72bf4988e1b284ebdd6524c4bead2c507a2d7f172201572bac6f593901 \ + --hash=sha256:67531da3b62f49c939e09d56492baf397175ff39926d0bd5bd2d191ac2bff95f \ + --hash=sha256:6bb05416444fafea170b07181bc70640975ecc2a8c92b3b658c554119519716c \ + --hash=sha256:6d0bf51e7745484d2092b3a51ae6eb58c3bd3ce0300cf2b2c14f76c536d5697a \ + --hash=sha256:713a777de88a73425cf08eb11f742cd2c98628e79a8673d6a52e3c5f0c116f33 \ + --hash=sha256:75419bb1a559af00250b8f1360d508444e80ed4b26d9d40ec5b09fe7875cb989 \ + --hash=sha256:7b62f94b523c251cf32aa4ab555f14d39bd1a9df385b72443fd76d7c7fb051f5 \ + --hash=sha256:7c4e7c44b6a31de77d4dc9772b7d2561937c9588a734681f70ec547cfbc51ecd \ + --hash=sha256:7dc1e1e2dbd872f8fae529acd5e4839efd0b141eaa8ae7ce835a9fe80fbad89f \ + --hash=sha256:83bc23ef65b6ae44f3287c38cbf82c269e2e96a26e560aa551735883388dcc4b \ + --hash=sha256:8a842ead8ca7c0ee2f396ca5d878c4c40439a527ebad2b996b0444f0074ed004 \ + --hash=sha256:92159782a4502858a21e0079d77cdcaade23e8a5d252ddf46b0652604300d7be \ + --hash=sha256:9b5e6abca8df9f9bdc5c3085f33ff32cdc86ed04c65e0355506d46a5ac19b6e9 \ + --hash=sha256:a1acbbba9edbcbb982bc2cac5e7108f0f553aebac1040fbec67a011a45afa1ba \ + --hash=sha256:a2af2897333b421360fdcce895c6f6281dc3fab018d19d341cf64d043fc8d90d \ + --hash=sha256:a482eecc0b7829c89b498fda883dbd50e98153a116de612ee7c111c8bcf82d1d \ + --hash=sha256:a5f197ffa6fc0e93207b0af71b302e0a2f6f29982e5de0fbda61606dd3a55832 \ + --hash=sha256:a88cbb729cc333334ccfb52f070463c21560fca63afcf636a9f160a55fac3301 \ + --hash=sha256:b424df1076e40d4e884cfcc4c77d815368b7fb9ebcd7e634f937725cd9a8a72a \ + --hash=sha256:bd85d118316b53ed73956435bee1997bd06cc66dd2fa74073e3b1322bd520a67 \ + --hash=sha256:c1cfa663468a189dab510ab231aad030970593f997746d7a324d40104db0d0a9 \ + --hash=sha256:c216b6d5275fc060c6280936bb3bb0e0be6126afb08abccde27eed23dead135f \ + --hash=sha256:c8e71b14938082ebaf78144f3b3917ac715f72d14c076f384a4c062df96f9df6 \ + --hash=sha256:cdd4bdcbaf35056086d910d219106f6a04e1ab0daa40ec0eeef1626c27d0fddb \ + --hash=sha256:d221fa421b389ab2345640a508db57da36947a437dfe31aeddb8d5c7b646c22d \ + --hash=sha256:d64141085864918392c3159cdad15b102a620a67975c786777874e1e90ef15ce \ + --hash=sha256:d6da84a26b3aa5da13a62e4b89ab36a396e9327de8cd48b436a3467077f8ccd4 \ + --hash=sha256:d994b87abaa7a88ceb7a37c90f547b8284ff9da694e6afcfaa8568d739faf3f7 \ + --hash=sha256:da68497f78953017deb20edff0dba95641cc86e7423dfadf7c0264e1ac60dc22 \ + --hash=sha256:daffa4807ef54b927451208f5f85750c545a4abbff03d740835fc444cd97f758 \ + --hash=sha256:df5aa4cead2044bab83e0ebae56e0944cc7fcc1505c7787e9e1057d6d549897e \ + --hash=sha256:e099ddfaa88f59dd8d36c8a3c66bd982b4984edf127eb18e30bb49bdba68ce67 \ + --hash=sha256:e64e61f29cf95afb43549063d8433b46352baf0c8a70aa45e2585618fcf59d86 \ + --hash=sha256:e928ec2d84dc8d13285b4a9288fd6246c5cde4f5f935b479f50d986911f085e3 \ + --hash=sha256:f32b9e65d70f3684532358255dc053f143835c5f5991e28a5ac4c93ce94b9ea7 \ + --hash=sha256:f6538aaaedd091d6e5abdaa19b99e6e82697d67518f114721b5248709b639fad \ + --hash=sha256:f9b8bde9909a010c75b3aea58ec3910393b758f3c219beed67063693df854db0 \ + --hash=sha256:ff1b50aeeec64df5603f17984e4b5be6166058dcf8f1e26a3da40d7a0f6ab547 + # via + # clickhouse-connect + # trino +makefun==1.16.0 \ + --hash=sha256:43baa4c3e7ae2b17de9ceac20b669e9a67ceeadff31581007cca20a07bbe42c4 \ + --hash=sha256:e14601831570bff1f6d7e68828bcd30d2f5856f24bad5de0ccb22921ceebc947 + # via great-expectations +markdown-it-py==4.0.0 \ + --hash=sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 \ + --hash=sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3 + # via rich +marko==2.2.2 \ + --hash=sha256:6940308e655f63733ca518c47a68ec9510279dbb916c83616e4c4b5829f052e8 \ + --hash=sha256:f064ae8c10416285ad1d96048dc11e98ef04e662d3342ae416f662b70aa7959e + # via docling +markupsafe==3.0.3 \ + --hash=sha256:0303439a41979d9e74d18ff5e2dd8c43ed6c6001fd40e5bf2e43f7bd9bbc523f \ + --hash=sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a \ + --hash=sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf \ + --hash=sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19 \ + --hash=sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf \ + --hash=sha256:0f4b68347f8c5eab4a13419215bdfd7f8c9b19f2b25520968adfad23eb0ce60c \ + --hash=sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175 \ + --hash=sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219 \ + --hash=sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb \ + --hash=sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6 \ + --hash=sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab \ + --hash=sha256:15d939a21d546304880945ca1ecb8a039db6b4dc49b2c5a400387cdae6a62e26 \ + --hash=sha256:177b5253b2834fe3678cb4a5f0059808258584c559193998be2601324fdeafb1 \ + --hash=sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce \ + --hash=sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218 \ + --hash=sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634 \ + --hash=sha256:1ba88449deb3de88bd40044603fafffb7bc2b055d626a330323a9ed736661695 \ + --hash=sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad \ + --hash=sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73 \ + --hash=sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c \ + --hash=sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe \ + --hash=sha256:2a15a08b17dd94c53a1da0438822d70ebcd13f8c3a95abe3a9ef9f11a94830aa \ + --hash=sha256:2f981d352f04553a7171b8e44369f2af4055f888dfb147d55e42d29e29e74559 \ + --hash=sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa \ + --hash=sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37 \ + --hash=sha256:3537e01efc9d4dccdf77221fb1cb3b8e1a38d5428920e0657ce299b20324d758 \ + --hash=sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f \ + --hash=sha256:38664109c14ffc9e7437e86b4dceb442b0096dfe3541d7864d9cbe1da4cf36c8 \ + --hash=sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d \ + --hash=sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c \ + --hash=sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97 \ + --hash=sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a \ + --hash=sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19 \ + --hash=sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9 \ + --hash=sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9 \ + --hash=sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc \ + --hash=sha256:591ae9f2a647529ca990bc681daebdd52c8791ff06c2bfa05b65163e28102ef2 \ + --hash=sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4 \ + --hash=sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354 \ + --hash=sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50 \ + --hash=sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698 \ + --hash=sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9 \ + --hash=sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b \ + --hash=sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc \ + --hash=sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115 \ + --hash=sha256:7c3fb7d25180895632e5d3148dbdc29ea38ccb7fd210aa27acbd1201a1902c6e \ + --hash=sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485 \ + --hash=sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f \ + --hash=sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12 \ + --hash=sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025 \ + --hash=sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009 \ + --hash=sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d \ + --hash=sha256:949b8d66bc381ee8b007cd945914c721d9aba8e27f71959d750a46f7c282b20b \ + --hash=sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a \ + --hash=sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5 \ + --hash=sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f \ + --hash=sha256:a320721ab5a1aba0a233739394eb907f8c8da5c98c9181d1161e77a0c8e36f2d \ + --hash=sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1 \ + --hash=sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287 \ + --hash=sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6 \ + --hash=sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f \ + --hash=sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581 \ + --hash=sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed \ + --hash=sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b \ + --hash=sha256:c0c0b3ade1c0b13b936d7970b1d37a57acde9199dc2aecc4c336773e1d86049c \ + --hash=sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026 \ + --hash=sha256:c4ffb7ebf07cfe8931028e3e4c85f0357459a3f9f9490886198848f4fa002ec8 \ + --hash=sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 \ + --hash=sha256:d2ee202e79d8ed691ceebae8e0486bd9a2cd4794cec4824e1c99b6f5009502f6 \ + --hash=sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e \ + --hash=sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d \ + --hash=sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d \ + --hash=sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01 \ + --hash=sha256:df2449253ef108a379b8b5d6b43f4b1a8e81a061d6537becd5582fba5f9196d7 \ + --hash=sha256:e1c1493fb6e50ab01d20a22826e57520f1284df32f2d8601fdd90b6304601419 \ + --hash=sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795 \ + --hash=sha256:e2103a929dfa2fcaf9bb4e7c091983a49c9ac3b19c9061b6d5427dd7d14d81a1 \ + --hash=sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5 \ + --hash=sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d \ + --hash=sha256:e8fc20152abba6b83724d7ff268c249fa196d8259ff481f3b1476383f8f24e42 \ + --hash=sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe \ + --hash=sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda \ + --hash=sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e \ + --hash=sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737 \ + --hash=sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523 \ + --hash=sha256:f42d0984e947b8adf7dd6dde396e720934d12c506ce84eea8476409563607591 \ + --hash=sha256:f71a396b3bf33ecaa1626c255855702aca4d3d9fea5e051b41ac59a9c1c41edc \ + --hash=sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a \ + --hash=sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50 + # via + # jinja2 + # nbconvert + # werkzeug +marshmallow==3.26.2 \ + --hash=sha256:013fa8a3c4c276c24d26d84ce934dc964e2aa794345a0f8c7e5a7191482c8a73 \ + --hash=sha256:bbe2adb5a03e6e3571b573f42527c6fe926e17467833660bebd11593ab8dfd57 + # via great-expectations +matplotlib-inline==0.2.1 \ + --hash=sha256:d56ce5156ba6085e00a9d54fead6ed29a9c47e215cd1bba2e976ef39f5710a76 \ + --hash=sha256:e1ee949c340d771fc39e241ea75683deb94762c8fa5f2927ec57c83c4dffa9fe + # via + # ipykernel + # ipython +mcp==1.25.0 \ + --hash=sha256:56310361ebf0364e2d438e5b45f7668cbb124e158bb358333cd06e49e83a6802 \ + --hash=sha256:b37c38144a666add0862614cc79ec276e97d72aa8ca26d622818d4e278b9721a + # via fastapi-mcp +mdurl==0.1.2 \ + --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ + --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba + # via markdown-it-py +milvus-lite==2.4.12 \ + --hash=sha256:20087663e7b4385050b7ad08f1f03404426d4c87b1ff91d5a8723eee7fd49e88 \ + --hash=sha256:334037ebbab60243b5d8b43d54ca2f835d81d48c3cda0c6a462605e588deb05d \ + --hash=sha256:a0f3a5ddbfd19f4a6b842b2fd3445693c796cde272b701a1646a94c1ac45d3d7 \ + --hash=sha256:e8d4f7cdd5f731efd6faeee3715d280fd91a5f9b4d89312664d56401f65b1473 + # via + # feast (setup.py) + # pymilvus +minio==7.2.11 \ + --hash=sha256:153582ed52ff3b5005ba558e1f25bfe1e9e834f7f0745e594777f28e3e81e1a0 \ + --hash=sha256:4db95a21fe1e2022ec975292d8a1f83bd5b18f830d23d42a4518ac7a5281d7c5 + # via feast (setup.py) +mistune==3.2.0 \ + --hash=sha256:708487c8a8cdd99c9d90eb3ed4c3ed961246ff78ac82f03418f5183ab70e398a \ + --hash=sha256:febdc629a3c78616b94393c6580551e0e34cc289987ec6c35ed3f4be42d0eee1 + # via + # great-expectations + # nbconvert +mmh3==5.2.0 \ + --hash=sha256:03e08c6ebaf666ec1e3d6ea657a2d363bb01effd1a9acfe41f9197decaef0051 \ + --hash=sha256:097e13c8b8a66c5753c6968b7640faefe85d8e38992703c1f666eda6ef4c3762 \ + --hash=sha256:0b898cecff57442724a0f52bf42c2de42de63083a91008fb452887e372f9c328 \ + --hash=sha256:10983c10f5c77683bd845751905ba535ec47409874acc759d5ce3ff7ef34398a \ + --hash=sha256:11730eeb16dfcf9674fdea9bb6b8e6dd9b40813b7eb839bc35113649eef38aeb \ + --hash=sha256:127c95336f2a98c51e7682341ab7cb0be3adb9df0819ab8505a726ed1801876d \ + --hash=sha256:12da42c0a55c9d86ab566395324213c319c73ecb0c239fad4726324212b9441c \ + --hash=sha256:132dd943451a7c7546978863d2f5a64977928410782e1a87d583cb60eb89e667 \ + --hash=sha256:1556e31e4bd0ac0c17eaf220be17a09c171d7396919c3794274cb3415a9d3646 \ + --hash=sha256:1a5f4d2e59d6bba8ef01b013c472741835ad961e7c28f50c82b27c57748744a4 \ + --hash=sha256:1ba55d6ca32eeef8b2625e1e4bfc3b3db52bc63014bd7e5df8cc11bf2b036b12 \ + --hash=sha256:1efc8fec8478e9243a78bb993422cf79f8ff85cb4cf6b79647480a31e0d950a8 \ + --hash=sha256:1f8d8b627799f4e2fcc7c034fed8f5f24dc7724ff52f69838a3d6d15f1ad4765 \ + --hash=sha256:1fae471339ae1b9c641f19cf46dfe6ffd7f64b1fba7c4333b99fa3dd7f21ae0a \ + --hash=sha256:1fdb36b940e9261aff0b5177c5b74a36936b902f473180f6c15bde26143681a9 \ + --hash=sha256:2421b9d665a0b1ad724ec7332fb5a98d075f50bc51a6ff854f3a1882bd650d49 \ + --hash=sha256:29c2b9ce61886809d0492a274a5a53047742dea0f703f9c4d5d223c3ea6377d3 \ + --hash=sha256:2c9da0d568569cc87315cb063486d761e38458b8ad513fedd3dc9263e1b81bcd \ + --hash=sha256:2ebfc46b39168ab1cd44670a32ea5489bcbc74a25795c61b6d888c5c2cf654ed \ + --hash=sha256:3193752fc05ea72366c2b63ff24b9a190f422e32d75fdeae71087c08fff26115 \ + --hash=sha256:33576136c06b46a7046b6d83a3d75fbca7d25f84cec743f1ae156362608dc6d2 \ + --hash=sha256:37a358cc881fe796e099c1db6ce07ff757f088827b4e8467ac52b7a7ffdca647 \ + --hash=sha256:382a6bb3f8c6532ea084e7acc5be6ae0c6effa529240836d59352398f002e3fc \ + --hash=sha256:384eda9361a7bf83a85e09447e1feafe081034af9dd428893701b959230d84be \ + --hash=sha256:38d899a156549da8ef6a9f1d6f7ef231228d29f8f69bce2ee12f5fba6d6fd7c5 \ + --hash=sha256:3bc244802ccab5220008cb712ca1508cb6a12f0eb64ad62997156410579a1770 \ + --hash=sha256:3c6041fd9d5fb5fcac57d5c80f521a36b74aea06b8566431c63e4ffc49aced51 \ + --hash=sha256:3ca975c51c5028947bbcfc24966517aac06a01d6c921e30f7c5383c195f87991 \ + --hash=sha256:3d6bfd9662a20c054bc216f861fa330c2dac7c81e7fb8307b5e32ab5b9b4d2e0 \ + --hash=sha256:419005f84ba1cab47a77465a2a843562dadadd6671b8758bf179d82a15ca63eb \ + --hash=sha256:45b590e31bc552c6f8e2150ff1ad0c28dd151e9f87589e7eaf508fbdd8e8e908 \ + --hash=sha256:49037d417419863b222ae47ee562b2de9c3416add0a45c8d7f4e864be8dc4f89 \ + --hash=sha256:4a5f5536b1cbfa72318ab3bfc8a8188b949260baed186b75f0abc75b95d8c051 \ + --hash=sha256:582f9dbeefe15c32a5fa528b79b088b599a1dfe290a4436351c6090f90ddebb8 \ + --hash=sha256:58477cf9ef16664d1ce2b038f87d2dc96d70fe50733a34a7f07da6c9a5e3538c \ + --hash=sha256:58981d6ea9646dbbf9e59a30890cbf9f610df0e4a57dbfe09215116fd90b0093 \ + --hash=sha256:5a5dba98e514fb26241868f6eb90a7f7ca0e039aed779342965ce24ea32ba513 \ + --hash=sha256:5b0b58215befe0f0e120b828f7645e97719bbba9f23b69e268ed0ac7adde8645 \ + --hash=sha256:61ac226af521a572700f863d6ecddc6ece97220ce7174e311948ff8c8919a363 \ + --hash=sha256:63830f846797187c5d3e2dae50f0848fdc86032f5bfdc58ae352f02f857e9025 \ + --hash=sha256:69fc339d7202bea69ef9bd7c39bfdf9fdabc8e6822a01eba62fb43233c1b3932 \ + --hash=sha256:6d541038b3fc360ec538fc116de87462627944765a6750308118f8b509a8eec7 \ + --hash=sha256:6ecb4e750d712abde046858ee6992b65c93f1f71b397fce7975c3860c07365d2 \ + --hash=sha256:72d80005b7634a3a2220f81fbeb94775ebd12794623bb2e1451701ea732b4aa3 \ + --hash=sha256:7303aab41e97adcf010a09efd8f1403e719e59b7705d5e3cfed3dd7571589290 \ + --hash=sha256:7434a27754049144539d2099a6d2da5d88b8bdeedf935180bf42ad59b3607aa3 \ + --hash=sha256:746a5ee71c6d1103d9b560fa147881b5e68fd35da56e54e03d5acefad0e7c055 \ + --hash=sha256:7733ec52296fc1ba22e9b90a245c821adbb943e98c91d8a330a2254612726106 \ + --hash=sha256:7901c893e704ee3c65f92d39b951f8f34ccf8e8566768c58103fb10e55afb8c1 \ + --hash=sha256:7aa18cdb58983ee660c9c400b46272e14fa253c675ed963d3812487f8ca42037 \ + --hash=sha256:7b986d506a8e8ea345791897ba5d8ba0d9d8820cd4fc3e52dbe6de19388de2e7 \ + --hash=sha256:7bbb0df897944b5ec830f3ad883e32c5a7375370a521565f5fe24443bfb2c4f7 \ + --hash=sha256:7c7f0b342fd06044bedd0b6e72177ddc0076f54fd89ee239447f8b271d919d9b \ + --hash=sha256:7e5634565367b6d98dc4aa2983703526ef556b3688ba3065edb4b9b90ede1c54 \ + --hash=sha256:7fddccd4113e7b736706e17a239a696332360cbaddf25ae75b57ba1acce65081 \ + --hash=sha256:81c504ad11c588c8629536b032940f2a359dda3b6cbfd4ad8f74cb24dcd1b0bc \ + --hash=sha256:81df0dae22cd0da87f1c978602750f33d17fb3d21fb0f326c89dc89834fea79b \ + --hash=sha256:86d1be5d63232e6eb93c50881aea55ff06eb86d8e08f9b5417c8c9b10db9db96 \ + --hash=sha256:8b0c53fe0994beade1ad7c0f13bd6fec980a0664bfbe5a6a7d64500b9ab76772 \ + --hash=sha256:8ebf241072cf2777a492d0e09252f8cc2b3edd07dfdb9404b9757bffeb4f2cee \ + --hash=sha256:931d47e08c9c8a67bf75d82f0ada8399eac18b03388818b62bfa42882d571d72 \ + --hash=sha256:932a6eec1d2e2c3c9e630d10f7128d80e70e2d47fe6b8c7ea5e1afbd98733e65 \ + --hash=sha256:941603bfd75a46023807511c1ac2f1b0f39cccc393c15039969806063b27e6db \ + --hash=sha256:956127e663d05edbeec54df38885d943dfa27406594c411139690485128525de \ + --hash=sha256:96f1e1ac44cbb42bcc406e509f70c9af42c594e72ccc7b1257f97554204445f0 \ + --hash=sha256:99bb6a4d809aa4e528ddfe2c85dd5239b78b9dd14be62cca0329db78505e7b50 \ + --hash=sha256:9f64bf06f4bf623325fda3a6d02d36cd69199b9ace99b04bb2d7fd9f89688504 \ + --hash=sha256:a094319ec0db52a04af9fdc391b4d39a1bc72bc8424b47c4411afb05413a44b5 \ + --hash=sha256:a367d4741ac0103f8198c82f429bccb9359f543ca542b06a51f4f0332e8de279 \ + --hash=sha256:a7c0c7845566b9686480e6a7e9044db4afb60038d5fabd19227443f0104eeee4 \ + --hash=sha256:aa6e5d31fdc5ed9e3e95f9873508615a778fe9b523d52c17fc770a3eb39ab6e4 \ + --hash=sha256:ae9d032488fcec32d22be6542d1a836f00247f40f320844dbb361393b5b22773 \ + --hash=sha256:b0271ac12415afd3171ab9a3c7cbfc71dee2c68760a7dc9d05bf8ed6ddfa3a7a \ + --hash=sha256:b0d753ad566c721faa33db7e2e0eddd74b224cdd3eaf8481d76c926603c7a00e \ + --hash=sha256:b29044e1ffdb84fe164d0a7ea05c7316afea93c00f8ed9449cf357c36fc4f814 \ + --hash=sha256:b5995088dd7023d2d9f310a0c67de5a2b2e06a570ecfd00f9ff4ab94a67cde43 \ + --hash=sha256:b5f317a727bba0e633a12e71228bc6a4acb4f471a98b1c003163b917311ea9a9 \ + --hash=sha256:b9a87025121d1c448f24f27ff53a5fe7b6ef980574b4a4f11acaabe702420d63 \ + --hash=sha256:bb0fdc451fb6d86d81ab8f23d881b8d6e37fc373a2deae1c02d27002d2ad7a05 \ + --hash=sha256:bb4fe46bdc6104fbc28db7a6bacb115ee6368ff993366bbd8a2a7f0076e6f0c0 \ + --hash=sha256:bc44fc2b886243d7c0d8daeb37864e16f232e5b56aaec27cc781d848264cfd28 \ + --hash=sha256:bdde97310d59604f2a9119322f61b31546748499a21b44f6715e8ced9308a6c5 \ + --hash=sha256:be1374df449465c9f2500e62eee73a39db62152a8bdfbe12ec5b5c1cd451344d \ + --hash=sha256:be7d3dca9358e01dab1bad881fb2b4e8730cec58d36dd44482bc068bfcd3bc65 \ + --hash=sha256:bf7bee43e17e81671c447e9c83499f53d99bf440bc6d9dc26a841e21acfbe094 \ + --hash=sha256:c3dca4cb5b946ee91b3d6bb700d137b1cd85c20827f89fdf9c16258253489044 \ + --hash=sha256:c3f563e8901960e2eaa64c8e8821895818acabeb41c96f2efbb936f65dbe486c \ + --hash=sha256:c463d7c1c4cfc9d751efeaadd936bbba07b5b0ed81a012b3a9f5a12f0872bd6e \ + --hash=sha256:c4a2f3d83879e3de2eb8cbf562e71563a8ed15ee9b9c2e77ca5d9f73072ac15c \ + --hash=sha256:c5584061fd3da584659b13587f26c6cad25a096246a481636d64375d0c1f6c07 \ + --hash=sha256:c677d78887244bf3095020b73c42b505b700f801c690f8eaa90ad12d3179612f \ + --hash=sha256:c903e71fd8debb35ad2a4184c1316b3cb22f64ce517b4e6747f25b0a34e41266 \ + --hash=sha256:c9ff37ba9f15637e424c2ab57a1a590c52897c845b768e4e0a4958084ec87f22 \ + --hash=sha256:cadc16e8ea64b5d9a47363013e2bea469e121e6e7cb416a7593aeb24f2ad122e \ + --hash=sha256:cedac4f4054b8f7859e5aed41aaa31ad03fce6851901a7fdc2af0275ac533c10 \ + --hash=sha256:d22c9dcafed659fadc605538946c041722b6d1104fe619dbf5cc73b3c8a0ded8 \ + --hash=sha256:d765058da196f68dc721116cab335e696e87e76720e6ef8ee5a24801af65e63d \ + --hash=sha256:d86651fa45799530885ba4dab3d21144486ed15285e8784181a0ab37a4552384 \ + --hash=sha256:dd966df3489ec13848d6c6303429bbace94a153f43d1ae2a55115fd36fd5ca5d \ + --hash=sha256:ddc63328889bcaee77b743309e5c7d2d52cee0d7d577837c91b6e7cc9e755e0b \ + --hash=sha256:dfbead5575f6470c17e955b94f92d62a03dfc3d07f2e6f817d9b93dc211a1515 \ + --hash=sha256:e0f3ed828d709f5b82d8bfe14f8856120718ec4bd44a5b26102c3030a1e12501 \ + --hash=sha256:e1861fb6b1d0453ed7293200139c0a9011eeb1376632e048e3766945b13313c5 \ + --hash=sha256:e5015f0bb6eb50008bed2d4b1ce0f2a294698a926111e4bb202c0987b4f89078 \ + --hash=sha256:e651e17bfde5840e9e4174b01e9e080ce49277b70d424308b36a7969d0d1af73 \ + --hash=sha256:e7884931fe5e788163e7b3c511614130c2c59feffdc21112290a194487efb2e9 \ + --hash=sha256:e79c00eba78f7258e5b354eccd4d7907d60317ced924ea4a5f2e9d83f5453065 \ + --hash=sha256:e912b19cf2378f2967d0c08e86ff4c6c360129887f678e27e4dde970d21b3f4d \ + --hash=sha256:e9a011469b47b752e7d20de296bb34591cdfcbe76c99c2e863ceaa2aa61113d2 \ + --hash=sha256:eb756caf8975882630ce4e9fbbeb9d3401242a72528230422c9ab3a0d278e60c \ + --hash=sha256:eba01ec3bd4a49b9ac5ca2bc6a73ff5f3af53374b8556fcc2966dd2af9eb7779 \ + --hash=sha256:ecbfc0437ddfdced5e7822d1ce4855c9c64f46819d0fdc4482c53f56c707b935 \ + --hash=sha256:eed4bba7ff8a0d37106ba931ab03bdd3915fbb025bcf4e1f0aa02bc8114960c5 \ + --hash=sha256:f35727c5118aba95f0397e18a1a5b8405425581bfe53e821f0fb444cbdc2bc9b \ + --hash=sha256:f698733a8a494466432d611a8f0d1e026f5286dee051beea4b3c3146817e35d5 \ + --hash=sha256:f7f9034c7cf05ddfaac8d7a2e63a3c97a840d4615d0a0e65ba8bdf6f8576e3be \ + --hash=sha256:fa0c966ee727aad5406d516375593c5f058c766b21236ab8985693934bb5085b \ + --hash=sha256:fc9c5f280438cf1c1a8f9abb87dc8ce9630a964120cfb5dd50d1e7ce79690c7a \ + --hash=sha256:fd6e6c3d90660d085f7e73710eab6f5545d4854b81b0135a3526e797009dbda3 \ + --hash=sha256:fdfd3fb739f4e22746e13ad7ba0c6eedf5f454b18d11249724a388868e308ee4 \ + --hash=sha256:ff3d50dc3fe8a98059f99b445dfb62792b5d006c5e0b8f03c6de2813b8376110 + # via feast (setup.py) +mock==2.0.0 \ + --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \ + --hash=sha256:b158b6df76edd239b8208d481dc46b6afd45a846b7812ff0ce58971cf5bc8bba + # via feast (setup.py) +moto==4.2.14 \ + --hash=sha256:6d242dbbabe925bb385ddb6958449e5c827670b13b8e153ed63f91dbdb50372c \ + --hash=sha256:8f9263ca70b646f091edcc93e97cda864a542e6d16ed04066b1370ed217bd190 + # via feast (setup.py) +mpire[dill]==2.10.2 \ + --hash=sha256:d627707f7a8d02aa4c7f7d59de399dec5290945ddf7fbd36cbb1d6ebb37a51fb \ + --hash=sha256:f66a321e93fadff34585a4bfa05e95bd946cf714b442f51c529038eb45773d97 + # via semchunk +mpmath==1.3.0 \ + --hash=sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f \ + --hash=sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c + # via sympy +msal==1.34.0 \ + --hash=sha256:76ba83b716ea5a6d75b0279c0ac353a0e05b820ca1f6682c0eb7f45190c43c2f \ + --hash=sha256:f669b1644e4950115da7a176441b0e13ec2975c29528d8b9e81316023676d6e1 + # via + # azure-identity + # msal-extensions +msal-extensions==1.3.1 \ + --hash=sha256:96d3de4d034504e969ac5e85bae8106c8373b5c6568e4c8fa7af2eca9dbe6bca \ + --hash=sha256:c5b0fd10f65ef62b5f1d62f4251d51cbcaf003fcedae8c91b040a488614be1a4 + # via azure-identity +msgpack==1.1.2 \ + --hash=sha256:0051fffef5a37ca2cd16978ae4f0aef92f164df86823871b5162812bebecd8e2 \ + --hash=sha256:04fb995247a6e83830b62f0b07bf36540c213f6eac8e851166d8d86d83cbd014 \ + --hash=sha256:180759d89a057eab503cf62eeec0aa61c4ea1200dee709f3a8e9397dbb3b6931 \ + --hash=sha256:1d1418482b1ee984625d88aa9585db570180c286d942da463533b238b98b812b \ + --hash=sha256:1de460f0403172cff81169a30b9a92b260cb809c4cb7e2fc79ae8d0510c78b6b \ + --hash=sha256:1fdf7d83102bf09e7ce3357de96c59b627395352a4024f6e2458501f158bf999 \ + --hash=sha256:1fff3d825d7859ac888b0fbda39a42d59193543920eda9d9bea44d958a878029 \ + --hash=sha256:283ae72fc89da59aa004ba147e8fc2f766647b1251500182fac0350d8af299c0 \ + --hash=sha256:2929af52106ca73fcb28576218476ffbb531a036c2adbcf54a3664de124303e9 \ + --hash=sha256:2e86a607e558d22985d856948c12a3fa7b42efad264dca8a3ebbcfa2735d786c \ + --hash=sha256:350ad5353a467d9e3b126d8d1b90fe05ad081e2e1cef5753f8c345217c37e7b8 \ + --hash=sha256:354e81bcdebaab427c3df4281187edc765d5d76bfb3a7c125af9da7a27e8458f \ + --hash=sha256:365c0bbe981a27d8932da71af63ef86acc59ed5c01ad929e09a0b88c6294e28a \ + --hash=sha256:372839311ccf6bdaf39b00b61288e0557916c3729529b301c52c2d88842add42 \ + --hash=sha256:3b60763c1373dd60f398488069bcdc703cd08a711477b5d480eecc9f9626f47e \ + --hash=sha256:41d1a5d875680166d3ac5c38573896453bbbea7092936d2e107214daf43b1d4f \ + --hash=sha256:42eefe2c3e2af97ed470eec850facbe1b5ad1d6eacdbadc42ec98e7dcf68b4b7 \ + --hash=sha256:446abdd8b94b55c800ac34b102dffd2f6aa0ce643c55dfc017ad89347db3dbdb \ + --hash=sha256:454e29e186285d2ebe65be34629fa0e8605202c60fbc7c4c650ccd41870896ef \ + --hash=sha256:4efd7b5979ccb539c221a4c4e16aac1a533efc97f3b759bb5a5ac9f6d10383bf \ + --hash=sha256:5559d03930d3aa0f3aacb4c42c776af1a2ace2611871c84a75afe436695e6245 \ + --hash=sha256:5928604de9b032bc17f5099496417f113c45bc6bc21b5c6920caf34b3c428794 \ + --hash=sha256:59415c6076b1e30e563eb732e23b994a61c159cec44deaf584e5cc1dd662f2af \ + --hash=sha256:5a46bf7e831d09470ad92dff02b8b1ac92175ca36b087f904a0519857c6be3ff \ + --hash=sha256:602b6740e95ffc55bfb078172d279de3773d7b7db1f703b2f1323566b878b90e \ + --hash=sha256:61c8aa3bd513d87c72ed0b37b53dd5c5a0f58f2ff9f26e1555d3bd7948fb7296 \ + --hash=sha256:67016ae8c8965124fdede9d3769528ad8284f14d635337ffa6a713a580f6c030 \ + --hash=sha256:6bde749afe671dc44893f8d08e83bf475a1a14570d67c4bb5cec5573463c8833 \ + --hash=sha256:6c15b7d74c939ebe620dd8e559384be806204d73b4f9356320632d783d1f7939 \ + --hash=sha256:70a0dff9d1f8da25179ffcf880e10cf1aad55fdb63cd59c9a49a1b82290062aa \ + --hash=sha256:70c5a7a9fea7f036b716191c29047374c10721c389c21e9ffafad04df8c52c90 \ + --hash=sha256:7bc8813f88417599564fafa59fd6f95be417179f76b40325b500b3c98409757c \ + --hash=sha256:80a0ff7d4abf5fecb995fcf235d4064b9a9a8a40a3ab80999e6ac1e30b702717 \ + --hash=sha256:86f8136dfa5c116365a8a651a7d7484b65b13339731dd6faebb9a0242151c406 \ + --hash=sha256:897c478140877e5307760b0ea66e0932738879e7aa68144d9b78ea4c8302a84a \ + --hash=sha256:8b696e83c9f1532b4af884045ba7f3aa741a63b2bc22617293a2c6a7c645f251 \ + --hash=sha256:8e22ab046fa7ede9e36eeb4cfad44d46450f37bb05d5ec482b02868f451c95e2 \ + --hash=sha256:94fd7dc7d8cb0a54432f296f2246bc39474e017204ca6f4ff345941d4ed285a7 \ + --hash=sha256:99e2cb7b9031568a2a5c73aa077180f93dd2e95b4f8d3b8e14a73ae94a9e667e \ + --hash=sha256:9ade919fac6a3e7260b7f64cea89df6bec59104987cbea34d34a2fa15d74310b \ + --hash=sha256:9fba231af7a933400238cb357ecccf8ab5d51535ea95d94fc35b7806218ff844 \ + --hash=sha256:a465f0dceb8e13a487e54c07d04ae3ba131c7c5b95e2612596eafde1dccf64a9 \ + --hash=sha256:a605409040f2da88676e9c9e5853b3449ba8011973616189ea5ee55ddbc5bc87 \ + --hash=sha256:a668204fa43e6d02f89dbe79a30b0d67238d9ec4c5bd8a940fc3a004a47b721b \ + --hash=sha256:a7787d353595c7c7e145e2331abf8b7ff1e6673a6b974ded96e6d4ec09f00c8c \ + --hash=sha256:a8f6e7d30253714751aa0b0c84ae28948e852ee7fb0524082e6716769124bc23 \ + --hash=sha256:ad09b984828d6b7bb52d1d1d0c9be68ad781fa004ca39216c8a1e63c0f34ba3c \ + --hash=sha256:bafca952dc13907bdfdedfc6a5f579bf4f292bdd506fadb38389afa3ac5b208e \ + --hash=sha256:be52a8fc79e45b0364210eef5234a7cf8d330836d0a64dfbb878efa903d84620 \ + --hash=sha256:be5980f3ee0e6bd44f3a9e9dea01054f175b50c3e6cdb692bc9424c0bbb8bf69 \ + --hash=sha256:c63eea553c69ab05b6747901b97d620bb2a690633c77f23feb0c6a947a8a7b8f \ + --hash=sha256:d198d275222dc54244bf3327eb8cbe00307d220241d9cec4d306d49a44e85f68 \ + --hash=sha256:d62ce1f483f355f61adb5433ebfd8868c5f078d1a52d042b0a998682b4fa8c27 \ + --hash=sha256:d99ef64f349d5ec3293688e91486c5fdb925ed03807f64d98d205d2713c60b46 \ + --hash=sha256:db6192777d943bdaaafb6ba66d44bf65aa0e9c5616fa1d2da9bb08828c6b39aa \ + --hash=sha256:e23ce8d5f7aa6ea6d2a2b326b4ba46c985dbb204523759984430db7114f8aa00 \ + --hash=sha256:e64c8d2f5e5d5fda7b842f55dec6133260ea8f53c4257d64494c534f306bf7a9 \ + --hash=sha256:e69b39f8c0aa5ec24b57737ebee40be647035158f14ed4b40e6f150077e21a84 \ + --hash=sha256:ea5405c46e690122a76531ab97a079e184c0daf491e588592d6a23d3e32af99e \ + --hash=sha256:f2cb069d8b981abc72b41aea1c580ce92d57c673ec61af4c500153a626cb9e20 \ + --hash=sha256:fac4be746328f90caa3cd4bc67e6fe36ca2bf61d5c6eb6d895b6527e3f05071e \ + --hash=sha256:fffee09044073e69f2bad787071aeec727183e7580443dfeb8556cbf1978d162 + # via ray +multidict==6.7.0 \ + --hash=sha256:03ca744319864e92721195fa28c7a3b2bc7b686246b35e4078c1e4d0eb5466d3 \ + --hash=sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec \ + --hash=sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd \ + --hash=sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b \ + --hash=sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb \ + --hash=sha256:08325c9e5367aa379a3496aa9a022fe8837ff22e00b94db256d3a1378c76ab32 \ + --hash=sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f \ + --hash=sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7 \ + --hash=sha256:096f52730c3fb8ed419db2d44391932b63891b2c5ed14850a7e215c0ba9ade36 \ + --hash=sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd \ + --hash=sha256:0a13fb8e748dfc94749f622de065dd5c1def7e0d2216dba72b1d8069a389c6ff \ + --hash=sha256:0db4956f82723cc1c270de9c6e799b4c341d327762ec78ef82bb962f79cc07d8 \ + --hash=sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d \ + --hash=sha256:14c9e076eede3b54c636f8ce1c9c252b5f057c62131211f0ceeec273810c9721 \ + --hash=sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0 \ + --hash=sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3 \ + --hash=sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d \ + --hash=sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa \ + --hash=sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10 \ + --hash=sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202 \ + --hash=sha256:23bfeee5316266e5ee2d625df2d2c602b829435fc3a235c2ba2131495706e4a0 \ + --hash=sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718 \ + --hash=sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e \ + --hash=sha256:295a92a76188917c7f99cda95858c822f9e4aae5824246bba9b6b44004ddd0a6 \ + --hash=sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1 \ + --hash=sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2 \ + --hash=sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754 \ + --hash=sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c \ + --hash=sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390 \ + --hash=sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128 \ + --hash=sha256:329aa225b085b6f004a4955271a7ba9f1087e39dcb7e65f6284a988264a63912 \ + --hash=sha256:363eb68a0a59bd2303216d2346e6c441ba10d36d1f9969fcb6f1ba700de7bb5c \ + --hash=sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3 \ + --hash=sha256:3996b50c3237c4aec17459217c1e7bbdead9a22a0fcd3c365564fbd16439dde6 \ + --hash=sha256:39f1719f57adbb767ef592a50ae5ebb794220d1188f9ca93de471336401c34d2 \ + --hash=sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f \ + --hash=sha256:3ba3ef510467abb0667421a286dc906e30eb08569365f5cdb131d7aff7c2dd84 \ + --hash=sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842 \ + --hash=sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9 \ + --hash=sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6 \ + --hash=sha256:3e56d780c238f9e1ae66a22d2adf8d16f485381878250db8d496623cd38b22bd \ + --hash=sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8 \ + --hash=sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599 \ + --hash=sha256:478cc36476687bac1514d651cbbaa94b86b0732fb6855c60c673794c7dd2da62 \ + --hash=sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec \ + --hash=sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34 \ + --hash=sha256:4b73189894398d59131a66ff157837b1fafea9974be486d036bb3d32331fdbf0 \ + --hash=sha256:4b7a9db5a870f780220e931d0002bbfd88fb53aceb6293251e2c839415c1b20e \ + --hash=sha256:4c09703000a9d0fa3c3404b27041e574cc7f4df4c6563873246d0e11812a94b6 \ + --hash=sha256:4d409aa42a94c0b3fa617708ef5276dfe81012ba6753a0370fcc9d0195d0a1fc \ + --hash=sha256:4d72a9a2d885f5c208b0cb91ff2ed43636bb7e345ec839ff64708e04f69a13cc \ + --hash=sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c \ + --hash=sha256:51cb455de290ae462593e5b1cb1118c5c22ea7f0d3620d9940bf695cea5a4bd7 \ + --hash=sha256:521f33e377ff64b96c4c556b81c55d0cfffb96a11c194fd0c3f1e56f3d8dd5a4 \ + --hash=sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4 \ + --hash=sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38 \ + --hash=sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5 \ + --hash=sha256:661709cdcd919a2ece2234f9bae7174e5220c80b034585d7d8a755632d3e2111 \ + --hash=sha256:680878b9f3d45c31e1f730eef731f9b0bc1da456155688c6745ee84eb818e90e \ + --hash=sha256:6843b28b0364dc605f21481c90fadb5f60d9123b442eb8a726bb74feef588a84 \ + --hash=sha256:68af405971779d8b37198726f2b6fe3955db846fee42db7a4286fc542203934c \ + --hash=sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1 \ + --hash=sha256:6bdce131e14b04fd34a809b6380dbfd826065c3e2fe8a50dbae659fa0c390546 \ + --hash=sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a \ + --hash=sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c \ + --hash=sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036 \ + --hash=sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38 \ + --hash=sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99 \ + --hash=sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64 \ + --hash=sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e \ + --hash=sha256:7e73299c99939f089dd9b2120a04a516b95cdf8c1cd2b18c53ebf0de80b1f18f \ + --hash=sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159 \ + --hash=sha256:7f5170993a0dd3ab871c74f45c0a21a4e2c37a2f2b01b5f722a2ad9c6650469e \ + --hash=sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12 \ + --hash=sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1 \ + --hash=sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0 \ + --hash=sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184 \ + --hash=sha256:8b55d5497b51afdfde55925e04a022f1de14d4f4f25cdfd4f5d9b0aa96166851 \ + --hash=sha256:8cfc12a8630a29d601f48d47787bd7eb730e475e83edb5d6c5084317463373eb \ + --hash=sha256:9281bf5b34f59afbc6b1e477a372e9526b66ca446f4bf62592839c195a718b32 \ + --hash=sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b \ + --hash=sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288 \ + --hash=sha256:95b5ffa4349df2887518bb839409bcf22caa72d82beec453216802f475b23c81 \ + --hash=sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd \ + --hash=sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45 \ + --hash=sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a \ + --hash=sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca \ + --hash=sha256:9cf41880c991716f3c7cec48e2f19ae4045fc9db5fc9cff27347ada24d710bb5 \ + --hash=sha256:9d14baca2ee12c1a64740d4531356ba50b82543017f3ad6de0deb943c5979abb \ + --hash=sha256:9f474ad5acda359c8758c8accc22032c6abe6dc87a8be2440d097785e27a9349 \ + --hash=sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b \ + --hash=sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f \ + --hash=sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32 \ + --hash=sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5 \ + --hash=sha256:a048ce45dcdaaf1defb76b2e684f997fb5abf74437b6cb7b22ddad934a964e34 \ + --hash=sha256:a265acbb7bb33a3a2d626afbe756371dce0279e7b17f4f4eda406459c2b5ff1c \ + --hash=sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4 \ + --hash=sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17 \ + --hash=sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60 \ + --hash=sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394 \ + --hash=sha256:a90af66facec4cebe4181b9e62a68be65e45ac9b52b67de9eec118701856e7ff \ + --hash=sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00 \ + --hash=sha256:afa8a2978ec65d2336305550535c9c4ff50ee527914328c8677b3973ade52b85 \ + --hash=sha256:b15b3afff74f707b9275d5ba6a91ae8f6429c3ffb29bbfd216b0b375a56f13d7 \ + --hash=sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304 \ + --hash=sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13 \ + --hash=sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e \ + --hash=sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e \ + --hash=sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792 \ + --hash=sha256:b61189b29081a20c7e4e0b49b44d5d44bb0dc92be3c6d06a11cc043f81bf9329 \ + --hash=sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb \ + --hash=sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b \ + --hash=sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000 \ + --hash=sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6 \ + --hash=sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62 \ + --hash=sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63 \ + --hash=sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5 \ + --hash=sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e \ + --hash=sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c \ + --hash=sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827 \ + --hash=sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8 \ + --hash=sha256:ce8fdc2dca699f8dbf055a61d73eaa10482569ad20ee3c36ef9641f69afa8c91 \ + --hash=sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96 \ + --hash=sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad \ + --hash=sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6 \ + --hash=sha256:d874eb056410ca05fed180b6642e680373688efafc7f077b2a2f61811e873a40 \ + --hash=sha256:db99677b4457c7a5c5a949353e125ba72d62b35f74e26da141530fbb012218a7 \ + --hash=sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4 \ + --hash=sha256:df0e3bf7993bdbeca5ac25aa859cf40d39019e015c9c91809ba7093967f7a648 \ + --hash=sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064 \ + --hash=sha256:e2862408c99f84aa571ab462d25236ef9cb12a602ea959ba9c9009a54902fc73 \ + --hash=sha256:e3aa16de190d29a0ea1b48253c57d99a68492c8dd8948638073ab9e74dc9410b \ + --hash=sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762 \ + --hash=sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e \ + --hash=sha256:eb866162ef2f45063acc7a53a88ef6fe8bf121d45c30ea3c9cd87ce7e191a8d4 \ + --hash=sha256:ec81878ddf0e98817def1e77d4f50dae5ef5b0e4fe796fae3bd674304172416e \ + --hash=sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546 \ + --hash=sha256:f0e77e3c0008bc9316e662624535b88d360c3a5d3f81e15cf12c139a75250046 \ + --hash=sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6 \ + --hash=sha256:f470f68adc395e0183b92a2f4689264d1ea4b40504a24d9882c27375e6662bb9 \ + --hash=sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d \ + --hash=sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf \ + --hash=sha256:f8e5c0031b90ca9ce555e2e8fd5c3b02a25f14989cbc310701823832c99eb687 \ + --hash=sha256:fb287618b9c7aa3bf8d825f02d9201b2f13078a5ed3b293c8f4d953917d84d5e \ + --hash=sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885 \ + --hash=sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7 + # via + # aiobotocore + # aiohttp + # yarl +multiprocess==0.70.16 \ + --hash=sha256:0dfd078c306e08d46d7a8d06fb120313d87aa43af60d66da43ffff40b44d2f41 \ + --hash=sha256:161af703d4652a0e1410be6abccecde4a7ddffd19341be0a7011b94aeb171ac1 \ + --hash=sha256:37b55f71c07e2d741374998c043b9520b626a8dddc8b3129222ca4f1a06ef67a \ + --hash=sha256:476887be10e2f59ff183c006af746cb6f1fd0eadcfd4ef49e605cbe2659920ee \ + --hash=sha256:a0bafd3ae1b732eac64be2e72038231c1ba97724b60b09400d68f229fcc2fbf3 \ + --hash=sha256:a71d82033454891091a226dfc319d0cfa8019a4e888ef9ca910372a446de4435 \ + --hash=sha256:af4cabb0dac72abfb1e794fa7855c325fd2b55a10a44628a3c1ad3311c04127a \ + --hash=sha256:ba8c31889abf4511c7308a8c52bb4a30b9d590e7f58523302ba00237702ca054 \ + --hash=sha256:c4a9944c67bd49f823687463660a2d6daae94c289adff97e0f9d696ba6371d02 \ + --hash=sha256:d951bed82c8f73929ac82c61f01a7b5ce8f3e5ef40f5b52553b4f547ce2b08ec \ + --hash=sha256:e7b9d0f307cd9bd50851afaac0dba2cb6c44449efff697df7c7645f7d3f2be3a \ + --hash=sha256:fc0544c531920dde3b00c29863377f87e1632601092ea2daca74e4beb40faa2e + # via + # datasets + # mpire +mypy==1.11.2 \ + --hash=sha256:06d26c277962f3fb50e13044674aa10553981ae514288cb7d0a738f495550b36 \ + --hash=sha256:2ff93107f01968ed834f4256bc1fc4475e2fecf6c661260066a985b52741ddce \ + --hash=sha256:36383a4fcbad95f2657642a07ba22ff797de26277158f1cc7bd234821468b1b6 \ + --hash=sha256:37c7fa6121c1cdfcaac97ce3d3b5588e847aa79b580c1e922bb5d5d2902df19b \ + --hash=sha256:3a66169b92452f72117e2da3a576087025449018afc2d8e9bfe5ffab865709ca \ + --hash=sha256:3f14cd3d386ac4d05c5a39a51b84387403dadbd936e17cb35882134d4f8f0d24 \ + --hash=sha256:41ea707d036a5307ac674ea172875f40c9d55c5394f888b168033177fce47383 \ + --hash=sha256:478db5f5036817fe45adb7332d927daa62417159d49783041338921dcf646fc7 \ + --hash=sha256:4a8a53bc3ffbd161b5b2a4fff2f0f1e23a33b0168f1c0778ec70e1a3d66deb86 \ + --hash=sha256:539c570477a96a4e6fb718b8d5c3e0c0eba1f485df13f86d2970c91f0673148d \ + --hash=sha256:57555a7715c0a34421013144a33d280e73c08df70f3a18a552938587ce9274f4 \ + --hash=sha256:6e658bd2d20565ea86da7d91331b0eed6d2eee22dc031579e6297f3e12c758c8 \ + --hash=sha256:6e7184632d89d677973a14d00ae4d03214c8bc301ceefcdaf5c474866814c987 \ + --hash=sha256:75746e06d5fa1e91bfd5432448d00d34593b52e7e91a187d981d08d1f33d4385 \ + --hash=sha256:7f9993ad3e0ffdc95c2a14b66dee63729f021968bff8ad911867579c65d13a79 \ + --hash=sha256:801780c56d1cdb896eacd5619a83e427ce436d86a3bdf9112527f24a66618fef \ + --hash=sha256:801ca29f43d5acce85f8e999b1e431fb479cb02d0e11deb7d2abb56bdaf24fd6 \ + --hash=sha256:969ea3ef09617aff826885a22ece0ddef69d95852cdad2f60c8bb06bf1f71f70 \ + --hash=sha256:a976775ab2256aadc6add633d44f100a2517d2388906ec4f13231fafbb0eccca \ + --hash=sha256:af8d155170fcf87a2afb55b35dc1a0ac21df4431e7d96717621962e4b9192e70 \ + --hash=sha256:b499bc07dbdcd3de92b0a8b29fdf592c111276f6a12fe29c30f6c417dd546d12 \ + --hash=sha256:cd953f221ac1379050a8a646585a29574488974f79d8082cedef62744f0a0104 \ + --hash=sha256:d42a6dd818ffce7be66cce644f1dff482f1d97c53ca70908dff0b9ddc120b77a \ + --hash=sha256:e8960dbbbf36906c5c0b7f4fbf2f0c7ffb20f4898e6a879fcf56a41a08b0d318 \ + --hash=sha256:edb91dded4df17eae4537668b23f0ff6baf3707683734b6a818d5b9d0c0c31a1 \ + --hash=sha256:ee23de8530d99b6db0573c4ef4bd8f39a2a6f9b60655bf7a1357e585a3486f2b \ + --hash=sha256:f7821776e5c4286b6a13138cc935e2e9b6fde05e081bdebf5cdb2bb97c9df81d + # via + # feast (setup.py) + # sqlalchemy +mypy-extensions==1.1.0 \ + --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ + --hash=sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558 + # via mypy +mypy-protobuf==3.3.0 \ + --hash=sha256:15604f6943b16c05db646903261e3b3e775cf7f7990b7c37b03d043a907b650d \ + --hash=sha256:24f3b0aecb06656e983f58e07c732a90577b9d7af3e1066fc2b663bbf0370248 + # via feast (setup.py) +nbclient==0.10.4 \ + --hash=sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9 \ + --hash=sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440 + # via nbconvert +nbconvert==7.16.6 \ + --hash=sha256:1375a7b67e0c2883678c48e506dc320febb57685e5ee67faa51b18a90f3a712b \ + --hash=sha256:576a7e37c6480da7b8465eefa66c17844243816ce1ccc372633c6b71c3c0f582 + # via jupyter-server +nbformat==5.10.4 \ + --hash=sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a \ + --hash=sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b + # via + # great-expectations + # jupyter-server + # nbclient + # nbconvert +nest-asyncio==1.6.0 \ + --hash=sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe \ + --hash=sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c + # via ipykernel +networkx==3.6.1 \ + --hash=sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509 \ + --hash=sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762 + # via + # scikit-image + # torch +ninja==1.13.0 \ + --hash=sha256:11be2d22027bde06f14c343f01d31446747dbb51e72d00decca2eb99be911e2f \ + --hash=sha256:1c97223cdda0417f414bf864cfb73b72d8777e57ebb279c5f6de368de0062988 \ + --hash=sha256:3c0b40b1f0bba764644385319028650087b4c1b18cdfa6f45cb39a3669b81aa9 \ + --hash=sha256:3d00c692fb717fd511abeb44b8c5d00340c36938c12d6538ba989fe764e79630 \ + --hash=sha256:3d7d7779d12cb20c6d054c61b702139fd23a7a964ec8f2c823f1ab1b084150db \ + --hash=sha256:4a40ce995ded54d9dc24f8ea37ff3bf62ad192b547f6c7126e7e25045e76f978 \ + --hash=sha256:4be9c1b082d244b1ad7ef41eb8ab088aae8c109a9f3f0b3e56a252d3e00f42c1 \ + --hash=sha256:5f8e1e8a1a30835eeb51db05cf5a67151ad37542f5a4af2a438e9490915e5b72 \ + --hash=sha256:60056592cf495e9a6a4bea3cd178903056ecb0943e4de45a2ea825edb6dc8d3e \ + --hash=sha256:6739d3352073341ad284246f81339a384eec091d9851a886dfa5b00a6d48b3e2 \ + --hash=sha256:8cfbb80b4a53456ae8a39f90ae3d7a2129f45ea164f43fadfa15dc38c4aef1c9 \ + --hash=sha256:aa45b4037b313c2f698bc13306239b8b93b4680eb47e287773156ac9e9304714 \ + --hash=sha256:b4f2a072db3c0f944c32793e91532d8948d20d9ab83da9c0c7c15b5768072200 \ + --hash=sha256:be7f478ff9f96a128b599a964fc60a6a87b9fa332ee1bd44fa243ac88d50291c \ + --hash=sha256:d741a5e6754e0bda767e3274a0f0deeef4807f1fec6c0d7921a0244018926ae5 \ + --hash=sha256:e8bad11f8a00b64137e9b315b137d8bb6cbf3086fbdc43bf1f90fd33324d2e96 \ + --hash=sha256:fa2a8bfc62e31b08f83127d1613d10821775a0eb334197154c4d6067b7068ff1 \ + --hash=sha256:fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa \ + --hash=sha256:fb8ee8719f8af47fed145cced4a85f0755dd55d45b2bddaf7431fa89803c5f3e + # via easyocr +nodeenv==1.10.0 \ + --hash=sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827 \ + --hash=sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb + # via pre-commit +notebook==7.5.2 \ + --hash=sha256:17d078a98603d70d62b6b4b3fcb67e87d7a68c398a7ae9b447eb2d7d9aec9979 \ + --hash=sha256:83e82f93c199ca730313bea1bb24bc279ea96f74816d038a92d26b6b9d5f3e4a + # via great-expectations +notebook-shim==0.2.4 \ + --hash=sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef \ + --hash=sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb + # via + # jupyterlab + # notebook +numpy==2.4.1 \ + --hash=sha256:0093e85df2960d7e4049664b26afc58b03236e967fb942354deef3208857a04c \ + --hash=sha256:09aa8a87e45b55a1c2c205d42e2808849ece5c484b2aab11fecabec3841cafba \ + --hash=sha256:0cce2a669e3c8ba02ee563c7835f92c153cf02edff1ae05e1823f1dde21b16a5 \ + --hash=sha256:0e6e8f9d9ecf95399982019c01223dc130542960a12edfa8edd1122dfa66a8a8 \ + --hash=sha256:0f118ce6b972080ba0758c6087c3617b5ba243d806268623dc34216d69099ba0 \ + --hash=sha256:178de8f87948163d98a4c9ab5bee4ce6519ca918926ec8df195af582de28544d \ + --hash=sha256:18e14c4d09d55eef39a6ab5b08406e84bc6869c1e34eef45564804f90b7e0574 \ + --hash=sha256:2023ef86243690c2791fd6353e5b4848eedaa88ca8a2d129f462049f6d484696 \ + --hash=sha256:20d4649c773f66cc2fc36f663e091f57c3b7655f936a4c681b4250855d1da8f5 \ + --hash=sha256:2302dc0224c1cbc49bb94f7064f3f923a971bfae45c33870dcbff63a2a550505 \ + --hash=sha256:26f0bcd9c79a00e339565b303badc74d3ea2bd6d52191eeca5f95936cad107d0 \ + --hash=sha256:297c72b1b98100c2e8f873d5d35fb551fce7040ade83d67dd51d38c8d42a2162 \ + --hash=sha256:2f44de05659b67d20499cbc96d49f2650769afcb398b79b324bb6e297bfe3844 \ + --hash=sha256:2ffd257026eb1b34352e749d7cc1678b5eeec3e329ad8c9965a797e08ccba205 \ + --hash=sha256:382ad67d99ef49024f11d1ce5dcb5ad8432446e4246a4b014418ba3a1175a1f4 \ + --hash=sha256:3869ea1ee1a1edc16c29bbe3a2f2a4e515cc3a44d43903ad41e0cacdbaf733dc \ + --hash=sha256:3d1a100e48cb266090a031397863ff8a30050ceefd798f686ff92c67a486753d \ + --hash=sha256:423797bdab2eeefbe608d7c1ec7b2b4fd3c58d51460f1ee26c7500a1d9c9ee93 \ + --hash=sha256:42d7dd5fa36d16d52a84f821eb96031836fd405ee6955dd732f2023724d0aa01 \ + --hash=sha256:49e792ec351315e16da54b543db06ca8a86985ab682602d90c60ef4ff4db2a9c \ + --hash=sha256:4e53170557d37ae404bf8d542ca5b7c629d6efa1117dac6a83e394142ea0a43f \ + --hash=sha256:4f1b68ff47680c2925f8063402a693ede215f0257f02596b1318ecdfb1d79e33 \ + --hash=sha256:4f9c360ecef085e5841c539a9a12b883dff005fbd7ce46722f5e9cef52634d82 \ + --hash=sha256:529050522e983e00a6c1c6b67411083630de8b57f65e853d7b03d9281b8694d2 \ + --hash=sha256:52b5f61bdb323b566b528899cc7db2ba5d1015bda7ea811a8bcf3c89c331fa42 \ + --hash=sha256:538bf4ec353709c765ff75ae616c34d3c3dca1a68312727e8f2676ea644f8509 \ + --hash=sha256:5adf01965456a664fc727ed69cc71848f28d063217c63e1a0e200a118d5eec9a \ + --hash=sha256:5b55aa56165b17aaf15520beb9cbd33c9039810e0d9643dd4379e44294c7303e \ + --hash=sha256:5d558123217a83b2d1ba316b986e9248a1ed1971ad495963d555ccd75dcb1556 \ + --hash=sha256:5de60946f14ebe15e713a6f22850c2372fa72f4ff9a432ab44aa90edcadaa65a \ + --hash=sha256:62fea415f83ad8fdb6c20840578e5fbaf5ddd65e0ec6c3c47eda0f69da172510 \ + --hash=sha256:6436cffb4f2bf26c974344439439c95e152c9a527013f26b3577be6c2ca64295 \ + --hash=sha256:6461de5113088b399d655d45c3897fa188766415d0f568f175ab071c8873bd73 \ + --hash=sha256:69e7419c9012c4aaf695109564e3387f1259f001b4326dfa55907b098af082d3 \ + --hash=sha256:71abbea030f2cfc3092a0ff9f8c8fdefdc5e0bf7d9d9c99663538bb0ecdac0b9 \ + --hash=sha256:7211b95ca365519d3596a1d8688a95874cc94219d417504d9ecb2df99fa7bfa8 \ + --hash=sha256:727c6c3275ddefa0dc078524a85e064c057b4f4e71ca5ca29a19163c607be745 \ + --hash=sha256:79e9e06c4c2379db47f3f6fc7a8652e7498251789bf8ff5bd43bf478ef314ca2 \ + --hash=sha256:7ad270f438cbdd402c364980317fb6b117d9ec5e226fff5b4148dd9aa9fc6e02 \ + --hash=sha256:7d5d7999df434a038d75a748275cd6c0094b0ecdb0837342b332a82defc4dc4d \ + --hash=sha256:8097529164c0f3e32bb89412a0905d9100bf434d9692d9fc275e18dcf53c9344 \ + --hash=sha256:82c55962006156aeef1629b953fd359064aa47e4d82cfc8e67f0918f7da3344f \ + --hash=sha256:8361ea4220d763e54cff2fbe7d8c93526b744f7cd9ddab47afeff7e14e8503be \ + --hash=sha256:899d2c18024984814ac7e83f8f49d8e8180e2fbe1b2e252f2e7f1d06bea92425 \ + --hash=sha256:8ad35f20be147a204e28b6a0575fbf3540c5e5f802634d4258d55b1ff5facce1 \ + --hash=sha256:8f085da926c0d491ffff3096f91078cc97ea67e7e6b65e490bc8dcda65663be2 \ + --hash=sha256:9171a42fcad32dcf3fa86f0a4faa5e9f8facefdb276f54b8b390d90447cff4e2 \ + --hash=sha256:92a0e65272fd60bfa0d9278e0484c2f52fe03b97aedc02b357f33fe752c52ffb \ + --hash=sha256:941c2a93313d030f219f3a71fd3d91a728b82979a5e8034eb2e60d394a2b83f9 \ + --hash=sha256:98b35775e03ab7f868908b524fc0a84d38932d8daf7b7e1c3c3a1b6c7a2c9f15 \ + --hash=sha256:a1ceafc5042451a858231588a104093474c6a5c57dcc724841f5c888d237d690 \ + --hash=sha256:a73044b752f5d34d4232f25f18160a1cc418ea4507f5f11e299d8ac36875f8a0 \ + --hash=sha256:a7870e8c5fc11aef57d6fea4b4085e537a3a60ad2cdd14322ed531fdca68d261 \ + --hash=sha256:a92f227dbcdc9e4c3e193add1a189a9909947d4f8504c576f4a732fd0b54240a \ + --hash=sha256:ac08c63cb7779b85e9d5318e6c3518b424bc1f364ac4cb2c6136f12e5ff2dccc \ + --hash=sha256:b6bcf39112e956594b3331316d90c90c90fb961e39696bda97b89462f5f3943f \ + --hash=sha256:c0faba4a331195bfa96f93dd9dfaa10b2c7aa8cda3a02b7fd635e588fe821bf5 \ + --hash=sha256:ce9ce141a505053b3c7bce3216071f3bf5c182b8b28930f14cd24d43932cd2df \ + --hash=sha256:cf6470d91d34bf669f61d515499859fa7a4c2f7c36434afb70e82df7217933f9 \ + --hash=sha256:d3703409aac693fa82c0aee023a1ae06a6e9d065dba10f5e8e80f642f1e9d0a2 \ + --hash=sha256:d3e3087f53e2b4428766b54932644d148613c5a595150533ae7f00dab2f319a8 \ + --hash=sha256:d3f8f0df9f4b8be57b3bf74a1d087fec68f927a2fab68231fdb442bf2c12e426 \ + --hash=sha256:d797454e37570cfd61143b73b8debd623c3c0952959adb817dd310a483d58a1b \ + --hash=sha256:e1a27bb1b2dee45a2a53f5ca6ff2d1a7f135287883a1689e930d44d1ff296c87 \ + --hash=sha256:e3bd2cb07841166420d2fa7146c96ce00cb3410664cbc1a6be028e456c4ee220 \ + --hash=sha256:e7b6b5e28bbd47b7532698e5db2fe1db693d84b58c254e4389d99a27bb9b8f6b \ + --hash=sha256:e867df947d427cdd7a60e3e271729090b0f0df80f5f10ab7dd436f40811699c3 \ + --hash=sha256:ea66d2b41ca4a1630aae5507ee0a71647d3124d1741980138aa8f28f44dac36e \ + --hash=sha256:edee228f76ee2dab4579fad6f51f6a305de09d444280109e0f75df247ff21501 \ + --hash=sha256:f0a90aba7d521e6954670550e561a4cb925713bd944445dbe9e729b71f6cabee \ + --hash=sha256:f93bc6892fe7b0663e5ffa83b61aab510aacffd58c16e012bb9352d489d90cb7 \ + --hash=sha256:fb1461c99de4d040666ca0444057b06541e5642f800b71c56e6ea92d6a853a0c + # via + # feast (setup.py) + # accelerate + # altair + # dask + # datasets + # db-dtypes + # docling-ibm-models + # easyocr + # faiss-cpu + # great-expectations + # ibis-framework + # imageio + # opencv-python-headless + # pandas + # pandas-gbq + # pyarrow + # qdrant-client + # ray + # safetensors + # scikit-image + # scikit-learn + # scipy + # shapely + # tifffile + # torchvision + # transformers +oauthlib==3.3.1 \ + --hash=sha256:0f0f8aa759826a193cf66c12ea1af1637f87b9b4622d46e866952bb022e538c9 \ + --hash=sha256:88119c938d2b8fb88561af5f6ee0eec8cc8d552b7bb1f712743136eb7523b7a1 + # via requests-oauthlib +opencensus==0.11.4 \ + --hash=sha256:a18487ce68bc19900336e0ff4655c5a116daf10c1b3685ece8d971bddad6a864 \ + --hash=sha256:cbef87d8b8773064ab60e5c2a1ced58bbaa38a6d052c41aec224958ce544eff2 + # via ray +opencensus-context==0.1.3 \ + --hash=sha256:073bb0590007af276853009fac7e4bab1d523c3f03baf4cb4511ca38967c6039 \ + --hash=sha256:a03108c3c10d8c80bb5ddf5c8a1f033161fa61972a9917f9b9b3a18517f0088c + # via opencensus +opencv-python-headless==4.13.0.90 \ + --hash=sha256:0e0c8c9f620802fddc4fa7f471a1d263c7b0dca16cd9e7e2f996bb8bd2128c0c \ + --hash=sha256:12a28674f215542c9bf93338de1b5bffd76996d32da9acb9e739fdb9c8bbd738 \ + --hash=sha256:32255203040dc98803be96362e13f9e4bce20146898222d2e5c242f80de50da5 \ + --hash=sha256:96060fc57a1abb1144b0b8129e2ff3bfcdd0ccd8e8bd05bd85256ff4ed587d3b \ + --hash=sha256:dbc1f4625e5af3a80ebdbd84380227c0f445228588f2521b11af47710caca1ba \ + --hash=sha256:e13790342591557050157713af17a7435ac1b50c65282715093c9297fa045d8f \ + --hash=sha256:eba38bc255d0b7d1969c5bcc90a060ca2b61a3403b613872c750bfa5dfe9e03b \ + --hash=sha256:f46b17ea0aa7e4124ca6ad71143f89233ae9557f61d2326bcdb34329a1ddf9bd + # via easyocr +openpyxl==3.1.5 \ + --hash=sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2 \ + --hash=sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050 + # via docling +openshift-client==1.0.18 \ + --hash=sha256:be3979440cfd96788146a3a1650dabe939d4d516eea0b39f87e66d2ab39495b1 \ + --hash=sha256:d8a84080307ccd9556f6c62a3707a3e6507baedee36fa425754f67db9ded528b + # via codeflare-sdk +opentelemetry-api==1.39.1 \ + --hash=sha256:2edd8463432a7f8443edce90972169b195e7d6a05500cd29e6d13898187c9950 \ + --hash=sha256:fbde8c80e1b937a2c61f20347e91c0c18a1940cecf012d62e65a7caf08967c9c + # via + # opentelemetry-exporter-prometheus + # opentelemetry-sdk + # opentelemetry-semantic-conventions +opentelemetry-exporter-prometheus==0.60b1 \ + --hash=sha256:49f59178de4f4590e3cef0b8b95cf6e071aae70e1f060566df5546fad773b8fd \ + --hash=sha256:a4011b46906323f71724649d301b4dc188aaa068852e814f4df38cc76eac616b + # via ray +opentelemetry-proto==1.27.0 \ + --hash=sha256:33c9345d91dafd8a74fc3d7576c5a38f18b7fdf8d02983ac67485386132aedd6 \ + --hash=sha256:b133873de5581a50063e1e4b29cdcf0c5e253a8c2d8dc1229add20a4c3830ace + # via ray +opentelemetry-sdk==1.39.1 \ + --hash=sha256:4d5482c478513ecb0a5d938dcc61394e647066e0cc2676bee9f3af3f3f45f01c \ + --hash=sha256:cf4d4563caf7bff906c9f7967e2be22d0d6b349b908be0d90fb21c8e9c995cc6 + # via + # opentelemetry-exporter-prometheus + # ray +opentelemetry-semantic-conventions==0.60b1 \ + --hash=sha256:87c228b5a0669b748c76d76df6c364c369c28f1c465e50f661e39737e84bc953 \ + --hash=sha256:9fa8c8b0c110da289809292b0591220d3a7b53c1526a23021e977d68597893fb + # via opentelemetry-sdk +orjson==3.11.5 \ + --hash=sha256:0522003e9f7fba91982e83a97fec0708f5a714c96c4209db7104e6b9d132f111 \ + --hash=sha256:073aab025294c2f6fc0807201c76fdaed86f8fc4be52c440fb78fbb759a1ac09 \ + --hash=sha256:09b94b947ac08586af635ef922d69dc9bc63321527a3a04647f4986a73f4bd30 \ + --hash=sha256:1b280e2d2d284a6713b0cfec7b08918ebe57df23e3f76b27586197afca3cb1e9 \ + --hash=sha256:1b6bd351202b2cd987f35a13b5e16471cf4d952b42a73c391cc537974c43ef6d \ + --hash=sha256:1cbf2735722623fcdee8e712cbaaab9e372bbcb0c7924ad711b261c2eccf4a5c \ + --hash=sha256:1db2088b490761976c1b2e956d5d4e6409f3732e9d79cfa69f876c5248d1baf9 \ + --hash=sha256:23d04c4543e78f724c4dfe656b3791b5f98e4c9253e13b2636f1af5d90e4a880 \ + --hash=sha256:298d2451f375e5f17b897794bcc3e7b821c0f32b4788b9bcae47ada24d7f3cf7 \ + --hash=sha256:2b91126e7b470ff2e75746f6f6ee32b9ab67b7a93c8ba1d15d3a0caaf16ec875 \ + --hash=sha256:2cc79aaad1dfabe1bd2d50ee09814a1253164b3da4c00a78c458d82d04b3bdef \ + --hash=sha256:334e5b4bff9ad101237c2d799d9fd45737752929753bf4faf4b207335a416b7d \ + --hash=sha256:38b22f476c351f9a1c43e5b07d8b5a02eb24a6ab8e75f700f7d479d4568346a5 \ + --hash=sha256:3b01799262081a4c47c035dd77c1301d40f568f77cc7ec1bb7db5d63b0a01629 \ + --hash=sha256:3c8d8a112b274fae8c5f0f01954cb0480137072c271f3f4958127b010dfefaec \ + --hash=sha256:3fd15f9fc8c203aeceff4fda211157fad114dde66e92e24097b3647a08f4ee9e \ + --hash=sha256:42e8961196af655bb5e63ce6c60d25e8798cd4dfbc04f4203457fa3869322c2e \ + --hash=sha256:4bdd8d164a871c4ec773f9de0f6fe8769c2d6727879c37a9666ba4183b7f8228 \ + --hash=sha256:4dad582bc93cef8f26513e12771e76385a7e6187fd713157e971c784112aad56 \ + --hash=sha256:53deb5addae9c22bbe3739298f5f2196afa881ea75944e7720681c7080909a81 \ + --hash=sha256:54aae9b654554c3b4edd61896b978568c6daa16af96fa4681c9b5babd469f863 \ + --hash=sha256:59ac72ea775c88b163ba8d21b0177628bd015c5dd060647bbab6e22da3aad287 \ + --hash=sha256:5f0a2ae6f09ac7bd47d2d5a5305c1d9ed08ac057cda55bb0a49fa506f0d2da00 \ + --hash=sha256:5f691263425d3177977c8d1dd896cde7b98d93cbf390b2544a090675e83a6a0a \ + --hash=sha256:61026196a1c4b968e1b1e540563e277843082e9e97d78afa03eb89315af531f1 \ + --hash=sha256:61de247948108484779f57a9f406e4c84d636fa5a59e411e6352484985e8a7c3 \ + --hash=sha256:667c132f1f3651c14522a119e4dd631fad98761fa960c55e8e7430bb2a1ba4ac \ + --hash=sha256:67394d3becd50b954c4ecd24ac90b5051ee7c903d167459f93e77fc6f5b4c968 \ + --hash=sha256:69a0f6ac618c98c74b7fbc8c0172ba86f9e01dbf9f62aa0b1776c2231a7bffe5 \ + --hash=sha256:6af8680328c69e15324b5af3ae38abbfcf9cbec37b5346ebfd52339c3d7e8a18 \ + --hash=sha256:7339f41c244d0eea251637727f016b3d20050636695bc78345cce9029b189401 \ + --hash=sha256:7403851e430a478440ecc1258bcbacbfbd8175f9ac1e39031a7121dd0de05ff8 \ + --hash=sha256:75412ca06e20904c19170f8a24486c4e6c7887dea591ba18a1ab572f1300ee9f \ + --hash=sha256:75bc2e59e6a2ac1dd28901d07115abdebc4563b5b07dd612bf64260a201b1c7f \ + --hash=sha256:7bb2ce0b82bc9fd1168a513ddae7a857994b780b2945a8c51db4ab1c4b751ebc \ + --hash=sha256:7cce16ae2f5fb2c53c3eafdd1706cb7b6530a67cc1c17abe8ec747f5cd7c0c51 \ + --hash=sha256:801a821e8e6099b8c459ac7540b3c32dba6013437c57fdcaec205b169754f38c \ + --hash=sha256:82393ab47b4fe44ffd0a7659fa9cfaacc717eb617c93cde83795f14af5c2e9d5 \ + --hash=sha256:82cd00d49d6063d2b8791da5d4f9d20539c5951f965e45ccf4e96d33505ce68f \ + --hash=sha256:835f26fa24ba0bb8c53ae2a9328d1706135b74ec653ed933869b74b6909e63fd \ + --hash=sha256:86cfc555bfd5794d24c6a1903e558b50644e5e68e6471d66502ce5cb5fdef3f9 \ + --hash=sha256:894aea2e63d4f24a7f04a1908307c738d0dce992e9249e744b8f4e8dd9197f39 \ + --hash=sha256:8be318da8413cdbbce77b8c5fac8d13f6eb0f0db41b30bb598631412619572e8 \ + --hash=sha256:8d5f16195bb671a5dd3d1dbea758918bada8f6cc27de72bd64adfbd748770814 \ + --hash=sha256:9172578c4eb09dbfcf1657d43198de59b6cef4054de385365060ed50c458ac98 \ + --hash=sha256:92a8d676748fca47ade5bc3da7430ed7767afe51b2f8100e3cd65e151c0eaceb \ + --hash=sha256:9645ef655735a74da4990c24ffbd6894828fbfa117bc97c1edd98c282ecb52e1 \ + --hash=sha256:9c8494625ad60a923af6b2b0bd74107146efe9b55099e20d7740d995f338fcd8 \ + --hash=sha256:9cc1e55c884921434a84a0c3dd2699eb9f92e7b441d7f53f3941079ec6ce7499 \ + --hash=sha256:9df95000fbe6777bf9820ae82ab7578e8662051bb5f83d71a28992f539d2cda7 \ + --hash=sha256:a230065027bc2a025e944f9d4714976a81e7ecfa940923283bca7bbc1f10f626 \ + --hash=sha256:a261fef929bcf98a60713bf5e95ad067cea16ae345d9a35034e73c3990e927d2 \ + --hash=sha256:a4f3cb2d874e03bc7767c8f88adaa1a9a05cecea3712649c3b58589ec7317310 \ + --hash=sha256:a66d7769e98a08a12a139049aac2f0ca3adae989817f8c43337455fbc7669b85 \ + --hash=sha256:a86fe4ff4ea523eac8f4b57fdac319faf037d3c1be12405e6a7e86b3fbc4756a \ + --hash=sha256:aa0f513be38b40234c77975e68805506cad5d57b3dfd8fe3baa7f4f4051e15b4 \ + --hash=sha256:aa5e4244063db8e1d87e0f54c3f7522f14b2dc937e65d5241ef0076a096409fd \ + --hash=sha256:acbc5fac7e06777555b0722b8ad5f574739e99ffe99467ed63da98f97f9ca0fe \ + --hash=sha256:b29d36b60e606df01959c4b982729c8845c69d1963f88686608be9ced96dbfaa \ + --hash=sha256:b42ffbed9128e547a1647a3e50bc88ab28ae9daa61713962e0d3dd35e820c125 \ + --hash=sha256:b923c1c13fa02084eb38c9c065afd860a5cff58026813319a06949c3af5732ac \ + --hash=sha256:b9f86d69ae822cabc2a0f6c099b43e8733dda788405cba2665595b7e8dd8d167 \ + --hash=sha256:bb150d529637d541e6af06bbe3d02f5498d628b7f98267ff87647584293ab439 \ + --hash=sha256:c028a394c766693c5c9909dec76b24f37e6a1b91999e8d0c0d5feecbe93c3e05 \ + --hash=sha256:c0d87bd1896faac0d10b4f849016db81a63e4ec5df38757ffae84d45ab38aa71 \ + --hash=sha256:c0e5d9f7a0227df2927d343a6e3859bebf9208b427c79bd31949abcc2fa32fa5 \ + --hash=sha256:c2021afda46c1ed64d74b555065dbd4c2558d510d8cec5ea6a53001b3e5e82a9 \ + --hash=sha256:c2ed66358f32c24e10ceea518e16eb3549e34f33a9d51f99ce23b0251776a1ef \ + --hash=sha256:c404603df4865f8e0afe981aa3c4b62b406e6d06049564d58934860b62b7f91d \ + --hash=sha256:c74099c6b230d4261fdc3169d50efc09abf38ace1a42ea2f9994b1d79153d477 \ + --hash=sha256:ccc70da619744467d8f1f49a8cadae5ec7bbe054e5232d95f92ed8737f8c5870 \ + --hash=sha256:d4be86b58e9ea262617b8ca6251a2f0d63cc132a6da4b5fcc8e0a4128782c829 \ + --hash=sha256:d7345c759276b798ccd6d77a87136029e71e66a8bbf2d2755cbdde1d82e78706 \ + --hash=sha256:ddbfdb5099b3e6ba6d6ea818f61997bb66de14b411357d24c4612cf1ebad08ca \ + --hash=sha256:ddc21521598dbe369d83d4d40338e23d4101dad21dae0e79fa20465dbace019f \ + --hash=sha256:df9eadb2a6386d5ea2bfd81309c505e125cfc9ba2b1b99a97e60985b0b3665d1 \ + --hash=sha256:e08ca8a6c851e95aaecc32bc44a5aa75d0ad26af8cdac7c77e4ed93acf3d5b69 \ + --hash=sha256:e446a8ea0a4c366ceafc7d97067bfd55292969143b57e3c846d87fc701e797a0 \ + --hash=sha256:e46c762d9f0e1cfb4ccc8515de7f349abbc95b59cb5a2bd68df5973fdef913f8 \ + --hash=sha256:e607b49b1a106ee2086633167033afbd63f76f2999e9236f638b06b112b24ea7 \ + --hash=sha256:e697d06ad57dd0c7a737771d470eedc18e68dfdefcdd3b7de7f33dfda5b6212e \ + --hash=sha256:e8b5f96c05fce7d0218df3fdfeb962d6b8cfff7e3e20264306b46dd8b217c0f3 \ + --hash=sha256:ed24250e55efbcb0b35bed7caaec8cedf858ab2f9f2201f17b8938c618c8ca6f \ + --hash=sha256:fa1863e75b92891f553b7922ce4ee10ed06db061e104f2b7815de80cdcb135ad \ + --hash=sha256:fea7339bdd22e6f1060c55ac31b6a755d86a5b2ad3657f2669ec243f8e3b2bdb \ + --hash=sha256:ff770589960a86eae279f5d8aa536196ebda8273a2a07db2a54e82b93bc86626 \ + --hash=sha256:ff7877d376add4e16b274e35a3f58b7f37b362abf4aa31863dadacdd20e3a583 + # via trino +overrides==7.7.0 \ + --hash=sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a \ + --hash=sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49 + # via jupyter-server +packaging==24.2 \ + --hash=sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759 \ + --hash=sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f + # via + # accelerate + # build + # dask + # datasets + # db-dtypes + # deprecation + # dunamai + # faiss-cpu + # google-cloud-bigquery + # great-expectations + # gunicorn + # huggingface-hub + # ibis-framework + # ibis-substrait + # ipykernel + # jupyter-events + # jupyter-server + # jupyterlab + # jupyterlab-server + # lazy-loader + # marshmallow + # nbconvert + # pandas-gbq + # pytest + # ray + # safetensors + # scikit-image + # snowflake-connector-python + # sphinx + # transformers +pandas==2.3.3 \ + --hash=sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7 \ + --hash=sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593 \ + --hash=sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5 \ + --hash=sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791 \ + --hash=sha256:23ebd657a4d38268c7dfbdf089fbc31ea709d82e4923c5ffd4fbd5747133ce73 \ + --hash=sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec \ + --hash=sha256:28083c648d9a99a5dd035ec125d42439c6c1c525098c58af0fc38dd1a7a1b3d4 \ + --hash=sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5 \ + --hash=sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac \ + --hash=sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084 \ + --hash=sha256:376c6446ae31770764215a6c937f72d917f214b43560603cd60da6408f183b6c \ + --hash=sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87 \ + --hash=sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35 \ + --hash=sha256:4793891684806ae50d1288c9bae9330293ab4e083ccd1c5e383c34549c6e4250 \ + --hash=sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c \ + --hash=sha256:503cf027cf9940d2ceaa1a93cfb5f8c8c7e6e90720a2850378f0b3f3b1e06826 \ + --hash=sha256:5554c929ccc317d41a5e3d1234f3be588248e61f08a74dd17c9eabb535777dc9 \ + --hash=sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713 \ + --hash=sha256:5caf26f64126b6c7aec964f74266f435afef1c1b13da3b0636c7518a1fa3e2b1 \ + --hash=sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523 \ + --hash=sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3 \ + --hash=sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78 \ + --hash=sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53 \ + --hash=sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c \ + --hash=sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21 \ + --hash=sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5 \ + --hash=sha256:854d00d556406bffe66a4c0802f334c9ad5a96b4f1f868adf036a21b11ef13ff \ + --hash=sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45 \ + --hash=sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110 \ + --hash=sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493 \ + --hash=sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b \ + --hash=sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450 \ + --hash=sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86 \ + --hash=sha256:a637c5cdfa04b6d6e2ecedcb81fc52ffb0fd78ce2ebccc9ea964df9f658de8c8 \ + --hash=sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98 \ + --hash=sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89 \ + --hash=sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66 \ + --hash=sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b \ + --hash=sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8 \ + --hash=sha256:bf1f8a81d04ca90e32a0aceb819d34dbd378a98bf923b6398b9a3ec0bf44de29 \ + --hash=sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6 \ + --hash=sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc \ + --hash=sha256:c503ba5216814e295f40711470446bc3fd00f0faea8a086cbc688808e26f92a2 \ + --hash=sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788 \ + --hash=sha256:d3e28b3e83862ccf4d85ff19cf8c20b2ae7e503881711ff2d534dc8f761131aa \ + --hash=sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151 \ + --hash=sha256:dd7478f1463441ae4ca7308a70e90b33470fa593429f9d4c578dd00d1fa78838 \ + --hash=sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b \ + --hash=sha256:e19d192383eab2f4ceb30b412b22ea30690c9e618f78870357ae1d682912015a \ + --hash=sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d \ + --hash=sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908 \ + --hash=sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0 \ + --hash=sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b \ + --hash=sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c \ + --hash=sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee + # via + # feast (setup.py) + # altair + # dask + # datasets + # db-dtypes + # docling + # docling-core + # google-cloud-bigquery + # great-expectations + # ibis-framework + # pandas-gbq + # pymilvus + # ray + # snowflake-connector-python +pandas-gbq==0.30.0 \ + --hash=sha256:8fe811786e4ad2e0d4608e897534207d9fbe768ab3168f766a99f0cb4cd5ed20 \ + --hash=sha256:d9b4454b17aee3c23ef1dfcfd91df6e2b77f1e69e1e4b28467701cd75850664a + # via google-cloud-bigquery +pandocfilters==1.5.1 \ + --hash=sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e \ + --hash=sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc + # via nbconvert +paramiko==4.0.0 \ + --hash=sha256:0e20e00ac666503bf0b4eda3b6d833465a2b7aff2e2b3d79a8bba5ef144ee3b9 \ + --hash=sha256:6a25f07b380cc9c9a88d2b920ad37167ac4667f8d9886ccebd8f90f654b5d69f + # via openshift-client +parsimonious==0.11.0 \ + --hash=sha256:32e3818abf9f05b3b9f3b6d87d128645e30177e91f614d2277d88a0aea98fae2 \ + --hash=sha256:e080377d98957beec053580d38ae54fcdf7c470fb78670ba4bf8b5f9d5cad2a9 + # via singlestoredb +parso==0.8.5 \ + --hash=sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a \ + --hash=sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887 + # via jedi +parsy==2.2 \ + --hash=sha256:5e981613d9d2d8b68012d1dd0afe928967bea2e4eefdb76c2f545af0dd02a9e7 \ + --hash=sha256:e943147644a8cf0d82d1bcb5c5867dd517495254cea3e3eb058b1e421cb7561f + # via ibis-framework +partd==1.4.2 \ + --hash=sha256:978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f \ + --hash=sha256:d022c33afbdc8405c226621b015e8067888173d85f7f5ecebb3cafed9a20f02c + # via dask +pbr==7.0.3 \ + --hash=sha256:b46004ec30a5324672683ec848aed9e8fc500b0d261d40a3229c2d2bbfcedc29 \ + --hash=sha256:ff223894eb1cd271a98076b13d3badff3bb36c424074d26334cd25aebeecea6b + # via mock +pexpect==4.9.0 \ + --hash=sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523 \ + --hash=sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f + # via ipython +pillow==11.3.0 \ + --hash=sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2 \ + --hash=sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214 \ + --hash=sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e \ + --hash=sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59 \ + --hash=sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50 \ + --hash=sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632 \ + --hash=sha256:092c80c76635f5ecb10f3f83d76716165c96f5229addbd1ec2bdbbda7d496e06 \ + --hash=sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a \ + --hash=sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51 \ + --hash=sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced \ + --hash=sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f \ + --hash=sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12 \ + --hash=sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8 \ + --hash=sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6 \ + --hash=sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580 \ + --hash=sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f \ + --hash=sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac \ + --hash=sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860 \ + --hash=sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd \ + --hash=sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722 \ + --hash=sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8 \ + --hash=sha256:23cff760a9049c502721bdb743a7cb3e03365fafcdfc2ef9784610714166e5a4 \ + --hash=sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673 \ + --hash=sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788 \ + --hash=sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542 \ + --hash=sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e \ + --hash=sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd \ + --hash=sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8 \ + --hash=sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523 \ + --hash=sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967 \ + --hash=sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809 \ + --hash=sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477 \ + --hash=sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027 \ + --hash=sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae \ + --hash=sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b \ + --hash=sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c \ + --hash=sha256:48d254f8a4c776de343051023eb61ffe818299eeac478da55227d96e241de53f \ + --hash=sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e \ + --hash=sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b \ + --hash=sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7 \ + --hash=sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27 \ + --hash=sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361 \ + --hash=sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae \ + --hash=sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d \ + --hash=sha256:6359a3bc43f57d5b375d1ad54a0074318a0844d11b76abccf478c37c986d3cfc \ + --hash=sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58 \ + --hash=sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad \ + --hash=sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6 \ + --hash=sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024 \ + --hash=sha256:6a418691000f2a418c9135a7cf0d797c1bb7d9a485e61fe8e7722845b95ef978 \ + --hash=sha256:6abdbfd3aea42be05702a8dd98832329c167ee84400a1d1f61ab11437f1717eb \ + --hash=sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d \ + --hash=sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0 \ + --hash=sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9 \ + --hash=sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f \ + --hash=sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874 \ + --hash=sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa \ + --hash=sha256:7aee118e30a4cf54fdd873bd3a29de51e29105ab11f9aad8c32123f58c8f8081 \ + --hash=sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149 \ + --hash=sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6 \ + --hash=sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d \ + --hash=sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd \ + --hash=sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f \ + --hash=sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c \ + --hash=sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31 \ + --hash=sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e \ + --hash=sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db \ + --hash=sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6 \ + --hash=sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f \ + --hash=sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494 \ + --hash=sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69 \ + --hash=sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94 \ + --hash=sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77 \ + --hash=sha256:97afb3a00b65cc0804d1c7abddbf090a81eaac02768af58cbdcaaa0a931e0b6d \ + --hash=sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7 \ + --hash=sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a \ + --hash=sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438 \ + --hash=sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288 \ + --hash=sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b \ + --hash=sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635 \ + --hash=sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3 \ + --hash=sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d \ + --hash=sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe \ + --hash=sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0 \ + --hash=sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe \ + --hash=sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a \ + --hash=sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805 \ + --hash=sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8 \ + --hash=sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36 \ + --hash=sha256:cadc9e0ea0a2431124cde7e1697106471fc4c1da01530e679b2391c37d3fbb3a \ + --hash=sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b \ + --hash=sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e \ + --hash=sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25 \ + --hash=sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12 \ + --hash=sha256:e5c5858ad8ec655450a7c7df532e9842cf8df7cc349df7225c60d5d348c8aada \ + --hash=sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c \ + --hash=sha256:ea944117a7974ae78059fcc1800e5d3295172bb97035c0c1d9345fca1419da71 \ + --hash=sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d \ + --hash=sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c \ + --hash=sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6 \ + --hash=sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1 \ + --hash=sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50 \ + --hash=sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653 \ + --hash=sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c \ + --hash=sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4 \ + --hash=sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3 + # via + # feast (setup.py) + # docling + # docling-core + # docling-ibm-models + # docling-parse + # easyocr + # imageio + # python-pptx + # scikit-image + # torchvision +pip==25.3 \ + --hash=sha256:8d0538dbbd7babbd207f261ed969c65de439f6bc9e5dbd3b3b9a77f25d95f343 \ + --hash=sha256:9655943313a94722b7774661c21049070f6bbb0a1516bf02f7c8d5d9201514cd + # via pip-tools +pip-tools==7.5.2 \ + --hash=sha256:2d64d72da6a044da1110257d333960563d7a4743637e8617dd2610ae7b82d60f \ + --hash=sha256:2fe16db727bbe5bf28765aeb581e792e61be51fc275545ef6725374ad720a1ce + # via feast (setup.py) +platformdirs==3.11.0 \ + --hash=sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3 \ + --hash=sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e + # via + # jupyter-core + # snowflake-connector-python + # virtualenv +pluggy==1.6.0 \ + --hash=sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3 \ + --hash=sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 + # via + # docling + # pytest + # pytest-cov +ply==3.11 \ + --hash=sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3 \ + --hash=sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce + # via thriftpy2 +poetry-core==1.9.1 \ + --hash=sha256:6f45dd3598e0de8d9b0367360253d4c5d4d0110c8f5c71120a14f0e0f116c1a0 \ + --hash=sha256:7a2d49214bf58b4f17f99d6891d947a9836c9899a67a5069f52d7b67217f61b8 + # via feast (setup.py) +poetry-dynamic-versioning==1.9.1 \ + --hash=sha256:65a0c814e6d30d4807734a3c34edf261fd7cc3b340dbd23b6a33ee41f7d0b547 \ + --hash=sha256:d6e7b9df817aa2ca4946cd695c6c89e1379d2e6c640f008a9b6170d081a9da48 + # via feast (setup.py) +portalocker==3.2.0 \ + --hash=sha256:1f3002956a54a8c3730586c5c77bf18fae4149e07eaf1c29fc3faf4d5a3f89ac \ + --hash=sha256:3cdc5f565312224bc570c49337bd21428bba0ef363bbcf58b9ef4a9f11779968 + # via qdrant-client +pre-commit==3.3.1 \ + --hash=sha256:218e9e3f7f7f3271ebc355a15598a4d3893ad9fc7b57fe446db75644543323b9 \ + --hash=sha256:733f78c9a056cdd169baa6cd4272d51ecfda95346ef8a89bf93712706021b907 + # via feast (setup.py) +prometheus-client==0.24.1 \ + --hash=sha256:150db128af71a5c2482b36e588fc8a6b95e498750da4b17065947c16070f4055 \ + --hash=sha256:7e0ced7fbbd40f7b84962d5d2ab6f17ef88a72504dcf7c0b40737b43b2a461f9 + # via + # feast (setup.py) + # jupyter-server + # opentelemetry-exporter-prometheus + # ray +prompt-toolkit==3.0.52 \ + --hash=sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855 \ + --hash=sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955 + # via ipython +propcache==0.4.1 \ + --hash=sha256:0002004213ee1f36cfb3f9a42b5066100c44276b9b72b4e1504cddd3d692e86e \ + --hash=sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4 \ + --hash=sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be \ + --hash=sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3 \ + --hash=sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85 \ + --hash=sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b \ + --hash=sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367 \ + --hash=sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf \ + --hash=sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393 \ + --hash=sha256:182b51b421f0501952d938dc0b0eb45246a5b5153c50d42b495ad5fb7517c888 \ + --hash=sha256:1cdb7988c4e5ac7f6d175a28a9aa0c94cb6f2ebe52756a3c0cda98d2809a9e37 \ + --hash=sha256:1eb2994229cc8ce7fe9b3db88f5465f5fd8651672840b2e426b88cdb1a30aac8 \ + --hash=sha256:1f0978529a418ebd1f49dad413a2b68af33f85d5c5ca5c6ca2a3bed375a7ac60 \ + --hash=sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1 \ + --hash=sha256:296f4c8ed03ca7476813fe666c9ea97869a8d7aec972618671b33a38a5182ef4 \ + --hash=sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717 \ + --hash=sha256:2b16ec437a8c8a965ecf95739448dd938b5c7f56e67ea009f4300d8df05f32b7 \ + --hash=sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc \ + --hash=sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe \ + --hash=sha256:357f5bb5c377a82e105e44bd3d52ba22b616f7b9773714bff93573988ef0a5fb \ + --hash=sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75 \ + --hash=sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6 \ + --hash=sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e \ + --hash=sha256:3d233076ccf9e450c8b3bc6720af226b898ef5d051a2d145f7d765e6e9f9bcff \ + --hash=sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566 \ + --hash=sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12 \ + --hash=sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367 \ + --hash=sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874 \ + --hash=sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf \ + --hash=sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566 \ + --hash=sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a \ + --hash=sha256:4b536b39c5199b96fc6245eb5fb796c497381d3942f169e44e8e392b29c9ebcc \ + --hash=sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a \ + --hash=sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1 \ + --hash=sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6 \ + --hash=sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61 \ + --hash=sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726 \ + --hash=sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49 \ + --hash=sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44 \ + --hash=sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af \ + --hash=sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa \ + --hash=sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153 \ + --hash=sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc \ + --hash=sha256:5d4e2366a9c7b837555cf02fb9be2e3167d333aff716332ef1b7c3a142ec40c5 \ + --hash=sha256:5fd37c406dd6dc85aa743e214cef35dc54bbdd1419baac4f6ae5e5b1a2976938 \ + --hash=sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf \ + --hash=sha256:66c1f011f45a3b33d7bcb22daed4b29c0c9e2224758b6be00686731e1b46f925 \ + --hash=sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8 \ + --hash=sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c \ + --hash=sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85 \ + --hash=sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e \ + --hash=sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0 \ + --hash=sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1 \ + --hash=sha256:71b749281b816793678ae7f3d0d84bd36e694953822eaad408d682efc5ca18e0 \ + --hash=sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992 \ + --hash=sha256:7c2d1fa3201efaf55d730400d945b5b3ab6e672e100ba0f9a409d950ab25d7db \ + --hash=sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f \ + --hash=sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d \ + --hash=sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1 \ + --hash=sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e \ + --hash=sha256:8c9b3cbe4584636d72ff556d9036e0c9317fa27b3ac1f0f558e7e84d1c9c5900 \ + --hash=sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89 \ + --hash=sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a \ + --hash=sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b \ + --hash=sha256:948dab269721ae9a87fd16c514a0a2c2a1bdb23a9a61b969b0f9d9ee2968546f \ + --hash=sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f \ + --hash=sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1 \ + --hash=sha256:99d43339c83aaf4d32bda60928231848eee470c6bda8d02599cc4cebe872d183 \ + --hash=sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66 \ + --hash=sha256:9a52009f2adffe195d0b605c25ec929d26b36ef986ba85244891dee3b294df21 \ + --hash=sha256:9d2b6caef873b4f09e26ea7e33d65f42b944837563a47a94719cc3544319a0db \ + --hash=sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded \ + --hash=sha256:a0ee98db9c5f80785b266eb805016e36058ac72c51a064040f2bc43b61101cdb \ + --hash=sha256:a129e76735bc792794d5177069691c3217898b9f5cee2b2661471e52ffe13f19 \ + --hash=sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0 \ + --hash=sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165 \ + --hash=sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778 \ + --hash=sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455 \ + --hash=sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f \ + --hash=sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b \ + --hash=sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237 \ + --hash=sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81 \ + --hash=sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859 \ + --hash=sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c \ + --hash=sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835 \ + --hash=sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393 \ + --hash=sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5 \ + --hash=sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641 \ + --hash=sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144 \ + --hash=sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74 \ + --hash=sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db \ + --hash=sha256:cbc3b6dfc728105b2a57c06791eb07a94229202ea75c59db644d7d496b698cac \ + --hash=sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403 \ + --hash=sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9 \ + --hash=sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f \ + --hash=sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311 \ + --hash=sha256:d82ad62b19645419fe79dd63b3f9253e15b30e955c0170e5cebc350c1844e581 \ + --hash=sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36 \ + --hash=sha256:daede9cd44e0f8bdd9e6cc9a607fc81feb80fae7a5fc6cecaff0e0bb32e42d00 \ + --hash=sha256:db65d2af507bbfbdcedb254a11149f894169d90488dd3e7190f7cdcb2d6cd57a \ + --hash=sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f \ + --hash=sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2 \ + --hash=sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7 \ + --hash=sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239 \ + --hash=sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757 \ + --hash=sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72 \ + --hash=sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9 \ + --hash=sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4 \ + --hash=sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24 \ + --hash=sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207 \ + --hash=sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e \ + --hash=sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1 \ + --hash=sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d \ + --hash=sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37 \ + --hash=sha256:f93243fdc5657247533273ac4f86ae106cc6445a0efacb9a1bfe982fcfefd90c \ + --hash=sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e \ + --hash=sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570 \ + --hash=sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af \ + --hash=sha256:fd138803047fb4c062b1c1dd95462f5209456bfab55c734458f15d11da288f8f \ + --hash=sha256:fd2dbc472da1f772a4dae4fa24be938a6c544671a912e30529984dd80400cd88 \ + --hash=sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48 \ + --hash=sha256:fe49d0a85038f36ba9e3ffafa1103e61170b28e95b16622e11be0a0ea07c6781 + # via + # aiohttp + # yarl +proto-plus==1.27.0 \ + --hash=sha256:1baa7f81cf0f8acb8bc1f6d085008ba4171eaf669629d1b6d1673b21ed1c0a82 \ + --hash=sha256:873af56dd0d7e91836aee871e5799e1c6f1bda86ac9a983e0bb9f0c266a568c4 + # via + # google-api-core + # google-cloud-bigquery-storage + # google-cloud-bigtable + # google-cloud-datastore +protobuf==4.25.8 \ + --hash=sha256:077ff8badf2acf8bc474406706ad890466274191a48d0abd3bd6987107c9cde5 \ + --hash=sha256:15a0af558aa3b13efef102ae6e4f3efac06f1eea11afb3a57db2901447d9fb59 \ + --hash=sha256:27d498ffd1f21fb81d987a041c32d07857d1d107909f5134ba3350e1ce80a4af \ + --hash=sha256:504435d831565f7cfac9f0714440028907f1975e4bed228e58e72ecfff58a1e0 \ + --hash=sha256:6135cf8affe1fc6f76cced2641e4ea8d3e59518d1f24ae41ba97bcad82d397cd \ + --hash=sha256:83e6e54e93d2b696a92cad6e6efc924f3850f82b52e1563778dfab8b355101b0 \ + --hash=sha256:9ad7ef62d92baf5a8654fbb88dac7fa5594cfa70fd3440488a5ca3bfc6d795a7 \ + --hash=sha256:bd551eb1fe1d7e92c1af1d75bdfa572eff1ab0e5bf1736716814cdccdb2360f9 \ + --hash=sha256:ca809b42f4444f144f2115c4c1a747b9a404d590f18f37e9402422033e464e0f \ + --hash=sha256:d552c53d0415449c8d17ced5c341caba0d89dbf433698e1436c8fa0aae7808a3 \ + --hash=sha256:f4510b93a3bec6eba8fd8f1093e9d7fb0d4a24d1a81377c10c0e5bbfe9e4ed24 + # via + # feast (setup.py) + # google-api-core + # google-cloud-bigquery-storage + # google-cloud-bigtable + # google-cloud-datastore + # googleapis-common-protos + # grpc-google-iam-v1 + # grpcio-health-checking + # grpcio-reflection + # grpcio-status + # grpcio-testing + # grpcio-tools + # ikvpy + # mypy-protobuf + # opentelemetry-proto + # proto-plus + # pymilvus + # qdrant-client + # ray + # substrait +psutil==5.9.0 \ + --hash=sha256:072664401ae6e7c1bfb878c65d7282d4b4391f1bc9a56d5e03b5a490403271b5 \ + --hash=sha256:1070a9b287846a21a5d572d6dddd369517510b68710fca56b0e9e02fd24bed9a \ + --hash=sha256:1d7b433519b9a38192dfda962dd8f44446668c009833e1429a52424624f408b4 \ + --hash=sha256:3151a58f0fbd8942ba94f7c31c7e6b310d2989f4da74fcbf28b934374e9bf841 \ + --hash=sha256:32acf55cb9a8cbfb29167cd005951df81b567099295291bcfd1027365b36591d \ + --hash=sha256:3611e87eea393f779a35b192b46a164b1d01167c9d323dda9b1e527ea69d697d \ + --hash=sha256:3d00a664e31921009a84367266b35ba0aac04a2a6cad09c550a89041034d19a0 \ + --hash=sha256:4e2fb92e3aeae3ec3b7b66c528981fd327fb93fd906a77215200404444ec1845 \ + --hash=sha256:539e429da49c5d27d5a58e3563886057f8fc3868a5547b4f1876d9c0f007bccf \ + --hash=sha256:55ce319452e3d139e25d6c3f85a1acf12d1607ddedea5e35fb47a552c051161b \ + --hash=sha256:58c7d923dc209225600aec73aa2c4ae8ea33b1ab31bc11ef8a5933b027476f07 \ + --hash=sha256:7336292a13a80eb93c21f36bde4328aa748a04b68c13d01dfddd67fc13fd0618 \ + --hash=sha256:742c34fff804f34f62659279ed5c5b723bb0195e9d7bd9907591de9f8f6558e2 \ + --hash=sha256:7641300de73e4909e5d148e90cc3142fb890079e1525a840cf0dfd39195239fd \ + --hash=sha256:76cebf84aac1d6da5b63df11fe0d377b46b7b500d892284068bacccf12f20666 \ + --hash=sha256:7779be4025c540d1d65a2de3f30caeacc49ae7a2152108adeaf42c7534a115ce \ + --hash=sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3 \ + --hash=sha256:8293942e4ce0c5689821f65ce6522ce4786d02af57f13c0195b40e1edb1db61d \ + --hash=sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25 \ + --hash=sha256:90a58b9fcae2dbfe4ba852b57bd4a1dded6b990a33d6428c7614b7d48eccb492 \ + --hash=sha256:9b51917c1af3fa35a3f2dabd7ba96a2a4f19df3dec911da73875e1edaf22a40b \ + --hash=sha256:b2237f35c4bbae932ee98902a08050a27821f8f6dfa880a47195e5993af4702d \ + --hash=sha256:c3400cae15bdb449d518545cbd5b649117de54e3596ded84aacabfbb3297ead2 \ + --hash=sha256:c51f1af02334e4b516ec221ee26b8fdf105032418ca5a5ab9737e8c87dafe203 \ + --hash=sha256:cb8d10461c1ceee0c25a64f2dd54872b70b89c26419e147a05a10b753ad36ec2 \ + --hash=sha256:d62a2796e08dd024b8179bd441cb714e0f81226c352c802fca0fd3f89eeacd94 \ + --hash=sha256:df2c8bd48fb83a8408c8390b143c6a6fa10cb1a674ca664954de193fdcab36a9 \ + --hash=sha256:e5c783d0b1ad6ca8a5d3e7b680468c9c926b804be83a3a8e95141b05c39c9f64 \ + --hash=sha256:e9805fed4f2a81de98ae5fe38b75a74c6e6ad2df8a5c479594c7629a1fe35f56 \ + --hash=sha256:ea42d747c5f71b5ccaa6897b216a7dadb9f52c72a0fe2b872ef7d3e1eacf3ba3 \ + --hash=sha256:ef216cc9feb60634bda2f341a9559ac594e2eeaadd0ba187a4c2eb5b5d40b91c \ + --hash=sha256:ff0d41f8b3e9ebb6b6110057e40019a432e96aae2008951121ba4e56040b84f3 + # via + # feast (setup.py) + # accelerate + # ipykernel +psycopg[binary, pool]==3.2.5 \ + --hash=sha256:b782130983e5b3de30b4c529623d3687033b4dafa05bb661fc6bf45837ca5879 \ + --hash=sha256:f5f750611c67cb200e85b408882f29265c66d1de7f813add4f8125978bfd70e8 + # via feast (setup.py) +psycopg-binary==3.2.5 \ + --hash=sha256:02fb96091e2fb3ea1470b113fef08953baaedbca1d39a3f72d82cb615177846c \ + --hash=sha256:11e3ed8b94c750d54fc3e4502dd930fb0fd041629845b6a7ce089873ac9756b0 \ + --hash=sha256:1494827c43265820d5dcdc6f8086521bc7dd04b9da8831310978a788cdcd2e62 \ + --hash=sha256:21b839f9bfd77ed074f7f71464a43f453400c57d038a0ba0716329a28e335897 \ + --hash=sha256:23a1dc61abb8f7cc702472ab29554167a9421842f976c201ceb3b722c0299769 \ + --hash=sha256:274e852f9e61252bc8e80a0a43d300ba352d40219e856733054023a3bb960eb4 \ + --hash=sha256:28bd5cb2324567e5e70f07fe1d646398d6b0e210e28b49be0e69593590a59980 \ + --hash=sha256:2b053eae21dd3a6828b516a1171e1274d1af5f7c07d2d9a8f597f2e19c732168 \ + --hash=sha256:2cbb8649cfdacbd14e17f5ab78edc52d33350013888518c73e90c5d17d7bea55 \ + --hash=sha256:2cc86657c05e09c701e97f87132cd58e0d55381dd568520081ac1fe7580a9bbb \ + --hash=sha256:2d10ce4c39eb9631381a0c3792727946a4391e843625a7ee9579ac6bb11495a5 \ + --hash=sha256:2d22a15e45f43d36ed35aed4d5261f8ef6ab7d9b84ee075576ca56ae03b9e0aa \ + --hash=sha256:2dbaf32c18c0d11c4480016b89c9c5cadb7b64c55de7f181d222b189bd13a558 \ + --hash=sha256:32b5673736f04c36ccbf8012800fe5bc01b46dac22c5d59e41b043bebaad9d3d \ + --hash=sha256:375149006e21d58ed8aba640e0295d8e636043064c433af94eb58057f9b96877 \ + --hash=sha256:393ab353196d364858b47317d27804ecc58ab56dbde32217bd67f0f2f2980662 \ + --hash=sha256:39e2cd10bf15442d95c3f48376b25dc33360418ea6c3c05884d8bf42407768c0 \ + --hash=sha256:3d2e57a1d06f3968e49e948ba374f21a7d8dcf44f37d582a4aeddeb7c85ce239 \ + --hash=sha256:3eb71cfc35116e4a8e336b7e785f1fe06ca23b4516a48ea91facd577d1a1fdf6 \ + --hash=sha256:3f893c0ed3d5c7b83b76b1f8f7d3ca5a03e38bcd3cab5d65b5c25a0d1064aca4 \ + --hash=sha256:473f6827cf1faf3924eb77146d1e85126a1b5e48a88053b8d8b78dd29e971d78 \ + --hash=sha256:48f97936145cb7de18b95d85670b2d3e2c257277263272be05815b74fb0ef195 \ + --hash=sha256:48fcb12a0a72fdfe4102bdb1252a7366e8d73a2c89fe6ce5923be890de367c2f \ + --hash=sha256:4914dc60f2fddf0884464985e31d775aa865b665471fa156ec2f56fa72a1a097 \ + --hash=sha256:51a96d9fe51f718912b4a0089784f1f32d800217499fd0f0095b888506aba4c5 \ + --hash=sha256:5244bebaa9734a236b7157fb57c065b6c0f2344281916187bd73f951df1899e0 \ + --hash=sha256:5b81342e139ddccfa417832089cd213bd4beacd7a1462ca4019cafe71682d177 \ + --hash=sha256:5d2253189aa4cca0a425e2ca896d1a29760cd3a2b10ab12194e4e827a566505c \ + --hash=sha256:5fd017d7ed71c58f19b0f614e7bfb8f01ec862bacb67ae584f494d090956102e \ + --hash=sha256:605f70e267222d567fc40de7813ee3fb29f8145a1a20aa6fd3dc62baba9312f1 \ + --hash=sha256:60d0f36a42a822e43c4c7472df8a0c980c0f32e5d74ed871333c423a4e942f11 \ + --hash=sha256:62965045cc0fe3dc5dd55d39779620b225ef75962825c7b1b533033cb91810bd \ + --hash=sha256:65162a9cc3f86d70b1d895dbda506e3c079f80d082eb41c54d3f6d33a00b3965 \ + --hash=sha256:659f2c675d478b1bc01b95a8d3ded74fa939b370e71ffbecd496f617b215eb05 \ + --hash=sha256:6b581da13126b8715c0c0585cd37ce934c9864d44b2a4019f5487c0b943275e6 \ + --hash=sha256:71d82dbc7c6c7f5746468e7992e5483aa45b12250d78d220a2431ab88795825c \ + --hash=sha256:7376b13504396da9678b646f5338462347da01286b2a688a0d8493ec764683a2 \ + --hash=sha256:7623659d44a6aa032be4a066c658ba45009d768c2481526fbef7c609702af116 \ + --hash=sha256:7a94020821723a6a210206ddb458001f3ed27e1e6a0555b9422bebf7ead8ff37 \ + --hash=sha256:7d5f1bfc848a94e0d63fe693adee4f88bd9e5c415ecb4c9c17d2d44eba6795a6 \ + --hash=sha256:7efe6c732fd2d7e22d72dc4f7cf9b644020adacfff61b0a8a151343da8e661c0 \ + --hash=sha256:8a602d9fdb567cca090ca19ac3ebf10219065be2a4f8cf9eb8356cffb5a7ab1d \ + --hash=sha256:8cd9ebf335262e864d740f9dad3f672f61162cc0d4825a5eb5cf50df334a688f \ + --hash=sha256:8e6f2bef5aed021fbdf46323d3cd8847bf960efb56394698644a8ee2306f8892 \ + --hash=sha256:93221d5a759bd39b1face1d7d887d2b9ede3e55aefaff8eacf1b663ccdcd204b \ + --hash=sha256:9639289b72f9339721982e156527c296693236d6192ccc31412ab36fccd1683c \ + --hash=sha256:98efaedf2bf79f4d563ca039a57a025b72847bd80568f54709cc39fc1404772c \ + --hash=sha256:9abe093a303e25ac58774a11241150e2fe2947358d1ca12521ad03c90b131060 \ + --hash=sha256:a4321ee8180982d70458d3e8378e31448901bf0ee40fe0d410a87413578f4098 \ + --hash=sha256:a82211a43372cba9b1555a110e84e679deec2dc9463ae4c736977dad99dca5ed \ + --hash=sha256:a91b0e096fdfeb52d86bb8f5ee25dc22483d6960af9b968e6b381a8ec5bfbf82 \ + --hash=sha256:b5e0acbc991472188c9df40eb56d8a97ad3ad00d4de560b8b74bdc2d94041a8f \ + --hash=sha256:b6b5a4542aca4095ab35e184517cb0d18895ba4b6661c92865b431fa7b7974d8 \ + --hash=sha256:ba4a610882171bdaae0779f14e0ff45f3ee271fd2dbf16cdadfc81bd67323232 \ + --hash=sha256:bc5bd9bf5f5894923b78a41c5becd52d6bced1e1e43744855bd85cb341376ca6 \ + --hash=sha256:c37eb3be7a6be93f4925ccf52bbfa60244da6c63201770a709dd81a3d2d08534 \ + --hash=sha256:c3c5fa3d4fa0a651cefab391b783f89bc5e331afa0a4e93c9b16141993fa05c8 \ + --hash=sha256:ca5e36a3e7480a5c09aed99ecdb8e6554b21485c3b064297fe77f7b1b5806106 \ + --hash=sha256:d4e0c1b1aa5283f6d9a384ffc7a8400d25386bb98fdb9bddae446e4ef4da7366 \ + --hash=sha256:dc8bc40d82d1ee8dec136e10707c7f3147a6322fd8014e174a0f3446fb793649 \ + --hash=sha256:de576c49d7deab2b78088feb24e1f6ae3e16a0020e8496cdd3b8543f5e350e87 \ + --hash=sha256:e7d215a43343d91ba08301865f059d9518818d66a222a85fb425e4156716f5a6 \ + --hash=sha256:eb8293d66c6a4ddc72fceb7ad0e111cb196cc394954ae0f9b63c251d97f1b00e \ + --hash=sha256:ee6d8f489a9b116ea8dc797664a50671585a4ca20573359f067858e1231cc217 \ + --hash=sha256:efb878d08dd49d7d9d18512e791b418a1171d08f935475eec98305f0886b7c14 + # via psycopg +psycopg-pool==3.3.0 \ + --hash=sha256:2e44329155c410b5e8666372db44276a8b1ebd8c90f1c3026ebba40d4bc81063 \ + --hash=sha256:fa115eb2860bd88fce1717d75611f41490dec6135efb619611142b24da3f6db5 + # via psycopg +ptyprocess==0.7.0 \ + --hash=sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35 \ + --hash=sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220 + # via + # pexpect + # terminado +pure-eval==0.2.3 \ + --hash=sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0 \ + --hash=sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42 + # via stack-data +py==1.11.0 \ + --hash=sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719 \ + --hash=sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378 + # via feast (setup.py) +py-cpuinfo==9.0.0 \ + --hash=sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690 \ + --hash=sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5 + # via pytest-benchmark +py-spy==0.4.1 \ + --hash=sha256:1fb8bf71ab8df95a95cc387deed6552934c50feef2cf6456bc06692a5508fd0c \ + --hash=sha256:4972c21890b6814017e39ac233c22572c4a61fd874524ebc5ccab0f2237aee0a \ + --hash=sha256:532d3525538254d1859b49de1fbe9744df6b8865657c9f0e444bf36ce3f19226 \ + --hash=sha256:6a80ec05eb8a6883863a367c6a4d4f2d57de68466f7956b6367d4edd5c61bb29 \ + --hash=sha256:809094208c6256c8f4ccadd31e9a513fe2429253f48e20066879239ba12cd8cc \ + --hash=sha256:d92e522bd40e9bf7d87c204033ce5bb5c828fca45fa28d970f58d71128069fdc \ + --hash=sha256:e53aa53daa2e47c2eef97dd2455b47bb3a7e7f962796a86cc3e7dbde8e6f4db4 \ + --hash=sha256:ee776b9d512a011d1ad3907ed53ae32ce2f3d9ff3e1782236554e22103b5c084 + # via ray +py4j==0.10.9.9 \ + --hash=sha256:c7c26e4158defb37b0bb124933163641a2ff6e3a3913f7811b0ddbe07ed61533 \ + --hash=sha256:f694cad19efa5bd1dee4f3e5270eb406613c974394035e5bfc4ec1aba870b879 + # via pyspark +pyarrow==17.0.0 \ + --hash=sha256:0071ce35788c6f9077ff9ecba4858108eebe2ea5a3f7cf2cf55ebc1dbc6ee24a \ + --hash=sha256:02dae06ce212d8b3244dd3e7d12d9c4d3046945a5933d28026598e9dbbda1fca \ + --hash=sha256:0b72e87fe3e1db343995562f7fff8aee354b55ee83d13afba65400c178ab2597 \ + --hash=sha256:0cdb0e627c86c373205a2f94a510ac4376fdc523f8bb36beab2e7f204416163c \ + --hash=sha256:13d7a460b412f31e4c0efa1148e1d29bdf18ad1411eb6757d38f8fbdcc8645fb \ + --hash=sha256:1c8856e2ef09eb87ecf937104aacfa0708f22dfeb039c363ec99735190ffb977 \ + --hash=sha256:2e19f569567efcbbd42084e87f948778eb371d308e137a0f97afe19bb860ccb3 \ + --hash=sha256:32503827abbc5aadedfa235f5ece8c4f8f8b0a3cf01066bc8d29de7539532687 \ + --hash=sha256:392bc9feabc647338e6c89267635e111d71edad5fcffba204425a7c8d13610d7 \ + --hash=sha256:42bf93249a083aca230ba7e2786c5f673507fa97bbd9725a1e2754715151a204 \ + --hash=sha256:4beca9521ed2c0921c1023e68d097d0299b62c362639ea315572a58f3f50fd28 \ + --hash=sha256:5984f416552eea15fd9cee03da53542bf4cddaef5afecefb9aa8d1010c335087 \ + --hash=sha256:6b244dc8e08a23b3e352899a006a26ae7b4d0da7bb636872fa8f5884e70acf15 \ + --hash=sha256:757074882f844411fcca735e39aae74248a1531367a7c80799b4266390ae51cc \ + --hash=sha256:75c06d4624c0ad6674364bb46ef38c3132768139ddec1c56582dbac54f2663e2 \ + --hash=sha256:7c7916bff914ac5d4a8fe25b7a25e432ff921e72f6f2b7547d1e325c1ad9d155 \ + --hash=sha256:9b564a51fbccfab5a04a80453e5ac6c9954a9c5ef2890d1bcf63741909c3f8df \ + --hash=sha256:9b8a823cea605221e61f34859dcc03207e52e409ccf6354634143e23af7c8d22 \ + --hash=sha256:9ba11c4f16976e89146781a83833df7f82077cdab7dc6232c897789343f7891a \ + --hash=sha256:a155acc7f154b9ffcc85497509bcd0d43efb80d6f733b0dc3bb14e281f131c8b \ + --hash=sha256:a27532c38f3de9eb3e90ecab63dfda948a8ca859a66e3a47f5f42d1e403c4d03 \ + --hash=sha256:a48ddf5c3c6a6c505904545c25a4ae13646ae1f8ba703c4df4a1bfe4f4006bda \ + --hash=sha256:a5c8b238d47e48812ee577ee20c9a2779e6a5904f1708ae240f53ecbee7c9f07 \ + --hash=sha256:af5ff82a04b2171415f1410cff7ebb79861afc5dae50be73ce06d6e870615204 \ + --hash=sha256:b0c6ac301093b42d34410b187bba560b17c0330f64907bfa4f7f7f2444b0cf9b \ + --hash=sha256:d7d192305d9d8bc9082d10f361fc70a73590a4c65cf31c3e6926cd72b76bc35c \ + --hash=sha256:da1e060b3876faa11cee287839f9cc7cdc00649f475714b8680a05fd9071d545 \ + --hash=sha256:db023dc4c6cae1015de9e198d41250688383c3f9af8f565370ab2b4cb5f62655 \ + --hash=sha256:dc5c31c37409dfbc5d014047817cb4ccd8c1ea25d19576acf1a001fe07f5b420 \ + --hash=sha256:dec8d129254d0188a49f8a1fc99e0560dc1b85f60af729f47de4046015f9b0a5 \ + --hash=sha256:e3343cb1e88bc2ea605986d4b94948716edc7a8d14afd4e2c097232f729758b4 \ + --hash=sha256:edca18eaca89cd6382dfbcff3dd2d87633433043650c07375d095cd3517561d8 \ + --hash=sha256:f1e70de6cb5790a50b01d2b686d54aaf73da01266850b05e3af2a1bc89e16053 \ + --hash=sha256:f553ca691b9e94b202ff741bdd40f6ccb70cdd5fbf65c187af132f1317de6145 \ + --hash=sha256:f7ae2de664e0b158d1607699a16a488de3d008ba99b3a7aa5de1cbc13574d047 \ + --hash=sha256:fa3c246cc58cb5a4a5cb407a18f193354ea47dd0648194e6265bd24177982fe8 + # via + # feast (setup.py) + # dask + # datasets + # db-dtypes + # deltalake + # google-cloud-bigquery + # ibis-framework + # pandas-gbq + # ray + # snowflake-connector-python +pyarrow-hotfix==0.7 \ + --hash=sha256:3236f3b5f1260f0e2ac070a55c1a7b339c4bb7267839bd2015e283234e758100 \ + --hash=sha256:59399cd58bdd978b2e42816a4183a55c6472d4e33d183351b6069f11ed42661d + # via ibis-framework +pyasn1==0.6.2 \ + --hash=sha256:1eb26d860996a18e9b6ed05e7aae0e9fc21619fcee6af91cca9bad4fbea224bf \ + --hash=sha256:9b59a2b25ba7e4f8197db7686c09fb33e658b98339fadb826e9512629017833b + # via + # pyasn1-modules + # rsa +pyasn1-modules==0.4.2 \ + --hash=sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a \ + --hash=sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6 + # via google-auth +pybindgen==0.22.0 \ + --hash=sha256:21612f4806a2af25a175716d7e694563af7e10c704538a350cb595d187952f6f \ + --hash=sha256:5b4837d3138ac56863d93fe462f1dac39fb87bd50898e0da4c57fefd645437ac + # via feast (setup.py) +pyclipper==1.4.0 \ + --hash=sha256:0a4d2736fb3c42e8eb1d38bf27a720d1015526c11e476bded55138a977c17d9d \ + --hash=sha256:0b74a9dd44b22a7fd35d65fb1ceeba57f3817f34a97a28c3255556362e491447 \ + --hash=sha256:0b8c2105b3b3c44dbe1a266f64309407fe30bf372cf39a94dc8aaa97df00da5b \ + --hash=sha256:14c8bdb5a72004b721c4e6f448d2c2262d74a7f0c9e3076aeff41e564a92389f \ + --hash=sha256:1b6c8d75ba20c6433c9ea8f1a0feb7e4d3ac06a09ad1fd6d571afc1ddf89b869 \ + --hash=sha256:222ac96c8b8281b53d695b9c4fedc674f56d6d4320ad23f1bdbd168f4e316140 \ + --hash=sha256:29dae3e0296dff8502eeb7639fcfee794b0eec8590ba3563aee28db269da6b04 \ + --hash=sha256:37bfec361e174110cdddffd5ecd070a8064015c99383d95eb692c253951eee8a \ + --hash=sha256:3ef44b64666ebf1cb521a08a60c3e639d21b8c50bfbe846ba7c52a0415e936f4 \ + --hash=sha256:58e29d7443d7cc0e83ee9daf43927730386629786d00c63b04fe3b53ac01462c \ + --hash=sha256:6a97b961f182b92d899ca88c1bb3632faea2e00ce18d07c5f789666ebb021ca4 \ + --hash=sha256:6c317e182590c88ec0194149995e3d71a979cfef3b246383f4e035f9d4a11826 \ + --hash=sha256:773c0e06b683214dcfc6711be230c83b03cddebe8a57eae053d4603dd63582f9 \ + --hash=sha256:7c87480fc91a5af4c1ba310bdb7de2f089a3eeef5fe351a3cedc37da1fcced1c \ + --hash=sha256:81d8bb2d1fb9d66dc7ea4373b176bb4b02443a7e328b3b603a73faec088b952e \ + --hash=sha256:8d42b07a2f6cfe2d9b87daf345443583f00a14e856927782fde52f3a255e305a \ + --hash=sha256:9882bd889f27da78add4dd6f881d25697efc740bf840274e749988d25496c8e1 \ + --hash=sha256:98b2a40f98e1fc1b29e8a6094072e7e0c7dfe901e573bf6cfc6eb7ce84a7ae87 \ + --hash=sha256:9bc45f2463d997848450dbed91c950ca37c6cf27f84a49a5cad4affc0b469e39 \ + --hash=sha256:a8d2b5fb75ebe57e21ce61e79a9131edec2622ff23cc665e4d1d1f201bc1a801 \ + --hash=sha256:a9f11ad133257c52c40d50de7a0ca3370a0cdd8e3d11eec0604ad3c34ba549e9 \ + --hash=sha256:adcb7ca33c5bdc33cd775e8b3eadad54873c802a6d909067a57348bcb96e7a2d \ + --hash=sha256:b3b3630051b53ad2564cb079e088b112dd576e3d91038338ad1cc7915e0f14dc \ + --hash=sha256:bafad70d2679c187120e8c44e1f9a8b06150bad8c0aecf612ad7dfbfa9510f73 \ + --hash=sha256:bbc827b77442c99deaeee26e0e7f172355ddb097a5e126aea206d447d3b26286 \ + --hash=sha256:c9a3faa416ff536cee93417a72bfb690d9dea136dc39a39dbbe1e5dadf108c9c \ + --hash=sha256:ce1f83c9a4e10ea3de1959f0ae79e9a5bd41346dff648fee6228ba9eaf8b3872 \ + --hash=sha256:d1e5498d883b706a4ce636247f0d830c6eb34a25b843a1b78e2c969754ca9037 \ + --hash=sha256:d1f807e2b4760a8e5c6d6b4e8c1d71ef52b7fe1946ff088f4fa41e16a881a5ca \ + --hash=sha256:d49df13cbb2627ccb13a1046f3ea6ebf7177b5504ec61bdef87d6a704046fd6e \ + --hash=sha256:d4b2d7c41086f1927d14947c563dfc7beed2f6c0d9af13c42fe3dcdc20d35832 \ + --hash=sha256:e9b973467d9c5fa9bc30bb6ac95f9f4d7c3d9fc25f6cf2d1cc972088e5955c01 \ + --hash=sha256:f160a2c6ba036f7eaf09f1f10f4fbfa734234af9112fb5187877efed78df9303 \ + --hash=sha256:f2a50c22c3a78cb4e48347ecf06930f61ce98cf9252f2e292aa025471e9d75b1 \ + --hash=sha256:f3672dbafbb458f1b96e1ee3e610d174acb5ace5bd2ed5d1252603bb797f2fc6 \ + --hash=sha256:fd24849d2b94ec749ceac7c34c9f01010d23b6e9d9216cf2238b8481160e703d + # via easyocr +pycparser==2.23 \ + --hash=sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2 \ + --hash=sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934 + # via cffi +pycryptodome==3.23.0 \ + --hash=sha256:0011f7f00cdb74879142011f95133274741778abba114ceca229adbf8e62c3e4 \ + --hash=sha256:11eeeb6917903876f134b56ba11abe95c0b0fd5e3330def218083c7d98bbcb3c \ + --hash=sha256:14e15c081e912c4b0d75632acd8382dfce45b258667aa3c67caf7a4d4c13f630 \ + --hash=sha256:156df9667ad9f2ad26255926524e1c136d6664b741547deb0a86a9acf5ea631f \ + --hash=sha256:187058ab80b3281b1de11c2e6842a357a1f71b42cb1e15bce373f3d238135c27 \ + --hash=sha256:257bb3572c63ad8ba40b89f6fc9d63a2a628e9f9708d31ee26560925ebe0210a \ + --hash=sha256:350ebc1eba1da729b35ab7627a833a1a355ee4e852d8ba0447fafe7b14504d56 \ + --hash=sha256:447700a657182d60338bab09fdb27518f8856aecd80ae4c6bdddb67ff5da44ef \ + --hash=sha256:45c69ad715ca1a94f778215a11e66b7ff989d792a4d63b68dc586a1da1392ff5 \ + --hash=sha256:4764e64b269fc83b00f682c47443c2e6e85b18273712b98aa43bcb77f8570477 \ + --hash=sha256:507dbead45474b62b2bbe318eb1c4c8ee641077532067fec9c1aa82c31f84886 \ + --hash=sha256:53ecbafc2b55353edcebd64bf5da94a2a2cdf5090a6915bcca6eca6cc452585a \ + --hash=sha256:573a0b3017e06f2cffd27d92ef22e46aa3be87a2d317a5abf7cc0e84e321bd75 \ + --hash=sha256:63dad881b99ca653302b2c7191998dd677226222a3f2ea79999aa51ce695f720 \ + --hash=sha256:64093fc334c1eccfd3933c134c4457c34eaca235eeae49d69449dc4728079339 \ + --hash=sha256:6501790c5b62a29fcb227bd6b62012181d886a767ce9ed03b303d1f22eb5c625 \ + --hash=sha256:67bd81fcbe34f43ad9422ee8fd4843c8e7198dd88dd3d40e6de42ee65fbe1490 \ + --hash=sha256:6fe8258e2039eceb74dfec66b3672552b6b7d2c235b2dfecc05d16b8921649a8 \ + --hash=sha256:763d1d74f56f031788e5d307029caef067febf890cd1f8bf61183ae142f1a77b \ + --hash=sha256:7ac1080a8da569bde76c0a104589c4f414b8ba296c0b3738cf39a466a9fb1818 \ + --hash=sha256:865d83c906b0fc6a59b510deceee656b6bc1c4fa0d82176e2b77e97a420a996a \ + --hash=sha256:89d4d56153efc4d81defe8b65fd0821ef8b2d5ddf8ed19df31ba2f00872b8002 \ + --hash=sha256:90460fc9e088ce095f9ee8356722d4f10f86e5be06e2354230a9880b9c549aae \ + --hash=sha256:93837e379a3e5fd2bb00302a47aee9fdf7940d83595be3915752c74033d17ca7 \ + --hash=sha256:954af0e2bd7cea83ce72243b14e4fb518b18f0c1649b576d114973e2073b273d \ + --hash=sha256:9a53a4fe5cb075075d515797d6ce2f56772ea7e6a1e5e4b96cf78a14bac3d265 \ + --hash=sha256:9a77627a330ab23ca43b48b130e202582e91cc69619947840ea4d2d1be21eb39 \ + --hash=sha256:a176b79c49af27d7f6c12e4b178b0824626f40a7b9fed08f712291b6d54bf566 \ + --hash=sha256:a7fc76bf273353dc7e5207d172b83f569540fc9a28d63171061c42e361d22353 \ + --hash=sha256:aa0698f65e5b570426fc31b8162ed4603b0c2841cbb9088e2b01641e3065915b \ + --hash=sha256:b34e8e11d97889df57166eda1e1ddd7676da5fcd4d71a0062a760e75060514b4 \ + --hash=sha256:c75b52aacc6c0c260f204cbdd834f76edc9fb0d8e0da9fbf8352ef58202564e2 \ + --hash=sha256:c8987bd3307a39bc03df5c8e0e3d8be0c4c3518b7f044b0f4c15d1aa78f52575 \ + --hash=sha256:ce64e84a962b63a47a592690bdc16a7eaf709d2c2697ababf24a0def566899a6 \ + --hash=sha256:cfb5cd445280c5b0a4e6187a7ce8de5a07b5f3f897f235caa11f1f435f182843 \ + --hash=sha256:d8e95564beb8782abfd9e431c974e14563a794a4944c29d6d3b7b5ea042110b4 \ + --hash=sha256:d97618c9c6684a97ef7637ba43bdf6663a2e2e77efe0f863cce97a76af396446 \ + --hash=sha256:ddb95b49df036ddd264a0ad246d1be5b672000f12d6961ea2c267083a5e19379 \ + --hash=sha256:dea827b4d55ee390dc89b2afe5927d4308a8b538ae91d9c6f7a5090f397af1aa \ + --hash=sha256:e3f2d0aaf8080bda0587d58fc9fe4766e012441e2eed4269a77de6aea981c8be \ + --hash=sha256:eb8f24adb74984aa0e5d07a2368ad95276cf38051fe2dc6605cbcf482e04f2a7 + # via minio +pydantic==2.12.5 \ + --hash=sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49 \ + --hash=sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d + # via + # feast (setup.py) + # codeflare-sdk + # docling + # docling-core + # docling-ibm-models + # docling-parse + # fastapi + # fastapi-mcp + # great-expectations + # mcp + # pydantic-settings + # qdrant-client + # ray +pydantic-core==2.41.5 \ + --hash=sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90 \ + --hash=sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740 \ + --hash=sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504 \ + --hash=sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84 \ + --hash=sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33 \ + --hash=sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c \ + --hash=sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0 \ + --hash=sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e \ + --hash=sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0 \ + --hash=sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a \ + --hash=sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34 \ + --hash=sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2 \ + --hash=sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3 \ + --hash=sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815 \ + --hash=sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14 \ + --hash=sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba \ + --hash=sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375 \ + --hash=sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf \ + --hash=sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963 \ + --hash=sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1 \ + --hash=sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808 \ + --hash=sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553 \ + --hash=sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1 \ + --hash=sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2 \ + --hash=sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5 \ + --hash=sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470 \ + --hash=sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2 \ + --hash=sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b \ + --hash=sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660 \ + --hash=sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c \ + --hash=sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093 \ + --hash=sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5 \ + --hash=sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594 \ + --hash=sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008 \ + --hash=sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a \ + --hash=sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a \ + --hash=sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd \ + --hash=sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284 \ + --hash=sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586 \ + --hash=sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869 \ + --hash=sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294 \ + --hash=sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f \ + --hash=sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66 \ + --hash=sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51 \ + --hash=sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc \ + --hash=sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97 \ + --hash=sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a \ + --hash=sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d \ + --hash=sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9 \ + --hash=sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c \ + --hash=sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07 \ + --hash=sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36 \ + --hash=sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e \ + --hash=sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05 \ + --hash=sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e \ + --hash=sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941 \ + --hash=sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3 \ + --hash=sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612 \ + --hash=sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3 \ + --hash=sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b \ + --hash=sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe \ + --hash=sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146 \ + --hash=sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11 \ + --hash=sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60 \ + --hash=sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd \ + --hash=sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b \ + --hash=sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c \ + --hash=sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a \ + --hash=sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460 \ + --hash=sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1 \ + --hash=sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf \ + --hash=sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf \ + --hash=sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858 \ + --hash=sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2 \ + --hash=sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9 \ + --hash=sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2 \ + --hash=sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3 \ + --hash=sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6 \ + --hash=sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770 \ + --hash=sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d \ + --hash=sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc \ + --hash=sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23 \ + --hash=sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26 \ + --hash=sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa \ + --hash=sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8 \ + --hash=sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d \ + --hash=sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3 \ + --hash=sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d \ + --hash=sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034 \ + --hash=sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9 \ + --hash=sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1 \ + --hash=sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56 \ + --hash=sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b \ + --hash=sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c \ + --hash=sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a \ + --hash=sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e \ + --hash=sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9 \ + --hash=sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5 \ + --hash=sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a \ + --hash=sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556 \ + --hash=sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e \ + --hash=sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49 \ + --hash=sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2 \ + --hash=sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9 \ + --hash=sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b \ + --hash=sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc \ + --hash=sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb \ + --hash=sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0 \ + --hash=sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8 \ + --hash=sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82 \ + --hash=sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69 \ + --hash=sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b \ + --hash=sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c \ + --hash=sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75 \ + --hash=sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5 \ + --hash=sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f \ + --hash=sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad \ + --hash=sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b \ + --hash=sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7 \ + --hash=sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425 \ + --hash=sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52 + # via pydantic +pydantic-settings==2.12.0 \ + --hash=sha256:005538ef951e3c2a68e1c08b292b5f2e71490def8589d4221b95dab00dafcfd0 \ + --hash=sha256:fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809 + # via + # docling + # fastapi-mcp + # mcp +pydata-google-auth==1.9.1 \ + --hash=sha256:0a51ce41c601ca0bc69b8795bf58bedff74b4a6a007c9106c7cbcdec00eaced2 \ + --hash=sha256:75ffce5d106e34b717b31844c1639ea505b7d9550dc23b96fb6c20d086b53fa3 + # via pandas-gbq +pygments==2.19.2 \ + --hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \ + --hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b + # via + # feast (setup.py) + # ipython + # ipython-pygments-lexers + # mpire + # nbconvert + # rich + # sphinx +pyjwt[crypto]==2.10.1 \ + --hash=sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953 \ + --hash=sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb + # via + # feast (setup.py) + # mcp + # msal + # singlestoredb + # snowflake-connector-python +pylatexenc==2.10 \ + --hash=sha256:3dd8fd84eb46dc30bee1e23eaab8d8fb5a7f507347b23e5f38ad9675c84f40d3 + # via docling +pymilvus==2.4.15 \ + --hash=sha256:0601591ce0498315e19e9ac3f4fdd3051102ca87b6ddff5b33849f522288cff7 \ + --hash=sha256:b21878e5df74dca91b3f3cf0b0597fa6b6aed7bf5cde9a1b10641994faa353bf + # via feast (setup.py) +pymongo==4.16.0 \ + --hash=sha256:03f42396c1b2c6f46f5401c5b185adc25f6113716e16d9503977ee5386fca0fb \ + --hash=sha256:12762e7cc0f8374a8cae3b9f9ed8dabb5d438c7b33329232dd9b7de783454033 \ + --hash=sha256:15bb062c0d6d4b0be650410032152de656a2a9a2aa4e1a7443a22695afacb103 \ + --hash=sha256:19a1c96e7f39c7a59a9cfd4d17920cf9382f6f684faeff4649bf587dc59f8edc \ + --hash=sha256:1c01e8a7cd0ea66baf64a118005535ab5bf9f9eb63a1b50ac3935dccf9a54abe \ + --hash=sha256:1d638b0b1b294d95d0fdc73688a3b61e05cc4188872818cd240d51460ccabcb5 \ + --hash=sha256:21d02cc10a158daa20cb040985e280e7e439832fc6b7857bff3d53ef6914ad50 \ + --hash=sha256:2290909275c9b8f637b0a92eb9b89281e18a72922749ebb903403ab6cc7da914 \ + --hash=sha256:25a6b03a68f9907ea6ec8bc7cf4c58a1b51a18e23394f962a6402f8e46d41211 \ + --hash=sha256:2a3ba6be3d8acf64b77cdcd4e36f0e4a8e87965f14a8b09b90ca86f10a1dd2f2 \ + --hash=sha256:2b0714d7764efb29bf9d3c51c964aed7c4c7237b341f9346f15ceaf8321fdb35 \ + --hash=sha256:2cd60cd1e05de7f01927f8e25ca26b3ea2c09de8723241e5d3bcfdc70eaff76b \ + --hash=sha256:2d0082631a7510318befc2b4fdab140481eb4b9dd62d9245e042157085da2a70 \ + --hash=sha256:311d4549d6bf1f8c61d025965aebb5ba29d1481dc6471693ab91610aaffbc0eb \ + --hash=sha256:36ef2fee50eee669587d742fb456e349634b4fcf8926208766078b089054b24b \ + --hash=sha256:3ead8a0050c53eaa55935895d6919d393d0328ec24b2b9115bdbe881aa222673 \ + --hash=sha256:46ffb728d92dd5b09fc034ed91acf5595657c7ca17d4cf3751322cd554153c17 \ + --hash=sha256:4a19ea46a0fe71248965305a020bc076a163311aefbaa1d83e47d06fa30ac747 \ + --hash=sha256:4a9390dce61d705a88218f0d7b54d7e1fa1b421da8129fc7c009e029a9a6b81e \ + --hash=sha256:4c4872299ebe315a79f7f922051061634a64fda95b6b17677ba57ef00b2ba2a4 \ + --hash=sha256:4cd047ba6cc83cc24193b9208c93e134a985ead556183077678c59af7aacc725 \ + --hash=sha256:4d4f7ba040f72a9f43a44059872af5a8c8c660aa5d7f90d5344f2ed1c3c02721 \ + --hash=sha256:4d79aa147ce86aef03079096d83239580006ffb684eead593917186aee407767 \ + --hash=sha256:4fbb8d3552c2ad99d9e236003c0b5f96d5f05e29386ba7abae73949bfebc13dd \ + --hash=sha256:55f8d5a6fe2fa0b823674db2293f92d74cd5f970bc0360f409a1fc21003862d3 \ + --hash=sha256:5b9c6d689bbe5beb156374508133218610e14f8c81e35bc17d7a14e30ab593e6 \ + --hash=sha256:5d9fdb386cf958e6ef6ff537d6149be7edb76c3268cd6833e6c36aa447e4443f \ + --hash=sha256:60307bb91e0ab44e560fe3a211087748b2b5f3e31f403baf41f5b7b0a70bd104 \ + --hash=sha256:61567f712bda04c7545a037e3284b4367cad8d29b3dec84b4bf3b2147020a75b \ + --hash=sha256:66af44ed23686dd5422307619a6db4b56733c5e36fe8c4adf91326dcf993a043 \ + --hash=sha256:6af1aaa26f0835175d2200e62205b78e7ec3ffa430682e322cc91aaa1a0dbf28 \ + --hash=sha256:6b2a20edb5452ac8daa395890eeb076c570790dfce6b7a44d788af74c2f8cf96 \ + --hash=sha256:6f2077ec24e2f1248f9cac7b9a2dfb894e50cc7939fcebfb1759f99304caabef \ + --hash=sha256:77cfd37a43a53b02b7bd930457c7994c924ad8bbe8dff91817904bcbf291b371 \ + --hash=sha256:78037d02389745e247fe5ab0bcad5d1ab30726eaac3ad79219c7d6bbb07eec53 \ + --hash=sha256:7902882ed0efb7f0e991458ab3b8cf0eb052957264949ece2f09b63c58b04f78 \ + --hash=sha256:85dc2f3444c346ea019a371e321ac868a4fab513b7a55fe368f0cc78de8177cc \ + --hash=sha256:8a0f73af1ea56c422b2dcfc0437459148a799ef4231c6aee189d2d4c59d6728f \ + --hash=sha256:8a254d49a9ffe9d7f888e3c677eed3729b14ce85abb08cd74732cead6ccc3c66 \ + --hash=sha256:8ba8405065f6e258a6f872fe62d797a28f383a12178c7153c01ed04e845c600c \ + --hash=sha256:91899dd7fb9a8c50f09c3c1cf0cb73bfbe2737f511f641f19b9650deb61c00ca \ + --hash=sha256:91ac0cb0fe2bf17616c2039dac88d7c9a5088f5cb5829b27c9d250e053664d31 \ + --hash=sha256:92a232af9927710de08a6c16a9710cc1b175fb9179c0d946cd4e213b92b2a69a \ + --hash=sha256:948152b30eddeae8355495f9943a3bf66b708295c0b9b6f467de1c620f215487 \ + --hash=sha256:96aa7ab896889bf330209d26459e493d00f8855772a9453bfb4520bb1f495baf \ + --hash=sha256:9caacac0dd105e2555521002e2d17afc08665187017b466b5753e84c016628e6 \ + --hash=sha256:9d9885aad05f82fd7ea0c9ca505d60939746b39263fa273d0125170da8f59098 \ + --hash=sha256:9dc2c00bed568732b89e211b6adca389053d5e6d2d5a8979e80b813c3ec4d1f9 \ + --hash=sha256:a1bf44e13cf2d44d2ea2e928a8140d5d667304abe1a61c4d55b4906f389fbe64 \ + --hash=sha256:aa30cd16ddd2f216d07ba01d9635c873e97ddb041c61cf0847254edc37d1c60e \ + --hash=sha256:acda193f440dd88c2023cb00aa8bd7b93a9df59978306d14d87a8b12fe426b05 \ + --hash=sha256:bd4911c40a43a821dfd93038ac824b756b6e703e26e951718522d29f6eb166a8 \ + --hash=sha256:be1099a8295b1a722d03fb7b48be895d30f4301419a583dcf50e9045968a041c \ + --hash=sha256:c126fb72be2518395cc0465d4bae03125119136462e1945aea19840e45d89cfc \ + --hash=sha256:c53338613043038005bf2e41a2fafa08d29cdbc0ce80891b5366c819456c1ae9 \ + --hash=sha256:c789236366525c3ee3cd6e4e450a9ff629a7d1f4d88b8e18a0aea0615fd7ecf8 \ + --hash=sha256:cf0ec79e8ca7077f455d14d915d629385153b6a11abc0b93283ed73a8013e376 \ + --hash=sha256:d15f060bc6d0964a8bb70aba8f0cb6d11ae99715438f640cff11bbcf172eb0e8 \ + --hash=sha256:d284bf68daffc57516535f752e290609b3b643f4bd54b28fc13cb16a89a8bda6 \ + --hash=sha256:dabbf3c14de75a20cc3c30bf0c6527157224a93dfb605838eabb1a2ee3be008d \ + --hash=sha256:dbbc5b254c36c37d10abb50e899bc3939bbb7ab1e7c659614409af99bd3e7675 \ + --hash=sha256:dfc320f08ea9a7ec5b2403dc4e8150636f0d6150f4b9792faaae539c88e7db3b \ + --hash=sha256:e2d509786344aa844ae243f68f833ca1ac92ac3e35a92ae038e2ceb44aa355ef \ + --hash=sha256:e37469602473f41221cea93fd3736708f561f0fa08ab6b2873dd962014390d52 \ + --hash=sha256:ed162b2227f98d5b270ecbe1d53be56c8c81db08a1a8f5f02d89c7bb4d19591d \ + --hash=sha256:efe020c46ce3c3a89af6baec6569635812129df6fb6cf76d4943af3ba6ee2069 \ + --hash=sha256:f1c5f1f818b669875d191323a48912d3fcd2e4906410e8297bb09ac50c4d5ccc \ + --hash=sha256:f25001a955073b80510c0c3db0e043dbbc36904fd69e511c74e3d8640b8a5111 \ + --hash=sha256:f3867dc225d9423c245a51eaac2cfcd53dde8e0a8d8090bb6aed6e31bd6c2d4f \ + --hash=sha256:f513b2c6c0d5c491f478422f6b5b5c27ac1af06a54c93ef8631806f7231bd92e \ + --hash=sha256:f6e42c1bc985d9beee884780ae6048790eb4cd565c46251932906bdb1630034a + # via feast (setup.py) +pymssql==2.3.2 \ + --hash=sha256:06883bc9bdb297ae9132d9371b5b1a3a223c8f93dd6a87d1c112c6a688f26d53 \ + --hash=sha256:0768d90f96ae3267d7561d3bcfe94dd671d107489e870388b12570c3debbc552 \ + --hash=sha256:0831c5c95aab0b9aba5142dc97e28f59c4130e1c34ffc13ecbfdd4d2fe45b8a0 \ + --hash=sha256:08facd25a50a7279385d1ffcee9d6d83c4e361db1af38e14519a87d7b1cadb10 \ + --hash=sha256:0a20a17db870fb0e446a6d6bf7664aaf84af7be58ab1fad025cafa4e092507a1 \ + --hash=sha256:1037053e6c74d6fe14c428cc942968b4e4bf06854706a83fe8e822e475e3f107 \ + --hash=sha256:148b7714fff5a5b7ce038e92b02dd9bf68fe442c181a3aae32148e7b13f6db95 \ + --hash=sha256:18089641b687be1ebd0f64f0d1ff977478a397ffa1af372bdf10dbec29cf6d2e \ + --hash=sha256:1afda7b7022eff9451bd83e3f64c450a1a8cdff4ba8b8e399866dcd2cb861a1e \ + --hash=sha256:1bc33ed9af6d8ebea2d49144cd2317b7ae1105dd51dddfd46982c90c8f0cf6ab \ + --hash=sha256:1c99dba4bf5b1ce10657e9e2885f18ba9179190251b63d1498e7d6d72e64f1ce \ + --hash=sha256:1cdc2619e7b4192b8d6619fd52ba8a2eae18b38b376f8649fb8f0727c4e88ff9 \ + --hash=sha256:22b1ce3a48f28ee7d06ebc9ed94276d0bf1c99051ee1df3d2377b74721bd62ef \ + --hash=sha256:22fb0fdd3b889bc10abbe3aa2abe7a008b30a6367b9ba159412d185d7d8fda9d \ + --hash=sha256:235c230e56d8c8c5f289e665c538f31d967fec302d05ad269dcd64fa9d6eb3b7 \ + --hash=sha256:23f5e2e2bdba1cf7cecbac66dd07de7631a8efca5692efee18ff46ebc087b757 \ + --hash=sha256:2568944db3888996e161b40ad06c1b9e0fbb6cfcb38279a3abb98ece7a8e1c4a \ + --hash=sha256:26bdb7abd5f107b6be422635f03e2cecaa52a5f4c394a205014586abbff9e72a \ + --hash=sha256:2a44a0898dacba4e25cac8778d0ed112e297883fe862204e447081888da78dc4 \ + --hash=sha256:2f4093b95f1f3a1232687fc92f652aaf675eb423db8549c16d146b91ac2f0eba \ + --hash=sha256:33ad813092f8fb8f74578c5b5e37c818c4ae130fd4047cb28f0b256f2f107367 \ + --hash=sha256:3870085a49e5332bc67ecb24f217c586977d5352eb51598244fc7bc278eee3e1 \ + --hash=sha256:41d09e1b2534229b288c37b88c1de3d964317af2c7eec58bfb97e01d679eba27 \ + --hash=sha256:5904d78e61668ec89761d3ae01efd4b42b31d820f612929f449e93cd23ba3c54 \ + --hash=sha256:6019d2939963112662288704f608f31634038bffcfd5cad1bc79cb167edb3cc1 \ + --hash=sha256:72b6599963b6e066998c4b27b7bf207684c243b12b1e5dcc180b2af22802ae6c \ + --hash=sha256:73fac766b448613d7ae26e6b304b2cb8a7ffebccaa373633bad3b3cbcc829935 \ + --hash=sha256:793a93da1521fa66bf02b3b873065e22bf14bda5570e005ce3d5fae0776d7b92 \ + --hash=sha256:79cdc3ed1da3129ba56232127db86279728c4328595e2532ed4d0da6379a5c72 \ + --hash=sha256:82ed3dd560d3fb222d26ce3a7373f46dc3ad1d50b6e6417ef7399e87fa9aefe1 \ + --hash=sha256:8cd806380d362d4cef2d925a6baee6a4b2b151a92cac2cab5c4bfabed4be4849 \ + --hash=sha256:9361593a89c9162fc631baf648a87e2666373382d9d54aacfb19edab9ceb2007 \ + --hash=sha256:97fbd8491ad3ece0adcb321acec6db48b8fe37bc74af4c91bb657d4d9347d634 \ + --hash=sha256:9e3d6fada7fbe7a5f5fafc420673f777bab3f399c78fa44e29de6a8cbc36e515 \ + --hash=sha256:a3f9e7eb813dfeab6d01bf6474049bb76b0521235159d3e969ec82df384eac49 \ + --hash=sha256:aa08b6203b2b5ed5ce47f80d5c529459181300d7e0d0c1e84390a4d01d45e509 \ + --hash=sha256:ab48de09864fa6f49c575ef569f6773981d0cd905ff7288b5b185f8079a5a21f \ + --hash=sha256:ab912d1178d5977e421cf9c4d4071958b223cbe4a2b6dd64611d521aa6bb7187 \ + --hash=sha256:ae02cc1594f0addd748bf5ac1ccc7a73c03846ada9c553663c381b242b586606 \ + --hash=sha256:b0c2b11aca16617cacaf385fb94134e73ba0216a924f9b85778cc7e3d3713361 \ + --hash=sha256:b14cc65369d1425f2fb517609113465a0f55f19a49648160f2d10be4cb43ff4d \ + --hash=sha256:b156b15165f7a0bbb392a124d8e2d678145c93e5bfcfef3b637e4d87eadcc85b \ + --hash=sha256:b16d5880f7028442d6c49c94801ce9bff3af8af0fbda7c6039febb936714aed5 \ + --hash=sha256:b3eb201c402bcf4f5b9399df0bb20d522636d2e87d1c6957a0b6d772ee636c61 \ + --hash=sha256:bac6f355c454f94b0e15a04b7841236e5c5c4ef44d2d1beed00a3ad7b50ccc53 \ + --hash=sha256:c24ba6aedb9b5540b56f3e74bff92b687c6e90c00650823385729c7e55923cf5 \ + --hash=sha256:cbe9058b6520be74463476ff2cdb17bbab5ff60b60b3ed7bd8bd2d086bdfd9bd \ + --hash=sha256:cc13c2e0f1b8efc3a46941de9db768fa59937b5a54081ec0cb0ff0da17d1fff3 \ + --hash=sha256:dd5fe7552edc81628e4242b4671f7bad5ff1ec790bae5c7615d989375620edac \ + --hash=sha256:eb629b5fb0376fbf39d575cf1365e504b84877b19f9e8d53caa5228fed56894a \ + --hash=sha256:ee8ee2c7c227c413ad9b88ddba1cb6a25e28c217ae73ecac1c7a6b8c29003604 \ + --hash=sha256:ef0d29c705db552f9e75230f946b0ca9db0db903c5c9ee79ce8b88ad25ea9670 \ + --hash=sha256:f1791f4627c42fe2d2833c884d036b0c5c8cf628f2cdfa3536191c217acf729e \ + --hash=sha256:f282e701dca155b3e7f1644d7e3b60c201ca5f3be8045bce34042d3c737d63ee \ + --hash=sha256:f2b1da4e68d618c7972e583ae19f386ae620258acb61564e8067c203f27cd769 \ + --hash=sha256:f9737c06b13ca2012b9900185fa3af72a37941c532da2e6373dd7c9ab16abddf \ + --hash=sha256:fb8a7b197aaf466a7577ca6690aa9d747081b653ab212d052d71f3cc10587c3b \ + --hash=sha256:fdd774b26407babd0205ef85a098f90553e6b3da77a22322a1e7d2cb51f742c0 + # via feast (setup.py) +pymysql==1.1.2 \ + --hash=sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03 \ + --hash=sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9 + # via feast (setup.py) +pynacl==1.6.0 \ + --hash=sha256:04f20784083014e265ad58c1b2dd562c3e35864b5394a14ab54f5d150ee9e53e \ + --hash=sha256:10d755cf2a455d8c0f8c767a43d68f24d163b8fe93ccfaabfa7bafd26be58d73 \ + --hash=sha256:140373378e34a1f6977e573033d1dd1de88d2a5d90ec6958c9485b2fd9f3eb90 \ + --hash=sha256:16c60daceee88d04f8d41d0a4004a7ed8d9a5126b997efd2933e08e93a3bd850 \ + --hash=sha256:16dd347cdc8ae0b0f6187a2608c0af1c8b7ecbbe6b4a06bff8253c192f696990 \ + --hash=sha256:25720bad35dfac34a2bcdd61d9e08d6bfc6041bebc7751d9c9f2446cf1e77d64 \ + --hash=sha256:2d6cd56ce4998cb66a6c112fda7b1fdce5266c9f05044fa72972613bef376d15 \ + --hash=sha256:347dcddce0b4d83ed3f32fd00379c83c425abee5a9d2cd0a2c84871334eaff64 \ + --hash=sha256:4853c154dc16ea12f8f3ee4b7e763331876316cc3a9f06aeedf39bcdca8f9995 \ + --hash=sha256:49c336dd80ea54780bcff6a03ee1a476be1612423010472e60af83452aa0f442 \ + --hash=sha256:4a25cfede801f01e54179b8ff9514bd7b5944da560b7040939732d1804d25419 \ + --hash=sha256:51fed9fe1bec9e7ff9af31cd0abba179d0e984a2960c77e8e5292c7e9b7f7b5d \ + --hash=sha256:536703b8f90e911294831a7fbcd0c062b837f3ccaa923d92a6254e11178aaf42 \ + --hash=sha256:5789f016e08e5606803161ba24de01b5a345d24590a80323379fc4408832d290 \ + --hash=sha256:6b08eab48c9669d515a344fb0ef27e2cbde847721e34bba94a343baa0f33f1f4 \ + --hash=sha256:6b393bc5e5a0eb86bb85b533deb2d2c815666665f840a09e0aa3362bb6088736 \ + --hash=sha256:84709cea8f888e618c21ed9a0efdb1a59cc63141c403db8bf56c469b71ad56f2 \ + --hash=sha256:8bfaa0a28a1ab718bad6239979a5a57a8d1506d0caf2fba17e524dbb409441cf \ + --hash=sha256:bbcc4452a1eb10cd5217318c822fde4be279c9de8567f78bad24c773c21254f8 \ + --hash=sha256:cb36deafe6e2bce3b286e5d1f3e1c246e0ccdb8808ddb4550bb2792f2df298f2 \ + --hash=sha256:cf831615cc16ba324240de79d925eacae8265b7691412ac6b24221db157f6bd1 \ + --hash=sha256:dcdeb41c22ff3c66eef5e63049abf7639e0db4edee57ba70531fc1b6b133185d \ + --hash=sha256:dea103a1afcbc333bc0e992e64233d360d393d1e63d0bc88554f572365664348 \ + --hash=sha256:ef214b90556bb46a485b7da8258e59204c244b1b5b576fb71848819b468c44a7 \ + --hash=sha256:f3482abf0f9815e7246d461fab597aa179b7524628a4bc36f86a7dc418d2608d \ + --hash=sha256:f46386c24a65383a9081d68e9c2de909b1834ec74ff3013271f1bca9c2d233eb \ + --hash=sha256:f4b3824920e206b4f52abd7de621ea7a44fd3cb5c8daceb7c3612345dfc54f2e + # via paramiko +pyodbc==5.3.0 \ + --hash=sha256:01166162149adf2b8a6dc21a212718f205cabbbdff4047dc0c415af3fd85867e \ + --hash=sha256:0263323fc47082c2bf02562f44149446bbbfe91450d271e44bffec0c3143bfb1 \ + --hash=sha256:08b2439500e212625471d32f8fde418075a5ddec556e095e5a4ba56d61df2dc6 \ + --hash=sha256:0df7ff47fab91ea05548095b00e5eb87ed88ddf4648c58c67b4db95ea4913e23 \ + --hash=sha256:101313a21d2654df856a60e4a13763e4d9f6c5d3fd974bcf3fc6b4e86d1bbe8e \ + --hash=sha256:13656184faa3f2d5c6f19b701b8f247342ed581484f58bf39af7315c054e69db \ + --hash=sha256:1629af4706e9228d79dabb4863c11cceb22a6dab90700db0ef449074f0150c0d \ + --hash=sha256:197bb6ddafe356a916b8ee1b8752009057fce58e216e887e2174b24c7ab99269 \ + --hash=sha256:2035c7dfb71677cd5be64d3a3eb0779560279f0a8dc6e33673499498caa88937 \ + --hash=sha256:25b6766e56748eb1fc1d567d863e06cbb7b7c749a41dfed85db0031e696fa39a \ + --hash=sha256:25c4cfb2c08e77bc6e82f666d7acd52f0e52a0401b1876e60f03c73c3b8aedc0 \ + --hash=sha256:2eb7151ed0a1959cae65b6ac0454f5c8bbcd2d8bafeae66483c09d58b0c7a7fc \ + --hash=sha256:2fe0e063d8fb66efd0ac6dc39236c4de1a45f17c33eaded0d553d21c199f4d05 \ + --hash=sha256:349a9abae62a968b98f6bbd23d2825151f8d9de50b3a8f5f3271b48958fdb672 \ + --hash=sha256:363311bd40320b4a61454bebf7c38b243cd67c762ed0f8a5219de3ec90c96353 \ + --hash=sha256:3cc472c8ae2feea5b4512e23b56e2b093d64f7cbc4b970af51da488429ff7818 \ + --hash=sha256:3f1bdb3ce6480a17afaaef4b5242b356d4997a872f39e96f015cabef00613797 \ + --hash=sha256:452e7911a35ee12a56b111ac5b596d6ed865b83fcde8427127913df53132759e \ + --hash=sha256:46185a1a7f409761716c71de7b95e7bbb004390c650d00b0b170193e3d6224bb \ + --hash=sha256:46869b9a6555ff003ed1d8ebad6708423adf2a5c88e1a578b9f029fb1435186e \ + --hash=sha256:58635a1cc859d5af3f878c85910e5d7228fe5c406d4571bffcdd281375a54b39 \ + --hash=sha256:5cbe4d753723c8a8f65020b7a259183ef5f14307587165ce37e8c7e251951852 \ + --hash=sha256:5ceaed87ba2ea848c11223f66f629ef121f6ebe621f605cde9cfdee4fd9f4b68 \ + --hash=sha256:5dd3d5e469f89a3112cf8b0658c43108a4712fad65e576071e4dd44d2bd763c7 \ + --hash=sha256:5ebf6b5d989395efe722b02b010cb9815698a4d681921bf5db1c0e1195ac1bde \ + --hash=sha256:6132554ffbd7910524d643f13ce17f4a72f3a6824b0adef4e9a7f66efac96350 \ + --hash=sha256:6682cdec78f1302d0c559422c8e00991668e039ed63dece8bf99ef62173376a5 \ + --hash=sha256:676031723aac7dcbbd2813bddda0e8abf171b20ec218ab8dfb21d64a193430ea \ + --hash=sha256:705903acf6f43c44fc64e764578d9a88649eb21bf7418d78677a9d2e337f56f2 \ + --hash=sha256:729c535341bb09c476f219d6f7ab194bcb683c4a0a368010f1cb821a35136f05 \ + --hash=sha256:74528fe148980d0c735c0ebb4a4dc74643ac4574337c43c1006ac4d09593f92d \ + --hash=sha256:754d052030d00c3ac38da09ceb9f3e240e8dd1c11da8906f482d5419c65b9ef5 \ + --hash=sha256:7713c740a10f33df3cb08f49a023b7e1e25de0c7c99650876bbe717bc95ee780 \ + --hash=sha256:7e9ab0b91de28a5ab838ac4db0253d7cc8ce2452efe4ad92ee6a57b922bf0c24 \ + --hash=sha256:8339d3094858893c1a68ee1af93efc4dff18b8b65de54d99104b99af6306320d \ + --hash=sha256:8aa396c6d6af52ccd51b8c8a5bffbb46fd44e52ce07ea4272c1d28e5e5b12722 \ + --hash=sha256:9b987a25a384f31e373903005554230f5a6d59af78bce62954386736a902a4b3 \ + --hash=sha256:9cd3f0a9796b3e1170a9fa168c7e7ca81879142f30e20f46663b882db139b7d2 \ + --hash=sha256:a48d731432abaee5256ed6a19a3e1528b8881f9cb25cb9cf72d8318146ea991b \ + --hash=sha256:ac23feb7ddaa729f6b840639e92f83ff0ccaa7072801d944f1332cd5f5b05f47 \ + --hash=sha256:af4d8c9842fc4a6360c31c35508d6594d5a3b39922f61b282c2b4c9d9da99514 \ + --hash=sha256:afe7c4ac555a8d10a36234788fc6cfc22a86ce37fc5ba88a1f75b3e6696665dc \ + --hash=sha256:b180bc5e49b74fd40a24ef5b0fe143d0c234ac1506febe810d7434bf47cb925b \ + --hash=sha256:b35b9983ad300e5aea82b8d1661fc9d3afe5868de527ee6bd252dd550e61ecd6 \ + --hash=sha256:bc834567c2990584b9726cba365834d039380c9dbbcef3030ddeb00c6541b943 \ + --hash=sha256:bfeb3e34795d53b7d37e66dd54891d4f9c13a3889a8f5fe9640e56a82d770955 \ + --hash=sha256:c25dc9c41f61573bdcf61a3408c34b65e4c0f821b8f861ca7531b1353b389804 \ + --hash=sha256:c2eb0b08e24fe5c40c7ebe9240c5d3bd2f18cd5617229acee4b0a0484dc226f2 \ + --hash=sha256:c5c30c5cd40b751f77bbc73edd32c4498630939bcd4e72ee7e6c9a4b982cc5ca \ + --hash=sha256:c67e7f2ce649155ea89beb54d3b42d83770488f025cf3b6f39ca82e9c598a02e \ + --hash=sha256:c68d9c225a97aedafb7fff1c0e1bfe293093f77da19eaf200d0e988fa2718d16 \ + --hash=sha256:c6ccb5315ec9e081f5cbd66f36acbc820ad172b8fa3736cf7f993cdf69bd8a96 \ + --hash=sha256:c79df54bbc25bce9f2d87094e7b39089c28428df5443d1902b0cc5f43fd2da6f \ + --hash=sha256:cf18797a12e70474e1b7f5027deeeccea816372497e3ff2d46b15bec2d18a0cc \ + --hash=sha256:d255f6b117d05cfc046a5201fdf39535264045352ea536c35777cf66d321fbb8 \ + --hash=sha256:d32c3259762bef440707098010035bbc83d1c73d81a434018ab8c688158bd3bb \ + --hash=sha256:d89a7f2e24227150c13be8164774b7e1f9678321a4248f1356a465b9cc17d31e \ + --hash=sha256:e3c39de3005fff3ae79246f952720d44affc6756b4b85398da4c5ea76bf8f506 \ + --hash=sha256:e981db84fee4cebec67f41bd266e1e7926665f1b99c3f8f4ea73cd7f7666e381 \ + --hash=sha256:ebc3be93f61ea0553db88589e683ace12bf975baa954af4834ab89f5ee7bf8ae \ + --hash=sha256:f1ad0e93612a6201621853fc661209d82ff2a35892b7d590106fe8f97d9f1f2a \ + --hash=sha256:f927b440c38ade1668f0da64047ffd20ec34e32d817f9a60d07553301324b364 \ + --hash=sha256:fc5ac4f2165f7088e74ecec5413b5c304247949f9702c8853b0e43023b4187e8 \ + --hash=sha256:fe77eb9dcca5fc1300c9121f81040cc9011d28cff383e2c35416e9ec06d4bc95 + # via + # feast (setup.py) + # ibis-framework +pyopenssl==25.1.0 \ + --hash=sha256:2b11f239acc47ac2e5aca04fd7fa829800aeee22a2eb30d744572a157bd8a1ab \ + --hash=sha256:8d031884482e0c67ee92bf9a4d8cceb08d92aba7136432ffb0703c5280fc205b + # via snowflake-connector-python +pyparsing==3.3.1 \ + --hash=sha256:023b5e7e5520ad96642e2c6db4cb683d3970bd640cdf7115049a6e9c3682df82 \ + --hash=sha256:47fad0f17ac1e2cad3de3b458570fbc9b03560aa029ed5e16ee5554da9a2251c + # via great-expectations +pypdfium2==4.30.0 \ + --hash=sha256:0dfa61421b5eb68e1188b0b2231e7ba35735aef2d867d86e48ee6cab6975195e \ + --hash=sha256:119b2969a6d6b1e8d55e99caaf05290294f2d0fe49c12a3f17102d01c441bd29 \ + --hash=sha256:3d0dd3ecaffd0b6dbda3da663220e705cb563918249bda26058c6036752ba3a2 \ + --hash=sha256:48b5b7e5566665bc1015b9d69c1ebabe21f6aee468b509531c3c8318eeee2e16 \ + --hash=sha256:4e55689f4b06e2d2406203e771f78789bd4f190731b5d57383d05cf611d829de \ + --hash=sha256:4e6e50f5ce7f65a40a33d7c9edc39f23140c57e37144c2d6d9e9262a2a854854 \ + --hash=sha256:5eda3641a2da7a7a0b2f4dbd71d706401a656fea521b6b6faa0675b15d31a163 \ + --hash=sha256:90dbb2ac07be53219f56be09961eb95cf2473f834d01a42d901d13ccfad64b4c \ + --hash=sha256:b33ceded0b6ff5b2b93bc1fe0ad4b71aa6b7e7bd5875f1ca0cdfb6ba6ac01aab \ + --hash=sha256:cc3bf29b0db8c76cdfaac1ec1cde8edf211a7de7390fbf8934ad2aa9b4d6dfad \ + --hash=sha256:ee2410f15d576d976c2ab2558c93d392a25fb9f6635e8dd0a8a3a5241b275e0e \ + --hash=sha256:f1f78d2189e0ddf9ac2b7a9b9bd4f0c66f54d1389ff6c17e9fd9dc034d06eb3f \ + --hash=sha256:f33bd79e7a09d5f7acca3b0b69ff6c8a488869a7fab48fdf400fec6e20b9c8be + # via docling +pyproject-hooks==1.2.0 \ + --hash=sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8 \ + --hash=sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913 + # via + # build + # pip-tools +pyspark==4.1.1 \ + --hash=sha256:77f78984aa84fbe865c717dd37b49913b4e5c97d76ef6824f932f1aefa6621ec + # via feast (setup.py) +pytest==7.4.4 \ + --hash=sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280 \ + --hash=sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8 + # via + # feast (setup.py) + # pytest-asyncio + # pytest-benchmark + # pytest-cov + # pytest-env + # pytest-lazy-fixture + # pytest-mock + # pytest-ordering + # pytest-timeout + # pytest-xdist +pytest-asyncio==0.23.8 \ + --hash=sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2 \ + --hash=sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3 + # via feast (setup.py) +pytest-benchmark==3.4.1 \ + --hash=sha256:36d2b08c4882f6f997fd3126a3d6dfd70f3249cde178ed8bbc0b73db7c20f809 \ + --hash=sha256:40e263f912de5a81d891619032983557d62a3d85843f9a9f30b98baea0cd7b47 + # via feast (setup.py) +pytest-cov==7.0.0 \ + --hash=sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1 \ + --hash=sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861 + # via feast (setup.py) +pytest-env==1.1.3 \ + --hash=sha256:aada77e6d09fcfb04540a6e462c58533c37df35fa853da78707b17ec04d17dfc \ + --hash=sha256:fcd7dc23bb71efd3d35632bde1bbe5ee8c8dc4489d6617fb010674880d96216b + # via feast (setup.py) +pytest-lazy-fixture==0.6.3 \ + --hash=sha256:0e7d0c7f74ba33e6e80905e9bfd81f9d15ef9a790de97993e34213deb5ad10ac \ + --hash=sha256:e0b379f38299ff27a653f03eaa69b08a6fd4484e46fd1c9907d984b9f9daeda6 + # via feast (setup.py) +pytest-mock==1.10.4 \ + --hash=sha256:43ce4e9dd5074993e7c021bb1c22cbb5363e612a2b5a76bc6d956775b10758b7 \ + --hash=sha256:5bf5771b1db93beac965a7347dc81c675ec4090cb841e49d9d34637a25c30568 + # via feast (setup.py) +pytest-ordering==0.6 \ + --hash=sha256:27fba3fc265f5d0f8597e7557885662c1bdc1969497cd58aff6ed21c3b617de2 \ + --hash=sha256:3f314a178dbeb6777509548727dc69edf22d6d9a2867bf2d310ab85c403380b6 \ + --hash=sha256:561ad653626bb171da78e682f6d39ac33bb13b3e272d406cd555adb6b006bda6 + # via feast (setup.py) +pytest-timeout==1.4.2 \ + --hash=sha256:20b3113cf6e4e80ce2d403b6fb56e9e1b871b510259206d40ff8d609f48bda76 \ + --hash=sha256:541d7aa19b9a6b4e475c759fd6073ef43d7cdc9a92d95644c260076eb257a063 + # via feast (setup.py) +pytest-xdist==3.8.0 \ + --hash=sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 \ + --hash=sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1 + # via feast (setup.py) +python-bidi==0.6.7 \ + --hash=sha256:01ff2fd676ef8351f32e820b2d3b61eac875a21702d2118263a2641b458e1996 \ + --hash=sha256:05fe5971110013610f0db40505d0b204edc756e92eafac1372a464f8b9162b11 \ + --hash=sha256:06650a164e63e94dc8a291cc9d415b4027cb1cce125bc9b02dac0f34d535ed47 \ + --hash=sha256:0cb75e8a410166fd677d55095e505bf6a4773c066f51efbda72d302ebc56e79b \ + --hash=sha256:0dbb4bbae212cca5bcf6e522fe8f572aff7d62544557734c2f810ded844d9eea \ + --hash=sha256:0f86e447e94ae78db7d56e7da2124c435eaee4425c87d3d92aea271317811112 \ + --hash=sha256:11c51579e01f768446a7e13a0059fea1530936a707abcbeaad9467a55cb16073 \ + --hash=sha256:1395e236c71f11267860b53293a33b19b991b06e0f4ac61045b892e6a99d96f2 \ + --hash=sha256:17572944e6d8fb616d111fc702c759da2bf7cedab85a3e4fa2af0c9eb95ed438 \ + --hash=sha256:19737d217088ef27014f98eac1827c5913e6fb1dea96332ed84ede61791070d9 \ + --hash=sha256:1ba28642928d1c8fdb18b0632fe931f156e888c646326a3ad8eb3e55ee904951 \ + --hash=sha256:1c061207212cd1db27bf6140b96dcd0536246f1e13e99bb5d03f4632f8e2ad7f \ + --hash=sha256:1c5fb99f774748de283fadf915106f130b74be1bade934b7f73a7a8488b95da1 \ + --hash=sha256:1dd0a5ec0d8710905cebb4c9e5018aa8464395a33cb32a3a6c2a951bf1984fe5 \ + --hash=sha256:24388c77cb00b8aa0f9c84beb7e3e523a3dac4f786ece64a1d8175a07b24da72 \ + --hash=sha256:24a4a268289bbe80ad7da3064d7325f1571173859e8ad75d2f99075d5278b02b \ + --hash=sha256:24afff65c581a5d6f658a9ec027d6719d19a1d8a4401000fdb22d2eeb677b8e3 \ + --hash=sha256:257d6dd0e07221f1dc8720fa61158471f5aae30d5f89837c38a026386151c250 \ + --hash=sha256:26a8fe0d532b966708fc5f8aea0602107fde4745a8a5ae961edd3cf02e807d07 \ + --hash=sha256:2a93b0394cc684d64356b0475858c116f1e335ffbaba388db93bf47307deadfa \ + --hash=sha256:2d28e2bdcadf5b6161bb4ee9313ce41eac746ba57e744168bf723a415a11af05 \ + --hash=sha256:349b89c3110bd25aa56d79418239ca4785d4bcc7a596e63bb996a9696fc6a907 \ + --hash=sha256:3a85275dfc24a96629da058c4c2fc93af6390aefe2f7cdde1500b6ac3fd40ca0 \ + --hash=sha256:3b63d19f3f56ff7f99bce5ca9ef8c811dbf0f509d8e84c1bc06105ed26a49528 \ + --hash=sha256:3b96744e4709f4445788a3645cea7ef8d7520ccd4fa8bbbfb3b650702e12c1e6 \ + --hash=sha256:414004fe9cba33d288ff4a04e1c9afe6a737f440595d01b5bbed00d750296bbd \ + --hash=sha256:4283f8b517411cc81b3c92d11998981fe54ac0d2300f4c58d803e0c071aba1ba \ + --hash=sha256:4636d572b357ab9f313c5340915c1cf51e3e54dd069351e02b6b76577fd1a854 \ + --hash=sha256:47deaada8949af3a790f2cd73b613f9bfa153b4c9450f91c44a60c3109a81f73 \ + --hash=sha256:49639743f1230648fd4fb47547f8a48ada9c5ca1426b17ac08e3be607c65394c \ + --hash=sha256:4c73cd980d45bb967799c7f0fc98ea93ae3d65b21ef2ba6abef6a057720bf483 \ + --hash=sha256:4d84e70923392f8c9611f0fb6b341577346ef6224f3809b05f0ae1fbf8f17578 \ + --hash=sha256:4ea928c31c7364098f853f122868f6f2155d6840661f7ea8b2ccfdf6084eb9f4 \ + --hash=sha256:5013ba963e9da606c4c03958cc737ebd5f8b9b8404bd71ab0d580048c746f875 \ + --hash=sha256:5debaab33562fdfc79ffdbd8d9c51cf07b8529de0e889d8cd145d78137aab21e \ + --hash=sha256:5ebc19f24e65a1f5c472e26d88e78b9d316e293bc6f205f32de4c4e99276336e \ + --hash=sha256:630cee960ba9e3016f95a8e6f725a621ddeff6fd287839f5693ccfab3f3a9b5c \ + --hash=sha256:6323e943c7672b271ad9575a2232508f17e87e81a78d7d10d6e93040e210eddf \ + --hash=sha256:6c051f2d28ca542092d01da8b5fe110fb6191ff58d298a54a93dc183bece63bf \ + --hash=sha256:6c19ab378fefb1f09623f583fcfa12ed42369a998ddfbd39c40908397243c56b \ + --hash=sha256:6df7be07af867ec1d121c92ea827efad4d77b25457c06eeab477b601e82b2340 \ + --hash=sha256:6f9fa1257e075eeeed67d21f95e411036b7ca2b5c78f757d4ac66485c191720a \ + --hash=sha256:7336a3c4ba4fc9e6741fbe60c6483266fe39e1f24830724dfce453471d11fa40 \ + --hash=sha256:73a88dc333efc42281bd800d5182c8625c6e11d109fc183fe3d7a11d48ab1150 \ + --hash=sha256:766d5f5a686eb99b53168a7bdfb338035931a609bdbbcb537cef9e050a86f359 \ + --hash=sha256:77bb4cbadf4121db395189065c58c9dd5d1950257cc1983004e6df4a3e2f97ad \ + --hash=sha256:77fea54c2379b93def4ed16db6390e1232e7b235679587295a23dd8b1925475f \ + --hash=sha256:8047c33b85f7790474a1f488bef95689f049976a4e1c6f213a8d075d180a93e4 \ + --hash=sha256:80e6fd06f6e4074d183cea73962c89cf76cb4f70c0ee403689f57a429ebde488 \ + --hash=sha256:849a57d39feaf897955d0b19bbf4796bea53d1bcdf83b82e0a7b059167eb2049 \ + --hash=sha256:8678c2272e7bd60a75f781409e900c9ddb9f01f55c625d83ae0d49dfc6a2674f \ + --hash=sha256:8814db38fa317bebec8eb74b826bae7d0cb978a7eca30dfe4ecf60e61f06ee0b \ + --hash=sha256:8860d67dc04dc530b8b4f588f38b7341a76f2ec44a45685a2d54e9dcffa5d15a \ + --hash=sha256:898db0ea3e4aaa95b7fecba02a7560dfbf368f9d85053f2875f6d610c4d4ec2c \ + --hash=sha256:8a17631e3e691eec4ae6a370f7b035cf0a5767f4457bd615d11728c23df72e43 \ + --hash=sha256:8a18c61817f3210ba74ad5792c8a5048d9550ba233233a0a8fe35800350988f4 \ + --hash=sha256:8d4e621caadfdbc73d36eabdb2f392da850d28c58b020738411d09dda6208509 \ + --hash=sha256:94dbfd6a6ec0ae64b5262290bf014d6063f9ac8688bda9ec668dc175378d2c80 \ + --hash=sha256:95867a07c5dee0ea2340fe1d0e4f6d9f5c5687d473193b6ee6f86fa44aac45d1 \ + --hash=sha256:95c9de7ebc55ffb777548f2ecaf4b96b0fa0c92f42bf4d897b9f4cd164ec7394 \ + --hash=sha256:9adeec7cab0f2c2c291bd7faf9fa3fa233365fd0bf1c1c27a6ddd6cc563d4b32 \ + --hash=sha256:9c463ae15e94b1c6a8a50bd671d6166b0b0d779fd1e56cbf46d8a4a84c9aa2d0 \ + --hash=sha256:9d9de35eb5987da27dd81e371c52142dd8e924bd61c1006003071ea05a735587 \ + --hash=sha256:a2eb8fca918c7381531035c3aae31c29a1c1300ab8a63cad1ec3a71331096c78 \ + --hash=sha256:a4319f478ab1b90bbbe9921606ecb7baa0ebf0b332e821d41c3abdf1a30f0c35 \ + --hash=sha256:a507fe6928a27a308e04ebf2065719b7850d1bf9ff1924f4e601ef77758812bd \ + --hash=sha256:a8892a7da0f617135fe9c92dc7070d13a0f96ab3081f9db7ff5b172a3905bd78 \ + --hash=sha256:a99d898ad1a399d9c8cab5561b3667fd24f4385820ac90c3340aa637aa5adfc9 \ + --hash=sha256:aa4136f8ccb9a8cd32befd1b3882c2597e6791e64e8b3cf3129c55549b5de62f \ + --hash=sha256:ab2a5177522b62426db897b655a02f574e27d9735bbeb6da41bc981b771df636 \ + --hash=sha256:ab806fd026bfd48bade5e21e06d0d799cbfad32f236989ff6f37db03a5fbe34f \ + --hash=sha256:ad5f0847da00687f52d2b81828e8d887bdea9eb8686a9841024ea7a0e153028e \ + --hash=sha256:b0bee27fb596a0f518369c275a965d0448c39a0730e53a030b311bb10562d4d5 \ + --hash=sha256:b31d66b62736b8514982a24a7dedcf8c062b27a8e9b51e52d7a5899045a45fe1 \ + --hash=sha256:b38ddfab41d10e780edb431edc30aec89bee4ce43d718e3896e99f33dae5c1d3 \ + --hash=sha256:be1bdbd52145dfe46880d8bb56eacc25aa75c3bb075fa103de7974295eb2811f \ + --hash=sha256:c10065081c0e137975de5d9ba2ff2306286dbf5e0c586d4d5aec87c856239b41 \ + --hash=sha256:c11c62a3cdb9d1426b1536de9e3446cb09c7d025bd4df125275cae221f214899 \ + --hash=sha256:c3777ae3e088e94df854fbcbd8d59f9239b74aac036cb6bbd19f8035c8e42478 \ + --hash=sha256:c3d93171dd65b36eca5367acf19eef82c79b4df557cb4bd0daf323b7a27f2d3b \ + --hash=sha256:c9a679b24f5c6f366a0dec75745e1abeae2f597f033d0d54c74cbe62e7e6ae28 \ + --hash=sha256:caa71c723f512f8d859fa239573086e16f38ffc426b5b2f7dab5d40fdb356c80 \ + --hash=sha256:ce86d9dfc6b409ad16556384244572bb3cbefa2ca0f0eab7fba0ff2112b2f068 \ + --hash=sha256:d4cd82e65b5aeb31bd73534e61ece1cab625f4bcbdc13bc4ddc5f8cbfb37c24a \ + --hash=sha256:d524a4ba765bae9b950706472a77a887a525ed21144fe4b41f6190f6e57caa2c \ + --hash=sha256:d7310312a68fdb1a8249cf114acb5435aa6b6a958b15810f053c1df5f98476e4 \ + --hash=sha256:d8274ff02d447cca026ba00f56070ba15f95e184b2d028ee0e4b6c9813d2aaf9 \ + --hash=sha256:d879be7fb5296409e18731c7ba666d56ecd45b816b2c9eb35138aa1d7777aeb5 \ + --hash=sha256:d87ed09e5c9b6d2648e8856a4e556147b9d3cd4d63905fa664dd6706bc414256 \ + --hash=sha256:dde1c3f3edb1f0095dcbf79cf8a0bb768f9539e809d0ad010d78200eea97d42a \ + --hash=sha256:df5e9db9539d70426f5d20c7ebb6f7b33da5fbd40620e11261fe3fba7e177145 \ + --hash=sha256:e7cad66317f12f0fd755fe41ee7c6b06531d2189a9048a8f37addb5109f7e3e3 \ + --hash=sha256:ec1694134961b71ac05241ac989b49ccf08e232b5834d5fc46f8a7c3bb1c13a9 \ + --hash=sha256:ec985386bc3cd54155f2ef0434fccbfd743617ed6fc1a84dae2ab1de6062e0c6 \ + --hash=sha256:ef9d103706560c15fecaf7d3cff939e0f68ce5763cf0e64d0e4e5d37f9bdd2d1 \ + --hash=sha256:f1350033431d75be749273236dcfc808e54404cd6ece6204cdb1bc4ccc163455 \ + --hash=sha256:f1fe71c203f66bc169a393964d5702f9251cfd4d70279cb6453fdd42bd2e675f \ + --hash=sha256:f24189dc3aea3a0a94391a047076e1014306b39ba17d7a38ebab510553cd1a97 \ + --hash=sha256:f57726b5a90d818625e6996f5116971b7a4ceb888832337d0e2cf43d1c362a90 \ + --hash=sha256:f7c055a50d068b3a924bd33a327646346839f55bcb762a26ec3fde8ea5d40564 \ + --hash=sha256:f7e5072269c34a1b719910ee4decf13b288159fb320f18aba3885f6b6aab7753 \ + --hash=sha256:f7e507e1e798ebca77ddc9774fd405107833315ad802cfdaa1ab07b6d9154fc8 \ + --hash=sha256:fbbffb948a32f9783d1a28bc0c53616f0a76736ed1e7c1d62e3e99a8dfaab869 \ + --hash=sha256:fd87d112eda1f0528074e1f7c0312881816cb75854133021124269a27c6c48dc \ + --hash=sha256:ff06e4aa781aa4f68fbfaf1e727fe221fa1c552fef8ae70b6d2a0178e1f229ad + # via easyocr +python-dateutil==2.9.0 \ + --hash=sha256:78e73e19c63f5b20ffa567001531680d939dc042bf7850431877645523c66709 \ + --hash=sha256:cbf2f1da5e6083ac2fbfd4da39a25f34312230110440f424a14c7558bb85d82e + # via + # feast (setup.py) + # aiobotocore + # arrow + # botocore + # elasticsearch + # google-cloud-bigquery + # great-expectations + # ibis-framework + # jupyter-client + # kubernetes + # moto + # pandas + # trino +python-docx==1.2.0 \ + --hash=sha256:3fd478f3250fbbbfd3b94fe1e985955737c145627498896a8a6bf81f4baf66c7 \ + --hash=sha256:7bc9d7b7d8a69c9c02ca09216118c86552704edc23bac179283f2e38f86220ce + # via docling +python-dotenv==1.2.1 \ + --hash=sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6 \ + --hash=sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61 + # via + # pydantic-settings + # pymilvus + # testcontainers + # uvicorn +python-json-logger==4.0.0 \ + --hash=sha256:af09c9daf6a813aa4cc7180395f50f2a9e5fa056034c9953aec92e381c5ba1e2 \ + --hash=sha256:f58e68eb46e1faed27e0f574a55a0455eecd7b8a5b88b85a784519ba3cff047f + # via jupyter-events +python-keycloak==4.2.2 \ + --hash=sha256:1d43a1accd4a038ed39317fcb3eb78211df6c75bbcbc4c482c99ee76327136f2 \ + --hash=sha256:5137fd87c69031a372a578df96bae96b9aead2c9dad976613bc978e9e0246a1e + # via feast (setup.py) +python-multipart==0.0.21 \ + --hash=sha256:7137ebd4d3bbf70ea1622998f902b97a29434a9e8dc40eb203bbcf7c2a2cba92 \ + --hash=sha256:cf7a6713e01c87aa35387f4774e812c4361150938d20d232800f75ffcf266090 + # via mcp +python-pptx==1.0.2 \ + --hash=sha256:160838e0b8565a8b1f67947675886e9fea18aa5e795db7ae531606d68e785cba \ + --hash=sha256:479a8af0eaf0f0d76b6f00b0887732874ad2e3188230315290cd1f9dd9cc7095 + # via docling +pytz==2025.2 \ + --hash=sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3 \ + --hash=sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 + # via + # clickhouse-connect + # great-expectations + # ibis-framework + # pandas + # snowflake-connector-python + # trino +pyyaml==6.0.3 \ + --hash=sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c \ + --hash=sha256:0150219816b6a1fa26fb4699fb7daa9caf09eb1999f3b70fb6e786805e80375a \ + --hash=sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3 \ + --hash=sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956 \ + --hash=sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6 \ + --hash=sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c \ + --hash=sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65 \ + --hash=sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a \ + --hash=sha256:1ebe39cb5fc479422b83de611d14e2c0d3bb2a18bbcb01f229ab3cfbd8fee7a0 \ + --hash=sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b \ + --hash=sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1 \ + --hash=sha256:22ba7cfcad58ef3ecddc7ed1db3409af68d023b7f940da23c6c2a1890976eda6 \ + --hash=sha256:27c0abcb4a5dac13684a37f76e701e054692a9b2d3064b70f5e4eb54810553d7 \ + --hash=sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e \ + --hash=sha256:2e71d11abed7344e42a8849600193d15b6def118602c4c176f748e4583246007 \ + --hash=sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310 \ + --hash=sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4 \ + --hash=sha256:3c5677e12444c15717b902a5798264fa7909e41153cdf9ef7ad571b704a63dd9 \ + --hash=sha256:3ff07ec89bae51176c0549bc4c63aa6202991da2d9a6129d7aef7f1407d3f295 \ + --hash=sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea \ + --hash=sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0 \ + --hash=sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e \ + --hash=sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac \ + --hash=sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9 \ + --hash=sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7 \ + --hash=sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35 \ + --hash=sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb \ + --hash=sha256:5cf4e27da7e3fbed4d6c3d8e797387aaad68102272f8f9752883bc32d61cb87b \ + --hash=sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69 \ + --hash=sha256:5ed875a24292240029e4483f9d4a4b8a1ae08843b9c54f43fcc11e404532a8a5 \ + --hash=sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b \ + --hash=sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c \ + --hash=sha256:6344df0d5755a2c9a276d4473ae6b90647e216ab4757f8426893b5dd2ac3f369 \ + --hash=sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd \ + --hash=sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824 \ + --hash=sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198 \ + --hash=sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065 \ + --hash=sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c \ + --hash=sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c \ + --hash=sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764 \ + --hash=sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196 \ + --hash=sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b \ + --hash=sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00 \ + --hash=sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac \ + --hash=sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8 \ + --hash=sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e \ + --hash=sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28 \ + --hash=sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3 \ + --hash=sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5 \ + --hash=sha256:9c57bb8c96f6d1808c030b1687b9b5fb476abaa47f0db9c0101f5e9f394e97f4 \ + --hash=sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b \ + --hash=sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf \ + --hash=sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5 \ + --hash=sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702 \ + --hash=sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8 \ + --hash=sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788 \ + --hash=sha256:b865addae83924361678b652338317d1bd7e79b1f4596f96b96c77a5a34b34da \ + --hash=sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d \ + --hash=sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc \ + --hash=sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c \ + --hash=sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba \ + --hash=sha256:c2514fceb77bc5e7a2f7adfaa1feb2fb311607c9cb518dbc378688ec73d8292f \ + --hash=sha256:c3355370a2c156cffb25e876646f149d5d68f5e0a3ce86a5084dd0b64a994917 \ + --hash=sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5 \ + --hash=sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26 \ + --hash=sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f \ + --hash=sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b \ + --hash=sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be \ + --hash=sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c \ + --hash=sha256:efd7b85f94a6f21e4932043973a7ba2613b059c4a000551892ac9f1d11f5baf3 \ + --hash=sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6 \ + --hash=sha256:fa160448684b4e94d80416c0fa4aac48967a969efe22931448d853ada8baf926 \ + --hash=sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0 + # via + # feast (setup.py) + # accelerate + # dask + # datasets + # docling-core + # easyocr + # huggingface-hub + # ibis-substrait + # jupyter-events + # kubernetes + # openshift-client + # pre-commit + # ray + # responses + # timm + # transformers + # uvicorn +pyzmq==27.1.0 \ + --hash=sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d \ + --hash=sha256:01f9437501886d3a1dd4b02ef59fb8cc384fa718ce066d52f175ee49dd5b7ed8 \ + --hash=sha256:03ff0b279b40d687691a6217c12242ee71f0fba28bf8626ff50e3ef0f4410e1e \ + --hash=sha256:05b12f2d32112bf8c95ef2e74ec4f1d4beb01f8b5e703b38537f8849f92cb9ba \ + --hash=sha256:0790a0161c281ca9723f804871b4027f2e8b5a528d357c8952d08cd1a9c15581 \ + --hash=sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05 \ + --hash=sha256:08e90bb4b57603b84eab1d0ca05b3bbb10f60c1839dc471fc1c9e1507bef3386 \ + --hash=sha256:0c996ded912812a2fcd7ab6574f4ad3edc27cb6510349431e4930d4196ade7db \ + --hash=sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28 \ + --hash=sha256:15c8bd0fe0dabf808e2d7a681398c4e5ded70a551ab47482067a572c054c8e2e \ + --hash=sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea \ + --hash=sha256:18339186c0ed0ce5835f2656cdfb32203125917711af64da64dbaa3d949e5a1b \ + --hash=sha256:18770c8d3563715387139060d37859c02ce40718d1faf299abddcdcc6a649066 \ + --hash=sha256:190cbf120fbc0fc4957b56866830def56628934a9d112aec0e2507aa6a032b97 \ + --hash=sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0 \ + --hash=sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113 \ + --hash=sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92 \ + --hash=sha256:1f8426a01b1c4098a750973c37131cf585f61c7911d735f729935a0c701b68d3 \ + --hash=sha256:226b091818d461a3bef763805e75685e478ac17e9008f49fce2d3e52b3d58b86 \ + --hash=sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd \ + --hash=sha256:346e9ba4198177a07e7706050f35d733e08c1c1f8ceacd5eb6389d653579ffbc \ + --hash=sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233 \ + --hash=sha256:3970778e74cb7f85934d2b926b9900e92bfe597e62267d7499acc39c9c28e345 \ + --hash=sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31 \ + --hash=sha256:448f9cb54eb0cee4732b46584f2710c8bc178b0e5371d9e4fc8125201e413a74 \ + --hash=sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc \ + --hash=sha256:49d3980544447f6bd2968b6ac913ab963a49dcaa2d4a2990041f16057b04c429 \ + --hash=sha256:4a19387a3dddcc762bfd2f570d14e2395b2c9701329b266f83dd87a2b3cbd381 \ + --hash=sha256:4c618fbcd069e3a29dcd221739cacde52edcc681f041907867e0f5cc7e85f172 \ + --hash=sha256:50081a4e98472ba9f5a02850014b4c9b629da6710f8f14f3b15897c666a28f1b \ + --hash=sha256:507b6f430bdcf0ee48c0d30e734ea89ce5567fd7b8a0f0044a369c176aa44556 \ + --hash=sha256:508e23ec9bc44c0005c4946ea013d9317ae00ac67778bd47519fdf5a0e930ff4 \ + --hash=sha256:510869f9df36ab97f89f4cff9d002a89ac554c7ac9cadd87d444aa4cf66abd27 \ + --hash=sha256:53b40f8ae006f2734ee7608d59ed661419f087521edbfc2149c3932e9c14808c \ + --hash=sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd \ + --hash=sha256:5bbf8d3630bf96550b3be8e1fc0fea5cbdc8d5466c1192887bd94869da17a63e \ + --hash=sha256:677e744fee605753eac48198b15a2124016c009a11056f93807000ab11ce6526 \ + --hash=sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e \ + --hash=sha256:6df079c47d5902af6db298ec92151db82ecb557af663098b92f2508c398bb54f \ + --hash=sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128 \ + --hash=sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96 \ + --hash=sha256:722ea791aa233ac0a819fc2c475e1292c76930b31f1d828cb61073e2fe5e208f \ + --hash=sha256:726b6a502f2e34c6d2ada5e702929586d3ac948a4dbbb7fed9854ec8c0466027 \ + --hash=sha256:753d56fba8f70962cd8295fb3edb40b9b16deaa882dd2b5a3a2039f9ff7625aa \ + --hash=sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f \ + --hash=sha256:7be883ff3d722e6085ee3f4afc057a50f7f2e0c72d289fd54df5706b4e3d3a50 \ + --hash=sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c \ + --hash=sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2 \ + --hash=sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146 \ + --hash=sha256:849ca054d81aa1c175c49484afaaa5db0622092b5eccb2055f9f3bb8f703782d \ + --hash=sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97 \ + --hash=sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5 \ + --hash=sha256:9541c444cfe1b1c0156c5c86ece2bb926c7079a18e7b47b0b1b3b1b875e5d098 \ + --hash=sha256:96c71c32fff75957db6ae33cd961439f386505c6e6b377370af9b24a1ef9eafb \ + --hash=sha256:9a916f76c2ab8d045b19f2286851a38e9ac94ea91faf65bd64735924522a8b32 \ + --hash=sha256:9c1790386614232e1b3a40a958454bdd42c6d1811837b15ddbb052a032a43f62 \ + --hash=sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf \ + --hash=sha256:a1aa0ee920fb3825d6c825ae3f6c508403b905b698b6460408ebd5bb04bbb312 \ + --hash=sha256:a5b42d7a0658b515319148875fcb782bbf118dd41c671b62dae33666c2213bda \ + --hash=sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540 \ + --hash=sha256:ac25465d42f92e990f8d8b0546b01c391ad431c3bf447683fdc40565941d0604 \ + --hash=sha256:ad68808a61cbfbbae7ba26d6233f2a4aa3b221de379ce9ee468aa7a83b9c36b0 \ + --hash=sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db \ + --hash=sha256:b1267823d72d1e40701dcba7edc45fd17f71be1285557b7fe668887150a14b78 \ + --hash=sha256:b2e592db3a93128daf567de9650a2f3859017b3f7a66bc4ed6e4779d6034976f \ + --hash=sha256:b721c05d932e5ad9ff9344f708c96b9e1a485418c6618d765fca95d4daacfbef \ + --hash=sha256:bafcb3dd171b4ae9f19ee6380dfc71ce0390fefaf26b504c0e5f628d7c8c54f2 \ + --hash=sha256:bd67e7c8f4654bef471c0b1ca6614af0b5202a790723a58b79d9584dc8022a78 \ + --hash=sha256:bf7b38f9fd7b81cb6d9391b2946382c8237fd814075c6aa9c3b746d53076023b \ + --hash=sha256:c0bb87227430ee3aefcc0ade2088100e528d5d3298a0a715a64f3d04c60ba02f \ + --hash=sha256:c17e03cbc9312bee223864f1a2b13a99522e0dc9f7c5df0177cd45210ac286e6 \ + --hash=sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39 \ + --hash=sha256:c895a6f35476b0c3a54e3eb6ccf41bf3018de937016e6e18748317f25d4e925f \ + --hash=sha256:c9f7f6e13dff2e44a6afeaf2cf54cee5929ad64afaf4d40b50f93c58fc687355 \ + --hash=sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a \ + --hash=sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a \ + --hash=sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856 \ + --hash=sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9 \ + --hash=sha256:da96ecdcf7d3919c3be2de91a8c513c186f6762aa6cf7c01087ed74fad7f0968 \ + --hash=sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7 \ + --hash=sha256:dd2fec2b13137416a1c5648b7009499bcc8fea78154cd888855fa32514f3dad1 \ + --hash=sha256:df7cd397ece96cf20a76fae705d40efbab217d217897a5053267cd88a700c266 \ + --hash=sha256:e2687c2d230e8d8584fbea433c24382edfeda0c60627aca3446aa5e58d5d1831 \ + --hash=sha256:e30a74a39b93e2e1591b58eb1acef4902be27c957a8720b0e368f579b82dc22f \ + --hash=sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7 \ + --hash=sha256:e829529fcaa09937189178115c49c504e69289abd39967cd8a4c215761373394 \ + --hash=sha256:eca6b47df11a132d1745eb3b5b5e557a7dae2c303277aa0e69c6ba91b8736e07 \ + --hash=sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496 \ + --hash=sha256:f328d01128373cb6763823b2b4e7f73bdf767834268c565151eacb3b7a392f90 \ + --hash=sha256:f605d884e7c8be8fe1aa94e0a783bf3f591b84c24e4bc4f3e7564c82ac25e271 \ + --hash=sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6 \ + --hash=sha256:ff8d114d14ac671d88c89b9224c63d6c4e5a613fe8acd5594ce53d752a3aafe9 + # via + # ipykernel + # jupyter-client + # jupyter-server +qdrant-client==1.16.2 \ + --hash=sha256:442c7ef32ae0f005e88b5d3c0783c63d4912b97ae756eb5e052523be682f17d3 \ + --hash=sha256:ca4ef5f9be7b5eadeec89a085d96d5c723585a391eb8b2be8192919ab63185f0 + # via feast (setup.py) +ray[data, default]==2.52.1 \ + --hash=sha256:08eb8f5fd55292ba6bee363a32491136a5e54af54e007f81e0603986fbea41a4 \ + --hash=sha256:24694e60cdc7770b90f123cc578cabb9d1a231c1fe673b5da0027b118de45846 \ + --hash=sha256:2b57ef272a2a0a0dbae6d18d70aa541eab620b4fe3b44d50466d3a533c16f9d9 \ + --hash=sha256:4e8478544fef69a17d865431c0bebdcfeff7c0f76a306f29b73c3bc3cbb0bdb9 \ + --hash=sha256:65bf461fdfe4ffa667c46f9455f8740b2ad6c1fa471b461d5f5cf6b7baf177b5 \ + --hash=sha256:6831592fedf0a122016f5dab4b67d85fa3d4db3b21f588d18834b5c031396d1c \ + --hash=sha256:8045172ad3fcff62b9dab9a4cd2e0991ad0e27fc814fe625a8d3a120306651d6 \ + --hash=sha256:843c0108ad72bb7fc6c23a22e29e6099546a5eaad3ad675c78a146d9080f6ec6 \ + --hash=sha256:993194a8be70540e0f819862031bbf19a64401fbe6c31b42065fd313ba466d34 \ + --hash=sha256:a5a3c268d45060c50cd029979ecc5f1eaaec040b19fa88dd4fe9e927d19ff13e \ + --hash=sha256:b3f9e61b799fb3cc8fd7077a3d2eb676ddfef7db644f6b6a2b657c5c3214cf19 \ + --hash=sha256:b5bc29548abb0a0a7ae9e6ff3b0ccca2824edaf011a4336e15a32793d574fbfd \ + --hash=sha256:bbe492c780a39a64bd3d0766cad10d54cf12222df88d287ec2d8f2d52de37c79 \ + --hash=sha256:e3826aeb4e4399de0c6885bd8be7ce2f629fa0010f0013f1183e0726b3d25e40 \ + --hash=sha256:f59e3b2d1a1466ac0778f2c6fac9ccb5f30107d77e3dddd1d60167248d268474 + # via codeflare-sdk +redis==4.6.0 \ + --hash=sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d \ + --hash=sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c + # via feast (setup.py) +referencing==0.37.0 \ + --hash=sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231 \ + --hash=sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8 + # via + # jsonschema + # jsonschema-specifications + # jupyter-events +regex==2026.1.15 \ + --hash=sha256:0057de9eaef45783ff69fa94ae9f0fd906d629d0bd4c3217048f46d1daa32e9b \ + --hash=sha256:008b185f235acd1e53787333e5690082e4f156c44c87d894f880056089e9bc7c \ + --hash=sha256:05d75a668e9ea16f832390d22131fe1e8acc8389a694c8febc3e340b0f810b93 \ + --hash=sha256:069f56a7bf71d286a6ff932a9e6fb878f151c998ebb2519a9f6d1cee4bffdba3 \ + --hash=sha256:0751a26ad39d4f2ade8fe16c59b2bf5cb19eb3d2cd543e709e583d559bd9efde \ + --hash=sha256:08df9722d9b87834a3d701f3fca570b2be115654dbfd30179f30ab2f39d606d3 \ + --hash=sha256:0bda75ebcac38d884240914c6c43d8ab5fb82e74cde6da94b43b17c411aa4c2b \ + --hash=sha256:0bf065240704cb8951cc04972cf107063917022511273e0969bdb34fc173456c \ + --hash=sha256:0bf650f26087363434c4e560011f8e4e738f6f3e029b85d4904c50135b86cfa5 \ + --hash=sha256:0dcd31594264029b57bf16f37fd7248a70b3b764ed9e0839a8f271b2d22c0785 \ + --hash=sha256:0f0c7684c7f9ca241344ff95a1de964f257a5251968484270e91c25a755532c5 \ + --hash=sha256:124dc36c85d34ef2d9164da41a53c1c8c122cfb1f6e1ec377a1f27ee81deb794 \ + --hash=sha256:164759aa25575cbc0651bef59a0b18353e54300d79ace8084c818ad8ac72b7d5 \ + --hash=sha256:166551807ec20d47ceaeec380081f843e88c8949780cd42c40f18d16168bed10 \ + --hash=sha256:1704d204bd42b6bb80167df0e4554f35c255b579ba99616def38f69e14a5ccb9 \ + --hash=sha256:18388a62989c72ac24de75f1449d0fb0b04dfccd0a1a7c1c43af5eb503d890f6 \ + --hash=sha256:194312a14819d3e44628a44ed6fea6898fdbecb0550089d84c403475138d0a09 \ + --hash=sha256:1ae6020fb311f68d753b7efa9d4b9a5d47a5d6466ea0d5e3b5a471a960ea6e4a \ + --hash=sha256:1cb740d044aff31898804e7bf1181cc72c03d11dfd19932b9911ffc19a79070a \ + --hash=sha256:1e1808471fbe44c1a63e5f577a1d5f02fe5d66031dcbdf12f093ffc1305a858e \ + --hash=sha256:1e8cd52557603f5c66a548f69421310886b28b7066853089e1a71ee710e1cdc1 \ + --hash=sha256:21ca32c28c30d5d65fc9886ff576fc9b59bbca08933e844fa2363e530f4c8218 \ + --hash=sha256:2748c1ec0663580b4510bd89941a31560b4b439a0b428b49472a3d9944d11cd8 \ + --hash=sha256:27618391db7bdaf87ac6c92b31e8f0dfb83a9de0075855152b720140bda177a2 \ + --hash=sha256:2a8d7b50c34578d0d3bf7ad58cde9652b7d683691876f83aedc002862a35dc5e \ + --hash=sha256:2b091aefc05c78d286657cd4db95f2e6313375ff65dcf085e42e4c04d9c8d410 \ + --hash=sha256:2c2b80399a422348ce5de4fe40c418d6299a0fa2803dd61dc0b1a2f28e280fcf \ + --hash=sha256:2f2775843ca49360508d080eaa87f94fa248e2c946bbcd963bb3aae14f333413 \ + --hash=sha256:3038a62fc7d6e5547b8915a3d927a0fbeef84cdbe0b1deb8c99bbd4a8961b52a \ + --hash=sha256:32655d17905e7ff8ba5c764c43cb124e34a9245e45b83c22e81041e1071aee10 \ + --hash=sha256:343db82cb3712c31ddf720f097ef17c11dab2f67f7a3e7be976c4f82eba4e6df \ + --hash=sha256:3601ffb5375de85a16f407854d11cca8fe3f5febbe3ac78fb2866bb220c74d10 \ + --hash=sha256:3d6ce5ae80066b319ae3bc62fd55a557c9491baa5efd0d355f0de08c4ba54e79 \ + --hash=sha256:3d7d92495f47567a9b1669c51fc8d6d809821849063d168121ef801bbc213846 \ + --hash=sha256:40c86d8046915bb9aeb15d3f3f15b6fd500b8ea4485b30e1bbc799dab3fe29f8 \ + --hash=sha256:4161d87f85fa831e31469bfd82c186923070fc970b9de75339b68f0c75b51903 \ + --hash=sha256:41aef6f953283291c4e4e6850607bd71502be67779586a61472beacb315c97ec \ + --hash=sha256:453078802f1b9e2b7303fb79222c054cb18e76f7bdc220f7530fdc85d319f99e \ + --hash=sha256:492534a0ab925d1db998defc3c302dae3616a2fc3fe2e08db1472348f096ddf2 \ + --hash=sha256:4c5ef43b5c2d4114eb8ea424bb8c9cec01d5d17f242af88b2448f5ee81caadbc \ + --hash=sha256:4c8fcc5793dde01641a35905d6731ee1548f02b956815f8f1cab89e515a5bdf1 \ + --hash=sha256:4def140aa6156bc64ee9912383d4038f3fdd18fee03a6f222abd4de6357ce42a \ + --hash=sha256:4e3dd93c8f9abe8aa4b6c652016da9a3afa190df5ad822907efe6b206c09896e \ + --hash=sha256:505831646c945e3e63552cc1b1b9b514f0e93232972a2d5bedbcc32f15bc82e3 \ + --hash=sha256:5170907244b14303edc5978f522f16c974f32d3aa92109fabc2af52411c9433b \ + --hash=sha256:55b4ea996a8e4458dd7b584a2f89863b1655dd3d17b88b46cbb9becc495a0ec5 \ + --hash=sha256:55e9d0118d97794367309635df398bdfd7c33b93e2fdfa0b239661cd74b4c14e \ + --hash=sha256:56a5595d0f892f214609c9f76b41b7428bed439d98dc961efafdd1354d42baae \ + --hash=sha256:57e7d17f59f9ebfa9667e6e5a1c0127b96b87cb9cede8335482451ed00788ba4 \ + --hash=sha256:5ef19071f4ac9f0834793af85bd04a920b4407715624e40cb7a0631a11137cdf \ + --hash=sha256:5ff818702440a5878a81886f127b80127f5d50563753a28211482867f8318106 \ + --hash=sha256:619843841e220adca114118533a574a9cd183ed8a28b85627d2844c500a2b0db \ + --hash=sha256:621f73a07595d83f28952d7bd1e91e9d1ed7625fb7af0064d3516674ec93a2a2 \ + --hash=sha256:693b465171707bbe882a7a05de5e866f33c76aa449750bee94a8d90463533cc9 \ + --hash=sha256:6bfc31a37fd1592f0c4fc4bfc674b5c42e52efe45b4b7a6a14f334cca4bcebe4 \ + --hash=sha256:6d220a2517f5893f55daac983bfa9fe998a7dbcaee4f5d27a88500f8b7873788 \ + --hash=sha256:6e42844ad64194fa08d5ccb75fe6a459b9b08e6d7296bd704460168d58a388f3 \ + --hash=sha256:726ea4e727aba21643205edad8f2187ec682d3305d790f73b7a51c7587b64bdd \ + --hash=sha256:74f45d170a21df41508cb67165456538425185baaf686281fa210d7e729abc34 \ + --hash=sha256:7dcc02368585334f5bc81fc73a2a6a0bbade60e7d83da21cead622faf408f32c \ + --hash=sha256:7e1e28be779884189cdd57735e997f282b64fd7ccf6e2eef3e16e57d7a34a815 \ + --hash=sha256:7ef7d5d4bd49ec7364315167a4134a015f61e8266c6d446fc116a9ac4456e10d \ + --hash=sha256:8050ba2e3ea1d8731a549e83c18d2f0999fbc99a5f6bd06b4c91449f55291804 \ + --hash=sha256:82345326b1d8d56afbe41d881fdf62f1926d7264b2fc1537f99ae5da9aad7913 \ + --hash=sha256:8355ad842a7c7e9e5e55653eade3b7d1885ba86f124dd8ab1f722f9be6627434 \ + --hash=sha256:86c1077a3cc60d453d4084d5b9649065f3bf1184e22992bd322e1f081d3117fb \ + --hash=sha256:87adf5bd6d72e3e17c9cb59ac4096b1faaf84b7eb3037a5ffa61c4b4370f0f13 \ + --hash=sha256:8db052bbd981e1666f09e957f3790ed74080c2229007c1dd67afdbf0b469c48b \ + --hash=sha256:8dd16fba2758db7a3780a051f245539c4451ca20910f5a5e6ea1c08d06d4a76b \ + --hash=sha256:8e32f7896f83774f91499d239e24cebfadbc07639c1494bb7213983842348337 \ + --hash=sha256:91c5036ebb62663a6b3999bdd2e559fd8456d17e2b485bf509784cd31a8b1705 \ + --hash=sha256:9250d087bc92b7d4899ccd5539a1b2334e44eee85d848c4c1aef8e221d3f8c8f \ + --hash=sha256:9479cae874c81bf610d72b85bb681a94c95722c127b55445285fb0e2c82db8e1 \ + --hash=sha256:968c14d4f03e10b2fd960f1d5168c1f0ac969381d3c1fcc973bc45fb06346599 \ + --hash=sha256:97499ff7862e868b1977107873dd1a06e151467129159a6ffd07b66706ba3a9f \ + --hash=sha256:99ad739c3686085e614bf77a508e26954ff1b8f14da0e3765ff7abbf7799f952 \ + --hash=sha256:9d787e3310c6a6425eb346be4ff2ccf6eece63017916fd77fe8328c57be83521 \ + --hash=sha256:a1774cd1981cd212506a23a14dba7fdeaee259f5deba2df6229966d9911e767a \ + --hash=sha256:a30a68e89e5a218b8b23a52292924c1f4b245cb0c68d1cce9aec9bbda6e2c160 \ + --hash=sha256:adc97a9077c2696501443d8ad3fa1b4fc6d131fc8fd7dfefd1a723f89071cf0a \ + --hash=sha256:b0d190e6f013ea938623a58706d1469a62103fb2a241ce2873a9906e0386582c \ + --hash=sha256:b10e42a6de0e32559a92f2f8dc908478cc0fa02838d7dbe764c44dca3fa13569 \ + --hash=sha256:b2a13dd6a95e95a489ca242319d18fc02e07ceb28fa9ad146385194d95b3c829 \ + --hash=sha256:b30bcbd1e1221783c721483953d9e4f3ab9c5d165aa709693d3f3946747b1aea \ + --hash=sha256:b325d4714c3c48277bfea1accd94e193ad6ed42b4bad79ad64f3b8f8a31260a5 \ + --hash=sha256:b5a28980a926fa810dbbed059547b02783952e2efd9c636412345232ddb87ff6 \ + --hash=sha256:b5f7d8d2867152cdb625e72a530d2ccb48a3d199159144cbdd63870882fb6f80 \ + --hash=sha256:bfb0d6be01fbae8d6655c8ca21b3b72458606c4aec9bbc932db758d47aba6db1 \ + --hash=sha256:bfd876041a956e6a90ad7cdb3f6a630c07d491280bfeed4544053cd434901681 \ + --hash=sha256:c08c1f3e34338256732bd6938747daa3c0d5b251e04b6e43b5813e94d503076e \ + --hash=sha256:c243da3436354f4af6c3058a3f81a97d47ea52c9bd874b52fd30274853a1d5df \ + --hash=sha256:c32bef3e7aeee75746748643667668ef941d28b003bfc89994ecf09a10f7a1b5 \ + --hash=sha256:c661fc820cfb33e166bf2450d3dadbda47c8d8981898adb9b6fe24e5e582ba60 \ + --hash=sha256:c6c4dcdfff2c08509faa15d36ba7e5ef5fcfab25f1e8f85a0c8f45bc3a30725d \ + --hash=sha256:c6c565d9a6e1a8d783c1948937ffc377dd5771e83bd56de8317c450a954d2056 \ + --hash=sha256:c8a154cf6537ebbc110e24dabe53095e714245c272da9c1be05734bdad4a61aa \ + --hash=sha256:c9c08c2fbc6120e70abff5d7f28ffb4d969e14294fb2143b4b5c7d20e46d1714 \ + --hash=sha256:ca89c5e596fc05b015f27561b3793dc2fa0917ea0d7507eebb448efd35274a70 \ + --hash=sha256:cc7cd0b2be0f0269283a45c0d8b2c35e149d1319dcb4a43c9c3689fa935c1ee6 \ + --hash=sha256:cda1ed70d2b264952e88adaa52eea653a33a1b98ac907ae2f86508eb44f65cdc \ + --hash=sha256:cf8ff04c642716a7f2048713ddc6278c5fd41faa3b9cab12607c7abecd012c22 \ + --hash=sha256:cfecdaa4b19f9ca534746eb3b55a5195d5c95b88cac32a205e981ec0a22b7d31 \ + --hash=sha256:d426616dae0967ca225ab12c22274eb816558f2f99ccb4a1d52ca92e8baf180f \ + --hash=sha256:d5eaa4a4c5b1906bd0d2508d68927f15b81821f85092e06f1a34a4254b0e1af3 \ + --hash=sha256:d639a750223132afbfb8f429c60d9d318aeba03281a5f1ab49f877456448dcf1 \ + --hash=sha256:d920392a6b1f353f4aa54328c867fec3320fa50657e25f64abf17af054fc97ac \ + --hash=sha256:d991483606f3dbec93287b9f35596f41aa2e92b7c2ebbb935b63f409e243c9af \ + --hash=sha256:d9ea2604370efc9a174c1b5dcc81784fb040044232150f7f33756049edfc9026 \ + --hash=sha256:dbaf3c3c37ef190439981648ccbf0c02ed99ae066087dd117fcb616d80b010a4 \ + --hash=sha256:dca3582bca82596609959ac39e12b7dad98385b4fefccb1151b937383cec547d \ + --hash=sha256:e3174a5ed4171570dc8318afada56373aa9289eb6dc0d96cceb48e7358b0e220 \ + --hash=sha256:e43a55f378df1e7a4fa3547c88d9a5a9b7113f653a66821bcea4718fe6c58763 \ + --hash=sha256:e69d0deeb977ffe7ed3d2e4439360089f9c3f217ada608f0f88ebd67afb6385e \ + --hash=sha256:e85dc94595f4d766bd7d872a9de5ede1ca8d3063f3bdf1e2c725f5eb411159e3 \ + --hash=sha256:e90b8db97f6f2c97eb045b51a6b2c5ed69cedd8392459e0642d4199b94fabd7e \ + --hash=sha256:e9bf3f0bbdb56633c07d7116ae60a576f846efdd86a8848f8d62b749e1209ca7 \ + --hash=sha256:ea4e6b3566127fda5e007e90a8fd5a4169f0cf0619506ed426db647f19c8454a \ + --hash=sha256:ec94c04149b6a7b8120f9f44565722c7ae31b7a6d2275569d2eefa76b83da3be \ + --hash=sha256:eddf73f41225942c1f994914742afa53dc0d01a6e20fe14b878a1b1edc74151f \ + --hash=sha256:ee6854c9000a10938c79238de2379bea30c82e4925a371711af45387df35cab8 \ + --hash=sha256:ef71d476caa6692eea743ae5ea23cde3260677f70122c4d258ca952e5c2d4e84 \ + --hash=sha256:f052d1be37ef35a54e394de66136e30fa1191fab64f71fc06ac7bc98c9a84618 \ + --hash=sha256:f1862739a1ffb50615c0fde6bae6569b5efbe08d98e59ce009f68a336f64da75 \ + --hash=sha256:f192a831d9575271a22d804ff1a5355355723f94f31d9eef25f0d45a152fdc1a \ + --hash=sha256:f42e68301ff4afee63e365a5fc302b81bb8ba31af625a671d7acb19d10168a8c \ + --hash=sha256:f7792f27d3ee6e0244ea4697d92b825f9a329ab5230a78c1a68bd274e64b5077 \ + --hash=sha256:f82110ab962a541737bd0ce87978d4c658f06e7591ba899192e2712a517badbb \ + --hash=sha256:f9ca1cbdc0fbfe5e6e6f8221ef2309988db5bcede52443aeaee9a4ad555e0dac \ + --hash=sha256:fd65af65e2aaf9474e468f9e571bd7b189e1df3a61caa59dcbabd0000e4ea839 \ + --hash=sha256:fe2fda4110a3d0bc163c2e0664be44657431440722c5c5315c65155cab92f9e5 \ + --hash=sha256:febd38857b09867d3ed3f4f1af7d241c5c50362e25ef43034995b77a50df494e + # via + # feast (setup.py) + # parsimonious + # transformers +requests==2.32.5 \ + --hash=sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 \ + --hash=sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf + # via + # feast (setup.py) + # azure-core + # datasets + # docker + # docling + # fastapi-mcp + # google-api-core + # google-cloud-bigquery + # google-cloud-storage + # great-expectations + # huggingface-hub + # jupyterlab-server + # kubernetes + # moto + # msal + # python-keycloak + # ray + # requests-oauthlib + # requests-toolbelt + # responses + # singlestoredb + # snowflake-connector-python + # sphinx + # transformers + # trino +requests-oauthlib==2.0.0 \ + --hash=sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36 \ + --hash=sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9 + # via + # google-auth-oauthlib + # kubernetes +requests-toolbelt==1.0.0 \ + --hash=sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6 \ + --hash=sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06 + # via python-keycloak +responses==0.25.8 \ + --hash=sha256:0c710af92def29c8352ceadff0c3fe340ace27cf5af1bbe46fb71275bcd2831c \ + --hash=sha256:9374d047a575c8f781b94454db5cab590b6029505f488d12899ddb10a4af1cf4 + # via moto +rfc3339-validator==0.1.4 \ + --hash=sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b \ + --hash=sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa + # via + # jsonschema + # jupyter-events +rfc3986-validator==0.1.1 \ + --hash=sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9 \ + --hash=sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055 + # via + # jsonschema + # jupyter-events +rfc3987-syntax==1.1.0 \ + --hash=sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f \ + --hash=sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d + # via jsonschema +rich==13.9.4 \ + --hash=sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098 \ + --hash=sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90 + # via + # codeflare-sdk + # fastapi-mcp + # ibis-framework + # typer +rpds-py==0.30.0 \ + --hash=sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f \ + --hash=sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136 \ + --hash=sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3 \ + --hash=sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7 \ + --hash=sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65 \ + --hash=sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4 \ + --hash=sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169 \ + --hash=sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf \ + --hash=sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4 \ + --hash=sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2 \ + --hash=sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c \ + --hash=sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4 \ + --hash=sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3 \ + --hash=sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6 \ + --hash=sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7 \ + --hash=sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89 \ + --hash=sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85 \ + --hash=sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6 \ + --hash=sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa \ + --hash=sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb \ + --hash=sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6 \ + --hash=sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87 \ + --hash=sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856 \ + --hash=sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4 \ + --hash=sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f \ + --hash=sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53 \ + --hash=sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229 \ + --hash=sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad \ + --hash=sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23 \ + --hash=sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db \ + --hash=sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038 \ + --hash=sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27 \ + --hash=sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00 \ + --hash=sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18 \ + --hash=sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083 \ + --hash=sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c \ + --hash=sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738 \ + --hash=sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898 \ + --hash=sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e \ + --hash=sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7 \ + --hash=sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08 \ + --hash=sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6 \ + --hash=sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551 \ + --hash=sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e \ + --hash=sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288 \ + --hash=sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df \ + --hash=sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0 \ + --hash=sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2 \ + --hash=sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05 \ + --hash=sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0 \ + --hash=sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464 \ + --hash=sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5 \ + --hash=sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404 \ + --hash=sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7 \ + --hash=sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139 \ + --hash=sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394 \ + --hash=sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb \ + --hash=sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15 \ + --hash=sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff \ + --hash=sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed \ + --hash=sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6 \ + --hash=sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e \ + --hash=sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95 \ + --hash=sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d \ + --hash=sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950 \ + --hash=sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3 \ + --hash=sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5 \ + --hash=sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97 \ + --hash=sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e \ + --hash=sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e \ + --hash=sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b \ + --hash=sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd \ + --hash=sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad \ + --hash=sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8 \ + --hash=sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425 \ + --hash=sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221 \ + --hash=sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d \ + --hash=sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825 \ + --hash=sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51 \ + --hash=sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e \ + --hash=sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f \ + --hash=sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8 \ + --hash=sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f \ + --hash=sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d \ + --hash=sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07 \ + --hash=sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877 \ + --hash=sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31 \ + --hash=sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58 \ + --hash=sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94 \ + --hash=sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28 \ + --hash=sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000 \ + --hash=sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1 \ + --hash=sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1 \ + --hash=sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7 \ + --hash=sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7 \ + --hash=sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40 \ + --hash=sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d \ + --hash=sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0 \ + --hash=sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84 \ + --hash=sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f \ + --hash=sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a \ + --hash=sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7 \ + --hash=sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419 \ + --hash=sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8 \ + --hash=sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a \ + --hash=sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9 \ + --hash=sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be \ + --hash=sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed \ + --hash=sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a \ + --hash=sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d \ + --hash=sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324 \ + --hash=sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f \ + --hash=sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2 \ + --hash=sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f \ + --hash=sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5 + # via + # jsonschema + # referencing +rsa==4.9.1 \ + --hash=sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762 \ + --hash=sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75 + # via google-auth +rtree==1.4.1 \ + --hash=sha256:12de4578f1b3381a93a655846900be4e3d5f4cd5e306b8b00aa77c1121dc7e8c \ + --hash=sha256:3d46f55729b28138e897ffef32f7ce93ac335cb67f9120125ad3742a220800f0 \ + --hash=sha256:a7e48d805e12011c2cf739a29d6a60ae852fb1de9fc84220bbcef67e6e595d7d \ + --hash=sha256:b558edda52eca3e6d1ee629042192c65e6b7f2c150d6d6cd207ce82f85be3967 \ + --hash=sha256:c6b1b3550881e57ebe530cc6cffefc87cd9bf49c30b37b894065a9f810875e46 \ + --hash=sha256:d672184298527522d4914d8ae53bf76982b86ca420b0acde9298a7a87d81d4a4 \ + --hash=sha256:efa8c4496e31e9ad58ff6c7df89abceac7022d906cb64a3e18e4fceae6b77f65 \ + --hash=sha256:efe125f416fd27150197ab8521158662943a40f87acab8028a1aac4ad667a489 \ + --hash=sha256:f155bc8d6bac9dcd383481dee8c130947a4866db1d16cb6dff442329a038a0dc + # via + # docling + # docling-ibm-models +ruamel-yaml==0.17.17 \ + --hash=sha256:9751de4cbb57d4bfbf8fc394e125ed4a2f170fbff3dc3d78abf50be85924f8be \ + --hash=sha256:9af3ec5d7f8065582f3aa841305465025d0afd26c5fb54e15b964e11838fc74f + # via great-expectations +ruff==0.14.13 \ + --hash=sha256:4acdf009f32b46f6e8864af19cbf6841eaaed8638e65c8dac845aea0d703c841 \ + --hash=sha256:591a7f68860ea4e003917d19b5c4f5ac39ff558f162dc753a2c5de897fd5502c \ + --hash=sha256:6070bd026e409734b9257e03e3ef18c6e1a216f0435c6751d7a8ec69cb59abef \ + --hash=sha256:61f4e40077a1248436772bb6512db5fc4457fe4c49e7a94ea7c5088655dd21ae \ + --hash=sha256:642442b42957093811cd8d2140dfadd19c7417030a7a68cf8d51fcdd5f217427 \ + --hash=sha256:6d02f1428357fae9e98ac7aa94b7e966fd24151088510d32cf6f902d6c09235e \ + --hash=sha256:76f62c62cd37c276cb03a275b198c7c15bd1d60c989f944db08a8c1c2dbec18b \ + --hash=sha256:774c77e841cc6e046fc3e91623ce0903d1cd07e3a36b1a9fe79b81dab3de506b \ + --hash=sha256:78d2b1097750d90ba82ce4ba676e85230a0ed694178ca5e61aa9b459970b3eb9 \ + --hash=sha256:7ab819e14f1ad9fe39f246cfcc435880ef7a9390d81a2b6ac7e01039083dd247 \ + --hash=sha256:7d0bf87705acbbcb8d4c24b2d77fbb73d40210a95c3903b443cd9e30824a5032 \ + --hash=sha256:83cd6c0763190784b99650a20fec7633c59f6ebe41c5cc9d45ee42749563ad47 \ + --hash=sha256:914a8023ece0528d5cc33f5a684f5f38199bbb566a04815c2c211d8f40b5d0ed \ + --hash=sha256:9aaf3870f14d925bbaf18b8a2347ee0ae7d95a2e490e4d4aea6813ed15ebc80e \ + --hash=sha256:a3eb5da8e2c9e9f13431032fdcbe7681de9ceda5835efee3269417c13f1fed5c \ + --hash=sha256:ac5b7f63dd3b27cc811850f5ffd8fff845b00ad70e60b043aabf8d6ecc304e09 \ + --hash=sha256:d24899478c35ebfa730597a4a775d430ad0d5631b8647a3ab368c29b7e7bd063 \ + --hash=sha256:e399341472ce15237be0c0ae5fbceca4b04cd9bebab1a2b2c979e015455d8f0c \ + --hash=sha256:ef720f529aec113968b45dfdb838ac8934e519711da53a0456038a0efecbd680 + # via feast (setup.py) +s3transfer==0.13.1 \ + --hash=sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724 \ + --hash=sha256:c3fdba22ba1bd367922f27ec8032d6a1cf5f10c934fb5d68cf60fd5a23d936cf + # via boto3 +safetensors[torch]==0.7.0 \ + --hash=sha256:0071bffba4150c2f46cae1432d31995d77acfd9f8db598b5d1a2ce67e8440ad2 \ + --hash=sha256:07663963b67e8bd9f0b8ad15bb9163606cd27cc5a1b96235a50d8369803b96b0 \ + --hash=sha256:12f49080303fa6bb424b362149a12949dfbbf1e06811a88f2307276b0c131afd \ + --hash=sha256:1d060c70284127fa805085d8f10fbd0962792aed71879d00864acda69dbab981 \ + --hash=sha256:42cb091236206bb2016d245c377ed383aa7f78691748f3bb6ee1bfa51ae2ce6a \ + --hash=sha256:473b32699f4200e69801bf5abf93f1a4ecd432a70984df164fc22ccf39c4a6f3 \ + --hash=sha256:54bef08bf00a2bff599982f6b08e8770e09cc012d7bba00783fc7ea38f1fb37d \ + --hash=sha256:5d72abdb8a4d56d4020713724ba81dac065fedb7f3667151c4a637f1d3fb26c0 \ + --hash=sha256:672132907fcad9f2aedcb705b2d7b3b93354a2aec1b2f706c4db852abe338f85 \ + --hash=sha256:6999421eb8ba9df4450a16d9184fcb7bef26240b9f98e95401f17af6c2210b71 \ + --hash=sha256:7b95a3fa7b3abb9b5b0e07668e808364d0d40f6bbbf9ae0faa8b5b210c97b140 \ + --hash=sha256:8469155f4cb518bafb4acf4865e8bb9d6804110d2d9bdcaa78564b9fd841e104 \ + --hash=sha256:94fd4858284736bb67a897a41608b5b0c2496c9bdb3bf2af1fa3409127f20d57 \ + --hash=sha256:b0f6d66c1c538d5a94a73aa9ddca8ccc4227e6c9ff555322ea40bdd142391dd4 \ + --hash=sha256:c74af94bf3ac15ac4d0f2a7c7b4663a15f8c2ab15ed0fc7531ca61d0835eccba \ + --hash=sha256:c82f4d474cf725255d9e6acf17252991c3c8aac038d6ef363a4bf8be2f6db517 \ + --hash=sha256:cdab83a366799fa730f90a4ebb563e494f28e9e92c4819e556152ad55e43591b \ + --hash=sha256:cfdead2f57330d76aa7234051dadfa7d4eedc0e5a27fd08e6f96714a92b00f09 \ + --hash=sha256:d1239932053f56f3456f32eb9625590cc7582e905021f94636202a864d470755 \ + --hash=sha256:dac7252938f0696ddea46f5e855dd3138444e82236e3be475f54929f0c510d48 \ + --hash=sha256:dc92bc2db7b45bda4510e4f51c59b00fe80b2d6be88928346e4294ce1c2abe7c \ + --hash=sha256:e07d91d0c92a31200f25351f4acb2bc6aff7f48094e13ebb1d0fb995b54b6542 \ + --hash=sha256:f4729811a6640d019a4b7ba8638ee2fd21fa5ca8c7e7bdf0fed62068fcaac737 + # via + # accelerate + # docling-ibm-models + # timm + # transformers +scikit-image==0.26.0 \ + --hash=sha256:0608aa4a9ec39e0843de10d60edb2785a30c1c47819b67866dd223ebd149acaf \ + --hash=sha256:0660b83968c15293fd9135e8d860053ee19500d52bf55ca4fb09de595a1af650 \ + --hash=sha256:09bad6a5d5949c7896c8347424c4cca899f1d11668030e5548813ab9c2865dcb \ + --hash=sha256:0baa0108d2d027f34d748e84e592b78acc23e965a5de0e4bb03cf371de5c0581 \ + --hash=sha256:163e9afb5b879562b9aeda0dd45208a35316f26cc7a3aed54fd601604e5cf46f \ + --hash=sha256:20ef4a155e2e78b8ab973998e04d8a361d49d719e65412405f4dadd9155a61d9 \ + --hash=sha256:21a818ee6ca2f2131b9e04d8eb7637b5c18773ebe7b399ad23dcc5afaa226d2d \ + --hash=sha256:27d58bc8b2acd351f972c6508c1b557cfed80299826080a4d803dd29c51b707e \ + --hash=sha256:2c1e7bd342f43e7a97e571b3f03ba4c1293ea1a35c3f13f41efdc8a81c1dc8f2 \ + --hash=sha256:3268f13310e6857508bd87202620df996199a016a1d281b309441d227c822394 \ + --hash=sha256:3409e89d66eff5734cd2b672d1c48d2759360057e714e1d92a11df82c87cba37 \ + --hash=sha256:3f5bf622d7c0435884e1e141ebbe4b2804e16b2dd23ae4c6183e2ea99233be70 \ + --hash=sha256:4c717490cec9e276afb0438dd165b7c3072d6c416709cc0f9f5a4c1070d23a44 \ + --hash=sha256:4d57e39ef67a95d26860c8caf9b14b8fb130f83b34c6656a77f191fa6d1d04d8 \ + --hash=sha256:52c496f75a7e45844d951557f13c08c81487c6a1da2e3c9c8a39fcde958e02cc \ + --hash=sha256:6381edf972b32e4f54085449afde64365a57316637496c1325a736987083e2ab \ + --hash=sha256:63af3d3a26125f796f01052052f86806da5b5e54c6abef152edb752683075a9c \ + --hash=sha256:6caec76e16c970c528d15d1c757363334d5cb3069f9cea93d2bead31820511f3 \ + --hash=sha256:724f79fd9b6cb6f4a37864fe09f81f9f5d5b9646b6868109e1b100d1a7019e59 \ + --hash=sha256:74aa5518ccea28121f57a95374581d3b979839adc25bb03f289b1bc9b99c58af \ + --hash=sha256:7af7aa331c6846bd03fa28b164c18d0c3fd419dbb888fb05e958ac4257a78fdd \ + --hash=sha256:7df650e79031634ac90b11e64a9eedaf5a5e06fcd09bcd03a34be01745744466 \ + --hash=sha256:915bb3ba66455cf8adac00dc8fdf18a4cd29656aec7ddd38cb4dda90289a6f21 \ + --hash=sha256:92242351bccf391fc5df2d1529d15470019496d2498d615beb68da85fe7fdf37 \ + --hash=sha256:9490360c8d3f9a7e85c8de87daf7c0c66507960cf4947bb9610d1751928721c7 \ + --hash=sha256:98329aab3bc87db352b9887f64ce8cdb8e75f7c2daa19927f2e121b797b678d5 \ + --hash=sha256:9ea6207d9e9d21c3f464efe733121c0504e494dbdc7728649ff3e23c3c5a4953 \ + --hash=sha256:9eefb4adad066da408a7601c4c24b07af3b472d90e08c3e7483d4e9e829d8c49 \ + --hash=sha256:a07200fe09b9d99fcdab959859fe0f7db8df6333d6204344425d476850ce3604 \ + --hash=sha256:a2d211bc355f59725efdcae699b93b30348a19416cc9e017f7b2fb599faf7219 \ + --hash=sha256:a2e852eccf41d2d322b8e60144e124802873a92b8d43a6f96331aa42888491c7 \ + --hash=sha256:abed017474593cd3056ae0fe948d07d0747b27a085e92df5474f4955dd65aec0 \ + --hash=sha256:ac529eb9dbd5954f9aaa2e3fe9a3fd9661bfe24e134c688587d811a0233127f1 \ + --hash=sha256:aeb14db1ed09ad4bee4ceb9e635547a8d5f3549be67fc6c768c7f923e027e6cd \ + --hash=sha256:b1ede33a0fb3731457eaf53af6361e73dd510f449dac437ab54573b26788baf0 \ + --hash=sha256:b36ab5e778bf50af5ff386c3ac508027dc3aaeccf2161bdf96bde6848f44d21b \ + --hash=sha256:b702c3bb115e1dcf4abf5297429b5c90f2189655888cbed14921f3d26f81d3a4 \ + --hash=sha256:b8d14d3181c21c11170477a42542c1addc7072a90b986675a71266ad17abc37f \ + --hash=sha256:c6624a76c6085218248154cc7e1500e6b488edcd9499004dd0d35040607d7505 \ + --hash=sha256:c9087cf7d0e7f33ab5c46d2068d86d785e70b05400a891f73a13400f1e1faf6a \ + --hash=sha256:cde0bbd57e6795eba83cb10f71a677f7239271121dc950bc060482834a668ad1 \ + --hash=sha256:ce00600cd70d4562ed59f80523e18cdcc1fae0e10676498a01f73c255774aefd \ + --hash=sha256:cefd85033e66d4ea35b525bb0937d7f42d4cdcfed2d1888e1570d5ce450d3932 \ + --hash=sha256:d454b93a6fa770ac5ae2d33570f8e7a321bb80d29511ce4b6b78058ebe176e8c \ + --hash=sha256:d5c244656de905e195a904e36dbc18585e06ecf67d90f0482cbde63d7f9ad59d \ + --hash=sha256:ede4d6d255cc5da9faeb2f9ba7fedbc990abbc652db429f40a16b22e770bb578 \ + --hash=sha256:f5f970ab04efad85c24714321fcc91613fcb64ef2a892a13167df2f3e59199fa \ + --hash=sha256:f775f0e420faac9c2aa6757135f4eb468fb7b70e0b67fa77a5e79be3c30ee331 \ + --hash=sha256:fac96a1f9b06cd771cbbb3cd96c5332f36d4efd839b1d8b053f79e5887acde62 + # via easyocr +scikit-learn==1.8.0 \ + --hash=sha256:00d6f1d66fbcf4eba6e356e1420d33cc06c70a45bb1363cd6f6a8e4ebbbdece2 \ + --hash=sha256:0d6ae97234d5d7079dc0040990a6f7aeb97cb7fa7e8945f1999a429b23569e0a \ + --hash=sha256:146b4d36f800c013d267b29168813f7a03a43ecd2895d04861f1240b564421da \ + --hash=sha256:15fc3b5d19cc2be65404786857f2e13c70c83dd4782676dd6814e3b89dc8f5b9 \ + --hash=sha256:2838551e011a64e3053ad7618dda9310175f7515f1742fa2d756f7c874c05961 \ + --hash=sha256:29ffc74089f3d5e87dfca4c2c8450f88bdc61b0fc6ed5d267f3988f19a1309f6 \ + --hash=sha256:2de443b9373b3b615aec1bb57f9baa6bb3a9bd093f1269ba95c17d870422b271 \ + --hash=sha256:35c007dedb2ffe38fe3ee7d201ebac4a2deccd2408e8621d53067733e3c74809 \ + --hash=sha256:3bad7565bc9cf37ce19a7c0d107742b320c1285df7aab1a6e2d28780df167242 \ + --hash=sha256:4496bb2cf7a43ce1a2d7524a79e40bc5da45cf598dbf9545b7e8316ccba47bb4 \ + --hash=sha256:4511be56637e46c25721e83d1a9cea9614e7badc7040c4d573d75fbe257d6fd7 \ + --hash=sha256:5025ce924beccb28298246e589c691fe1b8c1c96507e6d27d12c5fadd85bfd76 \ + --hash=sha256:56079a99c20d230e873ea40753102102734c5953366972a71d5cb39a32bc40c6 \ + --hash=sha256:5e30adb87f0cc81c7690a84f7932dd66be5bac57cfe16b91cb9151683a4a2d3b \ + --hash=sha256:5fb63362b5a7ddab88e52b6dbb47dac3fd7dafeee740dc6c8d8a446ddedade8e \ + --hash=sha256:6b595b07a03069a2b1740dc08c2299993850ea81cce4fe19b2421e0c970de6b7 \ + --hash=sha256:72358cce49465d140cc4e7792015bb1f0296a9742d5622c67e31399b75468b9e \ + --hash=sha256:74b66d8689d52ed04c271e1329f0c61635bcaf5b926db9b12d58914cdc01fe57 \ + --hash=sha256:7cc267b6108f0a1499a734167282c00c4ebf61328566b55ef262d48e9849c735 \ + --hash=sha256:80832434a6cc114f5219211eec13dcbc16c2bac0e31ef64c6d346cde3cf054cb \ + --hash=sha256:8c497fff237d7b4e07e9ef1a640887fa4fb765647f86fbe00f969ff6280ce2bb \ + --hash=sha256:8fdf95767f989b0cfedb85f7ed8ca215d4be728031f56ff5a519ee1e3276dc2e \ + --hash=sha256:9bccbb3b40e3de10351f8f5068e105d0f4083b1a65fa07b6634fbc401a6287fd \ + --hash=sha256:a0bcfe4d0d14aec44921545fd2af2338c7471de9cb701f1da4c9d85906ab847a \ + --hash=sha256:a69525355a641bf8ef136a7fa447672fb54fe8d60cab5538d9eb7c6438543fb9 \ + --hash=sha256:ada8121bcb4dac28d930febc791a69f7cb1673c8495e5eee274190b73a4559c1 \ + --hash=sha256:bf97c10a3f5a7543f9b88cbf488d33d175e9146115a451ae34568597ba33dcde \ + --hash=sha256:c22a2da7a198c28dd1a6e1136f19c830beab7fdca5b3e5c8bba8394f8a5c45b3 \ + --hash=sha256:c2656924ec73e5939c76ac4c8b026fc203b83d8900362eb2599d8aee80e4880f \ + --hash=sha256:c57b1b610bd1f40ba43970e11ce62821c2e6569e4d74023db19c6b26f246cb3b \ + --hash=sha256:eddde82a035681427cbedded4e6eff5e57fa59216c2e3e90b10b19ab1d0a65c3 \ + --hash=sha256:edec98c5e7c128328124a029bceb09eda2d526997780fef8d65e9a69eead963e \ + --hash=sha256:ee787491dbfe082d9c3013f01f5991658b0f38aa8177e4cd4bf434c58f551702 \ + --hash=sha256:f28dd15c6bb0b66ba09728cf09fd8736c304be29409bd8445a080c1280619e8c \ + --hash=sha256:f984ca4b14914e6b4094c5d52a32ea16b49832c03bd17a110f004db3c223e8e1 \ + --hash=sha256:fb65db5d7531bccf3a4f6bec3462223bea71384e2cda41da0f10b7c292b9e7c4 \ + --hash=sha256:fe1c011a640a9f0791146011dfd3c7d9669785f9fed2b2a5f9e207536cf5c2fd + # via feast (setup.py) +scipy==1.17.0 \ + --hash=sha256:00fb5f8ec8398ad90215008d8b6009c9db9fa924fd4c7d6be307c6f945f9cd73 \ + --hash=sha256:031121914e295d9791319a1875444d55079885bbae5bdc9c5e0f2ee5f09d34ff \ + --hash=sha256:0937a0b0d8d593a198cededd4c439a0ea216a3f36653901ea1f3e4be949056f8 \ + --hash=sha256:0cf46c8013fec9d3694dc572f0b54100c28405d55d3e2cb15e2895b25057996e \ + --hash=sha256:0d5018a57c24cb1dd828bcf51d7b10e65986d549f52ef5adb6b4d1ded3e32a57 \ + --hash=sha256:130d12926ae34399d157de777472bf82e9061c60cc081372b3118edacafe1d00 \ + --hash=sha256:13c4096ac6bc31d706018f06a49abe0485f96499deb82066b94d19b02f664209 \ + --hash=sha256:13e861634a2c480bd237deb69333ac79ea1941b94568d4b0efa5db5e263d4fd1 \ + --hash=sha256:1f9586a58039d7229ce77b52f8472c972448cded5736eaf102d5658bbac4c269 \ + --hash=sha256:1ff269abf702f6c7e67a4b7aad981d42871a11b9dd83c58d2d2ea624efbd1088 \ + --hash=sha256:255c0da161bd7b32a6c898e7891509e8a9289f0b1c6c7d96142ee0d2b114c2ea \ + --hash=sha256:2591060c8e648d8b96439e111ac41fd8342fdeff1876be2e19dea3fe8930454e \ + --hash=sha256:272a9f16d6bb4667e8b50d25d71eddcc2158a214df1b566319298de0939d2ab7 \ + --hash=sha256:2abd71643797bd8a106dff97894ff7869eeeb0af0f7a5ce02e4227c6a2e9d6fd \ + --hash=sha256:2b531f57e09c946f56ad0b4a3b2abee778789097871fc541e267d2eca081cff1 \ + --hash=sha256:30509da9dbec1c2ed8f168b8d8aa853bc6723fede1dbc23c7d43a56f5ab72a67 \ + --hash=sha256:33af70d040e8af9d5e7a38b5ed3b772adddd281e3062ff23fec49e49681c38cf \ + --hash=sha256:357ca001c6e37601066092e7c89cca2f1ce74e2a520ca78d063a6d2201101df2 \ + --hash=sha256:3625c631a7acd7cfd929e4e31d2582cf00f42fcf06011f59281271746d77e061 \ + --hash=sha256:363ad4ae2853d88ebcde3ae6ec46ccca903ea9835ee8ba543f12f575e7b07e4e \ + --hash=sha256:40052543f7bbe921df4408f46003d6f01c6af109b9e2c8a66dd1cf6cf57f7d5d \ + --hash=sha256:423ca1f6584fc03936972b5f7c06961670dbba9f234e71676a7c7ccf938a0d61 \ + --hash=sha256:474da16199f6af66601a01546144922ce402cb17362e07d82f5a6cf8f963e449 \ + --hash=sha256:4e00562e519c09da34c31685f6acc3aa384d4d50604db0f245c14e1b4488bfa2 \ + --hash=sha256:5194c445d0a1c7a6c1a4a4681b6b7c71baad98ff66d96b949097e7513c9d6742 \ + --hash=sha256:5fb10d17e649e1446410895639f3385fd2bf4c3c7dfc9bea937bddcbc3d7b9ba \ + --hash=sha256:65ec32f3d32dfc48c72df4291345dae4f048749bc8d5203ee0a3f347f96c5ce6 \ + --hash=sha256:6680f2dfd4f6182e7d6db161344537da644d1cf85cf293f015c60a17ecf08752 \ + --hash=sha256:6e886000eb4919eae3a44f035e63f0fd8b651234117e8f6f29bad1cd26e7bc45 \ + --hash=sha256:7204fddcbec2fe6598f1c5fdf027e9f259106d05202a959a9f1aecf036adc9f6 \ + --hash=sha256:819fc26862b4b3c73a60d486dbb919202f3d6d98c87cf20c223511429f2d1a97 \ + --hash=sha256:8547e7c57f932e7354a2319fab613981cde910631979f74c9b542bb167a8b9db \ + --hash=sha256:85b0ac3ad17fa3be50abd7e69d583d98792d7edc08367e01445a1e2076005379 \ + --hash=sha256:87b411e42b425b84777718cc41516b8a7e0795abfa8e8e1d573bf0ef014f0812 \ + --hash=sha256:88c22af9e5d5a4f9e027e26772cc7b5922fab8bcc839edb3ae33de404feebd9e \ + --hash=sha256:9244608d27eafe02b20558523ba57f15c689357c85bdcfe920b1828750aa26eb \ + --hash=sha256:979c3a0ff8e5ba254d45d59ebd38cde48fce4f10b5125c680c7a4bfe177aab07 \ + --hash=sha256:9eeb9b5f5997f75507814ed9d298ab23f62cf79f5a3ef90031b1ee2506abdb5b \ + --hash=sha256:9fad7d3578c877d606b1150135c2639e9de9cecd3705caa37b66862977cc3e72 \ + --hash=sha256:a38c3337e00be6fd8a95b4ed66b5d988bac4ec888fd922c2ea9fe5fb1603dd67 \ + --hash=sha256:aabf057c632798832f071a8dde013c2e26284043934f53b00489f1773b33527e \ + --hash=sha256:c17514d11b78be8f7e6331b983a65a7f5ca1fd037b95e27b280921fe5606286a \ + --hash=sha256:c5e8647f60679790c2f5c76be17e2e9247dc6b98ad0d3b065861e082c56e078d \ + --hash=sha256:cacbaddd91fcffde703934897c5cd2c7cb0371fac195d383f4e1f1c5d3f3bd04 \ + --hash=sha256:d7425fcafbc09a03731e1bc05581f5fad988e48c6a861f441b7ab729a49a55ea \ + --hash=sha256:dac97a27520d66c12a34fd90a4fe65f43766c18c0d6e1c0a80f114d2260080e4 \ + --hash=sha256:dbf133ced83889583156566d2bdf7a07ff89228fe0c0cb727f777de92092ec6b \ + --hash=sha256:e8c0b331c2c1f531eb51f1b4fc9ba709521a712cce58f1aa627bc007421a5306 \ + --hash=sha256:eb2651271135154aa24f6481cbae5cc8af1f0dd46e6533fb7b56aa9727b6a232 \ + --hash=sha256:ebb7446a39b3ae0fe8f416a9a3fdc6fba3f11c634f680f16a239c5187bc487c0 \ + --hash=sha256:ec0827aa4d36cb79ff1b81de898e948a51ac0b9b1c43e4a372c0508c38c0f9a3 \ + --hash=sha256:edce1a1cf66298cccdc48a1bdf8fb10a3bf58e8b58d6c3883dd1530e103f87c0 \ + --hash=sha256:eec3842ec9ac9de5917899b277428886042a93db0b227ebbe3a333b64ec7643d \ + --hash=sha256:ef28d815f4d2686503e5f4f00edc387ae58dfd7a2f42e348bb53359538f01558 \ + --hash=sha256:f2a4942b0f5f7c23c7cd641a0ca1955e2ae83dedcff537e3a0259096635e186b \ + --hash=sha256:f3cd947f20fe17013d401b64e857c6b2da83cae567adbb75b9dcba865abc66d8 \ + --hash=sha256:f603d8a5518c7426414d1d8f82e253e454471de682ce5e39c29adb0df1efb86b \ + --hash=sha256:f7df7941d71314e60a481e02d5ebcb3f0185b8d799c70d03d8258f6c80f3d467 \ + --hash=sha256:f9eb55bb97d00f8b7ab95cb64f873eb0bf54d9446264d9f3609130381233483f \ + --hash=sha256:fc02c37a5639ee67d8fb646ffded6d793c06c5622d36b35cfa8fe5ececb8f042 \ + --hash=sha256:fe508b5690e9eaaa9467fc047f833af58f1152ae51a0d0aed67aa5801f4dd7d6 + # via + # docling + # easyocr + # great-expectations + # scikit-image + # scikit-learn +semchunk==2.2.2 \ + --hash=sha256:940e89896e64eeb01de97ba60f51c8c7b96c6a3951dfcf574f25ce2146752f52 \ + --hash=sha256:94ca19020c013c073abdfd06d79a7c13637b91738335f3b8cdb5655ee7cc94d2 + # via docling-core +send2trash==2.1.0 \ + --hash=sha256:0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c \ + --hash=sha256:1c72b39f09457db3c05ce1d19158c2cbef4c32b8bedd02c155e49282b7ea7459 + # via jupyter-server +setuptools==80.9.0 \ + --hash=sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922 \ + --hash=sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c + # via + # feast (setup.py) + # grpcio-tools + # jupyterlab + # pandas-gbq + # pbr + # pip-tools + # pydata-google-auth + # pymilvus + # singlestoredb +shapely==2.1.2 \ + --hash=sha256:0036ac886e0923417932c2e6369b6c52e38e0ff5d9120b90eef5cd9a5fc5cae9 \ + --hash=sha256:01d0d304b25634d60bd7cf291828119ab55a3bab87dc4af1e44b07fb225f188b \ + --hash=sha256:0bd308103340030feef6c111d3eb98d50dc13feea33affc8a6f9fa549e9458a3 \ + --hash=sha256:136ab87b17e733e22f0961504d05e77e7be8c9b5a8184f685b4a91a84efe3c26 \ + --hash=sha256:16a9c722ba774cf50b5d4541242b4cce05aafd44a015290c82ba8a16931ff63d \ + --hash=sha256:16c5d0fc45d3aa0a69074979f4f1928ca2734fb2e0dde8af9611e134e46774e7 \ + --hash=sha256:19efa3611eef966e776183e338b2d7ea43569ae99ab34f8d17c2c054d3205cc0 \ + --hash=sha256:1d0bfb4b8f661b3b4ec3565fa36c340bfb1cda82087199711f86a88647d26b2f \ + --hash=sha256:1e7d4d7ad262a48bb44277ca12c7c78cb1b0f56b32c10734ec9a1d30c0b0c54b \ + --hash=sha256:1f2f33f486777456586948e333a56ae21f35ae273be99255a191f5c1fa302eb4 \ + --hash=sha256:1ff629e00818033b8d71139565527ced7d776c269a49bd78c9df84e8f852190c \ + --hash=sha256:21952dc00df38a2c28375659b07a3979d22641aeb104751e769c3ee825aadecf \ + --hash=sha256:2d93d23bdd2ed9dc157b46bc2f19b7da143ca8714464249bef6771c679d5ff40 \ + --hash=sha256:2ed4ecb28320a433db18a5bf029986aa8afcfd740745e78847e330d5d94922a9 \ + --hash=sha256:2fa78b49485391224755a856ed3b3bd91c8455f6121fee0db0e71cefb07d0ef6 \ + --hash=sha256:346ec0c1a0fcd32f57f00e4134d1200e14bf3f5ae12af87ba83ca275c502498c \ + --hash=sha256:361b6d45030b4ac64ddd0a26046906c8202eb60d0f9f53085f5179f1d23021a0 \ + --hash=sha256:40d784101f5d06a1fd30b55fc11ea58a61be23f930d934d86f19a180909908a4 \ + --hash=sha256:4a44bc62a10d84c11a7a3d7c1c4fe857f7477c3506e24c9062da0db0ae0c449c \ + --hash=sha256:5860eb9f00a1d49ebb14e881f5caf6c2cf472c7fd38bd7f253bbd34f934eb076 \ + --hash=sha256:5ebe3f84c6112ad3d4632b1fd2290665aa75d4cef5f6c5d77c4c95b324527c6a \ + --hash=sha256:61edcd8d0d17dd99075d320a1dd39c0cb9616f7572f10ef91b4b5b00c4aeb566 \ + --hash=sha256:6305993a35989391bd3476ee538a5c9a845861462327efe00dd11a5c8c709a99 \ + --hash=sha256:6ddc759f72b5b2b0f54a7e7cde44acef680a55019eb52ac63a7af2cf17cb9cd2 \ + --hash=sha256:743044b4cfb34f9a67205cee9279feaf60ba7d02e69febc2afc609047cb49179 \ + --hash=sha256:7ae48c236c0324b4e139bea88a306a04ca630f49be66741b340729d380d8f52f \ + --hash=sha256:7ed1a5bbfb386ee8332713bf7508bc24e32d24b74fc9a7b9f8529a55db9f4ee6 \ + --hash=sha256:8cff473e81017594d20ec55d86b54bc635544897e13a7cfc12e36909c5309a2a \ + --hash=sha256:8d8382dd120d64b03698b7298b89611a6ea6f55ada9d39942838b79c9bc89801 \ + --hash=sha256:9111274b88e4d7b54a95218e243282709b330ef52b7b86bc6aaf4f805306f454 \ + --hash=sha256:91121757b0a36c9aac3427a651a7e6567110a4a67c97edf04f8d55d4765f6618 \ + --hash=sha256:980c777c612514c0cf99bc8a9de6d286f5e186dcaf9091252fcd444e5638193d \ + --hash=sha256:9a522f460d28e2bf4e12396240a5fc1518788b2fcd73535166d748399ef0c223 \ + --hash=sha256:9c3a3c648aedc9f99c09263b39f2d8252f199cb3ac154fadc173283d7d111350 \ + --hash=sha256:a1fd0ea855b2cf7c9cddaf25543e914dd75af9de08785f20ca3085f2c9ca60b0 \ + --hash=sha256:a444e7afccdb0999e203b976adb37ea633725333e5b119ad40b1ca291ecf311c \ + --hash=sha256:a84e0582858d841d54355246ddfcbd1fce3179f185da7470f41ce39d001ee1af \ + --hash=sha256:b510dda1a3672d6879beb319bc7c5fd302c6c354584690973c838f46ec3e0fa8 \ + --hash=sha256:b54df60f1fbdecc8ebc2c5b11870461a6417b3d617f555e5033f1505d36e5735 \ + --hash=sha256:b705c99c76695702656327b819c9660768ec33f5ce01fa32b2af62b56ba400a1 \ + --hash=sha256:ba4d1333cc0bc94381d6d4308d2e4e008e0bd128bdcff5573199742ee3634359 \ + --hash=sha256:c64d5c97b2f47e3cd9b712eaced3b061f2b71234b3fc263e0fcf7d889c6559dc \ + --hash=sha256:c8876673449f3401f278c86eb33224c5764582f72b653a415d0e6672fde887bf \ + --hash=sha256:ca2591bff6645c216695bdf1614fca9c82ea1144d4a7591a466fef64f28f0715 \ + --hash=sha256:cc4f7397459b12c0b196c9efe1f9d7e92463cbba142632b4cc6d8bbbbd3e2b09 \ + --hash=sha256:cf831a13e0d5a7eb519e96f58ec26e049b1fad411fc6fc23b162a7ce04d9cffc \ + --hash=sha256:dc3487447a43d42adcdf52d7ac73804f2312cbfa5d433a7d2c506dcab0033dfd \ + --hash=sha256:df90e2db118c3671a0754f38e36802db75fe0920d211a27481daf50a711fdf26 \ + --hash=sha256:e38a190442aacc67ff9f75ce60aec04893041f16f97d242209106d502486a142 \ + --hash=sha256:e9eddfe513096a71896441a7c37db72da0687b34752c4e193577a145c71736fc \ + --hash=sha256:eba6710407f1daa8e7602c347dfc94adc02205ec27ed956346190d66579eb9ea \ + --hash=sha256:ef4a456cc8b7b3d50ccec29642aa4aeda959e9da2fe9540a92754770d5f0cf1f \ + --hash=sha256:f67b34271dedc3c653eba4e3d7111aa421d5be9b4c4c7d38d30907f796cb30df \ + --hash=sha256:f6f6cd5819c50d9bcf921882784586aab34a4bd53e7553e175dece6db513a6f0 \ + --hash=sha256:fe2533caae6a91a543dec62e8360fe86ffcdc42a7c55f9dfd0128a977a896b94 \ + --hash=sha256:fe7b77dc63d707c09726b7908f575fc04ff1d1ad0f3fb92aec212396bc6cfe5e \ + --hash=sha256:fe9627c39c59e553c90f5bc3128252cb85dc3b3be8189710666d2f8bc3a5503e + # via easyocr +shellingham==1.5.4 \ + --hash=sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686 \ + --hash=sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de + # via typer +singlestoredb==1.7.2 \ + --hash=sha256:2c5379ae7730b54a5b18f93a3c998bd22394d727837edc76a9cbb2b0eba3b567 \ + --hash=sha256:346ed52cb4280d44472d9f80197c90d220cd5d92ae687423beea89e4b291a701 \ + --hash=sha256:5bebdd48dc40dd670d0ae21f68bab4a14eb69aeabd357f177f5fc88821a4f0a1 \ + --hash=sha256:69c07490e0cd22fcfd823e493b630cfe845ad4c484fee80b340bfcce3427f48a \ + --hash=sha256:92bc932df8b124a3c88b552210f9e0bb11cba4bdfbc9e7568c1582c00f0e8bcb \ + --hash=sha256:c2a23b2b22f1e76cb0d53c99250de9a600bec9621766e25ae379c50914d6436a \ + --hash=sha256:fba7f30f7fddb88e656e4309157d9e0016b6b1127d5adf348ba831bf77872d07 + # via feast (setup.py) +six==1.17.0 \ + --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ + --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 + # via + # happybase + # kubernetes + # mock + # opencensus + # openshift-client + # python-dateutil + # rfc3339-validator + # thriftpy2 +smart-open==7.5.0 \ + --hash=sha256:87e695c5148bbb988f15cec00971602765874163be85acb1c9fb8abc012e6599 \ + --hash=sha256:f394b143851d8091011832ac8113ea4aba6b92e6c35f6e677ddaaccb169d7cb9 + # via ray +sniffio==1.3.1 \ + --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ + --hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc + # via + # elastic-transport + # elasticsearch + # httpx +snowballstemmer==3.0.1 \ + --hash=sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 \ + --hash=sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895 + # via sphinx +snowflake-connector-python[pandas]==3.18.0 \ + --hash=sha256:0af10b207af3d2de2b130e89018d49a60f2e5cfe841f3bf459e58f2e1c4c4506 \ + --hash=sha256:1841b60dc376639493dfc520cf39ad4f4da1f30286bba57e878d57414263d628 \ + --hash=sha256:1afbd9e21180d2b4a76500ac2978b11865fdb3230609f2a9d80ba459fc27f2e4 \ + --hash=sha256:1fb9fc9d8c2c7d209ba89282d367a32e75b0688afd4a3f02409e24f153c1a32e \ + --hash=sha256:283366b35df88cd0c71caf0215ba80370ddef4dd37d2adf43b24208c747231ee \ + --hash=sha256:2e4c285cc6a7f6431cff98c8f235a0fe9da2262462dd3dfc2b97120574a95cf9 \ + --hash=sha256:32b1abfea32561d817b0a2f80b06d936cb32712af06bf7b848a428bfd857a10a \ + --hash=sha256:3fee7035f865088f948510b094101c8a0e5b22501891f2115f7fb1cb555de76a \ + --hash=sha256:41a46eb9824574c5f8068e3ed5c02a2dc0a733ed08ee81fa1fb3dd0ebe921728 \ + --hash=sha256:4c068c8d3cd0c9736cb0679a9f544d34327e64415303bbfe07ec8ce3c5dae800 \ + --hash=sha256:4ed2d593f1983939d5d8d88b212d86fd4f14f0ceefc1df9882b4a18534adbde9 \ + --hash=sha256:51eb789a09dc6c62119cfabd044fba1a6b8378206f05a1e83ddb2e9cb49acc0b \ + --hash=sha256:5d89f608fde2fb0597ca5e020c4ac602027dc67f11b61b4d1e5448163bae4edc \ + --hash=sha256:65d37263dd288abb649820b7e34af96dc6b2d2115bf5521a2526245f81ddb0cb \ + --hash=sha256:7116cfa410d517328fd25fabffb54845b88667586718578c4333ce034fead1ba \ + --hash=sha256:783a9ab206563d7b52fdcdd7a72af62de811d3381ca64132fd3445537b4d041b \ + --hash=sha256:7a5fcb9a25a9b77b6cd86dfc6a6324b9910e15a493a916983229011ce3509b5f \ + --hash=sha256:8d3e96e1d09b07edca6c1f6ca675b6fdd05a4a7e428e4cdf6fb697d87b9f60fc \ + --hash=sha256:94e041e347b5151b66d19d6cfc3b3172dac1f51e44bbf7cf58f3989427dd464a \ + --hash=sha256:a8c570edff5a4888840dbe1e9e65c5e4d77d55c5c800cd359fe0903a769201e0 \ + --hash=sha256:aeeb181a156333480f60b5f8ddbb3d087e288b4509adbef7993236defe4d7570 \ + --hash=sha256:b211b4240596a225b895261a4ced2633e0262e82e2e32f6fb8dfc7d4bfedf8ca \ + --hash=sha256:b99f261c82be92224ac20c8c12bdf26ce3ed5dfd8a3df8a97f15a1e11c46ad27 \ + --hash=sha256:bd1de3038b6d7059ca59f93e105aba2a673151c693cc4292f72f38bfaf147df2 \ + --hash=sha256:cfa6b234f53ec624149e21156d0a98e43408d194f2e65bcfaf30acefd35a581e \ + --hash=sha256:e17a9e806823d3a0e578cf9349f6a93810a582b3132903ea9e1683854d08da00 + # via feast (setup.py) +sortedcontainers==2.4.0 \ + --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ + --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 + # via snowflake-connector-python +soupsieve==2.8.3 \ + --hash=sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349 \ + --hash=sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95 + # via beautifulsoup4 +sphinx==6.2.1 \ + --hash=sha256:6d56a34697bb749ffa0152feafc4b19836c755d90a7c59b72bc7dfd371b9cc6b \ + --hash=sha256:97787ff1fa3256a3eef9eda523a63dbf299f7b47e053cfcf684a1c2a8380c912 + # via feast (setup.py) +sphinxcontrib-applehelp==2.0.0 \ + --hash=sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1 \ + --hash=sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5 + # via sphinx +sphinxcontrib-devhelp==2.0.0 \ + --hash=sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad \ + --hash=sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2 + # via sphinx +sphinxcontrib-htmlhelp==2.1.0 \ + --hash=sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8 \ + --hash=sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9 + # via sphinx +sphinxcontrib-jsmath==1.0.1 \ + --hash=sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 \ + --hash=sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8 + # via sphinx +sphinxcontrib-qthelp==2.0.0 \ + --hash=sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab \ + --hash=sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb + # via sphinx +sphinxcontrib-serializinghtml==2.0.0 \ + --hash=sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 \ + --hash=sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d + # via sphinx +sqlalchemy[mypy]==2.0.45 \ + --hash=sha256:0209d9753671b0da74da2cfbb9ecf9c02f72a759e4b018b3ab35f244c91842c7 \ + --hash=sha256:040f6f0545b3b7da6b9317fc3e922c9a98fc7243b2a1b39f78390fc0942f7826 \ + --hash=sha256:0c9f6ada57b58420a2c0277ff853abe40b9e9449f8d7d231763c6bc30f5c4953 \ + --hash=sha256:0f02325709d1b1a1489f23a39b318e175a171497374149eae74d612634b234c0 \ + --hash=sha256:107029bf4f43d076d4011f1afb74f7c3e2ea029ec82eb23d8527d5e909e97aa6 \ + --hash=sha256:12c694ed6468333a090d2f60950e4250b928f457e4962389553d6ba5fe9951ac \ + --hash=sha256:13e27397a7810163440c6bfed6b3fe46f1bfb2486eb540315a819abd2c004128 \ + --hash=sha256:1632a4bda8d2d25703fdad6363058d882541bdaaee0e5e3ddfa0cd3229efce88 \ + --hash=sha256:1d8b4a7a8c9b537509d56d5cd10ecdcfbb95912d72480c8861524efecc6a3fff \ + --hash=sha256:215f0528b914e5c75ef2559f69dca86878a3beeb0c1be7279d77f18e8d180ed4 \ + --hash=sha256:2c0b74aa79e2deade948fe8593654c8ef4228c44ba862bb7c9585c8e0db90f33 \ + --hash=sha256:2e90a344c644a4fa871eb01809c32096487928bd2038bf10f3e4515cb688cc56 \ + --hash=sha256:3c5f76216e7b85770d5bb5130ddd11ee89f4d52b11783674a662c7dd57018177 \ + --hash=sha256:470daea2c1ce73910f08caf10575676a37159a6d16c4da33d0033546bddebc9b \ + --hash=sha256:4748601c8ea959e37e03d13dcda4a44837afcd1b21338e637f7c935b8da06177 \ + --hash=sha256:4b6bec67ca45bc166c8729910bd2a87f1c0407ee955df110d78948f5b5827e8a \ + --hash=sha256:5225a288e4c8cc2308dbdd874edad6e7d0fd38eac1e9e5f23503425c8eee20d0 \ + --hash=sha256:56ead1f8dfb91a54a28cd1d072c74b3d635bcffbd25e50786533b822d4f2cde2 \ + --hash=sha256:5964f832431b7cdfaaa22a660b4c7eb1dfcd6ed41375f67fd3e3440fd95cb3cc \ + --hash=sha256:59a8b8bd9c6bedf81ad07c8bd5543eedca55fe9b8780b2b628d495ba55f8db1e \ + --hash=sha256:672c45cae53ba88e0dad74b9027dddd09ef6f441e927786b05bec75d949fbb2e \ + --hash=sha256:6d0beadc2535157070c9c17ecf25ecec31e13c229a8f69196d7590bde8082bf1 \ + --hash=sha256:7ae64ebf7657395824a19bca98ab10eb9a3ecb026bf09524014f1bb81cb598d4 \ + --hash=sha256:7f46ec744e7f51275582e6a24326e10c49fbdd3fc99103e01376841213028774 \ + --hash=sha256:830d434d609fe7bfa47c425c445a8b37929f140a7a44cdaf77f6d34df3a7296a \ + --hash=sha256:83d7009f40ce619d483d26ac1b757dfe3167b39921379a8bd1b596cf02dab4a6 \ + --hash=sha256:883c600c345123c033c2f6caca18def08f1f7f4c3ebeb591a63b6fceffc95cce \ + --hash=sha256:8a420169cef179d4c9064365f42d779f1e5895ad26ca0c8b4c0233920973db74 \ + --hash=sha256:8defe5737c6d2179c7997242d6473587c3beb52e557f5ef0187277009f73e5e1 \ + --hash=sha256:9a62b446b7d86a3909abbcd1cd3cc550a832f99c2bc37c5b22e1925438b9367b \ + --hash=sha256:9c6378449e0940476577047150fd09e242529b761dc887c9808a9a937fe990c8 \ + --hash=sha256:a15b98adb7f277316f2c276c090259129ee4afca783495e212048daf846654b2 \ + --hash=sha256:afbf47dc4de31fa38fd491f3705cac5307d21d4bb828a4f020ee59af412744ee \ + --hash=sha256:b3ee2aac15169fb0d45822983631466d60b762085bc4535cd39e66bea362df5f \ + --hash=sha256:b8c8b41b97fba5f62349aa285654230296829672fc9939cd7f35aab246d1c08b \ + --hash=sha256:ba547ac0b361ab4f1608afbc8432db669bd0819b3e12e29fb5fa9529a8bba81d \ + --hash=sha256:c1c2091b1489435ff85728fafeb990f073e64f6f5e81d5cd53059773e8521eb6 \ + --hash=sha256:c64772786d9eee72d4d3784c28f0a636af5b0a29f3fe26ff11f55efe90c0bd85 \ + --hash=sha256:cd337d3526ec5298f67d6a30bbbe4ed7e5e68862f0bf6dd21d289f8d37b7d60b \ + --hash=sha256:d29b2b99d527dbc66dd87c3c3248a5dd789d974a507f4653c969999fc7c1191b \ + --hash=sha256:d2c3684fca8a05f0ac1d9a21c1f4a266983a7ea9180efb80ffeb03861ecd01a0 \ + --hash=sha256:d62e47f5d8a50099b17e2bfc1b0c7d7ecd8ba6b46b1507b58cc4f05eefc3bb1c \ + --hash=sha256:d8a2ca754e5415cde2b656c27900b19d50ba076aa05ce66e2207623d3fe41f5a \ + --hash=sha256:db6834900338fb13a9123307f0c2cbb1f890a8656fcd5e5448ae3ad5bbe8d312 \ + --hash=sha256:e057f928ffe9c9b246a55b469c133b98a426297e1772ad24ce9f0c47d123bd5b \ + --hash=sha256:e50dcb81a5dfe4b7b4a4aa8f338116d127cb209559124f3694c70d6cd072b68f \ + --hash=sha256:ebd300afd2b62679203435f596b2601adafe546cb7282d5a0cd3ed99e423720f \ + --hash=sha256:ed3635353e55d28e7f4a95c8eda98a5cdc0a0b40b528433fbd41a9ae88f55b3d \ + --hash=sha256:ee580ab50e748208754ae8980cec79ec205983d8cf8b3f7c39067f3d9f2c8e22 \ + --hash=sha256:f7d27a1d977a1cfef38a0e2e1ca86f09c4212666ce34e6ae542f3ed0a33bc606 \ + --hash=sha256:fd93c6f5d65f254ceabe97548c709e073d6da9883343adaa51bf1a913ce93f8e \ + --hash=sha256:fe187fc31a54d7fd90352f34e8c008cf3ad5d064d08fedd3de2e8df83eb4a1cf + # via feast (setup.py) +sqlglot[rs]==25.20.2 \ + --hash=sha256:169fe8308dd70d7bd40117b2221b62bdc7c4e2ea8eb07394b2a6146cdedf05ab \ + --hash=sha256:cdbfd7ce3f2f39f32bd7b4c23fd9e0fd261636a6b14285b914e8def25fd0a567 + # via + # feast (setup.py) + # ibis-framework +sqlglotrs==0.2.12 \ + --hash=sha256:0338c7770a5cb5bb0ec1dcbe5206359fe9b83da0aba8dde53b9e7bd1afc89a22 \ + --hash=sha256:057a8db59a6c4bcdc42831e7ad01f41cf9e7f388ed5b139816adafbcacf2f591 \ + --hash=sha256:065835e7f2be50ba83895b64d044a39dab9d95098fff995427365e4bd8bc7bc6 \ + --hash=sha256:08e8be22da77c964be76ab4438da2c77096f5871088466ca950ee1b4712a97d4 \ + --hash=sha256:147cda8412f45af290ad190d9a98b5829a5f46a575ce768279ccebf9b7b53785 \ + --hash=sha256:155b0d59e34851b119c7ff0b2c7968c7b51667c1a1c2abefe1ac7244b3c1d78e \ + --hash=sha256:17b289ef0f25a7c034d183c588345e2b56622f7f64a85d1020633a75f8e3ac96 \ + --hash=sha256:1fc98b7649445e726a492841b8b8b39a4e5724ec2787cd1436404ebccf42519a \ + --hash=sha256:2554ead3126c83864a4b7e48e8e7e1bc23faf7160a6f28d3db967661cf529c9e \ + --hash=sha256:2824fc87fd7e41a785150ff042c7934e1fff97c6ccd59e4d96bebf6697a90762 \ + --hash=sha256:2db7e6cd41ef88c2ac647ad0258f87906de822955dec8f14e91829083047d784 \ + --hash=sha256:315f7f7bbfedf0c87d98068e62363454e986bdd05baa165b7fb448b5c6fe9f1a \ + --hash=sha256:327bfc2d71449f4dffba93d63f0565c4a1fa818143b1cfbc3f936fa8c9bcce10 \ + --hash=sha256:39a6ef72cf271db93ec6019847b7832defa9f4013c1e66851ca9c0a11c010c0c \ + --hash=sha256:4364116b7b0c72b841de6acd149a002bfc8fe360125989d4f39debd387c874d8 \ + --hash=sha256:4c07d3dba9c3ae8b56a0e45a9e47aa2a2c6ed95870c5bcc67dacaadb873843ff \ + --hash=sha256:4ceb28cf2ee3850cd745167cebe59a5fc3d506b32e9c81307938d8d272c1d670 \ + --hash=sha256:4ec38035523d54ba33de1e2b5562de4938254b61e1df48eb1db0e26ea189de28 \ + --hash=sha256:5026eada48f258ce9ad26fa41994b2ea5404bef2c3df9cb5cb2a159112a6269f \ + --hash=sha256:59499adc27a70a72170db9241404a18d4829cd3a83a076b9e112ad365c4b1452 \ + --hash=sha256:5be231acf95920bed473524dd1cac93e4cb320ed7e6ae937531b232c54cfc232 \ + --hash=sha256:67e288759d2be822db2175d0025c1f61283b019f2cc3e2577f31ad0ef3b5854d \ + --hash=sha256:6aacab6e20d92be3ca76f7358fa12346f29985e2d408660c764b7f1c75cc40ee \ + --hash=sha256:6ef3a827f2980aad17af4f8548297c93c4989d4cd3f64b9bcb7443952c542423 \ + --hash=sha256:732516bffffc70f172306ad8bc747dd9f16512cdbc09475abe6ad6f744479dee \ + --hash=sha256:76e4e1765c6be438329e234e56a6772537f6de16c4bb5ba7170e344664cccdf7 \ + --hash=sha256:7b553cdb9e8afcfea5466815e865f874f6f51aaace4fb4101670e150f7bbfe5a \ + --hash=sha256:7c79c43c5cde1f4017641032f11770ed8111c963dccc096cd15df906d4fb46a4 \ + --hash=sha256:8174aa227193d0a755f4515e6c3883be4681c9b669a65c2316f09be27b84be4d \ + --hash=sha256:8a18b3a09c32788d1ee2d0610ab35af862413c56b65f8ad8bc0131701f03103b \ + --hash=sha256:8f268aea3d2ebc05cb9148bb487f21e532f8af1b0a4aed6b7374703aadfb6a7c \ + --hash=sha256:91971032603d05428fd42a978084110afb2a4c0975e4343b075f69a23889e3da \ + --hash=sha256:9334f6c394a671a630c61339d52fb7da1a72eca057570f039b2a4035d2e39380 \ + --hash=sha256:954ccd912391ab5922adb23159ebcc0c5dccb468381e2a1ce92117cb4b0f0ed3 \ + --hash=sha256:9597865efc40e5c41af7719106c7620e1338aaa64646726652c63bae14225391 \ + --hash=sha256:97b2c74fcdd89f0d4458c0e2b5783989be99a1e0b2d627797688ab716ad9391b \ + --hash=sha256:989ccc5dc6b38da937481b6eb2dc1fc0b13676fe129697b874828e577984d7ef \ + --hash=sha256:9c4c6f6fe1c54fff614f9d0b2dd7a6bf948bda87ce51a245dcd3f447f20c8b74 \ + --hash=sha256:9d5b9a9d6259b72258f6764f88a89faa3c648438bd1b2c3a9598b725d42bf6f2 \ + --hash=sha256:a266c9047726d83c51a8ec3d5278ceb9caf131307c9c93c4ceefd99c0116e538 \ + --hash=sha256:a4a2cacb31f75e242c7b9ff4afae1d95f548df8441444114376d8007cc91b55b \ + --hash=sha256:aaf86275a3388da1ed2161645aa346bfca3ee6e1dc0e2115867db9e78f1caddd \ + --hash=sha256:ab676d2d7da28907a139ad5fc20dee0890054967bac0b18e653ac048837c9ea1 \ + --hash=sha256:acc25d651eb663332157c2e5d2736516cddf4cd0effe67a887723934de5051d1 \ + --hash=sha256:b10bf6b71961b31951bf4dff937d8d5d399ea1b3bd47fb5c5810386710fe7dfb \ + --hash=sha256:b40601e67f5abae5d09d23f92394dbd735539de469ce663b596eb42bf77d2c54 \ + --hash=sha256:b6020825e58af6e2795e6dcb69639f5500e45e1da78f1b1abd74c4d11083a249 \ + --hash=sha256:bc1807c6222e32fc9bf6f5c7e12b85c4b72f12227800d40c1693244c198b33bb \ + --hash=sha256:bd6c4e6a7670f761c8e69b45d6d302a4d37a3cddb1fdca2ad90e54b77858fe80 \ + --hash=sha256:bf3e2eab11f06f1df13c0f85b3e26fbab0b7e8a5d189e5edfed951bc85f6bd48 \ + --hash=sha256:c3d62905ce74a48714b7662ad95efe299fad62f193be4b482a327af060f98710 \ + --hash=sha256:c3e0edde0fdf598561e7404ac56fb4b12276394ee5155b5365e42434c6f287a3 \ + --hash=sha256:c64066d13bd2e5e788b845c933c765af9991faa93982e273b623019a1161fadc \ + --hash=sha256:c8bf7ae29c0fc66e9c998d7f8e6f6fc26309c6eb5a4728e1443cb628218bc307 \ + --hash=sha256:d2827c7bf7e57496f9b95658bcd2395cfb0c51adc3023cd3386988337dfaf6a5 \ + --hash=sha256:e7b2da43b2a6a85807df6c56b2627abe244aff28fdf9a4940d38d749cb4b8e3e \ + --hash=sha256:ebc162a599fac86e59f899631716752fbc7f89598e94729eadb707e54db371b2 \ + --hash=sha256:f0a2ddeab27a94447270b7a240770a31a3afed0a972d60085205baec990ad76a \ + --hash=sha256:f104a98182761d4613f920eda7ec5fc921afb3608f7db648206ce06dd10a6be5 \ + --hash=sha256:f83ad3fb4ea57218c0e65d3499e31c9bb3051bbb5dccbb11593eaf1640964b51 \ + --hash=sha256:fa1ae834fb78bd52bb76e3c8d02cb79f45717ab1f02f4ad8154bf33a5408a502 + # via sqlglot +sqlite-vec==0.1.6 \ + --hash=sha256:77491bcaa6d496f2acb5cc0d0ff0b8964434f141523c121e313f9a7d8088dee3 \ + --hash=sha256:7b0519d9cd96164cd2e08e8eed225197f9cd2f0be82cb04567692a0a4be02da3 \ + --hash=sha256:823b0493add80d7fe82ab0fe25df7c0703f4752941aee1c7b2b02cec9656cb24 \ + --hash=sha256:c65bcfd90fa2f41f9000052bcb8bb75d38240b2dae49225389eca6c3136d3f0c \ + --hash=sha256:fdca35f7ee3243668a055255d4dee4dea7eed5a06da8cad409f89facf4595361 + # via feast (setup.py) +sqlparams==6.2.0 \ + --hash=sha256:3744a2ad16f71293db6505b21fd5229b4757489a9b09f3553656a1ae97ba7ca5 \ + --hash=sha256:63b32ed9051bdc52e7e8b38bc4f78aed51796cdd9135e730f4c6a7db1048dedf + # via singlestoredb +sse-starlette==3.2.0 \ + --hash=sha256:5876954bd51920fc2cd51baee47a080eb88a37b5b784e615abb0b283f801cdbf \ + --hash=sha256:8127594edfb51abe44eac9c49e59b0b01f1039d0c7461c6fd91d4e03b70da422 + # via mcp +stack-data==0.6.3 \ + --hash=sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9 \ + --hash=sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695 + # via ipython +starlette==0.50.0 \ + --hash=sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca \ + --hash=sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca + # via + # fastapi + # mcp + # sse-starlette +substrait==0.24.2 \ + --hash=sha256:743cc352e96b0927b2cd37cd5a8fdac0a96a68df9600bd104fc36aebd222a836 \ + --hash=sha256:d1d475833566fa9d67eed3273456883c0568486ccced92b524b31709d2817e19 + # via + # feast (setup.py) + # ibis-substrait +sympy==1.14.0 \ + --hash=sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517 \ + --hash=sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5 + # via torch +tabulate==0.9.0 \ + --hash=sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c \ + --hash=sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f + # via + # feast (setup.py) + # docling-core + # docling-parse +tenacity==8.5.0 \ + --hash=sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78 \ + --hash=sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687 + # via feast (setup.py) +terminado==0.18.1 \ + --hash=sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0 \ + --hash=sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e + # via + # jupyter-server + # jupyter-server-terminals +testcontainers==4.9.0 \ + --hash=sha256:2cd6af070109ff68c1ab5389dc89c86c2dc3ab30a21ca734b2cb8f0f80ad479e \ + --hash=sha256:c6fee929990972c40bf6b91b7072c94064ff3649b405a14fde0274c8b2479d32 + # via feast (setup.py) +threadpoolctl==3.6.0 \ + --hash=sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb \ + --hash=sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e + # via scikit-learn +thriftpy2==0.5.3 \ + --hash=sha256:08d8699d318b6a8fe9e9fd4c2234ec7912462d90cc636c371b4f4f6500a44328 \ + --hash=sha256:0f36f80a038dbfc2b3b048151ca4732f310ebd0385cdf20e7864d781d5d6f582 \ + --hash=sha256:13c0316a1a9b6f7840d9c084a5a1fa2e419ae86645e45530593558704e792d7f \ + --hash=sha256:195beb93caa104879d808e87d92962fff8d59d40486590fd653b5aeb7774420e \ + --hash=sha256:1bb6c0482663887f2a9ab98453ab0ca20a3e1f2336a500b7da12af33614c0d75 \ + --hash=sha256:2023abcc504e4fc8825419964ecfab904244b0bc189d0082380d481ecba951d7 \ + --hash=sha256:236a7d4627b1aa692a901ca45d7dfa4e516bcd3f309efc18ac69671b31789e39 \ + --hash=sha256:29b09fa1fb77f1927ac4ce21d8f8f6663d8917f75780aa6bad57ca9473d0a3b3 \ + --hash=sha256:2d3c0403673a3b7fc38304cf89e07c792f44ac6aa3b15c12e6cc411a85d10af3 \ + --hash=sha256:2eb14e24febbeca84d603e88a24db9ccb4a1437f90e9a862dcee02dc0a2194c2 \ + --hash=sha256:2fb20edf082965487bddfba03b2c05bb50db38ceda3111540cb2353949fdb29e \ + --hash=sha256:387c04d02f23ae83415cb2de35a88ba79321619af25cf34a481cabc367ddf1aa \ + --hash=sha256:3c00c340114c3041961906a628e70e6b6b5805ee691e682c290cec3513e77efc \ + --hash=sha256:3da0e3c1a5c17f67a203d9814853dd1d8fe8b0ec69a26d30d6b634e4c0e2c87c \ + --hash=sha256:3e2fa8c3d2b1505d2a463c090d9e771b8fed0eda8b01b0365e7547ba106bf2db \ + --hash=sha256:455440132b01b3a895001dc59ecf6056e8fd041ad6e745ff22391cf3a1f8361e \ + --hash=sha256:523c480a4b3aad480e4738c32f97b3f356ed998e6549f5f55eb6f7852474cfff \ + --hash=sha256:524d69102843fed087e30c6edc5b99f7b42b768d88bf910787add60e37e2a2a5 \ + --hash=sha256:53e761ea5eab24bb3520f8adecdbb633e69dda7cf9678ca2eb6ad1952cc56540 \ + --hash=sha256:5e799f6c4caf79a5566bc14941e768b132c533bed66e0a5ef0a127a74f98acab \ + --hash=sha256:6196d7d5adb6214ed21633ec57a222c90a6a66498cdd9f8da7c85c7514c7c439 \ + --hash=sha256:6384a142514982b380431b7d8811f137c5ec9cf5cf3affa33884b7ce4a51c8c2 \ + --hash=sha256:67ec304d83510d0ec83338ef029ea3bae91fdbb3bf0504f7990dd446b483773e \ + --hash=sha256:6efccde429f93740943bc4c0e2664a49f0799ed21663cc26b16a823e8719040f \ + --hash=sha256:710b7f3d9fdbb5788b37b4b694d30fa37a3c08c0d52aeb1def57a5140fa2f4fd \ + --hash=sha256:716c36885e29a9480bdabe117235967b5fe36dc179aca80cd8ef9e12866e4cef \ + --hash=sha256:72a1cdfd3bcf16b667379f8277e83295a34ae74227e54711c657305bf4c9e63b \ + --hash=sha256:73832e79732bab15920bed700a5efbe2b6e9dbd35710e815e870feb873b15059 \ + --hash=sha256:74dc6ed8c9098b66a17b916dd898abc32801a8ef0b439a407bce4f11c1b3da34 \ + --hash=sha256:772c9c1015d05177e37b9a547bcd27b560fc888ecd1e179ebf7f114ec467914d \ + --hash=sha256:86489105abb39c6ff93c3d270cf1474f7fddd380847f2b6bc8d09e5d0f0a23ab \ + --hash=sha256:8a6652e823e0ae6fa9f73b62c1a2ed04d7c0e1ac402c7ca7c509f9f14fbcc80f \ + --hash=sha256:9460a8284881854e210907eeb1761f44afacb4d164d1b6ecfddc184ed1b03277 \ + --hash=sha256:94806a0c3436189a75efac4ab067cdab7298876fee40cc0006300cc1d7982055 \ + --hash=sha256:9cba3454b4e5e05102d2dbfadd3a9a66c19488c6aa18c147bbeff2097ae67f04 \ + --hash=sha256:9eda43701a94def9d063550b0d8261630c40ade312c35b1f6e4804859c783ed8 \ + --hash=sha256:a57c67a880c9da2d252a6244e9ccf7b08850388c7afa4f0e98cb60fdca904a09 \ + --hash=sha256:a7a00b772783847c0c48a43e098b64f5741ca5a2e52e6c66d9b753765cd93ed3 \ + --hash=sha256:a7f2913ea3beac18767784059f02a67751d99094d4a368b350911784f0e09709 \ + --hash=sha256:ab47f689b0003ec63a881e5ad4f46046f62632da5168b0665fd369a3561eaa2a \ + --hash=sha256:addcc3ba9c106758e9073ab205e4bcf9a9540acb335fafa0184a1fa8e76a78cb \ + --hash=sha256:ade0165ba060b97333bc7a927229e992441bfa17bb8e13ea05590c2ec3551b17 \ + --hash=sha256:b208f3c23f916ca0517285c11748ca1fcf43a2ac2224ea5eef8bcba464a20652 \ + --hash=sha256:b5670936016aeaeb7111c96661ced36541211c0e82eb357a9bee5d4176ebbcff \ + --hash=sha256:be23631c152323dd3d7d51368dadcec75e60e90e4662be4f2b8ada208c61fa34 \ + --hash=sha256:bf69d246c39d0ce4ed922b6e00e643ca514cdf40010b00b46f82b0f758a840b3 \ + --hash=sha256:c01e0da29120709d46cb4310944fc717f28ce097d8845c4c29e111ff98c9deff \ + --hash=sha256:c0cf4418810ecf984f6d7f538988175c459f6bd5c85d94b878ebb11dbdbfa62b \ + --hash=sha256:ca4d554f8fc79c8152119bbd576e5d6a5c11e907e0baf467fb4676b1d274558a \ + --hash=sha256:d5080c1c4bd13c4431613a2c0cd607c5e3a07a496a865a0d01f534401d3b09c7 \ + --hash=sha256:e6a77d3d190f1c2726cfb11d1115678fcfa4b0ff509bd8bb38e451c629d9383c \ + --hash=sha256:eb440b7d8e7460f6969016d77e25ebfdee2aa6d5fed95aecf2bd59310c2c5530 \ + --hash=sha256:ec49907ee15513ca2344540c4ad2bf1945c41a6c0236d589eebd32be8298faa9 \ + --hash=sha256:f2ccb893ae687ff946902d96a5615a93847a7868bc5d66f51caf5ccf46466314 \ + --hash=sha256:f4210c10b686fe4a32b121f618b407aaccc7a72021c6d64fa181a09df72c4d89 \ + --hash=sha256:f4d122a82cf7cd4743a2640199b066a994f6527802c2dd16f2e4fffc15efa2a3 \ + --hash=sha256:f768756c0c105e98a3760fc7b4f4df12e25f5334b204060bb6bdab3ce1599e11 \ + --hash=sha256:f965fff2f2f323ddb5d9cb7fabe33c4c9f008955dbb59728ffc3111557b87793 \ + --hash=sha256:fb86f4c0cfcb39949a53dcc689e3758594a18724753861ba9f59646b72417383 \ + --hash=sha256:fd4c6131ca6e919f03263cc83b713f1797bc20126a858da8518ed49b3e32c334 \ + --hash=sha256:fdc5676b52fa6a3009d205360eb9ba257b8b4813883ed52797a20838bcc45dde + # via happybase +tifffile==2026.1.14 \ + --hash=sha256:29cf4adb43562a4624fc959018ab1b44e0342015d3db4581b983fe40e05f5924 \ + --hash=sha256:a423c583e1eecd9ca255642d47f463efa8d7f2365a0e110eb0167570493e0c8c + # via scikit-image +timm==1.0.24 \ + --hash=sha256:8301ac783410c6ad72c73c49326af6d71a9e4d1558238552796e825c2464913f \ + --hash=sha256:c7b909f43fe2ef8fe62c505e270cd4f1af230dfbc37f2ee93e3608492b9d9a40 + # via feast (setup.py) +tinycss2==1.4.0 \ + --hash=sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7 \ + --hash=sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289 + # via bleach +tokenizers==0.22.2 \ + --hash=sha256:143b999bdc46d10febb15cbffb4207ddd1f410e2c755857b5a0797961bbdc113 \ + --hash=sha256:1a62ba2c5faa2dd175aaeed7b15abf18d20266189fb3406c5d0550dd34dd5f37 \ + --hash=sha256:1c774b1276f71e1ef716e5486f21e76333464f47bece56bbd554485982a9e03e \ + --hash=sha256:1e418a55456beedca4621dbab65a318981467a2b188e982a23e117f115ce5001 \ + --hash=sha256:1e50f8554d504f617d9e9d6e4c2c2884a12b388a97c5c77f0bc6cf4cd032feee \ + --hash=sha256:2249487018adec45d6e3554c71d46eb39fa8ea67156c640f7513eb26f318cec7 \ + --hash=sha256:25b85325d0815e86e0bac263506dd114578953b7b53d7de09a6485e4a160a7dd \ + --hash=sha256:29c30b83d8dcd061078b05ae0cb94d3c710555fbb44861139f9f83dcca3dc3e4 \ + --hash=sha256:319f659ee992222f04e58f84cbf407cfa66a65fe3a8de44e8ad2bc53e7d99012 \ + --hash=sha256:369cc9fc8cc10cb24143873a0d95438bb8ee257bb80c71989e3ee290e8d72c67 \ + --hash=sha256:37ae80a28c1d3265bb1f22464c856bd23c02a05bb211e56d0c5301a435be6c1a \ + --hash=sha256:38337540fbbddff8e999d59970f3c6f35a82de10053206a7562f1ea02d046fa5 \ + --hash=sha256:473b83b915e547aa366d1eee11806deaf419e17be16310ac0a14077f1e28f917 \ + --hash=sha256:544dd704ae7238755d790de45ba8da072e9af3eea688f698b137915ae959281c \ + --hash=sha256:64d94e84f6660764e64e7e0b22baa72f6cd942279fdbb21d46abd70d179f0195 \ + --hash=sha256:753d47ebd4542742ef9261d9da92cd545b2cacbb48349a1225466745bb866ec4 \ + --hash=sha256:791135ee325f2336f498590eb2f11dc5c295232f288e75c99a36c5dbce63088a \ + --hash=sha256:9ce725d22864a1e965217204946f830c37876eee3b2ba6fc6255e8e903d5fcbc \ + --hash=sha256:a6bf3f88c554a2b653af81f3204491c818ae2ac6fbc09e76ef4773351292bc92 \ + --hash=sha256:bfb88f22a209ff7b40a576d5324bf8286b519d7358663db21d6246fb17eea2d5 \ + --hash=sha256:c9ea31edff2968b44a88f97d784c2f16dc0729b8b143ed004699ebca91f05c48 \ + --hash=sha256:df6c4265b289083bf710dff49bc51ef252f9d5be33a45ee2bed151114a56207b \ + --hash=sha256:e10bf9113d209be7cd046d40fbabbaf3278ff6d18eb4da4c500443185dc1896c \ + --hash=sha256:f01a9c019878532f98927d2bacb79bbb404b43d3437455522a00a30718cdedb5 + # via transformers +toml==0.10.2 \ + --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ + --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f + # via feast (setup.py) +tomli==2.4.0 \ + --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \ + --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \ + --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \ + --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \ + --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \ + --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \ + --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \ + --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \ + --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \ + --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \ + --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \ + --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \ + --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \ + --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \ + --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \ + --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \ + --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \ + --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \ + --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \ + --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \ + --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \ + --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \ + --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \ + --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \ + --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \ + --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \ + --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \ + --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \ + --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \ + --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \ + --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \ + --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \ + --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \ + --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \ + --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \ + --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \ + --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \ + --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \ + --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \ + --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \ + --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \ + --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \ + --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \ + --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \ + --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \ + --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \ + --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 + # via + # coverage + # fastapi-mcp +tomlkit==0.14.0 \ + --hash=sha256:592064ed85b40fa213469f81ac584f67a4f2992509a7c3ea2d632208623a3680 \ + --hash=sha256:cf00efca415dbd57575befb1f6634c4f42d2d87dbba376128adb42c121b87064 + # via + # poetry-dynamic-versioning + # snowflake-connector-python +toolz==0.12.1 \ + --hash=sha256:d22731364c07d72eea0a0ad45bafb2c2937ab6fd38a3507bf55eae8744aa7d85 \ + --hash=sha256:ecca342664893f177a13dac0e6b41cbd8ac25a358e5f215316d43e2100224f4d + # via + # altair + # dask + # ibis-framework + # partd +torch==2.9.1 \ + --hash=sha256:07c8a9660bc9414c39cac530ac83b1fb1b679d7155824144a40a54f4a47bfa73 \ + --hash=sha256:0a2bd769944991c74acf0c4ef23603b9c777fdf7637f115605a4b2d8023110c7 \ + --hash=sha256:0d06b30a9207b7c3516a9e0102114024755a07045f0c1d2f2a56b1819ac06bcb \ + --hash=sha256:19d144d6b3e29921f1fc70503e9f2fc572cde6a5115c0c0de2f7ca8b1483e8b6 \ + --hash=sha256:1cc208435f6c379f9b8fdfd5ceb5be1e3b72a6bdf1cb46c0d2812aa73472db9e \ + --hash=sha256:1edee27a7c9897f4e0b7c14cfc2f3008c571921134522d5b9b5ec4ebbc69041a \ + --hash=sha256:27331cd902fb4322252657f3902adf1c4f6acad9dcad81d8df3ae14c7c4f07c4 \ + --hash=sha256:2af70e3be4a13becba4655d6cc07dcfec7ae844db6ac38d6c1dafeb245d17d65 \ + --hash=sha256:2c14b3da5df416cf9cb5efab83aa3056f5b8cd8620b8fde81b4987ecab730587 \ + --hash=sha256:2e1c42c0ae92bf803a4b2409fdfed85e30f9027a66887f5e7dcdbc014c7531db \ + --hash=sha256:30a3e170a84894f3652434b56d59a64a2c11366b0ed5776fab33c2439396bf9a \ + --hash=sha256:52347912d868653e1528b47cafaf79b285b98be3f4f35d5955389b1b95224475 \ + --hash=sha256:524de44cd13931208ba2c4bde9ec7741fd4ae6bfd06409a604fc32f6520c2bc9 \ + --hash=sha256:545844cc16b3f91e08ce3b40e9c2d77012dd33a48d505aed34b7740ed627a1b2 \ + --hash=sha256:5be4bf7496f1e3ffb1dd44b672adb1ac3f081f204c5ca81eba6442f5f634df8e \ + --hash=sha256:62b3fd888277946918cba4478cf849303da5359f0fb4e3bfb86b0533ba2eaf8d \ + --hash=sha256:81a285002d7b8cfd3fdf1b98aa8df138d41f1a8334fd9ea37511517cedf43083 \ + --hash=sha256:8301a7b431e51764629208d0edaa4f9e4c33e6df0f2f90b90e261d623df6a4e2 \ + --hash=sha256:9fd35c68b3679378c11f5eb73220fdcb4e6f4592295277fbb657d31fd053237c \ + --hash=sha256:a83b0e84cc375e3318a808d032510dde99d696a85fe9473fc8575612b63ae951 \ + --hash=sha256:c0d25d1d8e531b8343bea0ed811d5d528958f1dcbd37e7245bc686273177ad7e \ + --hash=sha256:c29455d2b910b98738131990394da3e50eea8291dfeb4b12de71ecf1fdeb21cb \ + --hash=sha256:c432d04376f6d9767a9852ea0def7b47a7bbc8e7af3b16ac9cf9ce02b12851c9 \ + --hash=sha256:c88d3299ddeb2b35dcc31753305612db485ab6f1823e37fb29451c8b2732b87e \ + --hash=sha256:cb10896a1f7fedaddbccc2017ce6ca9ecaaf990f0973bdfcf405439750118d2c \ + --hash=sha256:d033ff0ac3f5400df862a51bdde9bad83561f3739ea0046e68f5401ebfa67c1b \ + --hash=sha256:d187566a2cdc726fc80138c3cdb260970fab1c27e99f85452721f7759bbd554d \ + --hash=sha256:da5f6f4d7f4940a173e5572791af238cb0b9e21b1aab592bd8b26da4c99f1cd6 + # via + # feast (setup.py) + # accelerate + # docling-ibm-models + # easyocr + # safetensors + # timm + # torchvision +torchvision==0.24.1 \ + --hash=sha256:056c525dc875f18fe8e9c27079ada166a7b2755cea5a2199b0bc7f1f8364e600 \ + --hash=sha256:1540a9e7f8cf55fe17554482f5a125a7e426347b71de07327d5de6bfd8d17caa \ + --hash=sha256:16274823b93048e0a29d83415166a2e9e0bf4e1b432668357b657612a4802864 \ + --hash=sha256:18f9cb60e64b37b551cd605a3d62c15730c086362b40682d23e24b616a697d41 \ + --hash=sha256:1b495edd3a8f9911292424117544f0b4ab780452e998649425d1f4b2bed6695f \ + --hash=sha256:1e39619de698e2821d71976c92c8a9e50cdfd1e993507dfb340f2688bfdd8283 \ + --hash=sha256:480b271d6edff83ac2e8d69bbb4cf2073f93366516a50d48f140ccfceedb002e \ + --hash=sha256:4aa6cb806eb8541e92c9b313e96192c6b826e9eb0042720e2fa250d021079952 \ + --hash=sha256:54ed17c3d30e718e08d8da3fd5b30ea44b0311317e55647cb97077a29ecbc25b \ + --hash=sha256:66a98471fc18cad9064123106d810a75f57f0838eee20edc56233fd8484b0cc7 \ + --hash=sha256:7fb7590c737ebe3e1c077ad60c0e5e2e56bb26e7bccc3b9d04dbfc34fd09f050 \ + --hash=sha256:8a6696db7fb71eadb2c6a48602106e136c785642e598eb1533e0b27744f2cce6 \ + --hash=sha256:9ef95d819fd6df81bc7cc97b8f21a15d2c0d3ac5dbfaab5cbc2d2ce57114b19e \ + --hash=sha256:a0f106663e60332aa4fcb1ca2159ef8c3f2ed266b0e6df88de261048a840e0df \ + --hash=sha256:a9308cdd37d8a42e14a3e7fd9d271830c7fecb150dd929b642f3c1460514599a \ + --hash=sha256:ab211e1807dc3e53acf8f6638df9a7444c80c0ad050466e8d652b3e83776987b \ + --hash=sha256:af9201184c2712d808bd4eb656899011afdfce1e83721c7cb08000034df353fe \ + --hash=sha256:cccf4b4fec7fdfcd3431b9ea75d1588c0a8596d0333245dafebee0462abe3388 \ + --hash=sha256:d83e16d70ea85d2f196d678bfb702c36be7a655b003abed84e465988b6128938 \ + --hash=sha256:db2125c46f9cb25dc740be831ce3ce99303cfe60439249a41b04fd9f373be671 \ + --hash=sha256:ded5e625788572e4e1c4d155d1bbc48805c113794100d70e19c76e39e4d53465 \ + --hash=sha256:e3f96208b4bef54cd60e415545f5200346a65024e04f29a26cd0006dbf9e8e66 \ + --hash=sha256:e48bf6a8ec95872eb45763f06499f87bd2fb246b9b96cb00aae260fda2f96193 \ + --hash=sha256:ec9d7379c519428395e4ffda4dbb99ec56be64b0a75b95989e00f9ec7ae0b2d7 \ + --hash=sha256:f035f0cacd1f44a8ff6cb7ca3627d84c54d685055961d73a1a9fb9827a5414c8 \ + --hash=sha256:f231f6a4f2aa6522713326d0d2563538fa72d613741ae364f9913027fa52ea35 \ + --hash=sha256:f476da4e085b7307aaab6f540219617d46d5926aeda24be33e1359771c83778f \ + --hash=sha256:fbdbdae5e540b868a681240b7dbd6473986c862445ee8a138680a6a97d6c34ff + # via + # feast (setup.py) + # docling-ibm-models + # easyocr + # timm +tornado==6.5.4 \ + --hash=sha256:053e6e16701eb6cbe641f308f4c1a9541f91b6261991160391bfc342e8a551a1 \ + --hash=sha256:1768110f2411d5cd281bac0a090f707223ce77fd110424361092859e089b38d1 \ + --hash=sha256:2d50f63dda1d2cac3ae1fa23d254e16b5e38153758470e9956cbc3d813d40843 \ + --hash=sha256:50ff0a58b0dc97939d29da29cd624da010e7f804746621c78d14b80238669335 \ + --hash=sha256:6076d5dda368c9328ff41ab5d9dd3608e695e8225d1cd0fd1e006f05da3635a8 \ + --hash=sha256:6eb82872335a53dd063a4f10917b3efd28270b56a33db69009606a0312660a6f \ + --hash=sha256:9c86b1643b33a4cd415f8d0fe53045f913bf07b4a3ef646b735a6a86047dda84 \ + --hash=sha256:a22fa9047405d03260b483980635f0b041989d8bcc9a313f8fe18b411d84b1d7 \ + --hash=sha256:d1cf66105dc6acb5af613c054955b8137e34a03698aa53272dbda4afe252be17 \ + --hash=sha256:d6241c1a16b1c9e4cc28148b1cda97dd1c6cb4fb7068ac1bedc610768dff0ba9 \ + --hash=sha256:e5fb5e04efa54cf0baabdd10061eb4148e0be137166146fff835745f59ab9f7f \ + --hash=sha256:fa07d31e0cd85c60713f2b995da613588aa03e1303d75705dca6af8babc18ddc + # via + # ipykernel + # jupyter-client + # jupyter-server + # jupyterlab + # notebook + # terminado +tqdm==4.67.1 \ + --hash=sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2 \ + --hash=sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2 + # via + # feast (setup.py) + # datasets + # docling + # docling-ibm-models + # great-expectations + # huggingface-hub + # milvus-lite + # mpire + # semchunk + # transformers +traitlets==5.14.3 \ + --hash=sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7 \ + --hash=sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f + # via + # ipykernel + # ipython + # ipywidgets + # jupyter-client + # jupyter-core + # jupyter-events + # jupyter-server + # jupyterlab + # matplotlib-inline + # nbclient + # nbconvert + # nbformat +transformers==4.57.6 \ + --hash=sha256:4c9e9de11333ddfe5114bc872c9f370509198acf0b87a832a0ab9458e2bd0550 \ + --hash=sha256:55e44126ece9dc0a291521b7e5492b572e6ef2766338a610b9ab5afbb70689d3 + # via + # feast (setup.py) + # docling-core + # docling-ibm-models +tree-sitter==0.24.0 \ + --hash=sha256:01ea01a7003b88b92f7f875da6ba9d5d741e0c84bb1bd92c503c0eecd0ee6409 \ + --hash=sha256:033506c1bc2ba7bd559b23a6bdbeaf1127cee3c68a094b82396718596dfe98bc \ + --hash=sha256:098a81df9f89cf254d92c1cd0660a838593f85d7505b28249216661d87adde4a \ + --hash=sha256:0b26bf9e958da6eb7e74a081aab9d9c7d05f9baeaa830dbb67481898fd16f1f5 \ + --hash=sha256:0d4a6416ed421c4210f0ca405a4834d5ccfbb8ad6692d4d74f7773ef68f92071 \ + --hash=sha256:14beeff5f11e223c37be7d5d119819880601a80d0399abe8c738ae2288804afc \ + --hash=sha256:23641bd25dcd4bb0b6fa91b8fb3f46cc9f1c9f475efe4d536d3f1f688d1b84c8 \ + --hash=sha256:24a8dd03b0d6b8812425f3b84d2f4763322684e38baf74e5bb766128b5633dc7 \ + --hash=sha256:26a5b130f70d5925d67b47db314da209063664585a2fd36fa69e0717738efaf4 \ + --hash=sha256:2a84ff87a2f2a008867a1064aba510ab3bd608e3e0cd6e8fef0379efee266c73 \ + --hash=sha256:3b1f3cbd9700e1fba0be2e7d801527e37c49fc02dc140714669144ef6ab58dce \ + --hash=sha256:464fa5b2cac63608915a9de8a6efd67a4da1929e603ea86abaeae2cb1fe89921 \ + --hash=sha256:4ddb113e6b8b3e3b199695b1492a47d87d06c538e63050823d90ef13cac585fd \ + --hash=sha256:57277a12fbcefb1c8b206186068d456c600dbfbc3fd6c76968ee22614c5cd5ad \ + --hash=sha256:5fc5c3c26d83c9d0ecb4fc4304fba35f034b7761d35286b936c1db1217558b4e \ + --hash=sha256:772e1bd8c0931c866b848d0369b32218ac97c24b04790ec4b0e409901945dd8e \ + --hash=sha256:7d5d9537507e1c8c5fa9935b34f320bfec4114d675e028f3ad94f11cf9db37b9 \ + --hash=sha256:a7c9c89666dea2ce2b2bf98e75f429d2876c569fab966afefdcd71974c6d8538 \ + --hash=sha256:abd95af65ca2f4f7eca356343391ed669e764f37748b5352946f00f7fc78e734 \ + --hash=sha256:c012e4c345c57a95d92ab5a890c637aaa51ab3b7ff25ed7069834b1087361c95 \ + --hash=sha256:d25fa22766d63f73716c6fec1a31ee5cf904aa429484256bd5fdf5259051ed74 \ + --hash=sha256:de0fb7c18c6068cacff46250c0a0473e8fc74d673e3e86555f131c2c1346fb13 \ + --hash=sha256:e0992d483677e71d5c5d37f30dfb2e3afec2f932a9c53eec4fca13869b788c6c \ + --hash=sha256:f3f00feff1fc47a8e4863561b8da8f5e023d382dd31ed3e43cd11d4cae445445 \ + --hash=sha256:f3f08a2ca9f600b3758792ba2406971665ffbad810847398d180c48cee174ee2 \ + --hash=sha256:f58bb4956917715ec4d5a28681829a8dad5c342cafd4aea269f9132a83ca9b34 \ + --hash=sha256:f733a83d8355fc95561582b66bbea92ffd365c5d7a665bc9ebd25e049c2b2abb \ + --hash=sha256:f9691be48d98c49ef8f498460278884c666b44129222ed6217477dffad5d4831 \ + --hash=sha256:f9e8b1605ab60ed43803100f067eed71b0b0e6c1fb9860a262727dbfbbb74751 + # via docling-core +tree-sitter-c==0.23.4 \ + --hash=sha256:013403e74765d74e523f380f9df8f3d99e9fe94132a3fc0c8b29cba538a7b2bf \ + --hash=sha256:2c92c0571b36b6da06f8882f34151dc11e67a493e9101cc0026a16da27709c05 \ + --hash=sha256:5e42a3519825ca59c91b2b7aec08dd3c89e02690c7b315d54a1e1743f9be3f15 \ + --hash=sha256:9215c7888dd019038f162ea5646178f6e129cd2b49fc506d14becf5e426121d7 \ + --hash=sha256:98c285a23bf4fb6fb34140d6ea0f0d25d0a93e0d93692f9dffe3db6d1fe08534 \ + --hash=sha256:a4d7bdeaca8f1da72352a945853f56aa5d34e7bc22569ec5bda5d7c1a04e5b0f \ + --hash=sha256:c15c7588c3d95872328019073a8d5eaf7c2691b4d4ef0393a0168399b2ad2356 \ + --hash=sha256:edd36e12cc79b8b5bbc81fc336ff7d2577d0fe16afd18163c9aff7ae3ff69e15 + # via docling-core +tree-sitter-javascript==0.23.1 \ + --hash=sha256:041fa22b34250ea6eb313d33104d5303f79504cb259d374d691e38bbdc49145b \ + --hash=sha256:056dc04fb6b24293f8c5fec43c14e7e16ba2075b3009c643abf8c85edc4c7c3c \ + --hash=sha256:5a6bc1055b061c5055ec58f39ee9b2e9efb8e6e0ae970838af74da0afb811f0a \ + --hash=sha256:6ca583dad4bd79d3053c310b9f7208cd597fd85f9947e4ab2294658bb5c11e35 \ + --hash=sha256:94100e491a6a247aa4d14caf61230c171b6376c863039b6d9cd71255c2d815ec \ + --hash=sha256:a11ca1c0f736da42967586b568dff8a465ee148a986c15ebdc9382806e0ce871 \ + --hash=sha256:b2059ce8b150162cda05a457ca3920450adbf915119c04b8c67b5241cd7fcfed \ + --hash=sha256:eb28130cd2fb30d702d614cbf61ef44d1c7f6869e7d864a9cc17111e370be8f7 + # via docling-core +tree-sitter-python==0.23.6 \ + --hash=sha256:28fbec8f74eeb2b30292d97715e60fac9ccf8a8091ce19b9d93e9b580ed280fb \ + --hash=sha256:29dacdc0cd2f64e55e61d96c6906533ebb2791972bec988450c46cce60092f5d \ + --hash=sha256:354bfa0a2f9217431764a631516f85173e9711af2c13dbd796a8815acfe505d9 \ + --hash=sha256:680b710051b144fedf61c95197db0094f2245e82551bf7f0c501356333571f7a \ + --hash=sha256:71334371bd73d5fe080aed39fbff49ed8efb9506edebe16795b0c7567ed6a272 \ + --hash=sha256:7e048733c36f564b379831689006801feb267d8194f9e793fbb395ef1723335d \ + --hash=sha256:8a9dcef55507b6567207e8ee0a6b053d0688019b47ff7f26edc1764b7f4dc0a4 \ + --hash=sha256:a24027248399fb41594b696f929f9956828ae7cc85596d9f775e6c239cd0c2be + # via docling-core +tree-sitter-typescript==0.23.2 \ + --hash=sha256:05db58f70b95ef0ea126db5560f3775692f609589ed6f8dd0af84b7f19f1cbb7 \ + --hash=sha256:3cd752d70d8e5371fdac6a9a4df9d8924b63b6998d268586f7d374c9fba2a478 \ + --hash=sha256:3f730b66396bc3e11811e4465c41ee45d9e9edd6de355a58bbbc49fa770da8f9 \ + --hash=sha256:4b1eed5b0b3a8134e86126b00b743d667ec27c63fc9de1b7bb23168803879e31 \ + --hash=sha256:7b167b5827c882261cb7a50dfa0fb567975f9b315e87ed87ad0a0a3aedb3834d \ + --hash=sha256:8d4f0f9bcb61ad7b7509d49a1565ff2cc363863644a234e1e0fe10960e55aea0 \ + --hash=sha256:c7cc1b0ff5d91bac863b0e38b1578d5505e718156c9db577c8baea2557f66de8 \ + --hash=sha256:e96d36b85bcacdeb8ff5c2618d75593ef12ebaf1b4eace3477e2bdb2abb1752c + # via docling-core +trino==0.336.0 \ + --hash=sha256:389150841446949119c3c2c13c1a51bb4be1a27818e40ae40dd3701f36c02550 \ + --hash=sha256:e82339e9fffe5c6c51de3bfdf28f083e3ae5945a4502739ab2094a0d08d68070 + # via feast (setup.py) +typeguard==4.4.4 \ + --hash=sha256:3a7fd2dffb705d4d0efaed4306a704c89b9dee850b688f060a8b1615a79e5f74 \ + --hash=sha256:b5f562281b6bfa1f5492470464730ef001646128b180769880468bd84b68b09e + # via feast (setup.py) +typer==0.12.5 \ + --hash=sha256:62fe4e471711b147e3365034133904df3e235698399bc4de2b36c8579298d52b \ + --hash=sha256:f592f089bedcc8ec1b974125d64851029c3b1af145f04aca64d69410f0c9b722 + # via + # docling + # docling-core + # fastapi-mcp +types-cffi==1.17.0.20250915 \ + --hash=sha256:4362e20368f78dabd5c56bca8004752cc890e07a71605d9e0d9e069dbaac8c06 \ + --hash=sha256:cef4af1116c83359c11bb4269283c50f0688e9fc1d7f0eeb390f3661546da52c + # via types-pyopenssl +types-protobuf==3.19.22 \ + --hash=sha256:d291388678af91bb045fafa864f142dc4ac22f5d4cdca097c7d8d8a32fa9b3ab \ + --hash=sha256:d2b26861b0cb46a3c8669b0df507b7ef72e487da66d61f9f3576aa76ce028a83 + # via + # feast (setup.py) + # mypy-protobuf +types-pymysql==1.1.0.20251220 \ + --hash=sha256:ae1c3df32a777489431e2e9963880a0df48f6591e0aa2fd3a6fabd9dee6eca54 \ + --hash=sha256:fa1082af7dea6c53b6caa5784241924b1296ea3a8d3bd060417352c5e10c0618 + # via feast (setup.py) +types-pyopenssl==24.1.0.20240722 \ + --hash=sha256:47913b4678a01d879f503a12044468221ed8576263c1540dcb0484ca21b08c39 \ + --hash=sha256:6a7a5d2ec042537934cfb4c9d4deb0e16c4c6250b09358df1f083682fe6fda54 + # via types-redis +types-python-dateutil==2.9.0.20251115 \ + --hash=sha256:8a47f2c3920f52a994056b8786309b43143faa5a64d4cbb2722d6addabdf1a58 \ + --hash=sha256:9cf9c1c582019753b8639a081deefd7e044b9fa36bd8217f565c6c4e36ee0624 + # via feast (setup.py) +types-pytz==2025.2.0.20251108 \ + --hash=sha256:0f1c9792cab4eb0e46c52f8845c8f77cf1e313cb3d68bf826aa867fe4717d91c \ + --hash=sha256:fca87917836ae843f07129567b74c1929f1870610681b4c92cb86a3df5817bdb + # via feast (setup.py) +types-pyyaml==6.0.12.20250915 \ + --hash=sha256:0f8b54a528c303f0e6f7165687dd33fafa81c807fcac23f632b63aa624ced1d3 \ + --hash=sha256:e7d4d9e064e89a3b3cae120b4990cd370874d2bf12fa5f46c97018dd5d3c9ab6 + # via feast (setup.py) +types-redis==4.6.0.20241004 \ + --hash=sha256:5f17d2b3f9091ab75384153bfa276619ffa1cf6a38da60e10d5e6749cc5b902e \ + --hash=sha256:ef5da68cb827e5f606c8f9c0b49eeee4c2669d6d97122f301d3a55dc6a63f6ed + # via feast (setup.py) +types-requests==2.30.0.0 \ + --hash=sha256:c6cf08e120ca9f0dc4fa4e32c3f953c3fba222bcc1db6b97695bce8da1ba9864 \ + --hash=sha256:dec781054324a70ba64430ae9e62e7e9c8e4618c185a5cb3f87a6738251b5a31 + # via feast (setup.py) +types-setuptools==80.9.0.20251223 \ + --hash=sha256:1b36db79d724c2287d83dc052cf887b47c0da6a2fff044378be0b019545f56e6 \ + --hash=sha256:d3411059ae2f5f03985217d86ac6084efea2c9e9cacd5f0869ef950f308169b2 + # via + # feast (setup.py) + # types-cffi +types-tabulate==0.9.0.20241207 \ + --hash=sha256:ac1ac174750c0a385dfd248edc6279fa328aaf4ea317915ab879a2ec47833230 \ + --hash=sha256:b8dad1343c2a8ba5861c5441370c3e35908edd234ff036d4298708a1d4cf8a85 + # via feast (setup.py) +types-urllib3==1.26.25.14 \ + --hash=sha256:229b7f577c951b8c1b92c1bc2b2fdb0b49847bd2af6d1cc2a2e3dd340f3bda8f \ + --hash=sha256:9683bbb7fb72e32bfe9d2be6e04875fbe1b3eeec3cbb4ea231435aa7fd6b4f0e + # via types-requests +typing-extensions==4.15.0 \ + --hash=sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466 \ + --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548 + # via + # aiosignal + # anyio + # azure-core + # azure-identity + # azure-storage-blob + # beautifulsoup4 + # docling-core + # elasticsearch + # fastapi + # great-expectations + # huggingface-hub + # ibis-framework + # ipython + # jwcrypto + # mcp + # minio + # mypy + # opentelemetry-api + # opentelemetry-sdk + # opentelemetry-semantic-conventions + # psycopg + # psycopg-pool + # pydantic + # pydantic-core + # pyopenssl + # python-docx + # python-pptx + # referencing + # snowflake-connector-python + # sqlalchemy + # starlette + # testcontainers + # torch + # typeguard + # typer + # typing-inspection +typing-inspection==0.4.2 \ + --hash=sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7 \ + --hash=sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464 + # via + # mcp + # pydantic + # pydantic-settings +tzdata==2025.3 \ + --hash=sha256:06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 \ + --hash=sha256:de39c2ca5dc7b0344f2eba86f49d614019d29f060fc4ebc8a417896a620b56a7 + # via + # arrow + # pandas +tzlocal==5.3.1 \ + --hash=sha256:cceffc7edecefea1f595541dbd6e990cb1ea3d19bf01b2809f362a03dd7921fd \ + --hash=sha256:eb1a66c3ef5847adf7a834f1be0800581b683b5608e74f86ecbcef8ab91bb85d + # via + # great-expectations + # trino +ujson==5.11.0 \ + --hash=sha256:0180a480a7d099082501cad1fe85252e4d4bf926b40960fb3d9e87a3a6fbbc80 \ + --hash=sha256:04c41afc195fd477a59db3a84d5b83a871bd648ef371cf8c6f43072d89144eef \ + --hash=sha256:0654a2691fc252c3c525e3d034bb27b8a7546c9d3eb33cd29ce6c9feda361a6a \ + --hash=sha256:090b4d11b380ae25453100b722d0609d5051ffe98f80ec52853ccf8249dfd840 \ + --hash=sha256:109f59885041b14ee9569bf0bb3f98579c3fa0652317b355669939e5fc5ede53 \ + --hash=sha256:10f29e71ecf4ecd93a6610bd8efa8e7b6467454a363c3d6416db65de883eb076 \ + --hash=sha256:1194b943e951092db611011cb8dbdb6cf94a3b816ed07906e14d3bc6ce0e90ab \ + --hash=sha256:12b5e7e22a1fe01058000d1b317d3b65cc3daf61bd2ea7a2b76721fe160fa74d \ + --hash=sha256:16ccb973b7ada0455201808ff11d48fe9c3f034a6ab5bd93b944443c88299f89 \ + --hash=sha256:181fb5b15703a8b9370b25345d2a1fd1359f0f18776b3643d24e13ed9c036d4c \ + --hash=sha256:185f93ebccffebc8baf8302c869fac70dd5dd78694f3b875d03a31b03b062cdb \ + --hash=sha256:1a0a9b76a89827a592656fe12e000cf4f12da9692f51a841a4a07aa4c7ecc41c \ + --hash=sha256:1a325fd2c3a056cf6c8e023f74a0c478dd282a93141356ae7f16d5309f5ff823 \ + --hash=sha256:1aa8a2ab482f09f6c10fba37112af5f957689a79ea598399c85009f2f29898b5 \ + --hash=sha256:1d663b96eb34c93392e9caae19c099ec4133ba21654b081956613327f0e973ac \ + --hash=sha256:29113c003ca33ab71b1b480bde952fbab2a0b6b03a4ee4c3d71687cdcbd1a29d \ + --hash=sha256:30f607c70091483550fbd669a0b37471e5165b317d6c16e75dba2aa967608723 \ + --hash=sha256:3134b783ab314d2298d58cda7e47e7a0f7f71fc6ade6ac86d5dbeaf4b9770fa6 \ + --hash=sha256:34032aeca4510a7c7102bd5933f59a37f63891f30a0706fb46487ab6f0edf8f0 \ + --hash=sha256:3772e4fe6b0c1e025ba3c50841a0ca4786825a4894c8411bf8d3afe3a8061328 \ + --hash=sha256:3d2720e9785f84312b8e2cb0c2b87f1a0b1c53aaab3b2af3ab817d54409012e0 \ + --hash=sha256:416389ec19ef5f2013592f791486bef712ebce0cd59299bf9df1ba40bb2f6e04 \ + --hash=sha256:446e8c11c06048611c9d29ef1237065de0af07cabdd97e6b5b527b957692ec25 \ + --hash=sha256:4598bf3965fc1a936bd84034312bcbe00ba87880ef1ee33e33c1e88f2c398b49 \ + --hash=sha256:48055e1061c1bb1f79e75b4ac39e821f3f35a9b82de17fce92c3140149009bec \ + --hash=sha256:4843f3ab4fe1cc596bb7e02228ef4c25d35b4bb0809d6a260852a4bfcab37ba3 \ + --hash=sha256:49e56ef8066f11b80d620985ae36869a3ff7e4b74c3b6129182ec5d1df0255f3 \ + --hash=sha256:4b42c115c7c6012506e8168315150d1e3f76e7ba0f4f95616f4ee599a1372bbc \ + --hash=sha256:4c9f5d6a27d035dd90a146f7761c2272cf7103de5127c9ab9c4cd39ea61e878a \ + --hash=sha256:5600202a731af24a25e2d7b6eb3f648e4ecd4bb67c4d5cf12f8fab31677469c9 \ + --hash=sha256:65724738c73645db88f70ba1f2e6fb678f913281804d5da2fd02c8c5839af302 \ + --hash=sha256:65f3c279f4ed4bf9131b11972040200c66ae040368abdbb21596bf1564899694 \ + --hash=sha256:674f306e3e6089f92b126eb2fe41bcb65e42a15432c143365c729fdb50518547 \ + --hash=sha256:683f57f0dd3acdd7d9aff1de0528d603aafcb0e6d126e3dc7ce8b020a28f5d01 \ + --hash=sha256:6b6ec7e7321d7fc19abdda3ad809baef935f49673951a8bab486aea975007e02 \ + --hash=sha256:6cd2df62f24c506a0ba322d5e4fe4466d47a9467b57e881ee15a31f7ecf68ff6 \ + --hash=sha256:6dd703c3e86dc6f7044c5ac0b3ae079ed96bf297974598116aa5fb7f655c3a60 \ + --hash=sha256:6eff24e1abd79e0ec6d7eae651dd675ddbc41f9e43e29ef81e16b421da896915 \ + --hash=sha256:7855ccea3f8dad5e66d8445d754fc1cf80265a4272b5f8059ebc7ec29b8d0835 \ + --hash=sha256:787aff4a84da301b7f3bac09bc696e2e5670df829c6f8ecf39916b4e7e24e701 \ + --hash=sha256:7895f0d2d53bd6aea11743bd56e3cb82d729980636cd0ed9b89418bf66591702 \ + --hash=sha256:78c684fb21255b9b90320ba7e199780f653e03f6c2528663768965f4126a5b50 \ + --hash=sha256:7e0ec1646db172beb8d3df4c32a9d78015e671d2000af548252769e33079d9a6 \ + --hash=sha256:7e3cff632c1d78023b15f7e3a81c3745cd3f94c044d1e8fa8efbd6b161997bbc \ + --hash=sha256:7f1a27ab91083b4770e160d17f61b407f587548f2c2b5fbf19f94794c495594a \ + --hash=sha256:80017e870d882d5517d28995b62e4e518a894f932f1e242cbc802a2fd64d365c \ + --hash=sha256:8254e858437c00f17cb72e7a644fc42dad0ebb21ea981b71df6e84b1072aaa7c \ + --hash=sha256:837da4d27fed5fdc1b630bd18f519744b23a0b5ada1bbde1a36ba463f2900c03 \ + --hash=sha256:849e65b696f0d242833f1df4182096cedc50d414215d1371fca85c541fbff629 \ + --hash=sha256:85e6796631165f719084a9af00c79195d3ebf108151452fefdcb1c8bb50f0105 \ + --hash=sha256:86baf341d90b566d61a394869ce77188cc8668f76d7bb2c311d77a00f4bdf844 \ + --hash=sha256:8fa2af7c1459204b7a42e98263b069bd535ea0cd978b4d6982f35af5a04a4241 \ + --hash=sha256:94fcae844f1e302f6f8095c5d1c45a2f0bfb928cccf9f1b99e3ace634b980a2a \ + --hash=sha256:952c0be400229940248c0f5356514123d428cba1946af6fa2bbd7503395fef26 \ + --hash=sha256:99c49400572cd77050894e16864a335225191fd72a818ea6423ae1a06467beac \ + --hash=sha256:9aacbeb23fdbc4b256a7d12e0beb9063a1ba5d9e0dbb2cfe16357c98b4334596 \ + --hash=sha256:a0af6574fc1d9d53f4ff371f58c96673e6d988ed2b5bf666a6143c782fa007e9 \ + --hash=sha256:a31c6b8004438e8c20fc55ac1c0e07dad42941db24176fe9acf2815971f8e752 \ + --hash=sha256:a4df61a6df0a4a8eb5b9b1ffd673429811f50b235539dac586bb7e9e91994138 \ + --hash=sha256:a638425d3c6eed0318df663df44480f4a40dc87cc7c6da44d221418312f6413b \ + --hash=sha256:aa6b3d4f1c0d3f82930f4cbd7fe46d905a4a9205a7c13279789c1263faf06dba \ + --hash=sha256:aa6d7a5e09217ff93234e050e3e380da62b084e26b9f2e277d2606406a2fc2e5 \ + --hash=sha256:ab2cb8351d976e788669c8281465d44d4e94413718af497b4e7342d7b2f78018 \ + --hash=sha256:abae0fb58cc820092a0e9e8ba0051ac4583958495bfa5262a12f628249e3b362 \ + --hash=sha256:b16930f6a0753cdc7d637b33b4e8f10d5e351e1fb83872ba6375f1e87be39746 \ + --hash=sha256:b7b136cc6abc7619124fd897ef75f8e63105298b5ca9bdf43ebd0e1fa0ee105f \ + --hash=sha256:be6b0eaf92cae8cdee4d4c9e074bde43ef1c590ed5ba037ea26c9632fb479c88 \ + --hash=sha256:c44c703842024d796b4c78542a6fcd5c3cb948b9fc2a73ee65b9c86a22ee3638 \ + --hash=sha256:c6618f480f7c9ded05e78a1938873fde68baf96cdd74e6d23c7e0a8441175c4b \ + --hash=sha256:ce076f2df2e1aa62b685086fbad67f2b1d3048369664b4cdccc50707325401f9 \ + --hash=sha256:d06e87eded62ff0e5f5178c916337d2262fdbc03b31688142a3433eabb6511db \ + --hash=sha256:d7c46cb0fe5e7056b9acb748a4c35aa1b428025853032540bb7e41f46767321f \ + --hash=sha256:d8951bb7a505ab2a700e26f691bdfacf395bc7e3111e3416d325b513eea03a58 \ + --hash=sha256:da473b23e3a54448b008d33f742bcd6d5fb2a897e42d1fc6e7bf306ea5d18b1b \ + --hash=sha256:de6e88f62796372fba1de973c11138f197d3e0e1d80bcb2b8aae1e826096d433 \ + --hash=sha256:e204ae6f909f099ba6b6b942131cee359ddda2b6e4ea39c12eb8b991fe2010e0 \ + --hash=sha256:e73df8648c9470af2b6a6bf5250d4744ad2cf3d774dcf8c6e31f018bdd04d764 \ + --hash=sha256:e750c436fb90edf85585f5c62a35b35082502383840962c6983403d1bd96a02c \ + --hash=sha256:e979fbc469a7f77f04ec2f4e853ba00c441bf2b06720aa259f0f720561335e34 \ + --hash=sha256:ecd6ff8a3b5a90c292c2396c2d63c687fd0ecdf17de390d852524393cd9ed052 \ + --hash=sha256:f278b31a7c52eb0947b2db55a5133fbc46b6f0ef49972cd1a80843b72e135aba \ + --hash=sha256:f62b9976fabbcde3ab6e413f4ec2ff017749819a0786d84d7510171109f2d53c \ + --hash=sha256:fa79fdb47701942c2132a9dd2297a1a85941d966d8c87bfd9e29b0cf423f26cc \ + --hash=sha256:fac6c0649d6b7c3682a0a6e18d3de6857977378dce8d419f57a0b20e3d775b39 + # via pymilvus +uri-template==1.3.0 \ + --hash=sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7 \ + --hash=sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363 + # via jsonschema +urllib3==2.6.3 \ + --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \ + --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 + # via + # feast (setup.py) + # botocore + # clickhouse-connect + # docker + # elastic-transport + # great-expectations + # kubernetes + # minio + # qdrant-client + # requests + # responses + # testcontainers +uvicorn[standard]==0.34.0 \ + --hash=sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4 \ + --hash=sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9 + # via + # feast (setup.py) + # fastapi-mcp + # mcp + # uvicorn-worker +uvicorn-worker==0.3.0 \ + --hash=sha256:6baeab7b2162ea6b9612cbe149aa670a76090ad65a267ce8e27316ed13c7de7b \ + --hash=sha256:ef0fe8aad27b0290a9e602a256b03f5a5da3a9e5f942414ca587b645ec77dd52 + # via feast (setup.py) +uvloop==0.22.1 \ + --hash=sha256:017bd46f9e7b78e81606329d07141d3da446f8798c6baeec124260e22c262772 \ + --hash=sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e \ + --hash=sha256:05e4b5f86e621cf3927631789999e697e58f0d2d32675b67d9ca9eb0bca55743 \ + --hash=sha256:0ae676de143db2b2f60a9696d7eca5bb9d0dd6cc3ac3dad59a8ae7e95f9e1b54 \ + --hash=sha256:1489cf791aa7b6e8c8be1c5a080bae3a672791fcb4e9e12249b05862a2ca9cec \ + --hash=sha256:17d4e97258b0172dfa107b89aa1eeba3016f4b1974ce85ca3ef6a66b35cbf659 \ + --hash=sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8 \ + --hash=sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad \ + --hash=sha256:286322a90bea1f9422a470d5d2ad82d38080be0a29c4dd9b3e6384320a4d11e7 \ + --hash=sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35 \ + --hash=sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289 \ + --hash=sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142 \ + --hash=sha256:3b7f102bf3cb1995cfeaee9321105e8f5da76fdb104cdad8986f85461a1b7b77 \ + --hash=sha256:40631b049d5972c6755b06d0bfe8233b1bd9a8a6392d9d1c45c10b6f9e9b2733 \ + --hash=sha256:481c990a7abe2c6f4fc3d98781cc9426ebd7f03a9aaa7eb03d3bfc68ac2a46bd \ + --hash=sha256:4a968a72422a097b09042d5fa2c5c590251ad484acf910a651b4b620acd7f193 \ + --hash=sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74 \ + --hash=sha256:512fec6815e2dd45161054592441ef76c830eddaad55c8aa30952e6fe1ed07c0 \ + --hash=sha256:51eb9bd88391483410daad430813d982010f9c9c89512321f5b60e2cddbdddd6 \ + --hash=sha256:535cc37b3a04f6cd2c1ef65fa1d370c9a35b6695df735fcff5427323f2cd5473 \ + --hash=sha256:53c85520781d84a4b8b230e24a5af5b0778efdb39142b424990ff1ef7c48ba21 \ + --hash=sha256:55502bc2c653ed2e9692e8c55cb95b397d33f9f2911e929dc97c4d6b26d04242 \ + --hash=sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705 \ + --hash=sha256:56a2d1fae65fd82197cb8c53c367310b3eabe1bbb9fb5a04d28e3e3520e4f702 \ + --hash=sha256:57df59d8b48feb0e613d9b1f5e57b7532e97cbaf0d61f7aa9aa32221e84bc4b6 \ + --hash=sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f \ + --hash=sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e \ + --hash=sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d \ + --hash=sha256:700e674a166ca5778255e0e1dc4e9d79ab2acc57b9171b79e65feba7184b3370 \ + --hash=sha256:7b5b1ac819a3f946d3b2ee07f09149578ae76066d70b44df3fa990add49a82e4 \ + --hash=sha256:7cd375a12b71d33d46af85a3343b35d98e8116134ba404bd657b3b1d15988792 \ + --hash=sha256:80eee091fe128e425177fbd82f8635769e2f32ec9daf6468286ec57ec0313efa \ + --hash=sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079 \ + --hash=sha256:a592b043a47ad17911add5fbd087c76716d7c9ccc1d64ec9249ceafd735f03c2 \ + --hash=sha256:ac33ed96229b7790eb729702751c0e93ac5bc3bcf52ae9eccbff30da09194b86 \ + --hash=sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6 \ + --hash=sha256:b45649628d816c030dba3c80f8e2689bab1c89518ed10d426036cdc47874dfc4 \ + --hash=sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3 \ + --hash=sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21 \ + --hash=sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c \ + --hash=sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e \ + --hash=sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25 \ + --hash=sha256:c3e5c6727a57cb6558592a95019e504f605d1c54eb86463ee9f7a2dbd411c820 \ + --hash=sha256:c60ebcd36f7b240b30788554b6f0782454826a0ed765d8430652621b5de674b9 \ + --hash=sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88 \ + --hash=sha256:e047cc068570bac9866237739607d1313b9253c3051ad84738cbb095be0537b2 \ + --hash=sha256:ea721dd3203b809039fcc2983f14608dae82b212288b346e0bfe46ec2fab0b7c \ + --hash=sha256:ef6f0d4cc8a9fa1f6a910230cd53545d9a14479311e87e3cb225495952eb672c \ + --hash=sha256:fe94b4564e865d968414598eea1a6de60adba0c040ba4ed05ac1300de402cd42 + # via uvicorn +virtualenv==20.23.0 \ + --hash=sha256:6abec7670e5802a528357fdc75b26b9f57d5d92f29c5462ba0fbe45feacc685e \ + --hash=sha256:a85caa554ced0c0afbd0d638e7e2d7b5f92d23478d05d17a76daeac8f279f924 + # via + # feast (setup.py) + # pre-commit + # ray +watchfiles==1.1.1 \ + --hash=sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c \ + --hash=sha256:03fa0f5237118a0c5e496185cafa92878568b652a2e9a9382a5151b1a0380a43 \ + --hash=sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510 \ + --hash=sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0 \ + --hash=sha256:08af70fd77eee58549cd69c25055dc344f918d992ff626068242259f98d598a2 \ + --hash=sha256:0b495de0bb386df6a12b18335a0285dda90260f51bdb505503c02bcd1ce27a8b \ + --hash=sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18 \ + --hash=sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219 \ + --hash=sha256:17ef139237dfced9da49fb7f2232c86ca9421f666d78c264c7ffca6601d154c3 \ + --hash=sha256:1a0bb430adb19ef49389e1ad368450193a90038b5b752f4ac089ec6942c4dff4 \ + --hash=sha256:1db5d7ae38ff20153d542460752ff397fcf5c96090c1230803713cf3147a6803 \ + --hash=sha256:28475ddbde92df1874b6c5c8aaeb24ad5be47a11f87cde5a28ef3835932e3e94 \ + --hash=sha256:2edc3553362b1c38d9f06242416a5d8e9fe235c204a4072e988ce2e5bb1f69f6 \ + --hash=sha256:30f7da3fb3f2844259cba4720c3fc7138eb0f7b659c38f3bfa65084c7fc7abce \ + --hash=sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099 \ + --hash=sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae \ + --hash=sha256:35c53bd62a0b885bf653ebf6b700d1bf05debb78ad9292cf2a942b23513dc4c4 \ + --hash=sha256:36193ed342f5b9842edd3532729a2ad55c4160ffcfa3700e0d54be496b70dd43 \ + --hash=sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd \ + --hash=sha256:399600947b170270e80134ac854e21b3ccdefa11a9529a3decc1327088180f10 \ + --hash=sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374 \ + --hash=sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051 \ + --hash=sha256:3bc570d6c01c206c46deb6e935a260be44f186a2f05179f52f7fcd2be086a94d \ + --hash=sha256:3dbd8cbadd46984f802f6d479b7e3afa86c42d13e8f0f322d669d79722c8ec34 \ + --hash=sha256:3e6f39af2eab0118338902798b5aa6664f46ff66bc0280de76fca67a7f262a49 \ + --hash=sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7 \ + --hash=sha256:3f6d37644155fb5beca5378feb8c1708d5783145f2a0f1c4d5a061a210254844 \ + --hash=sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77 \ + --hash=sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b \ + --hash=sha256:421e29339983e1bebc281fab40d812742268ad057db4aee8c4d2bce0af43b741 \ + --hash=sha256:4b943d3668d61cfa528eb949577479d3b077fd25fb83c641235437bc0b5bc60e \ + --hash=sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33 \ + --hash=sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42 \ + --hash=sha256:544364b2b51a9b0c7000a4b4b02f90e9423d97fbbf7e06689236443ebcad81ab \ + --hash=sha256:5524298e3827105b61951a29c3512deb9578586abf3a7c5da4a8069df247cccc \ + --hash=sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5 \ + --hash=sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da \ + --hash=sha256:57ca5281a8b5e27593cb7d82c2ac927ad88a96ed406aa446f6344e4328208e9e \ + --hash=sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05 \ + --hash=sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a \ + --hash=sha256:5f3f58818dc0b07f7d9aa7fe9eb1037aecb9700e63e1f6acfed13e9fef648f5d \ + --hash=sha256:5fac835b4ab3c6487b5dbad78c4b3724e26bcc468e886f8ba8cc4306f68f6701 \ + --hash=sha256:620bae625f4cb18427b1bb1a2d9426dc0dd5a5ba74c7c2cdb9de405f7b129863 \ + --hash=sha256:672b8adf25b1a0d35c96b5888b7b18699d27d4194bac8beeae75be4b7a3fc9b2 \ + --hash=sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101 \ + --hash=sha256:6c3631058c37e4a0ec440bf583bc53cdbd13e5661bb6f465bc1d88ee9a0a4d02 \ + --hash=sha256:6c9c9262f454d1c4d8aaa7050121eb4f3aea197360553699520767daebf2180b \ + --hash=sha256:6e43d39a741e972bab5d8100b5cdacf69db64e34eb19b6e9af162bccf63c5cc6 \ + --hash=sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb \ + --hash=sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620 \ + --hash=sha256:74472234c8370669850e1c312490f6026d132ca2d396abfad8830b4f1c096957 \ + --hash=sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6 \ + --hash=sha256:77a13aea58bc2b90173bc69f2a90de8e282648939a00a602e1dc4ee23e26b66d \ + --hash=sha256:79ff6c6eadf2e3fc0d7786331362e6ef1e51125892c75f1004bd6b52155fb956 \ + --hash=sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef \ + --hash=sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261 \ + --hash=sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02 \ + --hash=sha256:8526e8f916bb5b9a0a777c8317c23ce65de259422bba5b31325a6fa6029d33af \ + --hash=sha256:859e43a1951717cc8de7f4c77674a6d389b106361585951d9e69572823f311d9 \ + --hash=sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21 \ + --hash=sha256:89eef07eee5e9d1fda06e38822ad167a044153457e6fd997f8a858ab7564a336 \ + --hash=sha256:8c89f9f2f740a6b7dcc753140dd5e1ab9215966f7a3530d0c0705c83b401bd7d \ + --hash=sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c \ + --hash=sha256:8ca65483439f9c791897f7db49202301deb6e15fe9f8fe2fed555bf986d10c31 \ + --hash=sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81 \ + --hash=sha256:91d4c9a823a8c987cce8fa2690923b069966dabb196dd8d137ea2cede885fde9 \ + --hash=sha256:9bb9f66367023ae783551042d31b1d7fd422e8289eedd91f26754a66f44d5cff \ + --hash=sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2 \ + --hash=sha256:a36d8efe0f290835fd0f33da35042a1bb5dc0e83cbc092dcf69bce442579e88e \ + --hash=sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc \ + --hash=sha256:a625815d4a2bdca61953dbba5a39d60164451ef34c88d751f6c368c3ea73d404 \ + --hash=sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01 \ + --hash=sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18 \ + --hash=sha256:acb08650863767cbc58bca4813b92df4d6c648459dcaa3d4155681962b2aa2d3 \ + --hash=sha256:aebfd0861a83e6c3d1110b78ad54704486555246e542be3e2bb94195eabb2606 \ + --hash=sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04 \ + --hash=sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3 \ + --hash=sha256:b2cd9e04277e756a2e2d2543d65d1e2166d6fd4c9b183f8808634fda23f17b14 \ + --hash=sha256:b9c4702f29ca48e023ffd9b7ff6b822acdf47cb1ff44cb490a3f1d5ec8987e9c \ + --hash=sha256:bbe1ef33d45bc71cf21364df962af171f96ecaeca06bd9e3d0b583efb12aec82 \ + --hash=sha256:bd404be08018c37350f0d6e34676bd1e2889990117a2b90070b3007f172d0610 \ + --hash=sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0 \ + --hash=sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150 \ + --hash=sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5 \ + --hash=sha256:c1f5210f1b8fc91ead1283c6fd89f70e76fb07283ec738056cf34d51e9c1d62c \ + --hash=sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a \ + --hash=sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b \ + --hash=sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d \ + --hash=sha256:c882d69f6903ef6092bedfb7be973d9319940d56b8427ab9187d1ecd73438a70 \ + --hash=sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70 \ + --hash=sha256:cdab464fee731e0884c35ae3588514a9bcf718d0e2c82169c1c4a85cc19c3c7f \ + --hash=sha256:ce19e06cbda693e9e7686358af9cd6f5d61312ab8b00488bc36f5aabbaf77e24 \ + --hash=sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e \ + --hash=sha256:cf57a27fb986c6243d2ee78392c503826056ffe0287e8794503b10fb51b881be \ + --hash=sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5 \ + --hash=sha256:d6ff426a7cb54f310d51bfe83fe9f2bbe40d540c741dc974ebc30e6aa238f52e \ + --hash=sha256:d7e7067c98040d646982daa1f37a33d3544138ea155536c2e0e63e07ff8a7e0f \ + --hash=sha256:db476ab59b6765134de1d4fe96a1a9c96ddf091683599be0f26147ea1b2e4b88 \ + --hash=sha256:dcc5c24523771db3a294c77d94771abcfcb82a0e0ee8efd910c37c59ec1b31bb \ + --hash=sha256:de6da501c883f58ad50db3a32ad397b09ad29865b5f26f64c24d3e3281685849 \ + --hash=sha256:e84087b432b6ac94778de547e08611266f1f8ffad28c0ee4c82e028b0fc5966d \ + --hash=sha256:eef58232d32daf2ac67f42dea51a2c80f0d03379075d44a587051e63cc2e368c \ + --hash=sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44 \ + --hash=sha256:f0ab1c1af0cb38e3f598244c17919fb1a84d1629cc08355b0074b6d7f53138ac \ + --hash=sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428 \ + --hash=sha256:f537afb3276d12814082a2e9b242bdcf416c2e8fd9f799a737990a1dbe906e5b \ + --hash=sha256:f57b396167a2565a4e8b5e56a5a1c537571733992b226f4f1197d79e94cf0ae5 \ + --hash=sha256:f8979280bdafff686ba5e4d8f97840f929a87ed9cdf133cbbd42f7766774d2aa \ + --hash=sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf + # via uvicorn +wcwidth==0.2.14 \ + --hash=sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605 \ + --hash=sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1 + # via prompt-toolkit +webcolors==25.10.0 \ + --hash=sha256:032c727334856fc0b968f63daa252a1ac93d33db2f5267756623c210e57a4f1d \ + --hash=sha256:62abae86504f66d0f6364c2a8520de4a0c47b80c03fc3a5f1815fedbef7c19bf + # via jsonschema +webencodings==0.5.1 \ + --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \ + --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923 + # via + # bleach + # tinycss2 +websocket-client==1.9.0 \ + --hash=sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98 \ + --hash=sha256:af248a825037ef591efbf6ed20cc5faa03d3b47b9e5a2230a529eeee1c1fc3ef + # via + # jupyter-server + # kubernetes +websockets==16.0 \ + --hash=sha256:0298d07ee155e2e9fda5be8a9042200dd2e3bb0b8a38482156576f863a9d457c \ + --hash=sha256:04cdd5d2d1dacbad0a7bf36ccbcd3ccd5a30ee188f2560b7a62a30d14107b31a \ + --hash=sha256:08d7af67b64d29823fed316505a89b86705f2b7981c07848fb5e3ea3020c1abe \ + --hash=sha256:152284a83a00c59b759697b7f9e9cddf4e3c7861dd0d964b472b70f78f89e80e \ + --hash=sha256:1637db62fad1dc833276dded54215f2c7fa46912301a24bd94d45d46a011ceec \ + --hash=sha256:19c4dc84098e523fd63711e563077d39e90ec6702aff4b5d9e344a60cb3c0cb1 \ + --hash=sha256:1c1b30e4f497b0b354057f3467f56244c603a79c0d1dafce1d16c283c25f6e64 \ + --hash=sha256:2b9f1e0d69bc60a4a87349d50c09a037a2607918746f07de04df9e43252c77a3 \ + --hash=sha256:31a52addea25187bde0797a97d6fc3d2f92b6f72a9370792d65a6e84615ac8a8 \ + --hash=sha256:32da954ffa2814258030e5a57bc73a3635463238e797c7375dc8091327434206 \ + --hash=sha256:335c23addf3d5e6a8633f9f8eda77efad001671e80b95c491dd0924587ece0b3 \ + --hash=sha256:3425ac5cf448801335d6fdc7ae1eb22072055417a96cc6b31b3861f455fbc156 \ + --hash=sha256:349f83cd6c9a415428ee1005cadb5c2c56f4389bc06a9af16103c3bc3dcc8b7d \ + --hash=sha256:37b31c1623c6605e4c00d466c9d633f9b812ea430c11c8a278774a1fde1acfa9 \ + --hash=sha256:417b28978cdccab24f46400586d128366313e8a96312e4b9362a4af504f3bbad \ + --hash=sha256:485c49116d0af10ac698623c513c1cc01c9446c058a4e61e3bf6c19dff7335a2 \ + --hash=sha256:4a1aba3340a8dca8db6eb5a7986157f52eb9e436b74813764241981ca4888f03 \ + --hash=sha256:50f23cdd8343b984957e4077839841146f67a3d31ab0d00e6b824e74c5b2f6e8 \ + --hash=sha256:52a0fec0e6c8d9a784c2c78276a48a2bdf099e4ccc2a4cad53b27718dbfd0230 \ + --hash=sha256:52ac480f44d32970d66763115edea932f1c5b1312de36df06d6b219f6741eed8 \ + --hash=sha256:5569417dc80977fc8c2d43a86f78e0a5a22fee17565d78621b6bb264a115d4ea \ + --hash=sha256:569d01a4e7fba956c5ae4fc988f0d4e187900f5497ce46339c996dbf24f17641 \ + --hash=sha256:583b7c42688636f930688d712885cf1531326ee05effd982028212ccc13e5957 \ + --hash=sha256:5a4b4cc550cb665dd8a47f868c8d04c8230f857363ad3c9caf7a0c3bf8c61ca6 \ + --hash=sha256:5f451484aeb5cafee1ccf789b1b66f535409d038c56966d6101740c1614b86c6 \ + --hash=sha256:5f6261a5e56e8d5c42a4497b364ea24d94d9563e8fbd44e78ac40879c60179b5 \ + --hash=sha256:6e5a82b677f8f6f59e8dfc34ec06ca6b5b48bc4fcda346acd093694cc2c24d8f \ + --hash=sha256:71c989cbf3254fbd5e84d3bff31e4da39c43f884e64f2551d14bb3c186230f00 \ + --hash=sha256:781caf5e8eee67f663126490c2f96f40906594cb86b408a703630f95550a8c3e \ + --hash=sha256:7be95cfb0a4dae143eaed2bcba8ac23f4892d8971311f1b06f3c6b78952ee70b \ + --hash=sha256:7d837379b647c0c4c2355c2499723f82f1635fd2c26510e1f587d89bc2199e72 \ + --hash=sha256:86890e837d61574c92a97496d590968b23c2ef0aeb8a9bc9421d174cd378ae39 \ + --hash=sha256:878b336ac47938b474c8f982ac2f7266a540adc3fa4ad74ae96fea9823a02cc9 \ + --hash=sha256:8b6e209ffee39ff1b6d0fa7bfef6de950c60dfb91b8fcead17da4ee539121a79 \ + --hash=sha256:8cc451a50f2aee53042ac52d2d053d08bf89bcb31ae799cb4487587661c038a0 \ + --hash=sha256:8d7f0659570eefb578dacde98e24fb60af35350193e4f56e11190787bee77dac \ + --hash=sha256:8e1dab317b6e77424356e11e99a432b7cb2f3ec8c5ab4dabbcee6add48f72b35 \ + --hash=sha256:8ff32bb86522a9e5e31439a58addbb0166f0204d64066fb955265c4e214160f0 \ + --hash=sha256:95724e638f0f9c350bb1c2b0a7ad0e83d9cc0c9259f3ea94e40d7b02a2179ae5 \ + --hash=sha256:9b5aca38b67492ef518a8ab76851862488a478602229112c4b0d58d63a7a4d5c \ + --hash=sha256:a069d734c4a043182729edd3e9f247c3b2a4035415a9172fd0f1b71658a320a8 \ + --hash=sha256:a0b31e0b424cc6b5a04b8838bbaec1688834b2383256688cf47eb97412531da1 \ + --hash=sha256:a35539cacc3febb22b8f4d4a99cc79b104226a756aa7400adc722e83b0d03244 \ + --hash=sha256:a5e18a238a2b2249c9a9235466b90e96ae4795672598a58772dd806edc7ac6d3 \ + --hash=sha256:a653aea902e0324b52f1613332ddf50b00c06fdaf7e92624fbf8c77c78fa5767 \ + --hash=sha256:abf050a199613f64c886ea10f38b47770a65154dc37181bfaff70c160f45315a \ + --hash=sha256:af80d74d4edfa3cb9ed973a0a5ba2b2a549371f8a741e0800cb07becdd20f23d \ + --hash=sha256:b14dc141ed6d2dde437cddb216004bcac6a1df0935d79656387bd41632ba0bbd \ + --hash=sha256:b784ca5de850f4ce93ec85d3269d24d4c82f22b7212023c974c401d4980ebc5e \ + --hash=sha256:bc59589ab64b0022385f429b94697348a6a234e8ce22544e3681b2e9331b5944 \ + --hash=sha256:c0204dc62a89dc9d50d682412c10b3542d748260d743500a85c13cd1ee4bde82 \ + --hash=sha256:c0ee0e63f23914732c6d7e0cce24915c48f3f1512ec1d079ed01fc629dab269d \ + --hash=sha256:caab51a72c51973ca21fa8a18bd8165e1a0183f1ac7066a182ff27107b71e1a4 \ + --hash=sha256:d6297ce39ce5c2e6feb13c1a996a2ded3b6832155fcfc920265c76f24c7cceb5 \ + --hash=sha256:daa3b6ff70a9241cf6c7fc9e949d41232d9d7d26fd3522b1ad2b4d62487e9904 \ + --hash=sha256:df57afc692e517a85e65b72e165356ed1df12386ecb879ad5693be08fac65dde \ + --hash=sha256:e0334872c0a37b606418ac52f6ab9cfd17317ac26365f7f65e203e2d0d0d359f \ + --hash=sha256:e6578ed5b6981005df1860a56e3617f14a6c307e6a71b4fff8c48fdc50f3ed2c \ + --hash=sha256:eaded469f5e5b7294e2bdca0ab06becb6756ea86894a47806456089298813c89 \ + --hash=sha256:f4a32d1bd841d4bcbffdcb3d2ce50c09c3909fbead375ab28d0181af89fd04da \ + --hash=sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4 + # via uvicorn +werkzeug==3.1.5 \ + --hash=sha256:5111e36e91086ece91f93268bb39b4a35c1e6f1feac762c9c822ded0a4e322dc \ + --hash=sha256:6a548b0e88955dd07ccb25539d7d0cc97417ee9e179677d22c7041c8f078ce67 + # via moto +wheel==0.45.1 \ + --hash=sha256:661e1abd9198507b1409a20c02106d9670b2576e916d58f520316666abca6729 \ + --hash=sha256:708e7481cc80179af0e556bbf0cc00b8444c7321e2700b8d8580231d13017248 + # via + # pip-tools + # singlestoredb +widgetsnbextension==4.0.15 \ + --hash=sha256:8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366 \ + --hash=sha256:de8610639996f1567952d763a5a41af8af37f2575a41f9852a38f947eb82a3b9 + # via ipywidgets +wrapt==1.17.3 \ + --hash=sha256:02b551d101f31694fc785e58e0720ef7d9a10c4e62c1c9358ce6f63f23e30a56 \ + --hash=sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828 \ + --hash=sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f \ + --hash=sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396 \ + --hash=sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77 \ + --hash=sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d \ + --hash=sha256:0f5f51a6466667a5a356e6381d362d259125b57f059103dd9fdc8c0cf1d14139 \ + --hash=sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7 \ + --hash=sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb \ + --hash=sha256:1f23fa283f51c890eda8e34e4937079114c74b4c81d2b2f1f1d94948f5cc3d7f \ + --hash=sha256:223db574bb38637e8230eb14b185565023ab624474df94d2af18f1cdb625216f \ + --hash=sha256:249f88ed15503f6492a71f01442abddd73856a0032ae860de6d75ca62eed8067 \ + --hash=sha256:24c2ed34dc222ed754247a2702b1e1e89fdbaa4016f324b4b8f1a802d4ffe87f \ + --hash=sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7 \ + --hash=sha256:281262213373b6d5e4bb4353bc36d1ba4084e6d6b5d242863721ef2bf2c2930b \ + --hash=sha256:30ce38e66630599e1193798285706903110d4f057aab3168a34b7fdc85569afc \ + --hash=sha256:33486899acd2d7d3066156b03465b949da3fd41a5da6e394ec49d271baefcf05 \ + --hash=sha256:343e44b2a8e60e06a7e0d29c1671a0d9951f59174f3709962b5143f60a2a98bd \ + --hash=sha256:373342dd05b1d07d752cecbec0c41817231f29f3a89aa8b8843f7b95992ed0c7 \ + --hash=sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9 \ + --hash=sha256:3e62d15d3cfa26e3d0788094de7b64efa75f3a53875cdbccdf78547aed547a81 \ + --hash=sha256:41b1d2bc74c2cac6f9074df52b2efbef2b30bdfe5f40cb78f8ca22963bc62977 \ + --hash=sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa \ + --hash=sha256:46acc57b331e0b3bcb3e1ca3b421d65637915cfcd65eb783cb2f78a511193f9b \ + --hash=sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe \ + --hash=sha256:507553480670cab08a800b9463bdb881b2edeed77dc677b0a5915e6106e91a58 \ + --hash=sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8 \ + --hash=sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77 \ + --hash=sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85 \ + --hash=sha256:55cbbc356c2842f39bcc553cf695932e8b30e30e797f961860afb308e6b1bb7c \ + --hash=sha256:59923aa12d0157f6b82d686c3fd8e1166fa8cdfb3e17b42ce3b6147ff81528df \ + --hash=sha256:5a03a38adec8066d5a37bea22f2ba6bbf39fcdefbe2d91419ab864c3fb515454 \ + --hash=sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a \ + --hash=sha256:5d4478d72eb61c36e5b446e375bbc49ed002430d17cdec3cecb36993398e1a9e \ + --hash=sha256:5ea5eb3c0c071862997d6f3e02af1d055f381b1d25b286b9d6644b79db77657c \ + --hash=sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6 \ + --hash=sha256:656873859b3b50eeebe6db8b1455e99d90c26ab058db8e427046dbc35c3140a5 \ + --hash=sha256:65d1d00fbfb3ea5f20add88bbc0f815150dbbde3b026e6c24759466c8b5a9ef9 \ + --hash=sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd \ + --hash=sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277 \ + --hash=sha256:70d86fa5197b8947a2fa70260b48e400bf2ccacdcab97bb7de47e3d1e6312225 \ + --hash=sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22 \ + --hash=sha256:73d496de46cd2cdbdbcce4ae4bcdb4afb6a11234a1df9c085249d55166b95116 \ + --hash=sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16 \ + --hash=sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc \ + --hash=sha256:758895b01d546812d1f42204bd443b8c433c44d090248bf22689df673ccafe00 \ + --hash=sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2 \ + --hash=sha256:7e18f01b0c3e4a07fe6dfdb00e29049ba17eadbc5e7609a2a3a4af83ab7d710a \ + --hash=sha256:88547535b787a6c9ce4086917b6e1d291aa8ed914fdd3a838b3539dc95c12804 \ + --hash=sha256:88bbae4d40d5a46142e70d58bf664a89b6b4befaea7b2ecc14e03cedb8e06c04 \ + --hash=sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1 \ + --hash=sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba \ + --hash=sha256:a36692b8491d30a8c75f1dfee65bef119d6f39ea84ee04d9f9311f83c5ad9390 \ + --hash=sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0 \ + --hash=sha256:a7c06742645f914f26c7f1fa47b8bc4c91d222f76ee20116c43d5ef0912bba2d \ + --hash=sha256:a9a2203361a6e6404f80b99234fe7fb37d1fc73487b5a78dc1aa5b97201e0f22 \ + --hash=sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0 \ + --hash=sha256:ad85e269fe54d506b240d2d7b9f5f2057c2aa9a2ea5b32c66f8902f768117ed2 \ + --hash=sha256:af338aa93554be859173c39c85243970dc6a289fa907402289eeae7543e1ae18 \ + --hash=sha256:afd964fd43b10c12213574db492cb8f73b2f0826c8df07a68288f8f19af2ebe6 \ + --hash=sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311 \ + --hash=sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89 \ + --hash=sha256:caea3e9c79d5f0d2c6d9ab96111601797ea5da8e6d0723f77eabb0d4068d2b2f \ + --hash=sha256:cf30f6e3c077c8e6a9a7809c94551203c8843e74ba0c960f4a98cd80d4665d39 \ + --hash=sha256:d40770d7c0fd5cbed9d84b2c3f2e156431a12c9a37dc6284060fb4bec0b7ffd4 \ + --hash=sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5 \ + --hash=sha256:dc4a8d2b25efb6681ecacad42fca8859f88092d8732b170de6a5dddd80a1c8fa \ + --hash=sha256:df7d30371a2accfe4013e90445f6388c570f103d61019b6b7c57e0265250072a \ + --hash=sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050 \ + --hash=sha256:e1a4120ae5705f673727d3253de3ed0e016f7cd78dc463db1b31e2463e1f3cf6 \ + --hash=sha256:e228514a06843cae89621384cfe3a80418f3c04aadf8a3b14e46a7be704e4235 \ + --hash=sha256:e405adefb53a435f01efa7ccdec012c016b5a1d3f35459990afc39b6be4d5056 \ + --hash=sha256:e6b13af258d6a9ad602d57d889f83b9d5543acd471eee12eb51f5b01f8eb1bc2 \ + --hash=sha256:e6f40a8aa5a92f150bdb3e1c44b7e98fb7113955b2e5394122fa5532fec4b418 \ + --hash=sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c \ + --hash=sha256:ed7c635ae45cfbc1a7371f708727bf74690daedc49b4dba310590ca0bd28aa8a \ + --hash=sha256:f38e60678850c42461d4202739f9bf1e3a737c7ad283638251e79cc49effb6b6 \ + --hash=sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0 \ + --hash=sha256:f9b2601381be482f70e5d1051a5965c25fb3625455a2bf520b5a077b22afb775 \ + --hash=sha256:fbd3c8319de8e1dc79d346929cd71d523622da527cca14e0c1d257e31c2b8b10 \ + --hash=sha256:fd341868a4b6714a5962c1af0bd44f7c404ef78720c7de4892901e540417111c + # via + # aiobotocore + # smart-open + # testcontainers +xlsxwriter==3.2.9 \ + --hash=sha256:254b1c37a368c444eac6e2f867405cc9e461b0ed97a3233b2ac1e574efb4140c \ + --hash=sha256:9a5db42bc5dff014806c58a20b9eae7322a134abb6fce3c92c181bfb275ec5b3 + # via python-pptx +xmltodict==1.0.2 \ + --hash=sha256:54306780b7c2175a3967cad1db92f218207e5bc1aba697d887807c0fb68b7649 \ + --hash=sha256:62d0fddb0dcbc9f642745d8bbf4d81fd17d6dfaec5a15b5c1876300aad92af0d + # via moto +xxhash==3.6.0 \ + --hash=sha256:01262da8798422d0685f7cef03b2bd3f4f46511b02830861df548d7def4402ad \ + --hash=sha256:01362c4331775398e7bb34e3ab403bc9ee9f7c497bc7dee6272114055277dd3c \ + --hash=sha256:016e9190af8f0a4e3741343777710e3d5717427f175adfdc3e72508f59e2a7f3 \ + --hash=sha256:01be0c5b500c5362871fc9cfdf58c69b3e5c4f531a82229ddb9eb1eb14138004 \ + --hash=sha256:0226aa89035b62b6a86d3c68df4d7c1f47a342b8683da2b60cedcddb46c4d95b \ + --hash=sha256:02ea4cb627c76f48cd9fb37cf7ab22bd51e57e1b519807234b473faebe526796 \ + --hash=sha256:0444e7967dac37569052d2409b00a8860c2135cff05502df4da80267d384849f \ + --hash=sha256:08d45aef063a4531b785cd72de4887766d01dc8f362a515693df349fdb825e0c \ + --hash=sha256:0d50101e57aad86f4344ca9b32d091a2135a9d0a4396f19133426c88025b09f1 \ + --hash=sha256:0e4edbfc7d420925b0dd5e792478ed393d6e75ff8fc219a6546fb446b6a417b1 \ + --hash=sha256:0f7b7e2ec26c1666ad5fc9dbfa426a6a3367ceaf79db5dd76264659d509d73b0 \ + --hash=sha256:1244460adc3a9be84731d72b8e80625788e5815b68da3da8b83f78115a40a7ec \ + --hash=sha256:15e0dac10eb9309508bfc41f7f9deaa7755c69e35af835db9cb10751adebc35d \ + --hash=sha256:18b242455eccdfcd1fa4134c431a30737d2b4f045770f8fe84356b3469d4b919 \ + --hash=sha256:1cf9dcc4ab9cff01dfbba78544297a3a01dafd60f3bde4e2bfd016cf7e4ddc67 \ + --hash=sha256:1fc1ed882d1e8df932a66e2999429ba6cc4d5172914c904ab193381fba825360 \ + --hash=sha256:2577b276e060b73b73a53042ea5bd5203d3e6347ce0d09f98500f418a9fcf799 \ + --hash=sha256:25915e6000338999236f1eb68a02a32c3275ac338628a7eaa5a269c401995679 \ + --hash=sha256:26734cdc2d4ffe449b41d186bbeac416f704a482ed835d375a5c0cb02bc63fef \ + --hash=sha256:2762bfff264c4e73c0e507274b40634ff465e025f0eaf050897e88ec8367575d \ + --hash=sha256:277175a73900ad43a8caeb8b99b9604f21fe8d7c842f2f9061a364a7e220ddb7 \ + --hash=sha256:297b7fbf86c82c550e12e8fb71968b3f033d27b874276ba3624ea868c11165a8 \ + --hash=sha256:2aa5ee3444c25b69813663c9f8067dcfaa2e126dc55e8dddf40f4d1c25d7effa \ + --hash=sha256:2ab89a6b80f22214b43d98693c30da66af910c04f9858dd39c8e570749593d7e \ + --hash=sha256:2b6821e94346f96db75abaa6e255706fb06ebd530899ed76d32cd99f20dc52fa \ + --hash=sha256:2f171a900d59d51511209f7476933c34a0c2c711078d3c80e74e0fe4f38680ec \ + --hash=sha256:339f518c3c7a850dd033ab416ea25a692759dc7478a71131fe8869010d2b75e4 \ + --hash=sha256:39be8e4e142550ef69629c9cd71b88c90e9a5db703fecbcf265546d9536ca4ad \ + --hash=sha256:3cd01fa2aa00d8b017c97eb46b9a794fbdca53fc14f845f5a328c71254b0abb7 \ + --hash=sha256:3ed0df1b11a79856df5ffcab572cbd6b9627034c1c748c5566fa79df9048a7c5 \ + --hash=sha256:40c391dd3cd041ebc3ffe6f2c862f402e306eb571422e0aa918d8070ba31da11 \ + --hash=sha256:418daf3db71e1413cfe211c2f9a528456936645c17f46b5204705581a45390ae \ + --hash=sha256:42c36dd7dbad2f5238950c377fcbf6811b1cdb1c444fab447960030cea60504d \ + --hash=sha256:44e342e8cc11b4e79dae5c57f2fb6360c3c20cc57d32049af8f567f5b4bcb5f4 \ + --hash=sha256:457b8f85dec5825eed7b69c11ae86834a018b8e3df5e77783c999663da2f96d6 \ + --hash=sha256:45aae0c9df92e7fa46fbb738737324a563c727990755ec1965a6a339ea10a1df \ + --hash=sha256:48e6f2ffb07a50b52465a1032c3cf1f4a5683f944acaca8a134a2f23674c2058 \ + --hash=sha256:4903530e866b7a9c1eadfd3fa2fbe1b97d3aed4739a80abf506eb9318561c850 \ + --hash=sha256:49e03e6fe2cac4a1bc64952dd250cf0dbc5ef4ebb7b8d96bce82e2de163c82a2 \ + --hash=sha256:4a082ffff8c6ac07707fb6b671caf7c6e020c75226c561830b73d862060f281d \ + --hash=sha256:4b54219177f6c6674d5378bd862c6aedf64725f70dd29c472eaae154df1a2e89 \ + --hash=sha256:4ccbff013972390b51a18ef1255ef5ac125c92dc9143b2d1909f59abc765540e \ + --hash=sha256:4da8168ae52c01ac64c511d6f4a709479da8b7a4a1d7621ed51652f93747dffa \ + --hash=sha256:4f6f72232f849eb9d0141e2ebe2677ece15adfd0fa599bc058aad83c714bb2c6 \ + --hash=sha256:50fc255f39428a27299c20e280d6193d8b63b8ef8028995323bf834a026b4fbb \ + --hash=sha256:51312c768403d8540487dbbfb557454cfc55589bbde6424456951f7fcd4facb3 \ + --hash=sha256:51a73fb7cb3a3ead9f7a8b583ffd9b8038e277cdb8cb87cf890e88b3456afa0b \ + --hash=sha256:5576b002a56207f640636056b4160a378fe36a58db73ae5c27a7ec8db35f71d4 \ + --hash=sha256:568a6d743219e717b07b4e03b0a828ce593833e498c3b64752e0f5df6bfe84db \ + --hash=sha256:5851f033c3030dd95c086b4a36a2683c2ff4a799b23af60977188b057e467119 \ + --hash=sha256:599e64ba7f67472481ceb6ee80fa3bd828fd61ba59fb11475572cc5ee52b89ec \ + --hash=sha256:5c1343d49ac102799905e115aee590183c3921d475356cb24b4de29a4bc56518 \ + --hash=sha256:5dc1e14d14fa0f5789ec29a7062004b5933964bb9b02aae6622b8f530dc40296 \ + --hash=sha256:5f059d9faeacd49c0215d66f4056e1326c80503f51a1532ca336a385edadd033 \ + --hash=sha256:6105ef7e62b5ac73a837778efc331a591d8442f8ef5c7e102376506cb4ae2729 \ + --hash=sha256:627f0af069b0ea56f312fd5189001c24578868643203bca1abbc2c52d3a6f3ca \ + --hash=sha256:63275a8aba7865e44b1813d2177e0f5ea7eadad3dd063a21f7cf9afdc7054063 \ + --hash=sha256:653a91d7c2ab54a92c19ccf43508b6a555440b9be1bc8be553376778be7f20b5 \ + --hash=sha256:6551880383f0e6971dc23e512c9ccc986147ce7bfa1cd2e4b520b876c53e9f3d \ + --hash=sha256:6812c25fe0d6c36a46ccb002f40f27ac903bf18af9f6dd8f9669cb4d176ab18f \ + --hash=sha256:6965e0e90f1f0e6cb78da568c13d4a348eeb7f40acfd6d43690a666a459458b8 \ + --hash=sha256:6f2580ffab1a8b68ef2b901cde7e55fa8da5e4be0977c68f78fc80f3c143de42 \ + --hash=sha256:6fb5f5476bef678f69db04f2bd1efbed3030d2aba305b0fc1773645f187d6a4e \ + --hash=sha256:757320d45d2fbcce8f30c42a6b2f47862967aea7bf458b9625b4bbe7ee390392 \ + --hash=sha256:780b90c313348f030b811efc37b0fa1431163cb8db8064cf88a7936b6ce5f222 \ + --hash=sha256:78e7f2f4c521c30ad5e786fdd6bae89d47a32672a80195467b5de0480aa97b1f \ + --hash=sha256:794fe9145fe60191c6532fa95063765529770edcdd67b3d537793e8004cabbfd \ + --hash=sha256:7a0b169aafb98f4284f73635a8e93f0735f9cbde17bd5ec332480484241aaa77 \ + --hash=sha256:7c35c4cdc65f2a29f34425c446f2f5cdcd0e3c34158931e1cc927ece925ab802 \ + --hash=sha256:7d14a6cfaf03b1b6f5f9790f76880601ccc7896aff7ab9cd8978a939c1eb7e0d \ + --hash=sha256:7d8b8aaa30fca4f16f0c84a5c8d7ddee0e25250ec2796c973775373257dde8f1 \ + --hash=sha256:7dac94fad14a3d1c92affb661021e1d5cbcf3876be5f5b4d90730775ccb7ac41 \ + --hash=sha256:843b52f6d88071f87eba1631b684fcb4b2068cd2180a0224122fe4ef011a9374 \ + --hash=sha256:858dc935963a33bc33490128edc1c12b0c14d9c7ebaa4e387a7869ecc4f3e263 \ + --hash=sha256:87ff03d7e35c61435976554477a7f4cd1704c3596a89a8300d5ce7fc83874a71 \ + --hash=sha256:881b47fc47e051b37d94d13e7455131054b56749b91b508b0907eb07900d1c13 \ + --hash=sha256:89952ea539566b9fed2bbd94e589672794b4286f342254fad28b149f9615fef8 \ + --hash=sha256:8a8f1972e75ebdd161d7896743122834fe87378160c20e97f8b09166213bf8cc \ + --hash=sha256:8b29ee68625ab37b04c0b40c3fafdf24d2f75ccd778333cfb698f65f6c463f62 \ + --hash=sha256:8cb2f4f679b01513b7adbb9b1b2f0f9cdc31b70007eaf9d59d0878809f385b11 \ + --hash=sha256:9085e798c163ce310d91f8aa6b325dda3c2944c93c6ce1edb314030d4167cc65 \ + --hash=sha256:9176dcaddf4ca963d4deb93866d739a343c01c969231dbe21680e13a5d1a5bf0 \ + --hash=sha256:929142361a48ee07f09121fe9e96a84950e8d4df3bb298ca5d88061969f34d7b \ + --hash=sha256:93f107c673bccf0d592cdba077dedaf52fe7f42dcd7676eba1f6d6f0c3efffd2 \ + --hash=sha256:97460eec202017f719e839a0d3551fbc0b2fcc9c6c6ffaa5af85bbd5de432788 \ + --hash=sha256:9b3222c686a919a0f3253cfc12bb118b8b103506612253b5baeaac10d8027cf6 \ + --hash=sha256:9e040d3e762f84500961791fa3709ffa4784d4dcd7690afc655c095e02fff05f \ + --hash=sha256:a034590a727b44dd8ac5914236a7b8504144447a9682586c3327e935f33ec8cc \ + --hash=sha256:a40a3d35b204b7cc7643cbcf8c9976d818cb47befcfac8bbefec8038ac363f3e \ + --hash=sha256:a42e633d75cdad6d625434e3468126c73f13f7584545a9cf34e883aa1710e702 \ + --hash=sha256:a54844be970d3fc22630b32d515e79a90d0a3ddb2644d8d7402e3c4c8da61405 \ + --hash=sha256:a756fe893389483ee8c394d06b5ab765d96e68fbbfe6fde7aa17e11f5720559f \ + --hash=sha256:a75ffc1bd5def584129774c158e108e5d768e10b75813f2b32650bb041066ed6 \ + --hash=sha256:a87f271a33fad0e5bf3be282be55d78df3a45ae457950deb5241998790326f87 \ + --hash=sha256:a881851cf38b0a70e7c4d3ce81fc7afd86fbc2a024f4cfb2a97cf49ce04b75d3 \ + --hash=sha256:aa912c62f842dfd013c5f21a642c9c10cd9f4c4e943e0af83618b4a404d9091a \ + --hash=sha256:aed058764db109dc9052720da65fafe84873b05eb8b07e5e653597951af57c3b \ + --hash=sha256:af1f3278bd02814d6dedc5dec397993b549d6f16c19379721e5a1d31e132c49b \ + --hash=sha256:b0359391c3dad6de872fefb0cf5b69d55b0655c55ee78b1bb7a568979b2ce96b \ + --hash=sha256:b1e420ef35c503869c4064f4a2f2b08ad6431ab7b229a05cce39d74268bca6b8 \ + --hash=sha256:b45fad44d9c5c119e9c6fbf2e1c656a46dc68e280275007bbfd3d572b21426db \ + --hash=sha256:b465afd7909db30168ab62afe40b2fcf79eedc0b89a6c0ab3123515dc0df8b99 \ + --hash=sha256:b47bbd8cf2d72797f3c2772eaaac0ded3d3af26481a26d7d7d41dc2d3c46b04a \ + --hash=sha256:b5b848ad6c16d308c3ac7ad4ba6bede80ed5df2ba8ed382f8932df63158dd4b2 \ + --hash=sha256:b7b2df81a23f8cb99656378e72501b2cb41b1827c0f5a86f87d6b06b69f9f204 \ + --hash=sha256:b9c6df83594f7df8f7f708ce5ebeacfc69f72c9fbaaababf6cf4758eaada0c9b \ + --hash=sha256:ba284920194615cb8edf73bf52236ce2e1664ccd4a38fdb543506413529cc546 \ + --hash=sha256:bb79b1e63f6fd84ec778a4b1916dfe0a7c3fdb986c06addd5db3a0d413819d95 \ + --hash=sha256:bd17fede52a17a4f9a7bc4472a5867cb0b160deeb431795c0e4abe158bc784e9 \ + --hash=sha256:bec91b562d8012dae276af8025a55811b875baace6af510412a5e58e3121bc54 \ + --hash=sha256:bf48889c9630542d4709192578aebbd836177c9f7a4a2778a7d6340107c65f06 \ + --hash=sha256:c0f2ab8c715630565ab8991b536ecded9416d615538be8ecddce43ccf26cbc7c \ + --hash=sha256:c1ce4009c97a752e682b897aa99aef84191077a9433eb237774689f14f8ec152 \ + --hash=sha256:c2f9ccd5c4be370939a2e17602fbc49995299203da72a3429db013d44d590e86 \ + --hash=sha256:c5294f596a9017ca5a3e3f8884c00b91ab2ad2933cf288f4923c3fd4346cf3d4 \ + --hash=sha256:c5aa639bc113e9286137cec8fadc20e9cd732b2cc385c0b7fa673b84fc1f2a93 \ + --hash=sha256:c6dc31591899f5e5666f04cc2e529e69b4072827085c1ef15294d91a004bc1bd \ + --hash=sha256:c6e193e9f56e4ca4923c61238cdaced324f0feac782544eb4c6d55ad5cc99ddd \ + --hash=sha256:cc604dc06027dbeb8281aeac5899c35fcfe7c77b25212833709f0bff4ce74d2a \ + --hash=sha256:cfbc5b91397c8c2972fdac13fb3e4ed2f7f8ccac85cd2c644887557780a9b6e2 \ + --hash=sha256:d0a9751f71a1a65ce3584e9cae4467651c7e70c9d31017fa57574583a4540248 \ + --hash=sha256:d1927a69feddc24c987b337ce81ac15c4720955b667fe9b588e02254b80446fd \ + --hash=sha256:d597acf8506d6e7101a4a44a5e428977a51c0fadbbfd3c39650cca9253f6e5a6 \ + --hash=sha256:d706dca2d24d834a4661619dcacf51a75c16d65985718d6a7d73c1eeeb903ddf \ + --hash=sha256:d72f67ef8bf36e05f5b6c65e8524f265bd61071471cd4cf1d36743ebeeeb06b7 \ + --hash=sha256:dc94790144e66b14f67b10ac8ed75b39ca47536bf8800eb7c24b50271ea0c490 \ + --hash=sha256:dea26ae1eb293db089798d3973a5fc928a18fdd97cc8801226fae705b02b14b0 \ + --hash=sha256:e4ff728a2894e7f436b9e94c667b0f426b9c74b71f900cf37d5468c6b5da0536 \ + --hash=sha256:e82da5670f2d0d98950317f82a0e4a0197150ff19a6df2ba40399c2a3b9ae5fb \ + --hash=sha256:eae5c13f3bc455a3bbb68bdc513912dc7356de7e2280363ea235f71f54064829 \ + --hash=sha256:ec44b73a4220623235f67a996c862049f375df3b1052d9899f40a6382c32d746 \ + --hash=sha256:ee34327b187f002a596d7b167ebc59a1b729e963ce645964bbc050d2f1b73d07 \ + --hash=sha256:f01375c0e55395b814a679b3eea205db7919ac2af213f4a6682e01220e5fe292 \ + --hash=sha256:f0162a78b13a0d7617b2845b90c763339d1f1d82bb04a4b07f4ab535cc5e05d6 \ + --hash=sha256:f205badabde7aafd1a31e8ca2a3e5a763107a71c397c4481d6a804eb5063d8bd \ + --hash=sha256:f22927652cba98c44639ffdc7aaf35828dccf679b10b31c4ad72a5b530a18eb7 \ + --hash=sha256:f572dfd3d0e2eb1a57511831cf6341242f5a9f8298a45862d085f5b93394a27d \ + --hash=sha256:f7f99123f0e1194fa59cc69ad46dbae2e07becec5df50a0509a808f90a0f03f0 \ + --hash=sha256:fba27a198363a7ef87f8c0f6b171ec36b674fe9053742c58dd7e3201c1ab30ee \ + --hash=sha256:ffc578717a347baf25be8397cb10d2528802d24f94cfc005c0e44fef44b5cdd6 + # via datasets +yarl==1.22.0 \ + --hash=sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a \ + --hash=sha256:029866bde8d7b0878b9c160e72305bbf0a7342bcd20b9999381704ae03308dc8 \ + --hash=sha256:078278b9b0b11568937d9509b589ee83ef98ed6d561dfe2020e24a9fd08eaa2b \ + --hash=sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da \ + --hash=sha256:07a524d84df0c10f41e3ee918846e1974aba4ec017f990dc735aad487a0bdfdf \ + --hash=sha256:088e4e08f033db4be2ccd1f34cf29fe994772fb54cfe004bbf54db320af56890 \ + --hash=sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093 \ + --hash=sha256:0cf71bf877efeac18b38d3930594c0948c82b64547c1cf420ba48722fe5509f6 \ + --hash=sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79 \ + --hash=sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683 \ + --hash=sha256:10619d9fdee46d20edc49d3479e2f8269d0779f1b031e6f7c2aa1c76be04b7ed \ + --hash=sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2 \ + --hash=sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff \ + --hash=sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02 \ + --hash=sha256:14291620375b1060613f4aab9ebf21850058b6b1b438f386cc814813d901c60b \ + --hash=sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03 \ + --hash=sha256:1ab72135b1f2db3fed3997d7e7dc1b80573c67138023852b6efb336a5eae6511 \ + --hash=sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c \ + --hash=sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124 \ + --hash=sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c \ + --hash=sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da \ + --hash=sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2 \ + --hash=sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0 \ + --hash=sha256:2e4e1f6f0b4da23e61188676e3ed027ef0baa833a2e633c29ff8530800edccba \ + --hash=sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d \ + --hash=sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53 \ + --hash=sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138 \ + --hash=sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4 \ + --hash=sha256:3aa27acb6de7a23785d81557577491f6c38a5209a254d1191519d07d8fe51748 \ + --hash=sha256:3b06bcadaac49c70f4c88af4ffcfbe3dc155aab3163e75777818092478bcbbe7 \ + --hash=sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d \ + --hash=sha256:3e2daa88dc91870215961e96a039ec73e4937da13cf77ce17f9cad0c18df3503 \ + --hash=sha256:3ea66b1c11c9150f1372f69afb6b8116f2dd7286f38e14ea71a44eee9ec51b9d \ + --hash=sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2 \ + --hash=sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa \ + --hash=sha256:437840083abe022c978470b942ff832c3940b2ad3734d424b7eaffcd07f76737 \ + --hash=sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f \ + --hash=sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1 \ + --hash=sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d \ + --hash=sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694 \ + --hash=sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3 \ + --hash=sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a \ + --hash=sha256:4c52a6e78aef5cf47a98ef8e934755abf53953379b7d53e68b15ff4420e6683d \ + --hash=sha256:4dcc74149ccc8bba31ce1944acee24813e93cfdee2acda3c172df844948ddf7b \ + --hash=sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a \ + --hash=sha256:51af598701f5299012b8416486b40fceef8c26fc87dc6d7d1f6fc30609ea0aa6 \ + --hash=sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b \ + --hash=sha256:595697f68bd1f0c1c159fcb97b661fc9c3f5db46498043555d04805430e79bea \ + --hash=sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5 \ + --hash=sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f \ + --hash=sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df \ + --hash=sha256:5cdac20da754f3a723cceea5b3448e1a2074866406adeb4ef35b469d089adb8f \ + --hash=sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b \ + --hash=sha256:5dbeefd6ca588b33576a01b0ad58aa934bc1b41ef89dee505bf2932b22ddffba \ + --hash=sha256:62441e55958977b8167b2709c164c91a6363e25da322d87ae6dd9c6019ceecf9 \ + --hash=sha256:663e1cadaddae26be034a6ab6072449a8426ddb03d500f43daf952b74553bba0 \ + --hash=sha256:669930400e375570189492dc8d8341301578e8493aec04aebc20d4717f899dd6 \ + --hash=sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b \ + --hash=sha256:6944b2dc72c4d7f7052683487e3677456050ff77fcf5e6204e98caf785ad1967 \ + --hash=sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2 \ + --hash=sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708 \ + --hash=sha256:6dcbb0829c671f305be48a7227918cfcd11276c2d637a8033a99a02b67bf9eda \ + --hash=sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8 \ + --hash=sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10 \ + --hash=sha256:75976c6945d85dbb9ee6308cd7ff7b1fb9409380c82d6119bd778d8fcfe2931c \ + --hash=sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b \ + --hash=sha256:792a2af6d58177ef7c19cbf0097aba92ca1b9cb3ffdd9c7470e156c8f9b5e028 \ + --hash=sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e \ + --hash=sha256:80ddf7a5f8c86cb3eb4bc9028b07bbbf1f08a96c5c0bc1244be5e8fefcb94147 \ + --hash=sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33 \ + --hash=sha256:84fc3ec96fce86ce5aa305eb4aa9358279d1aa644b71fab7b8ed33fe3ba1a7ca \ + --hash=sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590 \ + --hash=sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c \ + --hash=sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53 \ + --hash=sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74 \ + --hash=sha256:99b6fc1d55782461b78221e95fc357b47ad98b041e8e20f47c1411d0aacddc60 \ + --hash=sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f \ + --hash=sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1 \ + --hash=sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27 \ + --hash=sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520 \ + --hash=sha256:a4fcfc8eb2c34148c118dfa02e6427ca278bfd0f3df7c5f99e33d2c0e81eae3e \ + --hash=sha256:a899cbd98dce6f5d8de1aad31cb712ec0a530abc0a86bd6edaa47c1090138467 \ + --hash=sha256:a9b1ba5610a4e20f655258d5a1fdc7ebe3d837bb0e45b581398b99eb98b1f5ca \ + --hash=sha256:af74f05666a5e531289cb1cc9c883d1de2088b8e5b4de48004e5ca8a830ac859 \ + --hash=sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273 \ + --hash=sha256:b266bd01fedeffeeac01a79ae181719ff848a5a13ce10075adbefc8f1daee70e \ + --hash=sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601 \ + --hash=sha256:b580e71cac3f8113d3135888770903eaf2f507e9421e5697d6ee6d8cd1c7f054 \ + --hash=sha256:b6a6f620cfe13ccec221fa312139135166e47ae169f8253f72a0abc0dae94376 \ + --hash=sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7 \ + --hash=sha256:b85b982afde6df99ecc996990d4ad7ccbdbb70e2a4ba4de0aecde5922ba98a0b \ + --hash=sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb \ + --hash=sha256:ba440ae430c00eee41509353628600212112cd5018d5def7e9b05ea7ac34eb65 \ + --hash=sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784 \ + --hash=sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71 \ + --hash=sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b \ + --hash=sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a \ + --hash=sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c \ + --hash=sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face \ + --hash=sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d \ + --hash=sha256:c7bd6683587567e5a49ee6e336e0612bec8329be1b7d4c8af5687dcdeb67ee1e \ + --hash=sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e \ + --hash=sha256:cb95a9b1adaa48e41815a55ae740cfda005758104049a640a398120bf02515ca \ + --hash=sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9 \ + --hash=sha256:d332fc2e3c94dad927f2112395772a4e4fedbcf8f80efc21ed7cdfae4d574fdb \ + --hash=sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95 \ + --hash=sha256:d5372ca1df0f91a86b047d1277c2aaf1edb32d78bbcefffc81b40ffd18f027ed \ + --hash=sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf \ + --hash=sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca \ + --hash=sha256:dd7afd3f8b0bfb4e0d9fc3c31bfe8a4ec7debe124cfd90619305def3c8ca8cd2 \ + --hash=sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62 \ + --hash=sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df \ + --hash=sha256:e1b329cb8146d7b736677a2440e422eadd775d1806a81db2d4cded80a48efc1a \ + --hash=sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67 \ + --hash=sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f \ + --hash=sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529 \ + --hash=sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486 \ + --hash=sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a \ + --hash=sha256:e6438cc8f23a9c1478633d216b16104a586b9761db62bfacb6425bac0a36679e \ + --hash=sha256:e81fda2fb4a07eda1a2252b216aa0df23ebcd4d584894e9612e80999a78fd95b \ + --hash=sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74 \ + --hash=sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d \ + --hash=sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b \ + --hash=sha256:f0d97c18dfd9a9af4490631905a3f131a8e4c9e80a39353919e2cfed8f00aedc \ + --hash=sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2 \ + --hash=sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e \ + --hash=sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8 \ + --hash=sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82 \ + --hash=sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd \ + --hash=sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249 + # via aiohttp +zipp==3.23.0 \ + --hash=sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e \ + --hash=sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166 + # via importlib-metadata +zstandard==0.25.0 \ + --hash=sha256:011d388c76b11a0c165374ce660ce2c8efa8e5d87f34996aa80f9c0816698b64 \ + --hash=sha256:01582723b3ccd6939ab7b3a78622c573799d5d8737b534b86d0e06ac18dbde4a \ + --hash=sha256:05353cef599a7b0b98baca9b068dd36810c3ef0f42bf282583f438caf6ddcee3 \ + --hash=sha256:05df5136bc5a011f33cd25bc9f506e7426c0c9b3f9954f056831ce68f3b6689f \ + --hash=sha256:06acb75eebeedb77b69048031282737717a63e71e4ae3f77cc0c3b9508320df6 \ + --hash=sha256:07b527a69c1e1c8b5ab1ab14e2afe0675614a09182213f21a0717b62027b5936 \ + --hash=sha256:0bbc9a0c65ce0eea3c34a691e3c4b6889f5f3909ba4822ab385fab9057099431 \ + --hash=sha256:0be7622c37c183406f3dbf0cba104118eb16a4ea7359eeb5752f0794882fc250 \ + --hash=sha256:106281ae350e494f4ac8a80470e66d1fe27e497052c8d9c3b95dc4cf1ade81aa \ + --hash=sha256:10ef2a79ab8e2974e2075fb984e5b9806c64134810fac21576f0668e7ea19f8f \ + --hash=sha256:1673b7199bbe763365b81a4f3252b8e80f44c9e323fc42940dc8843bfeaf9851 \ + --hash=sha256:172de1f06947577d3a3005416977cce6168f2261284c02080e7ad0185faeced3 \ + --hash=sha256:181eb40e0b6a29b3cd2849f825e0fa34397f649170673d385f3598ae17cca2e9 \ + --hash=sha256:1869da9571d5e94a85a5e8d57e4e8807b175c9e4a6294e3b66fa4efb074d90f6 \ + --hash=sha256:19796b39075201d51d5f5f790bf849221e58b48a39a5fc74837675d8bafc7362 \ + --hash=sha256:1cd5da4d8e8ee0e88be976c294db744773459d51bb32f707a0f166e5ad5c8649 \ + --hash=sha256:1f3689581a72eaba9131b1d9bdbfe520ccd169999219b41000ede2fca5c1bfdb \ + --hash=sha256:1f830a0dac88719af0ae43b8b2d6aef487d437036468ef3c2ea59c51f9d55fd5 \ + --hash=sha256:223415140608d0f0da010499eaa8ccdb9af210a543fac54bce15babbcfc78439 \ + --hash=sha256:22a06c5df3751bb7dc67406f5374734ccee8ed37fc5981bf1ad7041831fa1137 \ + --hash=sha256:22a086cff1b6ceca18a8dd6096ec631e430e93a8e70a9ca5efa7561a00f826fa \ + --hash=sha256:23ebc8f17a03133b4426bcc04aabd68f8236eb78c3760f12783385171b0fd8bd \ + --hash=sha256:25f8f3cd45087d089aef5ba3848cd9efe3ad41163d3400862fb42f81a3a46701 \ + --hash=sha256:2b6bd67528ee8b5c5f10255735abc21aa106931f0dbaf297c7be0c886353c3d0 \ + --hash=sha256:2e54296a283f3ab5a26fc9b8b5d4978ea0532f37b231644f367aa588930aa043 \ + --hash=sha256:3756b3e9da9b83da1796f8809dd57cb024f838b9eeafde28f3cb472012797ac1 \ + --hash=sha256:37daddd452c0ffb65da00620afb8e17abd4adaae6ce6310702841760c2c26860 \ + --hash=sha256:3a39c94ad7866160a4a46d772e43311a743c316942037671beb264e395bdd611 \ + --hash=sha256:3b870ce5a02d4b22286cf4944c628e0f0881b11b3f14667c1d62185a99e04f53 \ + --hash=sha256:3c83b0188c852a47cd13ef3bf9209fb0a77fa5374958b8c53aaa699398c6bd7b \ + --hash=sha256:4203ce3b31aec23012d3a4cf4a2ed64d12fea5269c49aed5e4c3611b938e4088 \ + --hash=sha256:457ed498fc58cdc12fc48f7950e02740d4f7ae9493dd4ab2168a47c93c31298e \ + --hash=sha256:474d2596a2dbc241a556e965fb76002c1ce655445e4e3bf38e5477d413165ffa \ + --hash=sha256:4b14abacf83dfb5c25eb4e4a79520de9e7e205f72c9ee7702f91233ae57d33a2 \ + --hash=sha256:4b6d83057e713ff235a12e73916b6d356e3084fd3d14ced499d84240f3eecee0 \ + --hash=sha256:4d441506e9b372386a5271c64125f72d5df6d2a8e8a2a45a0ae09b03cb781ef7 \ + --hash=sha256:4f187a0bb61b35119d1926aee039524d1f93aaf38a9916b8c4b78ac8514a0aaf \ + --hash=sha256:51526324f1b23229001eb3735bc8c94f9c578b1bd9e867a0a646a3b17109f388 \ + --hash=sha256:53e08b2445a6bc241261fea89d065536f00a581f02535f8122eba42db9375530 \ + --hash=sha256:53f94448fe5b10ee75d246497168e5825135d54325458c4bfffbaafabcc0a577 \ + --hash=sha256:5a56ba0db2d244117ed744dfa8f6f5b366e14148e00de44723413b2f3938a902 \ + --hash=sha256:5f1ad7bf88535edcf30038f6919abe087f606f62c00a87d7e33e7fc57cb69fcc \ + --hash=sha256:5f5e4c2a23ca271c218ac025bd7d635597048b366d6f31f420aaeb715239fc98 \ + --hash=sha256:6a573a35693e03cf1d67799fd01b50ff578515a8aeadd4595d2a7fa9f3ec002a \ + --hash=sha256:6c0e5a65158a7946e7a7affa6418878ef97ab66636f13353b8502d7ea03c8097 \ + --hash=sha256:6dffecc361d079bb48d7caef5d673c88c8988d3d33fb74ab95b7ee6da42652ea \ + --hash=sha256:7030defa83eef3e51ff26f0b7bfb229f0204b66fe18e04359ce3474ac33cbc09 \ + --hash=sha256:7149623bba7fdf7e7f24312953bcf73cae103db8cae49f8154dd1eadc8a29ecb \ + --hash=sha256:72d35d7aa0bba323965da807a462b0966c91608ef3a48ba761678cb20ce5d8b7 \ + --hash=sha256:75ffc32a569fb049499e63ce68c743155477610532da1eb38e7f24bf7cd29e74 \ + --hash=sha256:7713e1179d162cf5c7906da876ec2ccb9c3a9dcbdffef0cc7f70c3667a205f0b \ + --hash=sha256:78228d8a6a1c177a96b94f7e2e8d012c55f9c760761980da16ae7546a15a8e9b \ + --hash=sha256:7b3c3a3ab9daa3eed242d6ecceead93aebbb8f5f84318d82cee643e019c4b73b \ + --hash=sha256:809c5bcb2c67cd0ed81e9229d227d4ca28f82d0f778fc5fea624a9def3963f91 \ + --hash=sha256:81dad8d145d8fd981b2962b686b2241d3a1ea07733e76a2f15435dfb7fb60150 \ + --hash=sha256:85304a43f4d513f5464ceb938aa02c1e78c2943b29f44a750b48b25ac999a049 \ + --hash=sha256:89c4b48479a43f820b749df49cd7ba2dbc2b1b78560ecb5ab52985574fd40b27 \ + --hash=sha256:8e735494da3db08694d26480f1493ad2cf86e99bdd53e8e9771b2752a5c0246a \ + --hash=sha256:913cbd31a400febff93b564a23e17c3ed2d56c064006f54efec210d586171c00 \ + --hash=sha256:9174f4ed06f790a6869b41cba05b43eeb9a35f8993c4422ab853b705e8112bbd \ + --hash=sha256:9300d02ea7c6506f00e627e287e0492a5eb0371ec1670ae852fefffa6164b072 \ + --hash=sha256:933b65d7680ea337180733cf9e87293cc5500cc0eb3fc8769f4d3c88d724ec5c \ + --hash=sha256:9654dbc012d8b06fc3d19cc825af3f7bf8ae242226df5f83936cb39f5fdc846c \ + --hash=sha256:98750a309eb2f020da61e727de7d7ba3c57c97cf6213f6f6277bb7fb42a8e065 \ + --hash=sha256:99c0c846e6e61718715a3c9437ccc625de26593fea60189567f0118dc9db7512 \ + --hash=sha256:a1a4ae2dec3993a32247995bdfe367fc3266da832d82f8438c8570f989753de1 \ + --hash=sha256:a3f79487c687b1fc69f19e487cd949bf3aae653d181dfb5fde3bf6d18894706f \ + --hash=sha256:a4089a10e598eae6393756b036e0f419e8c1d60f44a831520f9af41c14216cf2 \ + --hash=sha256:a51ff14f8017338e2f2e5dab738ce1ec3b5a851f23b18c1ae1359b1eecbee6df \ + --hash=sha256:a5a419712cf88862a45a23def0ae063686db3d324cec7edbe40509d1a79a0aab \ + --hash=sha256:a9ec8c642d1ec73287ae3e726792dd86c96f5681eb8df274a757bf62b750eae7 \ + --hash=sha256:aaf21ba8fb76d102b696781bddaa0954b782536446083ae3fdaa6f16b25a1c4b \ + --hash=sha256:ab85470ab54c2cb96e176f40342d9ed41e58ca5733be6a893b730e7af9c40550 \ + --hash=sha256:b9af1fe743828123e12b41dd8091eca1074d0c1569cc42e6e1eee98027f2bbd0 \ + --hash=sha256:bfc4e20784722098822e3eee42b8e576b379ed72cca4a7cb856ae733e62192ea \ + --hash=sha256:bfd06b1c5584b657a2892a6014c2f4c20e0db0208c159148fa78c65f7e0b0277 \ + --hash=sha256:c19bcdd826e95671065f8692b5a4aa95c52dc7a02a4c5a0cac46deb879a017a2 \ + --hash=sha256:c2ba942c94e0691467ab901fc51b6f2085ff48f2eea77b1a48240f011e8247c7 \ + --hash=sha256:c8e167d5adf59476fa3e37bee730890e389410c354771a62e3c076c86f9f7778 \ + --hash=sha256:ca54090275939dc8ec5dea2d2afb400e0f83444b2fc24e07df7fdef677110859 \ + --hash=sha256:d7541afd73985c630bafcd6338d2518ae96060075f9463d7dc14cfb33514383d \ + --hash=sha256:d8c56bb4e6c795fc77d74d8e8b80846e1fb8292fc0b5060cd8131d522974b751 \ + --hash=sha256:da469dc041701583e34de852d8634703550348d5822e66a0c827d39b05365b12 \ + --hash=sha256:daab68faadb847063d0c56f361a289c4f268706b598afbf9ad113cbe5c38b6b2 \ + --hash=sha256:e05ab82ea7753354bb054b92e2f288afb750e6b439ff6ca78af52939ebbc476d \ + --hash=sha256:e09bb6252b6476d8d56100e8147b803befa9a12cea144bbe629dd508800d1ad0 \ + --hash=sha256:e29f0cf06974c899b2c188ef7f783607dbef36da4c242eb6c82dcd8b512855e3 \ + --hash=sha256:e59fdc271772f6686e01e1b3b74537259800f57e24280be3f29c8a0deb1904dd \ + --hash=sha256:e7360eae90809efd19b886e59a09dad07da4ca9ba096752e61a2e03c8aca188e \ + --hash=sha256:e96594a5537722fdfb79951672a2a63aec5ebfb823e7560586f7484819f2a08f \ + --hash=sha256:ea9d54cc3d8064260114a0bbf3479fc4a98b21dffc89b3459edd506b69262f6e \ + --hash=sha256:ec996f12524f88e151c339688c3897194821d7f03081ab35d31d1e12ec975e94 \ + --hash=sha256:f27662e4f7dbf9f9c12391cb37b4c4c3cb90ffbd3b1fb9284dadbbb8935fa708 \ + --hash=sha256:f373da2c1757bb7f1acaf09369cdc1d51d84131e50d5fa9863982fd626466313 \ + --hash=sha256:f5aeea11ded7320a84dcdd62a3d95b5186834224a9e55b92ccae35d21a8b63d4 \ + --hash=sha256:f604efd28f239cc21b3adb53eb061e2a205dc164be408e553b41ba2ffe0ca15c \ + --hash=sha256:f67e8f1a324a900e75b5e28ffb152bcac9fbed1cc7b43f99cd90f395c4375344 \ + --hash=sha256:fd7a5004eb1980d3cefe26b2685bcb0b17989901a70a1040d1ac86f1d898c551 \ + --hash=sha256:ffef5a74088f1e09947aecf91011136665152e0b4b359c42be3373897fb39b01 + # via + # clickhouse-connect + # trino diff --git a/sdk/python/tests/unit/online_store/test_online_writes.py b/sdk/python/tests/unit/online_store/test_online_writes.py index 8e67d9a1a30..52ac3885f1a 100644 --- a/sdk/python/tests/unit/online_store/test_online_writes.py +++ b/sdk/python/tests/unit/online_store/test_online_writes.py @@ -33,6 +33,9 @@ ) from feast.driver_test_data import create_driver_hourly_stats_df from feast.field import Field +from feast.infra.online_stores.mongodb_online_store.mongodb_openai import ( + MongoDBOnlineStoreConfig, +) from feast.infra.online_stores.sqlite import SqliteOnlineStoreConfig from feast.on_demand_feature_view import on_demand_feature_view from feast.types import Array, Float32, Float64, Int64, PdfBytes, String, ValueType @@ -48,9 +51,9 @@ def setUp(self): registry=os.path.join(data_dir, "registry.db"), provider="local", entity_key_serialization_version=3, - online_store=SqliteOnlineStoreConfig( - path=os.path.join(data_dir, "online.db") - ), + # online_store=SqliteOnlineStoreConfig(path=os.path.join(data_dir, "online.db")), + # TODO Try this with MongoDBOnlineStoreConfig defaults + online_store = MongoDBOnlineStoreConfig() ) ) From a066a99d6201486fb3539be0b57635d95d3534b4 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Fri, 13 Feb 2026 15:34:05 -0500 Subject: [PATCH 04/47] Handle Nan in dfs for test_online_writes.py. Now all tests in the module pass Signed-off-by: Casey Clements --- .../infra/online_stores/mongodb_online_store/mongodb_openai.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_openai.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_openai.py index 75581ac4bd3..58aa8d39abb 100644 --- a/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_openai.py +++ b/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_openai.py @@ -344,6 +344,8 @@ def value_proto_to_python(val: ValueProto): """Utility to convert Value proto to plain form saved in MongoDB.""" try: # hasattr(val, "val"): typ = val.WhichOneof("val") + if typ is None: + return None val = getattr(val, typ) if isinstance(val, datetime): val = val.replace(tzinfo=datetime.UTC) From 7c17759863fe60a7e958d1be07be1524f8d45f7e Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Fri, 13 Feb 2026 15:58:57 -0500 Subject: [PATCH 05/47] Removed suffix of implementation: mongodb_openai -> mongodb Signed-off-by: Casey Clements --- .../mongodb_online_store/{mongodb_openai.py => mongodb.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename sdk/python/feast/infra/online_stores/mongodb_online_store/{mongodb_openai.py => mongodb.py} (100%) diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_openai.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py similarity index 100% rename from sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_openai.py rename to sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py From c463f4a1c7a6865abe6d60ec1a08eca79b41e37d Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Wed, 18 Feb 2026 21:13:32 -0500 Subject: [PATCH 06/47] Moved MongoDBOnlineStore to feast.infra.online_store.contrib Signed-off-by: Casey Clements --- .../infra/online_stores/contrib/__init__.py | 0 .../contrib/mongodb_online_store/__init__.py | 3 + .../mongodb_online_store/mongodb.py | 105 +-- .../tests/test_online_retrieval.py | 495 ++++++++++++++ .../tests/test_online_writes.py | 632 ++++++++++++++++++ .../mongodb_online_store/__init__.py | 1 - .../docs/point_in_time.md | 255 ------- .../mongodb_online_store/mongodb_claude.py | 506 -------------- .../mongodb_online_store/tests/__init__.py | 1 - .../tests/test_mongodb_online.py | 630 ----------------- .../utils/mongodb/test_connection_utils.py | 240 ------- sdk/python/feast/repo_config.py | 3 +- sdk/python/tests/utils/cli_repo_creator.py | 13 + 13 files changed, 1163 insertions(+), 1721 deletions(-) create mode 100644 sdk/python/feast/infra/online_stores/contrib/__init__.py create mode 100644 sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/__init__.py rename sdk/python/feast/infra/online_stores/{ => contrib}/mongodb_online_store/mongodb.py (77%) create mode 100644 sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py create mode 100644 sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py delete mode 100644 sdk/python/feast/infra/online_stores/mongodb_online_store/__init__.py delete mode 100644 sdk/python/feast/infra/online_stores/mongodb_online_store/docs/point_in_time.md delete mode 100644 sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_claude.py delete mode 100644 sdk/python/feast/infra/online_stores/mongodb_online_store/tests/__init__.py delete mode 100644 sdk/python/feast/infra/online_stores/mongodb_online_store/tests/test_mongodb_online.py delete mode 100644 sdk/python/feast/infra/utils/mongodb/test_connection_utils.py diff --git a/sdk/python/feast/infra/online_stores/contrib/__init__.py b/sdk/python/feast/infra/online_stores/contrib/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/__init__.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/__init__.py new file mode 100644 index 00000000000..52d2c11f159 --- /dev/null +++ b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/__init__.py @@ -0,0 +1,3 @@ +from .mongodb import MongoDBOnlineStore, MongoDBOnlineStoreConfig + +__all__ = ["MongoDBOnlineStore", "MongoDBOnlineStoreConfig"] \ No newline at end of file diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py similarity index 77% rename from sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py rename to sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py index 58aa8d39abb..4dda67fb36b 100644 --- a/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py +++ b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py @@ -14,7 +14,8 @@ 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.type_map import python_values_to_proto_values +from feast.type_map import python_values_to_proto_values, feast_value_type_to_python_type + logger = logging.getLogger(__name__) @@ -30,16 +31,11 @@ class MongoDBOnlineStoreConfig(FeastConfigBaseModel): ] = "mongodb" """Online store type selector""" connection_string: str = "mongodb://localhost:27017" - database_name: str = "project" # todo - consider changing to project_name? - collection_suffix: str = "features_latest" + database_name: str = "features" # todo - consider removing, and using repo_config.project + collection_suffix: str = "latest" client_kwargs: Dict[str, Any] = {} -def _store_name(project_name: str, collection_suffix: str) -> str: - """OnlineStore Collection's full name.""" - return f"{project_name}_{collection_suffix}" - - class MongoDBOnlineStore(OnlineStore): """ MongoDB implementation of Feast OnlineStore. @@ -72,10 +68,6 @@ class MongoDBOnlineStore(OnlineStore): _client: Optional[MongoClient] = None _collection: Optional[Collection] = None - # ------------------------------------------------------------------ - # Lifecycle - # ------------------------------------------------------------------ - def online_write_batch( self, config: RepoConfig, @@ -101,7 +93,7 @@ def online_write_batch( entity_key, proto_values, event_timestamp, created_timestamp = row entity_id = serialize_entity_key(entity_key) feature_updates = { - f"features.{table.name}.{field}": value_proto_to_python(val) + f"features.{table.name}.{field}": feast_value_type_to_python_type(val) for field, val in proto_values.items() } update = { @@ -123,8 +115,6 @@ def online_write_batch( if progress: progress(1) - # ------------------------------------------------------------------ - def online_read( self, config: RepoConfig, @@ -275,7 +265,7 @@ def update( The Entities are serialized in the _id. No schema needs be adjusted. """ if config.online_store.type != "mongodb": - raise RuntimeError("config.online_store.type must be mongodb. Found ", config.online_store.type) + raise RuntimeError(f"{config.online_store.type = }. It must be mongodb.") clxn = self._get_collection(repo_config=config) @@ -296,43 +286,42 @@ def update( def teardown( self, - config: RepoConfig, # TODO - Need to resolve configs (Repo and Store) + config: RepoConfig, tables: Sequence[FeatureView], entities: Sequence[Entity], ): """ - Tear down MongoDB resources (drop collections). + Drop the backing collection and close the client. - Args: - config: Feast repository configuration - tables: Feature views whose collections should be dropped - entities: Entities (unused for MongoDB) + As in update, MongoDB requires very little here. """ assert config.online_store.type == "mongodb" - online_config: MongoDBOnlineStoreConfig = config.online_store - clxn = self._get_collection(repo_config=config) clxn.drop() - self._get_client(config) - client = MongoClient(config.online_store.uri) - client.close() + self._get_client(config).close() + # ------------------------------------------------------------------ # Helpers # ------------------------------------------------------------------ - def _get_client(self, online_config: MongoDBOnlineStoreConfig): + def _get_client(self, config: RepoConfig): """Returns a connection to the server.""" + online_store_config = config.online_store + if not isinstance(online_store_config, MongoDBOnlineStoreConfig): + raise ValueError(f"config.online_store should be MongoDBOnlineStoreConfig, got {online_store_config}") if self._client is None: - assert isinstance(online_config, MongoDBOnlineStoreConfig) + online_config = config.online_store + if not isinstance(online_config, MongoDBOnlineStoreConfig): + logger.warning(f"config.online_store passed to _get_client is not a MongoDBOnlineStoreConfig. It's of type {type(online_config)}") self._client = MongoClient(online_config.connection_string, **online_config.client_kwargs) return self._client def _get_collection(self, repo_config: RepoConfig) -> Collection: """Returns a connection to the online store collection.""" if self._collection is None: + self._client = self._get_client(repo_config) online_config = repo_config.online_store - self._client = self._get_client(online_config) db = self._client[online_config.database_name] clxn_name = f"{repo_config.project}_{online_config.collection_suffix}" if clxn_name not in db.list_collection_names(): @@ -340,61 +329,5 @@ def _get_collection(self, repo_config: RepoConfig) -> Collection: self._collection = db[clxn_name] return self._collection -def value_proto_to_python(val: ValueProto): - """Utility to convert Value proto to plain form saved in MongoDB.""" - try: # hasattr(val, "val"): - typ = val.WhichOneof("val") - if typ is None: - return None - val = getattr(val, typ) - if isinstance(val, datetime): - val = val.replace(tzinfo=datetime.UTC) - return val - except: - raise ValueError(f"Unsupported ValueProto: {val}") - - -def value_proto_to_python_deprecated(val: ValueProto): - """Utility to convert Value proto to plain form saved in MongoDB.""" - # TODO - # - Check timestamp implementation - - val = val.WhichOneof("val") - if val == "int32_val": - return val.int32_val - if val == "float_int64_val": - return val.int32_list_val - if val == "int64_val": - return val.int64_val - if val == "int64_list_val": - return val.int64_list_val - if val == "float_val": - return val.float_val - if val == "float_list_val": - return val.float_list_val - if val == "double_val": - return val.double_val - if val == "double_list_val": - return val.double_list_val - if val == "bool_val": - return val.bool_val - if val == "bool_list_val": - return val.bool_list_val - if val == "string_val": - return val.string_val - if val == "bytes_val": - return val.bytes_val - if val == "timestamp_val": - return datetime.fromtimestamp( - val.timestamp_val.seconds + val.timestamp_val.nanos / 1e9, - tz=datetime.timezone.utc, - ) - if val == "null_val": - return None - - raise ValueError(f"Unsupported ValueProto val: {val}") - - - # TODO # - Implement async API diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py new file mode 100644 index 00000000000..b481263ae7d --- /dev/null +++ b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py @@ -0,0 +1,495 @@ +import os +import platform +import random +import sqlite3 +import sys +import time +from typing import Any + +import numpy as np +import pandas as pd +import pytest +import sqlite_vec +from pandas.testing import assert_frame_equal + +from feast import FeatureStore, RepoConfig +from feast.errors import FeatureViewNotFoundException +from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto +from feast.protos.feast.types.Value_pb2 import FloatList as FloatListProto +from feast.protos.feast.types.Value_pb2 import Value as ValueProto +from feast.repo_config import RegistryConfig +from feast.torch_wrapper import get_torch +from feast.types import ValueType +from feast.utils import _utc_now +from tests.integration.feature_repos.universal.feature_views import TAGS +from tests.utils.cli_repo_creator import CliRunner, get_example_repo + + +def test_get_online_features() -> None: + """ + Test reading from the online store in local mode. + """ + runner = CliRunner() + with runner.local_repo( + example_repo_py=get_example_repo("example_feature_repo_1.py"), + offline_store="file", + online_store="mongodb", + apply=True, + teardown=True + ) as store: + # Write some data to two tables + driver_locations_fv = store.get_feature_view(name="driver_locations") + customer_profile_fv = store.get_feature_view(name="customer_profile") + customer_driver_combined_fv = store.get_feature_view( + name="customer_driver_combined" + ) + + provider = store._get_provider() + + driver_key = EntityKeyProto( + join_keys=["driver_id"], entity_values=[ValueProto(int64_val=1)] + ) + provider.online_write_batch( + config=store.config, + table=driver_locations_fv, + data=[ + ( + driver_key, + { + "lat": ValueProto(double_val=0.1), + "lon": ValueProto(string_val="1.0"), + }, + _utc_now(), + _utc_now(), + ) + ], + progress=None, + ) + + customer_key = EntityKeyProto( + join_keys=["customer_id"], entity_values=[ValueProto(string_val="5")] + ) + provider.online_write_batch( + config=store.config, + table=customer_profile_fv, + data=[ + ( + customer_key, + { + "avg_orders_day": ValueProto(float_val=1.0), + "name": ValueProto(string_val="John"), + "age": ValueProto(int64_val=3), + }, + _utc_now(), + _utc_now(), + ) + ], + progress=None, + ) + + customer_key = EntityKeyProto( + join_keys=["customer_id", "driver_id"], + entity_values=[ValueProto(string_val="5"), ValueProto(int64_val=1)], + ) + provider.online_write_batch( + config=store.config, + table=customer_driver_combined_fv, + data=[ + ( + customer_key, + {"trips": ValueProto(int64_val=7)}, + _utc_now(), + _utc_now(), + ) + ], + progress=None, + ) + + assert len(store.list_entities()) == 3 + assert len(store.list_entities(tags=TAGS)) == 2 + + # Retrieve two features using two keys, one valid one non-existing + result = store.get_online_features( + features=[ + "driver_locations:lon", + "customer_profile:avg_orders_day", + "customer_profile:name", + "customer_driver_combined:trips", + ], + entity_rows=[ + {"driver_id": 1, "customer_id": "5"}, + {"driver_id": 1, "customer_id": 5}, + ], + full_feature_names=False, + ).to_dict() + + assert "lon" in result + assert "avg_orders_day" in result + assert "name" in result + assert result["driver_id"] == [1, 1] + assert result["customer_id"] == ["5", "5"] + assert result["lon"] == ["1.0", "1.0"] + assert result["avg_orders_day"] == [1.0, 1.0] + assert result["name"] == ["John", "John"] + assert result["trips"] == [7, 7] + + tensor_result = store.get_online_features( + features=[ + "driver_locations:lon", + "customer_profile:avg_orders_day", + "customer_profile:name", + "customer_driver_combined:trips", + ], + entity_rows=[ + {"driver_id": 1, "customer_id": "5"}, + {"driver_id": 1, "customer_id": 5}, + ], + full_feature_names=False, + ).to_tensor() + + assert "lon" in tensor_result + assert "avg_orders_day" in tensor_result + assert "name" in tensor_result + assert "trips" in tensor_result + # Entity values + torch = get_torch() + device = "cuda" if torch.cuda.is_available() else "cpu" + assert torch.equal( + tensor_result["driver_id"], torch.tensor([1, 1], device=device) + ) + assert tensor_result["customer_id"] == ["5", "5"] + + # Feature values + assert tensor_result["lon"] == ["1.0", "1.0"] # String -> not tensor + assert torch.equal(tensor_result["avg_orders_day"], torch.tensor([1.0, 1.0])) + assert tensor_result["name"] == ["John", "John"] + assert torch.equal(tensor_result["trips"], torch.tensor([7, 7], device=device)) + + # Ensure features are still in result when keys not found + result = store.get_online_features( + features=["customer_driver_combined:trips"], + entity_rows=[{"driver_id": 0, "customer_id": 0}], + full_feature_names=False, + ).to_dict() + + assert "trips" in result + + result = store.get_online_features( + features=["customer_driver_combined:trips"], + entity_rows=[{"driver_id": 0, "customer_id": 0}], + full_feature_names=False, + ).to_tensor() + + assert "trips" in result + assert isinstance(result["trips"], torch.Tensor) + + with pytest.raises(KeyError) as excinfo: + _ = store.get_online_features( + features=["driver_locations:lon"], + entity_rows=[{"customer_id": 0}], + full_feature_names=False, + ).to_dict() + + error_message = str(excinfo.value) + assert "Missing join key values for keys:" in error_message + assert ( + "Missing join key values for keys: ['customer_id', 'driver_id', 'item_id']." + in error_message + ) + assert "Provided join_key_values: ['customer_id']" in error_message + + result = store.get_online_features( + features=["customer_profile_pandas_odfv:on_demand_age"], + entity_rows=[{"driver_id": 1, "customer_id": "5"}], + full_feature_names=False, + ).to_dict() + + assert "on_demand_age" in result + assert result["driver_id"] == [1] + assert result["customer_id"] == ["5"] + assert result["on_demand_age"] == [4] + + # invalid table reference + with pytest.raises(FeatureViewNotFoundException): + store.get_online_features( + features=["driver_locations_bad:lon"], + entity_rows=[{"driver_id": 1}], + full_feature_names=False, + ) + + # Create new FeatureStore object with fast cache invalidation + cache_ttl = 1 + fs_fast_ttl = FeatureStore( + config=RepoConfig( + registry=RegistryConfig( + path=store.config.registry.path, cache_ttl_seconds=cache_ttl + ), + online_store=store.config.online_store, + project=store.project, + provider=store.config.provider, + entity_key_serialization_version=3, + ) + ) + + # Should download the registry and cache it permanently (or until manually refreshed) + result = fs_fast_ttl.get_online_features( + features=[ + "driver_locations:lon", + "customer_profile:avg_orders_day", + "customer_profile:name", + "customer_driver_combined:trips", + ], + entity_rows=[{"driver_id": 1, "customer_id": 5}], + full_feature_names=False, + ).to_dict() + assert result["lon"] == ["1.0"] + assert result["trips"] == [7] + + # Rename the registry.db so that it cant be used for refreshes + os.rename(store.config.registry.path, store.config.registry.path + "_fake") + + # Wait for registry to expire + time.sleep(cache_ttl) + + # Will try to reload registry because it has expired (it will fail because we deleted the actual registry file) + with pytest.raises(FileNotFoundError): + fs_fast_ttl.get_online_features( + features=[ + "driver_locations:lon", + "customer_profile:avg_orders_day", + "customer_profile:name", + "customer_driver_combined:trips", + ], + entity_rows=[{"driver_id": 1, "customer_id": 5}], + full_feature_names=False, + ).to_dict() + + # Restore registry.db so that we can see if it actually reloads registry + os.rename(store.config.registry.path + "_fake", store.config.registry.path) + + # Test if registry is actually reloaded and whether results return + result = fs_fast_ttl.get_online_features( + features=[ + "driver_locations:lon", + "customer_profile:avg_orders_day", + "customer_profile:name", + "customer_driver_combined:trips", + ], + entity_rows=[{"driver_id": 1, "customer_id": 5}], + full_feature_names=False, + ).to_dict() + assert result["lon"] == ["1.0"] + assert result["trips"] == [7] + + # Create a registry with infinite cache (for users that want to manually refresh the registry) + fs_infinite_ttl = FeatureStore( + config=RepoConfig( + registry=RegistryConfig( + path=store.config.registry.path, cache_ttl_seconds=0 + ), + online_store=store.config.online_store, + project=store.project, + provider=store.config.provider, + entity_key_serialization_version=3, + ) + ) + + # Should return results (and fill the registry cache) + result = fs_infinite_ttl.get_online_features( + features=[ + "driver_locations:lon", + "customer_profile:avg_orders_day", + "customer_profile:name", + "customer_driver_combined:trips", + ], + entity_rows=[{"driver_id": 1, "customer_id": 5}], + full_feature_names=False, + ).to_dict() + assert result["lon"] == ["1.0"] + assert result["trips"] == [7] + + # Wait a bit so that an arbitrary TTL would take effect + time.sleep(2) + + # Rename the registry.db so that it cant be used for refreshes + os.rename(store.config.registry.path, store.config.registry.path + "_fake") + + # TTL is infinite so this method should use registry cache + result = fs_infinite_ttl.get_online_features( + features=[ + "driver_locations:lon", + "customer_profile:avg_orders_day", + "customer_profile:name", + "customer_driver_combined:trips", + ], + entity_rows=[{"driver_id": 1, "customer_id": 5}], + full_feature_names=False, + ).to_dict() + assert result["lon"] == ["1.0"] + assert result["trips"] == [7] + + # Force registry reload (should fail because file is missing) + with pytest.raises(FileNotFoundError): + fs_infinite_ttl.refresh_registry() + + # Restore registry.db so that teardown works + os.rename(store.config.registry.path + "_fake", store.config.registry.path) + + +def test_online_to_df(): + """ + Test dataframe conversion. Make sure the response columns and rows are + the same order as the request. + """ + driver_ids = [1, 2, 3] + customer_ids = [4, 5, 6] + name = "foo" + lon_multiply = 1.0 + lat_multiply = 0.1 + age_multiply = 10 + avg_order_day_multiply = 1.0 + + runner = CliRunner() + with runner.local_repo( + example_repo_py=get_example_repo("example_feature_repo_1.py"), + offline_store="file", + online_store="mongodb", + apply=True, + teardown=True + ) as store: + # Write three tables to online store + driver_locations_fv = store.get_feature_view(name="driver_locations") + customer_profile_fv = store.get_feature_view(name="customer_profile") + customer_driver_combined_fv = store.get_feature_view( + name="customer_driver_combined" + ) + provider = store._get_provider() + + for d, c in zip(driver_ids, customer_ids): + """ + driver table: + lon lat + 1 1.0 0.1 + 2 2.0 0.2 + 3 3.0 0.3 + """ + driver_key = EntityKeyProto( + join_keys=["driver_id"], entity_values=[ValueProto(int64_val=d)] + ) + provider.online_write_batch( + config=store.config, + table=driver_locations_fv, + data=[ + ( + driver_key, + { + "lat": ValueProto(double_val=d * lat_multiply), + "lon": ValueProto(string_val=str(d * lon_multiply)), + }, + _utc_now(), + _utc_now(), + ) + ], + progress=None, + ) + + """ + customer table + customer avg_orders_day name age + 4 4.0 foo4 40 + 5 5.0 foo5 50 + 6 6.0 foo6 60 + """ + customer_key = EntityKeyProto( + join_keys=["customer_id"], entity_values=[ValueProto(string_val=str(c))] + ) + provider.online_write_batch( + config=store.config, + table=customer_profile_fv, + data=[ + ( + customer_key, + { + "avg_orders_day": ValueProto( + float_val=c * avg_order_day_multiply + ), + "name": ValueProto(string_val=name + str(c)), + "age": ValueProto(int64_val=c * age_multiply), + }, + _utc_now(), + _utc_now(), + ) + ], + progress=None, + ) + """ + customer_driver_combined table + customer driver trips + 4 1 4 + 5 2 10 + 6 3 18 + """ + combo_keys = EntityKeyProto( + join_keys=["customer_id", "driver_id"], + entity_values=[ValueProto(string_val=str(c)), ValueProto(int64_val=d)], + ) + provider.online_write_batch( + config=store.config, + table=customer_driver_combined_fv, + data=[ + ( + combo_keys, + {"trips": ValueProto(int64_val=c * d)}, + _utc_now(), + _utc_now(), + ) + ], + progress=None, + ) + + # Get online features in dataframe + result_df = store.get_online_features( + features=[ + "driver_locations:lon", + "driver_locations:lat", + "customer_profile:avg_orders_day", + "customer_profile:name", + "customer_profile:age", + "customer_driver_combined:trips", + ], + # Reverse the row order + entity_rows=[ + {"driver_id": d, "customer_id": c} + for (d, c) in zip(reversed(driver_ids), reversed(customer_ids)) + ], + ).to_df() + """ + Construct the expected dataframe with reversed row order like so: + driver customer lon lat avg_orders_day name age trips + 3 6 3.0 0.3 6.0 foo6 60 18 + 2 5 2.0 0.2 5.0 foo5 50 10 + 1 4 1.0 0.1 4.0 foo4 40 4 + """ + df_dict = { + "driver_id": driver_ids, + "customer_id": [str(c) for c in customer_ids], + "lon": [str(d * lon_multiply) for d in driver_ids], + "lat": [d * lat_multiply for d in driver_ids], + "avg_orders_day": [c * avg_order_day_multiply for c in customer_ids], + "name": [name + str(c) for c in customer_ids], + "age": [c * age_multiply for c in customer_ids], + "trips": [d * c for (d, c) in zip(driver_ids, customer_ids)], + } + # Requested column order + ordered_column = [ + "driver_id", + "customer_id", + "lon", + "lat", + "avg_orders_day", + "name", + "age", + "trips", + ] + expected_df = pd.DataFrame({k: reversed(v) for (k, v) in df_dict.items()}) + assert_frame_equal(result_df[ordered_column], expected_df) diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py new file mode 100644 index 00000000000..00120531f98 --- /dev/null +++ b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py @@ -0,0 +1,632 @@ +# Copyright 2022 The Feast Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import asyncio +import os +import shutil +import tempfile +import unittest +from datetime import datetime, timedelta +from typing import Any + +import pandas as pd +import pytest + +from feast import ( + Entity, + FeatureStore, + FeatureView, + FileSource, + RepoConfig, + RequestSource, +) +from feast.driver_test_data import create_driver_hourly_stats_df +from feast.field import Field +from feast.infra.online_stores.contrib.mongodb_online_store.mongodb import ( + MongoDBOnlineStoreConfig, +) +from feast.infra.online_stores.sqlite import SqliteOnlineStoreConfig +from feast.on_demand_feature_view import on_demand_feature_view +from feast.types import Array, Float32, Float64, Int64, PdfBytes, String, ValueType +from tests.utils.test_wrappers import check_warnings + + +class TestOnlineWrites(unittest.TestCase): + def setUp(self): + with tempfile.TemporaryDirectory() as data_dir: + self.store = FeatureStore( + config=RepoConfig( + project="test_write_to_online_store", + registry=os.path.join(data_dir, "registry.db"), + provider="local", + entity_key_serialization_version=3, + # online_store=SqliteOnlineStoreConfig(path=os.path.join(data_dir, "online.db")), + # TODO Try this with MongoDBOnlineStoreConfig defaults + online_store = MongoDBOnlineStoreConfig() + ) + ) + + # Generate test data. + end_date = datetime.now().replace(microsecond=0, second=0, minute=0) + start_date = end_date - timedelta(days=15) + + driver_entities = [1001, 1002, 1003, 1004, 1005] + driver_df = create_driver_hourly_stats_df( + driver_entities, start_date, end_date + ) + driver_stats_path = os.path.join(data_dir, "driver_stats.parquet") + driver_df.to_parquet( + path=driver_stats_path, allow_truncated_timestamps=True + ) + + driver = Entity(name="driver", join_keys=["driver_id"]) + + driver_stats_source = FileSource( + name="driver_hourly_stats_source", + path=driver_stats_path, + timestamp_field="event_timestamp", + created_timestamp_column="created", + ) + + driver_stats_fv = FeatureView( + name="driver_hourly_stats", + entities=[driver], + ttl=timedelta(days=0), + 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, + ) + # Before apply() join_keys is empty + assert driver_stats_fv.join_keys == [] + assert driver_stats_fv.entity_columns == [] + + @on_demand_feature_view( + sources=[driver_stats_fv[["conv_rate", "acc_rate"]]], + schema=[Field(name="conv_rate_plus_acc", dtype=Float64)], + mode="python", + ) + def test_view(inputs: dict[str, Any]) -> dict[str, Any]: + output: dict[str, Any] = { + "conv_rate_plus_acc": [ + conv_rate + acc_rate + for conv_rate, acc_rate in zip( + inputs["conv_rate"], inputs["acc_rate"] + ) + ] + } + return output + + self.store.apply( + [ + driver, + driver_stats_source, + driver_stats_fv, + test_view, + ] + ) + # after apply() join_keys is [driver] + assert driver_stats_fv.join_keys == [driver.join_key] + assert driver_stats_fv.entity_columns[0].name == driver.join_key + + self.store.write_to_online_store( + feature_view_name="driver_hourly_stats", df=driver_df + ) + # This will give the intuitive structure of the data as: + # {"driver_id": [..], "conv_rate": [..], "acc_rate": [..], "avg_daily_trips": [..]} + driver_dict = driver_df.to_dict(orient="list") + self.store.write_to_online_store( + feature_view_name="driver_hourly_stats", + inputs=driver_dict, + ) + + def test_online_retrieval(self): + entity_rows = [ + { + "driver_id": 1001, + } + ] + + online_python_response = self.store.get_online_features( + entity_rows=entity_rows, + features=[ + "driver_hourly_stats:conv_rate", + "driver_hourly_stats:acc_rate", + "test_view:conv_rate_plus_acc", + ], + ).to_dict() + + assert len(online_python_response) == 4 + assert all( + key in online_python_response.keys() + for key in [ + "driver_id", + "acc_rate", + "conv_rate", + "conv_rate_plus_acc", + ] + ) + + +class TestEmptyDataFrameValidation(unittest.TestCase): + def setUp(self): + self.data_dir = tempfile.mkdtemp() + self.store = FeatureStore( + config=RepoConfig( + project="test_empty_df_validation", + registry=os.path.join(self.data_dir, "registry.db"), + provider="local", + entity_key_serialization_version=3, + online_store=MongoDBOnlineStoreConfig() + # online_store=SqliteOnlineStoreConfig(path=os.path.join(self.data_dir, "online.db")), + ) + ) + + # Generate test data for schema creation + end_date = datetime.now().replace(microsecond=0, second=0, minute=0) + start_date = end_date - timedelta(days=1) + + driver_entities = [1001] + driver_df = create_driver_hourly_stats_df(driver_entities, start_date, end_date) + driver_stats_path = os.path.join(self.data_dir, "driver_stats.parquet") + driver_df.to_parquet(path=driver_stats_path, allow_truncated_timestamps=True) + + driver = Entity(name="driver", join_keys=["driver_id"]) + + driver_stats_source = FileSource( + name="driver_hourly_stats_source", + path=driver_stats_path, + timestamp_field="event_timestamp", + created_timestamp_column="created", + ) + + driver_stats_fv = FeatureView( + name="driver_hourly_stats", + entities=[driver], + ttl=timedelta(days=0), + 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, + ) + + self.store.apply([driver, driver_stats_source, driver_stats_fv]) + + def tearDown(self): + shutil.rmtree(self.data_dir) + + @check_warnings( + expected_warnings=["Cannot write empty dataframe to online store"], + ) + def test_empty_dataframe_warns(self): + """Test that completely empty dataframe issues a warning instead of raising an error""" + empty_df = pd.DataFrame() + + self.store.write_to_online_store( + feature_view_name="driver_hourly_stats", df=empty_df + ) + + @check_warnings( + expected_warnings=["Cannot write empty dataframe to online store"], + ) + def test_empty_dataframe_async_warns(self): + """Test that completely empty dataframe issues a warning instead of raising an error in async version""" + + async def test_async_empty(): + empty_df = pd.DataFrame() + + await self.store.write_to_online_store_async( + feature_view_name="driver_hourly_stats", df=empty_df + ) + + asyncio.run(test_async_empty()) + + @check_warnings( + expected_warnings=[ + "Cannot write dataframe with empty feature columns to online store" + ], + ) + def test_dataframe_with_empty_feature_columns_warns(self): + """Test that dataframe with entity data but empty feature columns warns instead of raising error""" + current_time = pd.Timestamp.now() + df_with_entity_only = pd.DataFrame( + { + "driver_id": [1001, 1002, 1003], + "event_timestamp": [current_time] * 3, + "created": [current_time] * 3, + "conv_rate": [None, None, None], # All nulls + "acc_rate": [None, None, None], # All nulls + "avg_daily_trips": [None, None, None], # All nulls + } + ) + + self.store.write_to_online_store( + feature_view_name="driver_hourly_stats", df=df_with_entity_only + ) + + @check_warnings( + expected_warnings=[ + "Cannot write dataframe with empty feature columns to online store" + ], + ) + def test_dataframe_with_empty_feature_columns_async_warns(self): + """Test that dataframe with entity data but empty feature columns warns instead of raising error in async version""" + + async def test_async_empty_features(): + current_time = pd.Timestamp.now() + df_with_entity_only = pd.DataFrame( + { + "driver_id": [1001, 1002, 1003], + "event_timestamp": [current_time] * 3, + "created": [current_time] * 3, + "conv_rate": [None, None, None], + "acc_rate": [None, None, None], + "avg_daily_trips": [None, None, None], + } + ) + + await self.store.write_to_online_store_async( + feature_view_name="driver_hourly_stats", df=df_with_entity_only + ) + + asyncio.run(test_async_empty_features()) + + @check_warnings( + forbidden_warnings=[ + "Cannot write empty dataframe to online store", + "Cannot write dataframe with empty feature columns to online store", + ], + ) + def test_valid_dataframe(self): + """Test that valid dataframe with feature data succeeds""" + current_time = pd.Timestamp.now() + valid_df = pd.DataFrame( + { + "driver_id": [1001, 1002], + "event_timestamp": [current_time] * 2, + "created": [current_time] * 2, + "conv_rate": [0.5, 0.7], + "acc_rate": [0.8, 0.9], + "avg_daily_trips": [10, 12], + } + ) + + # This should not raise an exception or warnings - decorator handles warning validation + self.store.write_to_online_store( + feature_view_name="driver_hourly_stats", df=valid_df + ) + + @check_warnings( + forbidden_warnings=[ + "Cannot write empty dataframe to online store", + "Cannot write dataframe with empty feature columns to online store", + ], + ) + def test_valid_dataframe_async(self): + """Test that valid dataframe with feature data succeeds in async version""" + pytest.skip("Feature not implemented yet") + + async def test_async_valid(): + current_time = pd.Timestamp.now() + valid_df = pd.DataFrame( + { + "driver_id": [1001, 1002], + "event_timestamp": [current_time] * 2, + "created": [current_time] * 2, + "conv_rate": [0.5, 0.7], + "acc_rate": [0.8, 0.9], + "avg_daily_trips": [10, 12], + } + ) + + # This should not raise an exception or warnings - decorator handles warning validation + await self.store.write_to_online_store_async( + feature_view_name="driver_hourly_stats", df=valid_df + ) + + asyncio.run(test_async_valid()) + + @check_warnings( + forbidden_warnings=[ + "Cannot write empty dataframe to online store", + "Cannot write dataframe with empty feature columns to online store", + ], + ) + def test_mixed_dataframe_with_some_valid_features(self): + """Test that dataframe with some valid feature values succeeds""" + current_time = pd.Timestamp.now() + mixed_df = pd.DataFrame( + { + "driver_id": [1001, 1002, 1003], + "event_timestamp": [current_time] * 3, + "created": [current_time] * 3, + "conv_rate": [0.5, None, 0.7], # Mixed values + "acc_rate": [0.8, 0.9, None], # Mixed values # todo What behavior should this have? + "avg_daily_trips": [10, 12, 15], # All valid + } + ) + + # This should not raise an exception because not all feature values are null - decorator handles warning validation + self.store.write_to_online_store( + feature_view_name="driver_hourly_stats", df=mixed_df + ) + + @check_warnings( + expected_warnings=["Cannot write empty dataframe to online store"], + ) + def test_empty_inputs_dict_warns(self): + """Test that empty inputs dict warns instead of raising error""" + empty_inputs = { + "driver_id": [], + "conv_rate": [], + "acc_rate": [], + "avg_daily_trips": [], + } + + self.store.write_to_online_store( + feature_view_name="driver_hourly_stats", inputs=empty_inputs + ) + + @check_warnings( + expected_warnings=[ + "Cannot write dataframe with empty feature columns to online store" + ], + ) + def test_inputs_dict_with_empty_features_warns(self): + """Test that inputs dict with empty feature values warns instead of raising error""" + current_time = pd.Timestamp.now() + empty_feature_inputs = { + "driver_id": [1001, 1002, 1003], + "event_timestamp": [current_time] * 3, + "created": [current_time] * 3, + "conv_rate": [None, None, None], + "acc_rate": [None, None, None], + "avg_daily_trips": [None, None, None], + } + + self.store.write_to_online_store( + feature_view_name="driver_hourly_stats", inputs=empty_feature_inputs + ) + + @check_warnings( + forbidden_warnings=[ + "Cannot write empty dataframe to online store", + "Cannot write dataframe with empty feature columns to online store", + ], + ) + def test_multiple_feature_views_materialization_with_empty_data(self): + """Test materializing multiple feature views where one has empty data - should not break materialization""" + import tempfile + from datetime import timedelta + + with tempfile.TemporaryDirectory() as data_dir: + # Create a new store for this test + test_store = FeatureStore( + config=RepoConfig( + project="test_multiple_fv_materialization", + registry=os.path.join(data_dir, "registry.db"), + provider="local", + entity_key_serialization_version=3, + # online_store=SqliteOnlineStoreConfig(path=os.path.join(data_dir, "online.db")), + online_store=MongoDBOnlineStoreConfig(), + ) + ) + + # Create entities + driver = Entity(name="driver", join_keys=["driver_id"]) + customer = Entity(name="customer", join_keys=["customer_id"]) + + # Create 5 feature views with data + current_time = pd.Timestamp.now().replace(microsecond=0) + start_date = current_time - timedelta(hours=2) + end_date = current_time - timedelta(minutes=10) + feature_views = [] + dataframes = [] + offline_paths = [] + + for i in range(5): + # Create file path for offline data + offline_path = os.path.join(data_dir, f"feature_view_{i + 1}.parquet") + offline_paths.append(offline_path) + + # Create feature view with real file source + fv = FeatureView( + name=f"feature_view_{i + 1}", + entities=[driver if i % 2 == 0 else customer], + ttl=timedelta(days=1), + schema=[ + Field(name=f"feature_{i + 1}_rate", dtype=Float32), + Field(name=f"feature_{i + 1}_count", dtype=Int64), + ], + online=True, + source=FileSource( + name=f"source_{i + 1}", + path=offline_path, + timestamp_field="event_timestamp", + created_timestamp_column="created", + ), + ) + feature_views.append(fv) + + # Create data - make 2nd feature view (index 1) empty + if i == 1: # 2nd feature view gets empty data + df = pd.DataFrame() # Empty dataframe + else: + # Create valid data for other feature views + entity_key = "driver_id" if i % 2 == 0 else "customer_id" + df = pd.DataFrame( + { + entity_key: [1000 + j for j in range(3)], + "event_timestamp": [ + start_date + timedelta(minutes=j * 10) for j in range(3) + ], + "created": [current_time] * 3, + f"feature_{i + 1}_rate": [0.5 + j * 0.1 for j in range(3)], + f"feature_{i + 1}_count": [10 + j for j in range(3)], + } + ) + + # Write data to offline store (parquet files) - offline store allows empty dataframes + if len(df) > 0: + df.to_parquet(offline_path, allow_truncated_timestamps=True) + else: + # Create empty parquet file with correct schema (timezone-aware timestamps) + entity_key = "driver_id" if i % 2 == 0 else "customer_id" + empty_schema_df = pd.DataFrame( + { + entity_key: pd.Series([], dtype="int64"), + "event_timestamp": pd.Series( + [], dtype="datetime64[ns, UTC]" + ), # Timezone-aware + "created": pd.Series( + [], dtype="datetime64[ns, UTC]" + ), # Timezone-aware + f"feature_{i + 1}_rate": pd.Series([], dtype="float32"), + f"feature_{i + 1}_count": pd.Series([], dtype="int64"), + } + ) + empty_schema_df.to_parquet( + offline_path, allow_truncated_timestamps=True + ) + + dataframes.append(df) + + # Apply entities and feature views + test_store.apply([driver, customer] + feature_views) + + # Test: Use materialize() to move data from offline to online store + # This should NOT raise any exceptions even with empty data - decorator handles warning validation + try: + test_store.materialize( + start_date=start_date, + end_date=end_date, + feature_views=[fv.name for fv in feature_views], + ) + except Exception as e: + self.fail(f"Materialization raised an unexpected exception: {e}") + + # Verify that the operation was successful by checking that non-empty feature views have data + successful_materializations = 0 + for i, fv in enumerate(feature_views): + if i != 1: # Skip the empty one (2nd feature view) + entity_key = "driver_id" if i % 2 == 0 else "customer_id" + entity_value = 1000 # First entity from our test data + + # Try to retrieve features to verify they were written successfully + online_response = test_store.get_online_features( + entity_rows=[{entity_key: entity_value}], + features=[ + f"{fv.name}:feature_{i + 1}_rate", + f"{fv.name}:feature_{i + 1}_count", + ], + ).to_dict() + + # Verify we got some data back (not None/null) + rate_value = online_response.get(f"feature_{i + 1}_rate") + count_value = online_response.get(f"feature_{i + 1}_count") + + if rate_value is not None and count_value is not None: + successful_materializations += 1 + + self.assertIsNotNone(rate_value) + self.assertIsNotNone(count_value) + + # Verify that 4 out of 4 non-empty feature views were successfully materialized + self.assertEqual(successful_materializations, 4) + + +class TestOnlineWritesWithTransform(unittest.TestCase): + def test_transform_on_write_pdf(self): + with tempfile.TemporaryDirectory() as data_dir: + self.store = FeatureStore( + config=RepoConfig( + project="test_write_to_online_store_with_transform", + registry=os.path.join(data_dir, "registry.db"), + provider="local", + entity_key_serialization_version=3, + online_store=MongoDBOnlineStoreConfig() + # online_store=SqliteOnlineStoreConfig(path=os.path.join(self.data_dir, "online.db")), + ) + ) + + chunk = Entity( + name="chunk_id", + description="Chunk ID", + value_type=ValueType.STRING, + join_keys=["chunk_id"], + ) + + document = Entity( + name="document_id", + description="Document ID", + value_type=ValueType.STRING, + join_keys=["document_id"], + ) + + input_request_pdf = RequestSource( + name="pdf_request_source", + schema=[ + Field(name="document_id", dtype=String), + Field(name="pdf_bytes", dtype=PdfBytes), + Field(name="file_name", dtype=String), + ], + ) + + @on_demand_feature_view( + entities=[chunk, document], + sources=[input_request_pdf], + schema=[ + Field(name="document_id", dtype=String), + Field(name="chunk_id", dtype=String), + Field(name="chunk_text", dtype=String), + Field( + name="vector", + dtype=Array(Float32), + vector_index=True, + vector_search_metric="L2", + ), + ], + mode="python", + write_to_online_store=True, + singleton=True, + ) + def transform_pdf_on_write_view(inputs: dict[str, Any]) -> dict[str, Any]: + k = 10 + return { + "document_id": ["doc_1", "doc_2"], + "chunk_id": ["chunk-1", "chunk-2"], + "vector": [[0.5] * k, [0.4] * k], + "chunk_text": ["chunk text 1", "chunk text 2"], + } + + self.store.apply([chunk, document, transform_pdf_on_write_view]) + + sample_pdf = b"%PDF-1.3\n3 0 obj\n<>\nendobj\n4 0 obj\n<>\nstream\nx\x9c\x15\xcc1\x0e\x820\x18@\xe1\x9dS\xbcM]jk$\xd5\xd5(\x83!\x86\xa1\x17\xf8\xa3\xa5`LIh+\xd7W\xc6\xf7\r\xef\xc0\xbd\xd2\xaa\xb6,\xd5\xc5\xb1o\x0c\xa6VZ\xe3znn%\xf3o\xab\xb1\xe7\xa3:Y\xdc\x8bm\xeb\xf3&1\xc8\xd7\xd3\x97\xc82\xe6\x81\x87\xe42\xcb\x87Vb(\x12<\xdd<=}Jc\x0cL\x91\xee\xda$\xb5\xc3\xbd\xd7\xe9\x0f\x8d\x97 $\nendstream\nendobj\n1 0 obj\n<>\nendobj\n5 0 obj\n<>\nendobj\n2 0 obj\n<<\n/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n/Font <<\n/F1 5 0 R\n>>\n/XObject <<\n>>\n>>\nendobj\n6 0 obj\n<<\n/Producer (PyFPDF 1.7.2 http://pyfpdf.googlecode.com/)\n/Title (This is a sample title. And this is another sentence. Finally, this is the third sentence.)\n/Author (Francisco Javier Arceo)\n/CreationDate (D:20250312165548)\n>>\nendobj\n7 0 obj\n<<\n/Type /Catalog\n/Pages 1 0 R\n/OpenAction [3 0 R /FitH null]\n/PageLayout /OneColumn\n>>\nendobj\nxref\n0 8\n0000000000 65535 f \n0000000272 00000 n \n0000000455 00000 n \n0000000009 00000 n \n0000000087 00000 n \n0000000359 00000 n \n0000000559 00000 n \n0000000734 00000 n \ntrailer\n<<\n/Size 8\n/Root 7 0 R\n/Info 6 0 R\n>>\nstartxref\n837\n%%EOF\n" + sample_input = { + "pdf_bytes": sample_pdf, + "file_name": "sample_pdf", + "document_id": "doc_1", + } + input_df = pd.DataFrame([sample_input]) + + self.store.write_to_online_store( + feature_view_name="transform_pdf_on_write_view", + df=input_df, + ) diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/__init__.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/__init__.py deleted file mode 100644 index c7b38f213ab..00000000000 --- a/sdk/python/feast/infra/online_stores/mongodb_online_store/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# MongoDB Online Store for Feast diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/docs/point_in_time.md b/sdk/python/feast/infra/online_stores/mongodb_online_store/docs/point_in_time.md deleted file mode 100644 index 8e62ce21d1b..00000000000 --- a/sdk/python/feast/infra/online_stores/mongodb_online_store/docs/point_in_time.md +++ /dev/null @@ -1,255 +0,0 @@ -# Point-in-Time Joins in the MongoDB Offline Store - -This document describes the point-in-time join semantics supported by the MongoDB Offline Store implementation for Feast. - -The join logic itself is not implemented inside the Offline Store. Instead, the store’s schema, indexing strategy, and query guarantees are explicitly designed to support Feast’s point-in-time correctness model. - -## 1. Conceptual Overview - -A point-in-time join answers the question: - -Given an event that occurred at time T for entity E, what were the feature values that existed at or before T? - -This prevents data leakage by ensuring that training data never observes future feature values. - -Within Feast: -* Point-in-time semantics are defined by Feast core -* Store implementations provide efficient access primitives -* Joins are orchestrated above the store layer - -The MongoDB Offline Store enables these joins without embedding join logic itself. - -## 2. Key Concepts - -### Training Events - -A training event represents an observation used for model training. - -Each training event must include: -* One or more entity keys -* An event timestamp - -Example (taxi ride): -``` -{ - "_id": ObjectId("..."), - "driver_id": 123, - "pickup_ts": ISODate("2026-01-20T12:00:30Z"), - "fare": 18.50, - "tip": 3.25, - "label": 1 -} -``` -Training events: -* Are not owned by Feast -* Are not mutated by the Offline Store -* May live in any domain-specific collection - -### Feature History (Offline Store) - -Feature data is stored in an append-only MongoDB collection. - -Each document represents: -* One entity -* One feature view -* One event timestamp - -``` -{ - "_id": ObjectId("..."), - "entity_key": { - "driver_id": 123 - }, - "feature_view": "driver_stats", - "event_timestamp": ISODate("2026-01-20T12:00:00Z"), - "features": { - "rating": 4.91, - "trips_last_7d": 132 - } -} -``` -Multiple rows may exist for the same entity and feature view, distinguished only by timestamp. - -## 3. Required Schema Guarantees - -The MongoDB Offline Store must guarantee the following properties: -* Append-only writes - Feature rows are never updated or deleted. -* Monotonically increasing timestamps per entity - Newer feature values always have later timestamps. -* One row per (entity, feature_view, event_timestamp) - This ensures deterministic joins. - -⸻ - -## 4. Required Indexes - -To support efficient point-in-time queries, the following index is required on the feature history collection: - -``` -db.feature_history.create_index({ - "entity_key.driver_id": 1, - "feature_view": 1, - "event_timestamp": -1 -}) -``` -This index enables efficient retrieval of the most recent feature row at or before a given timestamp. - -## 5. Point-in-Time Join Semantics - -For each training event E and each feature view FV: - 1. Match feature rows with the same entity key - 2. Filter rows where -feature.event_timestamp ≤ training.event_timestamp - 3. Select the row with the maximum event_timestamp - -Each feature view is joined independently to avoid cross-feature coupling. - -⸻ - -## 6. Example: Taxi Ride Training Join (MongoDB Aggregation) - -### Training Events Collection -``` -{ - "_id": ObjectId("..."), - "driver_id": 123, - "pickup_ts": ISODate("2026-01-20T12:00:30Z"), - "fare": 18.50, - "label": 1 -} -``` -### Feature History Collection -``` -[{ - "entity_key": { "driver_id": 123 }, - "feature_view": "driver_stats", - "event_timestamp": ISODate("2026-01-20T12:00:00Z"), - "features": { - "rating": 4.91, - "trips_last_7d": 132 - } -}, -{ - "entity_key": { "driver_id": 123 }, - "feature_view": "pricing", - "event_timestamp": ISODate("2026-01-20T12:01:00Z"), - "features": { - "surge_multiplier": 1.2 - } -}] -``` - -### Aggregation Pipeline (Single Pass, No Application Loops) - -The following aggregation performs point-in-time joins for multiple feature views in a single pipeline. - -```python -pipeline = [ - { - "$lookup": { - "from": "feature_history", - "let": { - "driver_id": "$driver_id", - "event_ts": "$pickup_ts" - }, - "pipeline": [ - { - "$match": { - "$expr": { - "$and": [ - { "$eq": ["$entity_key.driver_id", "$$driver_id"] }, - { "$lte": ["$event_timestamp", "$$event_ts"] } - ] - } - } - }, - { "$sort": { "event_timestamp": -1 } }, - { - "$group": { - "_id": "$feature_view", - "features": { "$first": "$features" }, - "event_timestamp": { "$first": "$event_timestamp" } - } - } - ], - "as": "joined_features" - } - }, - { - "$addFields": { - "features": { - "$arrayToObject": { - "$map": { - "input": "$joined_features", - "as": "fv", - "in": { - "k": "$$fv._id", - "v": "$$fv.features" - } - } - } - } - } - }, - { - "$project": { - "joined_features": 0 - } - } -] -``` -### Execution -```python -results = list(db.training_events.aggregate(pipeline)) -``` -### Resulting Document -``` -{ - "driver_id": 123, - "pickup_ts": ISODate("2026-01-20T12:00:30Z"), - "fare": 18.50, - "label": 1, - "features": { - "driver_stats": { - "rating": 4.91, - "trips_last_7d": 132 - }, - "pricing": { - "surge_multiplier": 1.2 - } - } -} -``` -Feast may flatten this structure into feature columns such as: -``` -driver_stats__rating -driver_stats__trips_last_7d -pricing__surge_multiplier -``` - -## 7. Responsibilities and Non-Goals - -### MongoDB Offline Store Responsibilities -* Store append-only feature history -* Support efficient temporal lookups -* Guarantee ordering and timestamp semantics - -### Explicit Non-Goals - -The MongoDB Offline Store does *not*: -* Join training events with features -* Merge feature views together -* Enforce point-in-time correctness rules - -These responsibilities belong to Feast core. - - -## 8. Summary - -The MongoDB Offline Store enables point-in-time joins by providing: -* A complete historical record of feature values -* Stable schemas and required indexes -* Efficient access patterns for time-aware queries - -The join logic is documented here as a semantic contract, ensuring correctness while keeping the store implementation simple, testable, and aligned with Feast’s architecture. \ No newline at end of file diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_claude.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_claude.py deleted file mode 100644 index 98489b492fc..00000000000 --- a/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_claude.py +++ /dev/null @@ -1,506 +0,0 @@ -# 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. - -""" -MongoDB Online Store implementation for Feast. - -This module provides an online store implementation using MongoDB, with support for: -- MongoDB Atlas (primary target) -- Core MongoDB (for basic functionality) -- Async operations using PyMongo's AsyncMongoClient -- Vector search via Atlas Vector Search -- TTL-based feature expiration -""" - -import hashlib -import logging -from datetime import datetime, timedelta -from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple - -from pydantic import StrictBool, StrictInt, StrictStr - -from feast import Entity, FeatureView, RepoConfig -from feast.infra.key_encoding_utils import serialize_entity_key -from feast.infra.online_stores.online_store import OnlineStore, SupportedAsyncMethods -from feast.infra.online_stores.vector_store import VectorStoreConfig -from feast.infra.utils.mongodb.connection_utils import ( - get_async_mongo_client, - get_collection_name, - get_mongo_client, -) -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 feast.utils import to_naive_utc - -try: - from pymongo import AsyncMongoClient, MongoClient, UpdateOne - from pymongo.errors import OperationFailure -except ImportError as e: - from feast.errors import FeastExtrasDependencyImportError - - raise FeastExtrasDependencyImportError("mongodb", str(e)) - -logger = logging.getLogger(__name__) - - -class MongoDBOnlineStoreConfig(FeastConfigBaseModel, VectorStoreConfig): - """ - Configuration for MongoDB Online Store. - - Supports both MongoDB Atlas and core MongoDB deployments. - """ - - type: Literal[ - "mongodb", "feast.infra.online_stores.mongodb_online_store.mongodb.MongoDBOnlineStore" - ] = "mongodb" - """Online store type selector""" - - # Connection settings - connection_string: StrictStr - """MongoDB connection URI (mongodb:// or mongodb+srv:// for Atlas)""" - - database: StrictStr = "feast" - """Database name for online store""" - - # Performance settings - max_pool_size: StrictInt = 50 - """Maximum connection pool size""" - - min_pool_size: StrictInt = 10 - """Minimum connection pool size""" - - # TTL settings - ttl_seconds: Optional[StrictInt] = None - """Optional TTL for documents in seconds (uses MongoDB TTL index)""" - - # Atlas-specific features - atlas_vector_search_enabled: StrictBool = False - """Enable Atlas Vector Search for retrieve_online_documents_v2""" - - vector_index_name: StrictStr = "vector_index" - """Name of the Atlas vector search index""" - - vector_similarity_metric: StrictStr = "cosine" - """Similarity metric: 'cosine', 'euclidean', or 'dotProduct'""" - - # Write concern - write_concern_w: StrictInt = 1 - """Write concern w parameter (1=primary, 'majority'=majority, etc.)""" - - # Read preference - read_preference: StrictStr = "primaryPreferred" - """Read preference: 'primary', 'primaryPreferred', 'secondary', etc.""" - - -class MongoDBOnlineStore(OnlineStore): - """ - MongoDB implementation of the Feast online store interface. - - This implementation supports: - - Synchronous and asynchronous operations - - MongoDB Atlas Vector Search for similarity search - - TTL-based feature expiration - - Connection pooling for performance - - Document structure: - { - _id: ObjectId, - entity_key_hash: "md5_hash", - features: { - "feature1": , - "feature2": , - ... - }, - event_timestamp: ISODate, - created_timestamp: ISODate (optional), - vector_embedding: [float, ...] (optional, for vector search), - expire_at: ISODate (optional, for TTL) - } - """ - - _client: Optional[MongoClient] = None - _client_async: Optional[AsyncMongoClient] = None - - def _get_client(self, config: MongoDBOnlineStoreConfig) -> MongoClient: - """Get or create synchronous MongoDB client.""" - if not self._client: - self._client = get_mongo_client( - connection_string=config.connection_string, - max_pool_size=config.max_pool_size, - min_pool_size=config.min_pool_size, - write_concern_w=config.write_concern_w, - read_preference=config.read_preference, - ) - return self._client - - def _get_client_async(self, config: MongoDBOnlineStoreConfig) -> AsyncMongoClient: - """Get or create asynchronous MongoDB client.""" - if not self._client_async: - self._client_async = get_async_mongo_client( - connection_string=config.connection_string, - max_pool_size=config.max_pool_size, - min_pool_size=config.min_pool_size, - write_concern_w=config.write_concern_w, - read_preference=config.read_preference, - ) - return self._client_async - - @staticmethod - def _compute_entity_key_hash(entity_key_bin: bytes) -> str: - """Compute MD5 hash of entity key for efficient indexing.""" - return hashlib.md5(entity_key_bin).hexdigest() - - @property - def async_supported(self) -> SupportedAsyncMethods: - """Indicate that this online store supports async operations.""" - return SupportedAsyncMethods(read=True, write=True) - - def online_write_batch( - self, - config: RepoConfig, - table: FeatureView, - data: List[ - Tuple[EntityKeyProto, Dict[str, ValueProto], datetime, Optional[datetime]] - ], - progress: Optional[Callable[[int], Any]], - ) -> None: - """ - Write a batch of feature rows to MongoDB. - - Args: - config: Feast repository configuration - table: Feature view to write to - data: List of (entity_key, features, event_timestamp, created_timestamp) tuples - progress: Optional progress callback - """ - assert config.online_store.type == "mongodb" - online_config: MongoDBOnlineStoreConfig = config.online_store - - client = self._get_client(online_config) - db = client[online_config.database] - collection_name = get_collection_name(config.project, table.name) - collection = db[collection_name] - - bulk_operations = [] - for entity_key, values, timestamp, created_ts in data: - # Serialize entity key - entity_key_bin = serialize_entity_key( - entity_key, - entity_key_serialization_version=config.entity_key_serialization_version, - ) - entity_key_hash = self._compute_entity_key_hash(entity_key_bin) - - # Serialize feature values - features_dict = {} - for feature_name, val in values.items(): - features_dict[feature_name] = val.SerializeToString() # TODO - This is not sufficient to convert ValProto to python object - - # Build document - document = { - "_id": entity_key_bin, # TODO: What is entity_key_hash for? We don't need a string - "features": features_dict, - "event_timestamp": to_naive_utc(timestamp), - } - - if created_ts: - document["created_timestamp"] = to_naive_utc(created_ts) - - # Add TTL field if configured - if online_config.ttl_seconds: - expire_at = timestamp + timedelta(seconds=online_config.ttl_seconds) - document["expire_at"] = expire_at - - # Upsert operation - bulk_operations.append(UpdateOne(filter={"_id": entity_key_bin}, update={"$set": document}, upsert=True)) - - if progress: - progress(1) - - # Execute bulk write if there are operations - if bulk_operations: - collection.bulk_write(bulk_operations) - - - 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.""" - assert config.online_store.type == "mongodb" - online_config: MongoDBOnlineStoreConfig = config.online_store - - client = self._get_client_async(online_config) - db = client[online_config.database] - collection_name = get_collection_name(config.project, table.name) - collection = db[collection_name] - - bulk_operations = [] - for entity_key, values, timestamp, created_ts in data: - entity_key_bin = serialize_entity_key( - entity_key, - entity_key_serialization_version=config.entity_key_serialization_version, - ) - entity_key_hash = self._compute_entity_key_hash(entity_key_bin) - timestamp = to_naive_utc(timestamp) - created_ts = to_naive_utc(created_ts) if created_ts else None - - features_dict = { - feature_name: val.SerializeToString() - for feature_name, val in values.items() - } - - document = { - "entity_key_hash": entity_key_hash, - "features": features_dict, - "event_timestamp": timestamp, - } - - if created_ts: - document["created_timestamp"] = created_ts - - if online_config.ttl_seconds: - expire_at = timestamp + timedelta(seconds=online_config.ttl_seconds) - document["expire_at"] = expire_at - - bulk_operations.append({ - "filter": {"entity_key_hash": entity_key_hash}, - "update": {"$set": document}, - "upsert": True, - }) - - if progress: - progress(1) - - if bulk_operations: - from pymongo import UpdateOne - await collection.bulk_write([ - UpdateOne(op["filter"], op["update"], upsert=op["upsert"]) - for op in bulk_operations - ]) - - def online_read( - self, - config: RepoConfig, - table: FeatureView, - entity_keys: List[EntityKeyProto], - requested_features: Optional[List[str]] = None, - ) -> List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]]: - """ - Read feature values from MongoDB. - - Args: - config: Feast repository configuration - table: Feature view to read from - entity_keys: List of entity keys to read - requested_features: Optional list of specific features to retrieve - - Returns: - List of (event_timestamp, features_dict) tuples, one per entity key - """ - assert config.online_store.type == "mongodb" - online_config: MongoDBOnlineStoreConfig = config.online_store - - client = self._get_client(online_config) - db = client[online_config.database] - collection_name = get_collection_name(config.project, table.name) - collection = db[collection_name] - - # Compute entity key hashes - entity_key_hashes = [ - self._compute_entity_key_hash( - serialize_entity_key( - key, - entity_key_serialization_version=config.entity_key_serialization_version, - ) - ) - for key in entity_keys - ] - - # Query MongoDB - documents = list(collection.find({"entity_key_hash": {"$in": entity_key_hashes}})) - - # Build lookup map - doc_map = {doc["entity_key_hash"]: doc for doc in documents} - - # Build results in order of entity_keys - results = [] - for entity_key_hash in entity_key_hashes: - doc = doc_map.get(entity_key_hash) - - if not doc: - results.append((None, None)) # todo - is this req'd? - continue - - event_ts = doc.get("event_timestamp") - features_dict = {} - - for feature_name, feature_bin in doc.get("features", {}).items(): - if requested_features is None or feature_name in requested_features: - val = ValueProto() - val.ParseFromString(feature_bin) - features_dict[feature_name] = val - - results.append((event_ts, features_dict if features_dict else None)) - - return results - - async def online_read_async( - self, - config: RepoConfig, - table: FeatureView, - entity_keys: List[EntityKeyProto], - requested_features: Optional[List[str]] = None, - ) -> List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]]: - """Async version of online_read.""" - assert config.online_store.type == "mongodb" - online_config: MongoDBOnlineStoreConfig = config.online_store - - client = self._get_client_async(online_config) - db = client[online_config.database] - collection_name = get_collection_name(config.project, table.name) - collection = db[collection_name] - - entity_key_hashes = [ - self._compute_entity_key_hash( - serialize_entity_key( - key, - entity_key_serialization_version=config.entity_key_serialization_version, - ) - ) - for key in entity_keys - ] - - cursor = collection.find({"entity_key_hash": {"$in": entity_key_hashes}}) - documents = await cursor.to_list(length=len(entity_key_hashes)) - - doc_map = {doc["entity_key_hash"]: doc for doc in documents} - - results = [] - for entity_key_hash in entity_key_hashes: - doc = doc_map.get(entity_key_hash) - - if not doc: - results.append((None, None)) - continue - - event_ts = doc.get("event_timestamp") - features_dict = {} - - for feature_name, feature_bin in doc.get("features", {}).items(): - if requested_features is None or feature_name in requested_features: - val = ValueProto() - val.ParseFromString(feature_bin) - features_dict[feature_name] = val - - results.append((event_ts, features_dict if features_dict else None)) - - return results - - def update( - self, - config: RepoConfig, - tables_to_delete: Sequence[FeatureView], - tables_to_keep: Sequence[FeatureView], - entities_to_delete: Sequence[Entity], - entities_to_keep: Sequence[Entity], - partial: bool, - ): - """ - Update MongoDB resources (create/delete collections and indexes). - - Args: - config: Feast repository configuration - tables_to_delete: Feature views whose collections should be deleted - tables_to_keep: Feature views whose collections should be created/updated - entities_to_delete: Entities to delete (unused for MongoDB) - entities_to_keep: Entities to keep (unused for MongoDB) - partial: Whether this is a partial update - """ - assert config.online_store.type == "mongodb" - online_config: MongoDBOnlineStoreConfig = config.online_store - - client = self._get_client(online_config) - db = client[online_config.database] - - # Delete collections for removed feature views - for table in tables_to_delete: - collection_name = get_collection_name(config.project, table.name) - db[collection_name].drop() - logger.info(f"Dropped MongoDB collection: {collection_name}") - - # Create/update collections and indexes for feature views - for table in tables_to_keep: - collection_name = get_collection_name(config.project, table.name) - collection = db[collection_name] - - # Create unique index on entity_key_hash - try: - collection.create_index("entity_key_hash", unique=True, name="idx_entity_key_hash") - logger.info(f"Created index on entity_key_hash for {collection_name}") - except OperationFailure as e: - if "already exists" not in str(e): - raise - - # Create TTL index if configured - if online_config.ttl_seconds: - try: - collection.create_index( - "expire_at", - expireAfterSeconds=0, # TTL is encoded in the expire_at field - name="idx_ttl" - ) - logger.info(f"Created TTL index for {collection_name}") - except OperationFailure as e: - if "already exists" not in str(e): - raise - - def teardown( - self, - config: RepoConfig, - tables: Sequence[FeatureView], - entities: Sequence[Entity], - ): - """ - Tear down MongoDB resources (drop collections). - - Args: - config: Feast repository configuration - tables: Feature views whose collections should be dropped - entities: Entities (unused for MongoDB) - """ - assert config.online_store.type == "mongodb" - online_config: MongoDBOnlineStoreConfig = config.online_store - - client = self._get_client(online_config) - db = client[online_config.database] - - for table in tables: - collection_name = get_collection_name(config.project, table.name) - db[collection_name].drop() - logger.info(f"Dropped MongoDB collection during teardown: {collection_name}") - - # TODO: Implement vector search methods in next iteration - # def retrieve_online_documents_v2(...) - # async def initialize(...) - # async def close(...) - - - # TODO - # - Add unique index on entity_key hash. We need not convert to a string. We can keep as bson.binary diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/__init__.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/__init__.py deleted file mode 100644 index 092b88538ea..00000000000 --- a/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# Tests for MongoDB Online Store diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/test_mongodb_online.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/test_mongodb_online.py deleted file mode 100644 index 984048bfa6f..00000000000 --- a/sdk/python/feast/infra/online_stores/mongodb_online_store/tests/test_mongodb_online.py +++ /dev/null @@ -1,630 +0,0 @@ -# Copyright 2025 The Feast Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Unit and integration tests for MongoDB Online Store. - -These tests cover: -- Configuration validation -- CRUD operations (sync and async) -- Index creation -- TTL functionality -- Connection management -""" - -import os -from datetime import UTC, datetime, timedelta -from unittest.mock import MagicMock, patch - -import pytest - -from feast import Entity, FeatureView, Field, FileSource, RepoConfig -from feast.infra.online_stores.mongodb_online_store.mongodb import ( - MongoDBOnlineStore, - MongoDBOnlineStoreConfig, -) -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, Int64, String -from feast.value_type import ValueType - -MONGODB_URI = os.environ.get("MONGODB_URI", "mongodb://localhost:27017") - -class TestMongoDBOnlineStoreConfig: - """Test suite for MongoDBOnlineStoreConfig.""" - - def test_default_config(self): - """Test default configuration values.""" - config = MongoDBOnlineStoreConfig( - connection_string=MONGODB_URI - ) - - assert config.type == "mongodb" - assert config.database == "feast" - assert config.max_pool_size == 50 - assert config.min_pool_size == 10 - assert config.ttl_seconds is None - assert config.atlas_vector_search_enabled is False - assert config.vector_index_name == "vector_index" - assert config.vector_similarity_metric == "cosine" - assert config.write_concern_w == 1 - assert config.read_preference == "primaryPreferred" - - def test_custom_config(self): - """Test custom configuration values.""" - config = MongoDBOnlineStoreConfig( - connection_string="mongodb+srv://user:pass@cluster.mongodb.net", - database="custom_db", - max_pool_size=100, - min_pool_size=20, - ttl_seconds=86400, - atlas_vector_search_enabled=True, - vector_similarity_metric="euclidean", - write_concern_w=2, - read_preference="primary", - ) - - assert config.database == "custom_db" - assert config.max_pool_size == 100 - assert config.min_pool_size == 20 - assert config.ttl_seconds == 86400 - assert config.atlas_vector_search_enabled is True - assert config.vector_similarity_metric == "euclidean" - assert config.write_concern_w == 2 - assert config.read_preference == "primary" - - def test_atlas_connection_string(self): - """Test Atlas connection string format.""" - config = MongoDBOnlineStoreConfig( - connection_string="mongodb+srv://cluster.mongodb.net" - ) - assert "mongodb+srv://" in config.connection_string - - -class TestMongoDBOnlineStore: - """Test suite for MongoDBOnlineStore implementation.""" - - @pytest.fixture - def mock_config(self): - """Create a mock RepoConfig for testing.""" - return RepoConfig( - project="test_project", - online_store=MongoDBOnlineStoreConfig( - connection_string=MONGODB_URI, - database="feast_test", - ), - registry="dummy_registry", - ) - - @pytest.fixture - def mock_config_with_ttl(self): - """Create a mock RepoConfig with TTL enabled.""" - return RepoConfig( - project="test_project", - online_store=MongoDBOnlineStoreConfig( - connection_string=MONGODB_URI, - database="feast_test", - ttl_seconds=86400, - ), - registry="dummy_registry", - ) - - @pytest.fixture - def feature_view(self): - """Create a test FeatureView.""" - entity = Entity( - name="user_id", description="User ID", value_type=ValueType.INT64 - ) - source = FileSource(path="test.parquet", timestamp_field="event_timestamp") - return FeatureView( - name="test_features", - entities=[entity], - ttl=timedelta(days=1), - schema=[ - Field(name="user_id", dtype=Int64), - Field(name="feature1", dtype=String), - Field(name="feature2", dtype=Float32), - ], - source=source, - ) - - @pytest.fixture - def entity_keys(self): - """Create test entity keys.""" - keys = [] - for i in range(3): - key = EntityKeyProto() - key.join_keys.append(f"user_{i}") - key.entity_values.append( - ValueProto(int64_val=i) - ) - keys.append(key) - return keys - - @pytest.fixture - def feature_data(self, entity_keys): - """Create test feature data.""" - data = [] - timestamp = datetime.now(UTC) - - for i, key in enumerate(entity_keys): - features = { - "feature1": ValueProto(string_val=f"value_{i}"), - "feature2": ValueProto(float_val=float(i) * 1.5), - } - data.append((key, features, timestamp, None)) - - return data - - def test_compute_entity_key_hash(self): - """Test entity key hashing.""" - store = MongoDBOnlineStore() - - # Test consistent hashing - key_bin = b"test_entity_key" - hash1 = store._compute_entity_key_hash(key_bin) - hash2 = store._compute_entity_key_hash(key_bin) - - assert hash1 == hash2 - assert isinstance(hash1, str) - assert len(hash1) == 32 # MD5 hash length - - def test_async_supported(self): - """Test that async operations are supported.""" - store = MongoDBOnlineStore() - async_methods = store.async_supported - - assert async_methods.read is True - assert async_methods.write is True - - @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") - def test_online_write_batch(self, mock_get_client, mock_config, feature_view, feature_data): - """Test synchronous write batch operation.""" - # Mock MongoDB client and collection - mock_client = MagicMock() - mock_db = MagicMock() - mock_collection = MagicMock() - - # mock_client.__getitem__.return_value = mock_db - # mock_db.__getitem__.return_value = mock_collection - # mock_get_client.return_value = mock_client - - # Create store and write data - store = MongoDBOnlineStore() - store.online_write_batch( - config=mock_config, - table=feature_view, - data=feature_data, - progress=None, - ) - - # Verify client was created - mock_get_client.assert_called_once() - - # Verify bulk_write was called - mock_collection.bulk_write.assert_called_once() - - # Get the bulk operations - call_args = mock_collection.bulk_write.call_args - operations = call_args[0][0] - - # Verify we have the right number of operations - assert len(operations) == len(feature_data) - - @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") - def test_online_write_batch_with_ttl( - self, mock_get_client, mock_config_with_ttl, feature_view, feature_data - ): - """Test write batch with TTL enabled.""" - mock_client = MagicMock() - mock_db = MagicMock() - mock_collection = MagicMock() - - mock_client.__getitem__.return_value = mock_db - mock_db.__getitem__.return_value = mock_collection - mock_get_client.return_value = mock_client - - store = MongoDBOnlineStore() - store.online_write_batch( - config=mock_config_with_ttl, - table=feature_view, - data=feature_data, - progress=None, - ) - - # Verify bulk_write was called - assert mock_collection.bulk_write.called - - @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") - def test_online_read(self, mock_get_client, mock_config, feature_view, entity_keys): - """Test synchronous read operation.""" - # Mock MongoDB client and collection - mock_client = MagicMock() - mock_db = MagicMock() - mock_collection = MagicMock() - - mock_client.__getitem__.return_value = mock_db - mock_db.__getitem__.return_value = mock_collection - mock_get_client.return_value = mock_client - - # Mock find result - mock_doc = { - "entity_key_hash": "test_hash", - "event_timestamp": datetime.now(UTC), - "features": { - "feature1": ValueProto(string_val="test").SerializeToString(), - "feature2": ValueProto(float_val=1.5).SerializeToString(), - }, - } - mock_collection.find.return_value = [mock_doc] - - # Create store and read data - store = MongoDBOnlineStore() - results = store.online_read( - config=mock_config, - table=feature_view, - entity_keys=entity_keys, - requested_features=None, - ) - - # Verify results - assert len(results) == len(entity_keys) - assert mock_collection.find.called - - @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") - def test_online_read_with_missing_entities( - self, mock_get_client, mock_config, feature_view, entity_keys - ): - """Test read operation with some missing entities.""" - mock_client = MagicMock() - mock_db = MagicMock() - mock_collection = MagicMock() - - mock_client.__getitem__.return_value = mock_db - mock_db.__getitem__.return_value = mock_collection - mock_get_client.return_value = mock_client - - # Return empty list (no documents found) - mock_collection.find.return_value = [] - - store = MongoDBOnlineStore() - results = store.online_read( - config=mock_config, - table=feature_view, - entity_keys=entity_keys, - requested_features=None, - ) - - # All results should be (None, None) for missing entities - assert len(results) == len(entity_keys) - for event_ts, features in results: - assert event_ts is None - assert features is None - - @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") - def test_update_creates_indexes(self, mock_get_client, mock_config, feature_view): - """Test that update creates necessary indexes.""" - mock_client = MagicMock() - mock_db = MagicMock() - mock_collection = MagicMock() - - mock_client.__getitem__.return_value = mock_db - mock_db.__getitem__.return_value = mock_collection - mock_get_client.return_value = mock_client - - store = MongoDBOnlineStore() - store.update( - config=mock_config, - tables_to_delete=[], - tables_to_keep=[feature_view], - entities_to_delete=[], - entities_to_keep=[], - partial=False, - ) - - # Verify create_index was called for entity_key_hash - assert mock_collection.create_index.called - call_args_list = mock_collection.create_index.call_args_list - - # Should have at least one create_index call - assert len(call_args_list) >= 1 - - @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") - def test_update_creates_ttl_index( - self, mock_get_client, mock_config_with_ttl, feature_view - ): - """Test that update creates TTL index when TTL is configured.""" - mock_client = MagicMock() - mock_db = MagicMock() - mock_collection = MagicMock() - - mock_client.__getitem__.return_value = mock_db - mock_db.__getitem__.return_value = mock_collection - mock_get_client.return_value = mock_client - - store = MongoDBOnlineStore() - store.update( - config=mock_config_with_ttl, - tables_to_delete=[], - tables_to_keep=[feature_view], - entities_to_delete=[], - entities_to_keep=[], - partial=False, - ) - - # Verify create_index was called - assert mock_collection.create_index.called - - @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") - def test_update_deletes_collections(self, mock_get_client, mock_config, feature_view): - """Test that update deletes collections for removed feature views.""" - mock_client = MagicMock() - mock_db = MagicMock() - mock_collection = MagicMock() - - mock_client.__getitem__.return_value = mock_db - mock_db.__getitem__.return_value = mock_collection - mock_get_client.return_value = mock_client - - store = MongoDBOnlineStore() - store.update( - config=mock_config, - tables_to_delete=[feature_view], - tables_to_keep=[], - entities_to_delete=[], - entities_to_keep=[], - partial=False, - ) - - # Verify collection.drop was called - assert mock_collection.drop.called - - @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_mongo_client") - def test_teardown(self, mock_get_client, mock_config, feature_view): - """Test teardown operation.""" - mock_client = MagicMock() - mock_db = MagicMock() - mock_collection = MagicMock() - - mock_client.__getitem__.return_value = mock_db - mock_db.__getitem__.return_value = mock_collection - mock_get_client.return_value = mock_client - - store = MongoDBOnlineStore() - store.teardown( - config=mock_config, - tables=[feature_view], - entities=[], - ) - - # Verify collection.drop was called - assert mock_collection.drop.called - - -class TestMongoDBOnlineStoreAsync: - """Test suite for async operations.""" - - @pytest.fixture - def mock_config(self): - """Create a mock RepoConfig for testing.""" - return RepoConfig( - project="test_project", - online_store=MongoDBOnlineStoreConfig( - connection_string="mongodb://localhost:27017", - database="feast_test", - ), - registry="dummy_registry", - ) - - @pytest.fixture - def feature_view(self): - """Create a test FeatureView.""" - entity = Entity( - name="user_id", description="User ID", value_type=ValueType.INT64 - ) - source = FileSource(path="test.parquet", timestamp_field="event_timestamp") - return FeatureView( - name="test_features", - entities=[entity], - ttl=timedelta(days=1), - schema=[ - Field(name="user_id", dtype=Int64), - Field(name="feature1", dtype=String), - ], - source=source, - ) - - @pytest.mark.asyncio - @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_async_mongo_client") - async def test_online_write_batch_async( - self, mock_get_client_async, mock_config, feature_view - ): - """Test async write batch operation.""" - # Mock async MongoDB client - mock_client = MagicMock() - mock_db = MagicMock() - mock_collection = MagicMock() - mock_collection.bulk_write = MagicMock(return_value=None) - - mock_client.__getitem__.return_value = mock_db - mock_db.__getitem__.return_value = mock_collection - mock_get_client_async.return_value = mock_client - - # Create test data - entity_key = EntityKeyProto() - entity_key.join_keys.append("user_id") - entity_key.entity_values.append(ValueProto(int64_val=123)) - - features = { - "feature1": ValueProto(string_val="test"), - } - - data = [(entity_key, features, datetime.now(UTC), None)] - - # Write data - store = MongoDBOnlineStore() - await store.online_write_batch_async( - config=mock_config, - table=feature_view, - data=data, - progress=None, - ) - - # Verify client was created - mock_get_client_async.assert_called_once() - - @pytest.mark.asyncio - @patch("feast.infra.online_stores.mongodb_online_store.mongodb.get_async_mongo_client") - async def test_online_read_async( - self, mock_get_client_async, mock_config, feature_view - ): - """Test async read operation.""" - # Mock async MongoDB client - mock_client = MagicMock() - mock_db = MagicMock() - mock_collection = MagicMock() - - # Mock cursor - mock_cursor = MagicMock() - mock_cursor.to_list = MagicMock(return_value=[]) - mock_collection.find.return_value = mock_cursor - - mock_client.__getitem__.return_value = mock_db - mock_db.__getitem__.return_value = mock_collection - mock_get_client_async.return_value = mock_client - - # Create test entity key - entity_key = EntityKeyProto() - entity_key.join_keys.append("user_id") - entity_key.entity_values.append(ValueProto(int64_val=123)) - - # Read data - store = MongoDBOnlineStore() - results = await store.online_read_async( - config=mock_config, - table=feature_view, - entity_keys=[entity_key], - requested_features=None, - ) - - # Verify results - assert len(results) == 1 - mock_collection.find.assert_called_once() - - -@pytest.mark.integration -@pytest.mark.skipif( - os.getenv("MONGODB_CONNECTION_STRING") is None, - reason="MongoDB connection string not provided. Set MONGODB_CONNECTION_STRING env var to run integration tests.", -) -class TestMongoDBOnlineStoreIntegration: - """ - Integration tests for MongoDB Online Store. - - These tests require a running MongoDB instance. - Set MONGODB_CONNECTION_STRING environment variable to run these tests. - Example: export MONGODB_CONNECTION_STRING="mongodb://localhost:27017" - """ - - @pytest.fixture - def mongodb_config(self): - """Create configuration using real MongoDB connection.""" - return RepoConfig( - project="integration_test", - online_store=MongoDBOnlineStoreConfig( - connection_string=os.getenv("MONGODB_CONNECTION_STRING"), - database="feast_integration_test", - ), - registry="dummy_registry", - ) - - @pytest.fixture - def feature_view(self): - """Create a test FeatureView.""" - entity = Entity( - name="user_id", description="User ID", value_type=ValueType.INT64 - ) - source = FileSource(path="test.parquet", timestamp_field="event_timestamp") - return FeatureView( - name="test_integration_features", - entities=[entity], - ttl=timedelta(days=1), - schema=[ - Field(name="user_id", dtype=Int64), - Field(name="feature1", dtype=String), - Field(name="feature2", dtype=Float32), - ], - source=source, - ) - - def test_full_write_read_cycle(self, mongodb_config, feature_view): - """Test a complete write and read cycle with real MongoDB.""" - store = MongoDBOnlineStore() - - # Setup: Create indexes - store.update( - config=mongodb_config, - tables_to_delete=[], - tables_to_keep=[feature_view], - entities_to_delete=[], - entities_to_keep=[], - partial=False, - ) - - # Create test data - entity_key = EntityKeyProto() - entity_key.join_keys.append("user_id") - entity_key.entity_values.append(ValueProto(int64_val=123)) - - features = { - "feature1": ValueProto(string_val="integration_test_value"), - "feature2": ValueProto(float_val=42.5), - } - - timestamp = datetime.now(UTC) - data = [(entity_key, features, timestamp, None)] - - # Write data - store.online_write_batch( - config=mongodb_config, - table=feature_view, - data=data, - progress=None, - ) - - # Read data back - results = store.online_read( - config=mongodb_config, - table=feature_view, - entity_keys=[entity_key], - requested_features=None, - ) - - # Verify results - assert len(results) == 1 - event_ts, feature_dict = results[0] - - assert event_ts is not None - assert feature_dict is not None - assert "feature1" in feature_dict - assert "feature2" in feature_dict - assert feature_dict["feature1"].string_val == "integration_test_value" - assert abs(feature_dict["feature2"].float_val - 42.5) < 0.01 - - # Cleanup - store.teardown( - config=mongodb_config, - tables=[feature_view], - entities=[], - ) diff --git a/sdk/python/feast/infra/utils/mongodb/test_connection_utils.py b/sdk/python/feast/infra/utils/mongodb/test_connection_utils.py deleted file mode 100644 index 68491de9fd0..00000000000 --- a/sdk/python/feast/infra/utils/mongodb/test_connection_utils.py +++ /dev/null @@ -1,240 +0,0 @@ -# Copyright 2025 The Feast Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Unit tests for MongoDB connection utilities. -""" - -import pytest -from unittest.mock import MagicMock, patch - -from feast.infra.utils.mongodb.connection_utils import ( - get_mongo_client, - get_async_mongo_client, - is_atlas, - _parse_read_preference, - get_collection_name, -) - -try: - from pymongo.read_preferences import ReadPreference -except ImportError: - pytest.skip("pymongo not installed", allow_module_level=True) - - -class TestReadPreferenceParsing: - """Test read preference parsing.""" - - def test_primary(self): - """Test parsing 'primary' read preference.""" - result = _parse_read_preference("primary") - assert result == ReadPreference.PRIMARY - - def test_primary_preferred(self): - """Test parsing 'primaryPreferred' read preference.""" - result = _parse_read_preference("primaryPreferred") - assert result == ReadPreference.PRIMARY_PREFERRED - - def test_secondary(self): - """Test parsing 'secondary' read preference.""" - result = _parse_read_preference("secondary") - assert result == ReadPreference.SECONDARY - - def test_secondary_preferred(self): - """Test parsing 'secondaryPreferred' read preference.""" - result = _parse_read_preference("secondaryPreferred") - assert result == ReadPreference.SECONDARY_PREFERRED - - def test_nearest(self): - """Test parsing 'nearest' read preference.""" - result = _parse_read_preference("nearest") - assert result == ReadPreference.NEAREST - - def test_invalid_preference(self): - """Test that invalid preference raises ValueError.""" - with pytest.raises(ValueError, match="Invalid read preference"): - _parse_read_preference("invalid_preference") - - -class TestCollectionNameGeneration: - """Test collection name generation.""" - - def test_basic_names(self): - """Test basic project and table names.""" - result = get_collection_name("my_project", "my_table") - assert result == "my_project_my_table" - - def test_sanitizes_dollar_sign(self): - """Test that dollar signs are replaced.""" - result = get_collection_name("project$name", "table$name") - assert result == "project_name_table_name" - assert "$" not in result - - def test_sanitizes_null_character(self): - """Test that null characters are removed.""" - result = get_collection_name("project\x00name", "table\x00name") - assert result == "projectname_tablename" - assert "\x00" not in result - - def test_handles_underscores(self): - """Test that underscores are preserved.""" - result = get_collection_name("my_project", "my_table") - assert result == "my_project_my_table" - - -class TestMongoClientCreation: - """Test MongoDB client creation.""" - - @patch("feast.infra.utils.mongodb.connection_utils.MongoClient") - def test_get_mongo_client_default_params(self, mock_mongo_client): - """Test client creation with default parameters.""" - mock_client_instance = MagicMock() - mock_mongo_client.return_value = mock_client_instance - - connection_string = "mongodb://localhost:27017" - client = get_mongo_client(connection_string) - - # Verify MongoClient was called with correct parameters - mock_mongo_client.assert_called_once() - call_kwargs = mock_mongo_client.call_args[1] - - assert call_kwargs["maxPoolSize"] == 50 - assert call_kwargs["minPoolSize"] == 10 - assert call_kwargs["w"] == 1 - - # Verify ping was called to test connection - mock_client_instance.admin.command.assert_called_once_with("ping") - - @patch("feast.infra.utils.mongodb.connection_utils.MongoClient") - def test_get_mongo_client_custom_params(self, mock_mongo_client): - """Test client creation with custom parameters.""" - mock_client_instance = MagicMock() - mock_mongo_client.return_value = mock_client_instance - - connection_string = "mongodb://localhost:27017" - client = get_mongo_client( - connection_string, - max_pool_size=100, - min_pool_size=20, - write_concern_w=2, - read_preference="primary", - ) - - # Verify MongoClient was called with custom parameters - mock_mongo_client.assert_called_once() - call_kwargs = mock_mongo_client.call_args[1] - - assert call_kwargs["maxPoolSize"] == 100 - assert call_kwargs["minPoolSize"] == 20 - assert call_kwargs["w"] == 2 - assert call_kwargs["readPreference"] == ReadPreference.PRIMARY - - @patch("feast.infra.utils.mongodb.connection_utils.MongoClient") - def test_get_mongo_client_connection_failure(self, mock_mongo_client): - """Test that connection failures raise ConnectionError.""" - mock_client_instance = MagicMock() - mock_client_instance.admin.command.side_effect = Exception("Connection failed") - mock_mongo_client.return_value = mock_client_instance - - connection_string = "mongodb://invalid:27017" - - with pytest.raises(ConnectionError, match="Failed to connect to MongoDB"): - get_mongo_client(connection_string) - - @patch("feast.infra.utils.mongodb.connection_utils.AsyncMongoClient") - def test_get_async_mongo_client(self, mock_async_mongo_client): - """Test async client creation.""" - mock_client_instance = MagicMock() - mock_async_mongo_client.return_value = mock_client_instance - - connection_string = "mongodb://localhost:27017" - client = get_async_mongo_client(connection_string) - - # Verify AsyncMongoClient was called - mock_async_mongo_client.assert_called_once() - call_kwargs = mock_async_mongo_client.call_args[1] - - assert call_kwargs["maxPoolSize"] == 50 - assert call_kwargs["minPoolSize"] == 10 - - @patch("feast.infra.utils.mongodb.connection_utils.AsyncMongoClient") - def test_get_async_mongo_client_connection_failure(self, mock_async_mongo_client): - """Test that async client creation failures raise ConnectionError.""" - mock_async_mongo_client.side_effect = Exception("Connection failed") - - connection_string = "mongodb://invalid:27017" - - with pytest.raises(ConnectionError, match="Failed to create async MongoDB client"): - get_async_mongo_client(connection_string) - - -class TestAtlasDetection: - """Test MongoDB Atlas detection.""" - - def test_is_atlas_with_enterprise_module(self): - """Test Atlas detection with enterprise module.""" - mock_client = MagicMock() - mock_client.admin.command.return_value = { - "version": "5.0.0", - "modules": ["enterprise"], - } - - result = is_atlas(mock_client) - assert result is True - - def test_is_atlas_with_atlas_in_build_info(self): - """Test Atlas detection with 'atlas' in build info.""" - mock_client = MagicMock() - mock_client.admin.command.return_value = { - "version": "5.0.0-atlas", - "modules": [], - } - - result = is_atlas(mock_client) - assert result is True - - def test_is_not_atlas(self): - """Test non-Atlas deployment detection.""" - mock_client = MagicMock() - mock_client.admin.command.return_value = { - "version": "5.0.0", - "modules": [], - } - - result = is_atlas(mock_client) - assert result is False - - def test_is_atlas_exception_handling(self): - """Test that exceptions in Atlas detection return False.""" - mock_client = MagicMock() - mock_client.admin.command.side_effect = Exception("Command failed") - - result = is_atlas(mock_client) - assert result is False - - @pytest.mark.asyncio - async def test_is_atlas_async(self): - """Test async Atlas detection.""" - from feast.infra.utils.mongodb.connection_utils import is_atlas_async - - mock_client = MagicMock() - mock_client.admin.command = MagicMock( - return_value={ - "version": "5.0.0", - "modules": ["enterprise"], - } - ) - - result = await is_atlas_async(mock_client) - assert result is True diff --git a/sdk/python/feast/repo_config.py b/sdk/python/feast/repo_config.py index 2ca2616bff1..f3be7852846 100644 --- a/sdk/python/feast/repo_config.py +++ b/sdk/python/feast/repo_config.py @@ -82,7 +82,7 @@ "qdrant": "feast.infra.online_stores.qdrant_online_store.qdrant.QdrantOnlineStore", "couchbase.online": "feast.infra.online_stores.couchbase_online_store.couchbase.CouchbaseOnlineStore", "milvus": "feast.infra.online_stores.milvus_online_store.milvus.MilvusOnlineStore", - "mongodb": "feast.infra.online_stores.mongodb_online_store.mongodb.MongoDBOnlineStore", + "mongodb": "feast.infra.online_stores.contrib.mongodb_online_store.MongoDBOnlineStore", "hybrid": "feast.infra.online_stores.hybrid_online_store.hybrid_online_store.HybridOnlineStore", **LEGACY_ONLINE_STORE_CLASS_FOR_TYPE, } @@ -102,7 +102,6 @@ "remote": "feast.infra.offline_stores.remote.RemoteOfflineStore", "couchbase.offline": "feast.infra.offline_stores.contrib.couchbase_offline_store.couchbase.CouchbaseColumnarOfflineStore", "clickhouse": "feast.infra.offline_stores.contrib.clickhouse_offline_store.clickhouse.ClickhouseOfflineStore", - "mongodb.offline": "feast.infra.offline_stores.contrib.mongodb_offline_store.mongodb.MongoDBOfflineStore", "ray": "feast.infra.offline_stores.contrib.ray_offline_store.ray.RayOfflineStore", } diff --git a/sdk/python/tests/utils/cli_repo_creator.py b/sdk/python/tests/utils/cli_repo_creator.py index 554c5af99f2..8844908260b 100644 --- a/sdk/python/tests/utils/cli_repo_creator.py +++ b/sdk/python/tests/utils/cli_repo_creator.py @@ -148,6 +148,19 @@ def local_repo( entity_key_serialization_version: 3 """ ) + elif online_store: + yaml_config = dedent( + f""" + project: {project_id} + registry: {data_path / "registry.db"} + provider: local + online_store: + type: {online_store} + offline_store: + type: {offline_store} + entity_key_serialization_version: 3 + """ + ) else: pass From a6db5c7727ab283ed3957e2dd61e805c7ad22d3a Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Thu, 19 Feb 2026 08:36:10 -0500 Subject: [PATCH 07/47] Formatting Signed-off-by: Casey Clements --- .../contrib/mongodb_online_store/__init__.py | 2 +- .../contrib/mongodb_online_store/mongodb.py | 79 +------------------ .../tests/test_online_retrieval.py | 9 --- .../tests/test_online_writes.py | 1 - 4 files changed, 5 insertions(+), 86 deletions(-) diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/__init__.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/__init__.py index 52d2c11f159..84b2dfd763e 100644 --- a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/__init__.py +++ b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/__init__.py @@ -1,3 +1,3 @@ from .mongodb import MongoDBOnlineStore, MongoDBOnlineStoreConfig -__all__ = ["MongoDBOnlineStore", "MongoDBOnlineStoreConfig"] \ No newline at end of file +__all__ = ["MongoDBOnlineStore", "MongoDBOnlineStoreConfig"] diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py index 4dda67fb36b..9bbc43c018b 100644 --- a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py +++ b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py @@ -14,8 +14,10 @@ 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.type_map import python_values_to_proto_values, feast_value_type_to_python_type - +from feast.type_map import ( + feast_value_type_to_python_type, + python_values_to_proto_values, +) logger = logging.getLogger(__name__) @@ -165,79 +167,6 @@ def online_read( results.append((ts, features_proto)) return results - # todo v inefficient: the method below must infer types. additionally we're iterating over rows - # feature.dtype is held in table.feature.dtype. - """ - Feast’s online read is row-oriented in output, but type conversion is naturally column-oriented. - Instead of: - For each entity → convert each feature individually - You should: - 1. Gather values for a single feature across all entities. - 2. Convert them in one call. - 3. Then reassemble row-wise. - - Efficient Pattern - Assume: - • ids is ordered - • requested_features is defined (handle case) - • docs is your _id -> doc mapping - Step 1: Extract raw values column-wise - - - # Step 1: Extract raw values column-wise # (aligned by ordered ids column-wise) - raw_feature_columns = {feature: [] for feature in requested_features} - - for entity_id in ids: - doc = docs.get(entity_id) - feature_dict = ( - doc.get("features", {}).get(table.name, {}) - if doc else {} - ) - - for feature in requested_features: - raw_feature_columns[feature].append( - feature_dict.get(feature) - ) - - # Step 2: Convert per feature - # You need feature types. We can get these from the table! - # The following will map feature.name to its value type. This is across columns - # features_raw contains the columns for a single row (entity) - # feature_type_map is done outside the entity loop - feature_type_map = { - feature.name: feature.dtype.to_value_type() - for feature in table.features - } - proto_feature_columns = {} - for feature_name, raw_values in raw_feature_columns.items(): - proto_feature_columns[feature_name] = python_values_to_proto_values( - raw_values, - feature_type=feature_type_map[feature_name], - ) - - # Step 3: Reassemble row-wise - results = [] - - for i, entity_id in enumerate(ids): - doc = docs.get(entity_id) - - if doc is None: - results.append((None, None)) - continue - - ts = doc.get("event_timestamps", {}).get(table.name) - - row_features = { - feature_name: proto_feature_columns[feature_name][i] - for feature_name in requested_features - } - - results.append((ts, row_features)) - - return results - """ - # ------------------------------------------------------------------ - def update( self, config: RepoConfig, diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py index b481263ae7d..9df1eeb2e2e 100644 --- a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py +++ b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py @@ -1,25 +1,16 @@ import os -import platform -import random -import sqlite3 -import sys import time -from typing import Any -import numpy as np import pandas as pd import pytest -import sqlite_vec from pandas.testing import assert_frame_equal from feast import FeatureStore, RepoConfig from feast.errors import FeatureViewNotFoundException from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto -from feast.protos.feast.types.Value_pb2 import FloatList as FloatListProto from feast.protos.feast.types.Value_pb2 import Value as ValueProto from feast.repo_config import RegistryConfig from feast.torch_wrapper import get_torch -from feast.types import ValueType from feast.utils import _utc_now from tests.integration.feature_repos.universal.feature_views import TAGS from tests.utils.cli_repo_creator import CliRunner, get_example_repo diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py index 00120531f98..6cf9de82b0c 100644 --- a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py +++ b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py @@ -36,7 +36,6 @@ from feast.infra.online_stores.contrib.mongodb_online_store.mongodb import ( MongoDBOnlineStoreConfig, ) -from feast.infra.online_stores.sqlite import SqliteOnlineStoreConfig from feast.on_demand_feature_view import on_demand_feature_view from feast.types import Array, Float32, Float64, Int64, PdfBytes, String, ValueType from tests.utils.test_wrappers import check_warnings From 9ed89f0a2fcaef039261fa8021cf3266b77f91cc Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Thu, 19 Feb 2026 15:36:58 -0500 Subject: [PATCH 08/47] Refactor online_read that converts bson to proto. Left two methods for now. simply and transformming Signed-off-by: Casey Clements --- .../contrib/mongodb_online_store/mongodb.py | 154 ++++++++++++++---- 1 file changed, 126 insertions(+), 28 deletions(-) diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py index 9bbc43c018b..f4f7c7939b2 100644 --- a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py +++ b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py @@ -1,7 +1,8 @@ from __future__ import annotations -import logging +from collections import defaultdict from datetime import datetime +from logging import getLogger from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple from pymongo import MongoClient, UpdateOne @@ -19,7 +20,8 @@ python_values_to_proto_values, ) -logger = logging.getLogger(__name__) +logger = getLogger(__name__) + class MongoDBOnlineStoreConfig(FeastConfigBaseModel): """MongoDB configuration. @@ -29,11 +31,14 @@ class MongoDBOnlineStoreConfig(FeastConfigBaseModel): """ type: Literal[ - "mongodb", "feast.infra.online_stores.mongodb_online_store.mongodb.MongoDBOnlineStore" + "mongodb", + "feast.infra.online_stores.mongodb_online_store.mongodb.MongoDBOnlineStore", ] = "mongodb" """Online store type selector""" connection_string: str = "mongodb://localhost:27017" - database_name: str = "features" # todo - consider removing, and using repo_config.project + database_name: str = ( + "features" # todo - consider removing, and using repo_config.project + ) collection_suffix: str = "latest" client_kwargs: Dict[str, Any] = {} @@ -74,7 +79,9 @@ def online_write_batch( self, config: RepoConfig, table: FeatureView, - data: List[Tuple[EntityKeyProto, Dict[str, ValueProto], datetime, Optional[datetime]]], + data: List[ + Tuple[EntityKeyProto, Dict[str, ValueProto], datetime, Optional[datetime]] + ], progress: Optional[Callable[[int], Any]] = None, ) -> None: """ @@ -143,29 +150,16 @@ def online_read( f"event_timestamps.{table.name}": 1, } if requested_features: - projection.update({f"features.{table.name}.{x}": 1 for x in requested_features}) + projection.update( + {f"features.{table.name}.{x}": 1 for x in requested_features} + ) else: projection[f"features.{table.name}"] = 1 cursor = clxn.find(query_filter, projection=projection) docs = {doc["_id"]: doc for doc in cursor} - # Order and format output - results: List[Optional[Dict[str, ValueProto]]] = [] - for entity_id in ids: - doc = docs.get(entity_id) - if doc is None: - results.append((None, None)) - continue - - # Extract timestamp - ts = doc.get("event_timestamps", {}).get(table.name) - # Extract features - features_raw = doc.get("features", {}).get(table.name, {}) - - features_proto = {k: python_values_to_proto_values([v])[0] for k, v in features_raw.items()} # todo refactor: v inefficient - results.append((ts, features_proto)) - return results + return self.convert_raw_docs_to_proto_transforming(ids, docs, table) def update( self, @@ -208,11 +202,12 @@ def update( # Delete specific entities if entities_to_delete: - logger.warning(f"CHECK FORM. Can we call to_proto()?: {entities_to_delete = }") + logger.warning( + f"CHECK FORM. Can we call to_proto()?: {entities_to_delete = }" + ) ids = [serialize_entity_key(e.to_proto()) for e in entities_to_delete] clxn.delete_many({"_id": {"$in": ids}}) - def teardown( self, config: RepoConfig, @@ -229,7 +224,6 @@ def teardown( clxn.drop() self._get_client(config).close() - # ------------------------------------------------------------------ # Helpers # ------------------------------------------------------------------ @@ -238,12 +232,18 @@ def _get_client(self, config: RepoConfig): """Returns a connection to the server.""" online_store_config = config.online_store if not isinstance(online_store_config, MongoDBOnlineStoreConfig): - raise ValueError(f"config.online_store should be MongoDBOnlineStoreConfig, got {online_store_config}") + raise ValueError( + f"config.online_store should be MongoDBOnlineStoreConfig, got {online_store_config}" + ) if self._client is None: online_config = config.online_store if not isinstance(online_config, MongoDBOnlineStoreConfig): - logger.warning(f"config.online_store passed to _get_client is not a MongoDBOnlineStoreConfig. It's of type {type(online_config)}") - self._client = MongoClient(online_config.connection_string, **online_config.client_kwargs) + logger.warning( + f"config.online_store passed to _get_client is not a MongoDBOnlineStoreConfig. It's of type {type(online_config)}" + ) + self._client = MongoClient( + online_config.connection_string, **online_config.client_kwargs + ) return self._client def _get_collection(self, repo_config: RepoConfig) -> Collection: @@ -258,5 +258,103 @@ def _get_collection(self, repo_config: RepoConfig) -> Collection: self._collection = db[clxn_name] return self._collection + @staticmethod + def convert_raw_docs_to_proto_simply( + ids: list[bytes], + docs: dict[str, Any], + table: FeatureView, + requested_features: Optional[List[str]] = None, + ) -> List[Tuple[Optional[datetime], Optional[dict[str, ValueProto]]]]: + """Convert values in documents retrieved from MongoDB (BSON) into ValueProto types. + + The table, a FeatureView, provides a map from feature name to proto type. + ids is a sorted list of the serialized entity ids used in MongoDBOnlineStore. + + The heavy lifting is done in feast.type_map.python_values_to_proto_values. + It is intended to take a list of proto values with a single type (i.e. a column). + + In this method, we simply iterate over ids, calling this method each time. + It is naive, but straightforward. + """ + feature_type_map = { + feature.name: feature.dtype.to_value_type() for feature in table.features + } + + results: List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]] = [] + for entity_id in ids: + doc = docs.get(entity_id) + if doc is None: + results.append((None, None)) + continue + + # Extract timestamp + ts = doc.get("event_timestamps", {}).get(table.name) + + # Extract features + features_raw = doc.get("features", {}).get(table.name, {}) + features_proto = { + k: python_values_to_proto_values([v], feature_type_map[k])[0] + for k, v in features_raw.items() + } + + results.append((ts, features_proto)) + + @staticmethod + def convert_raw_docs_to_proto_transforming( + ids: list[bytes], docs: dict[str, Any], table: FeatureView + ) -> List[Tuple[Optional[datetime], Optional[dict[str, ValueProto]]]]: + """Convert values in documents retrieved from MongoDB (BSON) into ValueProto types. + + The table, a FeatureView, provides a map from feature name to proto type. + ids is a sorted list of the serialized entity ids used in MongoDBOnlineStore. + + The heavy lifting is done in feast.type_map.python_values_to_proto_values. + It is intended to take a list of proto values with a single type (i.e. a column). + + In this method, we simply iterate over ids, calling this method each time. + It is naive, but straightforward. + """ + feature_type_map = { + feature.name: feature.dtype.to_value_type() for feature in table.features + } + + # Step 1: Extract raw values column-wise # (aligned by ordered ids column-wise) + raw_feature_columns = defaultdict(list) + for entity_id in ids: + doc = docs.get(entity_id) + feature_dict = doc.get("features", {}).get(table.name, {}) if doc else {} + + for feature, value in feature_dict.items(): + raw_feature_columns[feature].append(value) + + # Step 2: Convert per feature + proto_feature_columns = {} + for feature_name, raw_values in raw_feature_columns.items(): + proto_feature_columns[feature_name] = python_values_to_proto_values( + raw_values, + feature_type=feature_type_map[feature_name], + ) + + # Step 3: Reassemble row-wise + results = [] + + for i, entity_id in enumerate(ids): + doc = docs.get(entity_id) + + if doc is None: + results.append((None, None)) + continue + + ts = doc.get("event_timestamps", {}).get(table.name) + + row_features = { + feature_name: proto_feature_columns[feature_name][i] + for feature_name in proto_feature_columns + } + + results.append((ts, row_features)) + return results + + # TODO # - Implement async API From 40e5ea50eb3efaf9ad22f483d83aec99f29927ba Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Thu, 19 Feb 2026 16:16:43 -0500 Subject: [PATCH 09/47] Remove file added early during discovery Signed-off-by: Casey Clements --- .../infra/utils/mongodb/connection_utils.py | 228 ------------------ 1 file changed, 228 deletions(-) delete mode 100644 sdk/python/feast/infra/utils/mongodb/connection_utils.py diff --git a/sdk/python/feast/infra/utils/mongodb/connection_utils.py b/sdk/python/feast/infra/utils/mongodb/connection_utils.py deleted file mode 100644 index 88b54e2a783..00000000000 --- a/sdk/python/feast/infra/utils/mongodb/connection_utils.py +++ /dev/null @@ -1,228 +0,0 @@ -# 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. - -""" -MongoDB connection utilities for Feast. - -This module provides helper functions for creating and managing MongoDB connections -for both the online and offline stores. -""" - -import logging -from typing import Any, Union - -try: - from pymongo import AsyncMongoClient, MongoClient - from pymongo.read_preferences import ReadPreference -except ImportError as e: - from feast.errors import FeastExtrasDependencyImportError - - raise FeastExtrasDependencyImportError("mongodb", str(e)) - -logger = logging.getLogger(__name__) - - -def get_mongo_client( - connection_string: str, - max_pool_size: int = 50, - min_pool_size: int = 10, - write_concern_w: Union[int, str] = 1, - read_preference: str = "primaryPreferred", - **kwargs: Any, -) -> MongoClient: - """ - Create a synchronous MongoDB client with connection pooling. - - Args: - connection_string: MongoDB connection URI (mongodb:// or mongodb+srv://) - max_pool_size: Maximum number of connections in the pool - min_pool_size: Minimum number of connections in the pool - write_concern_w: Write concern level (1, 'majority', etc.) - read_preference: Read preference ('primary', 'primaryPreferred', 'secondary', etc.) - **kwargs: Additional keyword arguments to pass to MongoClient - - Returns: - MongoClient instance configured with connection pooling - - Raises: - ConnectionError: If connection to MongoDB fails - """ - read_pref = _parse_read_preference(read_preference) - - try: - client = MongoClient( - connection_string, - maxPoolSize=max_pool_size, - minPoolSize=min_pool_size, - w=write_concern_w, - readPreference=read_pref, - **kwargs, - ) - # Test the connection - client.admin.command("ping") - logger.info( - f"Successfully connected to MongoDB (pool size: {min_pool_size}-{max_pool_size})" - ) - return client - except Exception as e: - logger.error(f"Failed to connect to MongoDB: {e}") - raise ConnectionError(f"Failed to connect to MongoDB: {e}") from e - - -def get_async_mongo_client( - connection_string: str, - max_pool_size: int = 50, - min_pool_size: int = 10, - write_concern_w: Union[int, str] = 1, - read_preference: str = "primaryPreferred", - **kwargs: Any, -) -> AsyncMongoClient: - """ - Create an asynchronous MongoDB client with connection pooling. - - Args: - connection_string: MongoDB connection URI (mongodb:// or mongodb+srv://) - max_pool_size: Maximum number of connections in the pool - min_pool_size: Minimum number of connections in the pool - write_concern_w: Write concern level (1, 'majority', etc.) - read_preference: Read preference ('primary', 'primaryPreferred', 'secondary', etc.) - **kwargs: Additional keyword arguments to pass to AsyncMongoClient - - Returns: - AsyncMongoClient instance configured with connection pooling - - Raises: - ConnectionError: If connection to MongoDB fails - """ - read_pref = _parse_read_preference(read_preference) - - try: - client = AsyncMongoClient( - connection_string, - maxPoolSize=max_pool_size, - minPoolSize=min_pool_size, - w=write_concern_w, - readPreference=read_pref, - **kwargs, - ) - logger.info( - f"Async MongoDB client created (pool size: {min_pool_size}-{max_pool_size})" - ) - return client - except Exception as e: - logger.error(f"Failed to create async MongoDB client: {e}") - raise ConnectionError(f"Failed to create async MongoDB client: {e}") from e - - -def is_atlas(client: MongoClient) -> bool: - """ - Detect if the MongoDB client is connected to MongoDB Atlas. - - Args: - client: MongoDB client instance - - Returns: - True if connected to Atlas, False otherwise - """ - try: - build_info = client.admin.command("buildInfo") - modules = build_info.get("modules", []) - is_atlas_deployment = "enterprise" in modules or "atlas" in str( - build_info - ).lower() - logger.debug(f"Atlas detection: {is_atlas_deployment} (modules: {modules})") - return is_atlas_deployment - except Exception as e: - logger.warning(f"Failed to detect Atlas deployment: {e}") - return False - - -async def is_atlas_async(client: AsyncMongoClient) -> bool: - """ - Async version: Detect if the MongoDB client is connected to MongoDB Atlas. - - Args: - client: Async MongoDB client instance - - Returns: - True if connected to Atlas, False otherwise - """ - try: - build_info = await client.admin.command("buildInfo") - modules = build_info.get("modules", []) - is_atlas_deployment = "enterprise" in modules or "atlas" in str( - build_info - ).lower() - logger.debug(f"Atlas detection: {is_atlas_deployment} (modules: {modules})") - return is_atlas_deployment - except Exception as e: - logger.warning(f"Failed to detect Atlas deployment: {e}") - return False - - -def _parse_read_preference(read_preference: str) -> ReadPreference: - """ - Convert string read preference to PyMongo ReadPreference enum. - - Args: - read_preference: String representation of read preference - - Returns: - ReadPreference enum value - - Raises: - ValueError: If read_preference is not valid - """ - preference_map = { - "primary": ReadPreference.PRIMARY, - "primaryPreferred": ReadPreference.PRIMARY_PREFERRED, - "secondary": ReadPreference.SECONDARY, - "secondaryPreferred": ReadPreference.SECONDARY_PREFERRED, - "nearest": ReadPreference.NEAREST, - } - - if read_preference not in preference_map: - raise ValueError( - f"Invalid read preference: {read_preference}. " - f"Valid options: {list(preference_map.keys())}" - ) - - return preference_map[read_preference] - - -def get_collection_name(project: str, table_name: str) -> str: - """ - Generate a MongoDB collection name from Feast project and table name. - - Args: - project: Feast project name - table_name: Feature view or table name - - Returns: - Collection name in format: {project}_{table_name} - """ - # Sanitize names to ensure valid MongoDB collection names - # MongoDB collection names cannot contain: $ or null character - # and should not start with "system." - safe_project = project.replace("$", "_").replace("\x00", "") - safe_table = table_name.replace("$", "_").replace("\x00", "") - - return f"{safe_project}_{safe_table}" - -# TODO -# - Consider removing this so that we don't create anything inside utils -# - get_collection_name, though safe, could easily be done manually by the user's specification of project and table name. Unless $ is often in project names -# - is_atlas methods. Are these accurate? -# - all the kwargs passed to get_client_connection are not needed. Just put in `connection_string` -# - _parse_read_preference is unneeded From 67f2c99a28aad512795648b19d8bd00316bf12aa Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Thu, 19 Feb 2026 16:17:17 -0500 Subject: [PATCH 10/47] Formatting Signed-off-by: Casey Clements --- .../tests/test_online_retrieval.py | 4 ++-- .../mongodb_online_store/tests/test_online_writes.py | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py index 9df1eeb2e2e..f0b78a09851 100644 --- a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py +++ b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py @@ -26,7 +26,7 @@ def test_get_online_features() -> None: offline_store="file", online_store="mongodb", apply=True, - teardown=True + teardown=True, ) as store: # Write some data to two tables driver_locations_fv = store.get_feature_view(name="driver_locations") @@ -346,7 +346,7 @@ def test_online_to_df(): offline_store="file", online_store="mongodb", apply=True, - teardown=True + teardown=True, ) as store: # Write three tables to online store driver_locations_fv = store.get_feature_view(name="driver_locations") diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py index 6cf9de82b0c..ad731e4de4b 100644 --- a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py +++ b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py @@ -52,7 +52,7 @@ def setUp(self): entity_key_serialization_version=3, # online_store=SqliteOnlineStoreConfig(path=os.path.join(data_dir, "online.db")), # TODO Try this with MongoDBOnlineStoreConfig defaults - online_store = MongoDBOnlineStoreConfig() + online_store=MongoDBOnlineStoreConfig(), ) ) @@ -170,7 +170,7 @@ def setUp(self): registry=os.path.join(self.data_dir, "registry.db"), provider="local", entity_key_serialization_version=3, - online_store=MongoDBOnlineStoreConfig() + online_store=MongoDBOnlineStoreConfig(), # online_store=SqliteOnlineStoreConfig(path=os.path.join(self.data_dir, "online.db")), ) ) @@ -357,7 +357,11 @@ def test_mixed_dataframe_with_some_valid_features(self): "event_timestamp": [current_time] * 3, "created": [current_time] * 3, "conv_rate": [0.5, None, 0.7], # Mixed values - "acc_rate": [0.8, 0.9, None], # Mixed values # todo What behavior should this have? + "acc_rate": [ + 0.8, + 0.9, + None, + ], # Mixed values # todo What behavior should this have? "avg_daily_trips": [10, 12, 15], # All valid } ) @@ -560,7 +564,7 @@ def test_transform_on_write_pdf(self): registry=os.path.join(data_dir, "registry.db"), provider="local", entity_key_serialization_version=3, - online_store=MongoDBOnlineStoreConfig() + online_store=MongoDBOnlineStoreConfig(), # online_store=SqliteOnlineStoreConfig(path=os.path.join(self.data_dir, "online.db")), ) ) From 35b66f07e63a52a1018c5c75dc26adfdd3d74c6f Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Thu, 19 Feb 2026 20:44:59 -0500 Subject: [PATCH 11/47] Added version of test that uses testcontainers mongodb instead of assuming one is running Signed-off-by: Casey Clements --- .../contrib/mongodb_online_store/mongodb.py | 28 ++- .../mongodb_repo_configuration.py | 13 ++ .../test_mongodb_online_retrieval.py | 177 ++++++++++++++++++ .../universal/online_store/mongodb.py | 30 +++ 4 files changed, 238 insertions(+), 10 deletions(-) create mode 100644 sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb_repo_configuration.py create mode 100644 sdk/python/tests/unit/online_store/test_mongodb_online_retrieval.py create mode 100644 sdk/python/tests/universal/feature_repos/universal/online_store/mongodb.py diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py index f4f7c7939b2..6beb5c8c0c1 100644 --- a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py +++ b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py @@ -1,6 +1,5 @@ from __future__ import annotations -from collections import defaultdict from datetime import datetime from logging import getLogger from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple @@ -32,7 +31,7 @@ class MongoDBOnlineStoreConfig(FeastConfigBaseModel): type: Literal[ "mongodb", - "feast.infra.online_stores.mongodb_online_store.mongodb.MongoDBOnlineStore", + "feast.infra.online_stores.contrib.mongodb_online_store.mongodb.MongoDBOnlineStore", ] = "mongodb" """Online store type selector""" connection_string: str = "mongodb://localhost:27017" @@ -100,7 +99,10 @@ def online_write_batch( ops = [] for row in data: entity_key, proto_values, event_timestamp, created_timestamp = row - entity_id = serialize_entity_key(entity_key) + entity_id = serialize_entity_key( + entity_key, + entity_key_serialization_version=config.entity_key_serialization_version, + ) feature_updates = { f"features.{table.name}.{field}": feast_value_type_to_python_type(val) for field, val in proto_values.items() @@ -253,8 +255,6 @@ def _get_collection(self, repo_config: RepoConfig) -> Collection: online_config = repo_config.online_store db = self._client[online_config.database_name] clxn_name = f"{repo_config.project}_{online_config.collection_suffix}" - if clxn_name not in db.list_collection_names(): - self._collection = db.create_collection(clxn_name) self._collection = db[clxn_name] return self._collection @@ -297,7 +297,9 @@ def convert_raw_docs_to_proto_simply( for k, v in features_raw.items() } - results.append((ts, features_proto)) + results.append((ts, features_proto)) + + return results @staticmethod def convert_raw_docs_to_proto_transforming( @@ -318,14 +320,19 @@ def convert_raw_docs_to_proto_transforming( feature.name: feature.dtype.to_value_type() for feature in table.features } - # Step 1: Extract raw values column-wise # (aligned by ordered ids column-wise) - raw_feature_columns = defaultdict(list) + # Step 1: Extract raw values column-wise (aligned by ordered ids) + # We need to maintain alignment, so we append None for missing features + raw_feature_columns = {feature_name: [] for feature_name in feature_type_map} + for entity_id in ids: doc = docs.get(entity_id) feature_dict = doc.get("features", {}).get(table.name, {}) if doc else {} - for feature, value in feature_dict.items(): - raw_feature_columns[feature].append(value) + # For each expected feature, append its value or None + for feature_name in feature_type_map: + raw_feature_columns[feature_name].append( + feature_dict.get(feature_name, None) + ) # Step 2: Convert per feature proto_feature_columns = {} @@ -358,3 +365,4 @@ def convert_raw_docs_to_proto_transforming( # TODO # - Implement async API +# - Vector Search diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb_repo_configuration.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb_repo_configuration.py new file mode 100644 index 00000000000..22c9f7eb51e --- /dev/null +++ b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb_repo_configuration.py @@ -0,0 +1,13 @@ +from tests.integration.feature_repos.integration_test_repo_config import ( + IntegrationTestRepoConfig, +) +from tests.integration.feature_repos.universal.online_store.mongodb import ( + MongoDBOnlineStoreCreator, +) + +FULL_REPO_CONFIGS = [ + IntegrationTestRepoConfig( + online_store="mongodb", + online_store_creator=MongoDBOnlineStoreCreator, + ), +] 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 new file mode 100644 index 00000000000..2ef981ebd00 --- /dev/null +++ b/sdk/python/tests/unit/online_store/test_mongodb_online_retrieval.py @@ -0,0 +1,177 @@ +""" +Unit tests for MongoDB online store using testcontainers. + +This test requires Docker to be running. It will be skipped if Docker is not available. +""" + +import pytest + +from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto +from feast.protos.feast.types.Value_pb2 import Value as ValueProto +from feast.utils import _utc_now +from tests.integration.feature_repos.universal.feature_views import TAGS +from tests.utils.cli_repo_creator import CliRunner, get_example_repo + +# Check if Docker is available +docker_available = False +try: + import docker + from testcontainers.mongodb import MongoDbContainer + + # Try to connect to Docker daemon + try: + client = docker.from_env() + client.ping() + docker_available = True + except Exception: + pass +except ImportError: + pass + +# Skip all tests in this module if Docker is not available +pytestmark = pytest.mark.skipif( + not docker_available, + reason="Docker is not available or not running. Start Docker daemon to run these tests.", +) + + +@pytest.fixture(scope="module") +def mongodb_container(): + """Start a MongoDB container for testing.""" + container = MongoDbContainer( + "mongo:latest", + username="test", + password="test", # pragma: allowlist secret + ).with_exposed_ports(27017) + container.start() + yield container + container.stop() + + +@pytest.fixture +def mongodb_connection_string(mongodb_container): + """Get MongoDB connection string from the container.""" + exposed_port = mongodb_container.get_exposed_port(27017) + return f"mongodb://test:test@localhost:{exposed_port}" # pragma: allowlist secret + + +def test_mongodb_online_features(mongodb_connection_string): + """ + Test reading from MongoDB online store using testcontainers. + """ + runner = CliRunner() + with ( + runner.local_repo( + get_example_repo("example_feature_repo_1.py"), + offline_store="file", + online_store="mongodb", + teardown=False, # Disable CLI teardown since container will be stopped by fixture + ) as store + ): + # Update the connection string to use the test container + store.config.online_store.connection_string = mongodb_connection_string + + # Write some data to two tables + driver_locations_fv = store.get_feature_view(name="driver_locations") + customer_profile_fv = store.get_feature_view(name="customer_profile") + customer_driver_combined_fv = store.get_feature_view( + name="customer_driver_combined" + ) + + provider = store._get_provider() + + driver_key = EntityKeyProto( + join_keys=["driver_id"], entity_values=[ValueProto(int64_val=1)] + ) + provider.online_write_batch( + config=store.config, + table=driver_locations_fv, + data=[ + ( + driver_key, + { + "lat": ValueProto(double_val=0.1), + "lon": ValueProto(string_val="1.0"), + }, + _utc_now(), + _utc_now(), + ) + ], + progress=None, + ) + + customer_key = EntityKeyProto( + join_keys=["customer_id"], entity_values=[ValueProto(string_val="5")] + ) + provider.online_write_batch( + config=store.config, + table=customer_profile_fv, + data=[ + ( + customer_key, + { + "avg_orders_day": ValueProto(float_val=1.0), + "name": ValueProto(string_val="John"), + "age": ValueProto(int64_val=3), + }, + _utc_now(), + _utc_now(), + ) + ], + progress=None, + ) + + customer_key = EntityKeyProto( + join_keys=["customer_id", "driver_id"], + entity_values=[ValueProto(string_val="5"), ValueProto(int64_val=1)], + ) + provider.online_write_batch( + config=store.config, + table=customer_driver_combined_fv, + data=[ + ( + customer_key, + {"trips": ValueProto(int64_val=7)}, + _utc_now(), + _utc_now(), + ) + ], + progress=None, + ) + + assert len(store.list_entities()) == 3 + assert len(store.list_entities(tags=TAGS)) == 2 + + # Retrieve features using two keys + result = store.get_online_features( + features=[ + "driver_locations:lon", + "customer_profile:avg_orders_day", + "customer_profile:name", + "customer_driver_combined:trips", + ], + entity_rows=[ + {"driver_id": 1, "customer_id": "5"}, + {"driver_id": 1, "customer_id": 5}, + ], + full_feature_names=False, + ).to_dict() + + assert "lon" in result + assert "avg_orders_day" in result + assert "name" in result + assert result["driver_id"] == [1, 1] + assert result["customer_id"] == ["5", "5"] + assert result["lon"] == ["1.0", "1.0"] + assert result["avg_orders_day"] == [1.0, 1.0] + assert result["name"] == ["John", "John"] + assert result["trips"] == [7, 7] + + # Ensure features are still in result when keys not found + result = store.get_online_features( + features=["customer_driver_combined:trips"], + entity_rows=[{"driver_id": 0, "customer_id": 0}], + full_feature_names=False, + ).to_dict() + + assert "trips" in result 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 new file mode 100644 index 00000000000..904c49eafaf --- /dev/null +++ b/sdk/python/tests/universal/feature_repos/universal/online_store/mongodb.py @@ -0,0 +1,30 @@ +from typing import Any, Dict + +from testcontainers.mongodb import MongoDbContainer +from tests.integration.feature_repos.universal.online_store_creator import ( + OnlineStoreCreator, +) + + +class MongoDBOnlineStoreCreator(OnlineStoreCreator): + def __init__(self, project_name: str, **kwargs): + super().__init__(project_name) + # MongoDbContainer from testcontainers sets up authentication by default + # with username and password from the constructor + self.container = MongoDbContainer( + "mongo:latest", + username="test", + password="test", # pragma: allowlist secret + ).with_exposed_ports(27017) + + def create_online_store(self) -> Dict[str, Any]: + self.container.start() + exposed_port = self.container.get_exposed_port(27017) + # Include authentication in the connection string + return { + "type": "mongodb", + "connection_string": f"mongodb://test:test@localhost:{exposed_port}", # pragma: allowlist secret + } + + def teardown(self): + self.container.stop() From a526a0c7561dfe5244035fbbad5d0632b5a4f78c Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Thu, 19 Feb 2026 21:24:03 -0500 Subject: [PATCH 12/47] Create Make target for universal tests Signed-off-by: Casey Clements --- Makefile | 19 +++++++++++++++++++ .../unit/online_store/test_online_writes.py | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3e0fbce6f6d..ec50d97209e 100644 --- a/Makefile +++ b/Makefile @@ -535,6 +535,25 @@ test-python-universal-elasticsearch-online: ## Run Python Elasticsearch online s not test_snowflake" \ sdk/python/tests +test-python-universal-mongodb-online: ## Run Python MongoDB online store integration tests + PYTHONPATH='.' \ + FULL_REPO_CONFIGS_MODULE=sdk.python.feast.infra.online_stores.contrib.mongodb_online_store.mongodb_repo_configuration \ + PYTEST_PLUGINS=sdk.python.tests.integration.feature_repos.universal.online_store.mongodb \ + python -m pytest -n 8 --integration \ + -k "not test_universal_cli and \ + not test_go_feature_server and \ + not test_feature_logging and \ + not test_reorder_columns and \ + not test_logged_features_validation and \ + not test_lambda_materialization_consistency and \ + not test_offline_write and \ + not test_push_features_to_offline_store and \ + not gcs_registry and \ + not s3_registry and \ + not test_universal_types and \ + not test_snowflake" \ + sdk/python/tests + test-python-universal-milvus-online: ## Run Python Milvus online store integration tests PYTHONPATH='.' \ FULL_REPO_CONFIGS_MODULE=sdk.python.feast.infra.online_stores.milvus_online_store.milvus_repo_configuration \ diff --git a/sdk/python/tests/unit/online_store/test_online_writes.py b/sdk/python/tests/unit/online_store/test_online_writes.py index 52ac3885f1a..c531c594670 100644 --- a/sdk/python/tests/unit/online_store/test_online_writes.py +++ b/sdk/python/tests/unit/online_store/test_online_writes.py @@ -33,7 +33,7 @@ ) from feast.driver_test_data import create_driver_hourly_stats_df from feast.field import Field -from feast.infra.online_stores.mongodb_online_store.mongodb_openai import ( +from feast.infra.online_stores.contrib.mongodb_online_store.mongodb import ( MongoDBOnlineStoreConfig, ) from feast.infra.online_stores.sqlite import SqliteOnlineStoreConfig From b0d57f58bea98fe29b34f8858f85bca4e27d640e Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Fri, 20 Feb 2026 10:12:20 -0500 Subject: [PATCH 13/47] Cleanup Signed-off-by: Casey Clements --- sdk/python/feast/infra/utils/mongodb/__init__.py | 1 - sdk/python/tests/unit/online_store/test_online_writes.py | 6 +++--- sdk/python/tests/utils/cli_repo_creator.py | 2 +- test_registry | 1 - 4 files changed, 4 insertions(+), 6 deletions(-) delete mode 100644 sdk/python/feast/infra/utils/mongodb/__init__.py delete mode 100644 test_registry diff --git a/sdk/python/feast/infra/utils/mongodb/__init__.py b/sdk/python/feast/infra/utils/mongodb/__init__.py deleted file mode 100644 index 327a4330cb7..00000000000 --- a/sdk/python/feast/infra/utils/mongodb/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# MongoDB utilities for Feast diff --git a/sdk/python/tests/unit/online_store/test_online_writes.py b/sdk/python/tests/unit/online_store/test_online_writes.py index c531c594670..542caed3afc 100644 --- a/sdk/python/tests/unit/online_store/test_online_writes.py +++ b/sdk/python/tests/unit/online_store/test_online_writes.py @@ -51,9 +51,9 @@ def setUp(self): registry=os.path.join(data_dir, "registry.db"), provider="local", entity_key_serialization_version=3, - # online_store=SqliteOnlineStoreConfig(path=os.path.join(data_dir, "online.db")), - # TODO Try this with MongoDBOnlineStoreConfig defaults - online_store = MongoDBOnlineStoreConfig() + online_store=SqliteOnlineStoreConfig( + path=os.path.join(data_dir, "online.db") + ), ) ) diff --git a/sdk/python/tests/utils/cli_repo_creator.py b/sdk/python/tests/utils/cli_repo_creator.py index 8844908260b..3aa96768f61 100644 --- a/sdk/python/tests/utils/cli_repo_creator.py +++ b/sdk/python/tests/utils/cli_repo_creator.py @@ -148,7 +148,7 @@ def local_repo( entity_key_serialization_version: 3 """ ) - elif online_store: + elif online_store: # Added for mongodb, but very general yaml_config = dedent( f""" project: {project_id} diff --git a/test_registry b/test_registry deleted file mode 100644 index 9757347d5b4..00000000000 --- a/test_registry +++ /dev/null @@ -1 +0,0 @@ -1"$558ef025-a9ab-4dc8-9679-6fa37dd8320f* ôˆšË˜×³™ \ No newline at end of file From 5a94a11c9f570e5f0d5212daae0bb2cf92df3855 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Fri, 20 Feb 2026 13:24:50 -0500 Subject: [PATCH 14/47] Removed temporary integration tests requiring one to spin up own mongodb server. Signed-off-by: Casey Clements --- .../tests/test_online_retrieval.py | 486 -------------- .../tests/test_online_writes.py | 635 ------------------ 2 files changed, 1121 deletions(-) delete mode 100644 sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py delete mode 100644 sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py deleted file mode 100644 index f0b78a09851..00000000000 --- a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_retrieval.py +++ /dev/null @@ -1,486 +0,0 @@ -import os -import time - -import pandas as pd -import pytest -from pandas.testing import assert_frame_equal - -from feast import FeatureStore, RepoConfig -from feast.errors import FeatureViewNotFoundException -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 -from feast.torch_wrapper import get_torch -from feast.utils import _utc_now -from tests.integration.feature_repos.universal.feature_views import TAGS -from tests.utils.cli_repo_creator import CliRunner, get_example_repo - - -def test_get_online_features() -> None: - """ - Test reading from the online store in local mode. - """ - runner = CliRunner() - with runner.local_repo( - example_repo_py=get_example_repo("example_feature_repo_1.py"), - offline_store="file", - online_store="mongodb", - apply=True, - teardown=True, - ) as store: - # Write some data to two tables - driver_locations_fv = store.get_feature_view(name="driver_locations") - customer_profile_fv = store.get_feature_view(name="customer_profile") - customer_driver_combined_fv = store.get_feature_view( - name="customer_driver_combined" - ) - - provider = store._get_provider() - - driver_key = EntityKeyProto( - join_keys=["driver_id"], entity_values=[ValueProto(int64_val=1)] - ) - provider.online_write_batch( - config=store.config, - table=driver_locations_fv, - data=[ - ( - driver_key, - { - "lat": ValueProto(double_val=0.1), - "lon": ValueProto(string_val="1.0"), - }, - _utc_now(), - _utc_now(), - ) - ], - progress=None, - ) - - customer_key = EntityKeyProto( - join_keys=["customer_id"], entity_values=[ValueProto(string_val="5")] - ) - provider.online_write_batch( - config=store.config, - table=customer_profile_fv, - data=[ - ( - customer_key, - { - "avg_orders_day": ValueProto(float_val=1.0), - "name": ValueProto(string_val="John"), - "age": ValueProto(int64_val=3), - }, - _utc_now(), - _utc_now(), - ) - ], - progress=None, - ) - - customer_key = EntityKeyProto( - join_keys=["customer_id", "driver_id"], - entity_values=[ValueProto(string_val="5"), ValueProto(int64_val=1)], - ) - provider.online_write_batch( - config=store.config, - table=customer_driver_combined_fv, - data=[ - ( - customer_key, - {"trips": ValueProto(int64_val=7)}, - _utc_now(), - _utc_now(), - ) - ], - progress=None, - ) - - assert len(store.list_entities()) == 3 - assert len(store.list_entities(tags=TAGS)) == 2 - - # Retrieve two features using two keys, one valid one non-existing - result = store.get_online_features( - features=[ - "driver_locations:lon", - "customer_profile:avg_orders_day", - "customer_profile:name", - "customer_driver_combined:trips", - ], - entity_rows=[ - {"driver_id": 1, "customer_id": "5"}, - {"driver_id": 1, "customer_id": 5}, - ], - full_feature_names=False, - ).to_dict() - - assert "lon" in result - assert "avg_orders_day" in result - assert "name" in result - assert result["driver_id"] == [1, 1] - assert result["customer_id"] == ["5", "5"] - assert result["lon"] == ["1.0", "1.0"] - assert result["avg_orders_day"] == [1.0, 1.0] - assert result["name"] == ["John", "John"] - assert result["trips"] == [7, 7] - - tensor_result = store.get_online_features( - features=[ - "driver_locations:lon", - "customer_profile:avg_orders_day", - "customer_profile:name", - "customer_driver_combined:trips", - ], - entity_rows=[ - {"driver_id": 1, "customer_id": "5"}, - {"driver_id": 1, "customer_id": 5}, - ], - full_feature_names=False, - ).to_tensor() - - assert "lon" in tensor_result - assert "avg_orders_day" in tensor_result - assert "name" in tensor_result - assert "trips" in tensor_result - # Entity values - torch = get_torch() - device = "cuda" if torch.cuda.is_available() else "cpu" - assert torch.equal( - tensor_result["driver_id"], torch.tensor([1, 1], device=device) - ) - assert tensor_result["customer_id"] == ["5", "5"] - - # Feature values - assert tensor_result["lon"] == ["1.0", "1.0"] # String -> not tensor - assert torch.equal(tensor_result["avg_orders_day"], torch.tensor([1.0, 1.0])) - assert tensor_result["name"] == ["John", "John"] - assert torch.equal(tensor_result["trips"], torch.tensor([7, 7], device=device)) - - # Ensure features are still in result when keys not found - result = store.get_online_features( - features=["customer_driver_combined:trips"], - entity_rows=[{"driver_id": 0, "customer_id": 0}], - full_feature_names=False, - ).to_dict() - - assert "trips" in result - - result = store.get_online_features( - features=["customer_driver_combined:trips"], - entity_rows=[{"driver_id": 0, "customer_id": 0}], - full_feature_names=False, - ).to_tensor() - - assert "trips" in result - assert isinstance(result["trips"], torch.Tensor) - - with pytest.raises(KeyError) as excinfo: - _ = store.get_online_features( - features=["driver_locations:lon"], - entity_rows=[{"customer_id": 0}], - full_feature_names=False, - ).to_dict() - - error_message = str(excinfo.value) - assert "Missing join key values for keys:" in error_message - assert ( - "Missing join key values for keys: ['customer_id', 'driver_id', 'item_id']." - in error_message - ) - assert "Provided join_key_values: ['customer_id']" in error_message - - result = store.get_online_features( - features=["customer_profile_pandas_odfv:on_demand_age"], - entity_rows=[{"driver_id": 1, "customer_id": "5"}], - full_feature_names=False, - ).to_dict() - - assert "on_demand_age" in result - assert result["driver_id"] == [1] - assert result["customer_id"] == ["5"] - assert result["on_demand_age"] == [4] - - # invalid table reference - with pytest.raises(FeatureViewNotFoundException): - store.get_online_features( - features=["driver_locations_bad:lon"], - entity_rows=[{"driver_id": 1}], - full_feature_names=False, - ) - - # Create new FeatureStore object with fast cache invalidation - cache_ttl = 1 - fs_fast_ttl = FeatureStore( - config=RepoConfig( - registry=RegistryConfig( - path=store.config.registry.path, cache_ttl_seconds=cache_ttl - ), - online_store=store.config.online_store, - project=store.project, - provider=store.config.provider, - entity_key_serialization_version=3, - ) - ) - - # Should download the registry and cache it permanently (or until manually refreshed) - result = fs_fast_ttl.get_online_features( - features=[ - "driver_locations:lon", - "customer_profile:avg_orders_day", - "customer_profile:name", - "customer_driver_combined:trips", - ], - entity_rows=[{"driver_id": 1, "customer_id": 5}], - full_feature_names=False, - ).to_dict() - assert result["lon"] == ["1.0"] - assert result["trips"] == [7] - - # Rename the registry.db so that it cant be used for refreshes - os.rename(store.config.registry.path, store.config.registry.path + "_fake") - - # Wait for registry to expire - time.sleep(cache_ttl) - - # Will try to reload registry because it has expired (it will fail because we deleted the actual registry file) - with pytest.raises(FileNotFoundError): - fs_fast_ttl.get_online_features( - features=[ - "driver_locations:lon", - "customer_profile:avg_orders_day", - "customer_profile:name", - "customer_driver_combined:trips", - ], - entity_rows=[{"driver_id": 1, "customer_id": 5}], - full_feature_names=False, - ).to_dict() - - # Restore registry.db so that we can see if it actually reloads registry - os.rename(store.config.registry.path + "_fake", store.config.registry.path) - - # Test if registry is actually reloaded and whether results return - result = fs_fast_ttl.get_online_features( - features=[ - "driver_locations:lon", - "customer_profile:avg_orders_day", - "customer_profile:name", - "customer_driver_combined:trips", - ], - entity_rows=[{"driver_id": 1, "customer_id": 5}], - full_feature_names=False, - ).to_dict() - assert result["lon"] == ["1.0"] - assert result["trips"] == [7] - - # Create a registry with infinite cache (for users that want to manually refresh the registry) - fs_infinite_ttl = FeatureStore( - config=RepoConfig( - registry=RegistryConfig( - path=store.config.registry.path, cache_ttl_seconds=0 - ), - online_store=store.config.online_store, - project=store.project, - provider=store.config.provider, - entity_key_serialization_version=3, - ) - ) - - # Should return results (and fill the registry cache) - result = fs_infinite_ttl.get_online_features( - features=[ - "driver_locations:lon", - "customer_profile:avg_orders_day", - "customer_profile:name", - "customer_driver_combined:trips", - ], - entity_rows=[{"driver_id": 1, "customer_id": 5}], - full_feature_names=False, - ).to_dict() - assert result["lon"] == ["1.0"] - assert result["trips"] == [7] - - # Wait a bit so that an arbitrary TTL would take effect - time.sleep(2) - - # Rename the registry.db so that it cant be used for refreshes - os.rename(store.config.registry.path, store.config.registry.path + "_fake") - - # TTL is infinite so this method should use registry cache - result = fs_infinite_ttl.get_online_features( - features=[ - "driver_locations:lon", - "customer_profile:avg_orders_day", - "customer_profile:name", - "customer_driver_combined:trips", - ], - entity_rows=[{"driver_id": 1, "customer_id": 5}], - full_feature_names=False, - ).to_dict() - assert result["lon"] == ["1.0"] - assert result["trips"] == [7] - - # Force registry reload (should fail because file is missing) - with pytest.raises(FileNotFoundError): - fs_infinite_ttl.refresh_registry() - - # Restore registry.db so that teardown works - os.rename(store.config.registry.path + "_fake", store.config.registry.path) - - -def test_online_to_df(): - """ - Test dataframe conversion. Make sure the response columns and rows are - the same order as the request. - """ - driver_ids = [1, 2, 3] - customer_ids = [4, 5, 6] - name = "foo" - lon_multiply = 1.0 - lat_multiply = 0.1 - age_multiply = 10 - avg_order_day_multiply = 1.0 - - runner = CliRunner() - with runner.local_repo( - example_repo_py=get_example_repo("example_feature_repo_1.py"), - offline_store="file", - online_store="mongodb", - apply=True, - teardown=True, - ) as store: - # Write three tables to online store - driver_locations_fv = store.get_feature_view(name="driver_locations") - customer_profile_fv = store.get_feature_view(name="customer_profile") - customer_driver_combined_fv = store.get_feature_view( - name="customer_driver_combined" - ) - provider = store._get_provider() - - for d, c in zip(driver_ids, customer_ids): - """ - driver table: - lon lat - 1 1.0 0.1 - 2 2.0 0.2 - 3 3.0 0.3 - """ - driver_key = EntityKeyProto( - join_keys=["driver_id"], entity_values=[ValueProto(int64_val=d)] - ) - provider.online_write_batch( - config=store.config, - table=driver_locations_fv, - data=[ - ( - driver_key, - { - "lat": ValueProto(double_val=d * lat_multiply), - "lon": ValueProto(string_val=str(d * lon_multiply)), - }, - _utc_now(), - _utc_now(), - ) - ], - progress=None, - ) - - """ - customer table - customer avg_orders_day name age - 4 4.0 foo4 40 - 5 5.0 foo5 50 - 6 6.0 foo6 60 - """ - customer_key = EntityKeyProto( - join_keys=["customer_id"], entity_values=[ValueProto(string_val=str(c))] - ) - provider.online_write_batch( - config=store.config, - table=customer_profile_fv, - data=[ - ( - customer_key, - { - "avg_orders_day": ValueProto( - float_val=c * avg_order_day_multiply - ), - "name": ValueProto(string_val=name + str(c)), - "age": ValueProto(int64_val=c * age_multiply), - }, - _utc_now(), - _utc_now(), - ) - ], - progress=None, - ) - """ - customer_driver_combined table - customer driver trips - 4 1 4 - 5 2 10 - 6 3 18 - """ - combo_keys = EntityKeyProto( - join_keys=["customer_id", "driver_id"], - entity_values=[ValueProto(string_val=str(c)), ValueProto(int64_val=d)], - ) - provider.online_write_batch( - config=store.config, - table=customer_driver_combined_fv, - data=[ - ( - combo_keys, - {"trips": ValueProto(int64_val=c * d)}, - _utc_now(), - _utc_now(), - ) - ], - progress=None, - ) - - # Get online features in dataframe - result_df = store.get_online_features( - features=[ - "driver_locations:lon", - "driver_locations:lat", - "customer_profile:avg_orders_day", - "customer_profile:name", - "customer_profile:age", - "customer_driver_combined:trips", - ], - # Reverse the row order - entity_rows=[ - {"driver_id": d, "customer_id": c} - for (d, c) in zip(reversed(driver_ids), reversed(customer_ids)) - ], - ).to_df() - """ - Construct the expected dataframe with reversed row order like so: - driver customer lon lat avg_orders_day name age trips - 3 6 3.0 0.3 6.0 foo6 60 18 - 2 5 2.0 0.2 5.0 foo5 50 10 - 1 4 1.0 0.1 4.0 foo4 40 4 - """ - df_dict = { - "driver_id": driver_ids, - "customer_id": [str(c) for c in customer_ids], - "lon": [str(d * lon_multiply) for d in driver_ids], - "lat": [d * lat_multiply for d in driver_ids], - "avg_orders_day": [c * avg_order_day_multiply for c in customer_ids], - "name": [name + str(c) for c in customer_ids], - "age": [c * age_multiply for c in customer_ids], - "trips": [d * c for (d, c) in zip(driver_ids, customer_ids)], - } - # Requested column order - ordered_column = [ - "driver_id", - "customer_id", - "lon", - "lat", - "avg_orders_day", - "name", - "age", - "trips", - ] - expected_df = pd.DataFrame({k: reversed(v) for (k, v) in df_dict.items()}) - assert_frame_equal(result_df[ordered_column], expected_df) diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py deleted file mode 100644 index ad731e4de4b..00000000000 --- a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/tests/test_online_writes.py +++ /dev/null @@ -1,635 +0,0 @@ -# Copyright 2022 The Feast Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import asyncio -import os -import shutil -import tempfile -import unittest -from datetime import datetime, timedelta -from typing import Any - -import pandas as pd -import pytest - -from feast import ( - Entity, - FeatureStore, - FeatureView, - FileSource, - RepoConfig, - RequestSource, -) -from feast.driver_test_data import create_driver_hourly_stats_df -from feast.field import Field -from feast.infra.online_stores.contrib.mongodb_online_store.mongodb import ( - MongoDBOnlineStoreConfig, -) -from feast.on_demand_feature_view import on_demand_feature_view -from feast.types import Array, Float32, Float64, Int64, PdfBytes, String, ValueType -from tests.utils.test_wrappers import check_warnings - - -class TestOnlineWrites(unittest.TestCase): - def setUp(self): - with tempfile.TemporaryDirectory() as data_dir: - self.store = FeatureStore( - config=RepoConfig( - project="test_write_to_online_store", - registry=os.path.join(data_dir, "registry.db"), - provider="local", - entity_key_serialization_version=3, - # online_store=SqliteOnlineStoreConfig(path=os.path.join(data_dir, "online.db")), - # TODO Try this with MongoDBOnlineStoreConfig defaults - online_store=MongoDBOnlineStoreConfig(), - ) - ) - - # Generate test data. - end_date = datetime.now().replace(microsecond=0, second=0, minute=0) - start_date = end_date - timedelta(days=15) - - driver_entities = [1001, 1002, 1003, 1004, 1005] - driver_df = create_driver_hourly_stats_df( - driver_entities, start_date, end_date - ) - driver_stats_path = os.path.join(data_dir, "driver_stats.parquet") - driver_df.to_parquet( - path=driver_stats_path, allow_truncated_timestamps=True - ) - - driver = Entity(name="driver", join_keys=["driver_id"]) - - driver_stats_source = FileSource( - name="driver_hourly_stats_source", - path=driver_stats_path, - timestamp_field="event_timestamp", - created_timestamp_column="created", - ) - - driver_stats_fv = FeatureView( - name="driver_hourly_stats", - entities=[driver], - ttl=timedelta(days=0), - 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, - ) - # Before apply() join_keys is empty - assert driver_stats_fv.join_keys == [] - assert driver_stats_fv.entity_columns == [] - - @on_demand_feature_view( - sources=[driver_stats_fv[["conv_rate", "acc_rate"]]], - schema=[Field(name="conv_rate_plus_acc", dtype=Float64)], - mode="python", - ) - def test_view(inputs: dict[str, Any]) -> dict[str, Any]: - output: dict[str, Any] = { - "conv_rate_plus_acc": [ - conv_rate + acc_rate - for conv_rate, acc_rate in zip( - inputs["conv_rate"], inputs["acc_rate"] - ) - ] - } - return output - - self.store.apply( - [ - driver, - driver_stats_source, - driver_stats_fv, - test_view, - ] - ) - # after apply() join_keys is [driver] - assert driver_stats_fv.join_keys == [driver.join_key] - assert driver_stats_fv.entity_columns[0].name == driver.join_key - - self.store.write_to_online_store( - feature_view_name="driver_hourly_stats", df=driver_df - ) - # This will give the intuitive structure of the data as: - # {"driver_id": [..], "conv_rate": [..], "acc_rate": [..], "avg_daily_trips": [..]} - driver_dict = driver_df.to_dict(orient="list") - self.store.write_to_online_store( - feature_view_name="driver_hourly_stats", - inputs=driver_dict, - ) - - def test_online_retrieval(self): - entity_rows = [ - { - "driver_id": 1001, - } - ] - - online_python_response = self.store.get_online_features( - entity_rows=entity_rows, - features=[ - "driver_hourly_stats:conv_rate", - "driver_hourly_stats:acc_rate", - "test_view:conv_rate_plus_acc", - ], - ).to_dict() - - assert len(online_python_response) == 4 - assert all( - key in online_python_response.keys() - for key in [ - "driver_id", - "acc_rate", - "conv_rate", - "conv_rate_plus_acc", - ] - ) - - -class TestEmptyDataFrameValidation(unittest.TestCase): - def setUp(self): - self.data_dir = tempfile.mkdtemp() - self.store = FeatureStore( - config=RepoConfig( - project="test_empty_df_validation", - registry=os.path.join(self.data_dir, "registry.db"), - provider="local", - entity_key_serialization_version=3, - online_store=MongoDBOnlineStoreConfig(), - # online_store=SqliteOnlineStoreConfig(path=os.path.join(self.data_dir, "online.db")), - ) - ) - - # Generate test data for schema creation - end_date = datetime.now().replace(microsecond=0, second=0, minute=0) - start_date = end_date - timedelta(days=1) - - driver_entities = [1001] - driver_df = create_driver_hourly_stats_df(driver_entities, start_date, end_date) - driver_stats_path = os.path.join(self.data_dir, "driver_stats.parquet") - driver_df.to_parquet(path=driver_stats_path, allow_truncated_timestamps=True) - - driver = Entity(name="driver", join_keys=["driver_id"]) - - driver_stats_source = FileSource( - name="driver_hourly_stats_source", - path=driver_stats_path, - timestamp_field="event_timestamp", - created_timestamp_column="created", - ) - - driver_stats_fv = FeatureView( - name="driver_hourly_stats", - entities=[driver], - ttl=timedelta(days=0), - 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, - ) - - self.store.apply([driver, driver_stats_source, driver_stats_fv]) - - def tearDown(self): - shutil.rmtree(self.data_dir) - - @check_warnings( - expected_warnings=["Cannot write empty dataframe to online store"], - ) - def test_empty_dataframe_warns(self): - """Test that completely empty dataframe issues a warning instead of raising an error""" - empty_df = pd.DataFrame() - - self.store.write_to_online_store( - feature_view_name="driver_hourly_stats", df=empty_df - ) - - @check_warnings( - expected_warnings=["Cannot write empty dataframe to online store"], - ) - def test_empty_dataframe_async_warns(self): - """Test that completely empty dataframe issues a warning instead of raising an error in async version""" - - async def test_async_empty(): - empty_df = pd.DataFrame() - - await self.store.write_to_online_store_async( - feature_view_name="driver_hourly_stats", df=empty_df - ) - - asyncio.run(test_async_empty()) - - @check_warnings( - expected_warnings=[ - "Cannot write dataframe with empty feature columns to online store" - ], - ) - def test_dataframe_with_empty_feature_columns_warns(self): - """Test that dataframe with entity data but empty feature columns warns instead of raising error""" - current_time = pd.Timestamp.now() - df_with_entity_only = pd.DataFrame( - { - "driver_id": [1001, 1002, 1003], - "event_timestamp": [current_time] * 3, - "created": [current_time] * 3, - "conv_rate": [None, None, None], # All nulls - "acc_rate": [None, None, None], # All nulls - "avg_daily_trips": [None, None, None], # All nulls - } - ) - - self.store.write_to_online_store( - feature_view_name="driver_hourly_stats", df=df_with_entity_only - ) - - @check_warnings( - expected_warnings=[ - "Cannot write dataframe with empty feature columns to online store" - ], - ) - def test_dataframe_with_empty_feature_columns_async_warns(self): - """Test that dataframe with entity data but empty feature columns warns instead of raising error in async version""" - - async def test_async_empty_features(): - current_time = pd.Timestamp.now() - df_with_entity_only = pd.DataFrame( - { - "driver_id": [1001, 1002, 1003], - "event_timestamp": [current_time] * 3, - "created": [current_time] * 3, - "conv_rate": [None, None, None], - "acc_rate": [None, None, None], - "avg_daily_trips": [None, None, None], - } - ) - - await self.store.write_to_online_store_async( - feature_view_name="driver_hourly_stats", df=df_with_entity_only - ) - - asyncio.run(test_async_empty_features()) - - @check_warnings( - forbidden_warnings=[ - "Cannot write empty dataframe to online store", - "Cannot write dataframe with empty feature columns to online store", - ], - ) - def test_valid_dataframe(self): - """Test that valid dataframe with feature data succeeds""" - current_time = pd.Timestamp.now() - valid_df = pd.DataFrame( - { - "driver_id": [1001, 1002], - "event_timestamp": [current_time] * 2, - "created": [current_time] * 2, - "conv_rate": [0.5, 0.7], - "acc_rate": [0.8, 0.9], - "avg_daily_trips": [10, 12], - } - ) - - # This should not raise an exception or warnings - decorator handles warning validation - self.store.write_to_online_store( - feature_view_name="driver_hourly_stats", df=valid_df - ) - - @check_warnings( - forbidden_warnings=[ - "Cannot write empty dataframe to online store", - "Cannot write dataframe with empty feature columns to online store", - ], - ) - def test_valid_dataframe_async(self): - """Test that valid dataframe with feature data succeeds in async version""" - pytest.skip("Feature not implemented yet") - - async def test_async_valid(): - current_time = pd.Timestamp.now() - valid_df = pd.DataFrame( - { - "driver_id": [1001, 1002], - "event_timestamp": [current_time] * 2, - "created": [current_time] * 2, - "conv_rate": [0.5, 0.7], - "acc_rate": [0.8, 0.9], - "avg_daily_trips": [10, 12], - } - ) - - # This should not raise an exception or warnings - decorator handles warning validation - await self.store.write_to_online_store_async( - feature_view_name="driver_hourly_stats", df=valid_df - ) - - asyncio.run(test_async_valid()) - - @check_warnings( - forbidden_warnings=[ - "Cannot write empty dataframe to online store", - "Cannot write dataframe with empty feature columns to online store", - ], - ) - def test_mixed_dataframe_with_some_valid_features(self): - """Test that dataframe with some valid feature values succeeds""" - current_time = pd.Timestamp.now() - mixed_df = pd.DataFrame( - { - "driver_id": [1001, 1002, 1003], - "event_timestamp": [current_time] * 3, - "created": [current_time] * 3, - "conv_rate": [0.5, None, 0.7], # Mixed values - "acc_rate": [ - 0.8, - 0.9, - None, - ], # Mixed values # todo What behavior should this have? - "avg_daily_trips": [10, 12, 15], # All valid - } - ) - - # This should not raise an exception because not all feature values are null - decorator handles warning validation - self.store.write_to_online_store( - feature_view_name="driver_hourly_stats", df=mixed_df - ) - - @check_warnings( - expected_warnings=["Cannot write empty dataframe to online store"], - ) - def test_empty_inputs_dict_warns(self): - """Test that empty inputs dict warns instead of raising error""" - empty_inputs = { - "driver_id": [], - "conv_rate": [], - "acc_rate": [], - "avg_daily_trips": [], - } - - self.store.write_to_online_store( - feature_view_name="driver_hourly_stats", inputs=empty_inputs - ) - - @check_warnings( - expected_warnings=[ - "Cannot write dataframe with empty feature columns to online store" - ], - ) - def test_inputs_dict_with_empty_features_warns(self): - """Test that inputs dict with empty feature values warns instead of raising error""" - current_time = pd.Timestamp.now() - empty_feature_inputs = { - "driver_id": [1001, 1002, 1003], - "event_timestamp": [current_time] * 3, - "created": [current_time] * 3, - "conv_rate": [None, None, None], - "acc_rate": [None, None, None], - "avg_daily_trips": [None, None, None], - } - - self.store.write_to_online_store( - feature_view_name="driver_hourly_stats", inputs=empty_feature_inputs - ) - - @check_warnings( - forbidden_warnings=[ - "Cannot write empty dataframe to online store", - "Cannot write dataframe with empty feature columns to online store", - ], - ) - def test_multiple_feature_views_materialization_with_empty_data(self): - """Test materializing multiple feature views where one has empty data - should not break materialization""" - import tempfile - from datetime import timedelta - - with tempfile.TemporaryDirectory() as data_dir: - # Create a new store for this test - test_store = FeatureStore( - config=RepoConfig( - project="test_multiple_fv_materialization", - registry=os.path.join(data_dir, "registry.db"), - provider="local", - entity_key_serialization_version=3, - # online_store=SqliteOnlineStoreConfig(path=os.path.join(data_dir, "online.db")), - online_store=MongoDBOnlineStoreConfig(), - ) - ) - - # Create entities - driver = Entity(name="driver", join_keys=["driver_id"]) - customer = Entity(name="customer", join_keys=["customer_id"]) - - # Create 5 feature views with data - current_time = pd.Timestamp.now().replace(microsecond=0) - start_date = current_time - timedelta(hours=2) - end_date = current_time - timedelta(minutes=10) - feature_views = [] - dataframes = [] - offline_paths = [] - - for i in range(5): - # Create file path for offline data - offline_path = os.path.join(data_dir, f"feature_view_{i + 1}.parquet") - offline_paths.append(offline_path) - - # Create feature view with real file source - fv = FeatureView( - name=f"feature_view_{i + 1}", - entities=[driver if i % 2 == 0 else customer], - ttl=timedelta(days=1), - schema=[ - Field(name=f"feature_{i + 1}_rate", dtype=Float32), - Field(name=f"feature_{i + 1}_count", dtype=Int64), - ], - online=True, - source=FileSource( - name=f"source_{i + 1}", - path=offline_path, - timestamp_field="event_timestamp", - created_timestamp_column="created", - ), - ) - feature_views.append(fv) - - # Create data - make 2nd feature view (index 1) empty - if i == 1: # 2nd feature view gets empty data - df = pd.DataFrame() # Empty dataframe - else: - # Create valid data for other feature views - entity_key = "driver_id" if i % 2 == 0 else "customer_id" - df = pd.DataFrame( - { - entity_key: [1000 + j for j in range(3)], - "event_timestamp": [ - start_date + timedelta(minutes=j * 10) for j in range(3) - ], - "created": [current_time] * 3, - f"feature_{i + 1}_rate": [0.5 + j * 0.1 for j in range(3)], - f"feature_{i + 1}_count": [10 + j for j in range(3)], - } - ) - - # Write data to offline store (parquet files) - offline store allows empty dataframes - if len(df) > 0: - df.to_parquet(offline_path, allow_truncated_timestamps=True) - else: - # Create empty parquet file with correct schema (timezone-aware timestamps) - entity_key = "driver_id" if i % 2 == 0 else "customer_id" - empty_schema_df = pd.DataFrame( - { - entity_key: pd.Series([], dtype="int64"), - "event_timestamp": pd.Series( - [], dtype="datetime64[ns, UTC]" - ), # Timezone-aware - "created": pd.Series( - [], dtype="datetime64[ns, UTC]" - ), # Timezone-aware - f"feature_{i + 1}_rate": pd.Series([], dtype="float32"), - f"feature_{i + 1}_count": pd.Series([], dtype="int64"), - } - ) - empty_schema_df.to_parquet( - offline_path, allow_truncated_timestamps=True - ) - - dataframes.append(df) - - # Apply entities and feature views - test_store.apply([driver, customer] + feature_views) - - # Test: Use materialize() to move data from offline to online store - # This should NOT raise any exceptions even with empty data - decorator handles warning validation - try: - test_store.materialize( - start_date=start_date, - end_date=end_date, - feature_views=[fv.name for fv in feature_views], - ) - except Exception as e: - self.fail(f"Materialization raised an unexpected exception: {e}") - - # Verify that the operation was successful by checking that non-empty feature views have data - successful_materializations = 0 - for i, fv in enumerate(feature_views): - if i != 1: # Skip the empty one (2nd feature view) - entity_key = "driver_id" if i % 2 == 0 else "customer_id" - entity_value = 1000 # First entity from our test data - - # Try to retrieve features to verify they were written successfully - online_response = test_store.get_online_features( - entity_rows=[{entity_key: entity_value}], - features=[ - f"{fv.name}:feature_{i + 1}_rate", - f"{fv.name}:feature_{i + 1}_count", - ], - ).to_dict() - - # Verify we got some data back (not None/null) - rate_value = online_response.get(f"feature_{i + 1}_rate") - count_value = online_response.get(f"feature_{i + 1}_count") - - if rate_value is not None and count_value is not None: - successful_materializations += 1 - - self.assertIsNotNone(rate_value) - self.assertIsNotNone(count_value) - - # Verify that 4 out of 4 non-empty feature views were successfully materialized - self.assertEqual(successful_materializations, 4) - - -class TestOnlineWritesWithTransform(unittest.TestCase): - def test_transform_on_write_pdf(self): - with tempfile.TemporaryDirectory() as data_dir: - self.store = FeatureStore( - config=RepoConfig( - project="test_write_to_online_store_with_transform", - registry=os.path.join(data_dir, "registry.db"), - provider="local", - entity_key_serialization_version=3, - online_store=MongoDBOnlineStoreConfig(), - # online_store=SqliteOnlineStoreConfig(path=os.path.join(self.data_dir, "online.db")), - ) - ) - - chunk = Entity( - name="chunk_id", - description="Chunk ID", - value_type=ValueType.STRING, - join_keys=["chunk_id"], - ) - - document = Entity( - name="document_id", - description="Document ID", - value_type=ValueType.STRING, - join_keys=["document_id"], - ) - - input_request_pdf = RequestSource( - name="pdf_request_source", - schema=[ - Field(name="document_id", dtype=String), - Field(name="pdf_bytes", dtype=PdfBytes), - Field(name="file_name", dtype=String), - ], - ) - - @on_demand_feature_view( - entities=[chunk, document], - sources=[input_request_pdf], - schema=[ - Field(name="document_id", dtype=String), - Field(name="chunk_id", dtype=String), - Field(name="chunk_text", dtype=String), - Field( - name="vector", - dtype=Array(Float32), - vector_index=True, - vector_search_metric="L2", - ), - ], - mode="python", - write_to_online_store=True, - singleton=True, - ) - def transform_pdf_on_write_view(inputs: dict[str, Any]) -> dict[str, Any]: - k = 10 - return { - "document_id": ["doc_1", "doc_2"], - "chunk_id": ["chunk-1", "chunk-2"], - "vector": [[0.5] * k, [0.4] * k], - "chunk_text": ["chunk text 1", "chunk text 2"], - } - - self.store.apply([chunk, document, transform_pdf_on_write_view]) - - sample_pdf = b"%PDF-1.3\n3 0 obj\n<>\nendobj\n4 0 obj\n<>\nstream\nx\x9c\x15\xcc1\x0e\x820\x18@\xe1\x9dS\xbcM]jk$\xd5\xd5(\x83!\x86\xa1\x17\xf8\xa3\xa5`LIh+\xd7W\xc6\xf7\r\xef\xc0\xbd\xd2\xaa\xb6,\xd5\xc5\xb1o\x0c\xa6VZ\xe3znn%\xf3o\xab\xb1\xe7\xa3:Y\xdc\x8bm\xeb\xf3&1\xc8\xd7\xd3\x97\xc82\xe6\x81\x87\xe42\xcb\x87Vb(\x12<\xdd<=}Jc\x0cL\x91\xee\xda$\xb5\xc3\xbd\xd7\xe9\x0f\x8d\x97 $\nendstream\nendobj\n1 0 obj\n<>\nendobj\n5 0 obj\n<>\nendobj\n2 0 obj\n<<\n/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n/Font <<\n/F1 5 0 R\n>>\n/XObject <<\n>>\n>>\nendobj\n6 0 obj\n<<\n/Producer (PyFPDF 1.7.2 http://pyfpdf.googlecode.com/)\n/Title (This is a sample title. And this is another sentence. Finally, this is the third sentence.)\n/Author (Francisco Javier Arceo)\n/CreationDate (D:20250312165548)\n>>\nendobj\n7 0 obj\n<<\n/Type /Catalog\n/Pages 1 0 R\n/OpenAction [3 0 R /FitH null]\n/PageLayout /OneColumn\n>>\nendobj\nxref\n0 8\n0000000000 65535 f \n0000000272 00000 n \n0000000455 00000 n \n0000000009 00000 n \n0000000087 00000 n \n0000000359 00000 n \n0000000559 00000 n \n0000000734 00000 n \ntrailer\n<<\n/Size 8\n/Root 7 0 R\n/Info 6 0 R\n>>\nstartxref\n837\n%%EOF\n" - sample_input = { - "pdf_bytes": sample_pdf, - "file_name": "sample_pdf", - "document_id": "doc_1", - } - input_df = pd.DataFrame([sample_input]) - - self.store.write_to_online_store( - feature_view_name="transform_pdf_on_write_view", - df=input_df, - ) From 46898b5331ae4b5148fe332b8716a4f9d6247739 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Fri, 20 Feb 2026 13:28:40 -0500 Subject: [PATCH 15/47] Format Signed-off-by: Casey Clements --- sdk/python/tests/unit/online_store/test_online_writes.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/sdk/python/tests/unit/online_store/test_online_writes.py b/sdk/python/tests/unit/online_store/test_online_writes.py index 542caed3afc..8e67d9a1a30 100644 --- a/sdk/python/tests/unit/online_store/test_online_writes.py +++ b/sdk/python/tests/unit/online_store/test_online_writes.py @@ -33,9 +33,6 @@ ) from feast.driver_test_data import create_driver_hourly_stats_df from feast.field import Field -from feast.infra.online_stores.contrib.mongodb_online_store.mongodb import ( - MongoDBOnlineStoreConfig, -) from feast.infra.online_stores.sqlite import SqliteOnlineStoreConfig from feast.on_demand_feature_view import on_demand_feature_view from feast.types import Array, Float32, Float64, Int64, PdfBytes, String, ValueType From 0356261cd7524d66e4d42e7c67569f7060829c5a Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Fri, 20 Feb 2026 13:40:31 -0500 Subject: [PATCH 16/47] Typing Signed-off-by: Casey Clements --- .../contrib/mongodb_online_store/mongodb.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py index 6beb5c8c0c1..9c56d6e26fb 100644 --- a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py +++ b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py @@ -202,13 +202,8 @@ def update( clxn.update_many({}, {"$unset": unset_fields}) - # Delete specific entities - if entities_to_delete: - logger.warning( - f"CHECK FORM. Can we call to_proto()?: {entities_to_delete = }" - ) - ids = [serialize_entity_key(e.to_proto()) for e in entities_to_delete] - clxn.delete_many({"_id": {"$in": ids}}) + # 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. def teardown( self, @@ -252,6 +247,7 @@ def _get_collection(self, repo_config: RepoConfig) -> Collection: """Returns a connection to the online store collection.""" if self._collection is None: self._client = self._get_client(repo_config) + assert self._client is not None online_config = repo_config.online_store db = self._client[online_config.database_name] clxn_name = f"{repo_config.project}_{online_config.collection_suffix}" @@ -261,7 +257,7 @@ def _get_collection(self, repo_config: RepoConfig) -> Collection: @staticmethod def convert_raw_docs_to_proto_simply( ids: list[bytes], - docs: dict[str, Any], + docs: dict[bytes, Any], table: FeatureView, requested_features: Optional[List[str]] = None, ) -> List[Tuple[Optional[datetime], Optional[dict[str, ValueProto]]]]: @@ -303,7 +299,7 @@ def convert_raw_docs_to_proto_simply( @staticmethod def convert_raw_docs_to_proto_transforming( - ids: list[bytes], docs: dict[str, Any], table: FeatureView + ids: list[bytes], docs: dict[bytes, Any], table: FeatureView ) -> List[Tuple[Optional[datetime], Optional[dict[str, ValueProto]]]]: """Convert values in documents retrieved from MongoDB (BSON) into ValueProto types. @@ -322,7 +318,7 @@ def convert_raw_docs_to_proto_transforming( # Step 1: Extract raw values column-wise (aligned by ordered ids) # We need to maintain alignment, so we append None for missing features - raw_feature_columns = {feature_name: [] for feature_name in feature_type_map} + raw_feature_columns: Dict[str, List[Any]] = {feature_name: [] for feature_name in feature_type_map} for entity_id in ids: doc = docs.get(entity_id) @@ -343,7 +339,7 @@ def convert_raw_docs_to_proto_transforming( ) # Step 3: Reassemble row-wise - results = [] + results: List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]] = [] for i, entity_id in enumerate(ids): doc = docs.get(entity_id) From 960881d7fad5da1f1f2c6f673a308a1f6995188a Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Sat, 21 Feb 2026 13:29:34 -0500 Subject: [PATCH 17/47] Implemented ASync API and Tests Signed-off-by: Casey Clements --- .../contrib/mongodb_online_store/mongodb.py | 128 +++++++++++++++++- .../test_push_features_to_online_store.py | 2 +- .../online_store/test_universal_online.py | 2 +- 3 files changed, 127 insertions(+), 5 deletions(-) diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py index 9c56d6e26fb..7935628d396 100644 --- a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py +++ b/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py @@ -4,13 +4,15 @@ from logging import getLogger from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple -from pymongo import MongoClient, UpdateOne +from pymongo import MongoClient, AsyncMongoClient, UpdateOne +from pymongo.asynchronous.collection import AsyncCollection from pymongo.collection import Collection from feast.entity import Entity from feast.feature_view import FeatureView from feast.infra.key_encoding_utils import serialize_entity_key from feast.infra.online_stores.online_store import OnlineStore +from feast.infra.supported_async_methods import SupportedAsyncMethods from feast.protos.feast.types.EntityKey_pb2 import EntityKey as EntityKeyProto from feast.protos.feast.types.Value_pb2 import Value as ValueProto from feast.repo_config import FeastConfigBaseModel, RepoConfig @@ -73,6 +75,8 @@ class MongoDBOnlineStore(OnlineStore): _client: Optional[MongoClient] = None _collection: Optional[Collection] = None + _client_async: Optional[AsyncMongoClient] = None + _collection_async: Optional[AsyncCollection] = None def online_write_batch( self, @@ -254,6 +258,35 @@ def _get_collection(self, repo_config: RepoConfig) -> Collection: self._collection = db[clxn_name] return self._collection + async def _get_client_async(self, config: RepoConfig) -> AsyncMongoClient: + """Returns an async MongoDB client.""" + if self._client_async is None: + online_config = config.online_store + if not isinstance(online_config, MongoDBOnlineStoreConfig): + logger.warning( + f"config.online_store passed to _get_client_async is not a MongoDBOnlineStoreConfig. It's of type {type(online_config)}" + ) + self._client_async = AsyncMongoClient( + online_config.connection_string, **online_config.client_kwargs + ) + return self._client_async + + async def _get_collection_async(self, repo_config: RepoConfig) -> AsyncCollection: + """Returns an async connection to the online store collection.""" + if self._collection_async is None: + self._client_async = await self._get_client_async(repo_config) + assert self._client_async is not None + online_config = repo_config.online_store + db = self._client_async[online_config.database_name] + clxn_name = f"{repo_config.project}_{online_config.collection_suffix}" + self._collection_async = db[clxn_name] + return self._collection_async + + @property + def async_supported(self) -> SupportedAsyncMethods: + """Indicates that this online store supports async operations.""" + return SupportedAsyncMethods(read=True, write=True) + @staticmethod def convert_raw_docs_to_proto_simply( ids: list[bytes], @@ -358,7 +391,96 @@ def convert_raw_docs_to_proto_transforming( results.append((ts, row_features)) return results + async def online_read_async( + self, + config: RepoConfig, + table: FeatureView, + entity_keys: List[EntityKeyProto], + requested_features: Optional[List[str]] = None, + ) -> List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]]: + """ + Asynchronously reads feature values from the online store. + + Args: + config: Feast repo configuration + table: FeatureView to read from + entity_keys: List of entity keys to read + requested_features: Optional list of specific features to read + + Returns: + List of tuples (event_timestamp, feature_dict) for each entity key + """ + clxn = await self._get_collection_async(config) + + # Serialize entity keys + ids = [ + serialize_entity_key( + entity_key, + entity_key_serialization_version=config.entity_key_serialization_version, + ) + for entity_key in entity_keys + ] + + # Query MongoDB asynchronously + cursor = clxn.find({"_id": {"$in": ids}}) + docs_list = await cursor.to_list(length=None) + docs = {doc["_id"]: doc for doc in docs_list} + + # Convert to proto format + return self.convert_raw_docs_to_proto_transforming(ids, docs, table) + + 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, + ) -> None: + """ + Asynchronously writes a batch of feature values to the online store. + + Args: + config: Feast repo configuration + table: FeatureView to write to + data: List of tuples (entity_key, features, event_ts, created_ts) + progress: Optional progress callback + """ + clxn = await self._get_collection_async(config) + ops = [] + for row in data: + entity_key_proto, features, event_ts, created_ts = row + entity_id = serialize_entity_key( + entity_key_proto, + entity_key_serialization_version=config.entity_key_serialization_version, + ) + + # Convert ValueProto to native Python types + feature_dict = {} + for feature_name, value_proto in features.items(): + feature_dict[feature_name] = feast_value_type_to_python_type(value_proto) + + # Build update operation + update_doc = { + "$set": { + f"features.{table.name}.{feature_name}": value + for feature_name, value in feature_dict.items() + }, + } + update_doc["$set"][f"event_timestamps.{table.name}"] = event_ts + if created_ts: + update_doc["$set"]["created_timestamp"] = created_ts + + ops.append(UpdateOne({"_id": entity_id}, update_doc, upsert=True)) + + # Execute bulk write asynchronously + if ops: + await clxn.bulk_write(ops, ordered=False) + + if progress: + progress(len(data)) + # TODO -# - Implement async API -# - Vector Search +# - Vector Search (requires atlas image in testcontainers or similar) diff --git a/sdk/python/tests/integration/online_store/test_push_features_to_online_store.py b/sdk/python/tests/integration/online_store/test_push_features_to_online_store.py index 902d9864bb9..536864ed97e 100644 --- a/sdk/python/tests/integration/online_store/test_push_features_to_online_store.py +++ b/sdk/python/tests/integration/online_store/test_push_features_to_online_store.py @@ -47,7 +47,7 @@ def test_push_features_and_read(store): @pytest.mark.integration -@pytest.mark.universal_online_stores(only=["dynamodb"]) +@pytest.mark.universal_online_stores(only=["dynamodb", "mongodb"]) async def test_push_features_and_read_async(store): await store.push_async("location_stats_push_source", _ingest_df()) 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 9c52782e92c..c4b141700b5 100644 --- a/sdk/python/tests/integration/online_store/test_universal_online.py +++ b/sdk/python/tests/integration/online_store/test_universal_online.py @@ -523,7 +523,7 @@ async def _do_async_retrieval_test(environment, universal_data_sources): @pytest.mark.asyncio @pytest.mark.integration -@pytest.mark.universal_online_stores(only=["redis", "postgres"]) +@pytest.mark.universal_online_stores(only=["redis", "postgres", "mongodb"]) async def test_async_online_retrieval_with_event_timestamps( environment, universal_data_sources ): From 52948a217db290328bebacd7a3c105b7eaa57bb1 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Mon, 23 Feb 2026 10:12:23 -0500 Subject: [PATCH 18/47] Removed offline store stubs. The first PR will only contain the OnlineStore Signed-off-by: Casey Clements --- .../offline_stores/contrib/mongodb_offline_store/__init__.py | 1 - .../contrib/mongodb_offline_store/tests/__init__.py | 1 - 2 files changed, 2 deletions(-) delete mode 100644 sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/__init__.py delete mode 100644 sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/tests/__init__.py 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 deleted file mode 100644 index 5ebb589a558..00000000000 --- a/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# MongoDB Offline Store for Feast diff --git a/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/tests/__init__.py b/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/tests/__init__.py deleted file mode 100644 index 0a2efb5c552..00000000000 --- a/sdk/python/feast/infra/offline_stores/contrib/mongodb_offline_store/tests/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# Tests for MongoDB Offline Store From f2e5dff04de779e653f4c6471d6bd1097d4c3396 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Mon, 23 Feb 2026 10:57:48 -0500 Subject: [PATCH 19/47] Moved mongodb_online_store out of cobtrib package. Signed-off-by: Casey Clements --- sdk/python/feast/infra/online_stores/contrib/__init__.py | 0 .../online_stores/{contrib => }/mongodb_online_store/__init__.py | 0 .../online_stores/{contrib => }/mongodb_online_store/mongodb.py | 0 .../mongodb_online_store/mongodb_repo_configuration.py | 0 4 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 sdk/python/feast/infra/online_stores/contrib/__init__.py rename sdk/python/feast/infra/online_stores/{contrib => }/mongodb_online_store/__init__.py (100%) rename sdk/python/feast/infra/online_stores/{contrib => }/mongodb_online_store/mongodb.py (100%) rename sdk/python/feast/infra/online_stores/{contrib => }/mongodb_online_store/mongodb_repo_configuration.py (100%) diff --git a/sdk/python/feast/infra/online_stores/contrib/__init__.py b/sdk/python/feast/infra/online_stores/contrib/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/__init__.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/__init__.py similarity index 100% rename from sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/__init__.py rename to sdk/python/feast/infra/online_stores/mongodb_online_store/__init__.py diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py similarity index 100% rename from sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb.py rename to sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py diff --git a/sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb_repo_configuration.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_repo_configuration.py similarity index 100% rename from sdk/python/feast/infra/online_stores/contrib/mongodb_online_store/mongodb_repo_configuration.py rename to sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_repo_configuration.py From 7f5a192a8ce60f7a677c738829fad75953b51ed6 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Tue, 24 Feb 2026 16:55:08 -0500 Subject: [PATCH 20/47] Add documentation. Signed-off-by: Casey Clements --- docs/SUMMARY.md | 1 + docs/reference/online-stores/README.md | 4 + docs/reference/online-stores/mongodb.md | 181 ++++++++++++++++++ ...fra.online_stores.mongodb_online_store.rst | 29 +++ .../docs/source/feast.infra.online_stores.rst | 1 + 5 files changed, 216 insertions(+) create mode 100644 docs/reference/online-stores/mongodb.md create mode 100644 sdk/python/docs/source/feast.infra.online_stores.mongodb_online_store.rst diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 36733d97e0f..82b1dac01d7 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -131,6 +131,7 @@ * [ScyllaDB](reference/online-stores/scylladb.md) * [SingleStore](reference/online-stores/singlestore.md) * [Milvus](reference/online-stores/milvus.md) + * [MongoDB](reference/online-stores/mongodb.md) * [Registries](reference/registries/README.md) * [Local](reference/registries/local.md) * [S3](reference/registries/s3.md) diff --git a/docs/reference/online-stores/README.md b/docs/reference/online-stores/README.md index 70c4431b8a6..2d962b2013f 100644 --- a/docs/reference/online-stores/README.md +++ b/docs/reference/online-stores/README.md @@ -50,6 +50,10 @@ Please see [Online Store](../../getting-started/components/online-store.md) for [mysql.md](mysql.md) {% endcontent-ref %} +{% content-ref url="mongodb.md" %} +[mongodb.md](mongodb.md) +{% endcontent-ref %} + {% content-ref url="hazelcast.md" %} [hazelcast.md](hazelcast.md) {% endcontent-ref %} diff --git a/docs/reference/online-stores/mongodb.md b/docs/reference/online-stores/mongodb.md new file mode 100644 index 00000000000..d783a80922a --- /dev/null +++ b/docs/reference/online-stores/mongodb.md @@ -0,0 +1,181 @@ +# MongoDB online store (Alpha) + +## 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 **alpha development**. 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 +* Native async support uses PyMongo's `AsyncMongoClient` (no Motor dependency required) +* Flexible connection options supporting MongoDB Atlas, self-hosted MongoDB, and MongoDB replica sets +* Automatic index creation for optimized query performance +* Entity key collocation for efficient feature retrieval + +## Getting started + +In order to use this online store, you'll need to install the MongoDB extra (along with the dependency needed for the offline store of choice): + +```bash +pip install 'feast[mongodb]' +``` + +You can get started by using any of the other templates (e.g. `feast init -t gcp` or `feast init -t snowflake` or `feast init -t aws`), and then swapping in MongoDB as the online store as seen below in the examples. + +## Examples + +### Basic configuration with MongoDB Atlas + +{% code title="feature_store.yaml" %} +```yaml +project: my_feature_repo +registry: data/registry.db +provider: local +online_store: + type: mongodb + connection_string: "mongodb+srv://username:password@cluster.mongodb.net/" + database_name: feast_online_store +``` +{% endcode %} + +### Self-hosted MongoDB with authentication + +{% code title="feature_store.yaml" %} +```yaml +project: my_feature_repo +registry: data/registry.db +provider: local +online_store: + type: mongodb + connection_string: "mongodb://username:password@localhost:27017/" + database_name: feast_online_store + collection_suffix: features +``` +{% endcode %} + +### MongoDB replica set configuration + +{% code title="feature_store.yaml" %} +```yaml +project: my_feature_repo +registry: data/registry.db +provider: local +online_store: + type: mongodb + connection_string: "mongodb://host1:27017,host2:27017,host3:27017/?replicaSet=myReplicaSet" + database_name: feast_online_store + client_kwargs: + retryWrites: true + w: majority +``` +{% endcode %} + +### Advanced configuration with custom client options + +{% code title="feature_store.yaml" %} +```yaml +project: my_feature_repo +registry: data/registry.db +provider: local +online_store: + type: mongodb + connection_string: "mongodb+srv://cluster.mongodb.net/" + database_name: feast_online_store + collection_suffix: features + client_kwargs: + maxPoolSize: 50 + minPoolSize: 10 + serverSelectionTimeoutMS: 5000 + connectTimeoutMS: 10000 +``` +{% endcode %} + +The full set of configuration options is available in [MongoDBOnlineStoreConfig](https://rtd.feast.dev/en/latest/#feast.infra.online_stores.contrib.mongodb_online_store.mongodb.MongoDBOnlineStoreConfig). + +## Data Model + +The MongoDB online store uses a **single collection per project** with entity key collocation. Features from multiple feature views for the same entity are stored together in a single document. + +### Example Document Schema + +The example shows a single entity. It contains 3 features from 2 feature views: "rating" and "trips_last7d" from Feature +View "driver_stats", and "surge_multiplier" from "pricing" view. +Each feature view has its own event timestamp. +The "created_timestamp" marks when the entity was materialized. + +```javascript +{ + "_id": "", // Binary entity key (bytes) + "features": { + "driver_stats": { + "rating": 4.91, + "trips_last_7d": 132 + }, + "pricing": { + "surge_multiplier": 1.2 + } + }, + "event_timestamps": { + "driver_stats": ISODate("2026-01-20T12:00:00Z"), + "pricing": ISODate("2026-01-21T08:30:00Z") + }, + "created_timestamp": ISODate("2026-01-21T12:00:05Z") +} +``` + +### Key Design Decisions + +* **`_id` field**: Uses the serialized entity key (bytes) as the primary key for efficient lookups +* **Nested features**: Features are organized by feature view name, allowing multiple feature views per entity +* **Event timestamps**: Stored per feature view to track when each feature set was last updated +* **Created timestamp**: Global timestamp for the entire document + +### Indexes + +The online store automatically creates the following index: +* Primary key index on `_id` (automatic in MongoDB), set to the serialized entity key. + +No additional indexes are required for the online store operations. + +## Async Support + +The MongoDB online store provides native async support using PyMongo 4.13+'s stable `AsyncMongoClient`. This enables: + +* **High concurrency**: Handle thousands of concurrent feature requests without thread pool limitations +* **True async I/O**: Non-blocking operations for better performance in async applications +* **10-20x performance improvement**: For concurrent workloads compared to sequential sync operations + +Both sync and async methods are fully supported: +* `online_read` / `online_read_async` +* `online_write_batch` / `online_write_batch_async` + +## Functionality Matrix + +The set of functionality supported by online stores is described in detail [here](overview.md#functionality). +Below is a matrix indicating which functionality is supported by the MongoDB online store. + +| | MongoDB | +| :-------------------------------------------------------- | :------ | +| write feature values to the online store | yes | +| read feature values from the online store | yes | +| update infrastructure (e.g. tables) in the online store | yes | +| teardown infrastructure (e.g. tables) in the online store | yes | +| generate a plan of infrastructure changes | no | +| support for on-demand transforms | yes | +| readable by Python SDK | yes | +| readable by Java | no | +| readable by Go | no | +| support for entityless feature views | yes | +| support for concurrent writing to the same key | yes | +| support for ttl (time to live) at retrieval | no | +| support for deleting expired data | no | +| collocated by feature view | no | +| collocated by feature service | no | +| collocated by entity key | yes | + +To compare this set of functionality against other online stores, please see the full [functionality matrix](overview.md#functionality-matrix). + diff --git a/sdk/python/docs/source/feast.infra.online_stores.mongodb_online_store.rst b/sdk/python/docs/source/feast.infra.online_stores.mongodb_online_store.rst new file mode 100644 index 00000000000..b221a370d31 --- /dev/null +++ b/sdk/python/docs/source/feast.infra.online_stores.mongodb_online_store.rst @@ -0,0 +1,29 @@ +feast.infra.online\_stores.mongodb\_online\_store package +================================================================= + +Submodules +---------- + +feast.infra.online\_stores.mongodb\_online\_store.mongodb module +------------------------------------------------------------------------ + +.. automodule:: feast.infra.online_stores.mongodb_online_store.mongodb + :members: + :undoc-members: + :show-inheritance: + +feast.infra.online\_stores.mongodb\_online\_store.mongodb\_repo\_configuration module +--------------------------------------------------------------------------------------------- + +.. automodule:: feast.infra.online_stores.mongodb_online_store.mongodb_repo_configuration + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: feast.infra.online_stores.mongodb_online_store + :members: + :undoc-members: + :show-inheritance: diff --git a/sdk/python/docs/source/feast.infra.online_stores.rst b/sdk/python/docs/source/feast.infra.online_stores.rst index 1bc2093fab4..91c3c6c90fa 100644 --- a/sdk/python/docs/source/feast.infra.online_stores.rst +++ b/sdk/python/docs/source/feast.infra.online_stores.rst @@ -13,6 +13,7 @@ Subpackages feast.infra.online_stores.hazelcast_online_store feast.infra.online_stores.hbase_online_store feast.infra.online_stores.milvus_online_store + feast.infra.online_stores.mongodb_online_store feast.infra.online_stores.mysql_online_store feast.infra.online_stores.postgres_online_store feast.infra.online_stores.qdrant_online_store From 619fdd371bbfd080f700169529b64567e730e051 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Tue, 24 Feb 2026 18:17:16 -0500 Subject: [PATCH 21/47] Cleanups and docstrings Signed-off-by: Casey Clements --- .../mongodb_online_store/mongodb.py | 74 ++++++++++++++----- 1 file changed, 55 insertions(+), 19 deletions(-) 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 7935628d396..efc21c820d8 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 @@ -139,6 +139,15 @@ def online_read( ) -> List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]]: """ Read features for a batch of entities. + + Args: + config: Feast repo configuration + table: FeatureView to read from + entity_keys: List of entity keys to read + requested_features: Optional list of specific features to read + + Returns: + List of tuples (event_timestamp, feature_dict) for each entity key """ clxn = self._get_collection(config) @@ -223,7 +232,15 @@ def teardown( assert config.online_store.type == "mongodb" clxn = self._get_collection(repo_config=config) clxn.drop() - self._get_client(config).close() + if self._client: + self._client.close() + + async def close(self) -> None: + """Close the async MongoDB client and release its resources.""" + if self._client_async is not None: + await self._client_async.close() + self._client_async = None + self._collection_async = None # ------------------------------------------------------------------ # Helpers @@ -288,22 +305,25 @@ def async_supported(self) -> SupportedAsyncMethods: return SupportedAsyncMethods(read=True, write=True) @staticmethod - def convert_raw_docs_to_proto_simply( + def convert_raw_docs_to_proto_naive( ids: list[bytes], docs: dict[bytes, Any], table: FeatureView, - requested_features: Optional[List[str]] = None, ) -> List[Tuple[Optional[datetime], Optional[dict[str, ValueProto]]]]: """Convert values in documents retrieved from MongoDB (BSON) into ValueProto types. - The table, a FeatureView, provides a map from feature name to proto type. - ids is a sorted list of the serialized entity ids used in MongoDBOnlineStore. - The heavy lifting is done in feast.type_map.python_values_to_proto_values. - It is intended to take a list of proto values with a single type (i.e. a column). + However, it is intended to take a list of proto values with a single type (i.e. a column). + + In this version, we simply iterate over ids, calling this method each time. + It is naive, but straightforward. # TODO Remove if transforming is faster. - In this method, we simply iterate over ids, calling this method each time. - It is naive, but straightforward. + Args: + ids: sorted list of the serialized entity ids requested. + docs: results of collection find. + table: The FeatureView of the read, providing the types. + Returns: + List of tuples (event_timestamp, feature_dict) for each entity key """ feature_type_map = { feature.name: feature.dtype.to_value_type() for feature in table.features @@ -336,14 +356,20 @@ def convert_raw_docs_to_proto_transforming( ) -> List[Tuple[Optional[datetime], Optional[dict[str, ValueProto]]]]: """Convert values in documents retrieved from MongoDB (BSON) into ValueProto types. - The table, a FeatureView, provides a map from feature name to proto type. - ids is a sorted list of the serialized entity ids used in MongoDBOnlineStore. - The heavy lifting is done in feast.type_map.python_values_to_proto_values. - It is intended to take a list of proto values with a single type (i.e. a column). + The issue is that it is column-oriented, expecting a list of proto values with a single type. + MongoDB lookups are row-oriented, plus we need to ensure ordering of ids. + So we transform twice to minimize calls to the python/proto converter. - In this method, we simply iterate over ids, calling this method each time. - It is naive, but straightforward. + Luckily, the table, a FeatureView, provides a map from feature name to proto type + so we don't have to infer types for each feature value. + + Args: + ids: sorted list of the serialized entity ids requested. + docs: results of collection find. + table: The FeatureView of the read, providing the types. + Returns: + List of tuples (event_timestamp, feature_dict) for each entity key """ feature_type_map = { feature.name: feature.dtype.to_value_type() for feature in table.features @@ -421,10 +447,20 @@ async def online_read_async( for entity_key in entity_keys ] - # Query MongoDB asynchronously - cursor = clxn.find({"_id": {"$in": ids}}) - docs_list = await cursor.to_list(length=None) - docs = {doc["_id"]: doc for doc in docs_list} + query_filter = {"_id": {"$in": ids}} + projection = { + "_id": 1, + f"event_timestamps.{table.name}": 1, + } + if requested_features: + projection.update( + {f"features.{table.name}.{x}": 1 for x in requested_features} + ) + else: + projection[f"features.{table.name}"] = 1 + + cursor = clxn.find(query_filter, projection=projection) + docs = {doc["_id"]: doc async for doc in cursor} # Convert to proto format return self.convert_raw_docs_to_proto_transforming(ids, docs, table) From 1f46d8e4a9fb013326426792e4e0d0db814705b2 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Tue, 24 Feb 2026 18:17:54 -0500 Subject: [PATCH 22/47] Fixed another reference to contrib dir Signed-off-by: Casey Clements --- sdk/python/feast/repo_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/python/feast/repo_config.py b/sdk/python/feast/repo_config.py index f3be7852846..86d2851331f 100644 --- a/sdk/python/feast/repo_config.py +++ b/sdk/python/feast/repo_config.py @@ -82,7 +82,7 @@ "qdrant": "feast.infra.online_stores.qdrant_online_store.qdrant.QdrantOnlineStore", "couchbase.online": "feast.infra.online_stores.couchbase_online_store.couchbase.CouchbaseOnlineStore", "milvus": "feast.infra.online_stores.milvus_online_store.milvus.MilvusOnlineStore", - "mongodb": "feast.infra.online_stores.contrib.mongodb_online_store.MongoDBOnlineStore", + "mongodb": "feast.infra.online_stores.mongodb_online_store.MongoDBOnlineStore", "hybrid": "feast.infra.online_stores.hybrid_online_store.hybrid_online_store.HybridOnlineStore", **LEGACY_ONLINE_STORE_CLASS_FOR_TYPE, } From de6b10370ca05dab3dc2314a10fd460a0adbd20d Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Wed, 25 Feb 2026 10:25:43 -0500 Subject: [PATCH 23/47] Typos Signed-off-by: Casey Clements --- docs/reference/online-stores/mongodb.md | 2 +- .../mongodb_online_store/mongodb.py | 24 +++++++------------ 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/docs/reference/online-stores/mongodb.md b/docs/reference/online-stores/mongodb.md index d783a80922a..d0b62497b96 100644 --- a/docs/reference/online-stores/mongodb.md +++ b/docs/reference/online-stores/mongodb.md @@ -94,7 +94,7 @@ online_store: ``` {% endcode %} -The full set of configuration options is available in [MongoDBOnlineStoreConfig](https://rtd.feast.dev/en/latest/#feast.infra.online_stores.contrib.mongodb_online_store.mongodb.MongoDBOnlineStoreConfig). +The full set of configuration options is available in [MongoDBOnlineStoreConfig](https://rtd.feast.dev/en/latest/#feast.infra.online_stores.mongodb_online_store.mongodb.MongoDBOnlineStoreConfig). ## Data Model 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 efc21c820d8..8347b941e8f 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 @@ -31,10 +31,7 @@ class MongoDBOnlineStoreConfig(FeastConfigBaseModel): see https://pymongo.readthedocs.io/en/stable/api/pymongo/mongo_client.html """ - type: Literal[ - "mongodb", - "feast.infra.online_stores.contrib.mongodb_online_store.mongodb.MongoDBOnlineStore", - ] = "mongodb" + type: Literal["mongodb"] = "mongodb" """Online store type selector""" connection_string: str = "mongodb://localhost:27017" database_name: str = ( @@ -67,9 +64,10 @@ class MongoDBOnlineStore(OnlineStore): }, }, "event_timestamps": { - "driver_stats": 2026-01-01 12:00:00+00:00 } - "pricing":: 2026-01-21 12:00:00+00:00 } - "created_timestamp": 2026-01-21 12:00:00+00:00 + "driver_stats": "2026-01-01 12:00:00+00:00", + "pricing": "2026-01-21 12:00:00+00:00" + }, + "created_timestamp": "2026-01-21 12:00:00+00:00" } """ @@ -128,7 +126,7 @@ def online_write_batch( if ops: clxn.bulk_write(ops, ordered=False) if progress: - progress(1) + progress(len(data)) def online_read( self, @@ -229,7 +227,8 @@ def teardown( As in update, MongoDB requires very little here. """ - assert config.online_store.type == "mongodb" + if not isinstance(config.online_store, MongoDBOnlineStoreConfig): + raise RuntimeError(f"{config.online_store.type = }. It must be mongodb.") clxn = self._get_collection(repo_config=config) clxn.drop() if self._client: @@ -255,10 +254,6 @@ def _get_client(self, config: RepoConfig): ) if self._client is None: online_config = config.online_store - if not isinstance(online_config, MongoDBOnlineStoreConfig): - logger.warning( - f"config.online_store passed to _get_client is not a MongoDBOnlineStoreConfig. It's of type {type(online_config)}" - ) self._client = MongoClient( online_config.connection_string, **online_config.client_kwargs ) @@ -505,8 +500,7 @@ async def online_write_batch_async( }, } update_doc["$set"][f"event_timestamps.{table.name}"] = event_ts - if created_ts: - update_doc["$set"]["created_timestamp"] = created_ts + update_doc["$set"]["created_timestamp"] = created_ts ops.append(UpdateOne({"_id": entity_id}, update_doc, upsert=True)) From 7e2a80df3566c623038652fe8b9c102f5bc569c3 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Wed, 25 Feb 2026 10:44:16 -0500 Subject: [PATCH 24/47] Made _convert_raw_docs_to_proto staticmethods private Signed-off-by: Casey Clements --- Makefile | 2 +- .../infra/online_stores/mongodb_online_store/mongodb.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index ec50d97209e..dd1ceb67dd3 100644 --- a/Makefile +++ b/Makefile @@ -537,7 +537,7 @@ test-python-universal-elasticsearch-online: ## Run Python Elasticsearch online s test-python-universal-mongodb-online: ## Run Python MongoDB online store integration tests PYTHONPATH='.' \ - FULL_REPO_CONFIGS_MODULE=sdk.python.feast.infra.online_stores.contrib.mongodb_online_store.mongodb_repo_configuration \ + FULL_REPO_CONFIGS_MODULE=sdk.python.feast.infra.online_stores.mongodb_online_store.mongodb_repo_configuration \ PYTEST_PLUGINS=sdk.python.tests.integration.feature_repos.universal.online_store.mongodb \ python -m pytest -n 8 --integration \ -k "not test_universal_cli and \ 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 8347b941e8f..d610251190b 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 @@ -172,7 +172,7 @@ def online_read( cursor = clxn.find(query_filter, projection=projection) docs = {doc["_id"]: doc for doc in cursor} - return self.convert_raw_docs_to_proto_transforming(ids, docs, table) + return self._convert_raw_docs_to_proto_transforming(ids, docs, table) def update( self, @@ -300,7 +300,7 @@ def async_supported(self) -> SupportedAsyncMethods: return SupportedAsyncMethods(read=True, write=True) @staticmethod - def convert_raw_docs_to_proto_naive( + def _convert_raw_docs_to_proto_naive( ids: list[bytes], docs: dict[bytes, Any], table: FeatureView, @@ -346,7 +346,7 @@ def convert_raw_docs_to_proto_naive( return results @staticmethod - def convert_raw_docs_to_proto_transforming( + def _convert_raw_docs_to_proto_transforming( ids: list[bytes], docs: dict[bytes, Any], table: FeatureView ) -> List[Tuple[Optional[datetime], Optional[dict[str, ValueProto]]]]: """Convert values in documents retrieved from MongoDB (BSON) into ValueProto types. @@ -458,7 +458,7 @@ async def online_read_async( docs = {doc["_id"]: doc async for doc in cursor} # Convert to proto format - return self.convert_raw_docs_to_proto_transforming(ids, docs, table) + return self._convert_raw_docs_to_proto_transforming(ids, docs, table) async def online_write_batch_async( self, From 8a82e7461b649267c499ecf68d1f8aa302a04e87 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Wed, 25 Feb 2026 11:43:38 -0500 Subject: [PATCH 25/47] After benchmarking two alogithm for conevrting read results from bson to proto, removed the naive one. It was outcompeted 3X across dimensions Signed-off-by: Casey Clements --- .../mongodb_online_store/mongodb.py | 59 +++---------------- 1 file changed, 7 insertions(+), 52 deletions(-) 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 d610251190b..1d6f2dedcfb 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 @@ -172,7 +172,7 @@ def online_read( cursor = clxn.find(query_filter, projection=projection) docs = {doc["_id"]: doc for doc in cursor} - return self._convert_raw_docs_to_proto_transforming(ids, docs, table) + return self._convert_raw_docs_to_proto(ids, docs, table) def update( self, @@ -299,61 +299,16 @@ def async_supported(self) -> SupportedAsyncMethods: """Indicates that this online store supports async operations.""" return SupportedAsyncMethods(read=True, write=True) - @staticmethod - def _convert_raw_docs_to_proto_naive( - ids: list[bytes], - docs: dict[bytes, Any], - table: FeatureView, - ) -> List[Tuple[Optional[datetime], Optional[dict[str, ValueProto]]]]: - """Convert values in documents retrieved from MongoDB (BSON) into ValueProto types. - - The heavy lifting is done in feast.type_map.python_values_to_proto_values. - However, it is intended to take a list of proto values with a single type (i.e. a column). - - In this version, we simply iterate over ids, calling this method each time. - It is naive, but straightforward. # TODO Remove if transforming is faster. - - Args: - ids: sorted list of the serialized entity ids requested. - docs: results of collection find. - table: The FeatureView of the read, providing the types. - Returns: - List of tuples (event_timestamp, feature_dict) for each entity key - """ - feature_type_map = { - feature.name: feature.dtype.to_value_type() for feature in table.features - } - - results: List[Tuple[Optional[datetime], Optional[Dict[str, ValueProto]]]] = [] - for entity_id in ids: - doc = docs.get(entity_id) - if doc is None: - results.append((None, None)) - continue - - # Extract timestamp - ts = doc.get("event_timestamps", {}).get(table.name) - - # Extract features - features_raw = doc.get("features", {}).get(table.name, {}) - features_proto = { - k: python_values_to_proto_values([v], feature_type_map[k])[0] - for k, v in features_raw.items() - } - - results.append((ts, features_proto)) - - return results @staticmethod - def _convert_raw_docs_to_proto_transforming( + def _convert_raw_docs_to_proto( ids: list[bytes], docs: dict[bytes, Any], table: FeatureView ) -> List[Tuple[Optional[datetime], Optional[dict[str, ValueProto]]]]: - """Convert values in documents retrieved from MongoDB (BSON) into ValueProto types. + """Optimized converting values in documents retrieved from MongoDB (BSON) into ValueProto types. - The heavy lifting is done in feast.type_map.python_values_to_proto_values. - The issue is that it is column-oriented, expecting a list of proto values with a single type. - MongoDB lookups are row-oriented, plus we need to ensure ordering of ids. + The conversion itself is done in feast.type_map.python_values_to_proto_values. + The issue we have is that it is column-oriented, expecting a list of proto values with a single type. + MongoDB lookups are row-oriented. Plus, we need to ensure ordering of ids. So we transform twice to minimize calls to the python/proto converter. Luckily, the table, a FeatureView, provides a map from feature name to proto type @@ -458,7 +413,7 @@ async def online_read_async( docs = {doc["_id"]: doc async for doc in cursor} # Convert to proto format - return self._convert_raw_docs_to_proto_transforming(ids, docs, table) + return self._convert_raw_docs_to_proto(ids, docs, table) async def online_write_batch_async( self, From f09faa0c0acd986186352faf1a78660a75b12790 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Wed, 25 Feb 2026 13:58:43 -0500 Subject: [PATCH 26/47] Add extra unit tests Signed-off-by: Casey Clements --- .../test_mongodb_online_retrieval.py | 100 +++++++++++++++++- 1 file changed, 95 insertions(+), 5 deletions(-) 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 2ef981ebd00..50bf25dd292 100644 --- a/sdk/python/tests/unit/online_store/test_mongodb_online_retrieval.py +++ b/sdk/python/tests/unit/online_store/test_mongodb_online_retrieval.py @@ -1,13 +1,19 @@ """ -Unit tests for MongoDB online store using testcontainers. +Unit tests for MongoDB online store. -This test requires Docker to be running. It will be skipped if Docker is not available. +Docker-dependent tests are marked with ``@_requires_docker`` and are skipped when +Docker is unavailable. Pure Python tests (no container needed) run in all environments. """ +from datetime import datetime, timedelta, timezone + import pytest +from feast import FeatureView, Field, 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 Int64 from feast.utils import _utc_now from tests.integration.feature_repos.universal.feature_views import TAGS from tests.utils.cli_repo_creator import CliRunner, get_example_repo @@ -28,8 +34,8 @@ except ImportError: pass -# Skip all tests in this module if Docker is not available -pytestmark = pytest.mark.skipif( +# Applied per-test so that pure Python tests still run without Docker. +_requires_docker = pytest.mark.skipif( not docker_available, reason="Docker is not available or not running. Start Docker daemon to run these tests.", ) @@ -55,6 +61,7 @@ def mongodb_connection_string(mongodb_container): return f"mongodb://test:test@localhost:{exposed_port}" # pragma: allowlist secret +@_requires_docker def test_mongodb_online_features(mongodb_connection_string): """ Test reading from MongoDB online store using testcontainers. @@ -174,4 +181,87 @@ def test_mongodb_online_features(mongodb_connection_string): full_feature_names=False, ).to_dict() - assert "trips" in result + assert result["trips"] == [None] + + +# --------------------------------------------------------------------------- +# Pure Python tests — no Docker required +# --------------------------------------------------------------------------- + + +def _make_fv(*field_names: str) -> FeatureView: + """Build a minimal FeatureView with Int64 features for use in unit tests.""" + return FeatureView( + name="test_fv", + entities=[], + schema=[Field(name=n, dtype=Int64) for n in field_names], + source=FileSource(path="fake.parquet", timestamp_field="event_timestamp"), + ttl=timedelta(days=1), + ) + + +def test_convert_raw_docs_missing_entity(): + """Entity key absent from docs → result tuple is (None, None) for that position.""" + fv = _make_fv("score") + ts = datetime(2024, 1, 1, tzinfo=timezone.utc) + ids = [b"present", b"missing"] + docs = { + b"present": { + "features": {"test_fv": {"score": 42}}, + "event_timestamps": {"test_fv": ts}, + } + } + + results = MongoDBOnlineStore._convert_raw_docs_to_proto(ids, docs, fv) + + assert len(results) == 2 + ts_out, feats_out = results[0] + assert ts_out == ts + assert feats_out["score"].int64_val == 42 + assert results[1] == (None, None) + + +def test_convert_raw_docs_partial_doc(): + """Entity exists but one feature key is absent → empty ValueProto for that feature.""" + fv = _make_fv("present_feat", "missing_feat") + ts = datetime(2024, 1, 1, tzinfo=timezone.utc) + ids = [b"entity1"] + docs = { + b"entity1": { + # missing_feat intentionally omitted (e.g. schema migration scenario) + "features": {"test_fv": {"present_feat": 99}}, + "event_timestamps": {"test_fv": ts}, + } + } + + results = MongoDBOnlineStore._convert_raw_docs_to_proto(ids, docs, fv) + + assert len(results) == 1 + ts_out, feats_out = results[0] + assert ts_out == ts + assert feats_out["present_feat"].int64_val == 99 + assert feats_out["missing_feat"] == ValueProto() # null / not-set + + +def test_convert_raw_docs_ordering(): + """Result order matches the ids list regardless of dict insertion order in docs.""" + fv = _make_fv("score") + ts = datetime(2024, 1, 1, tzinfo=timezone.utc) + + # Request entity keys in z → a → m order + ids = [b"entity_z", b"entity_a", b"entity_m"] + + # docs is in a different order (simulating arbitrary MongoDB cursor return order) + docs = { + b"entity_a": {"features": {"test_fv": {"score": 2}}, "event_timestamps": {"test_fv": ts}}, + b"entity_m": {"features": {"test_fv": {"score": 3}}, "event_timestamps": {"test_fv": ts}}, + b"entity_z": {"features": {"test_fv": {"score": 1}}, "event_timestamps": {"test_fv": ts}}, + } + + results = MongoDBOnlineStore._convert_raw_docs_to_proto(ids, docs, fv) + + assert len(results) == 3 + # Results must follow the ids order: z=1, a=2, m=3 + 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 From 0ba503c2d65d5cd7de48f7b67635cceacf07e747 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Wed, 25 Feb 2026 14:09:31 -0500 Subject: [PATCH 27/47] Formatting Signed-off-by: Casey Clements --- .../online_stores/mongodb_online_store/mongodb.py | 11 +++++++---- .../online_store/test_mongodb_online_retrieval.py | 15 ++++++++++++--- 2 files changed, 19 insertions(+), 7 deletions(-) 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 1d6f2dedcfb..7cf59d81005 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 @@ -4,7 +4,7 @@ from logging import getLogger from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple -from pymongo import MongoClient, AsyncMongoClient, UpdateOne +from pymongo import AsyncMongoClient, MongoClient, UpdateOne from pymongo.asynchronous.collection import AsyncCollection from pymongo.collection import Collection @@ -299,7 +299,6 @@ def async_supported(self) -> SupportedAsyncMethods: """Indicates that this online store supports async operations.""" return SupportedAsyncMethods(read=True, write=True) - @staticmethod def _convert_raw_docs_to_proto( ids: list[bytes], docs: dict[bytes, Any], table: FeatureView @@ -327,7 +326,9 @@ def _convert_raw_docs_to_proto( # Step 1: Extract raw values column-wise (aligned by ordered ids) # We need to maintain alignment, so we append None for missing features - raw_feature_columns: Dict[str, List[Any]] = {feature_name: [] for feature_name in feature_type_map} + raw_feature_columns: Dict[str, List[Any]] = { + feature_name: [] for feature_name in feature_type_map + } for entity_id in ids: doc = docs.get(entity_id) @@ -445,7 +446,9 @@ async def online_write_batch_async( # Convert ValueProto to native Python types feature_dict = {} for feature_name, value_proto in features.items(): - feature_dict[feature_name] = feast_value_type_to_python_type(value_proto) + feature_dict[feature_name] = feast_value_type_to_python_type( + value_proto + ) # Build update operation update_doc = { 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 50bf25dd292..c8344edb786 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 @@ -253,9 +253,18 @@ def test_convert_raw_docs_ordering(): # docs is in a different order (simulating arbitrary MongoDB cursor return order) docs = { - b"entity_a": {"features": {"test_fv": {"score": 2}}, "event_timestamps": {"test_fv": ts}}, - b"entity_m": {"features": {"test_fv": {"score": 3}}, "event_timestamps": {"test_fv": ts}}, - b"entity_z": {"features": {"test_fv": {"score": 1}}, "event_timestamps": {"test_fv": ts}}, + b"entity_a": { + "features": {"test_fv": {"score": 2}}, + "event_timestamps": {"test_fv": ts}, + }, + b"entity_m": { + "features": {"test_fv": {"score": 3}}, + "event_timestamps": {"test_fv": ts}, + }, + b"entity_z": { + "features": {"test_fv": {"score": 1}}, + "event_timestamps": {"test_fv": ts}, + }, } results = MongoDBOnlineStore._convert_raw_docs_to_proto(ids, docs, fv) From 6b96c0edf40cad3f63c2fd1901881a2c3b5f97eb Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Fri, 27 Feb 2026 15:34:56 -0500 Subject: [PATCH 28/47] Fixes in pyproject.toml Signed-off-by: Casey Clements --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e991d5b4bf1..19c21870a40 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -98,11 +98,12 @@ milvus = [ "feast[setuptools]" ] mongodb = [ - "pymongo>=4.6.0,<5.0.0", + "pymongo>=4.13.0,<5.0.0", "dnspython>=2.0.0", ] mssql = ["ibis-framework[mssql]>=10.0.0"] mysql = ["pymysql", "types-PyMySQL"] +openlineage = ["openlineage-python>=1.40.0"] opentelemetry = ["prometheus_client", "psutil"] spark = ["pyspark>=4.0.0"] trino = ["trino>=0.305.0,<0.400.0", "regex"] From 7c3874bf5542bdb4d8bc0515376d8637be683743 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Mon, 2 Mar 2026 16:06:13 -0500 Subject: [PATCH 29/47] Fixed Detect secrets false positives. Signed-off-by: Casey Clements --- docs/reference/online-stores/mongodb.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference/online-stores/mongodb.md b/docs/reference/online-stores/mongodb.md index d0b62497b96..c4a9bb72fce 100644 --- a/docs/reference/online-stores/mongodb.md +++ b/docs/reference/online-stores/mongodb.md @@ -37,7 +37,7 @@ registry: data/registry.db provider: local online_store: type: mongodb - connection_string: "mongodb+srv://username:password@cluster.mongodb.net/" + connection_string: "mongodb+srv://username:password@cluster.mongodb.net/" # pragma: allowlist secret database_name: feast_online_store ``` {% endcode %} @@ -51,7 +51,7 @@ registry: data/registry.db provider: local online_store: type: mongodb - connection_string: "mongodb://username:password@localhost:27017/" + connection_string: "mongodb://username:password@localhost:27017/" # pragma: allowlist secret database_name: feast_online_store collection_suffix: features ``` From 49022e30a914ffca6a39ba3fab59c684d178472c Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Mon, 2 Mar 2026 17:10:22 -0500 Subject: [PATCH 30/47] Update sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb.py Set _client and _collection to None upon synchronous teardown. Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com> Signed-off-by: Casey Clements --- .../feast/infra/online_stores/mongodb_online_store/mongodb.py | 2 ++ 1 file changed, 2 insertions(+) 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 7cf59d81005..8b60482fd3a 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 @@ -233,6 +233,8 @@ def teardown( clxn.drop() if self._client: self._client.close() + self._client = None + self._collection = None async def close(self) -> None: """Close the async MongoDB client and release its resources.""" From a2c493e8b3051975ce0ad71cfa362cf3f38d8041 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Tue, 3 Mar 2026 11:56:20 -0500 Subject: [PATCH 31/47] Fix CI: guard pymongo imports and skip test module when pymongo unavailable In the unit-test-python CI job, pymongo is not installed (it is an optional extra). This caused ModuleNotFoundError during pytest collection. Two changes: 1. mongodb.py: wrap pymongo imports in try/except -> FeastExtrasDependencyImportError (consistent with redis.py, dynamodb.py, datastore.py pattern) 2. test_mongodb_online_retrieval.py: add pytest.importorskip(\pymongo\) so the entire test module is skipped gracefully when pymongo is absent Signed-off-by: Casey Clements --- .../online_stores/mongodb_online_store/mongodb.py | 11 ++++++++--- .../online_store/test_mongodb_online_retrieval.py | 8 ++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) 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 8b60482fd3a..511e47d08bf 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 @@ -4,9 +4,14 @@ from logging import getLogger from typing import Any, Callable, Dict, List, Literal, Optional, Sequence, Tuple -from pymongo import AsyncMongoClient, MongoClient, UpdateOne -from pymongo.asynchronous.collection import AsyncCollection -from pymongo.collection import Collection +try: + from pymongo import AsyncMongoClient, MongoClient, UpdateOne + from pymongo.asynchronous.collection import AsyncCollection + from pymongo.collection import Collection +except ImportError as e: + from feast.errors import FeastExtrasDependencyImportError + + raise FeastExtrasDependencyImportError("mongodb", str(e)) from feast.entity import Entity from feast.feature_view import FeatureView 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 c8344edb786..c7ab98cba75 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 @@ -9,8 +9,12 @@ import pytest -from feast import FeatureView, Field, FileSource -from feast.infra.online_stores.mongodb_online_store.mongodb import MongoDBOnlineStore +pytest.importorskip("pymongo") + +from feast import FeatureView, Field, FileSource # 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 dcb9072a4694b3c532674e3de1599b92ad79721c Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Tue, 3 Mar 2026 12:16:19 -0500 Subject: [PATCH 32/47] Fix: return (None, None) when entity doc exists but feature view was never written MongoDB stores all feature views for an entity in a single document. If FV 'driver_stats' is written, an entity doc exists for driver_1. A subsequent read for FV 'pricing' (never written) was previously returning (None, {all_features: ValueProto()}) - a truthy feature dict with all-empty protos - instead of the correct (None, None) sentinel. Feast and downstream callers use (None, None) to signal entity absence. A non-None feature dict means 'entity found, values are null', which causes different behaviour in the feature retrieval pipeline. Fix: after confirming the entity doc exists, also check that the feature view key is present in doc['features']. If absent, return (None, None) rather than a dict of empty protos. Adds test_convert_raw_docs_entity_exists_but_fv_not_written to cover the multi-feature-view colocation scenario identified in code review. Signed-off-by: Casey Clements --- .../mongodb_online_store/mongodb.py | 7 ++++++ .../test_mongodb_online_retrieval.py | 25 +++++++++++++++++++ 2 files changed, 32 insertions(+) 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 511e47d08bf..b588791e17a 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 @@ -365,6 +365,13 @@ def _convert_raw_docs_to_proto( results.append((None, None)) continue + # Entity document exists (written by some other feature view), but + # this specific feature view was never written → treat as not found. + fv_features = doc.get("features", {}).get(table.name) + if fv_features is None: + results.append((None, None)) + continue + ts = doc.get("event_timestamps", {}).get(table.name) row_features = { 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 c7ab98cba75..a17f9ed6ca2 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 @@ -247,6 +247,31 @@ def test_convert_raw_docs_partial_doc(): assert feats_out["missing_feat"] == ValueProto() # null / not-set +def test_convert_raw_docs_entity_exists_but_fv_not_written(): + """Entity doc exists (written by another FV) but this FV was never written → (None, None). + + MongoDB stores all feature views for the same entity in one document. + If FV "driver_stats" was written, an entity doc exists for driver_1. + A subsequent read for FV "pricing" (never written) must return (None, None), + not a truthy dict of empty ValueProtos. + """ + pricing_fv = _make_fv("price") + ts = datetime(2024, 1, 1, tzinfo=timezone.utc) + ids = [b"driver_1"] + # doc was created by driver_stats, pricing key is absent entirely + docs = { + b"driver_1": { + "features": {"driver_stats": {"acc_rate": 0.9}}, + "event_timestamps": {"driver_stats": ts}, + } + } + + results = MongoDBOnlineStore._convert_raw_docs_to_proto(ids, docs, pricing_fv) + + assert len(results) == 1 + assert results[0] == (None, None) + + def test_convert_raw_docs_ordering(): """Result order matches the ids list regardless of dict insertion order in docs.""" fv = _make_fv("score") From bcb63aa3a3af1bacf1d53ef40c1622a385c62393 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Tue, 3 Mar 2026 12:38:52 -0500 Subject: [PATCH 33/47] Update pixi.lock after adding mongodb optional dependency to pyproject.toml Any change to pyproject.toml invalidates the pixi.lock manifest hash, causing 'pixi install --locked' to fail in CI even when the changed section (mongodb optional extras) is not used by any pixi environment. Regenerated with: pixi install (v0.63.2) Signed-off-by: Casey Clements --- pixi.lock | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pixi.lock b/pixi.lock index d50f8b6483a..ce31fdd102d 100644 --- a/pixi.lock +++ b/pixi.lock @@ -2239,8 +2239,8 @@ packages: requires_python: '>=3.10' - pypi: ./ name: feast - version: 0.60.1.dev28+gc2beabb4a.d20260303 - sha256: d8f9bea1bbb444aaa8706a838d593661a5031b257a4736070a64a93a1977e335 + version: 0.60.1.dev60+gb37e25a55.d20260304 + sha256: f06b53f6c086c78729760f6e7b3284717bbafa4793a1449d8a81f0270a7eb49f requires_dist: - click>=7.0.0,<9.0.0 - colorama>=0.3.9,<1 @@ -2313,12 +2313,14 @@ packages: - pymilvus>2.5 ; extra == 'milvus' - milvus-lite==2.4.12 ; extra == 'milvus' - feast[setuptools] ; extra == 'milvus' + - pymongo>=4.13.0,<5.0.0 ; extra == 'mongodb' + - dnspython>=2.0.0 ; extra == 'mongodb' - ibis-framework[mssql]>=10.0.0 ; extra == 'mssql' - pymysql ; extra == 'mysql' - types-pymysql ; extra == 'mysql' + - openlineage-python>=1.40.0 ; extra == 'openlineage' - prometheus-client ; extra == 'opentelemetry' - psutil ; extra == 'opentelemetry' - - openlineage-python>=1.40.0 ; extra == 'openlineage' - pyspark>=4.0.0 ; extra == 'spark' - trino>=0.305.0,<0.400.0 ; extra == 'trino' - regex ; extra == 'trino' From 1cb84dcd8edc113eacdd0694f91d76c8bf668eb1 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Wed, 4 Mar 2026 09:29:23 -0500 Subject: [PATCH 34/47] fix: catch FeastExtrasDependencyImportError in doctest runner Stores like mongodb, redis, and dynamodb raise FeastExtrasDependencyImportError at import time when their optional Python extras are not installed. test_all.py only caught ModuleNotFoundError, so any such import caused the entire test_docstrings() function to abort rather than gracefully skipping the module. Extend the except clause to also catch FeastExtrasDependencyImportError so the doctest run completes for all other modules when an optional extra is absent in the test environment. Signed-off-by: Casey Clements --- sdk/python/tests/doctest/test_all.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sdk/python/tests/doctest/test_all.py b/sdk/python/tests/doctest/test_all.py index 7f3adee1af5..d06ac207b30 100644 --- a/sdk/python/tests/doctest/test_all.py +++ b/sdk/python/tests/doctest/test_all.py @@ -6,6 +6,7 @@ import unittest import feast +from feast.errors import FeastExtrasDependencyImportError from feast.utils import _utc_now FILES_TO_IGNORE = {"app"} @@ -89,7 +90,11 @@ def test_docstrings(): temp_module = importlib.import_module(full_name) if is_pkg: next_packages.append(temp_module) - except ModuleNotFoundError: + except (ModuleNotFoundError, FeastExtrasDependencyImportError): + # ModuleNotFoundError: optional system dependency missing + # FeastExtrasDependencyImportError: optional Python extra + # missing (e.g. pymongo, couchbase). Gracefully skip so + # the doctest run is not aborted for unrelated modules. pass # Retrieve the setup and teardown functions defined in this file. From c02eebfda9c2626d62410c2ad68e40c0cfe2e055 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Wed, 4 Mar 2026 11:17:07 -0500 Subject: [PATCH 35/47] fix: update PYTEST_PLUGINS path for mongodb online store tests Directory was renamed from tests/integration/feature_repos to tests/universal/feature_repos in upstream/master. Update the PYTEST_PLUGINS module path in test-python-universal-mongodb-online to match the new location. Signed-off-by: Casey Clements --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index dd1ceb67dd3..58c99b8c984 100644 --- a/Makefile +++ b/Makefile @@ -538,7 +538,7 @@ test-python-universal-elasticsearch-online: ## Run Python Elasticsearch online s test-python-universal-mongodb-online: ## Run Python MongoDB online store integration tests PYTHONPATH='.' \ FULL_REPO_CONFIGS_MODULE=sdk.python.feast.infra.online_stores.mongodb_online_store.mongodb_repo_configuration \ - PYTEST_PLUGINS=sdk.python.tests.integration.feature_repos.universal.online_store.mongodb \ + PYTEST_PLUGINS=sdk.python.tests.universal.feature_repos.universal.online_store.mongodb \ python -m pytest -n 8 --integration \ -k "not test_universal_cli and \ not test_go_feature_server and \ From 3eb6107840eaba8997310415b07617b14a311ce6 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Wed, 4 Mar 2026 16:51:32 -0500 Subject: [PATCH 36/47] fix: broaden import exception handling in doctest runner to catch TypeError and other third-party import errors qdrant_client raises TypeError at import time when a gRPC EnumTypeWrapper is used with the | union operator on Python < 3.12. The previous fix only caught ModuleNotFoundError and FeastExtrasDependencyImportError, leaving the test runner vulnerable to any other exception raised by third-party libraries during pkgutil.walk_packages. Changes: - Catch bare Exception in the import try/except block so any import-time error from an optional dependency causes a graceful skip rather than an abort of the entire test run. - Initialize temp_module = None before the try block and add a continue guard so that a failed import never leaves a stale module reference to be used in the subsequent doctest execution block. Signed-off-by: Casey Clements --- sdk/python/tests/doctest/test_all.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/sdk/python/tests/doctest/test_all.py b/sdk/python/tests/doctest/test_all.py index d06ac207b30..4297a98e281 100644 --- a/sdk/python/tests/doctest/test_all.py +++ b/sdk/python/tests/doctest/test_all.py @@ -6,7 +6,6 @@ import unittest import feast -from feast.errors import FeastExtrasDependencyImportError from feast.utils import _utc_now FILES_TO_IGNORE = {"app"} @@ -78,6 +77,7 @@ def test_docstrings(): continue full_name = package.__name__ + "." + name + temp_module = None try: # https://github.com/feast-dev/feast/issues/5088 # Skip ray_transformation doctests - they hang on macOS due to @@ -90,13 +90,20 @@ def test_docstrings(): temp_module = importlib.import_module(full_name) if is_pkg: next_packages.append(temp_module) - except (ModuleNotFoundError, FeastExtrasDependencyImportError): - # ModuleNotFoundError: optional system dependency missing - # FeastExtrasDependencyImportError: optional Python extra - # missing (e.g. pymongo, couchbase). Gracefully skip so - # the doctest run is not aborted for unrelated modules. + except Exception: # noqa: BLE001 + # Gracefully skip modules that fail to import due to: + # - ModuleNotFoundError: optional system dependency missing + # - FeastExtrasDependencyImportError: optional Python extra + # missing (e.g. pymongo, couchbase) + # - TypeError or other errors: third-party libraries with + # internal incompatibilities at import time (e.g. + # qdrant_client raises TypeError when a grpc EnumTypeWrapper + # is used with the | union operator on Python < 3.12) pass + if temp_module is None: + continue + # Retrieve the setup and teardown functions defined in this file. relative_path_from_feast = full_name.split(".", 1)[1] function_suffix = relative_path_from_feast.replace(".", "_") From 01d2e4c3b22a0c7b6b0c418a935bb6a9c42ea3f3 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Wed, 4 Mar 2026 16:57:16 -0500 Subject: [PATCH 37/47] fix: pass onerror to pkgutil.walk_packages to suppress non-ImportError package import failures FeastExtrasDependencyImportError inherits from FeastError -> Exception, not from ImportError. pkgutil.walk_packages calls __import__ internally when recursing into sub-packages, and only silently swallows ImportError subclasses; any other exception is re-raised, crashing the entire test run. Passing onerror=lambda _: None tells walk_packages to skip any package that fails to import during the walk phase, regardless of the exception type. The inner importlib.import_module try/except already handles the same errors for the explicit import step used to collect doctests. Signed-off-by: Casey Clements --- sdk/python/tests/doctest/test_all.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sdk/python/tests/doctest/test_all.py b/sdk/python/tests/doctest/test_all.py index 4297a98e281..4f8a553bfac 100644 --- a/sdk/python/tests/doctest/test_all.py +++ b/sdk/python/tests/doctest/test_all.py @@ -72,7 +72,9 @@ def test_docstrings(): for package in current_packages: try: - for _, name, is_pkg in pkgutil.walk_packages(package.__path__): + for _, name, is_pkg in pkgutil.walk_packages( + package.__path__, onerror=lambda _: None + ): if name in FILES_TO_IGNORE: continue From 156f17bc99a8c58b078735cef9cce05a4de3e735 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Wed, 4 Mar 2026 18:11:01 -0500 Subject: [PATCH 38/47] fix: update stale tests.integration.feature_repos imports to tests.universal.feature_repos The upstream directory tests/integration/feature_repos was renamed to tests/universal/feature_repos. Three files still referenced the old path: - mongodb_repo_configuration.py: IntegrationTestRepoConfig and MongoDBOnlineStoreCreator imports - tests/.../online_store/mongodb.py: OnlineStoreCreator import - tests/unit/online_store/test_mongodb_online_retrieval.py: TAGS import Updating all three unblocks test collection and allows make test-python-universal-mongodb-online to run locally. Signed-off-by: Casey Clements --- .../mongodb_online_store/mongodb_repo_configuration.py | 4 ++-- .../tests/unit/online_store/test_mongodb_online_retrieval.py | 2 +- .../universal/feature_repos/universal/online_store/mongodb.py | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_repo_configuration.py b/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_repo_configuration.py index 22c9f7eb51e..c621902ba54 100644 --- a/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_repo_configuration.py +++ b/sdk/python/feast/infra/online_stores/mongodb_online_store/mongodb_repo_configuration.py @@ -1,7 +1,7 @@ -from tests.integration.feature_repos.integration_test_repo_config import ( +from tests.universal.feature_repos.integration_test_repo_config import ( IntegrationTestRepoConfig, ) -from tests.integration.feature_repos.universal.online_store.mongodb import ( +from tests.universal.feature_repos.universal.online_store.mongodb import ( MongoDBOnlineStoreCreator, ) 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 a17f9ed6ca2..cfadc3151fd 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 @@ -19,7 +19,7 @@ from feast.protos.feast.types.Value_pb2 import Value as ValueProto from feast.types import Int64 from feast.utils import _utc_now -from tests.integration.feature_repos.universal.feature_views import TAGS +from tests.universal.feature_repos.universal.feature_views import TAGS from tests.utils.cli_repo_creator import CliRunner, get_example_repo # Check if Docker is available 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 904c49eafaf..0c0afd4908a 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,7 +1,8 @@ from typing import Any, Dict from testcontainers.mongodb import MongoDbContainer -from tests.integration.feature_repos.universal.online_store_creator import ( + +from tests.universal.feature_repos.universal.online_store_creator import ( OnlineStoreCreator, ) From 762d17ba71d662be6aa569163b622d4cdfffbc3b Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Thu, 5 Mar 2026 10:25:15 -0500 Subject: [PATCH 39/47] feat: add mongodb to ValidOnlineStoreDBStorePersistenceTypes in feast-operator The Python ONLINE_STORE_CLASS_FOR_TYPE now includes 'mongodb', so the operator's parity check (test-datasources) fails unless the Go API also lists it. Add 'mongodb' to ValidOnlineStoreDBStorePersistenceTypes in both api/v1 and api/v1alpha1. Signed-off-by: Casey Clements --- .secrets.baseline | 156 +++++++++--------- .../api/v1/featurestore_types.go | 1 + .../api/v1alpha1/featurestore_types.go | 1 + 3 files changed, 80 insertions(+), 78 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index 1480d3529e4..06e2cefc508 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": 725 + "line_number": 726 } ], "infra/feast-operator/api/v1/zz_generated.deepcopy.go": [ @@ -966,7 +966,7 @@ "filename": "infra/feast-operator/api/v1alpha1/featurestore_types.go", "hashed_secret": "44e17306b837162269a410204daaa5ecee4ec22c", "is_verified": false, - "line_number": 646 + "line_number": 647 } ], "infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go": [ @@ -1311,81 +1311,6 @@ "line_number": 1 } ], - "sdk/python/tests/universal/feature_repos/repo_configuration.py": [ - { - "type": "Secret Keyword", - "filename": "sdk/python/tests/universal/feature_repos/repo_configuration.py", - "hashed_secret": "d90e76ef629fb00c95f4e84fec29fbda111e2392", - "is_verified": false, - "line_number": 452 - }, - { - "type": "Secret Keyword", - "filename": "sdk/python/tests/universal/feature_repos/repo_configuration.py", - "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", - "is_verified": false, - "line_number": 454 - } - ], - "sdk/python/tests/universal/feature_repos/universal/data_sources/file.py": [ - { - "type": "Base64 High Entropy String", - "filename": "sdk/python/tests/universal/feature_repos/universal/data_sources/file.py", - "hashed_secret": "d70eab08607a4d05faa2d0d6647206599e9abc65", - "is_verified": false, - "line_number": 257 - }, - { - "type": "Secret Keyword", - "filename": "sdk/python/tests/universal/feature_repos/universal/data_sources/file.py", - "hashed_secret": "d70eab08607a4d05faa2d0d6647206599e9abc65", - "is_verified": false, - "line_number": 257 - } - ], - "sdk/python/tests/universal/feature_repos/universal/online_store/couchbase.py": [ - { - "type": "Secret Keyword", - "filename": "sdk/python/tests/universal/feature_repos/universal/online_store/couchbase.py", - "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", - "is_verified": false, - "line_number": 29 - } - ], - "sdk/python/tests/universal/feature_repos/universal/online_store/mysql.py": [ - { - "type": "Secret Keyword", - "filename": "sdk/python/tests/universal/feature_repos/universal/online_store/mysql.py", - "hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", - "is_verified": false, - "line_number": 27 - } - ], - "sdk/python/tests/universal/feature_repos/universal/online_store/postgres.py": [ - { - "type": "Secret Keyword", - "filename": "sdk/python/tests/universal/feature_repos/universal/online_store/postgres.py", - "hashed_secret": "95433727ea51026e1e0dc8deadaabd4a3baaaaf4", - "is_verified": false, - "line_number": 19 - } - ], - "sdk/python/tests/universal/feature_repos/universal/online_store/singlestore.py": [ - { - "type": "Base64 High Entropy String", - "filename": "sdk/python/tests/universal/feature_repos/universal/online_store/singlestore.py", - "hashed_secret": "6f7c6dea79de6f298be425ade30f5afbbb6f8047", - "is_verified": false, - "line_number": 24 - }, - { - "type": "Secret Keyword", - "filename": "sdk/python/tests/universal/feature_repos/universal/online_store/singlestore.py", - "hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", - "is_verified": false, - "line_number": 37 - } - ], "sdk/python/tests/integration/offline_store/test_s3_custom_endpoint.py": [ { "type": "AWS Access Key", @@ -1529,6 +1454,81 @@ "line_number": 31 } ], + "sdk/python/tests/universal/feature_repos/repo_configuration.py": [ + { + "type": "Secret Keyword", + "filename": "sdk/python/tests/universal/feature_repos/repo_configuration.py", + "hashed_secret": "d90e76ef629fb00c95f4e84fec29fbda111e2392", + "is_verified": false, + "line_number": 452 + }, + { + "type": "Secret Keyword", + "filename": "sdk/python/tests/universal/feature_repos/repo_configuration.py", + "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", + "is_verified": false, + "line_number": 454 + } + ], + "sdk/python/tests/universal/feature_repos/universal/data_sources/file.py": [ + { + "type": "Base64 High Entropy String", + "filename": "sdk/python/tests/universal/feature_repos/universal/data_sources/file.py", + "hashed_secret": "d70eab08607a4d05faa2d0d6647206599e9abc65", + "is_verified": false, + "line_number": 257 + }, + { + "type": "Secret Keyword", + "filename": "sdk/python/tests/universal/feature_repos/universal/data_sources/file.py", + "hashed_secret": "d70eab08607a4d05faa2d0d6647206599e9abc65", + "is_verified": false, + "line_number": 257 + } + ], + "sdk/python/tests/universal/feature_repos/universal/online_store/couchbase.py": [ + { + "type": "Secret Keyword", + "filename": "sdk/python/tests/universal/feature_repos/universal/online_store/couchbase.py", + "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", + "is_verified": false, + "line_number": 29 + } + ], + "sdk/python/tests/universal/feature_repos/universal/online_store/mysql.py": [ + { + "type": "Secret Keyword", + "filename": "sdk/python/tests/universal/feature_repos/universal/online_store/mysql.py", + "hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", + "is_verified": false, + "line_number": 27 + } + ], + "sdk/python/tests/universal/feature_repos/universal/online_store/postgres.py": [ + { + "type": "Secret Keyword", + "filename": "sdk/python/tests/universal/feature_repos/universal/online_store/postgres.py", + "hashed_secret": "95433727ea51026e1e0dc8deadaabd4a3baaaaf4", + "is_verified": false, + "line_number": 19 + } + ], + "sdk/python/tests/universal/feature_repos/universal/online_store/singlestore.py": [ + { + "type": "Base64 High Entropy String", + "filename": "sdk/python/tests/universal/feature_repos/universal/online_store/singlestore.py", + "hashed_secret": "6f7c6dea79de6f298be425ade30f5afbbb6f8047", + "is_verified": false, + "line_number": 24 + }, + { + "type": "Secret Keyword", + "filename": "sdk/python/tests/universal/feature_repos/universal/online_store/singlestore.py", + "hashed_secret": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", + "is_verified": false, + "line_number": 37 + } + ], "sdk/python/tests/utils/auth_permissions_util.py": [ { "type": "Secret Keyword", @@ -1539,5 +1539,5 @@ } ] }, - "generated_at": "2026-03-03T05:01:02Z" + "generated_at": "2026-03-05T15:25:10Z" } diff --git a/infra/feast-operator/api/v1/featurestore_types.go b/infra/feast-operator/api/v1/featurestore_types.go index c97c9c7dd00..020f6f96415 100644 --- a/infra/feast-operator/api/v1/featurestore_types.go +++ b/infra/feast-operator/api/v1/featurestore_types.go @@ -475,6 +475,7 @@ var ValidOnlineStoreDBStorePersistenceTypes = []string{ "couchbase.online", "milvus", "hybrid", + "mongodb", } // LocalRegistryConfig configures the registry service diff --git a/infra/feast-operator/api/v1alpha1/featurestore_types.go b/infra/feast-operator/api/v1alpha1/featurestore_types.go index bb1d7ddf21d..13847bc5a62 100644 --- a/infra/feast-operator/api/v1alpha1/featurestore_types.go +++ b/infra/feast-operator/api/v1alpha1/featurestore_types.go @@ -396,6 +396,7 @@ var ValidOnlineStoreDBStorePersistenceTypes = []string{ "couchbase.online", "milvus", "hybrid", + "mongodb", } // LocalRegistryConfig configures the registry service From 6147c87121ff111aac5d0e9317c9a7bceb1b972d Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Thu, 5 Mar 2026 13:50:17 -0500 Subject: [PATCH 40/47] feat: add Feast driver metadata to MongoDB client instantiations Add DriverInfo with the Feast name and version to both the sync MongoClient and async AsyncMongoClient so that MongoDB can identify traffic originating from a Feast AI integration. Signed-off-by: Casey Clements --- .../online_stores/mongodb_online_store/mongodb.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) 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 b588791e17a..f10cb56afb7 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 @@ -8,11 +8,13 @@ from pymongo import AsyncMongoClient, MongoClient, UpdateOne from pymongo.asynchronous.collection import AsyncCollection from pymongo.collection import Collection + from pymongo.driver_info import DriverInfo except ImportError as e: from feast.errors import FeastExtrasDependencyImportError raise FeastExtrasDependencyImportError("mongodb", str(e)) +import feast.version from feast.entity import Entity from feast.feature_view import FeatureView from feast.infra.key_encoding_utils import serialize_entity_key @@ -28,6 +30,8 @@ logger = getLogger(__name__) +DRIVER_METADATA = DriverInfo(name="Feast", version=feast.version.get_version()) + class MongoDBOnlineStoreConfig(FeastConfigBaseModel): """MongoDB configuration. @@ -262,7 +266,9 @@ def _get_client(self, config: RepoConfig): if self._client is None: online_config = config.online_store self._client = MongoClient( - online_config.connection_string, **online_config.client_kwargs + online_config.connection_string, + driver=DRIVER_METADATA, + **online_config.client_kwargs, ) return self._client @@ -286,7 +292,9 @@ async def _get_client_async(self, config: RepoConfig) -> AsyncMongoClient: f"config.online_store passed to _get_client_async is not a MongoDBOnlineStoreConfig. It's of type {type(online_config)}" ) self._client_async = AsyncMongoClient( - online_config.connection_string, **online_config.client_kwargs + online_config.connection_string, + driver=DRIVER_METADATA, + **online_config.client_kwargs, ) return self._client_async From 1492a1ecefd3cf710d3e00d7ebe409e2e9e21dad Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Thu, 5 Mar 2026 14:05:05 -0500 Subject: [PATCH 41/47] docs: update MongoDB online store status from alpha to preview Signed-off-by: Casey Clements --- docs/reference/online-stores/mongodb.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/reference/online-stores/mongodb.md b/docs/reference/online-stores/mongodb.md index c4a9bb72fce..969637b9e68 100644 --- a/docs/reference/online-stores/mongodb.md +++ b/docs/reference/online-stores/mongodb.md @@ -1,11 +1,11 @@ -# MongoDB online store (Alpha) +# MongoDB online store (Preview) ## 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 **alpha development**. Some functionality may be unstable, and breaking changes may occur in future releases. +The MongoDB online store is currently in **preview**. Some functionality may be unstable, and breaking changes may occur in future releases. {% endhint %} ## Features From 0d80772361182980068eb5ff5ececb1aee58c0bb Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Thu, 5 Mar 2026 18:09:23 -0500 Subject: [PATCH 42/47] fix: add mongodb to kubebuilder Enum annotations for OnlineStoreDBStorePersistence The +kubebuilder:validation:Enum annotation on the Type field of OnlineStoreDBStorePersistence was not updated when mongodb was added to ValidOnlineStoreDBStorePersistenceTypes. This annotation drives CRD OpenAPI schema validation at Kubernetes admission time, so any FeatureStore CR specifying type: mongodb would be rejected by the API server. Updated both api/v1 and api/v1alpha1. Signed-off-by: Casey Clements --- infra/feast-operator/api/v1/featurestore_types.go | 2 +- infra/feast-operator/api/v1alpha1/featurestore_types.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/infra/feast-operator/api/v1/featurestore_types.go b/infra/feast-operator/api/v1/featurestore_types.go index 020f6f96415..6aeea91d70e 100644 --- a/infra/feast-operator/api/v1/featurestore_types.go +++ b/infra/feast-operator/api/v1/featurestore_types.go @@ -450,7 +450,7 @@ type OnlineStoreFilePersistence struct { // OnlineStoreDBStorePersistence configures the DB store persistence for the online store service type OnlineStoreDBStorePersistence struct { // Type of the persistence type you want to use. - // +kubebuilder:validation:Enum=snowflake.online;redis;datastore;dynamodb;bigtable;postgres;cassandra;mysql;hazelcast;singlestore;hbase;elasticsearch;qdrant;couchbase.online;milvus;hybrid + // +kubebuilder:validation:Enum=snowflake.online;redis;datastore;dynamodb;bigtable;postgres;cassandra;mysql;hazelcast;singlestore;hbase;elasticsearch;qdrant;couchbase.online;milvus;hybrid;mongodb Type string `json:"type"` // Data store parameters should be placed as-is from the "feature_store.yaml" under the secret key. "registry_type" & "type" fields should be removed. SecretRef corev1.LocalObjectReference `json:"secretRef"` diff --git a/infra/feast-operator/api/v1alpha1/featurestore_types.go b/infra/feast-operator/api/v1alpha1/featurestore_types.go index 13847bc5a62..23af949390c 100644 --- a/infra/feast-operator/api/v1alpha1/featurestore_types.go +++ b/infra/feast-operator/api/v1alpha1/featurestore_types.go @@ -371,7 +371,7 @@ type OnlineStoreFilePersistence struct { // OnlineStoreDBStorePersistence configures the DB store persistence for the online store service type OnlineStoreDBStorePersistence struct { // Type of the persistence type you want to use. - // +kubebuilder:validation:Enum=snowflake.online;redis;datastore;dynamodb;bigtable;postgres;cassandra;mysql;hazelcast;singlestore;hbase;elasticsearch;qdrant;couchbase.online;milvus;hybrid + // +kubebuilder:validation:Enum=snowflake.online;redis;datastore;dynamodb;bigtable;postgres;cassandra;mysql;hazelcast;singlestore;hbase;elasticsearch;qdrant;couchbase.online;milvus;hybrid;mongodb Type string `json:"type"` // Data store parameters should be placed as-is from the "feature_store.yaml" under the secret key. "registry_type" & "type" fields should be removed. SecretRef corev1.LocalObjectReference `json:"secretRef"` From 7563f113e2f242a232e557d8dfdeee6371b25f65 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Fri, 6 Mar 2026 12:39:32 -0500 Subject: [PATCH 43/47] Update +GOLANGCI_LINT_VERSION to fix upstream issue golang/go#74462 Signed-off-by: Casey Clements --- infra/feast-operator/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/feast-operator/Makefile b/infra/feast-operator/Makefile index f017154d39d..a1ccee8d049 100644 --- a/infra/feast-operator/Makefile +++ b/infra/feast-operator/Makefile @@ -243,7 +243,7 @@ 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.59.1 +GOLANGCI_LINT_VERSION ?= v1.63.4 ENVSUBST_VERSION ?= v1.4.2 .PHONY: kustomize From 26ad3bba54e6b499d0f4249188b0ce4a2db26913 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Fri, 6 Mar 2026 13:55:13 -0500 Subject: [PATCH 44/47] fix: raise ValueError in _get_client_async for invalid config type, consistent with sync counterpart Signed-off-by: Casey Clements --- .../feast/infra/online_stores/mongodb_online_store/mongodb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 f10cb56afb7..d8dafb0d48d 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 @@ -288,8 +288,8 @@ async def _get_client_async(self, config: RepoConfig) -> AsyncMongoClient: if self._client_async is None: online_config = config.online_store if not isinstance(online_config, MongoDBOnlineStoreConfig): - logger.warning( - f"config.online_store passed to _get_client_async is not a MongoDBOnlineStoreConfig. It's of type {type(online_config)}" + raise ValueError( + f"config.online_store should be MongoDBOnlineStoreConfig, got {online_config}" ) self._client_async = AsyncMongoClient( online_config.connection_string, From 2f92af9571e29955885014760d992765572f6dea Mon Sep 17 00:00:00 2001 From: ntkathole Date: Mon, 9 Mar 2026 14:29:49 +0530 Subject: [PATCH 45/47] fix: Added mongodb to operator yamls Signed-off-by: ntkathole --- .../config/crd/bases/feast.dev_featurestores.yaml | 4 ++++ infra/feast-operator/dist/install.yaml | 4 ++++ 2 files changed, 8 insertions(+) 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 76f134dbbed..b5888f12f40 100644 --- a/infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml +++ b/infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml @@ -2140,6 +2140,7 @@ spec: - couchbase.online - milvus - hybrid + - mongodb type: string required: - secretRef @@ -7857,6 +7858,7 @@ spec: - couchbase.online - milvus - hybrid + - mongodb type: string required: - secretRef @@ -12952,6 +12954,7 @@ spec: - couchbase.online - milvus - hybrid + - mongodb type: string required: - secretRef @@ -17171,6 +17174,7 @@ spec: - couchbase.online - milvus - hybrid + - mongodb type: string required: - secretRef diff --git a/infra/feast-operator/dist/install.yaml b/infra/feast-operator/dist/install.yaml index 00cc56e6554..669ba09fcd0 100644 --- a/infra/feast-operator/dist/install.yaml +++ b/infra/feast-operator/dist/install.yaml @@ -2148,6 +2148,7 @@ spec: - couchbase.online - milvus - hybrid + - mongodb type: string required: - secretRef @@ -7865,6 +7866,7 @@ spec: - couchbase.online - milvus - hybrid + - mongodb type: string required: - secretRef @@ -12960,6 +12962,7 @@ spec: - couchbase.online - milvus - hybrid + - mongodb type: string required: - secretRef @@ -17179,6 +17182,7 @@ spec: - couchbase.online - milvus - hybrid + - mongodb type: string required: - secretRef From 577f2a70561602330059945598a9c448582b48b5 Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Mon, 9 Mar 2026 10:38:13 -0400 Subject: [PATCH 46/47] Small change suggested by ntkathole Signed-off-by: Casey Clements --- .../feast/infra/online_stores/mongodb_online_store/mongodb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 d8dafb0d48d..37a75a19fe5 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 @@ -209,7 +209,7 @@ def update( We remove any feature views named in tables_to_delete. The Entities are serialized in the _id. No schema needs be adjusted. """ - if config.online_store.type != "mongodb": + if not isinstance(config.online_store, MongoDBOnlineStoreConfig): raise RuntimeError(f"{config.online_store.type = }. It must be mongodb.") clxn = self._get_collection(repo_config=config) From e761e104b8aafe4b7b836bca731ecf70c68b50cd Mon Sep 17 00:00:00 2001 From: Casey Clements Date: Mon, 9 Mar 2026 10:55:43 -0400 Subject: [PATCH 47/47] Factor out write logic into utility function making sync/async essentially identical. Signed-off-by: Casey Clements --- .../mongodb_online_store/mongodb.py | 96 ++++++++++--------- 1 file changed, 49 insertions(+), 47 deletions(-) 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 37a75a19fe5..3e7a3db84c8 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 @@ -85,31 +85,35 @@ class MongoDBOnlineStore(OnlineStore): _client_async: Optional[AsyncMongoClient] = None _collection_async: Optional[AsyncCollection] = None - def online_write_batch( - self, + @staticmethod + def _build_write_ops( config: RepoConfig, table: FeatureView, data: List[ Tuple[EntityKeyProto, Dict[str, ValueProto], datetime, Optional[datetime]] ], - progress: Optional[Callable[[int], Any]] = None, - ) -> None: + ) -> List[UpdateOne]: + """Build the list of UpdateOne upsert operations shared by the sync and async write paths. + + For each row in *data* this method: + + 1. Serializes the entity key to bytes using ``serialize_entity_key``. + 2. Converts every ``ValueProto`` feature value to its native Python type + via ``feast_value_type_to_python_type``. + 3. Constructs a ``$set`` update document that writes feature values under + ``features..``, the per-view event + timestamp under ``event_timestamps.``, and the + row-level ``created_timestamp``. + 4. Wraps that in a ``UpdateOne`` with ``upsert=True`` so that existing + entity documents are updated in-place and new ones are created on first + write. + + The caller is responsible for executing the returned operations via + ``collection.bulk_write(ops, ordered=False)`` (sync) or + ``await collection.bulk_write(ops, ordered=False)`` (async). """ - Writes a batch of feature values to the online store. - - data: - [ - {(} - entity_key_bytes, - { feature_ref: ValueProto }, - { feature_view_name: event_timestamp_unix } - ) - ] - """ - clxn = self._get_collection(config) ops = [] - for row in data: - entity_key, proto_values, event_timestamp, created_timestamp = row + for entity_key, proto_values, event_timestamp, created_timestamp in data: entity_id = serialize_entity_key( entity_key, entity_key_serialization_version=config.entity_key_serialization_version, @@ -132,6 +136,32 @@ def online_write_batch( upsert=True, ) ) + return ops + + def online_write_batch( + self, + config: RepoConfig, + table: FeatureView, + data: List[ + Tuple[EntityKeyProto, Dict[str, ValueProto], datetime, Optional[datetime]] + ], + progress: Optional[Callable[[int], Any]] = None, + ) -> None: + """ + Writes a batch of feature values to the online store. + + data: + [ + ( + entity_key_bytes, + { feature_ref: ValueProto }, + event_timestamp, + created_timestamp, + ) + ] + """ + clxn = self._get_collection(config) + ops = self._build_write_ops(config, table, data) if ops: clxn.bulk_write(ops, ordered=False) if progress: @@ -457,37 +487,9 @@ async def online_write_batch_async( progress: Optional progress callback """ clxn = await self._get_collection_async(config) - ops = [] - for row in data: - entity_key_proto, features, event_ts, created_ts = row - entity_id = serialize_entity_key( - entity_key_proto, - entity_key_serialization_version=config.entity_key_serialization_version, - ) - - # Convert ValueProto to native Python types - feature_dict = {} - for feature_name, value_proto in features.items(): - feature_dict[feature_name] = feast_value_type_to_python_type( - value_proto - ) - - # Build update operation - update_doc = { - "$set": { - f"features.{table.name}.{feature_name}": value - for feature_name, value in feature_dict.items() - }, - } - update_doc["$set"][f"event_timestamps.{table.name}"] = event_ts - update_doc["$set"]["created_timestamp"] = created_ts - - ops.append(UpdateOne({"_id": entity_id}, update_doc, upsert=True)) - - # Execute bulk write asynchronously + ops = self._build_write_ops(config, table, data) if ops: await clxn.bulk_write(ops, ordered=False) - if progress: progress(len(data))