Skip to main content

Dep man is a dependency manager library with dependency injection implementation and future annotations supporting for avoiding circular imports.

Project description

Web SDK

Dep man is a dependency manager library with dependency injection implementation and future annotations supporting for avoiding circular imports.

CI Coverage pypi downloads versions Web SDK alfa

Installation

Install using pip install dep-man-pydi or uv add dep-man-pydi

Features

  • Annotation like providers injection
  • Future annotation support
  • Class instances injection
  • Sync and Async function result injection
  • Nested providers for inject in classes attrs and function args
  • Classes providers inheritance
  • ContextVar based injection
  • Scopes with grouped providers
  • Export providers in other scopes
  • Interfaces and protocol based injection from different scopes
  • Sync and Async context manager like injection
  • Nested context managers usage
  • Global context for avoiding context manager usage
  • Decoration like scopes injection for functions
  • Decoration like injection for classes
  • Middlewares for django and starlette
  • Multi DI managers supporting
  • Supported custom DI managers, scopes and injectors classes

Examples

# docs/examples/home/minimal/usage.py

from typing import Awaitable

from dep_man import dm
from dep_man.types import BIND, Depend, FDepend


# declare function for providing in any file
def foo() -> str:
    return "foo_value"


# declare function with dependence on foo
def bar(foo_value: FDepend[str, foo] = BIND) -> tuple[str, str]:
    # also you can use Depend and FDepend with function or classes
    # which also hame save annotations their values will be created
    # from context or scope providers
    return "bar_value", foo_value


# declare class with dependence on foo and bar
class Foo:
    # in this case all fields with "Depend" of "FDepend" annotations
    # will be replaced with descriptor for getting value from context
    foo: FDepend[bool, foo]
    bar: FDepend[int, bar]
    # also you can use Depend and FDepend with function or classes
    # which also hame save annotations their values will be created
    # from context or scope providers

    # inheritance providers is also supported


# I recommend creating a new scope in the "dependencies.py" file
# in the roots of your modules or applications,
# and adding providers there as well
scope = dm.add_scope("scope")
# provide functions and classes
scope.provide(foo)
scope.provide(bar)
scope.provide(Foo)

"""
next you need specify modules for loading

if you have next structure
--
├── app
└   ├── bar
    │   ├── ...
    │   ├── dependencies.py
    │   ├── __init__.py
    └── foo
        ├── ...
        ├── dependencies.py
        ├── __init__.py

you need make next load call
dm.load(
    "core.bar",
    "core.foo",
)

you can also specify file_name via load arg file_name
"""

# for django you need call this in ready method of you AppConfig
dm.load()

# this method you need call for every request in middleware
dm.init()


# use injector on class object
@dm.inject
class Injectable:
    # in this case all fields with "Depend" of "FDepend" annotations
    # will be replaced with descriptor for getting value from context
    foo: Depend[Foo]


# usage example via context manager
with dm.inject("scope"):
    # create instance of inject decorated class
    instance = Injectable()

    # Foo instance was created ones and set to instance.__dict__
    instance.foo
    # <__main__.Foo object at ...>

    # foo call ones for getting result and set to instance.__dict__
    instance.foo.foo
    # foo_value

    # bar call ones for getting result and set to instance.__dict__
    # inside the bar call foo was called once.
    instance.foo.bar
    # ('bar_value', 'foo_value')

    # if you use context of run dm.init(globalize=True)
    # you can create instance or call functions for any provider
    foo_instance = Foo()
    foo_instance.foo
    # foo_value
    foo_instance.bar
    # ('bar_value', 'foo_value')

# you can also use nested context managers
with dm.inject("scope1"):
    with dm.inject("scope2"):
        with dm.inject("scope3"):
            pass


# via function decoration
# here you can specify scope or inject all if not specify
@dm.inject("scope")
def injectable(arg: Depend[Foo] = BIND):
    # in this case injectable __code__ will be replaced passing
    # providers via signature.parameters defaults values from context
    return arg.foo, arg.bar


# function call will be run with dm.inject("scope") context
injectable()


# ('foo_value', ('bar_value', 'foo_value'))


# async support
@dm.inject
class Foo:
    async_arg: FDepend[Awaitable[bool], async_func]


async with dm.inject("scope1"):
    async with dm.inject("scope2"):
        await Foo().async_arg


@dm.inject("scope")
async def async_injectable(arg: FDepend[Awaitable[bool], async_func]):
    return await arg

Changelog

v0.1.0

  • Add core logic
  • Add tests
  • Add minimal docs

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dep_man_pydi-0.1.2.tar.gz (32.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dep_man_pydi-0.1.2-py3-none-any.whl (28.6 kB view details)

Uploaded Python 3

File details

Details for the file dep_man_pydi-0.1.2.tar.gz.

File metadata

  • Download URL: dep_man_pydi-0.1.2.tar.gz
  • Upload date:
  • Size: 32.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for dep_man_pydi-0.1.2.tar.gz
Algorithm Hash digest
SHA256 94d9df9b5c188e34c66cfa4c4112fbf97e82ff874abaeea9def41ab4a0d1cfb8
MD5 2a90691f5f6f369a4cbf3d2e126251e3
BLAKE2b-256 a859ef3a66ce3202536a642debd69f114c40c5c5d60237ec7bb92e1a595e3c6d

See more details on using hashes here.

Provenance

The following attestation bundles were made for dep_man_pydi-0.1.2.tar.gz:

Publisher: ci.yml on extralait-web/dep-man

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dep_man_pydi-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: dep_man_pydi-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 28.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for dep_man_pydi-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 21bb3a6792dfb115f7bd3126967c877052ee26c7e42c48ec2bb7cabd6eca39d0
MD5 38efddeefa7086e03f2935cb12344090
BLAKE2b-256 e7187178a53d9f425e7c0813da91813a6d9b87920c716866f1044f9da7484bd4

See more details on using hashes here.

Provenance

The following attestation bundles were made for dep_man_pydi-0.1.2-py3-none-any.whl:

Publisher: ci.yml on extralait-web/dep-man

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page