neuroglia-python 0.7.3__tar.gz → 0.7.5__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.
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/PKG-INFO +1 -1
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/pyproject.toml +1 -1
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/__init__.py +1 -1
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/event_sourcing/event_sourcing_repository.py +13 -3
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/mongo/mongo_repository.py +3 -3
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/mongo/motor_query.py +5 -4
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/mongo/motor_repository.py +98 -9
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/queryable.py +68 -13
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/hosting/configuration/data_access_layer.py +79 -17
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/LICENSE +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/README.md +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/application/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/application/background_scheduler.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/coordination/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/coordination/abstractions.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/coordination/leader_election.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/coordination/redis_backend.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/core/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/core/module_loader.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/core/operation_result.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/core/problem_details.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/core/type_extensions.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/core/type_finder.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/core/type_registry.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/abstractions.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/exceptions.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/abstractions.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/event_sourcing/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/event_sourcing/abstractions.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/event_sourcing/event_store/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/event_sourcing/event_store/event_store.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/event_sourcing/read_model_reconciliator.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/filesystem/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/filesystem/filesystem_repository.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/memory/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/memory/memory_repository.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/mongo/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/mongo/enhanced_mongo_repository.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/mongo/serialization_helper.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/mongo/typed_mongo_query.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/resources/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/resources/in_memory_storage_backend.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/resources/postgres_resource_store.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/resources/redis_resource_store.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/resources/resource_repository.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/tracing_mixin.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/queries/generic/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/queries/generic/get_by_id_query.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/queries/generic/list_query.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/resources/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/resources/abstractions.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/resources/controller.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/resources/serializers/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/resources/serializers/xml_serializer.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/resources/serializers/yaml_serializer.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/resources/state_machine.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/resources/watcher.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/unit_of_work.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/dependency_injection/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/dependency_injection/service_provider.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/dependency_injection/service_provider_backup.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/eventing/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/eventing/cloud_events/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/eventing/cloud_events/cloud_event.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/eventing/cloud_events/decorators.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/eventing/cloud_events/infrastructure/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_bus.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_ingestor.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_middleware.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_publisher.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/eventing/tracing.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/expressions/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/expressions/javascript_expression_translator.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/extensions/cqrs_metrics_extensions.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/extensions/mediator_extensions.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/extensions/state_persistence_extensions.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/hosting/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/hosting/abstractions.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/hosting/web.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/integration/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/integration/cache_repository.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/integration/http_service_client.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/integration/models.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/logging/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/logging/logger.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/mapping/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/mapping/mapper.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/mediation/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/mediation/behaviors/domain_event_cloudevent_behavior.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/mediation/behaviors/domain_event_dispatching_middleware.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/mediation/mediator.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/mediation/metrics_middleware.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/mediation/pipeline_behavior.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/mediation/simple.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/mediation/tracing_middleware.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/mvc/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/mvc/controller_base.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/observability/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/observability/framework.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/observability/logging.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/observability/metrics.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/observability/otel_sdk.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/observability/settings.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/observability/tracing.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/py.typed +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/reactive/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/reactive/rx_async.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/serialization/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/serialization/abstractions.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/serialization/aggregate_serializer.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/serialization/json.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/utils/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/utils/camel_model.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/utils/case_conversion.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/validation/__init__.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/validation/business_rules.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/validation/exceptions.py +0 -0
- {neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/validation/validators.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "neuroglia-python"
|
|
3
|
-
version = "0.7.
|
|
3
|
+
version = "0.7.5"
|
|
4
4
|
description = "Port from .NET to Python of the Neuroglia Framework"
|
|
5
5
|
authors = ["Charles d'Avernas <charles.davernas@neuroglia.io>", "Bruno van de Werve <bvandewe@gmail.com>"]
|
|
6
6
|
license = "Apache"
|
|
@@ -113,10 +113,20 @@ class EventSourcingRepository(Generic[TAggregate, TKey], Repository[TAggregate,
|
|
|
113
113
|
return self._eventstore.contains_stream(self._build_stream_id_for(id))
|
|
114
114
|
|
|
115
115
|
async def get_async(self, id: TKey) -> Optional[TAggregate]:
|
|
116
|
-
"""
|
|
116
|
+
"""
|
|
117
|
+
Gets the aggregate with the specified id, if any.
|
|
118
|
+
|
|
119
|
+
Returns None if the stream does not exist.
|
|
120
|
+
"""
|
|
117
121
|
stream_id = self._build_stream_id_for(id)
|
|
118
|
-
|
|
119
|
-
|
|
122
|
+
try:
|
|
123
|
+
events = await self._eventstore.read_async(stream_id, StreamReadDirection.FORWARDS, 0)
|
|
124
|
+
if not events:
|
|
125
|
+
return None
|
|
126
|
+
return self._aggregator.aggregate(events, self.__orig_class__.__args__[0])
|
|
127
|
+
except Exception:
|
|
128
|
+
# If stream doesn't exist or any other error occurs, return None
|
|
129
|
+
return None
|
|
120
130
|
|
|
121
131
|
async def _do_add_async(self, aggregate: TAggregate) -> TAggregate:
|
|
122
132
|
"""Adds and persists the specified aggregate"""
|
|
@@ -38,8 +38,8 @@ class MongoRepositoryOptions(Generic[TEntity, TKey]):
|
|
|
38
38
|
class MongoQuery(Generic[T], Queryable[T]):
|
|
39
39
|
"""Represents a Mongo query"""
|
|
40
40
|
|
|
41
|
-
def __init__(self, query_provider: "MongoQueryProvider", expression: Optional[expr] = None):
|
|
42
|
-
super().__init__(query_provider, expression)
|
|
41
|
+
def __init__(self, query_provider: "MongoQueryProvider", expression: Optional[expr] = None, element_type: Optional[type] = None):
|
|
42
|
+
super().__init__(query_provider, expression, element_type)
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
class MongoQueryBuilder(NodeVisitor):
|
|
@@ -114,7 +114,7 @@ class MongoQueryProvider(QueryProvider):
|
|
|
114
114
|
_collection: Collection
|
|
115
115
|
|
|
116
116
|
def create_query(self, element_type: type, expression: expr) -> Queryable:
|
|
117
|
-
return MongoQuery
|
|
117
|
+
return MongoQuery(self, expression, element_type)
|
|
118
118
|
|
|
119
119
|
def execute(self, expression: expr, query_type: type) -> Any:
|
|
120
120
|
query = MongoQueryBuilder(self._collection, JavaScriptExpressionTranslator()).build(expression)
|
|
@@ -64,15 +64,16 @@ class MotorQuery(Generic[T], Queryable[T]):
|
|
|
64
64
|
```
|
|
65
65
|
"""
|
|
66
66
|
|
|
67
|
-
def __init__(self, query_provider: "MotorQueryProvider", expression: Optional[expr] = None):
|
|
67
|
+
def __init__(self, query_provider: "MotorQueryProvider", expression: Optional[expr] = None, element_type: Optional[type] = None):
|
|
68
68
|
"""
|
|
69
69
|
Initialize a Motor query.
|
|
70
70
|
|
|
71
71
|
Args:
|
|
72
72
|
query_provider: The Motor query provider
|
|
73
73
|
expression: Optional AST expression for the query
|
|
74
|
+
element_type: Optional element type (used for chaining to preserve type info)
|
|
74
75
|
"""
|
|
75
|
-
super().__init__(query_provider, expression)
|
|
76
|
+
super().__init__(query_provider, expression, element_type)
|
|
76
77
|
|
|
77
78
|
async def to_list_async(self) -> list[T]:
|
|
78
79
|
"""
|
|
@@ -319,9 +320,9 @@ class MotorQueryProvider(QueryProvider):
|
|
|
319
320
|
expression: AST expression for the query
|
|
320
321
|
|
|
321
322
|
Returns:
|
|
322
|
-
New MotorQuery instance
|
|
323
|
+
New MotorQuery instance with element_type propagated
|
|
323
324
|
"""
|
|
324
|
-
return MotorQuery(self, expression)
|
|
325
|
+
return MotorQuery(self, expression, element_type)
|
|
325
326
|
|
|
326
327
|
def execute(self, expression: expr, query_type: type) -> Any:
|
|
327
328
|
"""
|
|
@@ -578,31 +578,68 @@ class MotorRepository(Generic[TEntity, TKey], QueryableRepository[TEntity, TKey]
|
|
|
578
578
|
|
|
579
579
|
return entities
|
|
580
580
|
|
|
581
|
-
async def find_async(
|
|
581
|
+
async def find_async(
|
|
582
|
+
self,
|
|
583
|
+
filter_dict: dict,
|
|
584
|
+
sort: Optional[list[tuple[str, int]]] = None,
|
|
585
|
+
limit: Optional[int] = None,
|
|
586
|
+
skip: Optional[int] = None,
|
|
587
|
+
projection: Optional[dict] = None,
|
|
588
|
+
) -> list[TEntity]:
|
|
582
589
|
"""
|
|
583
|
-
Find entities matching a MongoDB filter query.
|
|
590
|
+
Find entities matching a MongoDB filter query with optional sorting, pagination, and projection.
|
|
584
591
|
|
|
585
|
-
This provides direct access to MongoDB's query language for complex queries
|
|
592
|
+
This provides direct access to MongoDB's query language for complex queries
|
|
593
|
+
with full support for cursor operations.
|
|
586
594
|
|
|
587
595
|
Args:
|
|
588
596
|
filter_dict: MongoDB query filter (e.g., {"state.email": "user@example.com"})
|
|
597
|
+
sort: List of (field, direction) tuples. Direction: 1 for ascending, -1 for descending.
|
|
598
|
+
Example: [("name", 1), ("created_at", -1)]
|
|
599
|
+
limit: Maximum number of documents to return
|
|
600
|
+
skip: Number of documents to skip (for pagination)
|
|
601
|
+
projection: Fields to include/exclude. Example: {"name": 1, "email": 1}
|
|
589
602
|
|
|
590
603
|
Returns:
|
|
591
604
|
List of entities matching the filter
|
|
592
605
|
|
|
593
|
-
|
|
606
|
+
Examples:
|
|
594
607
|
```python
|
|
595
608
|
# Find all active users
|
|
596
609
|
active_users = await repository.find_async({"state.is_active": True})
|
|
597
610
|
|
|
598
|
-
# Find users by email domain
|
|
599
|
-
gmail_users = await repository.find_async(
|
|
600
|
-
"state.email": {"$regex": "@gmail.com$"}
|
|
601
|
-
|
|
611
|
+
# Find users by email domain with sorting
|
|
612
|
+
gmail_users = await repository.find_async(
|
|
613
|
+
{"state.email": {"$regex": "@gmail.com$"}},
|
|
614
|
+
sort=[("state.name", 1)]
|
|
615
|
+
)
|
|
616
|
+
|
|
617
|
+
# Paginated query with sorting
|
|
618
|
+
page_2_users = await repository.find_async(
|
|
619
|
+
{"state.is_active": True},
|
|
620
|
+
sort=[("state.created_at", -1)],
|
|
621
|
+
skip=20,
|
|
622
|
+
limit=10
|
|
623
|
+
)
|
|
624
|
+
|
|
625
|
+
# Query with field projection (only return specific fields)
|
|
626
|
+
users = await repository.find_async(
|
|
627
|
+
{"state.is_active": True},
|
|
628
|
+
projection={"state.name": 1, "state.email": 1}
|
|
629
|
+
)
|
|
602
630
|
```
|
|
603
631
|
"""
|
|
632
|
+
cursor = self.collection.find(filter_dict, projection)
|
|
633
|
+
|
|
634
|
+
if sort:
|
|
635
|
+
cursor = cursor.sort(sort)
|
|
636
|
+
if skip:
|
|
637
|
+
cursor = cursor.skip(skip)
|
|
638
|
+
if limit:
|
|
639
|
+
cursor = cursor.limit(limit)
|
|
640
|
+
|
|
604
641
|
entities = []
|
|
605
|
-
async for doc in
|
|
642
|
+
async for doc in cursor:
|
|
606
643
|
entity = self._deserialize_entity(doc)
|
|
607
644
|
entities.append(entity)
|
|
608
645
|
|
|
@@ -631,6 +668,58 @@ class MotorRepository(Generic[TEntity, TKey], QueryableRepository[TEntity, TKey]
|
|
|
631
668
|
|
|
632
669
|
return self._deserialize_entity(doc)
|
|
633
670
|
|
|
671
|
+
async def count_async(self, filter_dict: Optional[dict] = None) -> int:
|
|
672
|
+
"""
|
|
673
|
+
Count documents matching a MongoDB filter query.
|
|
674
|
+
|
|
675
|
+
Args:
|
|
676
|
+
filter_dict: MongoDB query filter. If None or empty dict, counts all documents.
|
|
677
|
+
|
|
678
|
+
Returns:
|
|
679
|
+
Count of documents matching the filter
|
|
680
|
+
|
|
681
|
+
Examples:
|
|
682
|
+
```python
|
|
683
|
+
# Count all documents
|
|
684
|
+
total_count = await repository.count_async()
|
|
685
|
+
|
|
686
|
+
# Count with filter
|
|
687
|
+
active_count = await repository.count_async({"state.is_active": True})
|
|
688
|
+
|
|
689
|
+
# Useful for pagination
|
|
690
|
+
filter_query = {"state.status": "pending"}
|
|
691
|
+
total_pages = (await repository.count_async(filter_query) + page_size - 1) // page_size
|
|
692
|
+
```
|
|
693
|
+
"""
|
|
694
|
+
filter_dict = filter_dict or {}
|
|
695
|
+
return await self.collection.count_documents(filter_dict)
|
|
696
|
+
|
|
697
|
+
async def exists_async(self, filter_dict: dict) -> bool:
|
|
698
|
+
"""
|
|
699
|
+
Check if any document matches the MongoDB filter query.
|
|
700
|
+
|
|
701
|
+
This is more efficient than count_async for existence checks as it
|
|
702
|
+
stops after finding the first match.
|
|
703
|
+
|
|
704
|
+
Args:
|
|
705
|
+
filter_dict: MongoDB query filter
|
|
706
|
+
|
|
707
|
+
Returns:
|
|
708
|
+
True if at least one document matches, False otherwise
|
|
709
|
+
|
|
710
|
+
Examples:
|
|
711
|
+
```python
|
|
712
|
+
# Check if email already exists
|
|
713
|
+
email_exists = await repository.exists_async({"state.email": "user@example.com"})
|
|
714
|
+
if email_exists:
|
|
715
|
+
raise ValueError("Email already registered")
|
|
716
|
+
|
|
717
|
+
# Check if any active users exist
|
|
718
|
+
has_active = await repository.exists_async({"state.is_active": True})
|
|
719
|
+
```
|
|
720
|
+
"""
|
|
721
|
+
return await self.collection.count_documents(filter_dict, limit=1) > 0
|
|
722
|
+
|
|
634
723
|
@staticmethod
|
|
635
724
|
def configure(
|
|
636
725
|
builder: ApplicationBuilderBase,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import ast
|
|
2
2
|
import inspect
|
|
3
|
-
import os
|
|
4
3
|
from abc import ABC, abstractclassmethod
|
|
5
4
|
from ast import Attribute, Name, NodeTransformer, expr
|
|
6
5
|
from collections.abc import Callable
|
|
@@ -80,9 +79,10 @@ class Queryable(Generic[T]):
|
|
|
80
79
|
- Repository Pattern Guide: https://bvandewe.github.io/pyneuro/patterns/
|
|
81
80
|
"""
|
|
82
81
|
|
|
83
|
-
def __init__(self, provider: QueryProvider, expression: Optional[expr] = None):
|
|
82
|
+
def __init__(self, provider: QueryProvider, expression: Optional[expr] = None, element_type: Optional[type] = None):
|
|
84
83
|
self.provider = provider
|
|
85
84
|
self.expression = ast.Name(id="__query") if expression is None else expression
|
|
85
|
+
self._element_type = element_type
|
|
86
86
|
|
|
87
87
|
expression: expr
|
|
88
88
|
""" Gets the expression that is associated with the queryable """
|
|
@@ -92,6 +92,10 @@ class Queryable(Generic[T]):
|
|
|
92
92
|
|
|
93
93
|
def get_element_type(self) -> type:
|
|
94
94
|
"""Gets the type of elements to query against"""
|
|
95
|
+
# Try explicit element type first (set during chaining)
|
|
96
|
+
if hasattr(self, "_element_type") and self._element_type is not None:
|
|
97
|
+
return self._element_type
|
|
98
|
+
# Fall back to __orig_class__ for initial query creation
|
|
95
99
|
return self.__orig_class__.__args__[0]
|
|
96
100
|
|
|
97
101
|
def first_or_default(self, predicate: Callable[[T], bool] = None) -> T:
|
|
@@ -146,7 +150,9 @@ class Queryable(Generic[T]):
|
|
|
146
150
|
|
|
147
151
|
def order_by(self, selector: Callable[[T], Any]):
|
|
148
152
|
"""Orders the sequence using the specified attribute"""
|
|
149
|
-
|
|
153
|
+
frame = inspect.currentframe().f_back
|
|
154
|
+
frame_info = inspect.getframeinfo(frame)
|
|
155
|
+
selector_source = self._get_lambda_source_code(selector, frame_info.positions.end_col_offset)
|
|
150
156
|
selector_tree = ast.parse(selector_source)
|
|
151
157
|
selector_lambda_expression = selector_tree.body[0].value
|
|
152
158
|
if not isinstance(selector_lambda_expression.body, Attribute):
|
|
@@ -160,7 +166,9 @@ class Queryable(Generic[T]):
|
|
|
160
166
|
|
|
161
167
|
def order_by_descending(self, selector: Callable[[T], Any]):
|
|
162
168
|
"""Orders the sequence in a descending fashion using the specified attribute"""
|
|
163
|
-
|
|
169
|
+
frame = inspect.currentframe().f_back
|
|
170
|
+
frame_info = inspect.getframeinfo(frame)
|
|
171
|
+
selector_source = self._get_lambda_source_code(selector, frame_info.positions.end_col_offset)
|
|
164
172
|
selector_tree = ast.parse(selector_source)
|
|
165
173
|
selector_lambda_expression = selector_tree.body[0].value
|
|
166
174
|
if not isinstance(selector_lambda_expression.body, Attribute):
|
|
@@ -175,8 +183,9 @@ class Queryable(Generic[T]):
|
|
|
175
183
|
def select(self, selector: Callable[[T], Any]):
|
|
176
184
|
"""Projects each element of a sequence into a new form"""
|
|
177
185
|
frame = inspect.currentframe().f_back
|
|
186
|
+
frame_info = inspect.getframeinfo(frame)
|
|
178
187
|
variables = {**frame.f_locals}
|
|
179
|
-
selector_source = self._get_lambda_source_code(selector)
|
|
188
|
+
selector_source = self._get_lambda_source_code(selector, frame_info.positions.end_col_offset)
|
|
180
189
|
selector_tree = ast.parse(selector_source)
|
|
181
190
|
selector_lambda_expression = selector_tree.body[0].value
|
|
182
191
|
if not isinstance(selector_lambda_expression.body, Attribute) and not isinstance(selector_lambda_expression.body, ast.List):
|
|
@@ -239,18 +248,64 @@ class Queryable(Generic[T]):
|
|
|
239
248
|
function (Callable): The lambda to get the source code of
|
|
240
249
|
max_col_offset (int): The maximum column offset to walk the AST tree for the target lamba
|
|
241
250
|
|
|
251
|
+
Returns:
|
|
252
|
+
Optional[str]: The lambda source code, or None if extraction fails
|
|
253
|
+
|
|
242
254
|
Notes:
|
|
243
255
|
Credits to https://gist.github.com/Xion/617c1496ff45f3673a5692c3b0e3f75a
|
|
256
|
+
|
|
257
|
+
This method handles the case where the lambda is on a continuation line
|
|
258
|
+
that starts with '.' (common in method chaining). In such cases, the raw
|
|
259
|
+
source line is invalid Python syntax, so we prepend a dummy identifier
|
|
260
|
+
to make it parseable.
|
|
261
|
+
|
|
262
|
+
For multi-line continuations (backslash or implicit), we only process
|
|
263
|
+
the first line containing the lambda, as that's sufficient for extraction.
|
|
244
264
|
"""
|
|
245
|
-
|
|
246
|
-
|
|
265
|
+
try:
|
|
266
|
+
source_lines, _ = inspect.getsourcelines(function)
|
|
267
|
+
except (OSError, TypeError) as e:
|
|
268
|
+
# Cannot extract source (e.g., built-in functions, C extensions)
|
|
247
269
|
return None
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
None
|
|
253
|
-
|
|
270
|
+
|
|
271
|
+
# For multi-line sources (continuation), use only the first line
|
|
272
|
+
# The lambda itself is typically on the first line
|
|
273
|
+
if len(source_lines) == 0:
|
|
274
|
+
return None
|
|
275
|
+
|
|
276
|
+
# Strip the line and remove trailing backslash if present (line continuation)
|
|
277
|
+
source_text = source_lines[0].strip().rstrip("\\").strip()
|
|
278
|
+
|
|
279
|
+
# Handle continuation lines that start with '.' (method chaining)
|
|
280
|
+
# These are invalid Python syntax on their own
|
|
281
|
+
offset_adjustment = 0
|
|
282
|
+
if source_text.startswith("."):
|
|
283
|
+
source_text = "_" + source_text # Prepend dummy identifier
|
|
284
|
+
offset_adjustment = 1
|
|
285
|
+
|
|
286
|
+
try:
|
|
287
|
+
source_ast = ast.parse(source_text)
|
|
288
|
+
except SyntaxError:
|
|
289
|
+
return None
|
|
290
|
+
|
|
291
|
+
# Adjust max_col_offset if we prepended a dummy identifier
|
|
292
|
+
# Set to None if not provided to match all lambdas
|
|
293
|
+
adjusted_max_col_offset = None
|
|
294
|
+
if max_col_offset is not None:
|
|
295
|
+
adjusted_max_col_offset = max_col_offset + offset_adjustment
|
|
296
|
+
|
|
297
|
+
# Find lambda node within the adjusted column offset
|
|
298
|
+
if adjusted_max_col_offset is not None:
|
|
299
|
+
lambda_node = next(
|
|
300
|
+
(node for node in ast.walk(source_ast) if isinstance(node, ast.Lambda) and node.col_offset <= adjusted_max_col_offset),
|
|
301
|
+
None,
|
|
302
|
+
)
|
|
303
|
+
else:
|
|
304
|
+
lambda_node = next(
|
|
305
|
+
(node for node in ast.walk(source_ast) if isinstance(node, ast.Lambda)),
|
|
306
|
+
None,
|
|
307
|
+
)
|
|
308
|
+
|
|
254
309
|
if lambda_node is None:
|
|
255
310
|
return None
|
|
256
311
|
lambda_text = source_text[lambda_node.col_offset : lambda_node.end_col_offset]
|
|
@@ -23,15 +23,26 @@ class DataAccessLayer:
|
|
|
23
23
|
"""Represents a helper class used to configure an application's Write Model DAL
|
|
24
24
|
|
|
25
25
|
Supports two configuration patterns:
|
|
26
|
-
1. Simplified: Pass
|
|
26
|
+
1. Simplified: Pass database_name, consumer_group, and delete_mode to constructor
|
|
27
27
|
2. Custom: Pass custom repository_setup function to configure()
|
|
28
28
|
|
|
29
29
|
Examples:
|
|
30
|
-
# Simple configuration with
|
|
31
|
-
DataAccessLayer.WriteModel().configure(builder, ["domain.entities"])
|
|
32
|
-
|
|
33
|
-
# With custom delete mode
|
|
30
|
+
# Simple configuration with all required parameters
|
|
34
31
|
from neuroglia.data.infrastructure.event_sourcing.abstractions import DeleteMode
|
|
32
|
+
|
|
33
|
+
DataAccessLayer.WriteModel(
|
|
34
|
+
database_name="myapp",
|
|
35
|
+
consumer_group="myapp_group",
|
|
36
|
+
delete_mode=DeleteMode.HARD
|
|
37
|
+
).configure(builder, ["domain.entities"])
|
|
38
|
+
|
|
39
|
+
# Minimal configuration (uses default delete mode)
|
|
40
|
+
DataAccessLayer.WriteModel(
|
|
41
|
+
database_name="myapp",
|
|
42
|
+
consumer_group="myapp_group"
|
|
43
|
+
).configure(builder, ["domain.entities"])
|
|
44
|
+
|
|
45
|
+
# Legacy: With EventSourcingRepositoryOptions (backwards compatible)
|
|
35
46
|
from neuroglia.data.infrastructure.event_sourcing.event_sourcing_repository import (
|
|
36
47
|
EventSourcingRepositoryOptions
|
|
37
48
|
)
|
|
@@ -49,13 +60,42 @@ class DataAccessLayer:
|
|
|
49
60
|
)
|
|
50
61
|
"""
|
|
51
62
|
|
|
52
|
-
def __init__(
|
|
63
|
+
def __init__(
|
|
64
|
+
self,
|
|
65
|
+
database_name: Optional[str] = None,
|
|
66
|
+
consumer_group: Optional[str] = None,
|
|
67
|
+
delete_mode: Optional["DeleteMode"] = None,
|
|
68
|
+
options: Optional["EventSourcingRepositoryOptions"] = None,
|
|
69
|
+
):
|
|
53
70
|
"""Initialize WriteModel configuration
|
|
54
71
|
|
|
55
72
|
Args:
|
|
56
|
-
|
|
57
|
-
|
|
73
|
+
database_name: Database/stream prefix for event store (e.g., "myapp").
|
|
74
|
+
Internally creates EventStoreOptions and calls ESEventStore.configure().
|
|
75
|
+
consumer_group: Consumer group name for event store subscriptions.
|
|
76
|
+
delete_mode: Optional deletion strategy (DISABLED, SOFT, HARD).
|
|
77
|
+
If not provided, defaults to DISABLED.
|
|
78
|
+
options: Legacy parameter for EventSourcingRepositoryOptions (backwards compatible).
|
|
79
|
+
If database_name is provided, this parameter is ignored.
|
|
80
|
+
|
|
81
|
+
Example:
|
|
82
|
+
```python
|
|
83
|
+
# Simplified configuration (recommended)
|
|
84
|
+
DataAccessLayer.WriteModel(
|
|
85
|
+
database_name="myapp",
|
|
86
|
+
consumer_group="myapp_group",
|
|
87
|
+
delete_mode=DeleteMode.HARD
|
|
88
|
+
).configure(builder, ["domain.entities"])
|
|
89
|
+
|
|
90
|
+
# Legacy (still supported)
|
|
91
|
+
DataAccessLayer.WriteModel(
|
|
92
|
+
options=EventSourcingRepositoryOptions(delete_mode=DeleteMode.HARD)
|
|
93
|
+
).configure(builder, ["domain.entities"])
|
|
94
|
+
```
|
|
58
95
|
"""
|
|
96
|
+
self._database_name = database_name
|
|
97
|
+
self._consumer_group = consumer_group
|
|
98
|
+
self._delete_mode = delete_mode
|
|
59
99
|
self._options = options
|
|
60
100
|
|
|
61
101
|
def configure(self, builder: ApplicationBuilderBase, modules: list[str], repository_setup: Optional[Callable[[ApplicationBuilderBase, type, type], None]] = None) -> ApplicationBuilderBase:
|
|
@@ -66,13 +106,14 @@ class DataAccessLayer:
|
|
|
66
106
|
modules (List[str]): a list containing the names of the modules to scan for aggregate root types
|
|
67
107
|
repository_setup (Optional[Callable[[ApplicationBuilderBase, Type, Type], None]]):
|
|
68
108
|
Optional custom function to setup repositories. If provided, takes precedence over options.
|
|
69
|
-
If not provided, uses simplified configuration with
|
|
109
|
+
If not provided, uses simplified configuration with database_name/consumer_group or options.
|
|
70
110
|
|
|
71
111
|
Returns:
|
|
72
112
|
ApplicationBuilderBase: The configured builder
|
|
73
113
|
|
|
74
114
|
Raises:
|
|
75
115
|
ImportError: If EventSourcingRepository cannot be imported
|
|
116
|
+
ValueError: If database_name is provided without consumer_group
|
|
76
117
|
"""
|
|
77
118
|
# If custom setup provided, use it (backwards compatible)
|
|
78
119
|
if repository_setup is not None:
|
|
@@ -82,7 +123,26 @@ class DataAccessLayer:
|
|
|
82
123
|
repository_setup(builder, aggregate_type, key_type)
|
|
83
124
|
return builder
|
|
84
125
|
|
|
85
|
-
#
|
|
126
|
+
# If database_name provided, configure event store and use simplified configuration
|
|
127
|
+
if self._database_name is not None:
|
|
128
|
+
if self._consumer_group is None:
|
|
129
|
+
raise ValueError("consumer_group is required when database_name is provided")
|
|
130
|
+
|
|
131
|
+
# Configure ESEventStore
|
|
132
|
+
from neuroglia.data.infrastructure.event_sourcing.abstractions import (
|
|
133
|
+
EventStoreOptions,
|
|
134
|
+
)
|
|
135
|
+
from neuroglia.data.infrastructure.event_sourcing.event_store.event_store import (
|
|
136
|
+
ESEventStore,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
event_store_options = EventStoreOptions(
|
|
140
|
+
database_name=self._database_name,
|
|
141
|
+
consumer_group=self._consumer_group,
|
|
142
|
+
)
|
|
143
|
+
ESEventStore.configure(builder, event_store_options)
|
|
144
|
+
|
|
145
|
+
# Otherwise use simplified configuration with options or defaults
|
|
86
146
|
return self._configure_with_options(builder, modules)
|
|
87
147
|
|
|
88
148
|
def _configure_with_options(self, builder: ApplicationBuilderBase, modules: list[str]) -> ApplicationBuilderBase:
|
|
@@ -98,6 +158,7 @@ class DataAccessLayer:
|
|
|
98
158
|
from neuroglia.data.infrastructure.abstractions import Repository
|
|
99
159
|
from neuroglia.data.infrastructure.event_sourcing.abstractions import (
|
|
100
160
|
Aggregator,
|
|
161
|
+
DeleteMode,
|
|
101
162
|
EventStore,
|
|
102
163
|
)
|
|
103
164
|
from neuroglia.data.infrastructure.event_sourcing.event_sourcing_repository import (
|
|
@@ -107,6 +168,9 @@ class DataAccessLayer:
|
|
|
107
168
|
from neuroglia.dependency_injection import ServiceProvider
|
|
108
169
|
from neuroglia.mediation import Mediator
|
|
109
170
|
|
|
171
|
+
# Determine delete mode to use
|
|
172
|
+
delete_mode = self._delete_mode if self._delete_mode is not None else (self._options.delete_mode if self._options else DeleteMode.DISABLED)
|
|
173
|
+
|
|
110
174
|
# Discover and configure each aggregate type
|
|
111
175
|
for module in [ModuleLoader.load(module_name) for module_name in modules]:
|
|
112
176
|
for aggregate_type in TypeFinder.get_types(
|
|
@@ -115,13 +179,11 @@ class DataAccessLayer:
|
|
|
115
179
|
):
|
|
116
180
|
key_type = str # todo: reflect from DTO base type
|
|
117
181
|
|
|
118
|
-
# Create type-specific options
|
|
119
|
-
typed_options =
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
soft_delete_method_name=self._options.soft_delete_method_name,
|
|
124
|
-
)
|
|
182
|
+
# Create type-specific options
|
|
183
|
+
typed_options = EventSourcingRepositoryOptions[aggregate_type, key_type]( # type: ignore
|
|
184
|
+
delete_mode=delete_mode,
|
|
185
|
+
soft_delete_method_name=self._options.soft_delete_method_name if self._options else "mark_as_deleted",
|
|
186
|
+
)
|
|
125
187
|
|
|
126
188
|
# Create factory function with proper closure
|
|
127
189
|
def make_factory(et, kt, opts):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/application/background_scheduler.py
RENAMED
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/coordination/abstractions.py
RENAMED
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/coordination/leader_election.py
RENAMED
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/coordination/redis_backend.py
RENAMED
|
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
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/__init__.py
RENAMED
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/abstractions.py
RENAMED
|
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
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/infrastructure/tracing_mixin.py
RENAMED
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/queries/generic/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/queries/generic/list_query.py
RENAMED
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/resources/abstractions.py
RENAMED
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/resources/controller.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/data/resources/state_machine.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/dependency_injection/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/eventing/cloud_events/__init__.py
RENAMED
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/eventing/cloud_events/cloud_event.py
RENAMED
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/eventing/cloud_events/decorators.py
RENAMED
|
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
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/extensions/mediator_extensions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/integration/cache_repository.py
RENAMED
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/integration/http_service_client.py
RENAMED
|
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
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/mediation/metrics_middleware.py
RENAMED
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/mediation/pipeline_behavior.py
RENAMED
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/mediation/tracing_middleware.py
RENAMED
|
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
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/serialization/abstractions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.7.3 → neuroglia_python-0.7.5}/src/neuroglia/validation/business_rules.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|