mirror of
https://github.com/cookiecutter/cookiecutter-django.git
synced 2025-01-24 00:04:13 +03:00
Add uvicorn and web sockets for Django 3
* Add use_async option to cookiecutter.json * Add websocket configuration
This commit is contained in:
parent
0c36c57f2d
commit
aee2de347b
|
@ -44,6 +44,7 @@
|
|||
"SparkPost",
|
||||
"Other SMTP"
|
||||
],
|
||||
"use_async": "n",
|
||||
"use_drf": "n",
|
||||
"custom_bootstrap_compilation": "n",
|
||||
"use_compressor": "n",
|
||||
|
|
|
@ -83,6 +83,9 @@ mail_service:
|
|||
8. SparkPost_
|
||||
9. `Other SMTP`_
|
||||
|
||||
use_async:
|
||||
Indicates whether the project should use web sockets with Uvicorn + Gunicorn.
|
||||
|
||||
use_drf:
|
||||
Indicates whether the project should be configured to use `Django Rest Framework`_.
|
||||
|
||||
|
|
|
@ -101,6 +101,15 @@ def remove_celery_files():
|
|||
os.remove(file_name)
|
||||
|
||||
|
||||
def remove_async_files():
|
||||
file_names = [
|
||||
os.path.join("config", "asgi.py"),
|
||||
os.path.join("config", "websocket.py"),
|
||||
]
|
||||
for file_name in file_names:
|
||||
os.remove(file_name)
|
||||
|
||||
|
||||
def remove_dottravisyml_file():
|
||||
os.remove(".travis.yml")
|
||||
|
||||
|
@ -367,6 +376,9 @@ def main():
|
|||
if "{{ cookiecutter.use_drf }}".lower() == "n":
|
||||
remove_drf_starter_files()
|
||||
|
||||
if "{{ cookiecutter.use_async }}".lower() == "n":
|
||||
remove_async_files()
|
||||
|
||||
print(SUCCESS + "Project initialized, keep up the good work!" + TERMINATOR)
|
||||
|
||||
|
||||
|
|
|
@ -73,6 +73,8 @@ SUPPORTED_COMBINATIONS = [
|
|||
{"cloud_provider": "GCP", "mail_service": "SparkPost"},
|
||||
{"cloud_provider": "GCP", "mail_service": "Other SMTP"},
|
||||
# Note: cloud_providers GCP and None with mail_service Amazon SES is not supported
|
||||
{"use_async", "y"},
|
||||
{"use_async", "n"},
|
||||
{"use_drf": "y"},
|
||||
{"use_drf": "n"},
|
||||
{"js_task_runner": "None"},
|
||||
|
|
|
@ -6,4 +6,8 @@ set -o nounset
|
|||
|
||||
|
||||
python manage.py migrate
|
||||
{%- if cookiecutter.use_async %}
|
||||
/usr/local/bin/uvicorn config.asgi --bind 0.0.0.0:5000 --chdir=/app
|
||||
{%- else %}
|
||||
python manage.py runserver_plus 0.0.0.0:8000
|
||||
{% endif %}
|
||||
|
|
|
@ -27,4 +27,8 @@ if compress_enabled; then
|
|||
python /app/manage.py compress
|
||||
fi
|
||||
{%- endif %}
|
||||
{% if cookiecutter.use_async %}
|
||||
/usr/local/bin/uvicorn config.asgi --bind 0.0.0.0:5000 --chdir=/app
|
||||
{% else %}
|
||||
/usr/local/bin/gunicorn config.wsgi --bind 0.0.0.0:5000 --chdir=/app
|
||||
{%- endif %}
|
||||
|
|
41
{{cookiecutter.project_slug}}/config/asgi.py
Normal file
41
{{cookiecutter.project_slug}}/config/asgi.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
"""
|
||||
ASGI config for {{ cookiecutter.project_name }} project.
|
||||
|
||||
It exposes the ASGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/dev/howto/deployment/asgi/
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from django.core.asgi import get_asgi_application
|
||||
from .websocket import websocket_application
|
||||
|
||||
# This allows easy placement of apps within the interior
|
||||
# {{ cookiecutter.project_slug }} directory.
|
||||
app_path = Path(__file__).parents[1].resolve()
|
||||
sys.path.append(str(app_path / "{{ cookiecutter.project_slug }}"))
|
||||
# We defer to a DJANGO_SETTINGS_MODULE already in the environment. This breaks
|
||||
# if running multiple sites in the same mod_wsgi process. To fix this, use
|
||||
# mod_wsgi daemon mode with each site in its own daemon process, or use
|
||||
# os.environ["DJANGO_SETTINGS_MODULE"] = "config.settings.production"
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings.production")
|
||||
|
||||
# This application object is used by any ASGI server configured to use this
|
||||
# file. This includes Django's development server, if the ASGI_APPLICATION
|
||||
# setting points here.
|
||||
django_application = get_asgi_application()
|
||||
# Apply ASGI middleware here.
|
||||
# from helloworld.asgi import HelloWorldApplication
|
||||
# application = HelloWorldApplication(application)
|
||||
|
||||
|
||||
async def application(scope, receive, send):
|
||||
if scope['type'] == 'http':
|
||||
await django_application(scope, receive, send)
|
||||
elif scope['type'] == 'websocket':
|
||||
await websocket_application(scope, receive, send)
|
||||
else:
|
||||
raise NotImplementedError(f"Unknown scope type {scope['type']}")
|
18
{{cookiecutter.project_slug}}/config/websocket.py
Normal file
18
{{cookiecutter.project_slug}}/config/websocket.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
async def websocket_application(scope, receive, send):
|
||||
while True:
|
||||
event = await receive()
|
||||
|
||||
if event['type'] == 'websocket.connect':
|
||||
await send({
|
||||
'type': 'websocket.accept'
|
||||
})
|
||||
|
||||
if event['type'] == 'websocket.disconnect':
|
||||
break
|
||||
|
||||
if event['type'] == 'websocket.receive':
|
||||
if event['text'] == 'ping':
|
||||
await send({
|
||||
'type': 'websocket.send',
|
||||
'text': 'pong!'
|
||||
})
|
|
@ -16,6 +16,9 @@ django-celery-beat==2.0.0 # https://github.com/celery/django-celery-beat
|
|||
flower==0.9.3 # https://github.com/mher/flower
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
{%- if cookiecutter.use_async %}
|
||||
uvicorn==0.11.3 # https://github.com/encode/uvicorn
|
||||
{%- endif %}
|
||||
|
||||
# Django
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue
Block a user