mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 01:47:36 +03:00 
			
		
		
		
	Add provider async mode docs
This commit is contained in:
		
							parent
							
								
									b146504675
								
							
						
					
					
						commit
						0a484fa553
					
				| 
						 | 
				
			
			@ -32,3 +32,71 @@ This causes a cascade effect:
 | 
			
		|||
   └──> provider5()
 | 
			
		||||
        │
 | 
			
		||||
        └──> provider6()
 | 
			
		||||
 | 
			
		||||
In async mode provider prepares injections asynchronously.
 | 
			
		||||
 | 
			
		||||
If provider has multiple awaitable dependencies, it will run them concurrently. Provider will wait until all
 | 
			
		||||
dependencies are ready and inject them afterwards.
 | 
			
		||||
 | 
			
		||||
.. code-block:: bash
 | 
			
		||||
 | 
			
		||||
   provider1()
 | 
			
		||||
   │
 | 
			
		||||
   ├──> provider2()         <── Async mode enabled
 | 
			
		||||
   │
 | 
			
		||||
   ├──> provider3()         <── Async mode enabled
 | 
			
		||||
   │
 | 
			
		||||
   └──> provider4()         <── Async mode enabled
 | 
			
		||||
 | 
			
		||||
Here is what provider will do for the previous example:
 | 
			
		||||
 | 
			
		||||
.. code-block:: python
 | 
			
		||||
 | 
			
		||||
   injections = await asyncio.gather(
 | 
			
		||||
       provider2(),
 | 
			
		||||
       provider3(),
 | 
			
		||||
       provider4(),
 | 
			
		||||
   )
 | 
			
		||||
   await provider1(*injections)
 | 
			
		||||
 | 
			
		||||
Overriding behaviour
 | 
			
		||||
--------------------
 | 
			
		||||
 | 
			
		||||
In async mode provider always returns awaitable. It applies to the overriding too. If provider in async mode is
 | 
			
		||||
overridden by a provider that doesn't return awaitable result, the result will be wrapped into awaitable.
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../examples/providers/async_overriding.py
 | 
			
		||||
   :language: python
 | 
			
		||||
   :emphasize-lines: 19-24
 | 
			
		||||
   :lines: 3-
 | 
			
		||||
 | 
			
		||||
Async mode mechanics and API
 | 
			
		||||
----------------------------
 | 
			
		||||
 | 
			
		||||
By default provider's async mode is undefined.
 | 
			
		||||
 | 
			
		||||
When provider async mode is undefined, provider will automatically select the mode during the next call.
 | 
			
		||||
If the result is awaitable, provider will enable async mode, if not - disable it.
 | 
			
		||||
 | 
			
		||||
If provider async mode is enabled, provider always returns awaitable. If the result is not awaitable,
 | 
			
		||||
provider wraps it into awaitable explicitly. You can safely ``await`` provider in async mode.
 | 
			
		||||
 | 
			
		||||
If provider async mode is disabled, provider behaves the regular way. It doesn't do async injections
 | 
			
		||||
preparation or non-awaitables to awaitables conversion.
 | 
			
		||||
 | 
			
		||||
Once provider async mode is enabled or disabled, provider will stay in this state. No automatic switching
 | 
			
		||||
will be done.
 | 
			
		||||
 | 
			
		||||
.. image:: images/async_mode.png
 | 
			
		||||
 | 
			
		||||
You can also use following methods to change provider's async mode manually:
 | 
			
		||||
 | 
			
		||||
- ``Provider.enable_async_mode()``
 | 
			
		||||
- ``Provider.disable_async_mode()``
 | 
			
		||||
- ``Provider.reset_async_mode()``
 | 
			
		||||
 | 
			
		||||
To check the state of provider's async mode use:
 | 
			
		||||
 | 
			
		||||
- ``Provider.is_async_mode_enabled()``
 | 
			
		||||
- ``Provider.is_async_mode_disabled()``
 | 
			
		||||
- ``Provider.is_async_mode_undefined()``
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										
											BIN
										
									
								
								docs/providers/images/async_mode.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/providers/images/async_mode.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 12 KiB  | 
							
								
								
									
										32
									
								
								examples/providers/async_overriding.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								examples/providers/async_overriding.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
"""Provider overriding in async mode example."""
 | 
			
		||||
 | 
			
		||||
import asyncio
 | 
			
		||||
 | 
			
		||||
from dependency_injector import containers, providers
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def init_async_resource():
 | 
			
		||||
    return ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def init_resource_mock():
 | 
			
		||||
    return ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Container(containers.DeclarativeContainer):
 | 
			
		||||
 | 
			
		||||
    resource = providers.Resource(init_async_resource)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
async def main(container: Container):
 | 
			
		||||
    resource1 = await container.resource()
 | 
			
		||||
 | 
			
		||||
    container.resource.override(providers.Callable(init_resource_mock))
 | 
			
		||||
    resource2 = await container.resource()
 | 
			
		||||
    ...
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    container = Container()
 | 
			
		||||
 | 
			
		||||
    asyncio.run(main(container))
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user