A Container for the Dependency Injection in Python.

Overview

Python Dependency Injection library

aiodi is a Container for the Dependency Injection in Python.

Installation

Use the package manager pip to install aiodi.

pip install aiodi

Documentation

Usage

from abc import ABC, abstractmethod
from logging import Logger, getLogger, NOTSET, StreamHandler, Formatter
from os import getenv

from aiodi import Container
from typing import Optional, Union

_CONTAINER: Optional[Container] = None


def get_simple_logger(
        name: Optional[str] = None,
        level: Union[str, int] = NOTSET,
        fmt: str = '[%(asctime)s] - %(name)s - %(levelname)s - %(message)s',
) -> Logger:
    logger = getLogger(name)
    logger.setLevel(level)
    handler = StreamHandler()
    handler.setLevel(level)
    formatter = Formatter(fmt)
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    return logger


class GreetTo(ABC):
    @abstractmethod
    def __call__(self, who: str) -> None:
        pass


class GreetToWithPrint(GreetTo):
    def __call__(self, who: str) -> None:
        print('Hello ' + who)


class GreetToWithLogger(GreetTo):
    _logger: Logger

    def __init__(self, logger: Logger) -> None:
        self._logger = logger

    def __call__(self, who: str) -> None:
        self._logger.info('Hello ' + who)


def container() -> Container:
    global _CONTAINER
    if _CONTAINER:
        return _CONTAINER
    di = Container({'env': {
        'name': getenv('APP_NAME', 'aiodi'),
        'log_level': getenv('APP_LEVEL', 'INFO'),
    }})
    di.resolve([
        (
            Logger,
            get_simple_logger,
            {
                'name': di.resolve_parameter(lambda di_: di_.get('env.name', typ=str)),
                'level': di.resolve_parameter(lambda di_: di_.get('env.log_level', typ=str)),
            },
        ),
        (GreetTo, GreetToWithLogger),  # -> (GreetTo, GreetToWithLogger, {})
        GreetToWithPrint,  # -> (GreetToWithPrint, GreetToWithPrint, {})
    ])
    di.set('who', 'World!')
    # ...
    _CONTAINER = di
    return di


def main() -> None:
    di = container()

    di.get(Logger).info('Just simple call get with the type')

    for greet_to in di.get(GreetTo, instance_of=True):
        greet_to(di.get('who'))


if __name__ == '__main__':
    main()

Requirements

  • Python >= 3.6

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

License

MIT

Comments
  • Add status badges to README.md

    Add status badges to README.md

    As other Open source projects have, add the badges of the status of the CI passing the tests in GitHub Actions, of the latest version available in PyPi and the number of total downloads to the README.md.

    documentation good first issue 
    opened by ticdenis 0
  • Supports multiple casting for variables using ContainerBuilder

    Supports multiple casting for variables using ContainerBuilder

    Currently we have 3 options to cast variables using the ContainerBuilder:

    # pyproject.toml
    
    [tool.aiodi.variables]
    # Get static text.
    debug = "Text"
    # Get as str a variable.
    debug2 = "%var(debug)%"
    # Cast to int an environment variable.
    debug3 = "%env(int:APP_DEBUG, '1')%"
    

    But we can not do:

    # pyproject.toml
    
    [tool.aiodi.variables]
    # ...
    debug4 = "%env(bool:int:APP_DEBUG, '1')%"
    

    We've detected that this is a common operation so would be great have it integrate it on ContainerBuilder.

    enhancement 
    opened by ticdenis 0
  • Support for resolving Generic types as argument

    Support for resolving Generic types as argument

    Currently is not supported if we have something like:

    from typing import TypeVar
    
    
    Driver = TypeVar('Driver')
    
    class Connection(Generic[Driver]):
      ...
      
    class FakeConnection(Connection[int]):
      ...
      
    class App:
      def __init__(self, connection: Connection[int]) -> None:
        self._connection = connection
    

    When we try to resolve Connection as an argument will fail, example:

    # ...
    
    di.resolve([
      (Connection, FakeConnection()),
      (App), # will fail
    ])
    
    bug help wanted 
    opened by ticdenis 0
  • Improve CommandBuilder dependency resolution system

    Improve CommandBuilder dependency resolution system

    It is currently quite convoluted, abusing loops with a limit of the cube depending on the number of elements to be solved and messing up the unsolved elements so that they can be incorporated into the head of the next iteration and avoid infinite loops. But there can be.

    The dependency resolution system should be improved, as an idea based on a tree system.

    bug enhancement help wanted 
    opened by ticdenis 0
  • Support for resolving typed lists with ContainerBuilder

    Support for resolving typed lists with ContainerBuilder

    This is currently not possible and it would be great if examples like the following could work.

    class UserPermission:
      pass
    
    def default_user_permissions() -> list[UserPermission]:
      return [UserPermission()]
    
    class UserHandler:
      __slots__  = '_permissions'
      
      def __init__(self, permissions: list[UserPermission]) -> None:
        self._permissions = permissions 
    
    [tool.aiodi.services."default_user_permissions"]
    class = "sample.default_user_permissions"
    
    [tool.aiodi.services."UserHandler"]
    class = "sample.UserHandler" # <- this will fails because library does not inspect list type.
    
    enhancement help wanted 
    opened by ticdenis 0
