Add initial structure

This commit is contained in:
saqibur 2022-01-25 09:15:53 +06:00
parent b04381451e
commit fcacdcfe8f
58 changed files with 1561 additions and 2 deletions

154
.gitignore vendored Normal file
View File

@ -0,0 +1,154 @@
# Current Project Ignores
config/settings/local.py
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# 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/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
.idea/
# Visual Studio Code
.vscode

227
README.md
View File

@ -1,3 +1,226 @@
# Django REST Starter Template
A template for getting started with django rest framework projects
# Django Project Structure
This is a template/project structure for developing django-based applications -
either strictly through the `django-rest-framework` or just `django`.
The project is meant to be easily clonable, and used as the starter template for
the next big thing your team develops.
First, we'll define the scope of today's discussion.
We're here to talk about a long-standing project structure - not best practices. We'll deal with those later.
However, a lot of these decisions we're based on some accepted best practices. I'll be listing all my reference material at the presentation.
Additionally, I will not be taking questions or discussions today. Instead I ask that everyone takes detailed notes, and raises issues in the GitHub repository, and offers their contributions there. While I understand this adds extra steps for suggestions, it also serves as a place to concretely discuss improvements and offer detailed suggestions and examples in written form instead of verbal assumptions.
## Debugging and Tooling
* Add Silk
* Add Django Debug Toolbar
## Coding Style:
* https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/
## Instructions:
* Should we add a note for when we add new imports?
# Design Principles
* Each application should be designed in a way to be pluggable - dragged and
dropped into any other project and it'll still work independently.
# Code Checking
* We'll use mypy for static type checking
# Code Formatting
* We'll use black as our auto-formatter
# Testing
* We'll use pytest for testing
Disclaimer: I don't have 10 years of experience, nor do I have access to people
with 10 years of experience. What I do have is good reference material - books,
conferences, and documentation. These people are smarter than me, they are better
developers and they have more experience - I'm somewhat collecting and presenting
what they do.
Mani na
# Starting
Defining the scope of our projects
We need a project structure that is;
- Homogeneous across strativ applications
- Can be used to build Django Rest APIs and also support Django Templates
- We're limiting ourselves strictly to Django because there are developer
expectations - for instance, if you're a Django developer, you'll expect the
project to have a settings.py, a manage.py, etc.
What this allows -
When anyone visits this project, they are provided with a high-level view of the
project. We've found that this allows us to work easily with other developers
and even non-developers.
Please observe the following:
➤ We like to place all our API components into a package within an app called api/.
That allows us to isolate our API components in a consistent location. If we were to
put it in the root of our app, then we would end up with a huge list of API-specific
modules in the general area of the app.
➤ Viewsets belong in their own module.
➤ We always place routers in urls.py. Either at the app or project level, routers belong
in urls.py.
REST Framework Decisions:
For projects with a lot of small, interconnecting apps, it can be hard to hunt
down where a particular API view lives. In contrast to placing all API code
within each relevant app, sometimes it makes more sense to build an app
specifically for the API. This is where all the serializers, renderers, and views
are placed. Therefore, the name of the app should reflect its API version (see
Section 17.3.7: Version Your API).
For example, we might place all our views, serializers, and other API
components in an app titled apiv4. The downside is the possibility for the API
app to become too large and disconnected from the apps that power it. Hence we
consider an alternative in the next subsection.
# Zen of Python
```
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
```
## Git Ignore
https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
Git Ignore:
We're gonna follow ->
https://github.com/github/gitignore/blob/main/Python.gitignore
With or without the nuclear option.
https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
## Tree
```
│ .gitignore
│ Dockerfile
│ entrypoint.sh
│ manage.py
│ nginx.conf
│ README.md
├───app
│ │ admin.py
│ │ apps.py
│ │ models.py
│ │ urls.py
│ │ utils.py
│ │ __init__.py
│ │
│ ├───api
│ │ │ __init__.py
│ │ │
│ │ ├───v1
│ │ │ serializers.py
│ │ │ tests.py
│ │ │ urls.py
│ │ │ views.py
│ │ │ viewsets.py
│ │ │ __init__.py
│ │ │
│ │ └───v2
│ │ serializers.py
│ │ tests.py
│ │ urls.py
│ │ views.py
│ │ viewsets.py
│ │ __init__.py
│ │
│ ├───management
│ │ commands.py
│ │ __init__.py
│ │
│ ├───migrations
│ │ __init__.py
│ │
│ └───templates
├───config
│ │ asgi.py
│ │ settings.py
│ │ urls.py
│ │ wsgi.py
│ │ __init__.py
│ │
│ └───settings
│ base.py
│ development.py
│ local.py
│ local_template.py
│ production.py
├───core
│ │ admin.py
│ │ apps.py
│ │ models.py
│ │ tests.py
│ │ views.py
│ │ __init__.py
│ │
│ └───migrations
__init__.py
├───docs
│ CHANGELOG.md
│ CONTRIBUTING.md
│ LOCAL_DEVELOPMENT.md
│ PRODUCTION_DEPLOYMENT.md
│ swagger.yaml
├───requirements
│ common.txt
│ development.txt
│ local.txt
│ production.txt
├───static
└───templates
```
## References
Two Scoops of Django by Daniel and Audrey Feldroy
Where to Write Business Logic:
* https://stackoverflow.com/questions/57387711/django-rest-framework-where-to-write-complex-logic-in-serializer-py-or-views-py
Django Best Practices:
* https://django-best-practices.readthedocs.io/en/latest/index.html
Reference:
* https://github.com/cookiecutter/cookiecutter-django
## TODO
* Add versioning for swagger documentation - https://editor.swagger.io/

