Source code for autowire.resource

from __future__ import annotations

from typing import Any, Callable, ContextManager, Optional, TypeVar

from autowire.base_resource import BaseResource
from autowire.implementation import (
    ConstantImplementation,
    ContextManagerImplementation,
    Implementation,
    PlainFunctionImplementation,
)

R = TypeVar("R")
F = TypeVar("F", bound=Callable[..., Any])
C = TypeVar("C", bound=Callable[..., ContextManager[Any]])


[docs]class Resource(BaseResource[R]): """ Decalarative resource definition. Namespace generally be the module's name. `name` cannot include any dot(.) characters. :: >>> resource = BaseResource('name', __name__) """ def __init__(self, name: str, namespace: str): super().__init__(name, namespace) self.default_implementation: Optional[Implementation[R]] = None
[docs] def plain( self, *arg_resources: BaseResource[Any], **kwarg_resources: BaseResource[Any], ) -> Callable[[F], F]: """ Set the default implementation with plain function arg_resources and kwarg_resources will be used for dependency injection. :: config = Resource("config", __name__) connection_pool = Resource("connection_pool", __name__) db_connection = Resource("db_connection", __name__) @db_connection.plain(connection_pool, config=config) def get_db_connection(connection_pool: Pool, *, config: dict) -> Connection: # ... """ def decorator(fn: F) -> F: self.default_implementation = PlainFunctionImplementation( fn, arg_resources, kwarg_resources ) return fn return decorator
[docs] def contextual( self, *arg_resources: BaseResource[Any], **kwarg_resources: BaseResource[Any], ) -> Callable[[C], C]: """ Set the default implementation with context manager arg_resources and kwarg_resources will be used for dependency injection. :: db_connection = Resource("db_connection", __name__) db_transaction = Resource("transaction", __name__) @db_transaction.contextual(db_connection) @contextlib.contextmanager def begin_trasaction(db_connection: Connection): tx = db_connection.begin() try: yield tx except Exception: tx.rollback() raise finally: tx.commit() """ def decorator(manager: C) -> C: self.default_implementation = ContextManagerImplementation( manager, arg_resources, kwarg_resources ) return manager return decorator
[docs] def set_constant(self, constant: R): """ Set the default implementation with constant implementation that holds given ``constant`` as a value. :: global_config = Resource("global_config", __name__) global_config.set_constant({"DB_TIMEOUT": 30}) """ self.default_implementation = ConstantImplementation(constant)