Dependency injection
Depends
In your actor, you can declare a dependency as follows:
from typing import Annotated
from repid import Depends
def dependency_function() -> str:
    return "Hello!"
@router.actor  # (1)
async def my_actor(
    my_dependency: Annotated[str, Depends(dependency_function)]
) -> None:
    print(my_dependency)  # (2)
- Router declaration is omitted
 - Will print 
Hello! 
from typing_extensions import Annotated  # (1)
from repid import Depends
def dependency_function() -> str:
    return "Hello!"
@router.actor  # (2)
async def my_actor(
    my_dependency: Annotated[str, Depends(dependency_function)]
) -> None:
    print(my_dependency)  # (3)
- Annotated was added in Python 3.10, but you can use backported version from
typing_extenstionsin earlier versions - Router declaration is omitted
 - Will print 
Hello! 
Sub-dependencies
Your dependency can also have some dependencies of its own!
from typing import Annotated
from repid import Depends
def subdependency_function() -> str:
    return "world!"
def dependency_function(
    sub: Annotated[str, Depends(subdependency_function)]
) -> str:
    return "Hello " + sub
@router.actor  # (1)
async def my_actor(
    my_dependency: Annotated[str, Depends(dependency_function)]
) -> None:
    print(my_dependency)  # (2)
- Router declaration is omitted
 - Will print 
Hello world! 
from typing_extensions import Annotated  # (1)
from repid import Depends
def subdependency_function() -> str:
    return "world!"
def dependency_function(
    sub: Annotated[str, Depends(subdependency_function)]
) -> str:
    return "Hello " + sub
@router.actor  # (2)
async def my_actor(
    my_dependency: Annotated[str, Depends(dependency_function)]
) -> None:
    print(my_dependency)  # (3)
- Annotated was added in Python 3.10, but you can use backported version from
typing_extenstionsin earlier versions - Router declaration is omitted
 - Will print 
Hello world! 
Sync and Async dependencies
Your dependencies' functions can be both synchronous and asynchronous.
Asynchronous
async def dependency_function() -> str:
    await asyncio.sleep(0.1)  # (1)
    return "Hello world!"
Depends(dependency_function)
- Imitates some async work
 
Synchronous
Synchronous (CPU-heavy)
In case your function is synchronous, it will be run in a thread pool executor to avoid blocking the event loop.
You can also opt to run it in a process pool executor, if, for example, your function is CPU bound.
def dependency_function() -> int:
    # some CPU-heavy computation here
    return 123
Depends(dependency_function, run_in_process=True)
Overriding dependencies
You can override a dependency (e.g. for test purposes).
Beware global state mutation
Overrides can be extremly helpful in tests, especially when you want to do complete end-to-end testing.
However, as overrides are essentially a global state mutations, you have to be very careful if they are used inside of the application itself.
def dependency_function() -> str:
    return "Hello!"
d = Depends(dependency_function)
d.override(lambda: "Overriden!")  # (1)
@router.actor
async def my_actor(
    my_dependency: Annotated[str, d]
) -> None:
    print(my_dependency)  # (2)
- You can specify any other function here and even select 
run_in_processif you need - Will print 
Overriden!