Skip to content

Commit 5e19f70

Browse files
authored
Merge pull request #3 from testdrivenio/features/update-course
update django celery course
2 parents 4e8cd7c + 7790bb9 commit 5e19f70

33 files changed

+380
-271
lines changed

compose/auto_deploy_do.sh

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
# This shell script quickly deploys your project to your
44
# DigitalOcean Droplet
55

6+
if [ -z "$DIGITAL_OCEAN_IP_ADDRESS" ]
7+
then
8+
echo "DIGITAL_OCEAN_IP_ADDRESS not defined"
9+
exit 0
10+
fi
11+
612
# generate TAR file from git
713
git archive --format tar --output ./project.tar master
814

compose/local/django/celery/worker/start

+1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
set -o errexit
44
set -o nounset
55

6+
# celery -A django_celery_example worker -l INFO
67
python manage.py celery_worker

compose/production/django/celery/flower/start

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ celery -A django_celery_example \
1717
--broker="${CELERY_BROKER}" \
1818
flower \
1919
--basic_auth="${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}" \
20-
--persistent=1 --db=/app/flower_db/flower.db --state_save_interval=5000
20+
--persistent=1 --db=/app/flower_db/flower.db --state_save_interval=5000

compose/production/nginx/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM nginx:1.19-alpine
1+
FROM nginx:1.21-alpine
22

33
RUN rm /etc/nginx/conf.d/default.conf
44
COPY nginx.conf /etc/nginx/conf.d

django_celery_example/__init__.py

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from __future__ import absolute_import, unicode_literals
2-
31
# This will make sure the app is always imported when
42
# Django starts so that shared_task will use this app.
53
from .celery import app as celery_app

django_celery_example/asgi.py

+12-9
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
1+
"""
2+
ASGI config for django_celery_example project.
3+
4+
It exposes the ASGI callable as a module-level variable named ``application``.
5+
6+
For more information on this file, see
7+
https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/
8+
"""
9+
10+
111
import os
212

3-
import django
4-
from asgiref.compatibility import guarantee_single_callable
513
from channels.routing import ProtocolTypeRouter, URLRouter
6-
from django.conf import settings
14+
from django.core.asgi import get_asgi_application
715

816
from polls import routing
917

10-
1118
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_celery_example.settings')
12-
django.setup()
1319

1420
application = ProtocolTypeRouter({
21+
"http": get_asgi_application(),
1522
'websocket': URLRouter(
1623
routing.urlpatterns
1724
)
1825
})
19-
20-
if not settings.DEBUG:
21-
# https://github.com/django/channels/issues/1319
22-
application = guarantee_single_callable(application)

django_celery_example/celery.py

+5-10
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
"""
2-
Celery config file
3-
42
https://docs.celeryproject.org/en/stable/django/first-steps-with-django.html
5-
63
"""
7-
from __future__ import absolute_import
8-
import logging
94
import os
10-
import time
11-
5+
import logging
126
from celery import Celery
137
from celery.signals import after_setup_logger
148

@@ -18,23 +12,24 @@
1812
# set the default Django settings module for the 'celery' app.
1913
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_celery_example.settings')
2014

21-
# you change change the name here
15+
# you can change the name here
2216
app = Celery("django_celery_example")
2317

2418
# read config from Django settings, the CELERY namespace would make celery
2519
# config keys has `CELERY` prefix
2620
app.config_from_object('django.conf:settings', namespace='CELERY')
2721

28-
# load tasks.py in django apps
22+
# discover and load tasks.py in django apps
2923
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
3024

3125

3226
@app.task
33-
def add(x, y):
27+
def divide(x, y):
3428
# from celery.contrib import rdb
3529
# rdb.set_trace()
3630

3731
# this is for test purposes
32+
import time
3833
time.sleep(10)
3934
return x / y
4035

django_celery_example/settings.py

