├── myproject ├── core │ ├── __init__.py │ ├── migrations │ │ └── __init__.py │ ├── models.py │ ├── admin.py │ ├── tests.py │ ├── apps.py │ ├── urls.py │ ├── views.py │ ├── tasks.py │ ├── templates │ │ ├── includes │ │ │ └── nav.html │ │ ├── base.html │ │ └── index.html │ └── static │ │ └── js │ │ └── bootstrap-notify.min.js ├── __init__.py ├── wsgi.py ├── celery.py ├── urls.py └── settings.py ├── Dockerfile ├── config └── nginx │ └── app.conf ├── manage.py ├── requirements.txt ├── contrib └── env_gen.py ├── docker-compose.yml ├── README.md └── .gitignore /myproject/core/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /myproject/core/migrations/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /myproject/core/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /myproject/__init__.py: -------------------------------------------------------------------------------- 1 | from .celery import app as celery_app 2 | 3 | __all__ = ['celery_app'] 4 | -------------------------------------------------------------------------------- /myproject/core/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /myproject/core/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /myproject/core/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CoreConfig(AppConfig): 5 | name = 'myproject.core' 6 | -------------------------------------------------------------------------------- /myproject/core/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import path 2 | 3 | from myproject.core import views as v 4 | 5 | app_name = 'core' 6 | 7 | 8 | urlpatterns = [ 9 | path('', v.index, name='index'), 10 | path('task/print_numbers/', v.run_task, name='run_task'), 11 | ] 12 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.12-slim 2 | 3 | ENV PYTHONUNBUFFERED 1 4 | ENV DJANGO_ENV dev 5 | ENV DOCKER_CONTAINER 1 6 | 7 | RUN mkdir /app 8 | WORKDIR /app 9 | EXPOSE 8000 10 | 11 | ADD requirements.txt . 12 | RUN pip install -U pip && pip install -r requirements.txt 13 | 14 | COPY .env . 15 | COPY manage.py . 16 | COPY myproject myproject 17 | 18 | RUN python manage.py collectstatic --noinput 19 | # CMD gunicorn myproject.wsgi:application -b 0.0.0.0:8000 20 | -------------------------------------------------------------------------------- /myproject/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for myproject project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from dj_static import Cling 13 | from django.core.wsgi import get_wsgi_application 14 | 15 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings') 16 | 17 | application = Cling(get_wsgi_application()) 18 | -------------------------------------------------------------------------------- /config/nginx/app.conf: -------------------------------------------------------------------------------- 1 | # define group app 2 | upstream app { 3 | # define server app 4 | server app:8000; 5 | } 6 | 7 | # server 8 | server { 9 | listen 8000; 10 | 11 | client_max_body_size 50M; 12 | 13 | # domain localhost 14 | 15 | server_name localhost; 16 | charset utf-8; 17 | 18 | # Handle favicon.ico 19 | location = /favicon.ico { 20 | return 204; 21 | access_log off; 22 | log_not_found off; 23 | } 24 | 25 | # Django app 26 | location / { 27 | proxy_pass http://app; 28 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 29 | proxy_set_header Host $host; 30 | proxy_redirect off; 31 | } 32 | } -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings') 9 | try: 10 | from django.core.management import execute_from_command_line 11 | except ImportError as exc: 12 | raise ImportError( 13 | "Couldn't import Django. Are you sure it's installed and " 14 | "available on your PYTHONPATH environment variable? Did you " 15 | "forget to activate a virtual environment?" 16 | ) from exc 17 | execute_from_command_line(sys.argv) 18 | 19 | 20 | if __name__ == '__main__': 21 | main() 22 | -------------------------------------------------------------------------------- /myproject/celery.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import, unicode_literals 2 | 3 | import logging 4 | import os 5 | 6 | from celery import Celery 7 | 8 | # from django.conf import settings 9 | 10 | logger = logging.getLogger("Celery") 11 | 12 | # set the default Django settings module for the 'celery' program. 13 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings') 14 | 15 | app = Celery('myproject') 16 | 17 | app.config_from_object('django.conf:settings', namespace='CELERY') 18 | 19 | # app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) 20 | app.autodiscover_tasks() 21 | 22 | 23 | @app.task(bind=True, ignore_result=True) 24 | def debug_task(self): 25 | print(f'Request: {self.request!r}') 26 | -------------------------------------------------------------------------------- /myproject/core/views.py: -------------------------------------------------------------------------------- 1 | from decouple import config 2 | from django.http import HttpResponseRedirect 3 | from django.shortcuts import render 4 | from django.urls import reverse 5 | from django_celery_results.models import TaskResult 6 | 7 | from .tasks import print_numbers 8 | 9 | 10 | def index(request): 11 | template_name = 'index.html' 12 | object_list = TaskResult.objects.all() 13 | my_key = config('KEY') 14 | cluster = config('CLUSTER') 15 | context = { 16 | 'object_list': object_list, 17 | 'my_key': my_key, 18 | 'cluster': cluster, 19 | } 20 | return render(request, template_name, context) 21 | 22 | 23 | def run_task(request): 24 | print_numbers.delay(10) 25 | url = 'core:index' 26 | return HttpResponseRedirect(reverse(url)) 27 | -------------------------------------------------------------------------------- /myproject/core/tasks.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import pusher 4 | from celery import shared_task 5 | from celery.utils.log import get_task_logger 6 | from decouple import config 7 | 8 | logger = get_task_logger(__name__) 9 | 10 | 11 | channels_client = pusher.Pusher( 12 | app_id=config('APP_ID'), 13 | key=config('KEY'), 14 | secret=config('SECRET'), 15 | cluster=config('CLUSTER'), 16 | ssl=True 17 | ) 18 | 19 | 20 | @shared_task(queue='fila1') 21 | def print_numbers(max_number): 22 | logger.info('Creating the task..') 23 | 24 | _sec = 3 25 | logger.info('Aguardar {} seg'.format(_sec)) 26 | time.sleep(_sec) 27 | for i in range(max_number): 28 | logger.info(i) 29 | 30 | logger.info('Finishing task..') 31 | channels_client.trigger( 32 | 'my-channel', 'my-event', 33 | {'message': 'Finalizada com sucesso!'} 34 | ) 35 | return True 36 | -------------------------------------------------------------------------------- /myproject/urls.py: -------------------------------------------------------------------------------- 1 | """myproject URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.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 | """ 16 | from django.contrib import admin 17 | from django.urls import include, path 18 | 19 | urlpatterns = [ 20 | path('', include('myproject.core.urls')), 21 | path('admin/', admin.site.urls), 22 | ] 23 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | amqp==5.3.1 2 | asgiref==3.8.1 3 | billiard==4.2.1 4 | celery==5.4.0 5 | certifi==2024.8.30 6 | cffi==1.17.1 7 | charset-normalizer==3.4.0 8 | click==8.1.7 9 | click-didyoumean==0.3.1 10 | click-plugins==1.1.1 11 | click-repl==0.3.0 12 | cryptography==44.0.0 13 | dj-database-url==2.3.0 14 | dj-static==0.0.6 15 | Django==5.1.4 16 | django-celery-results==2.5.1 17 | django-extensions==3.2.3 18 | flower==2.0.1 19 | gunicorn==23.0.0 20 | humanize==4.11.0 21 | idna==3.10 22 | kombu==5.4.2 23 | ndg-httpsclient==0.5.1 24 | packaging==24.2 25 | prometheus_client==0.21.1 26 | prompt_toolkit==3.0.48 27 | psycopg2-binary==2.9.10 28 | pusher==3.3.2 29 | pyasn1==0.6.1 30 | pycparser==2.22 31 | PyNaCl==1.5.0 32 | pyOpenSSL==24.3.0 33 | python-dateutil==2.9.0.post0 34 | python-decouple==3.8 35 | pytz==2024.2 36 | redis==5.2.1 37 | requests==2.32.3 38 | six==1.17.0 39 | sqlparse==0.5.2 40 | static3==0.7.0 41 | tornado==6.4.2 42 | typing_extensions==4.12.2 43 | tzdata==2024.2 44 | urllib3==2.2.3 45 | vine==5.1.0 46 | wcwidth==0.2.13 47 | -------------------------------------------------------------------------------- /myproject/core/templates/includes/nav.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /contrib/env_gen.py: -------------------------------------------------------------------------------- 1 | """ 2 | Python SECRET_KEY generator. 3 | """ 4 | import random 5 | 6 | chars = "abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!?@#$%^&*()" 7 | size = 50 8 | secret_key = "".join(random.sample(chars, size)) 9 | 10 | chars = "abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!?@#$%_" 11 | size = 20 12 | password = "".join(random.sample(chars, size)) 13 | 14 | CONFIG_STRING = """ 15 | DEBUG=True 16 | SECRET_KEY=%s 17 | ALLOWED_HOSTS=127.0.0.1,.localhost,0.0.0.0 18 | 19 | #DATABASE_URL=postgres://USER:PASSWORD@HOST:PORT/NAME 20 | POSTGRES_DB=django_celery_db 21 | POSTGRES_USER=postgres 22 | POSTGRES_PASSWORD=postgres 23 | #DB_HOST=localhost 24 | 25 | #DEFAULT_FROM_EMAIL= 26 | #EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend 27 | #EMAIL_HOST=localhost 28 | #EMAIL_PORT= 29 | #EMAIL_HOST_USER= 30 | #EMAIL_HOST_PASSWORD= 31 | #EMAIL_USE_TLS=True 32 | 33 | #Pusher 34 | APP_ID= 35 | KEY= 36 | SECRET= 37 | CLUSTER= 38 | """.strip() % (secret_key, password) 39 | 40 | # Writing our configuration file to '.env' 41 | with open('.env', 'w') as configfile: 42 | configfile.write(CONFIG_STRING) 43 | 44 | print('Success!') 45 | print('Type: cat .env') 46 | -------------------------------------------------------------------------------- /myproject/core/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | {% load static %} 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 |