neuroglia-python 0.1.3__tar.gz → 0.1.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.
Files changed (61) hide show
  1. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/PKG-INFO +17 -13
  2. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/README.md +7 -3
  3. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/pyproject.toml +10 -10
  4. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/abstractions.py +1 -1
  5. neuroglia_python-0.1.5/src/neuroglia/eventing/cloud_events/cloud_event.py +83 -0
  6. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_middleware.py +6 -6
  7. neuroglia_python-0.1.3/src/neuroglia/eventing/cloud_events/cloud_event.py +0 -72
  8. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/LICENSE +0 -0
  9. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/__init__.py +0 -0
  10. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/core/__init__.py +0 -0
  11. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/core/module_loader.py +0 -0
  12. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/core/operation_result.py +0 -0
  13. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/core/problem_details.py +0 -0
  14. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/core/type_extensions.py +0 -0
  15. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/core/type_finder.py +0 -0
  16. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/__init__.py +0 -0
  17. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/infrastructure/__init__.py +0 -0
  18. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/infrastructure/abstractions.py +0 -0
  19. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/infrastructure/event_sourcing/__init__.py +0 -0
  20. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/infrastructure/event_sourcing/abstractions.py +0 -0
  21. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/infrastructure/event_sourcing/event_sourcing_repository.py +0 -0
  22. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/infrastructure/event_sourcing/event_store/__init__.py +0 -0
  23. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/infrastructure/event_sourcing/event_store/event_store.py +0 -0
  24. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/infrastructure/event_sourcing/read_model_reconciliator.py +0 -0
  25. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/infrastructure/memory/__init__.py +0 -0
  26. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/infrastructure/memory/memory_repository.py +0 -0
  27. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/infrastructure/mongo/__init__.py +0 -0
  28. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/infrastructure/mongo/mongo_repository.py +0 -0
  29. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/queries/generic/__init__.py +0 -0
  30. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/queries/generic/get_by_id_query.py +0 -0
  31. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/queries/generic/list_query.py +0 -0
  32. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/data/queryable.py +0 -0
  33. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/dependency_injection/__init__.py +0 -0
  34. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/dependency_injection/service_provider.py +0 -0
  35. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/eventing/cloud_events/__init__.py +0 -0
  36. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/eventing/cloud_events/decorators.py +0 -0
  37. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/eventing/cloud_events/infrastructure/__init__.py +0 -0
  38. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_bus.py +0 -0
  39. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_ingestor.py +0 -0
  40. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_publisher.py +0 -0
  41. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/expressions/__init__.py +0 -0
  42. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/expressions/javascript_expression_translator.py +0 -0
  43. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/hosting/__init__.py +0 -0
  44. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/hosting/abstractions.py +0 -0
  45. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/hosting/configuration/data_access_layer.py +0 -0
  46. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/hosting/web.py +0 -0
  47. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/integration/__init__.py +0 -0
  48. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/integration/models.py +0 -0
  49. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/logging/__init__.py +0 -0
  50. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/logging/logger.py +0 -0
  51. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/mapping/__init__.py +0 -0
  52. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/mapping/mapper.py +0 -0
  53. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/mediation/__init__.py +0 -0
  54. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/mediation/mediator.py +0 -0
  55. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/mvc/__init__.py +0 -0
  56. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/mvc/controller_base.py +0 -0
  57. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/reactive/__init__.py +0 -0
  58. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/reactive/rx_async.py +0 -0
  59. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/serialization/__init__.py +0 -0
  60. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/serialization/abstractions.py +0 -0
  61. {neuroglia_python-0.1.3 → neuroglia_python-0.1.5}/src/neuroglia/serialization/json.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: neuroglia-python
3
- Version: 0.1.3
3
+ Version: 0.1.5
4
4
  Summary: Port from .NET to Python of the Neuroglia Framework
5
5
  License: Apache
6
6
  Author: Charles d'Avernas
@@ -13,19 +13,19 @@ Classifier: Programming Language :: Python :: 3.13
13
13
  Requires-Dist: annotated-types (>0.6.0)
14
14
  Requires-Dist: classy-fastapi (>=0.6.1,<0.7.0)
15
15
  Requires-Dist: esdbclient (>1)
16
- Requires-Dist: fastapi (>=0.115.12,<0.116.0)
16
+ Requires-Dist: fastapi (>=0)
17
17
  Requires-Dist: grpcio (>=1.71)
18
18
  Requires-Dist: httpx (>=0.28.1,<0.29.0)
19
- Requires-Dist: mkdocs (>=1.6.1,<2.0.0)
20
- Requires-Dist: mkdocs-material (>=9.5.46,<10.0.0)
19
+ Requires-Dist: mkdocs (>=1.6.1)
20
+ Requires-Dist: mkdocs-material (>=9.5.46)
21
21
  Requires-Dist: multipledispatch (>=1.0.0,<2.0.0)
