Python lightweight dependency injection library

Overview

pythondi

license pypi pyversions badge Downloads


pythondi is a lightweight dependency injection library for python

Support both sync and async functions

Installation

pip3 install pythondi

Usage

First, you have to binding classes to provider.

There is three different ways to binding.

  • Binding one by one
from pythondi import Provider


provider = Provider()
provider.bind(Repo, SQLRepo)
provider.bind(Usecase, CreateUsecase)
  • Binding at initialization
from pythondi import Provider


provider = Provider(cls=Repo, new_cls=SQLRepo)
  • Binding at initialization with dictionary
from pythondi import Provider


provider = Provider(classes={Repo: SQLRepo, Usecase: CreateUsecase})

After binding, you need to configure it to container

from pythondi import configure, configure_after_clear


# Inject with configure
configure(provider=provider)

# Or if you want to fresh inject, use `configure_after_clear`
configure_after_clear(provider=provider)

Import inject

from pythondi import inject

Add type annotations that you want to inject dependencies

class Usecase:
    def __init__(self, repo: Repo):
        self.repo = repo

Add decorator

class Usecase:
    @inject()
    def __init__(self, repo: Repo):
        self.repo = repo

Initialize class with no arguments

usecase = Usecase()

Or, you can also inject manually through decorator arguments

class Usecase:
    @inject(repo=SQLRepo)
    def __init__(self, repo):
        self.repo = repo

In this case, do not have to configure providers and type annotation.

For test

In case of test codes, you probably want to use mock objects.

In that case, you must use keyword arguments.

class MockRepo:
    pass


@inject()
def test(repo: Repo):
    return repo

Yes:

test(repo=MockRepo())

No:

test(MockRepo())
test(MockRepo)

Note

At the moment of inject, class is automatically initialized.

So you don't have to initialize your class inside of code.

Yes:

@inject()
def __init__(self, repo: Repo):
    self.repo = repo

No:

@inject()
def __init__(self, repo: Repo):
    self.repo = repo()

General example

import abc

from pythondi import Provider, configure, configure_after_clear, inject


class Repo:
    """Interface class"""
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def get(self):
        pass


class SQLRepo(Repo):
    """Impl class"""
    def get(self):
        print('SQLRepo')


class Usecase:
    @inject()
    def __init__(self, repo: Repo):
        self.repo = repo


if __name__ == '__main__':
    # Init provider
    provider = Provider()

    # Bind `Impl` class to `Interface` class
    provider.bind(Repo, SQLRepo)

    # Inject with configure
    configure(provider=provider)

    # Or if you want to fresh injection, use `configure_after_clear`
    configure_after_clear(provider=provider)

    # Init class without arguments
    u = Usecase()

FastAPI example

from fastapi import FastAPI, APIRouter

from pythondi import Provider, configure, inject
import abc

router = APIRouter()


class Repo:
    """Interface class"""
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def get(self):
        pass


class SQLRepo(Repo):
    """Impl class"""
    def __init__(self):
        pass

    def get(self):
        print('SQLRepo')


@router.route('/')
def home():
    usecase = Usecase()
    usecase.repo.get()
    return {'hello': 'world'}


class Usecase:
    @inject()
    def __init__(self, repo: Repo):
        self.repo = repo


def create_app():
    provider = Provider()
    provider.bind(Repo, SQLRepo)
    configure(provider=provider)
    app = FastAPI()
    app.include_router(router)
    return app


if __name__ == '__main__':
    app = create_app()
    app.run(debug=True)

Flask example

from flask import Flask, Blueprint, jsonify

from pythondi import Provider, configure, inject
import abc

bp = Blueprint('home', __name__)


class Repo:
    """Interface class"""
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def get(self):
        pass


class SQLRepo(Repo):
    """Impl class"""
    def __init__(self):
        pass

    def get(self):
        print('SQLRepo')


@bp.route('/')
def home():
    usecase = Usecase()
    usecase.repo.get()
    return jsonify({'hello': 'world'})


class Usecase:
    @inject()
    def __init__(self, repo: Repo):
        self.repo = repo


def create_app():
    provider = Provider()
    provider.bind(Repo, SQLRepo)
    configure(provider=provider)
    app = Flask(__name__)
    app.register_blueprint(bp)
    return app


if __name__ == '__main__':
    app = create_app()
    app.run(debug=True)

Sanic example

import abc

from sanic import Sanic, Blueprint
from sanic.response import json

from pythondi import Provider, configure, inject


class Repo:
    """Interface class"""
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def get(self):
        pass


