📦 Autowiring dependency injection container for python 3

Overview

Lagom - Dependency injection container

Scrutinizer Code Quality Code Coverage PyPI Downloads

What

Lagom is a dependency injection container designed to give you "just enough" help with building your dependencies. The intention is that almost all of your code doesn't know about or rely on lagom. Lagom will only be involved at the top level to pull everything together.

Features

  • Typed based auto wiring with zero configuration.
  • Fully based on types. Strong integration with mypy.
  • Minimal changes to existing code.
  • Integration with a few common web frameworks.
  • Support for async python.
  • Thread-safe at runtime

You can see a comparison to other frameworks here

Installation

pip install lagom
# or: 
# pipenv install lagom
# poetry add lagom

Note: if you decide to clone from source then make sure you use the latest version tag. The master branch may contain features that will be removed.

Usage

Everything in Lagom is based on types. To create an object you pass the type to the container:

container = Container()
some_thing = container[SomeClass]

Auto-wiring (with zero configuration)

Most of the time Lagom doesn't need to be told how to build your classes. If the __init__ method has type hints then lagom will use these to inject the correct dependencies. The following will work without any special configuration:

class MyDataSource:
    pass
    
class SomeClass:
   def __init__(datasource: MyDataSource)
      pass

container = Container()
some_thing = container[SomeClass] # An instance of SomeClass will be built with an instance of MyDataSource provided

and later if you extend your class no changes are needed to lagom:

class SomeClass:
   def __init__(datasource: MyDataSource, service: SomeFeatureProvider)
      pass

# Note the following code is unchaged
container = Container()
some_thing = container[SomeClass] # An instance of SomeClass will be built with an instance of MyDataSource provided

Singletons

You can tell the container that something should be a singleton:

container[SomeExpensiveToCreateClass] = SomeExpensiveToCreateClass("up", "left")

Explicit build instructions when required

You can explicitly tell the container how to construct something by giving it a function:

container[SomeClass] = lambda: SomeClass("down", "spiral")

All of this is done without modifying any of your classes. This is one of the design goals of lagom.

Hooks in to existing systems

A decorator is provided to hook top level functions into the container.

@bind_to_container(container)
def handle_move_post_request(request: typing.Dict, game: Game = lagom.injectable):
    # do something to the game
    return Response()

