mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-11-24 11:55:47 +03:00
add docs, small reference in resource
This commit is contained in:
parent
36586a4e57
commit
9c9283d553
32
docs/providers/context_local_resource.rst
Normal file
32
docs/providers/context_local_resource.rst
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
.. _context-local-resource-provider:
|
||||||
|
|
||||||
|
Context Local Resource provider
|
||||||
|
================================
|
||||||
|
|
||||||
|
.. meta::
|
||||||
|
:keywords: Python,DI,Dependency injection,IoC,Inversion of Control,Resource,Context Local,
|
||||||
|
Context Variables,Singleton,Per-context
|
||||||
|
:description: Context Local Resource provider provides a component with initialization and shutdown
|
||||||
|
that is scoped to execution context using contextvars. This page demonstrates how to
|
||||||
|
use context local resource provider.
|
||||||
|
|
||||||
|
.. currentmodule:: dependency_injector.providers
|
||||||
|
|
||||||
|
``ContextLocalResource`` inherits from :ref:`resource-provider` and uses the same initialization and shutdown logic
|
||||||
|
as the standard ``Resource`` provider.
|
||||||
|
It extends it with context-local storage using Python's ``contextvars`` module.
|
||||||
|
This means that objects are context local singletons - the same context will
|
||||||
|
receive the same instance, but different execution contexts will have their own separate instances.
|
||||||
|
|
||||||
|
This is particularly useful in asynchronous applications where you need per-request resource instances
|
||||||
|
(such as database sessions) that are automatically cleaned up when the request context ends.
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. literalinclude:: ../../examples/providers/context_local_resource.py
|
||||||
|
:language: python
|
||||||
|
:lines: 3-
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. disqus::
|
||||||
|
|
||||||
|
|
@ -46,6 +46,7 @@ Providers module API docs - :py:mod:`dependency_injector.providers`
|
||||||
dict
|
dict
|
||||||
configuration
|
configuration
|
||||||
resource
|
resource
|
||||||
|
context_local_resource
|
||||||
aggregate
|
aggregate
|
||||||
selector
|
selector
|
||||||
dependency
|
dependency
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,9 @@ Resource provider
|
||||||
Resource providers help to initialize and configure logging, event loop, thread or process pool, etc.
|
Resource providers help to initialize and configure logging, event loop, thread or process pool, etc.
|
||||||
|
|
||||||
Resource provider is similar to ``Singleton``. Resource initialization happens only once.
|
Resource provider is similar to ``Singleton``. Resource initialization happens only once.
|
||||||
|
If you need a context local singleton (where each execution context has its own instance),
|
||||||
|
see :ref:`context-local-resource-provider`.
|
||||||
|
|
||||||
You can make injections and use provided instance the same way like you do with any other provider.
|
You can make injections and use provided instance the same way like you do with any other provider.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
|
||||||
50
examples/providers/context_local_resource.py
Normal file
50
examples/providers/context_local_resource.py
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
|
from fastapi import Depends, FastAPI
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers
|
||||||
|
from dependency_injector.wiring import Closing, Provide, inject
|
||||||
|
|
||||||
|
global_list = []
|
||||||
|
|
||||||
|
|
||||||
|
class AsyncSessionLocal:
|
||||||
|
def __init__(self):
|
||||||
|
self.id = uuid4()
|
||||||
|
|
||||||
|
async def __aenter__(self):
|
||||||
|
print("Entering session !")
|
||||||
|
return self
|
||||||
|
|
||||||
|
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
||||||
|
print("Closing session !")
|
||||||
|
|
||||||
|
async def execute(self, user_input):
|
||||||
|
return f"Executing {user_input} in session {self.id}"
|
||||||
|
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
db_session = providers.ContextLocalResource(AsyncSessionLocal)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/")
|
||||||
|
@inject
|
||||||
|
async def index(db: AsyncSessionLocal = Depends(Closing[Provide["db_session"]])):
|
||||||
|
global global_list
|
||||||
|
if db.id in global_list:
|
||||||
|
raise Exception("The db session is already used") # never reaches here
|
||||||
|
global_list.append(db.id)
|
||||||
|
res = await db.execute("SELECT 1")
|
||||||
|
return str(res)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import uvicorn
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
container.wire(modules=["__main__"])
|
||||||
|
uvicorn.run(app, host="localhost", port=8000)
|
||||||
|
container.unwire()
|
||||||
Loading…
Reference in New Issue
Block a user