neuroglia-python 0.1.1__tar.gz → 0.1.3__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 (62) hide show
  1. neuroglia_python-0.1.3/PKG-INFO +80 -0
  2. neuroglia_python-0.1.3/README.md +49 -0
  3. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/pyproject.toml +9 -8
  4. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/eventing/cloud_events/cloud_event.py +4 -27
  5. neuroglia_python-0.1.3/src/neuroglia/logging/logger.py +82 -0
  6. neuroglia_python-0.1.3/src/neuroglia/serialization/__init__.py +0 -0
  7. neuroglia_python-0.1.1/PKG-INFO +0 -49
  8. neuroglia_python-0.1.1/README.md +0 -19
  9. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/LICENSE +0 -0
  10. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/__init__.py +0 -0
  11. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/core/__init__.py +0 -0
  12. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/core/module_loader.py +0 -0
  13. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/core/operation_result.py +0 -0
  14. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/core/problem_details.py +0 -0
  15. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/core/type_extensions.py +0 -0
  16. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/core/type_finder.py +0 -0
  17. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/__init__.py +0 -0
  18. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/abstractions.py +0 -0
  19. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/infrastructure/__init__.py +0 -0
  20. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/infrastructure/abstractions.py +0 -0
  21. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/infrastructure/event_sourcing/__init__.py +0 -0
  22. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/infrastructure/event_sourcing/abstractions.py +0 -0
  23. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/infrastructure/event_sourcing/event_sourcing_repository.py +0 -0
  24. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/infrastructure/event_sourcing/event_store/__init__.py +0 -0
  25. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/infrastructure/event_sourcing/event_store/event_store.py +0 -0
  26. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/infrastructure/event_sourcing/read_model_reconciliator.py +0 -0
  27. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/infrastructure/memory/__init__.py +0 -0
  28. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/infrastructure/memory/memory_repository.py +0 -0
  29. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/infrastructure/mongo/__init__.py +0 -0
  30. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/infrastructure/mongo/mongo_repository.py +0 -0
  31. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/queries/generic/__init__.py +0 -0
  32. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/queries/generic/get_by_id_query.py +0 -0
  33. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/queries/generic/list_query.py +0 -0
  34. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/data/queryable.py +0 -0
  35. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/dependency_injection/__init__.py +0 -0
  36. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/dependency_injection/service_provider.py +0 -0
  37. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/eventing/cloud_events/__init__.py +0 -0
  38. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/eventing/cloud_events/decorators.py +0 -0
  39. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/eventing/cloud_events/infrastructure/__init__.py +0 -0
  40. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_bus.py +0 -0
  41. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_ingestor.py +0 -0
  42. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_middleware.py +0 -0
  43. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/eventing/cloud_events/infrastructure/cloud_event_publisher.py +0 -0
  44. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/expressions/__init__.py +0 -0
  45. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/expressions/javascript_expression_translator.py +0 -0
  46. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/hosting/__init__.py +0 -0
  47. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/hosting/abstractions.py +0 -0
  48. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/hosting/configuration/data_access_layer.py +0 -0
  49. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/hosting/web.py +0 -0
  50. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/integration/__init__.py +0 -0
  51. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/integration/models.py +0 -0
  52. {neuroglia_python-0.1.1/src/neuroglia/mvc → neuroglia_python-0.1.3/src/neuroglia/logging}/__init__.py +0 -0
  53. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/mapping/__init__.py +0 -0
  54. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/mapping/mapper.py +0 -0
  55. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/mediation/__init__.py +0 -0
  56. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/mediation/mediator.py +0 -0
  57. {neuroglia_python-0.1.1/src/neuroglia/serialization → neuroglia_python-0.1.3/src/neuroglia/mvc}/__init__.py +0 -0
  58. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/mvc/controller_base.py +0 -0
  59. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/reactive/__init__.py +0 -0
  60. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/reactive/rx_async.py +0 -0
  61. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/serialization/abstractions.py +0 -0
  62. {neuroglia_python-0.1.1 → neuroglia_python-0.1.3}/src/neuroglia/serialization/json.py +0 -0
