Module Index¶
Module contents¶
- class picodi.AutoScope[source]¶
Bases:
ScopeAutoScope is a scope that automatically closes dependencies after exiting the context.
Don’t use this class directly.
- class picodi.ContextVarScope[source]¶
Bases:
ManualScopeContextVar scope. Values cached in contextvars. Dependencies closed only when user manually call
shutdown_dependencies().
- class picodi.ManualScope[source]¶
Bases:
ScopeManualScope is a scope that requires manual closing of dependencies. For example
SingletonScopeorContextVarScopeuse this scope. You can close dependencies by callingshutdown_dependencies()orshutdown_dependencies(scope_class=MyCustomScope)for shutdown only dependencies that usesMyCustomScopescope.Don’t use this class directly. Inherit this class for your custom scope.
- enter(context_manager: AsyncContextManager | ContextManager, *, global_key: Hashable) Awaitable[source]¶
Hook for entering yielded dependencies context. Will be called automatically by picodi or when you call
init_dependencies().- Parameters:
context_manager – context manager created from yield dependency.
global_key – typically a function that requesting dependencies
- shutdown(exc: BaseException | None = None, *, global_key: Hashable) Awaitable[source]¶
Hook for shutdown dependencies. Will be called when you call
shutdown_dependencies()- Parameters:
exc – exception that was raised in the context.
global_key – typically a function that requesting dependencies
- class picodi.NullScope[source]¶
Bases:
AutoScopeNull scope. Values aren’t cached, dependencies closed automatically after function call. This is the default scope.
- picodi.Provide(dependency: Callable[[...], Any], /) Any[source]¶
Declare a provider. It takes a single “dependency” callable (like a function). Don’t call it directly, picodi will call it for you.
- Parameters:
dependency – can be a regular function or a generator with one yield. If the dependency is a generator, it will be used as a context manager. Any generator that is valid for
contextlib.contextmanager()can be used as a dependency.
Example¶
from picodi import Provide, inject def get_db(): yield "db connection" print("closing db connection") @inject def my_service(db: str = Provide(get_db)): assert db == "db connection"
- class picodi.Scope[source]¶
Bases:
objectScopes are used to store and retrieve values by key and for closing dependencies.
Don’t use this class directly and don’t inherit from it. Inherit from
AutoScopeorManualScope.- get(key: Hashable, *, global_key: Hashable) Any[source]¶
Get a value by key. If value is not exists must raise KeyError.
- Parameters:
key – key to get value, typically a dependency function.
global_key – typically a function that requesting dependencies
- Raises:
KeyError – if value not exists.
- set(key: Hashable, value: Any, *, global_key: Hashable) None[source]¶
Set a value by key.
- Parameters:
key – key to set value, typically a dependency function.
value – value to set, typically a dependency instance.
global_key – typically a function that requesting dependencies
- enter_inject(global_key: Hashable) None[source]¶
Called when entering an
inject()decorator.- Parameters:
global_key – typically a function that requesting dependencies
- exit_inject(exc: BaseException | None = None, *, global_key: Hashable) None[source]¶
Called before exiting a
inject()decorator.shutdownwill be called after this, e.g.:exit_inject->shutdown->injectwrapper returns.
- Parameters:
exc – exception that was raised in the context.
global_key – typically a function that requesting dependencies
- class picodi.SingletonScope[source]¶
Bases:
ManualScopeSingleton scope. Values cached for the lifetime of the application. Dependencies closed only when user manually call
shutdown_dependencies().
- picodi.inject(fn: Callable[P, T] | None = None, *, registry: Registry | None = None) Callable[P, T] | Callable[[Callable[P, T]], Callable[P, T]][source]¶
Decorator to inject dependencies into a function. Use it in combination with
Provide()to declare dependencies. Should be placed first in the decorator chain (on bottom).- Parameters:
fn – function to decorate.
Example¶
from picodi import inject, Provide @inject def my_service(db=Provide(some_dependency_func)): pass
- class picodi.Registry(for_init: Iterable[Callable[[...], Any]] | Callable[[], Iterable[Callable[[...], Any]]] | None = None)[source]¶
Manages dependencies and overrides.
- add(dependency: Callable[[...], Any], scope_class: type[AutoScope | ManualScope] = NullScope) None[source]¶
Add a dependency to the registry and set scope_class for it.
- add_for_init(dependencies: Iterable[Callable[[...], Any]] | Callable[[], Iterable[Callable[[...], Any]]]) None[source]¶
Add a dependencies to the list of dependencies to initialize.
- set_scope(scope_class: type[AutoScope | ManualScope], *, auto_init: bool = False) Callable[[TC], TC][source]¶
Decorator to declare a dependency. Should be placed last in the decorator chain (on top).
- Parameters:
scope_class – specify the scope class to use it for the dependency.
auto_init – if set to
True, the dependency will be added to the list of dependencies to initialize. This is useful for dependencies that need to be initialized before the application starts.
- init(dependencies: Iterable[Callable[[...], Any]] | Callable[[], Iterable[Callable[[...], Any]]] | None = None) Awaitable[source]¶
Call this method to init dependencies. Usually, it should be called when your application is starting up.
This method works both for synchronous and asynchronous dependencies. If you call it without
await, it will initialize only sync dependencies. If you call itawait init(...), it will initialize both sync and async dependencies.- Parameters:
dependencies – dependencies to initialize. If this argument is passed - init dependencies specified in the registry will be ignored.
- shutdown(scope_class: type[ManualScope] | tuple[type[ManualScope], ...] = ManualScope) Awaitable[source]¶
Call this method to close dependencies. Usually, it should be called when your application is shut down.
This method works both for synchronous and asynchronous dependencies. If you call it without
await, it will shutdown only sync dependencies. If you call itawait shutdown(), it will shutdown both sync and async dependencies.If you not pass any arguments, it will shutdown subclasses of
ManualScope.- Parameters:
scope_class – you can specify the scope class to shutdown. If passed - only dependencies of this scope class and its subclasses will be shutdown.
- lifespan() Generator[None][source]¶
Context manager to manage the lifespan of the application. It will automatically call init and shutdown methods.
- alifespan() AsyncGenerator[None][source]¶
Async context manager to manage the lifespan of the application. It will automatically call init and shutdown methods.
- property touched: frozenset[Callable[[...], Any]]¶
Get all dependencies that were used during the picodi lifecycle. This method will return a frozenset of dependencies that were resolved. It will not include dependencies that were overridden. Primarily used for testing purposes. For example, you can check that mongo database was used in the test and clear it after the test.
- override(dependency: Callable[[...], Any], new_dependency: Callable[[...], Any] | None) ContextManager[None][source]¶
Override a dependency with a new one. It can be used as a context manager or as a regular method call. New dependency will be added to the registry.
- Parameters:
dependency – dependency to override
new_dependency – new dependency to use. If explicitly set to
None, it will remove the override.
Examples¶
with registry.override(get_settings, real_settings): pass registry.override(get_settings, real_settings) registry.override(get_settings, None) # clear override
- resolve(dependency: Callable[[...], Generator[T]]) ContextManager[T][source]¶
- resolve(dependency: Callable[[...], T]) ContextManager[T]
Resolve a dependency synchronously. Returns a context manager that will return the result of the dependency. :param dependency: dependency to resolve. :return: sync context manager.
- aresolve(dependency: Callable[[...], Generator[T]]) AsyncContextManager[T][source]¶
- aresolve(dependency: Callable[[...], AsyncGenerator[T]]) AsyncContextManager[T]
- aresolve(dependency: Callable[[...], Awaitable[T]]) AsyncContextManager[T]
- aresolve(dependency: Callable[[...], T]) AsyncContextManager[T]
Resolve a dependency asynchronously. Returns a context manager that will return the result of the dependency. Also can resolve sync dependencies in async context. :param dependency: dependency to resolve. :return: async context manager.
- picodi.registry = <Registry>¶
Picodi registry. You can use it to register dependencies, scopes, overrides, initialize and shutdown dependencies.
Submodules¶
picodi.integrations module¶
Starlette¶
- class picodi.integrations.starlette.RequestScopeMiddleware(app: ASGIApp, *, registry: picodi.Registry | None = None, dependencies_for_init: picodi.InitDependencies | None = None)[source]¶
Bases:
objectStarlette Pure ASGI Middleware for automatically initializing and closing request scoped dependencies
FastAPI¶
- picodi.integrations.fastapi.Provide(dependency: Callable[[...], Any], /, *, wrap: bool = False) Any[source]¶
Drop-in replacement for
picodi.Provide()but for FastAPI.- Parameters:
dependency – callable dependency.
wrap – wrap dependency in
fastapi.Depends. In this mode you can usepicodidependencies in FastAPI routes withoutpicodi.inject()decorator.
- class picodi.integrations.fastapi.RequestScopeMiddleware(app: ASGIApp, *, registry: picodi.Registry | None = None, dependencies_for_init: picodi.InitDependencies | None = None)[source]¶
Bases:
objectStarlette Pure ASGI Middleware for automatically initializing and closing request scoped dependencies
picodi.helpers module¶
Helper functions and classes for picodi.
- picodi.helpers.get_value(path: str, obj: ~typing.Any, *, default: ~typing.Any = <object object>) Any[source]¶
Get attribute from nested objects. Can be useful to avoid passing entire objects like settings to functions that only need a small part of it.
- Parameters:
path – path to the attribute, separated by dots.
obj – object to search the attribute in.
default – default value to return if the attribute is not found. If not provided, an
PathNotFoundErroris raised.
- Raises:
PathNotFoundError – if the path is not found in the object and default is not provided.
Example¶
obj = SimpleNamespace(foo=SimpleNamespace(bar={"baz": 42})) get_value("foo.bar.baz", obj) # Output: 42 get_value("foo.bar.baz2", obj) # Output: AttributeError get_value("foo.bar.baz2", obj, default=12) # Output: 12
- class picodi.helpers.resolve(dependency: Callable[[], Coroutine[T, None, None] | Generator[T] | AsyncGenerator[T] | T], registry: Registry | None = None)[source]¶
Bases:
Generic[T]Create a context manager from a dependency.
Can be handy for testing or when you need to create “fabric” dependency (dependency that creates other dependencies based on some conditions).
- Parameters:
dependency – dependency to create a context manager from. Like with
Provide()- don’t call the dependency function here, just pass it.- Returns:
sync or async context manager.
Example¶
from picodi.helpers import resolve def get_42(): yield 42 with resolve(get_42) as val: assert val == 42
picodi.support module¶
Support module for picodi package.
May be useful for writing your own scopes or other customizations.
- class picodi.support.ExitStack[source]¶
Bases:
objectA context manager that combines multiple context managers - both sync and async.
Under the hood, it uses
contextlib.ExitStackfor sync context managers andcontextlib.AsyncExitStackfor async- enter_context(cm: AsyncContextManager | ContextManager) Any[source]¶
Enters a new context manager and adds its
__[a]exit__()method to the callback stack. The return value is the result of the context manager’s own__[a]enter__()method.- Parameters:
cm – context manager to enter.
- Returns:
Result of the context manager’s
__[a]enter__method.
- close(exc: BaseException | None = None) Awaitable[source]¶
Immediately unwinds the callback stack, invoking callbacks in the reverse order of registration.
- Parameters:
exc – exception to be passed to the
__[a]exit__method.
- picodi.support.is_async_environment() bool[source]¶
Check if we are in async environment.
- Returns:
True if we are in async environment, False otherwise.
- picodi.support.is_async_function(fn: Any) bool[source]¶
Check if the function is async.
- Parameters:
fn – function to check.
- Returns:
True if the function is async, False otherwise.
- picodi.support.call_cm_sync(cm: ContextManager) Any[source]¶
Call a sync context manager and return its result.
- Parameters:
cm – context manager to call.
- Returns:
Result of the context manager’s
__enter__method.
- async picodi.support.call_cm_async(cm: AsyncContextManager) Any[source]¶
Call an async context manager and return its result.
- Parameters:
cm – context manager to call.
- Returns:
Result of the context manager’s
__aenter__method.