0
apps/app/__init__.py Normal file
View File

3
apps/app/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

0
apps/app/api/__init__.py Normal file
View File

View File

View File

3
apps/app/api/v1/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

0
apps/app/api/v1/urls.py Normal file
View File

0
apps/app/api/v1/views.py Normal file
View File

View File

View File

0
apps/app/api/v2/tests.py Normal file
View File

0
apps/app/api/v2/urls.py Normal file
View File

2
apps/app/api/v2/views.py Normal file
View File

@ -0,0 +1,2 @@
APIView
def does one thing

6
apps/app/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class AppConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'app'

View File

View File

View File

3
apps/app/models.py Normal file
View File

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

0
apps/app/urls.py Normal file
View File

0
apps/app/utils.py Normal file
View File

0
apps/app/views.py Normal file
View File

View File

3
apps/second_app/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
apps/second_app/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class CoreConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'second_app'

View File

View File

@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

3
apps/second_app/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

3
apps/second_app/views.py Normal file
View File

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

0
config/__init__.py Normal file
View File

16
config/asgi.py Normal file
View File

@ -0,0 +1,16 @@
"""
ASGI config for config 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/4.0/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
application = get_asgi_application()

123
config/settings.py Normal file
View File

@ -0,0 +1,123 @@
"""
Django settings for config project.
Generated by 'django-admin startproject' using Django 4.0.1.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.0/ref/settings/
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-$227hjjmuq2e!)o^@2&#2v#+(-=@$v362o@8g#s9!2)tjn1)1a'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
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 = 'config.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 = 'config.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/4.0/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/4.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

View File

109
config/settings/base.py Normal file
View File

@ -0,0 +1,109 @@
"""
Django settings for config project.
Generated by 'django-admin startproject' using Django 4.0.1.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.0/ref/settings/
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-$227hjjmuq2e!)o^@2&#2v#+(-=@$v362o@8g#s9!2)tjn1)1a'
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
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 = 'config.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 = 'config.wsgi.application'
# Password validation
# https://docs.djangoproject.com/en/4.0/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/4.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

View File

@ -0,0 +1,14 @@
from .base import *
DEBUG = True
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'DB_NAME',
'USER': 'DB_USER',
'PASSWORD': 'DB_PASS',
'HOST': 'DB_HOST',
'PORT': '5432',
}
}

14
config/settings/local.py Normal file
View File

@ -0,0 +1,14 @@
from .base import *
DEBUG = True
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'DB_NAME',
'USER': 'DB_USER',
'PASSWORD': 'DB_PASS',
'HOST': 'DB_HOST',
'PORT': '5432',
}
}

View File

@ -0,0 +1,14 @@
from .base import *
DEBUG = True
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'DB_NAME',
'USER': 'DB_USER',
'PASSWORD': 'DB_PASS',
'HOST': 'DB_HOST',
'PORT': '5432',
}
}

View File

@ -0,0 +1,12 @@
from .base import *
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'DB_NAME',
'USER': 'DB_USER',
'PASSWORD': 'DB_PASS',
'HOST': 'DB_HOST',
'PORT': '5432',
}
}

21
config/urls.py Normal file
View File

@ -0,0 +1,21 @@
"""config URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.0/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
urlpatterns = [
path('admin/', admin.site.urls),
]