+15-13
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,28 @@
11
"""
22
Django settings for django_celery_example project.
33
4-
Generated by 'django-admin startproject' using Django 3.1.4.
4+
Generated by 'django-admin startproject' using Django 3.2.9.
55
66
For more information on this file, see
7-
https://docs.djangoproject.com/en/3.1/topics/settings/
7+
https://docs.djangoproject.com/en/3.2/topics/settings/
88
99
For the full list of settings and their values, see
10-
https://docs.djangoproject.com/en/3.1/ref/settings/
10+
https://docs.djangoproject.com/en/3.2/ref/settings/
1111
"""
12-
1312
import os
14-
from pathlib import Path
1513

14+
from pathlib import Path
1615
from kombu import Queue
1716

1817
# Build paths inside the project like this: BASE_DIR / 'subdir'.
1918
BASE_DIR = Path(__file__).resolve().parent.parent
2019

2120

2221
# Quick-start development settings - unsuitable for production
23-
# See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/
22+
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
2423

25-
# SECURITY WARNING: keep the secret key used in production secret!
2624
SECRET_KEY = os.environ.get("SECRET_KEY", "&nl8s430j^j8l*je+m&ys5dv#zoy)0a2+x1!m8hx290_sx&0gh")
2725

28-
# SECURITY WARNING: don't run with debug turned on in production!
2926
DEBUG = int(os.environ.get("DEBUG", default=1))
3027

3128
ALLOWED_HOSTS = os.environ.get("DJANGO_ALLOWED_HOSTS", "127.0.0.1").split(" ")
@@ -40,9 +37,9 @@
4037
'django.contrib.sessions',
4138
'django.contrib.messages',
4239
'django.contrib.staticfiles',
43-
'polls',
4440
'channels',
4541
'django_celery_beat',
42+
'polls',
4643
'tdd',
4744
]
4845

@@ -79,7 +76,7 @@
7976

8077

8178
# Database
82-
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases
79+
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
8380

