Django can only handle ASGI/HTTP connections, not lifespan. in uvicorn

1.5k Views Asked by At

The problem:

ValueError generic ASGI request Unhandled
Django can only handle ASGI/HTTP connections, not lifespan.

I'm using:

Django==3.2.6
gunicorn==20.1.0
uvicorn==0.20.0

docker CMD: gunicorn --bind 0.0.0.0:9999 --workers 1 --threads 8 --timeout 0 erp.asgi:application -k uvicorn.workers.UvicornWorker

The server works fine
need to make sure if solution uvicorn --lifespan off has any side-effects

2

There are 2 best solutions below

0
On BEST ANSWER

To close this warning:

  1. add a custom worker with lifespan off
from uvicorn.workers import UvicornWorker


class MyUvicornWorker(UvicornWorker):
    CONFIG_KWARGS = {"lifespan": "off"}
  1. user custom worker
gunicorn --bind 0.0.0.0:8888 --workers 1 --threads 8 --timeout 0 erp.asgi:application -k proj.uvicorn_worker.MyUvicornWorker

Tested on my Django 3.2.6, Turning the Lifespan protocol implementation off works

Untill Django 4.2.x django.core.asgi only handle http

# FIXME: Allow to override this.
        if scope["type"] != "http":
            raise ValueError(
                "Django can only handle ASGI/HTTP connections, not %s." % scope["type"]
            )
0
On

To build on previous answer, I suggest following.

from uvicorn.workers import UvicornWorker


class DjangoUvicornWorker(UvicornWorker):
    """
    Generate UvicornWorker with lifespan='off', because Django does not
    (and probably will not https://code.djangoproject.com/ticket/31508)
    support Lifespan.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.config.lifespan = 'off'

That will leave any existing CONFIG_KWARGS in place, and only change the lifespan setting.

Then use that for the --worker-class setting (abbreviated as -k) on the command line for gunicorn. I put that class inside my asgi.py file -- because I don't use it in any other context -- but you can put it inside any module you want.