@@ -0,0 +1,80 @@
1
+ Metadata-Version: 2.3
2
+ Name: neuroglia-python
3
+ Version: 0.1.3
4
+ Summary: Port from .NET to Python of the Neuroglia Framework
5
+ License: Apache
6
+ Author: Charles d'Avernas
7
+ Author-email: charles.davernas@neuroglia.io
8
+ Requires-Python: >=3.12,<4.0
9
+ Classifier: License :: Other/Proprietary License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Requires-Dist: annotated-types (>0.6.0)
14
+ Requires-Dist: classy-fastapi (>=0.6.1,<0.7.0)
15
+ Requires-Dist: esdbclient (>1)
16
+ Requires-Dist: fastapi (>=0.115.12,<0.116.0)
17
+ Requires-Dist: grpcio (>=1.71)
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)
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)
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)
29
+ Description-Content-Type: text/markdown
30
+
31
+ # Neuroglia Python Framework
32
+
33
+ The framework is a very thin software layer built on top of [FastAPI](https://fastapi.tiangolo.com/) that provides developers with a set of coding features and tools that may be useful for any microservice (regardless of its role and domain/bounded context), such as:
34
+
35
+ - Implements all guidelines from https://12factor.net
36
+ - MVC Web App builder with fundamental abstractions
37
+ - Simple Dependency Injection mechanism, including automatic class discovery and instantiation
38
+ - Class-based API controller with automatic module discovery
39
+ - Modular Command/Query responsibility segregation
40
+ - Optional Event-sourcing for event-driven Domain modeling
41
+ - Clean layered Code https://levelup.gitconnected.com/clean-architecture-86c4f03e4771
42
+ - Pure Domain models, independent of persistence
43
+ - Application handlers (Command, Queries, Events, Tasks)
44
+ - Repository pattern
45
+ - Independent API controllers, endpoints and models (DTO's) vs Domain models and logic
46
+ - Native async Events ingestion, handling, emission (JSON [CloudEvent](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/formats/json-format.md)) using [ReactiveX programming](https://medium.com/@willAmaral/asynchronous-programming-and-rx-anything-479d9cb8daee) with [RxPy](https://rxpy.readthedocs.io/en/latest/)
47
+ - Data models mapping between Domain and Integration
48
+ - Easy extension for background task scheduling with [apscheduler](https://apscheduler.readthedocs.io/en/3.x/)
49
+ - etc...
50
+
51
+ The code typically includes comments that help understand it.
52
+
53
+ The `src/main.py` file is the entry point that defines all dependencies, including the sub-folders where to dynamically load the API, Application, Persistence and Domain layers.
54
+
55
+ In turn, when booting, the web app dynamically discovers, identifies and instantiate dependencies then loads:
56
+
57
+ - API controllers and define the mapping between each endpoint and its corresponding Application handler
58
+ - Application handlers (incl. Commands, Queries, Events, Tasks) and services (any business logic)
59
+ - Integration dependencies (any API client service, persistence-layer clients, ) and models (API' DTO for requests and responses)
60
+
61
+ ## Documentation
62
+
63
+ Temporarily hosted at https://bvandewe.github.io/pyneuro/
64
+
65
+ ## Disclaimer
66
+
67
+ This project was the opportunity for me (cdavernas) to learn Python while porting some of the concepts and services of the .NET version of the Neuroglia Framework
68
+
69
+ ## Packaging
70
+
71
+ ```sh
72
+ # Set the version tag in pyproject.toml
73
+ # Commit changes
74
+
75
+ poetry build
76
+
77
+ poetry publish --repository gitlab -u <token-username> -p <token-password>
78
+
79
+ ```
80
+
@@ -0,0 +1,49 @@
1
+ # Neuroglia Python Framework
2
+
3
+ The framework is a very thin software layer built on top of [FastAPI](https://fastapi.tiangolo.com/) that provides developers with a set of coding features and tools that may be useful for any microservice (regardless of its role and domain/bounded context), such as:
4
+
5
+ - Implements all guidelines from https://12factor.net
6
+ - MVC Web App builder with fundamental abstractions
7
+ - Simple Dependency Injection mechanism, including automatic class discovery and instantiation
8
+ - Class-based API controller with automatic module discovery
9
+ - Modular Command/Query responsibility segregation
10
+ - Optional Event-sourcing for event-driven Domain modeling
11
+ - Clean layered Code https://levelup.gitconnected.com/clean-architecture-86c4f03e4771
12
+ - Pure Domain models, independent of persistence
13
+ - Application handlers (Command, Queries, Events, Tasks)
14
+ - Repository pattern
15
+ - Independent API controllers, endpoints and models (DTO's) vs Domain models and logic
16
+ - Native async Events ingestion, handling, emission (JSON [CloudEvent](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/formats/json-format.md)) using [ReactiveX programming](https://medium.com/@willAmaral/asynchronous-programming-and-rx-anything-479d9cb8daee) with [RxPy](https://rxpy.readthedocs.io/en/latest/)
17
+ - Data models mapping between Domain and Integration
18
+ - Easy extension for background task scheduling with [apscheduler](https://apscheduler.readthedocs.io/en/3.x/)
19
+ - etc...
20
+
21
+ The code typically includes comments that help understand it.
22
+
23
+ The `src/main.py` file is the entry point that defines all dependencies, including the sub-folders where to dynamically load the API, Application, Persistence and Domain layers.
24
+
25
+ In turn, when booting, the web app dynamically discovers, identifies and instantiate dependencies then loads:
26
+
27
+ - API controllers and define the mapping between each endpoint and its corresponding Application handler
28
+ - Application handlers (incl. Commands, Queries, Events, Tasks) and services (any business logic)
29
+ - Integration dependencies (any API client service, persistence-layer clients, ) and models (API' DTO for requests and responses)
30
+
31
+ ## Documentation
32
+
33
+ Temporarily hosted at https://bvandewe.github.io/pyneuro/
34
+
35
+ ## Disclaimer
36
+
37
+ This project was the opportunity for me (cdavernas) to learn Python while porting some of the concepts and services of the .NET version of the Neuroglia Framework
38
+
39
+ ## Packaging
40
+
41
+ ```sh
42
+ # Set the version tag in pyproject.toml
43
+ # Commit changes
44
+
45
+ poetry build
46
+
47
+ poetry publish --repository gitlab -u <token-username> -p <token-password>
48
+
49
+ ```
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "neuroglia-python"
3
- version = "0.1.1"
3
+ version = "0.1.3"
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"
@@ -8,21 +8,22 @@ readme = "README.md"
8
8
  packages = [
9
9
  { include = "neuroglia", from = "src" },
10
10
  ]
11
+ package-mode = true
11
12
 
12
13
  [tool.poetry.dependencies]
13
14
  python = "^3.12"
14
- annotated-types = "^0.6.0"
15
+ annotated-types = ">0.6.0"
15
16
  classy-fastapi = "^0.6.1"
16
- esdbclient = "^1.0.17"
17
- fastapi = "^0.109.2"
18
- grpcio = "^1.60.1"
19
- httpx = "^0.26.0"
17
+ esdbclient = ">1"
18
+ fastapi = "^0.115.12"
19
+ grpcio = ">=1.71"
20
+ httpx = "^0.28.1"
20
21
  multipledispatch = "^1.0.0"
21
22
  pydantic-settings = "^2.2.0"
22
23
  pymongo = "^4.6.1"
23
24
  python-dotenv = "^1.0.1"
24
25
  rx = "^3.2.0"
25
- uvicorn = "^0.27.1"
26
+ uvicorn = "^0.34.0"
26
27
  typing-extensions = "^4.9.0"
27
28
  pytest = "^8.1.1"
28
29
  mkdocs = "^1.6.1"
@@ -30,7 +31,7 @@ mkdocs-material = "^9.5.46"
30
31
 
31
32
  [tool.poetry.group.dev.dependencies]
32
33
  pytest = "^8.0.1"
33
- pytest-asyncio = "^0.23.5"
34
+ pytest-asyncio = "^0.26.0"
34
35
  mypy = "^1.8.0"
35
36
  autopep8 = "^2.0.4"
36
37
  coverage = "^7.4.1"
@@ -1,6 +1,6 @@
1
- from dataclasses import dataclass, field
1
+ from dataclasses import dataclass
2
2
  from datetime import datetime
3
- from typing import Any, Dict, Optional
3
+ from typing import Any, Optional
4
4
 
5
5
 
6
6
  class CloudEventSpecVersion:
@@ -26,7 +26,7 @@ class CloudEvent:
26
26
  dataschema (Optional[str]): An URI that references the versioned schema of the event's data.
27
27
  data (Optional[Any]): The event's data, if any. Only used if the event has been formatted using the structured mode.
28
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
- **extensions: Keyword arguments representing extension attributes.
29
+ extensionAttributes (Optional[Dict[str, Any]]): A mapping containing the event's extension attributes.
30
30
  '''
31
31
 
32
32
  id: str
@@ -65,31 +65,8 @@ class CloudEvent:
65
65
  data_base64: Optional[str] = None
66
66
  ''' Gets/sets the event's binary data, encoded in base 64. Used if the event has been formatted using the binary mode. '''
67
67
 
68
- extensions: Dict[str, Any] = field(default_factory=dict) # Store extensions in a dict
69
- ''' Gets/sets a mapping containing the event's extension attributes. '''
70
-
71
- def __post_init__(self, *args, **kwargs):
72
- # Capture any additional keyword arguments as extension attributes
73
- for key, value in kwargs.items():
74
- # only add them if they are not already defined fields
75
- if key not in self.__dataclass_fields__:
76
- self.extensions[key] = value
77
-
78
- def __getattr__(self, name):
79
- # Allow access to extensions as attributes
80
- if name in self.extensions:
81
- return self.extensions[name]
82
- raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
83
-
84
- def __setattr__(self, name, value):
85
- # Allow setting of extensions as attributes if it is an extension or not a predefined field.
86
- if name in self.extensions or name not in self.__dataclass_fields__:
87
- self.extensions[name] = value
88
- else:
89
- super().__setattr__(name, value) # Use default setting for standard attributes
90
-
91
68
  def get_attribute(self, name: str) -> Optional[Any]:
92
69
  ''' Gets the value of the attribute with the specified name, if any '''
93
70
  if not name:
94
71
  raise ValueError("Attribute name cannot be empty or None.")
95
- return getattr(self, name, None) # Use getattr to check both standard and extension attributes
72
+ self.__dict__[name] if name in self.__dict__.keys() else None
@@ -0,0 +1,82 @@
1
+ import logging
2
+ import os
3
+ import typing
4
+
5
+ # def configure_simplest_logging():
6
+ # logging.basicConfig(filename='logs/openbank.log', format='%(asctime)s %(levelname)-8s %(message)s', encoding='utf-8', level=logging.DEBUG)
7
+ # console_handler = logging.StreamHandler(sys.stdout)
8
+ # console_handler.setLevel(logging.DEBUG)
9
+ # log = logging.getLogger(__name__)
10
+ # log.addHandler(console_handler)
11
+
12
+
13
+ # def configure_logging_from_config(config_path: str):
14
+ # # config_path = "logging.conf"
15
+ # logging.config.fileConfig(config_path, disable_existing_loggers=True)
16
+
17
+
18
+ DEFAULT_LOG_FORMAT = "%(asctime)s %(levelname) - 8s %(name)s:%(lineno)d %(message)s"
19
+ DEFAULT_LOG_FILENAME = "logs/debug.log"
20
+ DEFAULT_LOG_LEVEL = "DEBUG"
21
+ DEFAULT_LOG_LIBRARIES_LIST = ["asyncio", "httpx", "httpcore"]
22
+ DEFAULT_LOG_LIBRARIES_LEVEL = "WARN"
23
+
24
+
25
+ def configure_logging(
26
+ log_level: str = DEFAULT_LOG_LEVEL,
27
+ log_format: str = DEFAULT_LOG_FORMAT,
28
+ console: bool = True,
29
+ file: bool = True,
30
+ filename: str = DEFAULT_LOG_FILENAME,
31
+ lib_list: typing.List = DEFAULT_LOG_LIBRARIES_LIST,
32
+ lib_level: str = DEFAULT_LOG_LIBRARIES_LEVEL,
33
+ ):
34
+ """Configures the root logger with the given format and handler(s).
35
+ Optionally, the log level for some libraries may be customized separately
36
+ (which is interesting when setting a log level DEBUG on root but not wishing to see debugs for all libs).
37
+
38
+ Args:
39
+ log_level (str, optional): The log_level for the root logger. Defaults to DEFAULT_LOG_LEVEL.
40
+ log_format (str, optional): The format of the log records. Defaults to DEFAULT_LOG_FORMAT.
41
+ console (bool, optional): Whether to enable the console handler. Defaults to True.
42
+ file (bool, optional): Whether to enable the file-based handler. Defaults to True.
43
+ filename (str, optional): If file-based handler is enabled, this will set the filename of the log file. Defaults to DEFAULT_LOG_FILENAME.
44
+ lib_list (typing.List, optional): List of libraries/packages name. Defaults to DEFAULT_LOG_LIBRARIES_LIST.
45
+ lib_level (str, optional): The separate log level for the libraries included in the lib_list. Defaults to DEFAULT_LOG_LIBRARIES_LEVEL.
46
+ """
47
+ root_logger = logging.getLogger()
48
+ root_logger.setLevel(log_level)
49
+ formatter = logging.Formatter(log_format)
50
+ if console:
51
+ _configure_console_based_logging(root_logger, log_level, formatter)
52
+ if file:
53
+ _configure_file_based_logging(root_logger, log_level, formatter, filename)
54
+
55
+ for lib_name in lib_list:
56
+ logging.getLogger(lib_name).setLevel(lib_level)
57
+
58
+
59
+ def _configure_console_based_logging(root_logger, log_level, formatter):
60
+ console_handler = logging.StreamHandler()
61
+ handler = _configure_handler(console_handler, log_level, formatter)
62
+ root_logger.addHandler(handler)
63
+
64
+
65
+ def _configure_file_based_logging(root_logger, log_level, formatter, filename):
66
+ # Ensure the directory exists
67
+ os.makedirs(os.path.dirname(filename), exist_ok=True)
68
+
69
+ # Check if the file exists, if not, create it
70
+ if not os.path.isfile(filename):
71
+ with open(filename, "w"): # This will create the file if it does not exist
72
+ pass
73
+
74
+ file_handler = logging.FileHandler(filename)
75
+ handler = _configure_handler(file_handler, log_level, formatter)
76
+ root_logger.addHandler(handler)
77
+
78
+
79
+ def _configure_handler(handler: logging.StreamHandler, log_level, formatter) -> logging.StreamHandler:
80
+ handler.setLevel(log_level)
81
+ handler.setFormatter(formatter)
82
+ return handler
@@ -1,49 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: neuroglia-python
3
- Version: 0.1.1
4
- Summary: Port from .NET to Python of the Neuroglia Framework
5
- License: Apache
6
- Author: Charles d'Avernas
7
- Author-email: charles.davernas@neuroglia.io
8
- Requires-Python: >=3.12,<4.0
9
- Classifier: License :: Other/Proprietary License
10
- Classifier: Programming Language :: Python :: 3
11
- Classifier: Programming Language :: Python :: 3.12
12
- Requires-Dist: annotated-types (>=0.6.0,<0.7.0)
13
- Requires-Dist: classy-fastapi (>=0.6.1,<0.7.0)
14
- Requires-Dist: esdbclient (>=1.0.17,<2.0.0)
15
- Requires-Dist: fastapi (>=0.109.2,<0.110.0)
16
- Requires-Dist: grpcio (>=1.60.1,<2.0.0)
17
- Requires-Dist: httpx (>=0.26.0,<0.27.0)
18
- Requires-Dist: mkdocs (>=1.6.1,<2.0.0)
19
- Requires-Dist: mkdocs-material (>=9.5.46,<10.0.0)
20
- Requires-Dist: multipledispatch (>=1.0.0,<2.0.0)
21
- Requires-Dist: pydantic-settings (>=2.2.0,<3.0.0)
22
- Requires-Dist: pymongo (>=4.6.1,<5.0.0)
23
- Requires-Dist: pytest (>=8.1.1,<9.0.0)
24
- Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
25
- Requires-Dist: rx (>=3.2.0,<4.0.0)
26
- Requires-Dist: typing-extensions (>=4.9.0,<5.0.0)
27
- Requires-Dist: uvicorn (>=0.27.1,<0.28.0)
28
- Description-Content-Type: text/markdown
29
-
30
- # Neuroglia Python Framework
31
-
32
- A framework of libraries used to build modern Python V3 applications
33
-
34
- ## Disclaimer
35
-
36
- This project was the opportunity for me (cdavernas) to learn Python while porting some of the concepts and services of the .NET version of the Neuroglia Framework
37
-
38
- ## Packaging
39
-
40
- ```sh
41
- # Set the version tag in pyproject.toml
42
- # Commit changes
43
-
44
- poetry build
45
-
46
- poetry publish --repository gitlab -u <token-username> -p <token-password>
47
-
48
- ```
49
-
@@ -1,19 +0,0 @@
1
- # Neuroglia Python Framework
2
-
3
- A framework of libraries used to build modern Python V3 applications
4
-
5
- ## Disclaimer
6
-
7
- This project was the opportunity for me (cdavernas) to learn Python while porting some of the concepts and services of the .NET version of the Neuroglia Framework
8
-
9
- ## Packaging
10
-
11
- ```sh
12
- # Set the version tag in pyproject.toml
13
- # Commit changes
14
-
15
- poetry build
16
-
17
- poetry publish --repository gitlab -u <token-username> -p <token-password>
18
-
19
- ```