Skip to content

Commit

Permalink
Fix dev mode ASGI
Browse files Browse the repository at this point in the history
Because uvicorn is needed for ASGI, when run in dev mode it
launches in a separate process. This was assuming it was running
in production mode.

It now loads an internal ``script.py:app.asgi_dev`` ASGI method.
  • Loading branch information
radiac committed Sep 27, 2024
1 parent 9eb4755 commit 28681ec
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 20 deletions.
5 changes: 3 additions & 2 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
Changelog
=========

0.9.1 - TBC
-----------
0.9.1 - 2024-09-27
------------------

Bugs:

* Fix incorrect tutorial syntax (#15)
* Fix instance name detection (#21, #22)
* Fix dev mode ASGI (#23)

Thanks to:

Expand Down
49 changes: 31 additions & 18 deletions nanodjango/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ def run(self, host: str | None = None):
raise UsageError("Install uvicorn to use async views")

uvicorn.run(
f"{self.app_name}:{self.instance_name}",
f"{self.app_name}:{self.instance_name}.asgi_dev",
host=host,
port=port,
log_level="info",
Expand Down Expand Up @@ -470,19 +470,6 @@ def convert(self, path: Path, name: str):
converter = Converter(app=self, path=path, name=name)
converter.build()

def _call_common(self):
"""
Common steps to set up WSGI/ASGI in production mode
"""
# WSGI/ASGI probably won't have had time to _prepare
if not self._prepared:
self._prepare()

if "DEBUG" not in self._settings:
from django.conf import settings

settings.DEBUG = False

def _prestart(self, host: str | None = None) -> tuple[str, int]:
"""
Common steps before start() and serve()
Expand Down Expand Up @@ -514,7 +501,25 @@ def _prestart(self, host: str | None = None) -> tuple[str, int]:

return host, port

async def asgi(self, scope, receive, send):
def _pre_xsgi(self, is_prod=True):
"""
Common steps to set up WSGI/ASGI
"""
# WSGI/ASGI probably won't have had time to _prepare
if not self._prepared:
self._prepare()

# Production settings
if not is_prod:
return

if "DEBUG" not in self._settings:
from django.conf import settings

settings.DEBUG = False


async def asgi(self, scope, receive, send, is_prod=True):
"""
ASGI handler
Expand All @@ -523,18 +528,26 @@ async def asgi(self, scope, receive, send):
Alternatively run with uvicorn script:app.asgi
"""
from django.core.asgi import get_asgi_application

self._call_common()
self._pre_xsgi(is_prod=is_prod)

application = get_asgi_application()
return await application(scope, receive, send)

async def asgi_dev(self, scope, receive, send):
"""
ASGI handler for development mode
Used by uvicorn when called from ``run``
"""
return await self.asgi(scope, receive, send, is_prod=False)

def wsgi(self, environ, start_response):
"""
WSGI handler
"""
from django.core.wsgi import get_wsgi_application

self._call_common()
self._pre_xsgi()
application = get_wsgi_application()
return application(environ, start_response)

Expand Down

0 comments on commit 28681ec

Please sign in to comment.