ipulse-shared-core-ftredge 27.2.0__tar.gz → 27.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ipulse-shared-core-ftredge might be problematic. Click here for more details.
- {ipulse_shared_core_ftredge-27.2.0/src/ipulse_shared_core_ftredge.egg-info → ipulse_shared_core_ftredge-27.3.0}/PKG-INFO +1 -1
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/setup.py +1 -1
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/models/time_series_packaged_dataset_model.py +9 -7
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/__init__.py +1 -1
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/base/__init__.py +1 -0
- ipulse_shared_core_ftredge-27.3.0/src/ipulse_shared_core_ftredge/services/base/multi_collection_cache_aware_firestore_service.py +244 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0/src/ipulse_shared_core_ftredge.egg-info}/PKG-INFO +1 -1
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge.egg-info/SOURCES.txt +1 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/LICENCE +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/README.md +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/pyproject.toml +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/setup.cfg +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/__init__.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/cache/__init__.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/cache/shared_cache.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/dependencies/__init__.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/dependencies/auth_firebase_token_validation.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/dependencies/auth_protected_router.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/dependencies/authz_credit_extraction.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/dependencies/authz_for_apis.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/dependencies/firestore_client.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/exceptions/__init__.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/exceptions/base_exceptions.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/exceptions/user_exceptions.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/models/__init__.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/models/base_api_response.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/models/base_data_model.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/models/catalog/__init__.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/models/catalog/subscriptionplan.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/models/catalog/usertype.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/models/credit_api_response.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/models/custom_json_response.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/models/user/__init__.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/models/user/user_permissions.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/models/user/user_subscription.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/models/user/userauth.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/models/user/userprofile.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/models/user/userstatus.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/monitoring/__init__.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/monitoring/tracemon.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/base/base_firestore_service.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/base/cache_aware_firestore_service.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/catalog/__init__.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/catalog/catalog_subscriptionplan_service.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/catalog/catalog_usertype_service.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/charging_processors.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/user/__init__.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/user/user_charging_operations.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/user/user_core_service.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/user/user_multistep_operations.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/user/user_permissions_operations.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/user/user_subscription_operations.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/user/userauth_operations.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/user/userprofile_operations.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/user/userstatus_operations.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/services/user_charging_service.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/utils/__init__.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/utils/authz_credit_extraction.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/utils/custom_json_encoder.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge/utils/json_encoder.py +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge.egg-info/dependency_links.txt +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge.egg-info/requires.txt +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/src/ipulse_shared_core_ftredge.egg-info/top_level.txt +0 -0
- {ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/tests/test_shared_cache.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ipulse_shared_core_ftredge
|
|
3
|
-
Version: 27.
|
|
3
|
+
Version: 27.3.0
|
|
4
4
|
Summary: Shared Core models and Logger util for the Pulse platform project. Using AI for financial advisory and investment management.
|
|
5
5
|
Home-page: https://github.com/TheFutureEdge/ipulse_shared_core
|
|
6
6
|
Author: Russlan Ramdowar
|
|
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages
|
|
|
3
3
|
|
|
4
4
|
setup(
|
|
5
5
|
name='ipulse_shared_core_ftredge',
|
|
6
|
-
version='27.
|
|
6
|
+
version='27.3.0',
|
|
7
7
|
package_dir={'': 'src'}, # Specify the source directory
|
|
8
8
|
packages=find_packages(where='src'), # Look for packages in 'src'
|
|
9
9
|
install_requires=[
|
|
@@ -3,7 +3,6 @@ from typing import List, Optional, TypeVar, Generic
|
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
from pydantic import Field, BaseModel
|
|
5
5
|
from ipulse_shared_core_ftredge.models.base_data_model import BaseDataModel
|
|
6
|
-
from ipulse_shared_base_ftredge.enums import DatasetLineage, DatasetScope
|
|
7
6
|
|
|
8
7
|
# Generic type for the records within the dataset
|
|
9
8
|
RecordsSamplingType = TypeVar('RecordsSamplingType', bound=BaseModel)
|
|
@@ -13,11 +12,14 @@ class TimeSeriesPackagedDatasetModel(BaseDataModel, Generic[RecordsSamplingType]
|
|
|
13
12
|
An intermediary model for time series datasets that holds aggregated records.
|
|
14
13
|
It provides a generic way to handle different types of time series records.
|
|
15
14
|
"""
|
|
16
|
-
|
|
15
|
+
# Subject identification fields
|
|
16
|
+
subject_id: str = Field(default="", description="The unique identifier for the subject.")
|
|
17
|
+
pulse_sector_category: str = Field(default="", description="The sector category for the subject.")
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
# Schema identification fields
|
|
20
|
+
schema_id: str = Field(default="", description="The unique identifier for the schema.")
|
|
21
|
+
schema_name: str = Field(default="", description="The name of the schema.")
|
|
22
|
+
schema_version: int = Field(default=1, description="The version of the schema.")
|
|
21
23
|
|
|
22
24
|
# Generic lists for different temporal buckets of records
|
|
23
25
|
max_bulk_records: List[RecordsSamplingType] = Field(default_factory=list)
|
|
@@ -39,5 +41,5 @@ class TimeSeriesPackagedDatasetModel(BaseDataModel, Generic[RecordsSamplingType]
|
|
|
39
41
|
|
|
40
42
|
@property
|
|
41
43
|
def id(self) -> str:
|
|
42
|
-
"""Return
|
|
43
|
-
return self.
|
|
44
|
+
"""Return subject_id for backward compatibility and consistency."""
|
|
45
|
+
return self.subject_id
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
# Import from base services
|
|
5
|
-
from .base import BaseFirestoreService, CacheAwareFirestoreService
|
|
5
|
+
from .base import BaseFirestoreService, CacheAwareFirestoreService, MultiCollectionCacheAwareFirestoreService
|
|
6
6
|
|
|
7
7
|
from .charging_processors import ChargingProcessor
|
|
8
8
|
from .user_charging_service import UserChargingService
|
|
@@ -7,6 +7,7 @@ preventing circular import dependencies.
|
|
|
7
7
|
|
|
8
8
|
from .base_firestore_service import BaseFirestoreService
|
|
9
9
|
from .cache_aware_firestore_service import CacheAwareFirestoreService
|
|
10
|
+
from .multi_collection_cache_aware_firestore_service import MultiCollectionCacheAwareFirestoreService
|
|
10
11
|
|
|
11
12
|
__all__ = [
|
|
12
13
|
'BaseFirestoreService',
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Generic multi-collection cache-aware Firestore service.
|
|
3
|
+
|
|
4
|
+
This service extends CacheAwareFirestoreService to support dynamic collection operations
|
|
5
|
+
while maintaining all proven infrastructure patterns. It's designed to be generic and
|
|
6
|
+
reusable across different model types.
|
|
7
|
+
"""
|
|
8
|
+
from typing import Dict, Any, List, Optional, Union, Type, TypeVar, Generic
|
|
9
|
+
from google.cloud import firestore
|
|
10
|
+
from .cache_aware_firestore_service import CacheAwareFirestoreService
|
|
11
|
+
from ...exceptions import ServiceError, ValidationError, ResourceNotFoundError
|
|
12
|
+
from ...cache.shared_cache import SharedCache
|
|
13
|
+
from ...models import BaseDataModel
|
|
14
|
+
import logging
|
|
15
|
+
|
|
16
|
+
# Generic type for BaseDataModel subclasses
|
|
17
|
+
T = TypeVar('T', bound=BaseDataModel)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class MultiCollectionCacheAwareFirestoreService(CacheAwareFirestoreService[T], Generic[T]):
|
|
21
|
+
"""
|
|
22
|
+
Generic multi-collection extension of CacheAwareFirestoreService.
|
|
23
|
+
|
|
24
|
+
This service extends the proven CacheAwareFirestoreService infrastructure to support
|
|
25
|
+
dynamic collection operations based on storage_location_path while maintaining
|
|
26
|
+
all caching, error handling, and CRUD capabilities.
|
|
27
|
+
|
|
28
|
+
This is a generic base class that can be extended for specific model types.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self,
|
|
32
|
+
db: firestore.Client,
|
|
33
|
+
logger: logging.Logger,
|
|
34
|
+
model_class: Type[T],
|
|
35
|
+
resource_type: str,
|
|
36
|
+
base_collection_name: str,
|
|
37
|
+
timeout: float = 30.0):
|
|
38
|
+
|
|
39
|
+
# Initialize the parent CacheAwareFirestoreService with a base collection
|
|
40
|
+
# We'll override the collection_name dynamically per operation
|
|
41
|
+
super().__init__(
|
|
42
|
+
db=db,
|
|
43
|
+
collection_name=base_collection_name, # Base collection name
|
|
44
|
+
resource_type=resource_type,
|
|
45
|
+
model_class=model_class,
|
|
46
|
+
logger=logger,
|
|
47
|
+
document_cache=None, # We'll manage caches per collection
|
|
48
|
+
collection_cache=None, # We'll manage caches per collection
|
|
49
|
+
timeout=timeout
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Cache for per-collection cache instances
|
|
53
|
+
self._collection_caches: Dict[str, Dict[str, SharedCache]] = {}
|
|
54
|
+
|
|
55
|
+
self.logger.info(f"MultiCollectionCacheAwareFirestoreService initialized for {resource_type}")
|
|
56
|
+
|
|
57
|
+
def _get_collection_caches(self, storage_location_path: str) -> Dict[str, SharedCache]:
|
|
58
|
+
"""Get or create cache instances for a specific storage location."""
|
|
59
|
+
if storage_location_path not in self._collection_caches:
|
|
60
|
+
# Create collection-specific cache instances
|
|
61
|
+
# No need for safe_name transformation - dots are fine in strings
|
|
62
|
+
|
|
63
|
+
document_cache = SharedCache(
|
|
64
|
+
name=f"MultiColDoc_{storage_location_path}",
|
|
65
|
+
ttl=600.0, # 10 minutes
|
|
66
|
+
enabled=True,
|
|
67
|
+
logger=self.logger
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
collection_cache = SharedCache(
|
|
71
|
+
name=f"MultiColCollection_{storage_location_path}",
|
|
72
|
+
ttl=600.0, # 10 minutes
|
|
73
|
+
enabled=True,
|
|
74
|
+
logger=self.logger
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
self._collection_caches[storage_location_path] = {
|
|
78
|
+
'document': document_cache,
|
|
79
|
+
'collection': collection_cache
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
self.logger.info(f"Created cache instances for collection: {storage_location_path}")
|
|
83
|
+
|
|
84
|
+
return self._collection_caches[storage_location_path]
|
|
85
|
+
|
|
86
|
+
def _set_collection_context(self, storage_location_path: str):
|
|
87
|
+
"""Set the collection context for the current operation."""
|
|
88
|
+
# Update the collection name for this operation
|
|
89
|
+
self.collection_name = storage_location_path
|
|
90
|
+
|
|
91
|
+
# Update the cache references for this collection
|
|
92
|
+
caches = self._get_collection_caches(storage_location_path)
|
|
93
|
+
self.document_cache = caches['document']
|
|
94
|
+
self.collection_cache = caches['collection']
|
|
95
|
+
|
|
96
|
+
async def get_document_from_collection(self,
|
|
97
|
+
storage_location_path: str,
|
|
98
|
+
doc_id: str,
|
|
99
|
+
convert_to_model: bool = True) -> Union[T, Dict[str, Any], None]:
|
|
100
|
+
"""
|
|
101
|
+
Get a document from a specific collection using the cache-aware infrastructure.
|
|
102
|
+
"""
|
|
103
|
+
try:
|
|
104
|
+
# Set collection context
|
|
105
|
+
self._set_collection_context(storage_location_path)
|
|
106
|
+
|
|
107
|
+
# Use the parent's cache-aware get_document method
|
|
108
|
+
return await super().get_document(doc_id, convert_to_model)
|
|
109
|
+
|
|
110
|
+
except ResourceNotFoundError:
|
|
111
|
+
self.logger.info(f"Document {doc_id} not found in {storage_location_path}")
|
|
112
|
+
return None
|
|
113
|
+
except Exception as e:
|
|
114
|
+
self.logger.error(f"Error getting document {doc_id} from {storage_location_path}: {str(e)}", exc_info=True)
|
|
115
|
+
raise ServiceError(
|
|
116
|
+
operation=f"getting document from {storage_location_path}",
|
|
117
|
+
error=e,
|
|
118
|
+
resource_type=self.resource_type,
|
|
119
|
+
resource_id=doc_id
|
|
120
|
+
) from e
|
|
121
|
+
|
|
122
|
+
async def get_all_documents_from_collection(self,
|
|
123
|
+
storage_location_path: str,
|
|
124
|
+
cache_key: Optional[str] = None) -> List[T]:
|
|
125
|
+
"""
|
|
126
|
+
Get all documents from a specific collection using cache-aware infrastructure.
|
|
127
|
+
"""
|
|
128
|
+
try:
|
|
129
|
+
# Set collection context
|
|
130
|
+
self._set_collection_context(storage_location_path)
|
|
131
|
+
|
|
132
|
+
# Use cache key if not provided
|
|
133
|
+
if not cache_key:
|
|
134
|
+
cache_key = f"all_documents_{storage_location_path}"
|
|
135
|
+
|
|
136
|
+
# Use the parent's cache-aware get_all_documents method
|
|
137
|
+
results = await super().get_all_documents(cache_key=cache_key, as_models=True)
|
|
138
|
+
|
|
139
|
+
# Ensure we return model instances
|
|
140
|
+
model_results: List[T] = []
|
|
141
|
+
for item in results:
|
|
142
|
+
if isinstance(item, BaseDataModel) and self.model_class and isinstance(item, self.model_class):
|
|
143
|
+
model_results.append(item) # type: ignore
|
|
144
|
+
elif isinstance(item, dict) and self.model_class:
|
|
145
|
+
try:
|
|
146
|
+
model_results.append(self.model_class.model_validate(item))
|
|
147
|
+
except Exception as e:
|
|
148
|
+
self.logger.warning(f"Failed to convert dict to model: {e}")
|
|
149
|
+
|
|
150
|
+
return model_results
|
|
151
|
+
|
|
152
|
+
except Exception as e:
|
|
153
|
+
self.logger.error(f"Error getting all documents from {storage_location_path}: {str(e)}", exc_info=True)
|
|
154
|
+
raise ServiceError(
|
|
155
|
+
operation=f"getting all documents from {storage_location_path}",
|
|
156
|
+
error=e,
|
|
157
|
+
resource_type=self.resource_type
|
|
158
|
+
) from e
|
|
159
|
+
|
|
160
|
+
async def create_document_in_collection(self,
|
|
161
|
+
storage_location_path: str,
|
|
162
|
+
doc_id: str,
|
|
163
|
+
data: Union[T, Dict[str, Any]],
|
|
164
|
+
creator_uid: str,
|
|
165
|
+
merge: bool = False) -> Dict[str, Any]:
|
|
166
|
+
"""
|
|
167
|
+
Create a document in a specific collection using cache-aware infrastructure.
|
|
168
|
+
Automatically handles cache invalidation.
|
|
169
|
+
"""
|
|
170
|
+
try:
|
|
171
|
+
# Set collection context
|
|
172
|
+
self._set_collection_context(storage_location_path)
|
|
173
|
+
|
|
174
|
+
# Use the parent's cache-aware create_document method
|
|
175
|
+
return await super().create_document(doc_id, data, creator_uid, merge)
|
|
176
|
+
|
|
177
|
+
except Exception as e:
|
|
178
|
+
self.logger.error(f"Error creating document {doc_id} in {storage_location_path}: {str(e)}", exc_info=True)
|
|
179
|
+
raise ServiceError(
|
|
180
|
+
operation=f"creating document in {storage_location_path}",
|
|
181
|
+
error=e,
|
|
182
|
+
resource_type=self.resource_type,
|
|
183
|
+
resource_id=doc_id
|
|
184
|
+
) from e
|
|
185
|
+
|
|
186
|
+
async def update_document_in_collection(self,
|
|
187
|
+
storage_location_path: str,
|
|
188
|
+
doc_id: str,
|
|
189
|
+
update_data: Dict[str, Any],
|
|
190
|
+
updater_uid: str,
|
|
191
|
+
require_exists: bool = True) -> Dict[str, Any]:
|
|
192
|
+
"""
|
|
193
|
+
Update a document in a specific collection using cache-aware infrastructure.
|
|
194
|
+
Automatically handles cache invalidation.
|
|
195
|
+
"""
|
|
196
|
+
try:
|
|
197
|
+
# Set collection context
|
|
198
|
+
self._set_collection_context(storage_location_path)
|
|
199
|
+
|
|
200
|
+
# Use the parent's cache-aware update_document method
|
|
201
|
+
return await super().update_document(doc_id, update_data, updater_uid, require_exists)
|
|
202
|
+
|
|
203
|
+
except Exception as e:
|
|
204
|
+
self.logger.error(f"Error updating document {doc_id} in {storage_location_path}: {str(e)}", exc_info=True)
|
|
205
|
+
raise ServiceError(
|
|
206
|
+
operation=f"updating document in {storage_location_path}",
|
|
207
|
+
error=e,
|
|
208
|
+
resource_type=self.resource_type,
|
|
209
|
+
resource_id=doc_id
|
|
210
|
+
) from e
|
|
211
|
+
|
|
212
|
+
async def delete_document_from_collection(self,
|
|
213
|
+
storage_location_path: str,
|
|
214
|
+
doc_id: str,
|
|
215
|
+
require_exists: bool = True) -> bool:
|
|
216
|
+
"""
|
|
217
|
+
Delete a document from a specific collection using cache-aware infrastructure.
|
|
218
|
+
Automatically handles cache invalidation.
|
|
219
|
+
"""
|
|
220
|
+
try:
|
|
221
|
+
# Set collection context
|
|
222
|
+
self._set_collection_context(storage_location_path)
|
|
223
|
+
|
|
224
|
+
# Use the parent's cache-aware delete_document method
|
|
225
|
+
return await super().delete_document(doc_id, require_exists)
|
|
226
|
+
|
|
227
|
+
except Exception as e:
|
|
228
|
+
self.logger.error(f"Error deleting document {doc_id} from {storage_location_path}: {str(e)}", exc_info=True)
|
|
229
|
+
raise ServiceError(
|
|
230
|
+
operation=f"deleting document from {storage_location_path}",
|
|
231
|
+
error=e,
|
|
232
|
+
resource_type=self.resource_type,
|
|
233
|
+
resource_id=doc_id
|
|
234
|
+
) from e
|
|
235
|
+
|
|
236
|
+
def get_cache_stats(self) -> Dict[str, Any]:
|
|
237
|
+
"""Get cache statistics for all collections managed by this service."""
|
|
238
|
+
stats = {}
|
|
239
|
+
for storage_path, caches in self._collection_caches.items():
|
|
240
|
+
stats[storage_path] = {
|
|
241
|
+
'document_cache': caches['document'].get_stats(),
|
|
242
|
+
'collection_cache': caches['collection'].get_stats()
|
|
243
|
+
}
|
|
244
|
+
return stats
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ipulse_shared_core_ftredge
|
|
3
|
-
Version: 27.
|
|
3
|
+
Version: 27.3.0
|
|
4
4
|
Summary: Shared Core models and Logger util for the Pulse platform project. Using AI for financial advisory and investment management.
|
|
5
5
|
Home-page: https://github.com/TheFutureEdge/ipulse_shared_core
|
|
6
6
|
Author: Russlan Ramdowar
|
|
@@ -42,6 +42,7 @@ src/ipulse_shared_core_ftredge/services/user_charging_service.py
|
|
|
42
42
|
src/ipulse_shared_core_ftredge/services/base/__init__.py
|
|
43
43
|
src/ipulse_shared_core_ftredge/services/base/base_firestore_service.py
|
|
44
44
|
src/ipulse_shared_core_ftredge/services/base/cache_aware_firestore_service.py
|
|
45
|
+
src/ipulse_shared_core_ftredge/services/base/multi_collection_cache_aware_firestore_service.py
|
|
45
46
|
src/ipulse_shared_core_ftredge/services/catalog/__init__.py
|
|
46
47
|
src/ipulse_shared_core_ftredge/services/catalog/catalog_subscriptionplan_service.py
|
|
47
48
|
src/ipulse_shared_core_ftredge/services/catalog/catalog_usertype_service.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipulse_shared_core_ftredge-27.2.0 → ipulse_shared_core_ftredge-27.3.0}/tests/test_shared_cache.py
RENAMED
|
File without changes
|