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()
 | 
					   └──> provider5()
 | 
				
			||||||
        │
 | 
					        │
 | 
				
			||||||
        └──> provider6()
 | 
					        └──> 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