Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a322584

Browse files
committed
Add context manager support to Resource provider
1 parent 4b3476c commit a322584

File tree

6 files changed

+260
-191
lines changed

6 files changed

+260
-191
lines changed

‎docs/providers/resource.rst

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,12 @@ When you call ``.shutdown()`` method on a resource provider, it will remove the
6161
if any, and switch to uninitialized state. Some of resource initializer types support specifying custom
6262
resource shutdown.
6363

64-
Resource provider supports 3 types of initializers:
64+
Resource provider supports 4 types of initializers:
6565

6666
- Function
67-
- Generator
68-
- Subclass of ``resources.Resource``
67+
- Context Manager
68+
- Generator (legacy)
69+
- Subclass of ``resources.Resource`` (legacy)
6970

7071
Function initializer
7172
--------------------
@@ -103,8 +104,44 @@ you configure global resource:
103104
104105
Function initializer does not provide a way to specify custom resource shutdown.
105106

106-
Generator initializer
107-
---------------------
107+
Context Manager initializer
108+
---------------------------
109+
110+
This is an extension to the Function initializer. Resource provider automatically detects if the initializer returns a
111+
context manager and uses it to manage the resource lifecycle.
112+
113+
.. code-block:: python
114+
115+
from dependency_injector import containers, providers
116+
117+
class DatabaseConnection:
118+
def __init__(self, host, port, user, password):
119+
self.host = host
120+
self.port = port
121+
self.user = user
122+
self.password = password
123+
124+
def __enter__(self):
125+
print(f"Connecting to {self.host}:{self.port} as {self.user}")
126+
return self
127+
128+
def __exit__(self, exc_type, exc_val, exc_tb):
129+
print("Closing connection")
130+
131+
132+
class Container(containers.DeclarativeContainer):
133+
134+
config = providers.Configuration()
135+
db = providers.Resource(
136+
DatabaseConnection,
137+
host=config.db.host,
138+
port=config.db.port,
139+
user=config.db.user,
140+
password=config.db.password,
141+
)
142+
143+
Generator initializer (legacy)
144+
------------------------------
108145

109146
Resource provider can use 2-step generators:
110147

@@ -154,8 +191,13 @@ object is not mandatory. You can leave ``yield`` statement empty:
154191
argument2=...,
155192
)
156193
157-
Subclass initializer
158-
--------------------
194+
.. note::
195+
196+
Generator initializers are automatically wrapped with ``contextmanager`` or ``asynccontextmanager`` decorator when
197+
provided to a ``Resource`` provider.
198+
199+
Subclass initializer (legacy)
200+
-----------------------------
159201

160202
You can create resource initializer by implementing a subclass of the ``resources.Resource``:
161203

@@ -263,10 +305,11 @@ Asynchronous function initializer:
263305
argument2=...,
264306
)
265307
266-
Asynchronous generator initializer:
308+
Asynchronous Context Manager initializer:
267309

268310
.. code-block:: python
269311
312+
@asynccontextmanager
270313
async def init_async_resource(argument1=..., argument2=...):
271314
connection = await connect()
272315
yield connection

‎examples/providers/resource.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
import sys
44
import logging
55
from concurrent.futures import ThreadPoolExecutor
6+
from contextlib import contextmanager
67

78
from dependency_injector import containers, providers
89

910

11+
@contextmanager
1012
def init_thread_pool(max_workers: int):
1113
thread_pool = ThreadPoolExecutor(max_workers=max_workers)
1214
yield thread_pool

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /