├── .gitignore ├── Dockerfile ├── README.md ├── core ├── __init__.py ├── admin.py ├── api │ ├── __init__.py │ ├── serializers.py │ └── viewsets.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ └── __init__.py ├── models.py ├── tests.py └── views.py ├── docker-compose.yml ├── docs ├── fargate │ ├── application-successful.png │ ├── aws-fargate-get-started.png │ ├── ecr-after-push-image.png │ ├── ecr.png │ ├── fargate-cluster-created.png │ ├── fargate-configure-your-cluster.png │ ├── fargate-define-your-service.png │ ├── fargate-edit-custom-container-step2.png │ ├── fargate-edit-custom-container.png │ ├── fargate-review.png │ ├── server-local-available.png │ ├── server-local.png │ ├── service-details.png │ ├── service-network-details.png │ └── task-details.png └── rds │ ├── connectivity.png │ ├── create-database.png │ ├── database-details-sg.png │ ├── database-details.png │ ├── database-features.png │ ├── databases-list.png │ └── db-security-group-inbound.png ├── manage.py ├── requirements-dev.txt ├── requirements.txt ├── start.sh └── tutorial ├── .env.example ├── __init__.py ├── asgi.py ├── settings.py ├── urls.py └── wsgi.py /.gitignore: -------------------------------------------------------------------------------- 1 | venv 2 | *.sqlite3 3 | .env 4 | .vscode 5 | 6 | __pycache__/ 7 | *.pyo 8 | *.pyc 9 | .DS_Store -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8.1-alpine3.11 2 | 3 | LABEL maintainer="muriloamendola@gmail.com" 4 | 5 | ENV PYTHONUNBUFFERED 1 6 | 7 | RUN mkdir /app 8 | WORKDIR /app 9 | 10 | COPY tutorial ./tutorial 11 | COPY core ./core 12 | COPY requirements-dev.txt . 13 | COPY requirements.txt . 14 | COPY manage.py . 15 | COPY start.sh . 16 | 17 | RUN apk update && apk add postgresql-dev gcc musl-dev 18 | RUN pip install -r requirements.txt 19 | 20 | ENTRYPOINT ./start.sh -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # django-aws-fargate-playground 2 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](#contributing) 3 | 4 | Scalability is an essential software component. Prioritizing it from the start leads to lower maintenance costs, better user experience, and higher agility. 5 | 6 | Thinking in that one of the biggest problem when talking about scalability is the database. 7 | 8 | This project is an study case where we will build a very simple API with Django Rest Framework, which consumes data from a serverless postgres database provided by AWS. Then we will dockerize our app and deploy it in an "production environment" using AWS Fargate. 9 | 10 | ## Requirements 11 | 12 | * Django Rest Framework >= 3.11.0 (powerful and flexible toolkit for building Web APIs) 13 | * AWS Account (You need to have an AWS account to deploy the application and to create the database) 14 | * [Docker](https://www.docker.com/) (We will deploy our app using docker containers for this reason you should know docker concepts to understand how things are working). 15 | 16 | ## Running project locally 17 | 18 | After clone or download this repository you must configure a file called `.env` inside the main folder `tutorial`. As you can see, inside this folder there is a sample file called `.env.example` that you can copy or rename to `.env`. 19 | 20 | This file is where we can configure our environments variables using keys. 21 | 22 | | WARNING: be careful in production environment you must configure this variables using other aproach! | 23 | | --- | 24 | 25 | For running this project locally, just keep the file with two keys: 26 | 27 | ``` 28 | DEBUG=True 29 | SECRET_KEY=${Put same random and unique value here} 30 | ``` 31 | 32 | When you don't configure a `DATABASE_URL` key by default the app will use Sqlite DB Engine. 33 | 34 | After create the `.env` file just run the following command: 35 | 36 | ```bash 37 | docker-compose up 38 | ``` 39 | 40 | If the command was successful your terminal will show: 41 | ![server running locally](./docs/fargate/server-local.png) 42 | 43 | The server will be available on http://0.0.0.0:8800/. 44 | ![server running locally on http://0.0.0.0:8800](./docs/fargate/server-local-available.png) 45 | 46 | ## Running project in AWS 47 | 48 | To create and activate a new AWS Account, please follow the steps covered by this article: [How do I create and activate a new Amazon Web Services account?](https://aws.amazon.com/premiumsupport/knowledge-center/create-and-activate-aws-account/). 49 | 50 | After that is it important to install [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) which will allow us to do changes at our AWS Account from command line. 51 | 52 | Finally, you can [configure your aws credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html). 53 | 54 | ### Creating AWS Fargate Cluster 55 | 56 | To know more about AWS Fargate you should read the oficial [documentation](https://aws.amazon.com/fargate/). 57 | 58 | This chapter will cover the configuration of a AWS Fargate Cluster where we will deploy our application. 59 | 60 | As you have read AWS Fargate is a serverless compute engine for containers so we need to configure the container that will run our application. 61 | 62 | #### Elastic Container Repository (ECR) 63 | 64 | To do this we have created the [Dockerfile](./Dockerfile) that contains the instructions to build a docker image thar can be used to create containeres to run our application. 65 | 66 | We will store this docker image in a Elastic Container Repository (ECR). To create this repository you can run the following command: 67 | 68 | ```bash 69 | aws ecr create-repository --repository-name django-aws-fargate-playground --region us-east-1 70 | ``` 71 | 72 | If the command is successful we should see: 73 | 74 | ```json 75 | { 76 | "repository": { 77 | "repositoryArn": "arn:aws:ecr:us-east-1:${accountId}:repository/django-aws-fargate-playground", 78 | "registryId": "${accountId}", 79 | "repositoryName": "django-aws-fargate-playground", 80 | "repositoryUri": "${accountId}.dkr.ecr.us-east-1.amazonaws.com/django-aws-fargate-playground", 81 | "createdAt": 1550555101.0 82 | } 83 | } 84 | ``` 85 | 86 | In AWS console you will see something like this: 87 | ![ECR Repository](./docs/fargate/ecr.png) 88 | 89 | After click on the repository name you will see all the images inside that repository. Click on `View push commands` to see a list of commands that we need to run to be able to push our image to ECR. Follow the steps as they are given. 90 | 91 | Now we have pushed our image in ECR. 92 | 93 | ![ECR Repository list of images and push commands](./docs/fargate/ecr-after-push-image.png) 94 | 95 | After pushing the image you can see the second column called Image URI (we will use this info to configure the Task container in AWS Fargate). 96 | 97 | ### AWS Fargate 98 | 99 | Now, let us go to the link https://console.aws.amazon.com/ecs/home?region=us-east-1#/getStarted and create a new Fargate Application. Click on `Get Started`. 100 | 101 | Now select under the container definition choose Custom and click on Configure. 102 | ![AWS Fargate configure custom container](./docs/fargate/aws-fargate-get-started.png) 103 | 104 | In the popup, enter a name for the container (django-aws-fargate-playground-container) and add the URL to the container image we have pushed to ECR in the step before. 105 | 106 | ![AWS Fargate custom container configuration](./docs/fargate/fargate-edit-custom-container.png) 107 | ![AWS Fargate custom container creation](./docs/fargate/fargate-edit-custom-container-step2.png) 108 | ![AWS Fargate service definition](./docs/fargate/fargate-define-your-service.png) 109 | ![AWS Fargate cluster definition](./docs/fargate/fargate-configure-your-cluster.png) 110 | ![AWS Fargate cluster review](./docs/fargate/fargate-review.png) 111 | ![AWS Fargate cluster created](./docs/fargate/fargate-cluster-created.png) 112 | 113 | Now we can see the status of the service we just created.After the steps being completed click on `View Service` button. 114 | 115 | Now we can test our fargate cluster. For that on the services page, click on the Tasks tab (as ilustrated in the image below) to see the different tasks running for our application. Click on the task id to see details about that task. 116 | ![AWS Fargate service details](./docs/fargate/service-details.png) 117 | ![AWS Fargate task details](./docs/fargate/task-details.png) 118 | 119 | As you can see a public IP was atributed to our cluster so you can access the application going to the url http://52.91.33.228:8800 120 | ![AWS Fargate application successful](./docs/fargate/application-successful.png) 121 | 122 | A last important point in this topic is about `VPC`. AWS Fargate creates a new VPC, subnets and security group for our cluster. In the next topic we will see how to create Aurora Serverless Database and we have to run this database inside the same VPC of our AWS Fargate Cluster because that is the only way to grant access to the database to our container. 123 | 124 | You can see the VPC created under service details tab: 125 | ![AWS Fargate service details](./docs/fargate/service-network-details.png) 126 | 127 | ### Creating Aurora Serverless Database 128 | 129 | Inside AWS Console go to RDS and create a new Database. 130 | ![AWS RDS create database](./docs/rds/create-database.png) 131 | 132 | We choose postgres compatibility, but, you can choose mysql if you prefer. 133 | 134 | In this project we will use Serveless database to delegate to AWS the responsibility to scale our infrastructure when it is necessary and we will pay only for the effective resources use. 135 | ![AWS RDS database features](./docs/rds/database-features.png) 136 | 137 | And finally the point about VPC that we have commented, don't forget to choose the VPC created by AWS Fargate in the step before. 138 | ![AWS RDS database connectivity](./docs/rds/connectivity.png) 139 | 140 | After that click on Create Database and wait until the creation process ends. 141 | ![AWS RDS database list](./docs/rds/databases-list.png) 142 | 143 | Click on DB Identifier to see database details. Inside this page you will see the instructions to connect to your database. 144 | ![AWS RDS database details](./docs/rds/database-details.png) 145 | 146 | To see the oficial docs about how to connect to an Amazon Aurora DB Cluster access the url: https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.Connecting.html 147 | 148 | Now that we can build the connection string to the database and configure the key `DATABASE_URL` in the .env file, then generate a new docker image with the new version of the application and push to ECR. 149 | 150 | In our case we can build the postgres connection url in the following way: 151 | 152 | ``` 153 | DATABASE_URL=psql://urser:password@host:5432/database_name 154 | ``` 155 | 156 | By default `database_name` is `postgres`. Unless you have specified a different name during the process of database creation. 157 | 158 | After create this key into the file .env, repeat the steps to generate a new image and to push it to ECR repository we have created. You could review the steps [clicking here](https://github.com/muriloamendola/django-aws-fargate-playground#elastic-container-repository-ecr) 159 | 160 | ### Allow container to access the database 161 | 162 | Now we have all the configurations necessary to run our application in AWS, but, we need to allow our container to access the database. 163 | 164 | To do it we need to insert our container security group into the Inbound configuration of the database security group as you can see in the image below: 165 | 166 | ![AWS RDS database details security group](./docs/rds/database-details-sg.png) 167 | ![AWS RDS database details security group](./docs/rds/db-security-group-inbound.png) 168 | 169 | After that your container will have the grants to access the database. 170 | 171 | ## Contributing 172 | 173 | Yes, please! 174 | This project was created just for study and to guide other developers who would like to use this tecnologies. Any other suggestion will be kindly accepted! 175 | 176 | Any doubts or suggestions please contact me muriloamendola@gmail.com. -------------------------------------------------------------------------------- /core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/core/__init__.py -------------------------------------------------------------------------------- /core/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import Client 3 | 4 | admin.site.register(Client) 5 | -------------------------------------------------------------------------------- /core/api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/core/api/__init__.py -------------------------------------------------------------------------------- /core/api/serializers.py: -------------------------------------------------------------------------------- 1 | from rest_framework import serializers 2 | from core.models import Client 3 | 4 | 5 | class ClientSerializer(serializers.ModelSerializer): 6 | class Meta: 7 | model = Client 8 | fields = ('__all__') 9 | -------------------------------------------------------------------------------- /core/api/viewsets.py: -------------------------------------------------------------------------------- 1 | from rest_framework import viewsets 2 | from core.models import Client 3 | from .serializers import ClientSerializer 4 | 5 | 6 | class ClientViewSet(viewsets.ModelViewSet): 7 | """ 8 | API endpoint that allows clients to be viewed or edited. 9 | """ 10 | queryset = Client.objects.all() 11 | serializer_class = ClientSerializer 12 | -------------------------------------------------------------------------------- /core/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CoreConfig(AppConfig): 5 | name = 'core' 6 | -------------------------------------------------------------------------------- /core/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.0.2 on 2020-01-25 15:33 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | initial = True 9 | 10 | dependencies = [ 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='Client', 16 | fields=[ 17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('name', models.CharField(max_length=60)), 19 | ('email', models.EmailField(max_length=100)), 20 | ], 21 | ), 22 | ] 23 | -------------------------------------------------------------------------------- /core/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/core/migrations/__init__.py -------------------------------------------------------------------------------- /core/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | class Client(models.Model): 4 | name = models.CharField(max_length=60) 5 | email = models.EmailField(max_length=100) 6 | 7 | 8 | def __str__(self): 9 | return self.name 10 | -------------------------------------------------------------------------------- /core/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /core/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | drf: 4 | build: . 5 | image: django-aws-fargate-playground 6 | ports: 7 | - "8800:8800" 8 | volumes: 9 | - .:/app 10 | -------------------------------------------------------------------------------- /docs/fargate/application-successful.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/fargate/application-successful.png -------------------------------------------------------------------------------- /docs/fargate/aws-fargate-get-started.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/fargate/aws-fargate-get-started.png -------------------------------------------------------------------------------- /docs/fargate/ecr-after-push-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/fargate/ecr-after-push-image.png -------------------------------------------------------------------------------- /docs/fargate/ecr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/fargate/ecr.png -------------------------------------------------------------------------------- /docs/fargate/fargate-cluster-created.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/fargate/fargate-cluster-created.png -------------------------------------------------------------------------------- /docs/fargate/fargate-configure-your-cluster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/fargate/fargate-configure-your-cluster.png -------------------------------------------------------------------------------- /docs/fargate/fargate-define-your-service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/fargate/fargate-define-your-service.png -------------------------------------------------------------------------------- /docs/fargate/fargate-edit-custom-container-step2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/fargate/fargate-edit-custom-container-step2.png -------------------------------------------------------------------------------- /docs/fargate/fargate-edit-custom-container.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/fargate/fargate-edit-custom-container.png -------------------------------------------------------------------------------- /docs/fargate/fargate-review.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/fargate/fargate-review.png -------------------------------------------------------------------------------- /docs/fargate/server-local-available.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/fargate/server-local-available.png -------------------------------------------------------------------------------- /docs/fargate/server-local.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/fargate/server-local.png -------------------------------------------------------------------------------- /docs/fargate/service-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/fargate/service-details.png -------------------------------------------------------------------------------- /docs/fargate/service-network-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/fargate/service-network-details.png -------------------------------------------------------------------------------- /docs/fargate/task-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/fargate/task-details.png -------------------------------------------------------------------------------- /docs/rds/connectivity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/rds/connectivity.png -------------------------------------------------------------------------------- /docs/rds/create-database.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/rds/create-database.png -------------------------------------------------------------------------------- /docs/rds/database-details-sg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/rds/database-details-sg.png -------------------------------------------------------------------------------- /docs/rds/database-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/rds/database-details.png -------------------------------------------------------------------------------- /docs/rds/database-features.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/rds/database-features.png -------------------------------------------------------------------------------- /docs/rds/databases-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/rds/databases-list.png -------------------------------------------------------------------------------- /docs/rds/db-security-group-inbound.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/docs/rds/db-security-group-inbound.png -------------------------------------------------------------------------------- /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', 'tutorial.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 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | asgiref==3.2.3 2 | astroid==2.3.3 3 | Django==3.1.14 4 | django-environ==0.4.5 5 | djangorestframework==3.11.2 6 | isort==4.3.21 7 | lazy-object-proxy==1.4.3 8 | mccabe==0.6.1 9 | pylint==2.4.4 10 | pytz==2019.3 11 | six==1.14.0 12 | sqlparse==0.3.0 13 | wrapt==1.11.2 14 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | -r requirements-dev.txt 2 | psycopg2==2.8.4 -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | python manage.py migrate 4 | echo "from django.contrib.auth.models import User; User.objects.create_superuser('muriloamendola', 'muriloamendola@gmail.com', '123@Changeme')" | python manage.py shell 5 | python manage.py runserver 0.0.0.0:8800 6 | exec "$@" -------------------------------------------------------------------------------- /tutorial/.env.example: -------------------------------------------------------------------------------- 1 | DEBUG=True 2 | SECRET_KEY= 3 | DATABASE_URL=psql://urser:password@host:5432/database_name 4 | -------------------------------------------------------------------------------- /tutorial/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muriloamendola/django-aws-fargate-playground/20de11526656ec1f38a31d1c517cd1f9a7709ed0/tutorial/__init__.py -------------------------------------------------------------------------------- /tutorial/asgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | ASGI config for tutorial 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.0/howto/deployment/asgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.asgi import get_asgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tutorial.settings') 15 | 16 | application = get_asgi_application() 17 | -------------------------------------------------------------------------------- /tutorial/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | import environ 3 | 4 | env = environ.Env() 5 | environ.Env.read_env() 6 | 7 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 8 | 9 | SECRET_KEY = env.str('SECRET_KEY') 10 | 11 | DEBUG = env.bool('DEBUG', default=False) 12 | 13 | ALLOWED_HOSTS = ['*'] 14 | 15 | # Application definition 16 | INSTALLED_APPS = [ 17 | 'django.contrib.admin', 18 | 'django.contrib.auth', 19 | 'django.contrib.contenttypes', 20 | 'django.contrib.sessions', 21 | 'django.contrib.messages', 22 | 'django.contrib.staticfiles', 23 | 'rest_framework', 24 | 'core', 25 | ] 26 | 27 | MIDDLEWARE = [ 28 | 'django.middleware.security.SecurityMiddleware', 29 | 'django.contrib.sessions.middleware.SessionMiddleware', 30 | 'django.middleware.common.CommonMiddleware', 31 | 'django.middleware.csrf.CsrfViewMiddleware', 32 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 33 | 'django.contrib.messages.middleware.MessageMiddleware', 34 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 35 | ] 36 | 37 | ROOT_URLCONF = 'tutorial.urls' 38 | 39 | TEMPLATES = [ 40 | { 41 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 42 | 'DIRS': [], 43 | 'APP_DIRS': True, 44 | 'OPTIONS': { 45 | 'context_processors': [ 46 | 'django.template.context_processors.debug', 47 | 'django.template.context_processors.request', 48 | 'django.contrib.auth.context_processors.auth', 49 | 'django.contrib.messages.context_processors.messages', 50 | ], 51 | }, 52 | }, 53 | ] 54 | 55 | WSGI_APPLICATION = 'tutorial.wsgi.application' 56 | 57 | 58 | # Database 59 | # https://docs.djangoproject.com/en/3.0/ref/settings/#databases 60 | DATABASES = { 61 | 'default': env.db(default='sqlite:///db.sqlite3') 62 | } 63 | 64 | 65 | # Password validation 66 | # https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators 67 | 68 | AUTH_PASSWORD_VALIDATORS = [ 69 | { 70 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 71 | }, 72 | { 73 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 74 | }, 75 | { 76 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 77 | }, 78 | { 79 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 80 | }, 81 | ] 82 | 83 | 84 | # Internationalization 85 | # https://docs.djangoproject.com/en/3.0/topics/i18n/ 86 | 87 | LANGUAGE_CODE = 'en-us' 88 | 89 | TIME_ZONE = 'UTC' 90 | 91 | USE_I18N = True 92 | 93 | USE_L10N = True 94 | 95 | USE_TZ = True 96 | 97 | 98 | # Static files (CSS, JavaScript, Images) 99 | # https://docs.djangoproject.com/en/3.0/howto/static-files/ 100 | 101 | STATIC_URL = '/static/' 102 | -------------------------------------------------------------------------------- /tutorial/urls.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.urls import path, include 3 | from rest_framework import routers 4 | from core.api.viewsets import ClientViewSet 5 | 6 | router = routers.DefaultRouter() 7 | router.register(r'clients', ClientViewSet) 8 | 9 | urlpatterns = [ 10 | path('', include(router.urls)), 11 | path('admin/', admin.site.urls), 12 | ] 13 | -------------------------------------------------------------------------------- /tutorial/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for tutorial 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/3.0/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tutorial.settings') 15 | 16 | application = get_wsgi_application() 17 | --------------------------------------------------------------------------------