From 2beedcd5ec756c636fbc9d04d9e96c5ee2b076cc Mon Sep 17 00:00:00 2001 From: Thomas Rabaix Date: Sun, 29 Jun 2025 22:07:34 +0000 Subject: [PATCH 1/2] feat(pydantic): add support for pydantic model --- ioc/component.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/ioc/component.py b/ioc/component.py index 5f7b0f4..382b0a2 100644 --- a/ioc/component.py +++ b/ioc/component.py @@ -20,6 +20,13 @@ import importlib, inspect, re, logging +HAS_PYDANTIC = False +try: + from pydantic import BaseModel as PydanticBaseModel + HAS_PYDANTIC = True +except ImportError: + pass + class Reference(object): def __init__(self, id: str, method: Optional[str] = None) -> None: self.id = id @@ -102,6 +109,22 @@ def __init__(self, logger: Optional[logging.Logger] = None) -> None: self.stack: list[str] = [] def _resolve(self, parameter: Any, parameter_holder: ParameterHolder) -> Any: + if HAS_PYDANTIC and isinstance(parameter, PydanticBaseModel): + # If the parameter is a Pydantic model, resolve its fields + def walk_and_modify(model): + for field in model.__fields__: + value = getattr(model, field) + if isinstance(value, PydanticBaseModel): + parameter = walk_and_modify(value) # Recursive call for nested models + else: + parameter = self.resolve(value, parameter_holder) + + setattr(model, field, parameter) + + return model + + return walk_and_modify(parameter) + if isinstance(parameter, (tuple)): parameter = list(parameter) for key in get_keys(parameter): From 718d831ad4059af72a8ecf27806961863dc12fc7 Mon Sep 17 00:00:00 2001 From: Thomas Rabaix Date: Sun, 29 Jun 2025 22:09:09 +0000 Subject: [PATCH 2/2] feat(resources): add support for a more flatten organisation --- docs/references/extension.rst | 4 ++-- ioc/extra/jinja2/di.py | 1 + ioc/extra/locator/di.py | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/references/extension.rst b/docs/references/extension.rst index b7f32df..2b26900 100644 --- a/docs/references/extension.rst +++ b/docs/references/extension.rst @@ -17,7 +17,7 @@ Here a flask extension, ``ioc.extra.flask.di.Extension`` # load an external file defining services loader = ioc.loader.YamlLoader() - loader.load("%s/resources/config/flask.yml" % path, container_builder) + loader.load("%s/config/flask.yml" % path, container_builder) # set default parameters into the container to be reuse by the container builder # or by external services @@ -125,4 +125,4 @@ shirka configuration defined inside the ``config.yml`` file:: base_url: '/shirka/api' data_dir: '%base_dir%/data' -So through some configuration, the user can configure how the Flask action will be expose ``/shirka/api``. \ No newline at end of file +So through some configuration, the user can configure how the Flask action will be expose ``/shirka/api``. diff --git a/ioc/extra/jinja2/di.py b/ioc/extra/jinja2/di.py index 861805d..d25d7d3 100644 --- a/ioc/extra/jinja2/di.py +++ b/ioc/extra/jinja2/di.py @@ -33,6 +33,7 @@ def load(self, config, container_builder): mapping[name] = jinja2.FileSystemLoader([ "%s/resources/%s/templates" % (container_builder.parameters.get('project.root_folder'), name), "%s/resources/templates" % os.path.dirname(importlib.import_module(name).__file__), + "%s/templates" % os.path.dirname(importlib.import_module(name).__file__), ]) container_builder.parameters.set("ioc.extra.jinja2.loader_mapping", mapping) diff --git a/ioc/extra/locator/di.py b/ioc/extra/locator/di.py index 4aad5a1..5f9b6c2 100644 --- a/ioc/extra/locator/di.py +++ b/ioc/extra/locator/di.py @@ -25,7 +25,8 @@ def load(self, config, container_builder): for extension in extensions: arguments = [[ Definition('ioc.locator.FileSystemLocator', arguments=["%s/resources/%s" % (container_builder.parameters.get('project.root_folder'), extension)]), - Definition('ioc.locator.PackageLocator', arguments=[extension], kwargs={'package_path': 'resources'}) + Definition('ioc.locator.PackageLocator', arguments=[extension], kwargs={'package_path': 'resources'}), + Definition('ioc.locator.PackageLocator', arguments=[extension], kwargs={'package_path': ''}) ]] locator_map[extension] = Definition('ioc.locator.ChoiceLocator', arguments=arguments)