(There's also a few common framework integrations provided here)

Full docs here here

Contributing

Contributions are very welcome. Please see instructions here

Comments
  • Injecting instances with a __call__ method on the class

    Injecting instances with a __call__ method on the class

    One of the use case is to Inject an instance of HttpBearer in FastAPI routes

    since the instance will have a different type than the class definition itself, this doesn't inject the instance as a dependency. Is there a workaround? Thanks

    opened by bejoygm 10
  • Support Classes with partial/magic_partial

    Support Classes with partial/magic_partial

    Resolves #129

    These changes allow calling Container.partial and Container.magic_partial with a class Callable. It also supports using the bind_to_container and magic_bind_to_container decorators on classes.

    Tests added for relevant methods in:

    • test_partial_classes.py
    • tests_magic_partial_classes.py

    Let me know if anything looks strange or if you feel the test coverage is not adequate.

    opened by BrentSouza 8
  • Consider creating a

    Consider creating a "compiled" container

    Since the container implements a dictionary interface it should be possible to analyse the code and generate a dictionary that can be dropped in place of the container. This would avoid any reflection happening at runtime.

    enhancement perfomance 
    opened by meadsteve 8
  • @dependency_definition doesn't work for generator functions with a Container parameter

    @dependency_definition doesn't work for generator functions with a Container parameter

    One more issue to throw your way @meadsteve 😅

    It seems @dependency_definition doesn't work for generator functions with the c: Container parameter, e.g.:

    @dependency_definition(container)
    def _session_dependency(container: Container) -> Generator[Session, None, None]:
        read_only: bool = container[Request].scope["db_access"] == "READ_ONLY"
        with get_db_session(read_only) as session:
            yield session
    

    This gives the following error:

    ImportError while loading conftest '/home/rbarrie/code/gdb/tests/unit/api/conftest.py'.
    tests/unit/api/conftest.py:10: in <module>
        from gdb.entrypoints.bootstrap import deps
    gdb/entrypoints/bootstrap.py:133: in <module>
        def _session_dependency(container: Container) -> Session:
    ../../.cache/pypoetry/virtualenvs/gdb-wpT7sdDb-py3.8/lib/python3.8/site-packages/lagom/decorators.py:69: in _decorator
        definition_func, return_type = _extract_definition_func_and_type(func)  # type: ignore
    ../../.cache/pypoetry/virtualenvs/gdb-wpT7sdDb-py3.8/lib/python3.8/site-packages/lagom/decorators.py:102: in _extract_definition_func_and_type
        return value_from_gen, return_type.__args__[0]  # todo: something less hacky
    E   AttributeError: type object 'Session' has no attribute '__args__'
    

    For comparison a simple generator function without the c: Container parameter works fine:

    @dependency_definition(container)
    def _session_dependency() -> Generator[Session, None, None]:
        with get_db_session(False) as session:
            yield session
    

    I'm not sure if this is by design or not?

    I may be being too ambitious here but I want to have each of my FastAPI endpoints determine (via a custom APIRoute + Request.scope attribute) which DB transaction / connection is used (read/write vs read-only). I suppose I could achieve this with two independent Lagom containers, but then I would have two of every dependency initialised...

    bug question 
    opened by rowanbarrie 5
  • Support FastAPI dependency overrides

    Support FastAPI dependency overrides

    Hi Steve,

    Love the framework so far. One issue I'm having is in trying to use FastAPI dependency overrides in a similar manner to vanilla FastAPI, when making web-layer unit tests. I.e. mocking out dependencies.

    In vanilla FastAPI you would do something like this (with pytest):

    ...
    from fastapi.testclient import TestClient
    from dependencies import get_foo_service  # <-- Dependency function
    from foo import FooService
    ...
    
    @pytest.fixture
    def foo_service_mock():
        return Mock(FooService)
    
    @pytest.fixture
    def client(foo_service_mock) -> Generator:
        app.dependency_overrides[get_foo_service] = lambda: foo_service_mock
    
        with TestClient(app) as c:
            yield c
    

    But I can't see how I could replicate the override (app.dependency_overrides[get_foo_service]) functionality when using the Lagom FastAPI DI approach (i.e. when using deps.depends(FooService)).

    I suppose I would somehow need to reference the inner _resolver function of depends...surely this isn't possible?

    Thus it would be nice if there were explicit support for FastAPI dependency overrides.

    Thanks!

    enhancement Integrations 
    opened by rowanbarrie 5
  • handle injecting into starlette HTTPEndpoints + tests

    handle injecting into starlette HTTPEndpoints + tests

    Closes #166

    Hey Steve! I was playing around with lagom and starlette and noticed there was a recent issue about this.

    This PR handles starlette's class-based views hopefully in a reasonably idiomatic way. The basic approach is to wrap the endpoint in a proxy class which ignores existing attributes from HTTPEndpoint but otherwise use lagom's DI to wrap what's assumed to be a handler function.

    Now that I look at it in a diff, potentially a more robust approach would be to wrap only attributes named after HTTP methods and otherwise not interfere, since (in theory, not sure why you would since you have no control over the way __init__ gets called) there could be custom non-route properties on a subclass of HTTPEndpoint.

    Happy to discuss / make changes either way!

    opened by marginalhours 5
  • Injection into instance methods

    Injection into instance methods

    Hi!

    Strangely I'm unable to make DI work with async / await coroutines as instance methods. Codes:

    import asyncio
    from lagom import Container, injectable
    class Foo: pass
    class Bar: pass
    class CoroutineHolder:
        async def coroutine(self, foo: Foo = injectable, bar: Bar = injectable):
            print(foo)
            print(bar)
    container = Container()
    holder = CoroutineHolder()
    coroutine_with_deps = container.partial(holder.coroutine)
    asyncio.run(coroutine_with_deps())
    # prints the following:
    # <lagom.markers.Injectable object at 0x0000026A36369FD0>
    # <lagom.markers.Injectable object at 0x0000026A36369FD0>
    

    I inspected into the code a little (I'm not a great python programmer) and it seems Container._get_spec_without_self(self, func: Callable[..., X]) errs when the func argument is a Coroutine:

    if isinstance(func, FunctionType):
        spec = self._reflector.get_function_spec(func)
    else:
        t = cast(Type[X], func)
        spec = self._reflector.get_function_spec(t.__init__).without_argument(
            "self"
        )
    return spec
    

    Coroutines are CoroutineType unrelated to FunctionType, so this function makes a call to __init__, perhaps that is why, or I'm doing something wrong 😄

    bug 
    opened by LeafyLappa 4
  • Aliasing a concrete type causes a RecursionError for identity map

    Aliasing a concrete type causes a RecursionError for identity map

    It appears that the change to how the Alias.skip_definitions flag is used in #150 introduced a regression. If an alias maps a type to itself, any resolution to the alias will raise a RecursionError.

    Python 3.9.4 (tags/v3.9.4:1f2e308, Apr  6 2021, 13:40:21) [MSC v.1928 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import abc
    >>> import sys
    >>> import lagom
    >>> sys.tracebacklimit = 5
    >>>
    >>> class AbstractFoo(abc.ABC):
    ...   pass
    ...
    >>> class Foo(AbstractFoo):
    ...   pass
    ...
    >>> container = lagom.Container()
    >>>
    >>> container[AbstractFoo] = Foo
    >>> container[AbstractFoo]
    <__main__.Foo object at 0x000001BF1CA4D700>
    >>> container[Foo]
    <__main__.Foo object at 0x000001BF1CA4D790>
    >>>
    >>> container[Foo] = Foo
    >>> container[AbstractFoo]
    Traceback (most recent call last):
      File "X:\lagom\.venv\lib\site-packages\lagom\definitions.py", line 68, in get_instance
        return container.resolve(
      File "X:\lagom\.venv\lib\site-packages\lagom\container.py", line 237, in resolve
        return definition.get_instance(self)
      File "X:\lagom\.venv\lib\site-packages\lagom\definitions.py", line 68, in get_instance
        return container.resolve(
      File "X:\lagom\.venv\lib\site-packages\lagom\container.py", line 235, in resolve
        definition = self.get_definition(dep_type)
      File "X:\lagom\.venv\lib\site-packages\lagom\container.py", line 352, in get_definition
        definition = self._registered_types.get(dep_type, Unset)
    RecursionError: maximum recursion depth exceeded while calling a Python object
    >>> container[Foo]
    Traceback (most recent call last):
      File "X:\lagom\.venv\lib\site-packages\lagom\definitions.py", line 68, in get_instance
        return container.resolve(
      File "X:\lagom\.venv\lib\site-packages\lagom\container.py", line 237, in resolve
        return definition.get_instance(self)
      File "X:\lagom\.venv\lib\site-packages\lagom\definitions.py", line 68, in get_instance
        return container.resolve(
      File "X:\lagom\.venv\lib\site-packages\lagom\container.py", line 235, in resolve
        definition = self.get_definition(dep_type)
      File "X:\lagom\.venv\lib\site-packages\lagom\container.py", line 352, in get_definition
        definition = self._registered_types.get(dep_type, Unset)
    RecursionError: maximum recursion depth exceeded while calling a Python object
    >>>
    
    

    This is Python 3.9.4 and Lagom 1.3.0.

    Ultimately, this isn't a huge issue. But it seems that a guard condition is merited so the identity map can be allowed.

    bug 
    opened by mrogaski 4
  • magic_partial fails for a class

    magic_partial fails for a class

    Not sure if intentional, but I had a need for using Container.magic_partial on a class type as opposed to a function. This throws an error because it's not able to resolve any of the dependencies.

    Taking a look at the pathway for Container.resolve, I noticed that it reflects on __init__ whereas magic_partial reflects directly on the callable:

    https://github.com/meadsteve/lagom/blob/70127078149c2d209fef8ec229937acb9fa3f03f/lagom/container.py#L384

    vs

    https://github.com/meadsteve/lagom/blob/70127078149c2d209fef8ec229937acb9fa3f03f/lagom/container.py#L319

    I was able to patch this by checking if func is a function or not:

    if isinstance(func, types.FunctionType):
        spec = self._reflector.get_function_spec(func)
    else:
        spec = self._reflector.get_function_spec(func.__init__)
    

    Which works successfully with something like:

    class Foo:
        def greet(self) -> str:
            return "Hello Foo"
    
    class Bar:
        def __init__(self, not_injected: str, foo: foo) -> None:
            self.not_injected = not_injected
            self.foo = foo
    
        def greet(self) -> str:
            return self.foo.greet() + self.not_injected
    
    container = Container()
    container[Foo] = Foo()
    bar = c.magic_partial(Bar)(not_injected="!")
    bar.greet()
    

    I can open a pull request with the fix above, just wanted to check if this was a design decision first.

    Also, thanks for your work on the library!

    enhancement 
    opened by BrentSouza 3
  • Add request scoped context manager based resources for the fastapi integration

    Add request scoped context manager based resources for the fastapi integration

    Similar to: https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/

    See conversation on this issue: https://github.com/meadsteve/lagom/issues/179#issuecomment-979763975

    Stretch goal: make this generic enough to use for all lagom usages.

    enhancement 
    opened by meadsteve 2
  • Decide whether django should have explicit or magic binding to views.

    Decide whether django should have explicit or magic binding to views.

    Magic (the current implementation):

    from .dependency_config import container
    
    
    @container.bind_view
    def index(request, dep: SomeService):
        return HttpResponse(f"service says: {dep.get_message()}")
    
    # Or if you prefer class based views
    
    @container.bind_view
    class CBVexample(View):
        def get(self, request, dep: SomeService):
            return HttpResponse(f"service says: {dep.get_message()}")
    

    vs. explicit:

    from lagom import injectable
    from .dependency_config import container
    
    
    @container.bind_view
    def index(request, dep: SomeService=injectable):
        return HttpResponse(f"service says: {dep.get_message()}")
    
    # Or if you prefer class based views
    
    @container.bind_view
    class CBVexample(View):
        def get(self, request, dep: SomeService=injectable):
            return HttpResponse(f"service says: {dep.get_message()}")
    
    opened by meadsteve 2
  • Request level singletons can not resolve fastapi/starlette Request class

    Request level singletons can not resolve fastapi/starlette Request class

    When resolving request level singletons, Request class from starlette can not be resolved

    As an example, editing the tests located at tests/integrations/fastapi_app/__init__.py as;

     from contextlib import contextmanager
     from typing import Iterator
     
    -from fastapi import FastAPI
    +from fastapi import FastAPI, Request
     
     from lagom import Container, dependency_definition
     from lagom.integrations.fast_api import FastApiIntegration
     
     
     class Inner:
    -    def __init__(self, msg=None):
    +    def __init__(self, request: Request, msg=None):
             self.msg = msg
    +        self.request = request
     
    

    The resolution gives the following error;

    lagom.exceptions.UnresolvableType: Unable to construct dependency of type Inner The constructor probably has some unre
    solvable dependencies
    

    I will try to make a PR when i have time. But not promise :D

    opened by alkimake 0
  • Document dependency lifetimes

    Document dependency lifetimes

    There are broadly three lifetimes:

    • Singleton - exists for the life of the container once created.
    • Invocation level shared - constructed once during a single function call (wrapped by a lagom decorator).
    • Regular - Constructed new every time they are needed.

    Special case for a lot of the framework integrations:

    • Request level - This is equivalent to the invocation level shared resources above but specifically for the lifetime of a request.
    documentation 
    opened by meadsteve 0
  • WIP integration with strawberry

    WIP integration with strawberry

    The TLDR goal of this work is to be able to build @strawberry data loaders like this:

    class AuthorLoader(DataLoader[str, Author]):
        def __init__(self, some_dep_db: DB):
            super().__init__(self.get_authors)
            self.db = some_dep_db
    
        async def get_authors(self, ids) -> typing.List["Author"]:
            print(f"Bulk loading authors: {ids}")
            return await self.db.get_the_authors(ids)
    
    

    and then use it like

    container = StrawberryContainer()
    container[AuthorLoader] = AuthorLoader
    
    @strawberry.type
    class Book:
        title: str
        author_id: int
    
        @strawberry.field
        @container.attach_field
        async def author(self, loader: "AuthorLoader") -> "Author":
            return await loader.load(self.author_id)
    
    class MyGraphQL(GraphQL):
        async def get_context(self, *args, **kwargs) -> Any:
            context: Dict = {}
            container.hook_into_context(context)
            return context
    
    opened by meadsteve 1
  • Document container layering

    Document container layering

    Lagom allows (and should encourage) containers to be stacked on top of each other. This is especially useful when you have different contexts like a web app and a worker on some job queue that share some dependency construction logic but not all.

    documentation 
    opened by meadsteve 0
Releases(2.0.0)
  • 2.0.0(Sep 26, 2022)

    2.0.0 (2022-09-26)

    Enhancements

    • Add helper exception if an async type is requested without being wrapped in Awaitable.
    • Use mypyc to compile some parts of lagom for a speed boost. This is only available on some platforms. A non-compiled fallback is also built.

    Bug Fixes

    None

    Backwards incompatible changes

    • 3.6 is now no longer formally supported (though it may still work)
    • The compiled classes are less tolerant of slightly incorrectly typed arguments

    Benchmarking for compilation

    Running the benchmarking on a Darwin-CPython-3.8-64bit.

    001 is version 1.7.1 of lagom pre compilation. 002 is the newly compiled version.

    ---------------------------------------------------------------------------------------------- benchmark: 6 tests ----------------------------------------------------------------------------------------------
    Name (time in us)                      Min                    Max                Mean              StdDev              Median                IQR            Outliers  OPS (Kops/s)            Rounds  Iterations
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    test_optimised (0002_baselin)      71.7450 (1.0)         971.7620 (1.65)      87.0807 (1.0)       20.9528 (1.0)       81.8410 (1.0)       5.2518 (1.0)     6107;9432       11.4836 (1.0)       87699           1
    test_plain (0002_baselin)         128.2760 (1.79)        588.2040 (1.0)      154.0175 (1.77)      32.0413 (1.53)     144.8510 (1.77)      9.5982 (1.83)    1084;1869        6.4928 (0.57)      14475           1
    test_magic (0002_baselin)         147.2380 (2.05)        598.4200 (1.02)     169.9302 (1.95)      36.6631 (1.75)     159.4025 (1.95)      8.2840 (1.58)      227;405        5.8848 (0.51)       2962           1
    test_optimised (0001_baselin)     159.1330 (2.22)     19,492.6290 (33.14)    218.7509 (2.51)     238.4710 (11.38)    185.7110 (2.27)     40.6575 (7.74)     542;4813        4.5714 (0.40)      43520           1
    test_plain (0001_baselin)         250.3910 (3.49)        780.7970 (1.33)     289.7597 (3.33)      52.2043 (2.49)     272.0675 (3.32)     18.1820 (3.46)     839;1469        3.4511 (0.30)       9416           1
    test_magic (0001_baselin)         271.6470 (3.79)      1,122.6480 (1.91)     314.4931 (3.61)      65.8549 (3.14)     291.0765 (3.56)     24.0800 (4.59)      230;353        3.1797 (0.28)       2718           1
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    

    Upgrade instructions

    Python 3.6 is no longer supported so this upgrade will not be possible. This release of the code may still work but this version and future releases will not be tested against 3.6.

    For python 3.7 and above the core parts of the library are now compiled and published to pypi. The interface for this new release is intended to be compatible with the 1.7.X version, but you should test before deploying to production and report any bugs. The compiled version (and therefore performance improvements) is only available for CPython, other python runtimes are supported through a pure python wheel.

    Source code(tar.gz)
    Source code(zip)
  • 1.7.1(May 25, 2022)

    1.7.1 (2022-05-25)

    Enhancements

    None

    Bug Fixes

    • Fairly serious bug which affected fastapi integrations with more than 1 request level singleton. The bug caused the definitions of the singletons to all point to the last defined singleton. Fixed in #197 thanks to Dag for reporting and helping with replication.

    Backwards incompatible changes

    None

    Source code(tar.gz)
    Source code(zip)
  • 1.7.0(Nov 30, 2021)

    1.7.0 (2021-11-30)

    Enhancements

    • Request lifetime instances with cleanup (using ContextManagers) for the FastApi integration.

    Bug Fixes

    • Fixed bug which meant generator dependencies could not accept the container as an argument

    Backwards incompatible changes

    None

    Source code(tar.gz)
    Source code(zip)
  • 1.6.0(Nov 25, 2021)

    1.6.0 (2021-11-25)

    Enhancements

    • Starlette integration now has support for web sockets. #173. Thanks again @MisterKeefe
    • FastApi integration provides method to support altering dependency chains during test.

    Bug Fixes

    None

    Backwards incompatible changes

    None

    Source code(tar.gz)
    Source code(zip)
  • 1.5.0(Nov 13, 2021)

    1.5.0 (2021-11-13)

    Enhancements

    • Better error messages when failing to load environment variables.
    • Starlette integration now supports class based endpoints #170 thanks @MisterKeefe

    Bug Fixes

    None

    Backwards incompatible changes

    None

    New Contributors

    • @MisterKeefe made their first contribution in https://github.com/meadsteve/lagom/pull/170

    Full Changelog: https://github.com/meadsteve/lagom/compare/1.4.1...1.5.0

    Source code(tar.gz)
    Source code(zip)
  • 1.4.0(Aug 16, 2021)

    1.4.0 (2021-08-16)

    Enhancements

    • container.partial now works for instance methods. Thanks to @LeafyLappa for pointing out this didn't work.
    • Added FunctionCollection type. Allows the container to store a collection of functions

    Bug Fixes

    • container.partial now works for instance methods. Thanks to @LeafyLappa for pointing out this didn't work.

    Backwards incompatible changes

    None

    Source code(tar.gz)
    Source code(zip)
  • 1.3.1(May 28, 2021)

    1.3.1 (2021-05-27)

    Enhancements

    None

    Bug Fixes

    • Fixed bug in flask integration where multiple route decorators caused an error
    • Fixed bug with self aliases causing infinite recursion. Thanks to @mrogaski for the report. #159.

    Backwards incompatible changes

    None

    Source code(tar.gz)
    Source code(zip)
  • 1.2.1(Mar 21, 2021)

    1.2.1 (2021-03-21)

    Enhancements

    None

    Bug Fixes

    • Fixed a bug that could cause an aliased class to skip a defined way of constructing the class.
    • Custom caching reflection logic replaced with lru cache. This prevents an in theory bug when the cache could fill up memory if a lot of temporary functions got reflected upon.

    Backwards incompatible changes

    None

    Source code(tar.gz)
    Source code(zip)
  • 1.2.0(Mar 17, 2021)

    1.2.0 (2021-03-17)

    Enhancements

    • FastAPI integration now provides request level singletons.
    • [EXPERIMENTAL] Integration to click CLI package added

    Bug Fixes

    None

    Backwards incompatible changes

    • Internal detail: The type hints for FunctionSpec from the caching reflector are now all non-mutable. The implementation is not changed but the immutable hints should prevent state based bugs.
    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Feb 24, 2021)

    1.1.0 (2021-02-24)

    Enhancements

    • Classes can now be passed to container.partial and container.magic_partial. Thanks to @BrentSouza via PR #132.
    • Decorators now preserve function docs.
    • Decorators now communicate that the return type of the decorated function is preserved.

    Bug fixes

    • Stop unnecessary function call to parent definitions.

    Backwards incompatible changes

    None

    Source code(tar.gz)
    Source code(zip)
  • 1.0.0-beta.4(Dec 4, 2020)

  • 1.0.0-beta.3(Nov 28, 2020)

  • 1.0.0-beta.2(Nov 28, 2020)

  • 1.0.0-beta.1(Nov 27, 2020)

  • v0.19.0(Nov 16, 2020)

  • v0.18.1(Nov 3, 2020)

    0.18.1 (2020-10-23)

    Enhancements

    • Better interface for build version info.

    Bug fixes

    • fix but in retrieving the git hash from the package.

    0.18.0 (2020-10-23)

    Enhancements

    • (internal detail) when a plain object is provided to the container as a definition it is no longer wrapped as a Singleton, but stored instead as PlainInstance. This allows the container to skip any thread locks added in the singleton logic.
    • add publishing logic to ship git commit hash with package.

    Bug fixes

    None

    Backwards incompatible changes

    None

    Source code(tar.gz)
    Source code(zip)
  • v0.17.0(Oct 20, 2020)

    0.17.0 (2020-10-20)

    Enhancements

    • Magic partial and regular partial binding for framework integrations
    • Thread locks for mutable state in the caching reflector and the singletons.

    Bug fixes

    None

    Backwards incompatible changes

    • All framework binding methods are now non magic by default
    Source code(tar.gz)
    Source code(zip)
  • v0.14.0(Jun 24, 2020)

Owner
Steve B
:unicorn: :rainbow:
Steve B
python fastapi example connection to mysql

Quickstart Then run the following commands to bootstrap your environment with poetry: git clone https://github.com/xiaozl/fastapi-realworld-example-ap

null 55 Dec 15, 2022
更新 2.0 版本,使用 Python WEB 高性能异步框架 FastAPI 制作的抖音无水印解析下载,采用前后端分离思想!

前言 这个是 2.0 版本,使用现在流行的前后端分离思想重构。 体验网址:https://douyin.bigdataboy.cn 更新日志 2020.05.30:使用 FastAPI 前后端分离重构 2020.05.02:已更新,正常使用 2020.04.27:抖音结构更新,已修复视频有水印。(失

null 64 Nov 25, 2022
Monitor Python applications using Spring Boot Admin

Pyctuator Monitor Python web apps using Spring Boot Admin. Pyctuator supports Flask, FastAPI, aiohttp and Tornado. Django support is planned as well.

SolarEdge Technologies 145 Dec 28, 2022
TODO aplication made with Python's FastAPI framework and Hexagonal Architecture

FastAPI Todolist Description Todolist aplication made with Python's FastAPI framework and Hexagonal Architecture. This is a test repository for the pu

Giovanni Armane 91 Dec 31, 2022
python template private service

Template for private python service This is a cookiecutter template for an internal REST API service, written in Python, inspired by layout-golang. Th

UrvanovCompany 15 Oct 2, 2022
A Python pickling decompiler and static analyzer

Fickling Fickling is a decompiler, static analyzer, and bytecode rewriter for Python pickle object serializations. Pickled Python objects are in fact

Trail of Bits 162 Dec 13, 2022
A Container for the Dependency Injection in Python.

Python Dependency Injection library aiodi is a Container for the Dependency Injection in Python. Installation Use the package manager pip to install a

Denis NA 3 Nov 25, 2022
Dependency Injector is a dependency injection framework for Python.

What is Dependency Injector? Dependency Injector is a dependency injection framework for Python. It helps implementing the dependency injection princi

ETS Labs 2.6k Jan 4, 2023
Aiminsun 165 Dec 21, 2022
Caretaker 2 Jun 6, 2022
Simple dependency injection framework for Python

A simple, strictly typed dependency injection library.

BentoML 14 Jun 29, 2022
Dependency injection lib for Python 3.8+

PyDI Dependency injection lib for python How to use To define the classes that should be injected and stored as bean use decorator @component @compone

Nikita Antropov 2 Nov 9, 2021
Python lightweight dependency injection library

pythondi pythondi is a lightweight dependency injection library for python Support both sync and async functions Installation pip3 install pythondi Us

Hide 41 Dec 16, 2022
Async-first dependency injection library based on python type hints

Dependency Depression Async-first dependency injection library based on python type hints Quickstart First let's create a class we would be injecting:

Doctor 8 Oct 10, 2022
Dependency injection in python with autoconfiguration

The base is a DynamicContainer to autoconfigure services using the decorators @services for regular services and @command_handler for using command pattern.

Sergio Gómez 2 Jan 17, 2022
A type based dependency injection framework for Python 3.9+

Alluka A type based dependency injection framework for Python 3.9+. Installation You can install Alluka from PyPI using the following command in any P

Lucina 16 Dec 15, 2022
Reusable Lightweight Pythonic Dependency Injection Library

Vacuna Inject everything! Vacuna is a little library to provide dependency management for your python code. Install pip install vacuna Usage import va

Fernando Martínez González 16 Sep 15, 2021
Run async workflows using pytest-fixtures-style dependency injection

Run async workflows using pytest-fixtures-style dependency injection

Simon Willison 26 Jun 26, 2022
fastapi-admin2 is an upgraded fastapi-admin, that supports ORM dialects, true Dependency Injection and extendability

FastAPI2 Admin Introduction fastapi-admin2 is an upgraded fastapi-admin, that supports ORM dialects, true Dependency Injection and extendability. Now

Glib 14 Dec 5, 2022
Dependency Combobulator is an Open-Source, modular and extensible framework to detect and prevent dependency confusion leakage and potential attacks.

Dependency Combobulator Dependency Combobulator is an Open-Source, modular and extensible framework to detect and prevent dependency confusion leakage

Apiiro 84 Dec 23, 2022