Commit b6bfae1d authored by Crowdbotics's avatar Crowdbotics
Browse files

Initial commit.

parents
Pipeline #14 failed with stages
in 0 seconds
Showing with 929 additions and 0 deletions
+929 -0
version: 2.1
setup: true
orbs:
continuation: circleci/continuation@0.1.0
jobs:
setup:
executor: continuation/default
steps:
- checkout
- run:
name: Generate Pipeline generated_config.yml file
command: |
bash .circleci/generate_gcp_config.sh
- continuation/continue:
parameters: '{}'
configuration_path: configs/generated_config.yml
workflows:
setup-workflow:
jobs:
- setup
\ No newline at end of file
#!/bin/bash
set -o pipefail
BACKEND_PATH=$1
mkdir configs/
cat << EOF > configs/generated_config.yml
version: 2.1
orbs:
cloudrun: circleci/gcp-cloud-run@1.0.2
executors:
my-executor:
docker:
- image: 'cimg/base:stable'
jobs:
build_and_deploy:
executor: my-executor
steps:
- checkout
- cloudrun/init
- cloudrun/build:
tag: 'gcr.io/${GOOGLE_PROJECT_ID}/${GOOGLE_SERVICE_NAME}'
source: "$BACKEND_PATH"
- run:
name: Run collectstatic and migrations
command: |
gcloud builds submit --config "$BACKEND_PATH.cloudbuild/migrate_collectstatic.yaml" \
--substitutions _INSTANCE_NAME=${GOOGLE_PROJECT_ID},_REGION=${GOOGLE_REGION},_SERVICE_NAME=${GOOGLE_PROJECT_ID}
- run:
name: Deploy to CloudRun
command: |
gcloud run deploy ${GOOGLE_PROJECT_ID} --platform managed --region ${GOOGLE_REGION} \
--image gcr.io/${GOOGLE_PROJECT_ID}/${GOOGLE_SERVICE_NAME} \
--add-cloudsql-instances ${GOOGLE_PROJECT_ID}:${GOOGLE_REGION}:${GOOGLE_PROJECT_ID} \
--allow-unauthenticated
echo "Service Deployed"
GET_GCP_DEPLOY_ENDPOINT=\$(gcloud beta run services describe ${GOOGLE_SERVICE_NAME} --platform managed --region ${GOOGLE_REGION} --format="value(status.address.url)")
echo "export GCP_DEPLOY_ENDPOINT=\$GET_GCP_DEPLOY_ENDPOINT" >> \$BASH_ENV
source \$BASH_ENV
echo \$GCP_DEPLOY_ENDPOINT
- run:
name: Webhook Success
command: bash "$BACKEND_PATH.circleci/webhook_callback.sh" "success"
when: on_success
- run:
name: Webhook Failed
command: bash "$BACKEND_PATH.circleci/webhook_callback.sh" "failure"
when: on_fail
dns_mapping:
executor: my-executor
steps:
- cloudrun/init
- run:
name: Check DNS Mapping
command: |
gcloud beta run domain-mappings describe --region ${GOOGLE_REGION} --domain ${GOOGLE_PROJECT_ID}-gcp.botics.co --format="json" | jq -r '.spec.routeName' |grep ${GOOGLE_PROJECT_ID}
- run:
name: Enable DNS Mapping
command: |
gcloud beta run domain-mappings create --region=${GOOGLE_REGION} --service=${GOOGLE_PROJECT_ID} --domain=${GOOGLE_PROJECT_ID}-gcp.botics.co --project=${GOOGLE_PROJECT_ID}
when: on_fail
workflows:
build_and_deploy_to_managed_workflow:
jobs:
- build_and_deploy
- dns_mapping:
requires:
- build_and_deploy
EOF
\ No newline at end of file
url="https://$WEBHOOK_HOSTNAME/api/v1/github-repos/$PROJECT_ID/circleci_webhook/"
payload=$(
cat <<EOM
{
"status": "$1",
"job": "$CIRCLE_JOB",
"build_num": "$CIRCLE_BUILD_NUM",
"repo": "$CIRCLE_REPOSITORY_URL",
"branch": "$CIRCLE_BRANCH",
"build_url": "$CIRCLE_BUILD_URL",
"sha1": "$CIRCLE_SHA1",
"platform_id": "$PLATFORM_ID",
"app_url": "$GCP_DEPLOY_ENDPOINT"
}
EOM
)
curl -X POST -H "Content-Type: application/json" -H "Authorization: Api-Key $WEBHOOK_API_KEY" --data "$payload" $url
echo "Webhook call completed"
\ No newline at end of file
steps:
- id: "collect static"
name: "gcr.io/google-appengine/exec-wrapper"
args:
[
"-i",
"gcr.io/$PROJECT_ID/${_SERVICE_NAME}",
"-s",
"${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME}",
"-e",
"SETTINGS_NAME=${_SECRET_SETTINGS_NAME}",
"--",
"python3",
"manage.py",
"collectstatic",
"--verbosity",
"2",
"--no-input",
]
- id: "apply migrations"
name: "gcr.io/google-appengine/exec-wrapper"
args:
[
"-i",
"gcr.io/$PROJECT_ID/${_SERVICE_NAME}",
"-s",
"${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME}",
"-e",
"SETTINGS_NAME=${_SECRET_SETTINGS_NAME}",
"--",
"python3",
"manage.py",
"migrate",
]
images:
- "gcr.io/${PROJECT_ID}/${_SERVICE_NAME}"
substitutions:
_INSTANCE_NAME: django-instance
_REGION: us-east4
_SERVICE_NAME: service-name
_SECRET_SETTINGS_NAME: django_settings
\ No newline at end of file
postgres-data/
.env
*.pyc
*.db
*.css.map
.sass-cache
.vagrant
.git
.DS_Store
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
nosetests.xml
coverage.xml
*,cover
# Translations
*.pot
# Django stuff:
*.log
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Docker
Dockerfile
docker-compose.yml
docker-compose.override.yml
docker/docker-compose.prod.yml
# JetBrains
.idea/
\ No newline at end of file
# In order to get .env approach working, you might copy this file. This file is read
# line by line by django-environ library (Refer to its documentation to more info).
# Each line is formed by KEY=VALUE where `KEY` is the configuration read by the
# settings.py file. You need to change the values after the `=` sign and can create
# new values by appending new variables at the end of the file.
DEBUG=1
HOST=localhost
PORT=8000
DATABASE_URL=postgres://postgres:<postgres_pwd>@postgres:5432/postgres
REDIS_URL=redis://redis:6379
SECRET_KEY=<random_string_goes_here>
\ No newline at end of file
.terraform
staticfiles/
postgres-data/
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Translations
*.pot
# Django stuff:
*.log
local_settings.py
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
notebooks
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# dotenv
.env
# virtualenv
.venv
venv/
ENV/
myvenv/
\ No newline at end of file
FROM crowdbotics/cb-django:3.8-slim-buster AS build
# Copy dependency management files and install app packages to /.venv
COPY ./Pipfile ./Pipfile.lock /
RUN PIPENV_VENV_IN_PROJECT=1 pipenv install --deploy
FROM crowdbotics/cb-django:3.8-slim-buster AS release
ARG SECRET_KEY
# Set Working directory
WORKDIR /opt/webapp
# Add runtime user with respective access permissions
RUN groupadd -r django \
&& useradd -d /opt/webapp -r -g django django \
&& chown django:django -R /opt/webapp
USER django
# Copy virtual env from build stage
COPY --chown=django:django --from=build /.venv /.venv
ENV PATH="/.venv/bin:$PATH"
# Copy app source
COPY --chown=django:django . .
# Collect static files and serve app
RUN python3 manage.py collectstatic --no-input
CMD waitress-serve --port=$PORT django_app_01_14.wsgi:application
[[source]]
verify_ssl = true
url = "https://pypi.org/simple"
name = "pypi"
[dev-packages]
[requires]
python_version = "3.8"
[packages]
cryptography = "~=37.0.4"
django = "~=2.2.26"
"boto3" = "~=1.26.8"
django-environ = "~=0.9.0"
django-storages = "~=1.12"
psycopg2 = "<2.9"
waitress = "~=2.1.2"
whitenoise = "~=6.0.0"
djangorestframework = "~=3.13.1"
django-bootstrap4 = "~=22.1"
django-allauth = "~=0.51.0"
django-rest-auth = "~=0.9.5"
django-extensions = "~=3.1.5"
packaging = "*"
pyyaml = "~=6.0"
pillow = "~=9.2.0"
pytest = "==7.1.3"
factory-boy = "==3.2.1"
google-cloud-secret-manager = "==2.12.6"
google-auth = "==2.12.0"
google-cloud-storage = "==2.5.0"
pipenv = "*"
django-import-export = "*"
drf-spectacular = "~=0.24.2"
This diff is collapsed.
# django_app_01_14
This is a repository for a web application developed with Django, built with [Crowdbotics](https://crowdbotics.com)
## Table of Contents
1. [Project Structure](#project-structure)
2. [Features](#features)
3. [Getting Started: Backend](#getting-started-backend)
- [Docker Setup (recommended)](#docker-setup-recommended)
- [Local Setup](#local-setup-alternative-to-docker)
4. [Usage](#usage)
- [Admin Panel](#admin-panel)
- [API Documentation](#api-documentation)
## Project Structure
..
├── home # Starter home app
├── modules # Crowdbotics Modules app
├── django_app_01_14 # Django project configurations
├── static # Static assets
├── users # Starter users app
├── web_build # React Native Web build
├── ...
├── README.md
└── ...
## Features
1. **Local Authentication** using email and password with [allauth](https://pypi.org/project/django-allauth/)
2. **Rest API** using [django rest framework](http://www.django-rest-framework.org/)
3. **Forgot Password**
4. [Bootstrap4](https://getbootstrap.com/docs/4.0/getting-started/introduction/)
5. Toast Notification
6. Inline content editor in homepage
# Getting Started: Backend
Following are instructions on setting up your development environment.
The recommended way for running the project locally and for development is using Docker.
It's possible to also run the project without Docker.
## Docker Setup (Recommended)
This project is set up to run using [Docker Compose](https://docs.docker.com/compose/) by default. It is the recommended way. You can also use existing Docker Compose files as basis for custom deployment, e.g. [Docker Swarm](https://docs.docker.com/engine/swarm/), [kubernetes](https://kubernetes.io/), etc.
1. Install Docker:
- Linux - [get.docker.com](https://get.docker.com/)
- Windows or MacOS - [Docker Desktop](https://www.docker.com/products/docker-desktop)
1. Clone this repo and `cd django_app_01_14`
1. Make sure `Pipfile.lock` exists. If it doesn't, generate it with:
```sh
$ docker run -it --rm -v "$PWD":/django -w /django python:3.7 pip3 install --no-cache-dir -q pipenv && pipenv lock
```
1. Use `.env.example` to create `.env`:
```sh
$ cp .env.example .env
```
1. Update `.env` and `docker-compose.override.yml` replacing all `<placeholders>`
1. Use `python -c 'from secrets import token_urlsafe; print("SECRET_KEY=" + token_urlsafe(50))'` to generate the random `SECRET_KEY`
1. Start up the containers:
```sh
$ docker-compose up
```
This will build the necessary containers and start them, including the web server on the host and port you specified in `.env`.
Current (project) directory will be mapped with the container meaning any edits you make will be picked up by the container.
1. Seed the Postgres DB (in a separate terminal):
```sh
$ docker-compose exec web python3 manage.py makemigrations
$ docker-compose exec web python3 manage.py migrate
```
1. Create a superuser if required:
```sh
$ docker-compose exec web python3 manage.py createsuperuser
```
You will find an activation link in the server log output.
## Local Setup (Alternative to Docker)
1. [Postgresql](https://www.postgresql.org/download/)
2. [Python](https://www.python.org/downloads/release/python-365/)
### Installation
1. Install [pipenv](https://pypi.org/project/pipenv/)
2. Clone this repo and `cd django_app_01_14`
3. Run `pip install --user --upgrade pipenv` to get the latest pipenv version.
4. Run `pipenv --python 3.8`
5. Run `pipenv install`
6. Run `cp .env.example .env`
7. Update .env file `DATABASE_URL` with your `database_name`, `database_user`, `database_password`, if you use postgresql.
Can alternatively set it to `sqlite:////tmp/my-tmp-sqlite.db`, if you want to use sqlite for local development.
### Getting Started
1. Run `pipenv shell`
2. Run `python manage.py makemigrations`
3. Run `python manage.py migrate`
4. Run `python manage.py runserver`
# Usage
## Admin Panel
Admin Panel can be accessed through http://localhost:8000/admin/. If you are the Project Owner, admin credentials can be generated from App > Settings on [Crowdbotics App Dashboard](https://app.crowdbotics.com/). If not, please request your PM or Project Owner to generate admin credentials and share with you.
## API Documentation
API Documentation is generated automatically and can be access through http://localhost:8000/api-docs/. Please make sure you are signed in to the admin panel before navigating to this page.
"""
Django settings for django_app_01_14 project.
Generated by 'django-admin startproject' using Django 2.2.2.
For more information on this file, see
https://docs.djangoproject.com/en/2.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.2/ref/settings/
"""
import os
import io
import environ
import logging
import json
import base64
import binascii
import google.auth
from google.oauth2 import service_account
from google.cloud import secretmanager
from google.auth.exceptions import DefaultCredentialsError
from google.api_core.exceptions import PermissionDenied
from modules.manifest import get_modules
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
env_file = os.path.join(BASE_DIR, ".env")
env = environ.Env()
env.read_env(env_file)
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env.bool("DEBUG", default=False)
try:
# Pull secrets from Secret Manager
_, project = google.auth.default()
client = secretmanager.SecretManagerServiceClient()
settings_name = os.environ.get("SETTINGS_NAME", "django_settings")
name = client.secret_version_path(project, settings_name, "latest")
payload = client.access_secret_version(name=name).payload.data.decode("UTF-8")
env.read_env(io.StringIO(payload))
except (DefaultCredentialsError, PermissionDenied):
pass
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env.str("SECRET_KEY")
ALLOWED_HOSTS = env.list("HOST", default=["*"])
SITE_ID = 1
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_SSL_REDIRECT = env.bool("SECURE_REDIRECT", default=False)
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites'
]
LOCAL_APPS = [
'home',
'users.apps.UsersConfig',
]
THIRD_PARTY_APPS = [
'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'rest_auth.registration',
'bootstrap4',
'allauth',
'allauth.account',
'allauth.socialaccount',
'allauth.socialaccount.providers.google',
'django_extensions',
'drf_spectacular',
'storages',
'import_export',
]
MODULES_APPS = get_modules()
INSTALLED_APPS += LOCAL_APPS + THIRD_PARTY_APPS + MODULES_APPS
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'django_app_01_14.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'django_app_01_14.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
if env.str("DATABASE_URL", default=None):
DATABASES = {
'default': env.db()
}
# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
STATIC_URL = '/static/'
MIDDLEWARE += ['whitenoise.middleware.WhiteNoiseMiddleware']
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend'
)
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
MEDIA_URL = '/mediafiles/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'mediafiles')
# allauth / users
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_EMAIL_VERIFICATION = "optional"
ACCOUNT_CONFIRM_EMAIL_ON_GET = True
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True
ACCOUNT_UNIQUE_EMAIL = True
LOGIN_REDIRECT_URL = "users:redirect"
ACCOUNT_ADAPTER = "users.adapters.AccountAdapter"
SOCIALACCOUNT_ADAPTER = "users.adapters.SocialAccountAdapter"
ACCOUNT_ALLOW_REGISTRATION = env.bool("ACCOUNT_ALLOW_REGISTRATION", True)
SOCIALACCOUNT_ALLOW_REGISTRATION = env.bool("SOCIALACCOUNT_ALLOW_REGISTRATION", True)
REST_AUTH_SERIALIZERS = {
# Replace password reset serializer to fix 500 error
"PASSWORD_RESET_SERIALIZER": "home.api.v1.serializers.PasswordSerializer",
}
REST_AUTH_REGISTER_SERIALIZERS = {
# Use custom serializer that has no username and matches web signup
"REGISTER_SERIALIZER": "home.api.v1.serializers.SignupSerializer",
}
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}
# Custom user model
AUTH_USER_MODEL = "users.User"
EMAIL_HOST = env.str("EMAIL_HOST", "smtp.sendgrid.net")
EMAIL_HOST_USER = env.str("SENDGRID_USERNAME", "")
EMAIL_HOST_PASSWORD = env.str("SENDGRID_PASSWORD", "")
EMAIL_PORT = 587
EMAIL_USE_TLS = True
# AWS S3 config
AWS_ACCESS_KEY_ID = env.str("AWS_ACCESS_KEY_ID", "")
AWS_SECRET_ACCESS_KEY = env.str("AWS_SECRET_ACCESS_KEY", "")
AWS_STORAGE_BUCKET_NAME = env.str("AWS_STORAGE_BUCKET_NAME", "")
AWS_STORAGE_REGION = env.str("AWS_STORAGE_REGION", "")
USE_S3 = (
AWS_ACCESS_KEY_ID and
AWS_SECRET_ACCESS_KEY and
AWS_STORAGE_BUCKET_NAME and
AWS_STORAGE_REGION
)
if USE_S3:
AWS_S3_CUSTOM_DOMAIN = env.str("AWS_S3_CUSTOM_DOMAIN", "")
AWS_S3_OBJECT_PARAMETERS = {"CacheControl": "max-age=86400"}
AWS_DEFAULT_ACL = env.str("AWS_DEFAULT_ACL", "public-read")
AWS_MEDIA_LOCATION = env.str("AWS_MEDIA_LOCATION", "media")
AWS_AUTO_CREATE_BUCKET = env.bool("AWS_AUTO_CREATE_BUCKET", True)
DEFAULT_FILE_STORAGE = env.str(
"DEFAULT_FILE_STORAGE", "home.storage_backends.MediaStorage"
)
SPECTACULAR_SETTINGS = {
# available SwaggerUI configuration parameters
# https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/
"SWAGGER_UI_SETTINGS": {
"deepLinking": True,
"persistAuthorization": True,
"displayOperationId": True,
},
"SERVE_PERMISSIONS": ["rest_framework.permissions.IsAuthenticated"],\
"TITLE": "django_app_01_14 API",
"DESCRIPTION": "API documentation for django_app_01_14 App",
"VERSION": "v1",
}
if DEBUG or not (EMAIL_HOST_USER and EMAIL_HOST_PASSWORD):
# output email to console instead of sending
if not DEBUG:
logging.warning("You should setup `SENDGRID_USERNAME` and `SENDGRID_PASSWORD` env vars to send emails.")
EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
# GCP config
def google_service_account_config():
# base64 encoded service_account.json file
service_account_config = env.str("GS_CREDENTIALS", "")
if not service_account_config:
return {}
try:
return json.loads(base64.b64decode(service_account_config))
except (binascii.Error, ValueError):
return {}
GOOGLE_SERVICE_ACCOUNT_CONFIG = google_service_account_config()
if GOOGLE_SERVICE_ACCOUNT_CONFIG:
GS_CREDENTIALS = service_account.Credentials.from_service_account_info(GOOGLE_SERVICE_ACCOUNT_CONFIG)
GS_BUCKET_NAME = env.str("GS_BUCKET_NAME", "")
if GS_BUCKET_NAME:
DEFAULT_FILE_STORAGE = "storages.backends.gcloud.GoogleCloudStorage"
STATICFILES_STORAGE = "storages.backends.gcloud.GoogleCloudStorage"
GS_DEFAULT_ACL = "publicRead"
"""django_app_01_14 URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include, re_path
from django.views.generic.base import TemplateView
from allauth.account.views import confirm_email
from rest_framework import permissions
from drf_spectacular.views import SpectacularJSONAPIView, SpectacularSwaggerView
urlpatterns = [
path("", include("home.urls")),
path("accounts/", include("allauth.urls")),
path("modules/", include("modules.urls")),
path("api/v1/", include("home.api.v1.urls")),
path("admin/", admin.site.urls),
path("users/", include("users.urls", namespace="users")),
path("rest-auth/", include("rest_auth.urls")),
# Override email confirm to use allauth's HTML view instead of rest_auth's API view
path("rest-auth/registration/account-confirm-email/<str:key>/", confirm_email),
path("rest-auth/registration/", include("rest_auth.registration.urls")),
]
admin.site.site_header = "django app 01"
admin.site.site_title = "django app 01 Admin Portal"
admin.site.index_title = "django app 01 Admin"
# swagger
urlpatterns += [
path("api-docs/schema/", SpectacularJSONAPIView.as_view(), name="schema"),
path("api-docs/", SpectacularSwaggerView.as_view(url_name='schema'), name="api_docs")
]
"""
WSGI config for django_app_01_14 project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_app_01_14.settings')
application = get_wsgi_application()
version: "3.9"
services:
web:
build:
context: .
args:
SECRET_KEY: ${SECRET_KEY}
env_file: .env
volumes:
- ./:/opt/webapp
ports:
- "8000:${PORT}"
postgres:
environment:
POSTGRES_PASSWORD: <postgres_pwd>
volumes:
- postgres-data:/var/lib/postgresql/data
ports:
- "5432:5432"
redis:
ports:
- "6379:6379"
volumes:
postgres-data:
version: "3"
services:
web:
depends_on:
- postgres
- redis
postgres:
image: postgres:12
redis:
image: redis:5
build:
docker:
web: Dockerfile
config:
DEBUG_COLLECTSTATIC: 1
SECRET_KEY: build
release:
image: web
command:
- python3 manage.py migrate
from django.contrib import admin
# Register your models here.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment