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
NetConfParser is a tool that helps you analyze the rpcs coming and going from a netconf client to a server

NetConfParser is a tool that helps you analyze the rpcs coming and going from a netconf client to a server

Aero 1 Mar 31, 2022
'ToolBurnt' A Set Of Tools In One Place =}

'ToolBurnt' A Set Of Tools In One Place =}

MasterBurnt 5 Sep 10, 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
Small Python script to parse endlessh's output and print some neat statistics

endlessh_parser endlessh_parser is a small Python script that parses endlessh's output and prints some neat statistics about it Usage Install all the

ManicRobot 1 Oct 18, 2021
✨ Un générateur de lien raccourcis en fonction d'un lien totalement fait en Python par moi, et en français.

Shorter Link ❗ Un générateur de lien raccourcis en fonction d'un lien totalement fait en Python par moi, et en français. Dépendences : pip install pys

MrGabin 3 Jun 06, 2021
This repository contains scripts that help you validate QR codes.

Validation tools This repository contains scripts that help you validate QR codes. It's hacky, and a warning for Apple Silicon users: the dependencies

Ryan Barrett 8 Mar 01, 2022
A plugin to simplify creating multi-page Dash apps

Multi-Page Dash App Plugin A plugin to simplify creating multi-page Dash apps. This is a preview of functionality that will of Dash 2.1. Background Th

Plotly 19 Dec 09, 2022
Airspy-Utils is a small software collection to help with firmware related operations on Airspy HF+ devices.

Airspy-Utils Airspy-Utils is a small software collection to help with firmware related operations on Airspy HF+ devices on Linux (and other free syste

Dhiru Kholia 11 Oct 04, 2022
PyHook is an offensive API hooking tool written in python designed to catch various credentials within the API call.

PyHook is the python implementation of my SharpHook project, It uses various API hooks in order to give us the desired credentials. PyHook Uses

Ilan Kalendarov 158 Dec 22, 2022
Napari plugin for loading Bitplane Imaris files .ims

napari-imaris-loader Napari plugin for loading Bitplane Imaris files '.ims'. Notes: For this plugin to work "File/Preferences/Experimental/Render Imag

Alan Watson 4 Dec 01, 2022
Creating low-level foundations and abstractions for asynchronous programming in Python.

DIY Async I/O Creating low-level foundations and abstractions for asynchronous programming in Python (i.e., implementing concurrency without using thr

Doc Jones 4 Dec 11, 2021
VerSign: Easy Signature Verification in Python

VerSign: Easy Signature Verification in Python versign is a small Python package which can be used to perform verification of offline signatures. It a

Muhammad Saif Ullah Khan 3 Dec 01, 2022
A simple tool to move and rename Nvidia Share recordings to a more sensible format.

A simple tool to move and rename Nvidia Share recordings to a more sensible format.

Jasper Rebane 8 Dec 23, 2022
✨ Un générateur d'adresse IP aléatoire totalement fait en Python par moi, et en français.

IP Generateur ❗ Un générateur d'adresse IP aléatoire totalement fait en Python par moi, et en français. 🔮 Avec l'utilisation du module "random", j'ai

MrGabin 3 Jun 06, 2021
This tool lets you perform some quick tasks for CTFs and Pentesting.

This tool lets you convert strings and numbers between number bases (2, 8, 10 and 16) as well as ASCII text. You can use the IP address analyzer to find out details on IPv4 and perform abbreviation a

Ayomide Ayodele-Soyebo 1 Jul 16, 2022
Generates a random prnt.sc link and display image.

Generates a random prnt.sc link and display image.

Emirhan 3 Oct 08, 2021
Greenery - tools for parsing and manipulating regular expressions

Greenery - tools for parsing and manipulating regular expressions

qntm 242 Dec 15, 2022
🦩 A Python tool to create comment-free Jupyter notebooks.

Pelikan Pelikan lets you convert notebooks to comment-free notebooks. In other words, It removes Python block and inline comments from source cells in

Hakan Özler 7 Nov 20, 2021
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
Simple profile athena generator for Fortnite Private Servers.

Profile-Athena-Generator A simple profile athena generator for Fortnite Private Servers. This profile athena generrator features: Item variants Get al

Fevers 10 Aug 27, 2022