class SQLRepo(Repo):
    """Impl class"""
    def __init__(self):
        pass

    def get(self):
        print('SQLRepo')


bp = Blueprint('home', url_prefix='/')


@bp.route('/')
async def home(request):
    usecase = Usecase()
    usecase.repo.get()
    return json({'hello': 'world'})


class Usecase:
    @inject()
    def __init__(self, repo: Repo):
        self.repo = repo


def create_app():
    provider = Provider()
    provider.bind(Repo, SQLRepo)
    configure(provider=provider)
    app = Sanic(__name__)
    app.blueprint(bp)
    return app


if __name__ == '__main__':
    app = create_app()
    app.run(debug=True)

Django example

"""
In case of django, just put the initializing code inside of django startup

You can use project folder's __init__.py or urls.py
"""
Owner
Hide
Software Engineer
Hide
Rabbito is a mini tool to find serialized objects in input values

Rabbito-ObjectFinder Rabbito is a mini tool to find serialized objects in input values What does Rabbito do Rabbito has the main object finding Serial

7 Dec 13, 2021
Skywater 130nm Klayout Device Generators PDK

Skywaters 130nm Technology for KLayout Device Generators Mabrains is excited to share with you our Device Generator Library for Skywater 130nm PDK. It

Mabrains 18 Dec 14, 2022
A time table app to notify the user about their class timings

kivyTimeTable A time table app to notify the user about their class timings Features This project incorporates some features i wanted to see in a time

2 Dec 15, 2021
Python USD rate in RUB parser

Python EUR and USD rate parser. Python USD and EUR rate in RUB parser. Parsing i

Andrew 2 Feb 17, 2022
Writing Alfred copy/paste scripts in Python

Writing Alfred copy/paste scripts in Python This repository shows how to create Alfred scripts in Python. It assumes that you using pyenv for Python v

Will Fitzgerald 2 Oct 26, 2021
convert a dict-list object from / to a typed object(class instance with type annotation)

objtyping 带类型定义的对象转换器 由来 Python不是强类型语言,开发人员没有给数据定义类型的习惯。这样虽然灵活,但处理复杂业务逻辑的时候却不够方便——缺乏类型检查可能导致很难发现错误,在IDE里编码时也没

Song Hui 15 Dec 22, 2022
A library to easily convert climbing route grades between different grading systems.

pyclimb A library to easily convert climbing route grades between different grading systems. In rock climbing, mountaineering, and other climbing disc

Ilias Antonopoulos 4 Jan 26, 2022
A python app which aggregates and splits costs from multiple public cloud providers into a csv

Cloud Billing This project aggregates the costs public cloud resources by accounts, services and tags by importing the invoices from public cloud prov

1 Oct 04, 2022
Program to extract signatures from documents.

Extracting Signatures from Bank Checks Introduction Ahmed et al. [1] suggest a connected components-based method for segmenting signatures in document

Muhammad Saif Ullah Khan 9 Jan 26, 2022
Extends the pyranges module with operations on joined genomic intervals

tiedpyranges Extends the pyranges module with operations on joined genomic intervals (e.g. exons of same transcript) Install with: pip install tiedpyr

Marco Mariotti 4 Aug 05, 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
Data Utilities e.g. for importing files to onetask

Use this repository to easily convert your source files (csv, txt, excel, json, html) into record-oriented JSON files that can be uploaded into onetask.

onetask.ai 1 Jul 18, 2022
Simple Python tool that generates a pseudo-random password with numbers, letters, and special characters in accordance with password policy best practices.

Simple Python tool that generates a pseudo-random password with numbers, letters, and special characters in accordance with password policy best practices.

Joe Helle 7 Mar 25, 2022
API for obtaining results from the Beery-Bukenica test of the visomotor integration development (VMI) 4th edition.

VMI API API for obtaining results from the Beery-Bukenica test of the visomotor integration development (VMI) 4th edition. Install docker-compose up -

Victor Vargas Sandoval 1 Oct 26, 2021
A workflow management tool for numerical models on the NCI computing systems

Payu Payu is a climate model workflow management tool for supercomputing environments. Payu is currently only configured for use on computing clusters

The Payu Organization 11 Aug 25, 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
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 program will generate a eth key pair that has the public key that starts with a defined amount of 0

ETHAdressGenerator This short program will generate a eth key pair that has the public key that starts with a defined amount of 0 Requirements Python

3 Nov 19, 2021
About Library for extract infomation from thai personal identity card.

ThaiPersonalCardExtract Library for extract infomation from thai personal identity card. imprement from easyocr and tesseract New Feature v1.3.2 🎁 In

ggafiled 26 Nov 15, 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