Sincpro framework to use DDD, Clean architecture, Hexagonal architecture
Project description
Sincpro Framework (Application layer framework)
The main goal of this framework is create a proxy and facade component/entity, using a pattern bus components that wraps all the application layer, allowing to the developer import all the business logic ready to be executed in any context
Main features:
- Allow to inject
dependenciesprovided by the user - Allow to inject
error handlerat the top level - Execute the business logic in a
buscomponent only providing the DTO(Data transfer object) - Allow to execute decoupled (
use case,feature,business logic)- using the component
Feature
- using the component
- Allow to execute several
use casesbased on abstraction calledApplicationService- This one contains the
feature busand the developer will be able to execute theuse casein any context
- This one contains the
Example usage
Init the framework
This framework provide a command bus that will provide to the developer register use cases
Feature-> This component will be used to execute decoupled business logicApplicationService-> This component has injected thefeature busand the developer will be able to execute the registeredFeature
# Import the framework
from sincpro_framework import (
UseFramework,
ApplicationService,
DataTransferObject,
Feature as _Feature
)
# Define exceptions this is optional but is a good practice
class GlobalError(Exception): pass
class AppServiceError(Exception): pass
class FeatureError(Exception): pass
# Some dependencies as function
def call_print(algo):
print(f"Calling from closure {algo}")
def global_error_handler(error):
"""
Global layer to handle an error
This function will catch all the exceptions that were
raised
"""
if isinstance(error, GlobalError):
print("ERROR HANDLEADO")
else:
raise Exception("ERROR NO HANDLEADO")
def app_error_handler(error):
"""
We add a handler for `application service` errors
"""
if isinstance(error, AppServiceError):
print("APPLICATION HANDLER ERROR")
raise GlobalError("ERROR DESEDE APPLICATION")
else:
raise Exception("ERROR NO HANDLEADO")
def feat_error_handler(error):
"""
"""
if isinstance(error, FeatureError):
print("FEATURE HANDLER ERROR")
raise AppServiceError("ERROR DESEDE FEATURE")
else:
raise Exception("ERROR NO HANDLEADO")
framework_sp = UseFramework()
# You can add as many dependencies as you want
# Also need to provide a name to the dependency, so in the context of the framework
# you will be able to call the injedted dependency
framework_sp.add_dependency("andres", call_print)
framework_sp.add_global_error_handler(global_error_handler)
framework_sp.add_app_service_error_handler(app_error_handler)
framework_sp.add_feature_error_handler(feat_error_handler)
# -------------------------------------------- #
# Buena practica en caso de querer tipar las injecciones de dependiencias
# se sugiere crear una clase `Feature` o `ApplicationService` que hereden de las abtracciones
# por ejemplo estamos importando `Feature` original pero como `_Feature` para no confundir
from typing import TypeAlias
class Feature(_Feature, ABC):
andres: TypeAlias = call_print
# de esta forma el IDE o editor nos ayudara a ver los tipos de las injecciones de dependencias
# Recordar utilizar la clase Feature de este modulo en lugar de `sincpro_framework.Feature` ya que este contiene
# los tipos de las injecciones de dependencias y normalmente este contiene toda la configuracion
once you initialize the bus, you will be able to import the framework in your application layer
this framework should be used in the application layer
pattern to import the framework follow the next snippet
# Path file: src.apps.siat_api
# Application layer main entry: __init__.py
# import the initialized framework
from src.apps.some_application.infrastructure.sp_framework import (
ApplicationService,
DataTransferObject,
Feature,
framework_sp,
)
# the `use_case` represent the application layer inside of it
# you should find all the `Feature` and `ApplicationService`
from .use_case import *
# Require to export to be consumed for the infrastructure layer or the more external layer
__all__ = [
"use_case",
"framework_sp",
"Feature",
"DataTransferObject",
"ApplicationService",
]
# then import the framework_sp from any another consumer
Once you have the framework imported you will be able to register the use cases(Features or ServiceApplication)
from src.apps.some_application import framework_sp
# -------------------------------------------- #
# Feature
# -------------------------------------------- #
@dataclass(kw_only=True)
class CommandRegisterServiceConfiguration(DataTransferObject):
comm: str
@dataclass(kw_only=True)
class ResponseRegisterServiceConfiguration(DataTransferObject):
comm: str
@framework_sp.feature(CommandRegisterServiceConfiguration)
class RegisterServiceConfiguration(Feature):
def execute(
self, dto: CommandRegisterServiceConfiguration
) -> ResponseRegisterServiceConfiguration:
raise FeatureError("EError de feature")
return ResponseRegisterServiceConfiguration(comm=dto.comm)
# -------------------------------------------- #
# Application service
# -------------------------------------------- #
@dataclass(kw_only=True)
class CommandRegisterServiceConfiguration2(DataTransferObject):
comm: str
@dataclass(kw_only=True)
class ResponseRegisterServiceConfiguration(DataTransferObject):
comm: str
@framework_sp.app_service(CommandRegisterServiceConfiguration2)
class RegisterServiceConfiguration(ApplicationService):
def execute(
self, dto: CommandRegisterServiceConfiguration2
) -> ResponseRegisterServiceConfiguration:
self.andres("Hello") # -> Dependency injected by the user
self.feature_bus.execute(CommandRegisterServiceConfiguration(comm="Hello")) #-> Decoupled feature
raise AppServiceError("Testing Global error")
return ResponseRegisterServiceConfiguration(comm=dto.comm)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sincpro_framework-1.0.1.tar.gz.
File metadata
- Download URL: sincpro_framework-1.0.1.tar.gz
- Upload date:
- Size: 8.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.12.6 Linux/6.8.0-45-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
200e20f2698789b26ac69aa3b36f578480e14c6a3c5de68c04e95a19ff372928
|
|
| MD5 |
94cf14d2dd7175b2ebaf3fba8a9f0f05
|
|
| BLAKE2b-256 |
2bca1b0504902a216188d890cb6770d234cee744397e4e824c2e9cddba434ff1
|
File details
Details for the file sincpro_framework-1.0.1-py3-none-any.whl.
File metadata
- Download URL: sincpro_framework-1.0.1-py3-none-any.whl
- Upload date:
- Size: 9.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.12.6 Linux/6.8.0-45-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d26ca35b857d44184887568c460e138551dbf7b6854655ea583827c19cb83ee6
|
|
| MD5 |
509d29678214980f9c9364864dc145ac
|
|
| BLAKE2b-256 |
9d931809882493124ef40607926f0f8b0aea601698b41d5f00601047e4245fe0
|