Skip to content

alluka#

A type based dependency injection framework for Python 3.9+.

Injected module-attribute #

Injected = typing.Annotated[_T, InjectedTypes.TYPE]

Type alias used to declare a keyword argument as requiring an injected type.

If a union (e.g. typing.Union[A, B], A | B, typing.Optional[A]) is passed then each type in the union will be tried separately rather than the literal type, allowing for resolving A | B to the value set by set_type_dependency(B, ...).

If a union has None as one of its types (including Optional[T]) then None will be passed for the parameter if none of the types could be resolved using the linked client.

Note

This is a typing.Annotated alias and the behaviour for nested Annotated types may be found at the docs for it typing.Annotated.

AllukaError #

Bases: Exception

Base class for the custom errors raised by Alluka.

AsyncSelfInjecting #

Bases: alluka.AsyncSelfInjecting[_CallbackSigT]

Class used to link a sync function to a client to make it self-injecting.

Examples:

async def callback(database: Database = alluka.inject(type=Database)) -> None:
    await database.do_something()
...

client = alluka.Client()
injecting_callback = alluka.AsyncSelfInjecting(callback, client)
await injecting_callback()

Alternatively alluka.abc.Client.as_async_self_injecting may be used:

client = alluka.Client()

@client.as_async_self_injecting
async def callback(database: Database = alluka.inject(type=Database)) -> None:
    ...

__init__ #

__init__(client, callback)

Initialise a self injecting callback.

PARAMETER DESCRIPTION
client

The injection client to use to resolve dependencies.

TYPE: alluka.Client

callback

The callback to make self-injecting.

This may be sync or async.

TYPE: alluka.abc.CallbackSig

RAISES DESCRIPTION
ValueError

If callback has any injected arguments which can only be passed positionally.

BasicContext #

Bases: alluka.Context

Basic implementation of alluka.abc.Context.

__init__ #

__init__(client)

Initialise a basic injection context.

PARAMETER DESCRIPTION
client

The injection client this context is bound to.

TYPE: alluka.Client

Client #

Bases: alluka.Client

Standard implementation of a dependency injection client.

This is used to track type dependencies and execute callbacks.

__init__ #

__init__(*, introspect_annotations=True)

Initialise an injector client.

InjectedDescriptor #

Bases: typing.Generic[_T]

Descriptor used to a declare keyword-argument as requiring an injected dependency.

This is the type returned by alluka.inject.

__init__ #

__init__(*, callback=None, type=None)

Initialise an injection default descriptor.

Note

If neither type or callback is provided, an injected type will be inferred from the argument's annotation.

PARAMETER DESCRIPTION
callback

The callback to use to resolve the dependency.

If this callback has no type dependencies then this will still work without an injection context but this can be overridden using alluka.abc.Client.set_callback_override.

TYPE: typing.Optional[alluka.CallbackSig[_T]] DEFAULT: None

type

The type of the dependency to resolve.

If a union (e.g. typing.Union[A, B], A | B, typing.Optional[A]) is passed for type then each type in the union will be tried separately after the litarl union type is tried, allowing for resolving A | B to the value set by set_type_dependency(B, ...).

If a union has None as one of its types (including Optional[T]) then None will be passed for the parameter if none of the types could be resolved using the linked client.

TYPE: typing.Optional[_TypeT[_T]] DEFAULT: None

RAISES DESCRIPTION
ValueError

If both callback and type are provided.

MissingDependencyError #

Bases: AllukaError

Error raised when a dependency couldn't be found.

__init__ #

__init__(message, dependency_type)

Initialise a missing dependency error.

PARAMETER DESCRIPTION
message

The error message.

TYPE: str

SelfInjecting #

Bases: alluka.SelfInjecting[_SyncCallbackT]

Class used to link a sync function to a client to make it self-injecting.

Note

This executes the callback synchronously and therefore will error if any of the callback's dependencies are async.

Examples:

async def callback(database: Database = alluka.inject(type=Database)) -> None:
    await database.do_something()
...

client = alluka.Client()
injecting_callback = alluka.SelfInjecting(callback, client)
await injecting_callback()

Alternatively alluka.abc.Client.as_self_injecting may be used:

client = alluka.Client()

@client.as_self_injecting
async def callback(database: Database = alluka.inject(type=Database)) -> None:
    ...

__init__ #

__init__(client, callback)

Initialise a sync self injecting callback.

PARAMETER DESCRIPTION
client

The injection client to use to resolve dependencies.

TYPE: alluka.Client

callback

The callback to make self-injecting.

TYPE: collections.abc.Callable

RAISES DESCRIPTION
ValueError

If callback has any injected arguments which can only be passed positionally.

SyncOnlyError #

Bases: AllukaError

Error raised when trying to execute async DI in a sync context.

inject #

inject(*, callback=None, type=None)

Decare a keyword-argument as requiring an injected dependency.

This may be assigned to an arugment's default value to declare injection or as a part of its Annotated metadata.

Note

If neither type nor callback is provided, an injected type will be inferred from the argument's annotation.

Examples:

async def callback(
    # Here we require an implementation of the type `Component` to be
    # injected.
    injected_type: Component = alluka.inject(type=Component)
    # Here we inject an out-of-scope callback which itself is taking
    # advantage of type injectioallukan.
    callback_result: ResultT = alluka.inject(callback=injected_callback)
) -> None:
    raise NotImplementedError

...
# where client is an `alluka.Client` instance.
result = await client.call_with_async_di(callback)
PARAMETER DESCRIPTION
callback

The callback to use to resolve the dependency.

If this callback has no type dependencies then this will still work without an injection context but this can be overridden using alluka.abc.Client.set_callback_override.

TYPE: typing.Optional[alluka.CallbackSig[_T]] DEFAULT: None

type

The type of the dependency to resolve.

If a union (e.g. typing.Union[A, B], A | B, typing.Optional[A]) is passed for type then each type in the union will be tried separately rather than the literal type, allowing for resolving A | B to the value set by set_type_dependency(B, ...).

If a union has None as one of its types (including Optional[T]) then None will be passed for the parameter if none of the types could be resolved using the linked client.

TYPE: typing.Any DEFAULT: None

RAISES DESCRIPTION
ValueError

If both type and callback are provided.