### Install from Source Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/installation.md Installs Django ASGI Lifespan after downloading the source code. This command should be run from the root directory of the cloned repository or extracted tarball. ```console pip install . ``` -------------------------------- ### Install with Poetry Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/installation.md Installs the latest stable release of Django ASGI Lifespan using the Poetry package manager. This is the recommended method for managing dependencies. ```console poetry add django-asgi-lifespan@latest ``` -------------------------------- ### Install with Pip Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/installation.md Installs or upgrades Django ASGI Lifespan to the latest stable release using pip. This command ensures you have the most recent version available. ```console pip install --upgrade django-asgi-lifespan ``` -------------------------------- ### Clone Repository Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/installation.md Clones the public Git repository for Django ASGI Lifespan from GitHub. This allows you to access the source code directly. ```console git clone git://github.com/illagrenan/django-asgi-lifespan ``` -------------------------------- ### Download Source Tarball Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/installation.md Downloads the source tarball for Django ASGI Lifespan from GitHub using curl. This method is useful for obtaining the source code without cloning the repository. ```console curl --proto '=https' --tlsv1.3 -fsSL \ --connect-timeout 10 \ --retry 3 \ --max-redirs 3 \ -OJ https://github.com/illagrenan/django-asgi-lifespan/tarball/main ``` -------------------------------- ### Install Dependencies with Poetry Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/development.md Install project dependencies and set up the virtual environment using Poetry. Ensure Poetry is installed before running this command. ```console poetry install ``` -------------------------------- ### Install django-asgi-lifespan Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/README.md Installs the django-asgi-lifespan package using either Poetry or pip. This is the first step to enable lifespan management in your Django project. ```console poetry add django-asgi-lifespan@latest ``` ```console pip install --upgrade django-asgi-lifespan ``` -------------------------------- ### Run uvicorn with lifespan Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/README.md Starts the uvicorn server with the --lifespan=on flag, enabling the ASGI lifespan protocol and allowing django-asgi-lifespan to manage application startup and shutdown. ```console uvicorn asgi:application --lifespan=on --port=8080 ``` -------------------------------- ### Define Async Context Manager Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/how_to_use/context_manager.md An example of defining an asynchronous context manager in Python. The code before the 'yield' is executed on ASGI server startup, and the code after 'yield' is executed on shutdown. This is where shared state initialization and cleanup logic resides. ```python --8<-- "example/context.py" ``` -------------------------------- ### Example Usage: Django ASGI Handler with HTTPX Client Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/README.md This snippet demonstrates accessing an `httpx.AsyncClient` instance from the request state within a Django view. The client is typically instantiated once at application startup and closed upon shutdown, facilitating the management of long-lived client connections. ```python async def example_view(request) -> HttpResponse: # The client is instanciated just once when the application starts, # and closed when the server shuts down httpx_client: httpx.AsyncClient = request.state["httpx_client"] ``` -------------------------------- ### Register Async Context Manager Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/README.md Registers an async context manager with django-asgi-lifespan to manage resources during the application's lifespan. The example shows registering an httpx.AsyncClient. ```python from contextlib import asynccontextmanager import httpx from django_asgi_lifespan.types import LifespanManager @asynccontextmanager async def httpx_lifespan_manager() -> LifespanManager: state = { "httpx_client": httpx.AsyncClient() } try: yield state finally: await state["httpx_client"].aclose() ``` ```python from django.apps import AppConfig from django_asgi_lifespan.register import register_lifespan_manager from .context import ( httpx_lifespan_manager, ) class ExampleAppConfig(AppConfig): def ready(self): register_lifespan_manager( context_manager=httpx_lifespan_manager ) ``` -------------------------------- ### Connect Lifespan Receivers to Signals Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/how_to_use/signals.md Connects the custom startup and shutdown event handlers to the ASGI lifespan signals. This ensures the HTTPX client is properly initialized before the application starts and closed upon shutdown. ```python from django.apps import AppConfig from django.core.signals import setting_changed class LibraryConfig(AppConfig): name = "library" def ready(self): from . import handlers # Connect the startup and shutdown handlers to the lifespan signals # This is a simplified example; in a real app, you might use a # more robust signal connection mechanism. # For demonstration, we assume handlers.startup_event and handlers.shutdown_event # are registered implicitly or explicitly with the ASGI server's lifespan events. pass ``` -------------------------------- ### Bump Version with bump-my-version Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/release.md This command uses the `bump-my-version` tool to increment the project's version number (major, minor, or patch). It includes verbose output and allows dirty working directories. The `--dry-run` flag is used for testing the command before applying changes. ```console poetry run bump-my-version bump major|minor|patch \ --verbose --allow-dirty --dry-run ``` -------------------------------- ### Clone Repository Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/development.md Clone the django-asgi-lifespan repository from GitHub to your local machine. This is the first step in setting up the project for local development. ```console git clone git@github.com:your_name_here/django-asgi-lifespan.git ``` -------------------------------- ### ASGI Server Compatibility Summary Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/asgi.md A summary table detailing the compatibility of popular ASGI servers with the django-asgi-lifespan project, indicating support for lifespan events and lifespan scope state. ```APIDOC ASGI Server Compatibility: | ASGI server | Lifespan support | Lifespan scope state support | |----------------------------------------------------------------------------------------------------|---------------------------------------------|------------------------------------------| | [Uvicorn](https://github.com/encode/uvicorn) | Yes | Yes | | [gunicorn with UvicornWorker](https://www.uvicorn.org/deployment/#gunicorn) | Yes | Yes | | [Granian](https://github.com/emmett-framework/granian) | Yes | Yes | | [Hypercorn](https://github.com/pgjones/hypercorn) | Yes | Not compatible | | [Daphne](https://github.com/django/daphne) | Not compatible | _not relevant_ | | [Django runserver](https://docs.djangoproject.com/en/dev/ref/django-admin/#django-admin-runserver) | Not compatible | _not relevant_ | | [NGINX Unit](https://github.com/nginx/unit) | Not yet tested | Not yet tested | Note: Compatibility issues listed do not prevent the project from working as usual; the plugin only handles lifespan events if provided by the server. Other ASGI servers not listed are expected to behave similarly. ``` -------------------------------- ### Push Git Tags Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/release.md This command pushes all local Git tags to the remote origin. This is typically done after a new version tag has been created by the version bumping process. ```bash git push --verbose origin --tags ``` -------------------------------- ### Run Local Django Test Project Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/development.md Run the integrated Django test project locally using Uvicorn. This allows observation of how the application behaves in a real environment. ```shell cd ./tests/ poetry run uvicorn django_test_application.asgi:application --log-level=debug --reload ``` -------------------------------- ### NGINX Unit Details Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/asgi.md Compatibility status for NGINX Unit, which has not yet been tested for lifespan event support. ```APIDOC NGINX Unit: - Lifespan Support: Not yet tested - Lifespan Scope State Support: Not yet tested ``` -------------------------------- ### Test ASGI Servers Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/development.md Run the Django test application with various ASGI servers to test compatibility and performance. This includes Uvicorn, Hypercorn, Daphne, Granian, and Gunicorn. ```console cd ./tests/ poetry run uvicorn django_test_application.asgi:application --log-level=debug --reload poetry run hypercorn django_test_application.asgi:application --log-level debug --reload poetry run daphne django_test_application.asgi:application poetry run granian --interface asgi django_test_application.asgi:application poetry run gunicorn django_test_application.asgi:application -k uvicorn.workers.UvicornWorker --log-level debug --reload ``` -------------------------------- ### Granian ASGI Server Details Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/asgi.md Compatibility information for Granian, indicating full support for lifespan events and scope state. ```APIDOC Granian: - Lifespan Support: Yes - Lifespan Scope State Support: Yes ``` -------------------------------- ### Daphne ASGI Server Details Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/asgi.md Information regarding Daphne's compatibility with django-asgi-lifespan. Daphne does not support the lifespan protocol at all. ```APIDOC Daphne: - Lifespan Protocol Support: Not compatible - Notes: Asynchronous start/shutdown signals will not be handled when using Daphne. - Issue Reference: - https://github.com/django/daphne/issues/264 ``` -------------------------------- ### Register Context Manager in AppConfig Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/how_to_use/context_manager.md This code demonstrates how to register the custom async context manager within a Django AppConfig. The 'ready' method is used to signal the ASGI server to use the defined context manager for lifespan events. ```python --8<-- "example/managers_app.py" ``` -------------------------------- ### API Reference: django_asgi_lifespan.register Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/reference.md Documentation for the public API of the `django_asgi_lifespan.register` module. This section details mechanisms for registering ASGI applications or components. ```APIDOC ::: django_asgi_lifespan.register options: show_root_full_path: false show_root_heading: true show_source: true show_symbol_type_heading: true ``` -------------------------------- ### Gunicorn with UvicornWorker Details Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/asgi.md Compatibility information for using Gunicorn with UvicornWorker, indicating full support for lifespan events and scope state. ```APIDOC Gunicorn with UvicornWorker: - Lifespan Support: Yes - Lifespan Scope State Support: Yes - Notes: Gunicorn does not support Windows operating systems. ``` -------------------------------- ### Create HTTPX Client Lifespan Receivers Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/how_to_use/signals.md Implements startup and shutdown receivers for ASGI lifespan signals. The startup receiver creates an httpx.AsyncClient instance and stores it in the application state, while the shutdown receiver closes the client. ```python import httpx from django.core.asgi import get_asgi_application from django.dispatch import receiver from django.urls import path from .types import HTTPXAppConfig async def startup_event(app: HTTPXAppConfig): """Startup event handler to create and store the HTTPX client.""" app.state["client"] = httpx.AsyncClient() async def shutdown_event(app: HTTPXAppConfig): """Shutdown event handler to close the HTTPX client.""" await app.state["client"].close() ``` -------------------------------- ### API Reference: django_asgi_lifespan.signals Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/reference.md Documentation for the public API of the `django_asgi_lifespan.signals` module. This section details signal handling and definitions for lifecycle events. ```APIDOC ::: django_asgi_lifespan.signals options: show_root_full_path: false show_root_heading: true show_source: true show_symbol_type_heading: true ``` -------------------------------- ### Uvicorn ASGI Server Details Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/asgi.md Information regarding Uvicorn's compatibility with django-asgi-lifespan. Uvicorn is the most tested ASGI server by the plugin's author and is recommended for development, testing, and production. ```APIDOC Uvicorn: - Compatibility: Fully compatible with lifespan events and scope state. - Usage: Recommended for development, testing, and production environments. - Notes: It is perfectly fine to use Uvicorn without Gunicorn in production. - References: - https://stackoverflow.com/questions/66362199/what-is-the-difference-between-uvicorn-and-gunicornuvicorn/71546833 - https://github.com/encode/uvicorn/issues/303 ``` -------------------------------- ### API Reference: django_asgi_lifespan.middleware Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/reference.md Documentation for the public API of the `django_asgi_lifespan.middleware` module. This section details the ASGI middleware components. ```APIDOC ::: django_asgi_lifespan.middleware options: show_root_full_path: false show_root_heading: true show_source: true show_symbol_type_heading: true ``` -------------------------------- ### Configure ASGI application Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/README.md Modifies the main ASGI application file (e.g., asgi.py) to use the get_asgi_application helper from django_asgi_lifespan. This ensures that lifespan events are correctly handled. ```python from django_asgi_lifespan.asgi import get_asgi_application django_application = get_asgi_application() async def application(scope, receive, send): if scope["type"] in {"http", "lifespan"}: await django_application(scope, receive, send) else: raise NotImplementedError( f"Unknown scope type {scope['type']}" ) ``` -------------------------------- ### Register LifespanStateMiddleware Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/how_to_use/context_manager.md This snippet shows how to include the LifespanStateMiddleware in your Django project's MIDDLEWARE setting. This middleware is crucial for accessing the shared state from ASGI lifespan events within your views. ```python MIDDLEWARE = [ # ... 'django_asgi_lifespan.middleware.LifespanStateMiddleware', # ... ] ``` -------------------------------- ### API Reference: django_asgi_lifespan.dispatcher Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/reference.md Documentation for the public API of the `django_asgi_lifespan.dispatcher` module. This section details its functions, classes, and their usage in dispatching ASGI events. ```APIDOC ::: django_asgi_lifespan.dispatcher options: show_root_full_path: false show_root_heading: true show_source: true show_symbol_type_heading: true ``` -------------------------------- ### Django runserver Details Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/asgi.md Compatibility information for Django's built-in runserver, indicating it is not compatible with lifespan events. ```APIDOC Django runserver: - Lifespan Support: Not compatible - Lifespan Scope State Support: Not relevant ``` -------------------------------- ### API Reference: django_asgi_lifespan.handler Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/reference.md Documentation for the public API of the `django_asgi_lifespan.handler` module. This section details the core request handling mechanisms. ```APIDOC ::: django_asgi_lifespan.handler options: show_root_full_path: false show_root_heading: true show_source: true show_symbol_type_heading: true ``` -------------------------------- ### Commit and Push Changes Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/development.md Stage, commit, and push your local changes to your GitHub fork. This prepares your contributions for a pull request. ```console git add . git commit -m "Your detailed description of your changes." git push origin name-of-your-bugfix-or-feature ``` -------------------------------- ### Run Tests Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/development.md Execute the project's test suite to ensure your changes do not break existing functionality. This command is typically run after making local modifications. ```console task test ``` -------------------------------- ### Format Code with Poetry Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/development.md Format the project's code according to established style guidelines using a Poetry task. This ensures code consistency across the project. ```console poetry task format ``` -------------------------------- ### API Reference: django_asgi_lifespan.asgi Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/reference.md Documentation for the public API of the `django_asgi_lifespan.asgi` module. This section details its functions, classes, and their usage within the ASGI lifecycle. ```APIDOC ::: django_asgi_lifespan.asgi options: show_root_full_path: false show_root_heading: true show_source: true show_symbol_type_heading: true ``` -------------------------------- ### Create Development Branch Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/development.md Create a new branch for your local development work. This helps in isolating your changes and managing contributions. ```console git checkout -b name-of-your-bugfix-or-feature ``` -------------------------------- ### Hypercorn ASGI Server Details Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/asgi.md Details on Hypercorn's support for lifespan events. Hypercorn supports the lifespan protocol but does not support lifespan scope state. ```APIDOC Hypercorn: - Lifespan Protocol Support: Yes - Lifespan Scope State Support: Not compatible - Notes: Related Pull Requests: - https://github.com/pgjones/hypercorn/pull/107 - https://github.com/pgjones/hypercorn/pull/110 ``` -------------------------------- ### API Reference: django_asgi_lifespan.events Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/reference.md Documentation for the public API of the `django_asgi_lifespan.events` module. This section details event-related functionalities and structures. ```APIDOC ::: django_asgi_lifespan.events options: show_root_full_path: false show_root_heading: true show_source: true show_symbol_type_heading: true ``` -------------------------------- ### API Reference: django_asgi_lifespan.errors Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/reference.md Documentation for the public API of the `django_asgi_lifespan.errors` module. This section details custom exception classes used within the library. ```APIDOC ::: django_asgi_lifespan.errors options: show_root_full_path: false show_root_heading: true show_source: true show_symbol_type_heading: true ``` -------------------------------- ### Define HTTPXAppConfig Protocol Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/how_to_use/signals.md Defines a Protocol for typehinting, specifying an interface for requests that include an httpx.AsyncClient instance in their state dictionary. This ensures type safety when accessing the client. ```python from typing import Protocol import httpx class HTTPXAppConfig(Protocol): """A protocol for ASGI applications that have an httpx.AsyncClient in their state.""" state: dict async def __call__(self, scope, receive, send): """The ASGI application callable.""" pass ``` -------------------------------- ### Use managed resource in view Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/README.md Demonstrates how to access resources managed by the registered async context manager within a Django view. The httpx_client is retrieved from request.state. ```python from http import HTTPStatus import httpx from django.http import HttpResponse async def example_view(request) -> HttpResponse: httpx_client: httpx.AsyncClient = request.state["httpx_client"] await httpx_client.head("https://www.example.com/") return HttpResponse( "OK", status=HTTPStatus.OK, content_type="text/plain; charset=utf-8", ) ``` -------------------------------- ### Add LifespanStateMiddleware Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/README.md Adds the LifespanStateMiddleware to your Django project's MIDDLEWARE setting. This middleware is crucial for making application state available to views via request.state. ```python MIDDLEWARE = [ # ... "django_asgi_lifespan.middleware.LifespanStateMiddleware", # ... ] ``` -------------------------------- ### Access Shared State in Django View Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/how_to_use/context_manager.md This snippet illustrates how to access the shared state, which is attached to the request object by the LifespanStateMiddleware, within a Django view. This allows views to utilize application-level configurations or resources initialized during server startup. ```python --8<-- "example/managers_view.py" ``` -------------------------------- ### Access HTTPX Client in Django View Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/how_to_use/signals.md Demonstrates how to access the shared httpx.AsyncClient instance within a Django view. The client is retrieved from the application state dictionary, allowing for efficient API calls. ```python from django.http import HttpResponse async def book_list(request): """View to fetch book information using the shared HTTPX client.""" # Access the ASGI application instance from the request asgi_app = request.scope["asgi_app"] # Retrieve the HTTPX client from the application state client = asgi_app.state["client"] # Use the client to make an API request response = await client.get("https://example.com/api/books") books = await response.json() return HttpResponse(f"Books: {books}") ``` -------------------------------- ### Access Test Project Endpoints Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/development.md Make HTTP requests to specific endpoints of the locally running Django test project to verify functionality. These are useful for integration testing. ```console curl -v http://127.0.0.1:8000/client-from-app-config curl -v http://127.0.0.1:8000/client-from-scope-state ``` -------------------------------- ### API Reference: django_asgi_lifespan.types Source: https://github.com/illagrenan/django-asgi-lifespan/blob/main/docs/reference.md Documentation for the public API of the `django_asgi_lifespan.types` module. This section details custom type definitions and annotations used within the library. ```APIDOC ::: django_asgi_lifespan.types options: show_root_full_path: false show_root_heading: true show_source: true show_symbol_type_heading: true ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.