16
config/wsgi.py Normal file
View File

@ -0,0 +1,16 @@
"""
WSGI config for config 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/4.0/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
application = get_wsgi_application()

22
deployments/.env.example Normal file
View File

@ -0,0 +1,22 @@
# README
# 1. No spaces before or after `=`.
# 2. Don't use quotations around strings, they're counted as strings by default.
# 3. Change values according to your environment.
# 4. Docker will automatically take all values from this file automatically.
# 5. If values exist in the environment, it will not take values from this file.
# 6. Rename this file from `.env.example` to `.env`
SECRET_KEY=django-insecure-$227hjjmuq2e!)o^@2&#2v#+(-=@$v362o@8g#s9!2)tjn1)1a
DEBUG=True
ALLOWED_HOSTS=*
ENV_NAME=DEV
DB_HOST=localhost
DB_PORT=5432
DB_NAME=example_db
DB_USERNAME=postgres
DB_PASSWORD=12345678
# Super user
SUPERUSER_EMAIL=superuser@example.com

View File

View File

View File

View File

View File

@ -0,0 +1,33 @@
# Gunicorn server
upstream django {
server domain.com:9000;
}
# Redirect all requests on the www subdomain to the root domain
server {
listen 80;
server_name www.domain.com;
rewrite ^/(.*) http://domain.com/$1 permanent;
}
# Serve static files and redirect any other request to Gunicorn
server {
listen 80;
server_name domain.com;
root /var/www/domain.com/;
access_log /var/log/nginx/domain.com.access.log;
error_log /var/log/nginx/domain.com.error.log;
# Check if a file exists at /var/www/domain/ for the incoming request.
# If it doesn't proxy to Gunicorn/Django.
try_files $uri @django;
# Setup named location for Django requests and handle proxy details
location @django {
proxy_pass http://django;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

0
docs/CHANGELOG.md Normal file
View File

0
docs/CONTRIBUTING.md Normal file
View File

0
docs/deployment.md Normal file
View File

View File

728
docs/swagger.yaml Normal file
View File

@ -0,0 +1,728 @@
openapi: 3.0.1
info:
title: Swagger Petstore
description: 'This is a sample server Petstore server. You can find out more about Swagger
at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For
this sample, you can use the api key `special-key` to test the authorization filters.'
termsOfService: http://swagger.io/terms/
contact:
email: apiteam@swagger.io
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
version: 1.0.0
externalDocs:
description: Find out more about Swagger
url: http://swagger.io
servers:
- url: https://petstore.swagger.io/v2
- url: http://petstore.swagger.io/v2
tags:
- name: pet
description: Everything about your Pets
externalDocs:
description: Find out more
url: http://swagger.io
- name: store
description: Access to Petstore orders
- name: user
description: Operations about user
externalDocs:
description: Find out more about our store
url: http://swagger.io
paths:
/pet:
put:
tags:
- pet
summary: Update an existing pet
operationId: updatePet
requestBody:
description: Pet object that needs to be added to the store
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/Pet'
required: true
responses:
400:
description: Invalid ID supplied
content: {}
404:
description: Pet not found
content: {}
405:
description: Validation exception
content: {}
security:
- petstore_auth:
- write:pets
- read:pets
x-codegen-request-body-name: body
post:
tags:
- pet
summary: Add a new pet to the store
operationId: addPet
requestBody:
description: Pet object that needs to be added to the store
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/Pet'
required: true
responses:
405:
description: Invalid input
content: {}
security:
- petstore_auth:
- write:pets
- read:pets
x-codegen-request-body-name: body
/pet/findByStatus:
get:
tags:
- pet
summary: Finds Pets by status
description: Multiple status values can be provided with comma separated strings
operationId: findPetsByStatus
parameters:
- name: status
in: query
description: Status values that need to be considered for filter
required: true
style: form
explode: true
schema:
type: array
items:
type: string
default: available
enum:
- available
- pending
- sold
responses:
200:
description: successful operation
content:
application/xml:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
400:
description: Invalid status value
content: {}
security:
- petstore_auth:
- write:pets
- read:pets
/pet/findByTags:
get:
tags:
- pet
summary: Finds Pets by tags
description: Muliple tags can be provided with comma separated strings. Use tag1,
tag2, tag3 for testing.
operationId: findPetsByTags
parameters:
- name: tags
in: query
description: Tags to filter by
required: true
style: form
explode: true
schema:
type: array
items:
type: string
responses:
200:
description: successful operation
content:
application/xml:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
400:
description: Invalid tag value
content: {}
deprecated: true
security:
- petstore_auth:
- write:pets
- read:pets
/pet/{petId}:
get:
tags:
- pet
summary: Find pet by ID
description: Returns a single pet
operationId: getPetById
parameters:
- name: petId
in: path
description: ID of pet to return
required: true
schema:
type: integer
format: int64
responses:
200:
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/json:
schema:
$ref: '#/components/schemas/Pet'
400:
description: Invalid ID supplied
content: {}
404:
description: Pet not found
content: {}
security:
- api_key: []
post:
tags:
- pet
summary: Updates a pet in the store with form data
operationId: updatePetWithForm
parameters:
- name: petId
in: path
description: ID of pet that needs to be updated
required: true
schema:
type: integer
format: int64
requestBody:
content:
application/x-www-form-urlencoded:
schema:
properties:
name:
type: string
description: Updated name of the pet
status:
type: string
description: Updated status of the pet
responses:
405:
description: Invalid input
content: {}
security:
- petstore_auth:
- write:pets
- read:pets
delete:
tags:
- pet
summary: Deletes a pet
operationId: deletePet
parameters:
- name: api_key
in: header
schema:
type: string
- name: petId
in: path
description: Pet id to delete
required: true
schema:
type: integer
format: int64
responses:
400:
description: Invalid ID supplied
content: {}
404:
description: Pet not found
content: {}
security:
- petstore_auth:
- write:pets
- read:pets
/pet/{petId}/uploadImage:
post:
tags:
- pet
summary: uploads an image
operationId: uploadFile
parameters:
- name: petId
in: path
description: ID of pet to update
required: true
schema:
type: integer
format: int64
requestBody:
content:
multipart/form-data:
schema:
properties:
additionalMetadata:
type: string
description: Additional data to pass to server
file:
type: string
description: file to upload
format: binary
responses:
200:
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
security:
- petstore_auth:
- write:pets
- read:pets
/store/inventory:
get:
tags:
- store
summary: Returns pet inventories by status
description: Returns a map of status codes to quantities
operationId: getInventory
responses:
200:
description: successful operation
content:
application/json:
schema:
type: object
additionalProperties:
type: integer
format: int32
security:
- api_key: []
/store/order:
post:
tags:
- store
summary: Place an order for a pet
operationId: placeOrder
requestBody:
description: order placed for purchasing the pet
content:
'*/*':
schema:
$ref: '#/components/schemas/Order'
required: true
responses:
200:
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Order'
application/json:
schema:
$ref: '#/components/schemas/Order'
400:
description: Invalid Order
content: {}
x-codegen-request-body-name: body
/store/order/{orderId}:
get:
tags:
- store
summary: Find purchase order by ID
description: For valid response try integer IDs with value >= 1 and <= 10. Other
values will generated exceptions
operationId: getOrderById
parameters:
- name: orderId
in: path
description: ID of pet that needs to be fetched
required: true
schema:
maximum: 10.0
minimum: 1.0
type: integer
format: int64
responses:
200:
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Order'
application/json:
schema:
$ref: '#/components/schemas/Order'
400:
description: Invalid ID supplied
content: {}
404:
description: Order not found
content: {}
delete:
tags:
- store
summary: Delete purchase order by ID
description: For valid response try integer IDs with positive integer value. Negative
or non-integer values will generate API errors
operationId: deleteOrder
parameters:
- name: orderId
in: path
description: ID of the order that needs to be deleted
required: true
schema:
minimum: 1.0
type: integer
format: int64
responses:
400:
description: Invalid ID supplied
content: {}
404:
description: Order not found
content: {}
/user:
post:
tags:
- user
summary: Create user
description: This can only be done by the logged in user.
operationId: createUser
requestBody:
description: Created user object
content:
'*/*':
schema:
$ref: '#/components/schemas/User'
required: true
responses:
default:
description: successful operation
content: {}
x-codegen-request-body-name: body
/user/createWithArray:
post:
tags:
- user
summary: Creates list of users with given input array
operationId: createUsersWithArrayInput
requestBody:
description: List of user object
content:
'*/*':
schema:
type: array
items:
$ref: '#/components/schemas/User'
required: true
responses:
default:
description: successful operation
content: {}
x-codegen-request-body-name: body
/user/createWithList:
post:
tags:
- user
summary: Creates list of users with given input array
operationId: createUsersWithListInput
requestBody:
description: List of user object
content:
'*/*':
schema:
type: array
items:
$ref: '#/components/schemas/User'
required: true
responses:
default:
description: successful operation
content: {}
x-codegen-request-body-name: body
/user/login:
get:
tags:
- user
summary: Logs user into the system
operationId: loginUser
parameters:
- name: username
in: query
description: The user name for login
required: true
schema:
type: string
- name: password
in: query
description: The password for login in clear text
required: true
schema:
type: string
responses:
200:
description: successful operation
headers:
X-Rate-Limit:
description: calls per hour allowed by the user
schema:
type: integer
format: int32
X-Expires-After:
description: date in UTC when token expires
schema:
type: string
format: date-time
content:
application/xml:
schema:
type: string
application/json:
schema:
type: string
400:
description: Invalid username/password supplied
content: {}
/user/logout:
get:
tags:
- user
summary: Logs out current logged in user session
operationId: logoutUser
responses:
default:
description: successful operation
content: {}
/user/{username}:
get:
tags:
- user
summary: Get user by user name
operationId: getUserByName
parameters:
- name: username
in: path
description: 'The name that needs to be fetched. Use user1 for testing. '
required: true
schema:
type: string
responses:
200:
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/User'
application/json:
schema:
$ref: '#/components/schemas/User'
400:
description: Invalid username supplied
content: {}
404:
description: User not found
content: {}
put:
tags:
- user
summary: Updated user
description: This can only be done by the logged in user.
operationId: updateUser
parameters:
- name: username
in: path
description: name that need to be updated
required: true
schema:
type: string
requestBody:
description: Updated user object
content:
'*/*':
schema:
$ref: '#/components/schemas/User'
required: true
responses:
400:
description: Invalid user supplied
content: {}
404:
description: User not found
content: {}
x-codegen-request-body-name: body
delete:
tags:
- user
summary: Delete user
description: This can only be done by the logged in user.
operationId: deleteUser
parameters:
- name: username
in: path
description: The name that needs to be deleted
required: true
schema:
type: string
responses:
400:
description: Invalid username supplied
content: {}
404:
description: User not found
content: {}
components:
schemas:
Order:
type: object
properties:
id:
type: integer
format: int64
petId:
type: integer
format: int64
quantity:
type: integer
format: int32
shipDate:
type: string
format: date-time
status:
type: string
description: Order Status
enum:
- placed
- approved
- delivered
complete:
type: boolean
default: false
xml:
name: Order
Category:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
xml:
name: Category
User:
type: object
properties:
id:
type: integer
format: int64
username:
type: string
firstName:
type: string
lastName:
type: string
email:
type: string
password:
type: string
phone:
type: string
userStatus:
type: integer
description: User Status
format: int32
xml:
name: User
Tag:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
xml:
name: Tag
Pet:
required:
- name
- photoUrls
type: object
properties:
id:
type: integer
format: int64
category:
$ref: '#/components/schemas/Category'
name:
type: string
example: doggie
photoUrls:
type: array
xml:
name: photoUrl
wrapped: true
items:
type: string
tags:
type: array
xml:
name: tag
wrapped: true
items:
$ref: '#/components/schemas/Tag'
status:
type: string
description: pet status in the store
enum:
- available
- pending
- sold
xml:
name: Pet
ApiResponse:
type: object
properties:
code:
type: integer
format: int32
type:
type: string
message:
type: string
securitySchemes:
petstore_auth:
type: oauth2
flows:
implicit:
authorizationUrl: http://petstore.swagger.io/oauth/dialog
scopes:
write:pets: modify pets in your account
read:pets: read your pets
api_key:
type: apiKey
name: api_key
in: header

22
manage.py Normal file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

0
pytest.ini Normal file
View File

0
requirements/common.txt Normal file
View File

View File

@ -0,0 +1 @@
-r common.txt

1
requirements/local.txt Normal file
View File

@ -0,0 +1 @@
-r common.txt

View File

@ -0,0 +1 @@
-r common.txt