22
- Requires-Dist: pydantic-settings (>=2.2.0,<3.0.0)
23
- Requires-Dist: pymongo (>=4.6.1,<5.0.0)
24
- Requires-Dist: pytest (>=8.1.1,<9.0.0)
22
+ Requires-Dist: pydantic-settings (>=2)
23
+ Requires-Dist: pymongo (>=4.6.3)
24
+ Requires-Dist: pytest (>=8.1.1)
25
25
  Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
26
- Requires-Dist: rx (>=3.2.0,<4.0.0)
27
- Requires-Dist: typing-extensions (>=4.9.0,<5.0.0)
28
- Requires-Dist: uvicorn (>=0.34.0,<0.35.0)
26
+ Requires-Dist: rx (>=3.2.0)
27
+ Requires-Dist: typing-extensions (>=4.9.0)
28
+ Requires-Dist: uvicorn (>=0.34.0)
29
29
  Description-Content-Type: text/markdown
30
30
 
31
31
  # Neuroglia Python Framework
@@ -69,12 +69,16 @@ This project was the opportunity for me (cdavernas) to learn Python while portin
69
69
  ## Packaging
70
70
 
71
71
  ```sh
72
+ # Set `package-mode = true` in pyproject.toml
72
73
  # Set the version tag in pyproject.toml
73
74
  # Commit changes
74
-
75
+ # Create API Token in pypi.org...
76
+ # Configure credentials for pypi registry:
77
+ poetry config pypi-token.pypi {pypi-....mytoken}
78
+ # Build package locally
75
79
  poetry build
76
-
77
- poetry publish --repository gitlab -u <token-username> -p <token-password>
80
+ # Publish package to pypi.org:
81
+ poetry publish
78
82
 
79
83
  ```
80
84
 
@@ -39,11 +39,15 @@ This project was the opportunity for me (cdavernas) to learn Python while portin
39
39
  ## Packaging
40
40
 
41
41
  ```sh
42
+ # Set `package-mode = true` in pyproject.toml
42
43
  # Set the version tag in pyproject.toml
43
44
  # Commit changes
44
-
45
+ # Create API Token in pypi.org...
46
+ # Configure credentials for pypi registry:
47
+ poetry config pypi-token.pypi {pypi-....mytoken}
48
+ # Build package locally
45
49
  poetry build
46
-
47
- poetry publish --repository gitlab -u <token-username> -p <token-password>
50
+ # Publish package to pypi.org:
51
+ poetry publish
48
52
 
49
53
  ```
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "neuroglia-python"
3
- version = "0.1.3"
3
+ version = "0.1.5"
4
4
  description = "Port from .NET to Python of the Neuroglia Framework"
5
5
  authors = ["Charles d'Avernas <charles.davernas@neuroglia.io>"]
6
6
  license = "Apache"
@@ -15,19 +15,19 @@ python = "^3.12"
15
15
  annotated-types = ">0.6.0"
16
16
  classy-fastapi = "^0.6.1"
17
17
  esdbclient = ">1"
18
- fastapi = "^0.115.12"
18
+ fastapi = ">=0"
19
19
  grpcio = ">=1.71"
20
20
  httpx = "^0.28.1"
21
21
  multipledispatch = "^1.0.0"
22
- pydantic-settings = "^2.2.0"
23
- pymongo = "^4.6.1"
22
+ pydantic-settings = ">=2"
23
+ pymongo = ">=4.6.3"
24
24
  python-dotenv = "^1.0.1"
25
- rx = "^3.2.0"
26
- uvicorn = "^0.34.0"
27
- typing-extensions = "^4.9.0"
28
- pytest = "^8.1.1"
29
- mkdocs = "^1.6.1"
30
- mkdocs-material = "^9.5.46"
25
+ rx = ">=3.2.0"
26
+ uvicorn = ">=0.34.0"
27
+ typing-extensions = ">=4.9.0"
28
+ pytest = ">=8.1.1"
29
+ mkdocs = ">=1.6.1"
30
+ mkdocs-material = ">=9.5.46"
31
31
 
32
32
  [tool.poetry.group.dev.dependencies]
33
33
  pytest = "^8.0.1"
@@ -22,7 +22,7 @@ class Entity(Generic[TKey], Identifiable[TKey], ABC):
22
22
 
23
23
  def __init__(self) -> None:
24
24
  super().__init__()
25
- self.created_at = datetime.now()
25
+ # self.created_at = datetime.now()
26
26
 
27
27
  created_at: datetime
28
28
  ''' Gets the date and time the entity has been created at '''
@@ -0,0 +1,83 @@
1
+ from dataclasses import dataclass, field
2
+ from datetime import datetime
3
+ from typing import Any, Optional, Union, Dict
4
+
5
+
6
+ class CloudEventSpecVersion:
7
+ """Exposes all supported versions of the Cloud Event Specification"""
8
+
9
+ v1_0: str = "1.0"
10
+ """ Gets the version '1.0' of the Cloud Event Specification """
11
+
12
+
13
+ @dataclass
14
+ class CloudEvent:
15
+ """
16
+ Represents a Cloud Event.
17
+
18
+ Attributes:
19
+ id (str): A string that uniquely identifies the cloud event in the scope of its source.
20
+ specversion (str): The version of the CloudEvents specification which the event uses. Defaults to '1.0'.
21
+ time (Optional[datetime]): The date and time at which the event has been produced.
22
+ source (str): The cloud event's source.
23
+ type (str): The cloud event's type.
24
+ subject (Optional[str]): A value that describes the subject of the event in the context of the event producer.
25
+ datacontenttype (Optional[str]): The cloud event's data content type. Defaults to 'application/json'.
26
+ dataschema (Optional[str]): An URI that references the versioned schema of the event's data.
27
+ data (Optional[Any]): The event's data, if any. Only used if the event has been formatted using the structured mode.
28
+ data_base64 (Optional[str]): The event's binary data, encoded in base 64. Used if the event has been formatted using the binary mode.
29
+ extensionAttributes (Optional[Dict[str, Any]]): A mapping containing the event's extension attributes.
30
+ """
31
+
32
+ id: str
33
+ """ Gets/sets string that uniquely identifies the cloud event in the scope of its source. """
34
+
35
+ source: str
36
+ """ Gets/sets the cloud event's source. Must be an absolute URI. """
37
+
38
+ type: str
39
+ """ Gets/sets the cloud event's source. Should be a reverse DNS domain name, which must only contain lowercase alphanumeric, '-' and '.' characters. """
40
+
41
+ specversion: str = "1.0" # Default value for specversion
42
+ """ Gets/sets the version of the CloudEvents specification which the event uses. Defaults to '1.0'. """
43
+
44
+ sequencetype: Optional[str] = None
45
+ """ Gets/sets the type of the sequence. """
46
+
47
+ sequence: Optional[int] = None
48
+ """ Gets/sets the sequence of the event. """
49
+
50
+ time: Optional[datetime] = None
51
+ """ Gets/sets the date and time at which the event has been produced. """
52
+
53
+ subject: Optional[str] = None
54
+ """ Gets/sets value that describes the subject of the event in the context of the event producer. """
55
+
56
+ datacontenttype: Optional[str] = "application/json" # Default value for datacontenttype
57
+ """ Gets/sets the cloud event's data content type. Defaults to 'application/json'. """
58
+
59
+ dataschema: Optional[str] = None
60
+ """ Gets/sets an URI, if any, that references the versioned schema of the event's data. """
61
+
62
+ data: Optional[Any] = None
63
+ """ Gets/sets the event's data, if any. Only used if the event has been formatted using the structured mode. """
64
+
65
+ data_base64: Optional[str] = None
66
+ """ Gets/sets the event's binary data, encoded in base 64. Used if the event has been formatted using the binary mode. """
67
+
68
+ _extra_attributes: Dict[str, Any] = field(default_factory=dict, repr=False)
69
+
70
+ def __init__(self, **kwargs):
71
+ self._extra_attributes = {}
72
+ for key, value in kwargs.items():
73
+ if key in CloudEvent.__dataclass_fields__:
74
+ setattr(self, key, value)
75
+ else:
76
+ self._extra_attributes[key] = value
77
+ super().__init__()
78
+
79
+ def get_attribute(self, name: str) -> Optional[Any]:
80
+ """Gets the value of the attribute with the specified name, if any"""
81
+ if not name:
82
+ raise ValueError("Attribute name cannot be empty or None.")
83
+ return self.__dict__[name] if name in self.__dict__.keys() else None
@@ -8,7 +8,7 @@ from starlette.middleware.base import BaseHTTPMiddleware
8
8
 
9
9
 
10
10
  class CloudEventMiddleware(BaseHTTPMiddleware):
11
- ''' Represents the HTTP middleware used to handle incoming cloud events '''
11
+ """Represents the HTTP middleware used to handle incoming cloud events"""
12
12
 
13
13
  def __init__(self, app, service_provider: ServiceProviderBase):
14
14
  super().__init__(app)
@@ -17,17 +17,17 @@ class CloudEventMiddleware(BaseHTTPMiddleware):
17
17
  self.cloud_event_bus = self.service_provider.get_required_service(CloudEventBus)