8481
DATABASES = {
8582
"default": {
@@ -94,7 +91,7 @@
9491

9592

9693
# Password validation
97-
# https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators
94+
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
9895

9996
AUTH_PASSWORD_VALIDATORS = [
10097
{
@@ -113,7 +110,7 @@
113110

114111

115112
# Internationalization
116-
# https://docs.djangoproject.com/en/3.1/topics/i18n/
113+
# https://docs.djangoproject.com/en/3.2/topics/i18n/
117114

118115
LANGUAGE_CODE = 'en-us'
119116

@@ -127,11 +124,16 @@
127124

128125

129126
# Static files (CSS, JavaScript, Images)
130-
# https://docs.djangoproject.com/en/3.1/howto/static-files/
127+
# https://docs.djangoproject.com/en/3.2/howto/static-files/
131128

132129
STATIC_URL = '/static/'
133130
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
134131

132+
# Default primary key field type
133+
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
134+
135+
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
136+
135137
MEDIA_URL = '/media/'
136138
MEDIA_ROOT = os.path.join(BASE_DIR, 'mediafiles')
137139

django_celery_example/urls.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
1+
"""django_celery_example URL Configuration
2+
3+
The `urlpatterns` list routes URLs to views. For more information please see:
4+
https://docs.djangoproject.com/en/3.2/topics/http/urls/
5+
Examples:
6+
Function views
7+
1. Add an import: from my_app import views
8+
2. Add a URL to urlpatterns: path('', views.home, name='home')
9+
Class-based views
10+
1. Add an import: from other_app.views import Home
11+
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
12+
Including another URLconf
13+
1. Import the include() function: from django.urls import include, path
14+
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15+
"""
116
from django.contrib import admin
217
from django.urls import path, include
318

419

520
urlpatterns = [
621
path('admin/', admin.site.urls),
722
path("member/", include('tdd.urls')),
8-
path("", include('polls.urls')),
23+
path('', include('polls.urls')),
924
]

django_celery_example/wsgi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
It exposes the WSGI callable as a module-level variable named ``application``.
55
66
For more information on this file, see
7-
https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/
7+
https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/
88
"""
99

1010
import os

docker-compose.prod.yml

+5-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ services:
99
- mediafiles:/app/mediafiles
1010
ports:
1111
- 80:80
12-
- 5559:5555
12+
- 5555:5555
1313
- 15672:15672
1414
depends_on:
1515
- web
@@ -30,7 +30,7 @@ services:
3030
- db
3131

3232
db:
33-
image: postgres:12.0-alpine
33+
image: postgres:14-alpine
3434
volumes:
3535
- postgres_data:/var/lib/postgresql/data/
3636
environment:
@@ -39,10 +39,10 @@ services:
3939
- POSTGRES_PASSWORD=hello_django
4040

4141
redis:
42-
image: redis:5-alpine
42+
image: redis:6-alpine
4343

4444
rabbitmq:
45-
image: rabbitmq:3.8-management
45+
image: rabbitmq:3-management
4646
env_file:
4747
- ./.env/.prod-sample
4848

@@ -92,7 +92,6 @@ services:
9292
- redis
9393
- db
9494

95-
9695
prometheus:
9796
image: prom/prometheus
9897
ports:
@@ -118,4 +117,4 @@ volumes:
118117
postgres_data:
119118
staticfiles:
120119
mediafiles:
121-
flower_db:
120+
flower_db:

docker-compose.yml

+3-8
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ services:
2222
- db
2323

2424
db:
25-
image: postgres:12.0-alpine
25+
image: postgres:14-alpine
2626
volumes:
2727
- postgres_data:/var/lib/postgresql/data/
2828
environment:
@@ -31,19 +31,14 @@ services:
3131
- POSTGRES_PASSWORD=hello_django
3232

3333
redis:
34-
image: redis:5-alpine
34+
image: redis:6-alpine
3535

3636
celery_worker:
3737
build:
3838
context: .
3939
dockerfile: ./compose/local/django/Dockerfile
4040
image: django_celery_example_celery_worker
4141
command: /start-celeryworker
42-
# logging:
43-
# driver: syslog
44-
# options:
45-
# syslog-address: "tcp+tls://logs2.papertrailapp.com:45883"
46-
# tag: "{{.Name}}/{{.ID}}"
4742
volumes:
4843
- .:/app
4944
env_file:
@@ -70,7 +65,7 @@ services:
7065
build:
7166
context: .
7267
dockerfile: ./compose/local/django/Dockerfile
73-
image: django_celery_example_celey_flower
68+
image: django_celery_example_celery_flower
7469
command: /start-flower
7570
volumes:
7671
- .:/app

polls/apps.py

+1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22

33

44
class PollsConfig(AppConfig):
5+
default_auto_field = 'django.db.models.BigAutoField'
56
name = 'polls'

polls/base_task.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66

77
class custom_celery_task:
8-
98
EXCEPTION_BLOCK_LIST = (
109
IndexError,
1110
KeyError,
@@ -15,8 +14,8 @@ class custom_celery_task:
1514
)
1615

1716
def __init__(self, *args, **kwargs):
18-
self.task_args = args
19-
self.task_kwargs = kwargs
17+
self.task_args = args
18+
self.task_kwargs = kwargs
2019

2120
def __call__(self, func):
2221
@functools.wraps(func)

polls/consumers.py

+2-14
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
from asgiref.sync import async_to_sync
44
from channels.layers import get_channel_layer
5-
# from channels.generic.websocket import WebsocketConsumer
65
from channels.generic.websocket import AsyncWebsocketConsumer
76
from celery.result import AsyncResult
87

@@ -50,25 +49,14 @@ async def connect(self):
5049

5150
await self.accept()
5251

52+
await self.send(text_data=json.dumps(get_task_info(self.task_id)))
53+
5354
async def disconnect(self, close_code):
5455
await self.channel_layer.group_discard(
5556
self.task_id,
5657
self.channel_name
5758
)
5859

59-
async def receive(self, text_data):
60-
text_data_json = json.loads(text_data)
61-
task_type = text_data_json['type']
62-
63-
if task_type == 'check_task_status':
64-
await self.channel_layer.group_send(
65-
self.task_id,
66-
{
67-
'type': 'update_task_status',
68-
'data': get_task_info(self.task_id)
69-
}
70-
)
71-
7260
async def update_task_status(self, event):
7361
data = event['data']
7462

0 commit comments

Comments
 (0)