neuroglia-python 0.6.22__tar.gz → 0.7.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.
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/PKG-INFO +39 -38
- neuroglia_python-0.7.0/pyproject.toml +97 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/__init__.py +1 -1
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/event_sourcing/__init__.py +0 -2
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/event_sourcing/event_store/event_store.py +3 -3
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/hosting/configuration/data_access_layer.py +98 -44
- neuroglia_python-0.6.22/pyproject.toml +0 -97
- neuroglia_python-0.6.22/src/neuroglia/data/infrastructure/event_sourcing/patches.py +0 -74
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/LICENSE +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/README.md +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/application/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/application/background_scheduler.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/coordination/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/coordination/abstractions.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/coordination/leader_election.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/coordination/redis_backend.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/core/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/core/module_loader.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/core/operation_result.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/core/problem_details.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/core/type_extensions.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/core/type_finder.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/core/type_registry.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/abstractions.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/exceptions.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/abstractions.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/event_sourcing/abstractions.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/event_sourcing/event_sourcing_repository.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/event_sourcing/event_store/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/event_sourcing/read_model_reconciliator.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/filesystem/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/filesystem/filesystem_repository.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/memory/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/memory/memory_repository.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/mongo/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/mongo/enhanced_mongo_repository.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/mongo/mongo_repository.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/mongo/motor_repository.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/mongo/serialization_helper.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/mongo/typed_mongo_query.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/resources/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/resources/in_memory_storage_backend.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/resources/postgres_resource_store.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/resources/redis_resource_store.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/resources/resource_repository.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/tracing_mixin.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/queries/generic/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/queries/generic/get_by_id_query.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/queries/generic/list_query.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/queryable.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/resources/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/resources/abstractions.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/resources/controller.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/resources/serializers/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/resources/serializers/xml_serializer.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/resources/serializers/yaml_serializer.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/resources/state_machine.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/resources/watcher.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/unit_of_work.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/dependency_injection/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/dependency_injection/service_provider.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/dependency_injection/service_provider_backup.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/eventing/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/eventing/cloud_events/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/eventing/cloud_events/cloud_event.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/eventing/cloud_events/decorators.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/eventing/cloud_events/infrastructure/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_bus.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_ingestor.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_middleware.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_publisher.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/eventing/tracing.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/expressions/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/expressions/javascript_expression_translator.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/extensions/cqrs_metrics_extensions.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/extensions/mediator_extensions.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/extensions/state_persistence_extensions.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/hosting/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/hosting/abstractions.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/hosting/web.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/integration/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/integration/cache_repository.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/integration/http_service_client.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/integration/models.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/logging/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/logging/logger.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/mapping/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/mapping/mapper.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/mediation/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/mediation/behaviors/domain_event_cloudevent_behavior.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/mediation/behaviors/domain_event_dispatching_middleware.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/mediation/mediator.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/mediation/metrics_middleware.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/mediation/pipeline_behavior.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/mediation/simple.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/mediation/tracing_middleware.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/mvc/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/mvc/controller_base.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/observability/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/observability/framework.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/observability/logging.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/observability/metrics.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/observability/otel_sdk.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/observability/settings.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/observability/tracing.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/py.typed +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/reactive/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/reactive/rx_async.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/serialization/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/serialization/abstractions.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/serialization/aggregate_serializer.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/serialization/json.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/utils/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/utils/camel_model.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/utils/case_conversion.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/validation/__init__.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/validation/business_rules.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/validation/exceptions.py +0 -0
- {neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/validation/validators.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: neuroglia-python
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Port from .NET to Python of the Neuroglia Framework
|
|
5
5
|
License: Apache
|
|
6
6
|
License-File: LICENSE
|
|
@@ -21,43 +21,44 @@ Provides-Extra: etcd
|
|
|
21
21
|
Provides-Extra: eventstore
|
|
22
22
|
Provides-Extra: mongodb
|
|
23
23
|
Provides-Extra: redis
|
|
24
|
-
Requires-Dist: annotated-types (
|
|
25
|
-
Requires-Dist: apscheduler (
|
|
26
|
-
Requires-Dist: boto3 (
|
|
27
|
-
Requires-Dist: classy-fastapi (
|
|
28
|
-
Requires-Dist: email-validator (
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-Dist:
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-Dist: httpx (
|
|
34
|
-
Requires-Dist: itsdangerous (
|
|
35
|
-
Requires-Dist: jinja2 (
|
|
36
|
-
Requires-Dist:
|
|
37
|
-
Requires-Dist:
|
|
38
|
-
Requires-Dist:
|
|
39
|
-
Requires-Dist: opentelemetry-
|
|
40
|
-
Requires-Dist: opentelemetry-exporter-otlp-proto-
|
|
41
|
-
Requires-Dist: opentelemetry-exporter-
|
|
42
|
-
Requires-Dist: opentelemetry-
|
|
43
|
-
Requires-Dist: opentelemetry-instrumentation
|
|
44
|
-
Requires-Dist: opentelemetry-instrumentation-
|
|
45
|
-
Requires-Dist: opentelemetry-instrumentation-
|
|
46
|
-
Requires-Dist: opentelemetry-instrumentation-
|
|
47
|
-
Requires-Dist: opentelemetry-
|
|
48
|
-
Requires-Dist:
|
|
49
|
-
Requires-Dist:
|
|
50
|
-
Requires-Dist:
|
|
51
|
-
Requires-Dist:
|
|
52
|
-
Requires-Dist: pydantic
|
|
53
|
-
Requires-Dist:
|
|
54
|
-
Requires-Dist:
|
|
55
|
-
Requires-Dist:
|
|
56
|
-
Requires-Dist: python-
|
|
57
|
-
Requires-Dist:
|
|
58
|
-
Requires-Dist:
|
|
59
|
-
Requires-Dist:
|
|
60
|
-
Requires-Dist:
|
|
24
|
+
Requires-Dist: annotated-types (==0.7.0)
|
|
25
|
+
Requires-Dist: apscheduler (==3.11.0)
|
|
26
|
+
Requires-Dist: boto3 (==1.40.64) ; extra == "aws" or extra == "all"
|
|
27
|
+
Requires-Dist: classy-fastapi (==0.6.1)
|
|
28
|
+
Requires-Dist: email-validator (==2.2.0)
|
|
29
|
+
Requires-Dist: etcd3-py (==0.1.6) ; extra == "etcd" or extra == "all"
|
|
30
|
+
Requires-Dist: fastapi (==0.115.5)
|
|
31
|
+
Requires-Dist: grpcio (==1.76.0)
|
|
32
|
+
Requires-Dist: h11 (==0.16.0)
|
|
33
|
+
Requires-Dist: httpx (==0.27.2)
|
|
34
|
+
Requires-Dist: itsdangerous (==2.2.0)
|
|
35
|
+
Requires-Dist: jinja2 (==3.1.4)
|
|
36
|
+
Requires-Dist: kurrentdbclient (==1.1.2) ; extra == "eventstore" or extra == "all"
|
|
37
|
+
Requires-Dist: motor (==3.7.0) ; extra == "mongodb" or extra == "all"
|
|
38
|
+
Requires-Dist: multipledispatch (==1.0.0)
|
|
39
|
+
Requires-Dist: opentelemetry-api (==1.38.0)
|
|
40
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc (==1.38.0)
|
|
41
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http (==1.38.0)
|
|
42
|
+
Requires-Dist: opentelemetry-exporter-prometheus (==0.59b0)
|
|
43
|
+
Requires-Dist: opentelemetry-instrumentation (==0.59b0)
|
|
44
|
+
Requires-Dist: opentelemetry-instrumentation-fastapi (==0.59b0)
|
|
45
|
+
Requires-Dist: opentelemetry-instrumentation-httpx (==0.59b0)
|
|
46
|
+
Requires-Dist: opentelemetry-instrumentation-logging (==0.59b0)
|
|
47
|
+
Requires-Dist: opentelemetry-instrumentation-system-metrics (==0.59b0)
|
|
48
|
+
Requires-Dist: opentelemetry-sdk (==1.38.0)
|
|
49
|
+
Requires-Dist: passlib[bcrypt] (==1.7.4)
|
|
50
|
+
Requires-Dist: prometheus-client (==0.21.0)
|
|
51
|
+
Requires-Dist: protobuf (==6.33.1) ; extra == "etcd" or extra == "all"
|
|
52
|
+
Requires-Dist: pydantic-settings (==2.6.1)
|
|
53
|
+
Requires-Dist: pydantic[email] (==2.10.3)
|
|
54
|
+
Requires-Dist: pyjwt (==2.10.1)
|
|
55
|
+
Requires-Dist: pymongo (==4.15.4) ; extra == "mongodb" or extra == "all"
|
|
56
|
+
Requires-Dist: python-dotenv (==1.0.1)
|
|
57
|
+
Requires-Dist: python-multipart (==0.0.17)
|
|
58
|
+
Requires-Dist: redis (==5.2.0) ; extra == "redis" or extra == "all"
|
|
59
|
+
Requires-Dist: rx (==3.2.0)
|
|
60
|
+
Requires-Dist: typing-extensions (==4.12.2)
|
|
61
|
+
Requires-Dist: uvicorn (==0.32.1)
|
|
61
62
|
Description-Content-Type: text/markdown
|
|
62
63
|
|
|
63
64
|
# Neuroglia Python Framework
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "neuroglia-python"
|
|
3
|
+
version = "0.7.0"
|
|
4
|
+
description = "Port from .NET to Python of the Neuroglia Framework"
|
|
5
|
+
authors = ["Charles d'Avernas <charles.davernas@neuroglia.io>", "Bruno van de Werve <bvandewe@gmail.com>"]
|
|
6
|
+
license = "Apache"
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
packages = [
|
|
9
|
+
{ include = "neuroglia", from = "src" },
|
|
10
|
+
]
|
|
11
|
+
package-mode = true
|
|
12
|
+
|
|
13
|
+
[tool.poetry.dependencies]
|
|
14
|
+
python = "^3.9"
|
|
15
|
+
# Core framework dependencies - always required
|
|
16
|
+
annotated-types = "0.7.0"
|
|
17
|
+
classy-fastapi = "0.6.1"
|
|
18
|
+
fastapi = "0.115.5"
|
|
19
|
+
multipledispatch = "1.0.0"
|
|
20
|
+
pydantic-settings = "2.6.1"
|
|
21
|
+
python-dotenv = "1.0.1"
|
|
22
|
+
typing-extensions = "4.12.2"
|
|
23
|
+
rx = { version = "3.2.0" }
|
|
24
|
+
uvicorn = { version = "0.32.1" }
|
|
25
|
+
httpx = { version = "0.27.2" }
|
|
26
|
+
grpcio = { version = "1.76.0" }
|
|
27
|
+
h11 = { version = "0.16.0" } # Security fix for CVE-2025-43859
|
|
28
|
+
|
|
29
|
+
# Authentication dependencies
|
|
30
|
+
pyjwt = "2.10.1"
|
|
31
|
+
passlib = { extras = ["bcrypt"], version = "1.7.4" }
|
|
32
|
+
python-multipart = "0.0.17"
|
|
33
|
+
itsdangerous = "2.2.0"
|
|
34
|
+
|
|
35
|
+
# Core dependencies
|
|
36
|
+
protobuf = "6.33.1" # Pinned for compatibility with kurrentdbclient, OpenTelemetry, and etcd3-py
|
|
37
|
+
apscheduler = "3.11.0"
|
|
38
|
+
pydantic = {extras = ["email"], version = "2.10.3"}
|
|
39
|
+
email-validator = "2.2.0"
|
|
40
|
+
jinja2 = "3.1.4"
|
|
41
|
+
|
|
42
|
+
# Optional dependencies - install with extras
|
|
43
|
+
redis = { version = "5.2.0", optional = true }
|
|
44
|
+
pymongo = { version = "4.15.4", optional = true }
|
|
45
|
+
motor = { version = "3.7.0", optional = true }
|
|
46
|
+
kurrentdbclient = { version = "1.1.2", optional = true } # Bug fix: AsyncPersistentSubscription.init() now propagates subscription_id
|
|
47
|
+
etcd3-py = { version = "0.1.6", optional = true } # Maintained fork with protobuf 5.x/6.x support
|
|
48
|
+
|
|
49
|
+
# OpenTelemetry dependencies - pinned versions for protobuf 6.x compatibility
|
|
50
|
+
opentelemetry-api = "1.38.0"
|
|
51
|
+
opentelemetry-sdk = "1.38.0"
|
|
52
|
+
opentelemetry-exporter-otlp-proto-grpc = "1.38.0"
|
|
53
|
+
opentelemetry-exporter-otlp-proto-http = "1.38.0"
|
|
54
|
+
opentelemetry-instrumentation = "0.59b0"
|
|
55
|
+
opentelemetry-instrumentation-fastapi = "0.59b0"
|
|
56
|
+
opentelemetry-instrumentation-httpx = "0.59b0"
|
|
57
|
+
opentelemetry-instrumentation-logging = "0.59b0"
|
|
58
|
+
opentelemetry-instrumentation-system-metrics = "0.59b0"
|
|
59
|
+
opentelemetry-exporter-prometheus = "0.59b0" # Prometheus /metrics endpoint support
|
|
60
|
+
prometheus-client = "0.21.0" # Required by opentelemetry-exporter-prometheus
|
|
61
|
+
boto3 = { version = "1.40.64", optional = true }
|
|
62
|
+
|
|
63
|
+
[tool.poetry.extras]
|
|
64
|
+
mongodb = ["pymongo", "motor"]
|
|
65
|
+
eventstore = ["kurrentdbclient"] # Formerly esdbclient
|
|
66
|
+
redis = ["redis"]
|
|
67
|
+
etcd = ["etcd3-py", "protobuf"]
|
|
68
|
+
aws = ["boto3"]
|
|
69
|
+
all = ["pymongo", "motor", "kurrentdbclient", "redis", "etcd3-py", "protobuf", "boto3"]
|
|
70
|
+
|
|
71
|
+
[tool.poetry.group.dev.dependencies]
|
|
72
|
+
# Development and testing dependencies
|
|
73
|
+
pre-commit = "^4.0.1"
|
|
74
|
+
pytest = "^8.3.3"
|
|
75
|
+
pytest-asyncio = "^0.24.0"
|
|
76
|
+
mypy = "^1.13.0"
|
|
77
|
+
autopep8 = "^2.3.1"
|
|
78
|
+
coverage = "^7.6.9"
|
|
79
|
+
mypy-extensions = "^1.0.0"
|
|
80
|
+
flake8 = "^7.1.1"
|
|
81
|
+
isort = "^5.13.2"
|
|
82
|
+
|
|
83
|
+
[tool.poetry.group.docs]
|
|
84
|
+
optional = true
|
|
85
|
+
|
|
86
|
+
[tool.poetry.group.docs.dependencies]
|
|
87
|
+
# Documentation dependencies
|
|
88
|
+
mkdocs = "^1.6.1"
|
|
89
|
+
mkdocs-material = "^9.5.48"
|
|
90
|
+
mkdocs-mermaid2-plugin = "^1.2.2"
|
|
91
|
+
|
|
92
|
+
[build-system]
|
|
93
|
+
requires = ["poetry-core"]
|
|
94
|
+
build-backend = "poetry.core.masonry.api"
|
|
95
|
+
|
|
96
|
+
[tool.black]
|
|
97
|
+
line-length = 500
|
|
@@ -4,8 +4,6 @@ Event sourcing infrastructure for Neuroglia.
|
|
|
4
4
|
Provides event store implementations and aggregate root support.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
# Apply runtime patches for third-party library bugs
|
|
8
|
-
from . import patches # noqa: F401
|
|
9
7
|
from .abstractions import (
|
|
10
8
|
Aggregator,
|
|
11
9
|
EventDescriptor,
|
|
@@ -5,9 +5,9 @@ import sys
|
|
|
5
5
|
from typing import Any, Dict, Optional
|
|
6
6
|
|
|
7
7
|
import rx
|
|
8
|
-
from
|
|
9
|
-
from
|
|
10
|
-
from
|
|
8
|
+
from kurrentdbclient import AsyncKurrentDBClient as AsyncClientFactory
|
|
9
|
+
from kurrentdbclient import NewEvent, RecordedEvent, StreamState
|
|
10
|
+
from kurrentdbclient.exceptions import AlreadyExistsError as AlreadyExists
|
|
11
11
|
from rx.core.observable.observable import Observable
|
|
12
12
|
from rx.disposable.disposable import Disposable
|
|
13
13
|
from rx.subject.subject import Subject
|
|
@@ -146,16 +146,23 @@ class DataAccessLayer:
|
|
|
146
146
|
class ReadModel:
|
|
147
147
|
"""Represents a helper class used to configure an application's Read Model DAL
|
|
148
148
|
|
|
149
|
-
Supports
|
|
150
|
-
1. Simplified: Pass database_name
|
|
151
|
-
2.
|
|
149
|
+
Supports three configuration patterns:
|
|
150
|
+
1. Simplified Sync: Pass database_name with repository_type='mongo' (default)
|
|
151
|
+
2. Simplified Async: Pass database_name with repository_type='motor' for FastAPI
|
|
152
|
+
3. Custom: Pass custom repository_setup function to configure()
|
|
152
153
|
|
|
153
154
|
Examples:
|
|
154
|
-
# Simple configuration
|
|
155
|
+
# Simple synchronous configuration (default)
|
|
155
156
|
DataAccessLayer.ReadModel(database_name="myapp").configure(
|
|
156
157
|
builder, ["integration.models"]
|
|
157
158
|
)
|
|
158
159
|
|
|
160
|
+
# Async configuration with Motor for FastAPI
|
|
161
|
+
DataAccessLayer.ReadModel(
|
|
162
|
+
database_name="myapp",
|
|
163
|
+
repository_type='motor'
|
|
164
|
+
).configure(builder, ["integration.models"])
|
|
165
|
+
|
|
159
166
|
# Custom factory (advanced, backwards compatible)
|
|
160
167
|
def custom_setup(builder_, entity_type, key_type):
|
|
161
168
|
# Custom configuration logic
|
|
@@ -165,14 +172,34 @@ class DataAccessLayer:
|
|
|
165
172
|
)
|
|
166
173
|
"""
|
|
167
174
|
|
|
168
|
-
def __init__(self, database_name: Optional[str] = None):
|
|
175
|
+
def __init__(self, database_name: Optional[str] = None, repository_type: str = "mongo"):
|
|
169
176
|
"""Initialize ReadModel configuration
|
|
170
177
|
|
|
171
178
|
Args:
|
|
172
179
|
database_name: Optional database name for MongoDB repositories.
|
|
173
180
|
If not provided, custom repository_setup must be used.
|
|
181
|
+
repository_type: Type of repository to use ('mongo' or 'motor'). Defaults to 'mongo'.
|
|
182
|
+
- 'mongo': Use MongoRepository with PyMongo (synchronous driver)
|
|
183
|
+
- 'motor': Use MotorRepository with Motor (async driver for FastAPI)
|
|
184
|
+
|
|
185
|
+
Example:
|
|
186
|
+
```python
|
|
187
|
+
# Simplified sync configuration
|
|
188
|
+
DataAccessLayer.ReadModel(database_name="myapp").configure(...)
|
|
189
|
+
|
|
190
|
+
# Async configuration with Motor
|
|
191
|
+
DataAccessLayer.ReadModel(
|
|
192
|
+
database_name="myapp",
|
|
193
|
+
repository_type='motor'
|
|
194
|
+
).configure(...)
|
|
195
|
+
```
|
|
174
196
|
"""
|
|
175
197
|
self._database_name = database_name
|
|
198
|
+
self._repository_type = repository_type
|
|
199
|
+
|
|
200
|
+
# Validate repository_type
|
|
201
|
+
if repository_type not in ("mongo", "motor"):
|
|
202
|
+
raise ValueError(f"Invalid repository_type '{repository_type}'. " "Must be either 'mongo' (synchronous PyMongo) or 'motor' (async Motor)")
|
|
176
203
|
|
|
177
204
|
def configure(
|
|
178
205
|
self,
|
|
@@ -235,58 +262,85 @@ class DataAccessLayer:
|
|
|
235
262
|
if not self._database_name:
|
|
236
263
|
raise ValueError("Cannot configure Read Model with simplified API: " "database_name not provided. Either pass database_name to ReadModel() " "or use custom repository_setup function.")
|
|
237
264
|
|
|
238
|
-
from pymongo import MongoClient
|
|
239
|
-
|
|
240
265
|
from neuroglia.data.infrastructure.abstractions import (
|
|
241
266
|
QueryableRepository,
|
|
242
267
|
Repository,
|
|
243
268
|
)
|
|
244
|
-
from neuroglia.data.infrastructure.mongo.mongo_repository import (
|
|
245
|
-
MongoRepository,
|
|
246
|
-
MongoRepositoryOptions,
|
|
247
|
-
)
|
|
248
269
|
from neuroglia.dependency_injection import ServiceProvider
|
|
249
270
|
|
|
250
|
-
#
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
raise ValueError(f"Missing '{connection_string_name}' connection string in application settings")
|
|
271
|
+
# Configure based on repository type
|
|
272
|
+
if self._repository_type == "mongo":
|
|
273
|
+
# Synchronous MongoRepository configuration
|
|
274
|
+
from pymongo import MongoClient
|
|
255
275
|
|
|
256
|
-
|
|
257
|
-
|
|
276
|
+
from neuroglia.data.infrastructure.mongo.mongo_repository import (
|
|
277
|
+
MongoRepository,
|
|
278
|
+
MongoRepositoryOptions,
|
|
279
|
+
)
|
|
258
280
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
281
|
+
# Get MongoDB connection string
|
|
282
|
+
connection_string_name = "mongo"
|
|
283
|
+
connection_string = builder.settings.connection_strings.get(connection_string_name, None)
|
|
284
|
+
if connection_string is None:
|
|
285
|
+
raise ValueError(f"Missing '{connection_string_name}' connection string in application settings")
|
|
263
286
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
MongoRepositoryOptions[queryable_type, key_type], # type: ignore
|
|
267
|
-
singleton=MongoRepositoryOptions[queryable_type, key_type](self._database_name), # type: ignore
|
|
268
|
-
)
|
|
287
|
+
# Register MongoClient singleton (shared across all repositories)
|
|
288
|
+
builder.services.try_add_singleton(MongoClient, singleton=MongoClient(connection_string))
|
|
269
289
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
)
|
|
290
|
+
# Discover and configure each queryable type
|
|
291
|
+
for module in [ModuleLoader.load(module_name) for module_name in modules]:
|
|
292
|
+
for queryable_type in TypeFinder.get_types(module, lambda cls: inspect.isclass(cls) and hasattr(cls, "__queryable__")):
|
|
293
|
+
key_type = str # todo: reflect from DTO base type
|
|
275
294
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
295
|
+
# Register options for this entity type
|
|
296
|
+
builder.services.try_add_singleton(
|
|
297
|
+
MongoRepositoryOptions[queryable_type, key_type], # type: ignore
|
|
298
|
+
singleton=MongoRepositoryOptions[queryable_type, key_type](self._database_name), # type: ignore
|
|
299
|
+
)
|
|
280
300
|
|
|
281
|
-
|
|
301
|
+
# Register repository
|
|
302
|
+
builder.services.try_add_singleton(
|
|
303
|
+
Repository[queryable_type, key_type], # type: ignore
|
|
304
|
+
MongoRepository[queryable_type, key_type], # type: ignore
|
|
305
|
+
)
|
|
282
306
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
307
|
+
# Register queryable repository alias
|
|
308
|
+
def make_queryable_factory(qt, kt):
|
|
309
|
+
def queryable_factory(provider: ServiceProvider):
|
|
310
|
+
return provider.get_required_service(Repository[qt, kt]) # type: ignore
|
|
311
|
+
|
|
312
|
+
return queryable_factory
|
|
313
|
+
|
|
314
|
+
builder.services.try_add_singleton(
|
|
315
|
+
QueryableRepository[queryable_type, key_type], # type: ignore
|
|
316
|
+
implementation_factory=make_queryable_factory(queryable_type, key_type),
|
|
317
|
+
)
|
|
287
318
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
319
|
+
# Register query handlers
|
|
320
|
+
builder.services.add_transient(RequestHandler, GetByIdQueryHandler[queryable_type, key_type]) # type: ignore
|
|
321
|
+
builder.services.add_transient(RequestHandler, ListQueryHandler[queryable_type, key_type]) # type: ignore
|
|
322
|
+
|
|
323
|
+
elif self._repository_type == "motor":
|
|
324
|
+
# Async MotorRepository configuration using MotorRepository.configure()
|
|
325
|
+
from neuroglia.data.infrastructure.mongo.motor_repository import (
|
|
326
|
+
MotorRepository,
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
# Use MotorRepository.configure() for each discovered type
|
|
330
|
+
# Note: MotorRepository types are NOT queryable yet, so we scan for all classes
|
|
331
|
+
# (not just those with __queryable__ attribute)
|
|
332
|
+
# This configuration supports direct Repository[T, K] injection in handlers
|
|
333
|
+
for module in [ModuleLoader.load(module_name) for module_name in modules]:
|
|
334
|
+
for entity_type in TypeFinder.get_types(module, lambda cls: inspect.isclass(cls)):
|
|
335
|
+
key_type = str # todo: reflect from entity type
|
|
336
|
+
|
|
337
|
+
# Use MotorRepository's static configure method
|
|
338
|
+
# This handles AsyncIOMotorClient, repository registration, etc.
|
|
339
|
+
MotorRepository.configure(
|
|
340
|
+
builder=builder,
|
|
341
|
+
entity_type=entity_type,
|
|
342
|
+
key_type=key_type,
|
|
343
|
+
database_name=self._database_name,
|
|
344
|
+
)
|
|
291
345
|
|
|
292
346
|
return builder
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
[tool.poetry]
|
|
2
|
-
name = "neuroglia-python"
|
|
3
|
-
version = "0.6.22"
|
|
4
|
-
description = "Port from .NET to Python of the Neuroglia Framework"
|
|
5
|
-
authors = ["Charles d'Avernas <charles.davernas@neuroglia.io>", "Bruno van de Werve <bvandewe@gmail.com>"]
|
|
6
|
-
license = "Apache"
|
|
7
|
-
readme = "README.md"
|
|
8
|
-
packages = [
|
|
9
|
-
{ include = "neuroglia", from = "src" },
|
|
10
|
-
]
|
|
11
|
-
package-mode = true
|
|
12
|
-
|
|
13
|
-
[tool.poetry.dependencies]
|
|
14
|
-
python = "^3.9"
|
|
15
|
-
# Core framework dependencies - always required
|
|
16
|
-
annotated-types = "^0.7.0"
|
|
17
|
-
classy-fastapi = "^0.6.1"
|
|
18
|
-
fastapi = "^0.115.5"
|
|
19
|
-
multipledispatch = "^1.0.0"
|
|
20
|
-
pydantic-settings = "^2.6.1"
|
|
21
|
-
python-dotenv = "^1.0.1"
|
|
22
|
-
typing-extensions = "^4.12.2"
|
|
23
|
-
rx = { version = "^3.2.0" }
|
|
24
|
-
uvicorn = { version = "^0.32.1" }
|
|
25
|
-
httpx = { version = "^0.27.2" }
|
|
26
|
-
grpcio = { version = "^1.68.1" }
|
|
27
|
-
|
|
28
|
-
# Authentication dependencies
|
|
29
|
-
pyjwt = "^2.10.1"
|
|
30
|
-
passlib = { extras = ["bcrypt"], version = "^1.7.4" }
|
|
31
|
-
python-multipart = "^0.0.17"
|
|
32
|
-
itsdangerous = "^2.2.0"
|
|
33
|
-
|
|
34
|
-
# Core dependencies
|
|
35
|
-
protobuf = "^5.0" # Use protobuf 5.x for compatibility with latest OpenTelemetry and etcd3-py
|
|
36
|
-
apscheduler = "^3.11.0"
|
|
37
|
-
pydantic = {extras = ["email"], version = "^2.10.3"}
|
|
38
|
-
email-validator = "^2.2.0"
|
|
39
|
-
jinja2 = "^3.1.4"
|
|
40
|
-
|
|
41
|
-
# Optional dependencies - install with extras
|
|
42
|
-
redis = { version = "^5.2.0", optional = true }
|
|
43
|
-
pymongo = { version = "^4.10.1", optional = true }
|
|
44
|
-
motor = { version = "^3.6.0", optional = true }
|
|
45
|
-
esdbclient = { version = "^1.1.1", optional = true }
|
|
46
|
-
etcd3-py = { version = "^0.1.6", optional = true } # Maintained fork with protobuf 5.x support
|
|
47
|
-
|
|
48
|
-
# OpenTelemetry dependencies
|
|
49
|
-
# Using latest versions with protobuf 5.x support
|
|
50
|
-
opentelemetry-api = "^1.28.2"
|
|
51
|
-
opentelemetry-sdk = "^1.28.2"
|
|
52
|
-
opentelemetry-exporter-otlp-proto-grpc = "^1.28.2"
|
|
53
|
-
opentelemetry-exporter-otlp-proto-http = "^1.28.2"
|
|
54
|
-
opentelemetry-instrumentation = "^0.49b2"
|
|
55
|
-
opentelemetry-instrumentation-fastapi = "^0.49b2"
|
|
56
|
-
opentelemetry-instrumentation-httpx = "^0.49b2"
|
|
57
|
-
opentelemetry-instrumentation-logging = "^0.49b2"
|
|
58
|
-
opentelemetry-instrumentation-system-metrics = "^0.49b2"
|
|
59
|
-
opentelemetry-exporter-prometheus = "^0.49b2" # Prometheus /metrics endpoint support
|
|
60
|
-
prometheus-client = "^0.21.0" # Required by opentelemetry-exporter-prometheus
|
|
61
|
-
boto3 = { version = "^1.40.64", optional = true }
|
|
62
|
-
|
|
63
|
-
[tool.poetry.extras]
|
|
64
|
-
mongodb = ["pymongo", "motor"]
|
|
65
|
-
eventstore = ["esdbclient"]
|
|
66
|
-
redis = ["redis"]
|
|
67
|
-
etcd = ["etcd3-py", "protobuf"]
|
|
68
|
-
aws = ["boto3"]
|
|
69
|
-
all = ["pymongo", "motor", "esdbclient", "redis", "etcd3-py", "protobuf", "boto3"]
|
|
70
|
-
|
|
71
|
-
[tool.poetry.group.dev.dependencies]
|
|
72
|
-
# Development and testing dependencies
|
|
73
|
-
pre-commit = "^4.0.1"
|
|
74
|
-
pytest = "^8.3.3"
|
|
75
|
-
pytest-asyncio = "^0.24.0"
|
|
76
|
-
mypy = "^1.13.0"
|
|
77
|
-
autopep8 = "^2.3.1"
|
|
78
|
-
coverage = "^7.6.9"
|
|
79
|
-
mypy-extensions = "^1.0.0"
|
|
80
|
-
flake8 = "^7.1.1"
|
|
81
|
-
isort = "^5.13.2"
|
|
82
|
-
|
|
83
|
-
[tool.poetry.group.docs]
|
|
84
|
-
optional = true
|
|
85
|
-
|
|
86
|
-
[tool.poetry.group.docs.dependencies]
|
|
87
|
-
# Documentation dependencies
|
|
88
|
-
mkdocs = "^1.6.1"
|
|
89
|
-
mkdocs-material = "^9.5.48"
|
|
90
|
-
mkdocs-mermaid2-plugin = "^1.2.2"
|
|
91
|
-
|
|
92
|
-
[build-system]
|
|
93
|
-
requires = ["poetry-core"]
|
|
94
|
-
build-backend = "poetry.core.masonry.api"
|
|
95
|
-
|
|
96
|
-
[tool.black]
|
|
97
|
-
line-length = 500
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Runtime patches for third-party library bugs affecting Neuroglia event sourcing.
|
|
3
|
-
|
|
4
|
-
This module contains monkey-patches that fix critical bugs in dependencies.
|
|
5
|
-
Patches are applied automatically when this module is imported.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import logging
|
|
9
|
-
|
|
10
|
-
log = logging.getLogger(__name__)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def patch_esdbclient_async_subscription_id():
|
|
14
|
-
"""
|
|
15
|
-
Fix esdbclient bug: AsyncPersistentSubscription.init() doesn't propagate
|
|
16
|
-
subscription_id to _read_reqs, causing ACKs to be sent with empty subscription ID.
|
|
17
|
-
|
|
18
|
-
**Bug Description**:
|
|
19
|
-
The sync version (PersistentSubscription.__init__) has this line:
|
|
20
|
-
self._read_reqs.subscription_id = subscription_id.encode()
|
|
21
|
-
|
|
22
|
-
But the async version (AsyncPersistentSubscription.init) is missing it!
|
|
23
|
-
This causes ACKs to fail silently because EventStoreDB doesn't know which
|
|
24
|
-
subscription the ACK is for.
|
|
25
|
-
|
|
26
|
-
**Symptoms**:
|
|
27
|
-
- Events are redelivered every message_timeout seconds despite being processed
|
|
28
|
-
- Checkpoint never advances in EventStoreDB
|
|
29
|
-
- Events eventually get parked after maxRetryCount attempts
|
|
30
|
-
- Read models may process the same event multiple times
|
|
31
|
-
|
|
32
|
-
**Root Cause**:
|
|
33
|
-
BaseSubscriptionReadReqs.__init__() initializes subscription_id = b"" (empty bytes).
|
|
34
|
-
The sync version overwrites this with the correct value in __init__, but the async
|
|
35
|
-
version only sets self._subscription_id without propagating it to _read_reqs.
|
|
36
|
-
|
|
37
|
-
**Affected Versions**:
|
|
38
|
-
- esdbclient: 1.1.7 (and likely all earlier versions with async support)
|
|
39
|
-
- kurrentdbclient: Likely affected (same codebase, rebranded)
|
|
40
|
-
|
|
41
|
-
**Upstream Issue**:
|
|
42
|
-
Bug report to be filed with esdbclient/kurrentdbclient maintainers.
|
|
43
|
-
|
|
44
|
-
**Verification**:
|
|
45
|
-
After applying this patch, check EventStoreDB admin UI:
|
|
46
|
-
- Navigate to Persistent Subscriptions → your subscription
|
|
47
|
-
- lastCheckpointedEventPosition should advance after processing events
|
|
48
|
-
- totalInFlightMessages should decrease after successful ACKs
|
|
49
|
-
"""
|
|
50
|
-
try:
|
|
51
|
-
from esdbclient.persistent import (
|
|
52
|
-
AsyncPersistentSubscription, # type: ignore[import-not-found]
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
original_init = AsyncPersistentSubscription.init
|
|
56
|
-
|
|
57
|
-
async def patched_init(self) -> None:
|
|
58
|
-
await original_init(self)
|
|
59
|
-
# Propagate subscription_id to _read_reqs (missing in esdbclient async version)
|
|
60
|
-
if hasattr(self, "_subscription_id") and hasattr(self, "_read_reqs"):
|
|
61
|
-
self._read_reqs.subscription_id = self._subscription_id.encode()
|
|
62
|
-
log.debug(f"🔧 Patched: propagated subscription_id to _read_reqs: {self._subscription_id}")
|
|
63
|
-
|
|
64
|
-
AsyncPersistentSubscription.init = patched_init
|
|
65
|
-
log.info("🔧 Patched esdbclient AsyncPersistentSubscription.init() to propagate subscription_id")
|
|
66
|
-
|
|
67
|
-
except ImportError:
|
|
68
|
-
log.debug("esdbclient not installed, skipping AsyncPersistentSubscription patch")
|
|
69
|
-
except Exception as e:
|
|
70
|
-
log.warning(f"Failed to apply esdbclient AsyncPersistentSubscription patch: {e}")
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
# Auto-apply patches when this module is imported
|
|
74
|
-
patch_esdbclient_async_subscription_id()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/application/background_scheduler.py
RENAMED
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/coordination/abstractions.py
RENAMED
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/coordination/leader_election.py
RENAMED
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/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.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/infrastructure/__init__.py
RENAMED
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/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
|
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/queries/generic/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/queries/generic/list_query.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/resources/abstractions.py
RENAMED
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/resources/controller.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/data/resources/state_machine.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/dependency_injection/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/eventing/cloud_events/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/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.6.22 → neuroglia_python-0.7.0}/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.6.22 → neuroglia_python-0.7.0}/src/neuroglia/integration/cache_repository.py
RENAMED
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/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.6.22 → neuroglia_python-0.7.0}/src/neuroglia/mediation/metrics_middleware.py
RENAMED
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/src/neuroglia/mediation/pipeline_behavior.py
RENAMED
|
File without changes
|
|
File without changes
|
{neuroglia_python-0.6.22 → neuroglia_python-0.7.0}/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.6.22 → neuroglia_python-0.7.0}/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.6.22 → neuroglia_python-0.7.0}/src/neuroglia/validation/business_rules.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|