18
18
 
19
19
  service_provider: ServiceProviderBase
20
- ''' Gets the current service provider '''
20
+ """ Gets the current service provider """
21
21
 
22
22
  cloud_event_bus: CloudEventBus
23
- ''' Gets the service used to stream the application's incoming and outgoing cloud events '''
23
+ """ Gets the service used to stream the application's incoming and outgoing cloud events """
24
24
 
25
25
  serializer: JsonSerializer
26
- ''' Gets the service used to serialize/deserialize values to/from JSON '''
26
+ """ Gets the service used to serialize/deserialize values to/from JSON """
27
27
 
28
28
  async def dispatch(self, request: Request, call_next):
29
- content_type = request.headers.get('content-type', None)
30
- if content_type is None or not content_type.startswith('application/cloudevents+json'):
29
+ content_type = request.headers.get("content-type", None)
30
+ if content_type is None or not content_type.startswith("application/cloudevents+json"):
31
31
  return await call_next(request)
32
32
  try:
33
33
  attributes = self.serializer.deserialize(await request.body(), dict)
@@ -1,72 +0,0 @@
1
- from dataclasses import dataclass
2
- from datetime import datetime
3
- from typing import Any, Optional
4
-
5
-
6
- class CloudEventSpecVersion:
7
- ''' Exposes all supported versions of the Cloud Event Specification '''
8
-
9
- v1_0: str = "1.0"
10
- ''' Gets the version '1.0' of the Cloud Event Specification '''
11
-
12
-
13
- @dataclass
14
- class CloudEvent:
15
- '''
16
- Represents a Cloud Event.
17
-
18
- Attributes:
19
- id (str): A string that uniquely identifies the cloud event in the scope of its source.
20
- specversion (str): The version of the CloudEvents specification which the event uses. Defaults to '1.0'.
21
- time (Optional[datetime]): The date and time at which the event has been produced.
22
- source (str): The cloud event's source.
23
- type (str): The cloud event's type.
24
- subject (Optional[str]): A value that describes the subject of the event in the context of the event producer.
25
- datacontenttype (Optional[str]): The cloud event's data content type. Defaults to 'application/json'.
26
- dataschema (Optional[str]): An URI that references the versioned schema of the event's data.
27
- data (Optional[Any]): The event's data, if any. Only used if the event has been formatted using the structured mode.
28
- data_base64 (Optional[str]): The event's binary data, encoded in base 64. Used if the event has been formatted using the binary mode.
29
- extensionAttributes (Optional[Dict[str, Any]]): A mapping containing the event's extension attributes.
30
- '''
31
-
32
- id: str
33
- ''' Gets/sets string that uniquely identifies the cloud event in the scope of its source. '''
34
-
35
- source: str
36
- ''' Gets/sets the cloud event's source. Must be an absolute URI. '''
37
-
38
- type: str
39
- ''' Gets/sets the cloud event's source. Should be a reverse DNS domain name, which must only contain lowercase alphanumeric, '-' and '.' characters. '''
40
-
41
- specversion: str = '1.0' # Default value for specversion
42
- ''' Gets/sets the version of the CloudEvents specification which the event uses. Defaults to '1.0'. '''
43
-
44
- sequencetype: Optional[str] = None
45
- ''' Gets/sets the type of the sequence. '''
46
-
47
- sequence: Optional[int] = None
48
- ''' Gets/sets the sequence of the event. '''
49
-
50
- time: Optional[datetime] = None
51
- ''' Gets/sets the date and time at which the event has been produced. '''
52
-
53
- subject: Optional[str] = None
54
- ''' Gets/sets value that describes the subject of the event in the context of the event producer. '''
55
-
56
- datacontenttype: Optional[str] = 'application/json' # Default value for datacontenttype
57
- ''' Gets/sets the cloud event's data content type. Defaults to 'application/json'. '''
58
-
59
- dataschema: Optional[str] = None
60
- ''' Gets/sets an URI, if any, that references the versioned schema of the event's data. '''
61
-
62
- data: Optional[Any] = None
63
- ''' Gets/sets the event's data, if any. Only used if the event has been formatted using the structured mode. '''
64
-
65
- data_base64: Optional[str] = None
66
- ''' Gets/sets the event's binary data, encoded in base 64. Used if the event has been formatted using the binary mode. '''
67
-
68
- def get_attribute(self, name: str) -> Optional[Any]:
69
- ''' Gets the value of the attribute with the specified name, if any '''
70
- if not name:
71
- raise ValueError("Attribute name cannot be empty or None.")
72
- self.__dict__[name] if name in self.__dict__.keys() else None