| 
							
							
							
						 |  |  | @ -0,0 +1,246 @@ | 
		
	
		
			
				|  |  |  |  | Metadata-Version: 2.1 | 
		
	
		
			
				|  |  |  |  | Name: asgiref | 
		
	
		
			
				|  |  |  |  | Version: 3.7.2 | 
		
	
		
			
				|  |  |  |  | Summary: ASGI specs, helper code, and adapters | 
		
	
		
			
				|  |  |  |  | Home-page: https://github.com/django/asgiref/ | 
		
	
		
			
				|  |  |  |  | Author: Django Software Foundation | 
		
	
		
			
				|  |  |  |  | Author-email: foundation@djangoproject.com | 
		
	
		
			
				|  |  |  |  | License: BSD-3-Clause | 
		
	
		
			
				|  |  |  |  | Project-URL: Documentation, https://asgi.readthedocs.io/ | 
		
	
		
			
				|  |  |  |  | Project-URL: Further Documentation, https://docs.djangoproject.com/en/stable/topics/async/#async-adapter-functions | 
		
	
		
			
				|  |  |  |  | Project-URL: Changelog, https://github.com/django/asgiref/blob/master/CHANGELOG.txt | 
		
	
		
			
				|  |  |  |  | Classifier: Development Status :: 5 - Production/Stable | 
		
	
		
			
				|  |  |  |  | Classifier: Environment :: Web Environment | 
		
	
		
			
				|  |  |  |  | Classifier: Intended Audience :: Developers | 
		
	
		
			
				|  |  |  |  | Classifier: License :: OSI Approved :: BSD License | 
		
	
		
			
				|  |  |  |  | Classifier: Operating System :: OS Independent | 
		
	
		
			
				|  |  |  |  | Classifier: Programming Language :: Python | 
		
	
		
			
				|  |  |  |  | Classifier: Programming Language :: Python :: 3 | 
		
	
		
			
				|  |  |  |  | Classifier: Programming Language :: Python :: 3 :: Only | 
		
	
		
			
				|  |  |  |  | Classifier: Programming Language :: Python :: 3.7 | 
		
	
		
			
				|  |  |  |  | Classifier: Programming Language :: Python :: 3.8 | 
		
	
		
			
				|  |  |  |  | Classifier: Programming Language :: Python :: 3.9 | 
		
	
		
			
				|  |  |  |  | Classifier: Programming Language :: Python :: 3.10 | 
		
	
		
			
				|  |  |  |  | Classifier: Programming Language :: Python :: 3.11 | 
		
	
		
			
				|  |  |  |  | Classifier: Topic :: Internet :: WWW/HTTP | 
		
	
		
			
				|  |  |  |  | Requires-Python: >=3.7 | 
		
	
		
			
				|  |  |  |  | License-File: LICENSE | 
		
	
		
			
				|  |  |  |  | Requires-Dist: typing-extensions (>=4) ; python_version < "3.11" | 
		
	
		
			
				|  |  |  |  | Provides-Extra: tests | 
		
	
		
			
				|  |  |  |  | Requires-Dist: pytest ; extra == 'tests' | 
		
	
		
			
				|  |  |  |  | Requires-Dist: pytest-asyncio ; extra == 'tests' | 
		
	
		
			
				|  |  |  |  | Requires-Dist: mypy (>=0.800) ; extra == 'tests' | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | asgiref | 
		
	
		
			
				|  |  |  |  | ======= | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | .. image:: https://api.travis-ci.org/django/asgiref.svg | 
		
	
		
			
				|  |  |  |  |     :target: https://travis-ci.org/django/asgiref | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | .. image:: https://img.shields.io/pypi/v/asgiref.svg | 
		
	
		
			
				|  |  |  |  |     :target: https://pypi.python.org/pypi/asgiref | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | ASGI is a standard for Python asynchronous web apps and servers to communicate | 
		
	
		
			
				|  |  |  |  | with each other, and positioned as an asynchronous successor to WSGI. You can | 
		
	
		
			
				|  |  |  |  | read more at https://asgi.readthedocs.io/en/latest/ | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | This package includes ASGI base libraries, such as: | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | * Sync-to-async and async-to-sync function wrappers, ``asgiref.sync`` | 
		
	
		
			
				|  |  |  |  | * Server base classes, ``asgiref.server`` | 
		
	
		
			
				|  |  |  |  | * A WSGI-to-ASGI adapter, in ``asgiref.wsgi`` | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Function wrappers | 
		
	
		
			
				|  |  |  |  | ----------------- | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | These allow you to wrap or decorate async or sync functions to call them from | 
		
	
		
			
				|  |  |  |  | the other style (so you can call async functions from a synchronous thread, | 
		
	
		
			
				|  |  |  |  | or vice-versa). | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | In particular: | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | * AsyncToSync lets a synchronous subthread stop and wait while the async | 
		
	
		
			
				|  |  |  |  |   function is called on the main thread's event loop, and then control is | 
		
	
		
			
				|  |  |  |  |   returned to the thread when the async function is finished. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | * SyncToAsync lets async code call a synchronous function, which is run in | 
		
	
		
			
				|  |  |  |  |   a threadpool and control returned to the async coroutine when the synchronous | 
		
	
		
			
				|  |  |  |  |   function completes. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | The idea is to make it easier to call synchronous APIs from async code and | 
		
	
		
			
				|  |  |  |  | asynchronous APIs from synchronous code so it's easier to transition code from | 
		
	
		
			
				|  |  |  |  | one style to the other. In the case of Channels, we wrap the (synchronous) | 
		
	
		
			
				|  |  |  |  | Django view system with SyncToAsync to allow it to run inside the (asynchronous) | 
		
	
		
			
				|  |  |  |  | ASGI server. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Note that exactly what threads things run in is very specific, and aimed to | 
		
	
		
			
				|  |  |  |  | keep maximum compatibility with old synchronous code. See | 
		
	
		
			
				|  |  |  |  | "Synchronous code & Threads" below for a full explanation. By default, | 
		
	
		
			
				|  |  |  |  | ``sync_to_async`` will run all synchronous code in the program in the same | 
		
	
		
			
				|  |  |  |  | thread for safety reasons; you can disable this for more performance with | 
		
	
		
			
				|  |  |  |  | ``@sync_to_async(thread_sensitive=False)``, but make sure that your code does | 
		
	
		
			
				|  |  |  |  | not rely on anything bound to threads (like database connections) when you do. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Threadlocal replacement | 
		
	
		
			
				|  |  |  |  | ----------------------- | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | This is a drop-in replacement for ``threading.local`` that works with both | 
		
	
		
			
				|  |  |  |  | threads and asyncio Tasks. Even better, it will proxy values through from a | 
		
	
		
			
				|  |  |  |  | task-local context to a thread-local context when you use ``sync_to_async`` | 
		
	
		
			
				|  |  |  |  | to run things in a threadpool, and vice-versa for ``async_to_sync``. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | If you instead want true thread- and task-safety, you can set | 
		
	
		
			
				|  |  |  |  | ``thread_critical`` on the Local object to ensure this instead. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Server base classes | 
		
	
		
			
				|  |  |  |  | ------------------- | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Includes a ``StatelessServer`` class which provides all the hard work of | 
		
	
		
			
				|  |  |  |  | writing a stateless server (as in, does not handle direct incoming sockets | 
		
	
		
			
				|  |  |  |  | but instead consumes external streams or sockets to work out what is happening). | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | An example of such a server would be a chatbot server that connects out to | 
		
	
		
			
				|  |  |  |  | a central chat server and provides a "connection scope" per user chatting to | 
		
	
		
			
				|  |  |  |  | it. There's only one actual connection, but the server has to separate things | 
		
	
		
			
				|  |  |  |  | into several scopes for easier writing of the code. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | You can see an example of this being used in `frequensgi <https://github.com/andrewgodwin/frequensgi>`_. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | WSGI-to-ASGI adapter | 
		
	
		
			
				|  |  |  |  | -------------------- | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Allows you to wrap a WSGI application so it appears as a valid ASGI application. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Simply wrap it around your WSGI application like so:: | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     asgi_application = WsgiToAsgi(wsgi_application) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | The WSGI application will be run in a synchronous threadpool, and the wrapped | 
		
	
		
			
				|  |  |  |  | ASGI application will be one that accepts ``http`` class messages. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Please note that not all extended features of WSGI may be supported (such as | 
		
	
		
			
				|  |  |  |  | file handles for incoming POST bodies). | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Dependencies | 
		
	
		
			
				|  |  |  |  | ------------ | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | ``asgiref`` requires Python 3.7 or higher. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Contributing | 
		
	
		
			
				|  |  |  |  | ------------ | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Please refer to the | 
		
	
		
			
				|  |  |  |  | `main Channels contributing docs <https://github.com/django/channels/blob/master/CONTRIBUTING.rst>`_. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Testing | 
		
	
		
			
				|  |  |  |  | ''''''' | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | To run tests, make sure you have installed the ``tests`` extra with the package:: | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     cd asgiref/ | 
		
	
		
			
				|  |  |  |  |     pip install -e .[tests] | 
		
	
		
			
				|  |  |  |  |     pytest | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Building the documentation | 
		
	
		
			
				|  |  |  |  | '''''''''''''''''''''''''' | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | The documentation uses `Sphinx <http://www.sphinx-doc.org>`_:: | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     cd asgiref/docs/ | 
		
	
		
			
				|  |  |  |  |     pip install sphinx | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | To build the docs, you can use the default tools:: | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     sphinx-build -b html . _build/html  # or `make html`, if you've got make set up | 
		
	
		
			
				|  |  |  |  |     cd _build/html | 
		
	
		
			
				|  |  |  |  |     python -m http.server | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | ...or you can use ``sphinx-autobuild`` to run a server and rebuild/reload | 
		
	
		
			
				|  |  |  |  | your documentation changes automatically:: | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     pip install sphinx-autobuild | 
		
	
		
			
				|  |  |  |  |     sphinx-autobuild . _build/html | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Releasing | 
		
	
		
			
				|  |  |  |  | ''''''''' | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | To release, first add details to CHANGELOG.txt and update the version number in ``asgiref/__init__.py``. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Then, build and push the packages:: | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |     python -m build | 
		
	
		
			
				|  |  |  |  |     twine upload dist/* | 
		
	
		
			
				|  |  |  |  |     rm -r build/ dist/ | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Implementation Details | 
		
	
		
			
				|  |  |  |  | ---------------------- | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Synchronous code & threads | 
		
	
		
			
				|  |  |  |  | '''''''''''''''''''''''''' | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | The ``asgiref.sync`` module provides two wrappers that let you go between | 
		
	
		
			
				|  |  |  |  | asynchronous and synchronous code at will, while taking care of the rough edges | 
		
	
		
			
				|  |  |  |  | for you. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Unfortunately, the rough edges are numerous, and the code has to work especially | 
		
	
		
			
				|  |  |  |  | hard to keep things in the same thread as much as possible. Notably, the | 
		
	
		
			
				|  |  |  |  | restrictions we are working with are: | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | * All synchronous code called through ``SyncToAsync`` and marked with | 
		
	
		
			
				|  |  |  |  |   ``thread_sensitive`` should run in the same thread as each other (and if the | 
		
	
		
			
				|  |  |  |  |   outer layer of the program is synchronous, the main thread) | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | * If a thread already has a running async loop, ``AsyncToSync`` can't run things | 
		
	
		
			
				|  |  |  |  |   on that loop if it's blocked on synchronous code that is above you in the | 
		
	
		
			
				|  |  |  |  |   call stack. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | The first compromise you get to might be that ``thread_sensitive`` code should | 
		
	
		
			
				|  |  |  |  | just run in the same thread and not spawn in a sub-thread, fulfilling the first | 
		
	
		
			
				|  |  |  |  | restriction, but that immediately runs you into the second restriction. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | The only real solution is to essentially have a variant of ThreadPoolExecutor | 
		
	
		
			
				|  |  |  |  | that executes any ``thread_sensitive`` code on the outermost synchronous | 
		
	
		
			
				|  |  |  |  | thread - either the main thread, or a single spawned subthread. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | This means you now have two basic states: | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | * If the outermost layer of your program is synchronous, then all async code | 
		
	
		
			
				|  |  |  |  |   run through ``AsyncToSync`` will run in a per-call event loop in arbitrary | 
		
	
		
			
				|  |  |  |  |   sub-threads, while all ``thread_sensitive`` code will run in the main thread. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | * If the outermost layer of your program is asynchronous, then all async code | 
		
	
		
			
				|  |  |  |  |   runs on the main thread's event loop, and all ``thread_sensitive`` synchronous | 
		
	
		
			
				|  |  |  |  |   code will run in a single shared sub-thread. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Crucially, this means that in both cases there is a thread which is a shared | 
		
	
		
			
				|  |  |  |  | resource that all ``thread_sensitive`` code must run on, and there is a chance | 
		
	
		
			
				|  |  |  |  | that this thread is currently blocked on its own ``AsyncToSync`` call. Thus, | 
		
	
		
			
				|  |  |  |  | ``AsyncToSync`` needs to act as an executor for thread code while it's blocking. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | The ``CurrentThreadExecutor`` class provides this functionality; rather than | 
		
	
		
			
				|  |  |  |  | simply waiting on a Future, you can call its ``run_until_future`` method and | 
		
	
		
			
				|  |  |  |  | it will run submitted code until that Future is done. This means that code | 
		
	
		
			
				|  |  |  |  | inside the call can then run code on your thread. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | Maintenance and Security | 
		
	
		
			
				|  |  |  |  | ------------------------ | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | To report security issues, please contact security@djangoproject.com. For GPG | 
		
	
		
			
				|  |  |  |  | signatures and more security process information, see | 
		
	
		
			
				|  |  |  |  | https://docs.djangoproject.com/en/dev/internals/security/. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | To report bugs or request new features, please open a new GitHub issue. | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | This repository is part of the Channels project. For the shepherd and maintenance team, please see the | 
		
	
		
			
				|  |  |  |  | `main Channels readme <https://github.com/django/channels/blob/master/README.rst>`_. |