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
A simple tool that updates your pubspec.yaml file, of a Flutter project, without altering the structure of your file.

A simple tool that updates your pubspec.yaml file, of a Flutter project, without altering the structure of your file.

3 Dec 10, 2021
Adding two matrix from scratch using python.

Adding-two-matrix-from-scratch-using-python. Here, I have take two matrix from user and add it without using any library. I made this program from scr

Sachin Vinayak Dabhade 4 Sep 24, 2021
Homebase Name Changer for Fortnite: Save the World.

Homebase Name Changer This program allows you to change the Homebase name in Fortnite: Save the World. How to use it? After starting the HomebaseNameC

PRO100KatYT 7 May 21, 2022
Gradually automate your procedures, one step at a time

Gradualist Gradually automate your procedures, one step at a time Inspired by https://blog.danslimmon.com/2019/07/15/ Features Main Features Converts

Ross Jacobs 8 Jul 24, 2022
A quick username checker to see if a username is available on a list of assorted websites.

A quick username checker to see if a username is available on a list of assorted websites.

Maddie 4 Jan 04, 2022
A python module for extract domains

A python module for extract domains

Fayas Noushad 4 Aug 10, 2022
Abby's Left Hand Modifiers Dictionary

Abby's Left Hand Modifiers Dictionary Design This dictionary is inspired by and

12 Dec 08, 2022
A script to parse and display buy_tag and sell_reason for freqtrade backtesting trades

freqtrade-buyreasons A script to parse and display buy_tag and sell_reason for freqtrade backtesting trades Usage Copy the buy_reasons.py script into

Robert Davey 31 Jan 01, 2023
✨ Un DNS Resolver totalement fait en Python par moi, et en français

DNS Resolver ❗ Un DNS Resolver totalement fait en Python par moi, et en français. 🔮 Grâce a une adresse (url) vous pourrez avoir l'ip ainsi que le DN

MrGabin 3 Jun 06, 2021
Collection of code auto-generation utility scripts for the Horizon `Boot` system module

boot-scripts This is a collection of code auto-generation utility scripts for the Horizon Boot system module, intended for use in Atmosphère. Usage Us

4 Oct 11, 2022
A fast Python implementation of Ac Auto Mechine

A fast Python implementation of Ac Auto Mechine

Jin Zitian 1 Dec 07, 2021
Python code to generate and store certificates automatically , using names from a csv file

WOC-certificate-generator Python code to generate and store certificates automatically , using names from a csv file IMPORTANT In order to make the co

Google Developer Student Club - IIIT Kalyani 10 May 26, 2022
Creates a C array from a hex-string or a stream of binary data.

hex2array-c Creates a C array from a hex-string. Usage Usage: python3 hex2array_c.py HEX_STRING [-h|--help] Use '-' to read the hex string from STDIN.

John Doe 3 Nov 24, 2022
Check the basic quality of any dataset

Data Quality Checker in Python Check the basic quality of any dataset. Sneak Peek Read full tutorial at Medium. Explore the app Requirements python 3.

MalaDeep 8 Feb 23, 2022
Software to help automate collecting crowdsourced annotations using Mechanical Turk.

Video Crowdsourcing Software to help automate collecting crowdsourced annotations using Mechanical Turk. The goal of this project is to enable crowdso

Mike Peven 1 Oct 25, 2021
Create C bindings for python automatically with the help of libclang

Python C Import Dynamic library + header + ctypes = Module like object! Create C bindings for python automatically with the help of libclang. Examples

1 Jul 25, 2022
Early version for manipulate Geo localization data trough API REST.

Backend para obtener los datos (beta) Descripción El servidor está diseñado para recibir y almacenar datos enviados en forma de JSON por una aplicació

Víctor Omar Vento Hernández 1 Nov 14, 2021
A python lib for generate random string and digits and special characters or A combination of them

A python lib for generate random string and digits and special characters or A combination of them

Torham 4 Nov 15, 2022
An okayish python script to generate a random Euler circuit with given number of vertices and edges.

Euler-Circuit-Test-Case-Generator An okayish python script to generate a random Euler circuit with given number of vertices and edges. Executing the S

Alen Antony 1 Nov 13, 2021
A script copies movie and TV files to your GD drive, or create Hard Link in a seperate dir, in Emby-happy struct.

torcp A script copies movie and TV files to your GD drive, or create Hard Link in a seperate dir, in Emby-happy struct. Usage: python3 torcp.py -h Exa

ccf2012 105 Dec 22, 2022