Releases(1.1.4)
  • 1.1.4(Jun 9, 2022)

  • 1.1.2(Feb 20, 2022)

    What's Changed

    • refactor(*): Improve ContainerBuilder architecture by @ticdenis in https://github.com/ticdenis/python-aiodi/pull/6
    • Support multiple casting for variables and allows "None" as None for default values by @ticdenis in https://github.com/ticdenis/python-aiodi/pull/7

    Full Changelog: https://github.com/ticdenis/python-aiodi/compare/1.1.1...1.1.2

    Source code(tar.gz)
    Source code(zip)
  • 1.1.1(Feb 10, 2022)

  • 1.1.0(Jan 19, 2022)

    What's Changed

    • release(1.0.0): Initial release by @ticdenis in https://github.com/ticdenis/python-aiodi/pull/2
    • docs: Add symbolic link for index.md to en/index.md by @ticdenis in https://github.com/ticdenis/python-aiodi/pull/3
    • feat(*): Add support for pyproject.toml by @ticdenis in https://github.com/ticdenis/python-aiodi/pull/4

    Full Changelog: https://github.com/ticdenis/python-aiodi/commits/1.1.0

    Source code(tar.gz)
    Source code(zip)
Owner
Denis NA
Denis NA
Bounding Boxes Python Utils

Bounding Boxes Python Utils

Vadim 4 May 01, 2022
Casefy (/keɪsfaɪ/) is a lightweight Python package to convert the casing of strings

Casefy (/keɪsfaɪ/) is a lightweight Python package to convert the casing of strings. It has no third-party dependencies and supports Unicode.

Diego Miguel Lozano 12 Jan 08, 2023
Automatically Generate Rulesets for IIS for Intelligent HTTP/S C2 Redirection

Automatically Generate Rulesets for IIS for Intelligent HTTP/S C2 Redirection This project converts a Cobalt Strike profile to a functional web.config

Jesse 99 Dec 13, 2022
A Python library for reading, writing and visualizing the OMEGA Format

A Python library for reading, writing and visualizing the OMEGA Format, targeted towards storing reference and perception data in the automotive context on an object list basis with a focus on an urb

Institut für Kraftfahrzeuge, RWTH Aachen, ika 12 Sep 01, 2022
This utility synchronises spelling dictionaries from various tools with each other.

This utility synchronises spelling dictionaries from various tools with each other. This way the words that have been trained on MS Office are also correctly checked in vim or Firefox. And vice versa

Patrice Neff 2 Feb 11, 2022
Build capture utility for Linux

CX-BUILD Compilation Database alternative Build Prerequisite the CXBUILD uses linux system call trace utility called strace which was customized. So I

GLaDOS (G? L? Automatic Debug Operation System) 3 Nov 03, 2022
Playing with python imports and inducing those pesky errors.

super-duper-python-imports In this repository we are playing with python imports and inducing those pesky ImportErrors. File Organization project │

James Kelsey 2 Oct 14, 2021
Extract the download URL from OneDrive or SharePoint share link and push it to aria2

OneDriveShareLinkPushAria2 Extract the download URL from OneDrive or SharePoint share link and push it to aria2 从OneDrive或SharePoint共享链接提取下载URL并将其推送到a

高玩梁 262 Jan 08, 2023
A python script to generate wallpaper

wallpaper eits Warning You need to set the path to Robot Mono font in the source code. (Settings are in the main function) Usage A script that given a

Henrique Tsuyoshi Yara 5 Dec 02, 2021
Easy compression and extraction for any compression or archival format.

Tzar: Tar, Zip, Anything Really Easy compression and extraction for any compression or archival format. Usage/Examples tzar compress large-dir compres

DanielVZ 37 Nov 02, 2022
This is a tool to calculate a resulting color of the alpha blending process.

blec: alpha blending calculator This is a tool to calculate a resulting color of the alpha blending process. A gamma correction is enabled and the def

Igor Mikushkin 12 Sep 07, 2022
.bvh to .mcfunction file converter.

bvh-to-mcf .bvh file to .mcfunction converter

Hanmin Kim 28 Nov 21, 2022
cpp20.py is a Python script to compile C++20 code using modules.

cpp20.py is a Python script to compile C++20 code using modules. It browses the source files to determine their dependencies. Then, it compiles then in order using the correct flags.

Julien VERNAY 6 Aug 26, 2022
A simple toolchain for moving Remarkable highlights to Readwise

A simple toolchain for moving Remarkable highlights to Readwise

zach wick 20 Dec 20, 2022
Create a Web Component (a Custom Element) from a python file

wyc Create a Web Component (a Custom Element) from a python file (transpile python code to javascript (es2015)). Features Use python to define your cu

7 Oct 09, 2022
This project is a set of programs that I use to create a README.md file.

This project is a set of programs that I use to create a README.md file.

Tom Dörr 223 Dec 24, 2022
Make your functions return something meaningful, typed, and safe!

Make your functions return something meaningful, typed, and safe! Features Brings functional programming to Python land Provides a bunch of primitives

dry-python 2.6k Jan 09, 2023
Python program for analyzing the output files of phonopy.

PhononTools Description Python program to analyze the results generated by phonopy. Using the .yaml and .dat files that phonopy generates one can plot

Harry LaBollita 8 Nov 27, 2022
Install, run, and update apps without root and only in your home directory

Qube Apps Install, run, and update apps in the private storage of a Qube. Build and install in Qubes Get the code: git clone https://github.com/micahf

Micah Lee 26 Dec 27, 2022
Python Libraries with functions and constants related to electrical engineering.

ElectricPy Electrical-Engineering-for-Python Python Libraries with functions and constants related to electrical engineering. The functions and consta

Joe Stanley 39 Dec 23, 2022