New python-fastapi generator (#9611)

* [python-fastapi] Added new generator

See https://fastapi.tiangolo.com/ for more details about FastAPI

Signed-off-by: Nikita Vakula <programmistov.programmist@gmail.com>

* [python-fastapi] Added samples

Signed-off-by: Nikita Vakula <programmistov.programmist@gmail.com>
This commit is contained in:
Nikita Vakula
2021-05-30 11:43:31 +02:00
committed by GitHub
parent dee2840b20
commit 0da4099868
52 changed files with 3483 additions and 0 deletions

View File

@@ -0,0 +1,138 @@
# 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
# 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/

View File

@@ -0,0 +1,23 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md

View File

@@ -0,0 +1,23 @@
.gitignore
Dockerfile
README.md
docker-compose.yaml
openapi.yaml
pyproject.toml
requirements.txt
setup.cfg
src/openapi_server/apis/__init__.py
src/openapi_server/apis/pet_api.py
src/openapi_server/apis/store_api.py
src/openapi_server/apis/user_api.py
src/openapi_server/main.py
src/openapi_server/models/__init__.py
src/openapi_server/models/api_response.py
src/openapi_server/models/category.py
src/openapi_server/models/extra_models.py
src/openapi_server/models/order.py
src/openapi_server/models/pet.py
src/openapi_server/models/tag.py
src/openapi_server/models/user.py
src/openapi_server/security_api.py
tests/conftest.py

View File

@@ -0,0 +1 @@
5.2.0-SNAPSHOT

View File

@@ -0,0 +1,30 @@
FROM python:3.6 AS builder
WORKDIR /usr/src/app
RUN python3 -m venv /venv
ENV PATH="/venv/bin:$PATH"
RUN pip install --upgrade pip
COPY . .
RUN pip install --no-cache-dir .
FROM python:3.6 AS test_runner
WORKDIR /tmp
COPY --from=builder /venv /venv
COPY --from=builder /usr/src/app/tests tests
ENV PATH=/venv/bin:$PATH
# install test dependencies
RUN pip install pytest
# run tests
RUN pytest tests
FROM python:3.6 AS service
WORKDIR /root/app/site-packages
COPY --from=test_runner /venv /venv
ENV PATH=/venv/bin:$PATH

View File

@@ -0,0 +1,29 @@
# OpenAPI generated FastAPI server
This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
- API version: 1.0.0
- Build package: org.openapitools.codegen.languages.PythonFastAPIServerCodegen
## Requirements.
Python >= 3.6
## Installation & Usage
To run the server, please execute the following from the root directory:
```
pip3 install -r requirements.txt
uvicorn main:app --host 0.0.0.0 --port 8080
```
and open your browser at `http://localhost:8080/docs/` to see the docs.
## Running with Docker
To run the server on a Docker container, please execute the following from the root directory:
```bash
docker-compose up --build
```

View File

@@ -0,0 +1,9 @@
version: '3.6'
services:
service:
build:
context: .
target: service
ports:
- "8080:8080"
command: uvicorn openapi_server.main:app --host 0.0.0.0 --port 8080

View File

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

View File

@@ -0,0 +1,30 @@
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
[tool.black]
line-length = 88
exclude = '''
(
/(
\.eggs # exclude a few common directories in the
| \.git # root of the project
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| buck-out
| build
| dist
)/
)
'''
[tool.isort]
profile = "black"
skip = [
'.eggs', '.git', '.hg', '.mypy_cache', '.nox', '.pants.d', '.tox',
'.venv', '_build', 'buck-out', 'build', 'dist', 'node_modules', 'venv',
]
skip_gitignore = true

View File

@@ -0,0 +1,36 @@
aiofiles==0.5.0
aniso8601==7.0.0
async-exit-stack==1.0.1
async-generator==1.10
certifi==2020.12.5
chardet==4.0.0
click==7.1.2
dnspython==2.1.0
email-validator==1.1.2
fastapi==0.65.1
graphene==2.1.8
graphql-core==2.3.2
graphql-relay==2.0.1
h11==0.12.0
httptools==0.1.2
idna==2.10
itsdangerous==1.1.0
Jinja2==2.11.3
MarkupSafe==2.0.1
orjson==3.5.2
promise==2.3
pydantic==1.8.2
python-dotenv==0.17.1
python-multipart==0.0.5
PyYAML==5.4.1
requests==2.25.1
Rx==1.6.1
six==1.16.0
starlette==0.14.2
typing-extensions==3.10.0.0
ujson==4.0.2
urllib3==1.26.4
uvicorn==0.13.4
uvloop==0.14.0
watchgod==0.7
websockets==8.1

View File

@@ -0,0 +1,23 @@
[metadata]
name = openapi_server
version = 1.0.0
description = This is a sample server Petstore server. For this sample, you can use the api key &#x60;special-key&#x60; to test the authorization filters.
long_description = file: README.md
keywords = OpenAPI OpenAPI Petstore
python_requires = >= 3.6.*
classifiers =
Operating System :: OS Independent
Programming Language :: Python :: 3
Programming Language :: Python :: 3.6
[options]
install_requires =
fastapi[all]
setup_requires =
setuptools
package_dir=
=src
packages=find_namespace:
[options.packages.find]
where=src

View File

@@ -0,0 +1,189 @@
# coding: utf-8
from typing import Dict, List
from fastapi import (
APIRouter,
Body,
Cookie,
Depends,
Form,
Header,
Path,
Query,
Response,
Security,
status,
)
from openapi_server.models.extra_models import TokenModel
from openapi_server.models.api_response import ApiResponse
from openapi_server.models.pet import Pet
from openapi_server.security_api import get_token_petstore_auth, get_token_api_key
router = APIRouter()
@router.post(
"/pet",
responses={
200: {"model": Pet, "description": "successful operation"},
405: {"description": "Invalid input"},
},
tags=["pet"],
summary="Add a new pet to the store",
)
async def add_pet(
pet: Pet = Body(None, description="Pet object that needs to be added to the store")
,
token_petstore_auth: TokenModel = Security(
get_token_petstore_auth, scopes=["write:pets", "read:pets"]
),
) -> Pet: # noqa: E501
...
@router.delete(
"/pet/{petId}",
responses={
400: {"description": "Invalid pet value"},
},
tags=["pet"],
summary="Deletes a pet",
)
async def delete_pet(
petId: int = Path(None, description="Pet id to delete")
,
api_key: str = Header(None, description="")
,
token_petstore_auth: TokenModel = Security(
get_token_petstore_auth, scopes=["write:pets", "read:pets"]
),
) -> None: # noqa: E501
...
@router.get(
"/pet/findByStatus",
responses={
200: {"model": List[Pet], "description": "successful operation"},
400: {"description": "Invalid status value"},
},
tags=["pet"],
summary="Finds Pets by status",
)
async def find_pets_by_status(
status: List[str] = Query(None, description="Status values that need to be considered for filter")
,
token_petstore_auth: TokenModel = Security(
get_token_petstore_auth, scopes=["read:pets"]
),
) -> List[Pet]: # noqa: E501
"""Multiple status values can be provided with comma separated strings"""
...
@router.get(
"/pet/findByTags",
responses={
200: {"model": List[Pet], "description": "successful operation"},
400: {"description": "Invalid tag value"},
},
tags=["pet"],
summary="Finds Pets by tags",
)
async def find_pets_by_tags(
tags: List[str] = Query(None, description="Tags to filter by")
,
token_petstore_auth: TokenModel = Security(
get_token_petstore_auth, scopes=["read:pets"]
),
) -> List[Pet]: # noqa: E501
"""Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing."""
...
@router.get(
"/pet/{petId}",
responses={
200: {"model": Pet, "description": "successful operation"},
400: {"description": "Invalid ID supplied"},
404: {"description": "Pet not found"},
},
tags=["pet"],
summary="Find pet by ID",
)
async def get_pet_by_id(
petId: int = Path(None, description="ID of pet to return")
,
token_api_key: TokenModel = Security(
get_token_api_key
),
) -> Pet: # noqa: E501
"""Returns a single pet"""
...
@router.put(
"/pet",
responses={
200: {"model": Pet, "description": "successful operation"},
400: {"description": "Invalid ID supplied"},
404: {"description": "Pet not found"},
405: {"description": "Validation exception"},
},
tags=["pet"],
summary="Update an existing pet",
)
async def update_pet(
pet: Pet = Body(None, description="Pet object that needs to be added to the store")
,
token_petstore_auth: TokenModel = Security(
get_token_petstore_auth, scopes=["write:pets", "read:pets"]
),
) -> Pet: # noqa: E501
...
@router.post(
"/pet/{petId}",
responses={
405: {"description": "Invalid input"},
},
tags=["pet"],
summary="Updates a pet in the store with form data",
)
async def update_pet_with_form(
petId: int = Path(None, description="ID of pet that needs to be updated")
,
name: str = Form(None, description="Updated name of the pet")
,
status: str = Form(None, description="Updated status of the pet")
,
token_petstore_auth: TokenModel = Security(
get_token_petstore_auth, scopes=["write:pets", "read:pets"]
),
) -> None: # noqa: E501
...
@router.post(
"/pet/{petId}/uploadImage",
responses={
200: {"model": ApiResponse, "description": "successful operation"},
},
tags=["pet"],
summary="uploads an image",
)
async def upload_file(
petId: int = Path(None, description="ID of pet to update")
,
additional_metadata: str = Form(None, description="Additional data to pass to server")
,
file: str = Form(None, description="file to upload")
,
token_petstore_auth: TokenModel = Security(
get_token_petstore_auth, scopes=["write:pets", "read:pets"]
),
) -> ApiResponse: # noqa: E501
...

View File

@@ -0,0 +1,91 @@
# coding: utf-8
from typing import Dict, List
from fastapi import (
APIRouter,
Body,
Cookie,
Depends,
Form,
Header,
Path,
Query,
Response,
Security,
status,
)
from openapi_server.models.extra_models import TokenModel
from openapi_server.models.order import Order
from openapi_server.security_api import get_token_api_key
router = APIRouter()
@router.delete(
"/store/order/{orderId}",
responses={
400: {"description": "Invalid ID supplied"},
404: {"description": "Order not found"},
},
tags=["store"],
summary="Delete purchase order by ID",
)
async def delete_order(
orderId: str = Path(None, description="ID of the order that needs to be deleted")
,
) -> None: # noqa: E501
"""For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors"""
...
@router.get(
"/store/inventory",
responses={
200: {"model": Dict[str, int], "description": "successful operation"},
},
tags=["store"],
summary="Returns pet inventories by status",
)
async def get_inventory(
token_api_key: TokenModel = Security(
get_token_api_key
),
) -> Dict[str, int]: # noqa: E501
"""Returns a map of status codes to quantities"""
...
@router.get(
"/store/order/{orderId}",
responses={
200: {"model": Order, "description": "successful operation"},
400: {"description": "Invalid ID supplied"},
404: {"description": "Order not found"},
},
tags=["store"],
summary="Find purchase order by ID",
)
async def get_order_by_id(
orderId: int = Path(None, description="ID of pet that needs to be fetched")
,
) -> Order: # noqa: E501
"""For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generated exceptions"""
...
@router.post(
"/store/order",
responses={
200: {"model": Order, "description": "successful operation"},
400: {"description": "Invalid Order"},
},
tags=["store"],
summary="Place an order for a pet",
)
async def place_order(
order: Order = Body(None, description="order placed for purchasing the pet")
,
) -> Order: # noqa: E501
...

View File

@@ -0,0 +1,171 @@
# coding: utf-8
from typing import Dict, List
from fastapi import (
APIRouter,
Body,
Cookie,
Depends,
Form,
Header,
Path,
Query,
Response,
Security,
status,
)
from openapi_server.models.extra_models import TokenModel
from openapi_server.models.user import User
from openapi_server.security_api import get_token_api_key
router = APIRouter()
@router.post(
"/user",
responses={
200: {"description": "successful operation"},
},
tags=["user"],
summary="Create user",
)
async def create_user(
user: User = Body(None, description="Created user object")
,
token_api_key: TokenModel = Security(
get_token_api_key
),
) -> None: # noqa: E501
"""This can only be done by the logged in user."""
...
@router.post(
"/user/createWithArray",
responses={
200: {"description": "successful operation"},
},
tags=["user"],
summary="Creates list of users with given input array",
)
async def create_users_with_array_input(
user: List[User] = Body(None, description="List of user object")
,
token_api_key: TokenModel = Security(
get_token_api_key
),
) -> None: # noqa: E501
...
@router.post(
"/user/createWithList",
responses={
200: {"description": "successful operation"},
},
tags=["user"],
summary="Creates list of users with given input array",
)
async def create_users_with_list_input(
user: List[User] = Body(None, description="List of user object")
,
token_api_key: TokenModel = Security(
get_token_api_key
),
) -> None: # noqa: E501
...
@router.delete(
"/user/{username}",
responses={
400: {"description": "Invalid username supplied"},
404: {"description": "User not found"},
},
tags=["user"],
summary="Delete user",
)
async def delete_user(
username: str = Path(None, description="The name that needs to be deleted")
,
token_api_key: TokenModel = Security(
get_token_api_key
),
) -> None: # noqa: E501
"""This can only be done by the logged in user."""
...
@router.get(
"/user/{username}",
responses={
200: {"model": User, "description": "successful operation"},
400: {"description": "Invalid username supplied"},
404: {"description": "User not found"},
},
tags=["user"],
summary="Get user by user name",
)
async def get_user_by_name(
username: str = Path(None, description="The name that needs to be fetched. Use user1 for testing.")
,
) -> User: # noqa: E501
...
@router.get(
"/user/login",
responses={
200: {"model": str, "description": "successful operation"},
400: {"description": "Invalid username/password supplied"},
},
tags=["user"],
summary="Logs user into the system",
)
async def login_user(
username: str = Query(None, description="The user name for login")
,
password: str = Query(None, description="The password for login in clear text")
,
) -> str: # noqa: E501
...
@router.get(
"/user/logout",
responses={
200: {"description": "successful operation"},
},
tags=["user"],
summary="Logs out current logged in user session",
)
async def logout_user(
token_api_key: TokenModel = Security(
get_token_api_key
),
) -> None: # noqa: E501
...
@router.put(
"/user/{username}",
responses={
400: {"description": "Invalid user supplied"},
404: {"description": "User not found"},
},
tags=["user"],
summary="Updated user",
)
async def update_user(
username: str = Path(None, description="name that need to be deleted")
,
user: User = Body(None, description="Updated user object")
,
token_api_key: TokenModel = Security(
get_token_api_key
),
) -> None: # noqa: E501
"""This can only be done by the logged in user."""
...

View File

@@ -0,0 +1,27 @@
# coding: utf-8
"""
OpenAPI Petstore
This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
The version of the OpenAPI document: 1.0.0
Generated by: https://openapi-generator.tech
"""
from fastapi import FastAPI
from openapi_server.apis.pet_api import router as PetApiRouter
from openapi_server.apis.store_api import router as StoreApiRouter
from openapi_server.apis.user_api import router as UserApiRouter
app = FastAPI(
title="OpenAPI Petstore",
description="This is a sample server Petstore server. For this sample, you can use the api key &#x60;special-key&#x60; to test the authorization filters.",
version="1.0.0",
)
app.include_router(PetApiRouter)
app.include_router(StoreApiRouter)
app.include_router(UserApiRouter)

View File

@@ -0,0 +1,24 @@
# coding: utf-8
from datetime import date, datetime
from typing import Dict, List, Optional
from pydantic import BaseModel, EmailStr, validator
class ApiResponse(BaseModel):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Do not edit the class manually.
ApiResponse - a model defined in OpenAPI
code: The code of this ApiResponse [Optional].
type: The type of this ApiResponse [Optional].
message: The message of this ApiResponse [Optional].
"""
code: Optional[int] = None
type: Optional[str] = None
message: Optional[str] = None

View File

@@ -0,0 +1,22 @@
# coding: utf-8
from datetime import date, datetime
from typing import Dict, List, Optional
from pydantic import BaseModel, EmailStr, validator
class Category(BaseModel):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Do not edit the class manually.
Category - a model defined in OpenAPI
id: The id of this Category [Optional].
name: The name of this Category [Optional].
"""
id: Optional[int] = None
name: Optional[str] = None

View File

@@ -0,0 +1,8 @@
# coding: utf-8
from pydantic import BaseModel
class TokenModel(BaseModel):
"""Defines a token model."""
sub: str

View File

@@ -0,0 +1,30 @@
# coding: utf-8
from datetime import date, datetime
from typing import Dict, List, Optional
from pydantic import BaseModel, EmailStr, validator
class Order(BaseModel):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Do not edit the class manually.
Order - a model defined in OpenAPI
id: The id of this Order [Optional].
pet_id: The pet_id of this Order [Optional].
quantity: The quantity of this Order [Optional].
ship_date: The ship_date of this Order [Optional].
status: The status of this Order [Optional].
complete: The complete of this Order [Optional].
"""
id: Optional[int] = None
pet_id: Optional[int] = None
quantity: Optional[int] = None
ship_date: Optional[datetime] = None
status: Optional[str] = None
complete: Optional[bool] = None

View File

@@ -0,0 +1,32 @@
# coding: utf-8
from datetime import date, datetime
from typing import Dict, List, Optional
from pydantic import BaseModel, EmailStr, validator
from openapi_server.models.category import Category
from openapi_server.models.tag import Tag
class Pet(BaseModel):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Do not edit the class manually.
Pet - a model defined in OpenAPI
id: The id of this Pet [Optional].
category: The category of this Pet [Optional].
name: The name of this Pet.
photo_urls: The photo_urls of this Pet.
tags: The tags of this Pet [Optional].
status: The status of this Pet [Optional].
"""
id: Optional[int] = None
category: Optional[Category] = None
name: str
photo_urls: List[str]
tags: Optional[List[Tag]] = None
status: Optional[str] = None

View File

@@ -0,0 +1,22 @@
# coding: utf-8
from datetime import date, datetime
from typing import Dict, List, Optional
from pydantic import BaseModel, EmailStr, validator
class Tag(BaseModel):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Do not edit the class manually.
Tag - a model defined in OpenAPI
id: The id of this Tag [Optional].
name: The name of this Tag [Optional].
"""
id: Optional[int] = None
name: Optional[str] = None

View File

@@ -0,0 +1,34 @@
# coding: utf-8
from datetime import date, datetime
from typing import Dict, List, Optional
from pydantic import BaseModel, EmailStr, validator
class User(BaseModel):
"""NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
Do not edit the class manually.
User - a model defined in OpenAPI
id: The id of this User [Optional].
username: The username of this User [Optional].
first_name: The first_name of this User [Optional].
last_name: The last_name of this User [Optional].
email: The email of this User [Optional].
password: The password of this User [Optional].
phone: The phone of this User [Optional].
user_status: The user_status of this User [Optional].
"""
id: Optional[int] = None
username: Optional[str] = None
first_name: Optional[str] = None
last_name: Optional[str] = None
email: Optional[str] = None
password: Optional[str] = None
phone: Optional[str] = None
user_status: Optional[int] = None

View File

@@ -0,0 +1,83 @@
# coding: utf-8
from typing import List
from fastapi import APIRouter, Depends, Response, Security, status
from fastapi.openapi.models import OAuthFlowImplicit, OAuthFlows
from fastapi.security import (
HTTPAuthorizationCredentials,
HTTPBasic,
HTTPBasicCredentials,
HTTPBearer,
OAuth2,
OAuth2AuthorizationCodeBearer,
OAuth2PasswordBearer,
SecurityScopes,
)
from fastapi.security.api_key import APIKey, APIKeyCookie, APIKeyHeader, APIKeyQuery
from openapi_server.models.extra_models import TokenModel
def get_token_api_key(
token_api_key_header: str = Security(
APIKeyHeader(name="api_key", auto_error=False)
),
) -> TokenModel:
"""
Check and retrieve authentication information from api_key.
:param token_api_key_header API key provided by Authorization[api_key] header
:type token_api_key_header: str
:return: Information attached to provided api_key or None if api_key is invalid or does not allow access to called API
:rtype: TokenModel | None
"""
...
oauth2_implicit = OAuth2(
flows=OAuthFlows(
implicit=OAuthFlowImplicit(
authorizationUrl="http://petstore.swagger.io/api/oauth/dialog",
scopes={
"write:pets": "modify pets in your account",
"read:pets": "read your pets",
}
)
)
)
def get_token_petstore_auth(
security_scopes: SecurityScopes, token: str = Depends(oauth2_implicit)
) -> TokenModel:
"""
Validate and decode token.
:param token Token provided by Authorization header
:type token: str
:return: Decoded token information or None if token is invalid
:rtype: TokenModel | None
"""
...
def validate_scope_petstore_auth(
required_scopes: SecurityScopes, token_scopes: List[str]
) -> bool:
"""
Validate required scopes are included in token scope
:param required_scopes Required scope to access called API
:type required_scopes: List[str]
:param token_scopes Scope present in token
:type token_scopes: List[str]
:return: True if access to called API is allowed
:rtype: bool
"""
return False

View File

@@ -0,0 +1,20 @@
import contextlib
from typing import Any
import pytest
from fastapi import FastAPI
from fastapi.testclient import TestClient
from openapi_server.main import app as application
@pytest.fixture
def app() -> FastAPI:
application.dependency_overrides = {}
return application
@pytest.fixture
def client(app) -> TestClient:
return TestClient(app)

View File

@@ -0,0 +1,165 @@
# coding: utf-8
from fastapi.testclient import TestClient
import json
import pytest
from openapi_server.models.api_response import ApiResponse
from openapi_server.models.pet import Pet
def test_add_pet(client: TestClient):
"""Test case for add_pet
Add a new pet to the store
"""
pet = {"photo_urls":["photoUrls","photoUrls"],"name":"doggie","id":0,"category":{"name":"name","id":6},"tags":[{"name":"name","id":1},{"name":"name","id":1}],"status":"available"}
headers = {
'Authorization': 'Bearer special-key',
}
response = client.request(
'POST',
'/pet',
headers=headers,
json=pet,
)
assert response.status_code == 200
def test_delete_pet(client: TestClient):
"""Test case for delete_pet
Deletes a pet
"""
headers = {
'api_key': 'api_key_example',
'Authorization': 'Bearer special-key',
}
response = client.request(
'DELETE',
'/pet/{petId}'.format(petId=56),
headers=headers,
)
assert response.status_code == 200
def test_find_pets_by_status(client: TestClient):
"""Test case for find_pets_by_status
Finds Pets by status
"""
params = [("status", ['status_example'])]
headers = {
'Authorization': 'Bearer special-key',
}
response = client.request(
'GET',
'/pet/findByStatus',
headers=headers,
params=params,
)
assert response.status_code == 200
def test_find_pets_by_tags(client: TestClient):
"""Test case for find_pets_by_tags
Finds Pets by tags
"""
params = [("tags", ['tags_example'])]
headers = {
'Authorization': 'Bearer special-key',
}
response = client.request(
'GET',
'/pet/findByTags',
headers=headers,
params=params,
)
assert response.status_code == 200
def test_get_pet_by_id(client: TestClient):
"""Test case for get_pet_by_id
Find pet by ID
"""
headers = {
'api_key': 'special-key',
}
response = client.request(
'GET',
'/pet/{petId}'.format(petId=56),
headers=headers,
)
assert response.status_code == 200
def test_update_pet(client: TestClient):
"""Test case for update_pet
Update an existing pet
"""
pet = {"photo_urls":["photoUrls","photoUrls"],"name":"doggie","id":0,"category":{"name":"name","id":6},"tags":[{"name":"name","id":1},{"name":"name","id":1}],"status":"available"}
headers = {
'Authorization': 'Bearer special-key',
}
response = client.request(
'PUT',
'/pet',
headers=headers,
json=pet,
)
assert response.status_code == 200
def test_update_pet_with_form(client: TestClient):
"""Test case for update_pet_with_form
Updates a pet in the store with form data
"""
headers = {
'Authorization': 'Bearer special-key',
}
data = {
'name': 'name_example',
'status': 'status_example'
}
response = client.request(
'POST',
'/pet/{petId}'.format(petId=56),
headers=headers,
data=data,
)
assert response.status_code == 200
def test_upload_file(client: TestClient):
"""Test case for upload_file
uploads an image
"""
headers = {
'Authorization': 'Bearer special-key',
}
data = {
'additional_metadata': 'additional_metadata_example',
'file': '/path/to/file'
}
response = client.request(
'POST',
'/pet/{petId}/uploadImage'.format(petId=56),
headers=headers,
data=data,
)
assert response.status_code == 200

View File

@@ -0,0 +1,76 @@
# coding: utf-8
from fastapi.testclient import TestClient
import json
import pytest
from openapi_server.models.order import Order
def test_delete_order(client: TestClient):
"""Test case for delete_order
Delete purchase order by ID
"""
headers = {
}
response = client.request(
'DELETE',
'/store/order/{orderId}'.format(orderId='order_id_example'),
headers=headers,
)
assert response.status_code == 200
def test_get_inventory(client: TestClient):
"""Test case for get_inventory
Returns pet inventories by status
"""
headers = {
'api_key': 'special-key',
}
response = client.request(
'GET',
'/store/inventory',
headers=headers,
)
assert response.status_code == 200
def test_get_order_by_id(client: TestClient):
"""Test case for get_order_by_id
Find purchase order by ID
"""
headers = {
}
response = client.request(
'GET',
'/store/order/{orderId}'.format(orderId=56),
headers=headers,
)
assert response.status_code == 200
def test_place_order(client: TestClient):
"""Test case for place_order
Place an order for a pet
"""
order = {"pet_id":6,"quantity":1,"id":0,"ship_date":"2000-01-23T04:56:07.000+00:00","complete":0,"status":"placed"}
headers = {
}
response = client.request(
'POST',
'/store/order',
headers=headers,
json=order,
)
assert response.status_code == 200

View File

@@ -0,0 +1,154 @@
# coding: utf-8
from fastapi.testclient import TestClient
import json
import pytest
from openapi_server.models.user import User
def test_create_user(client: TestClient):
"""Test case for create_user
Create user
"""
user = {"first_name":"firstName","last_name":"lastName","password":"password","user_status":6,"phone":"phone","id":0,"email":"email","username":"username"}
headers = {
'api_key': 'special-key',
}
response = client.request(
'POST',
'/user',
headers=headers,
json=user,
)
assert response.status_code == 200
def test_create_users_with_array_input(client: TestClient):
"""Test case for create_users_with_array_input
Creates list of users with given input array
"""
user = [{"first_name":"firstName","last_name":"lastName","password":"password","user_status":6,"phone":"phone","id":0,"email":"email","username":"username"}]
headers = {
'api_key': 'special-key',
}
response = client.request(
'POST',
'/user/createWithArray',
headers=headers,
json=user,
)
assert response.status_code == 200
def test_create_users_with_list_input(client: TestClient):
"""Test case for create_users_with_list_input
Creates list of users with given input array
"""
user = [{"first_name":"firstName","last_name":"lastName","password":"password","user_status":6,"phone":"phone","id":0,"email":"email","username":"username"}]
headers = {
'api_key': 'special-key',
}
response = client.request(
'POST',
'/user/createWithList',
headers=headers,
json=user,
)
assert response.status_code == 200
def test_delete_user(client: TestClient):
"""Test case for delete_user
Delete user
"""
headers = {
'api_key': 'special-key',
}
response = client.request(
'DELETE',
'/user/{username}'.format(username='username_example'),
headers=headers,
)
assert response.status_code == 200
def test_get_user_by_name(client: TestClient):
"""Test case for get_user_by_name
Get user by user name
"""
headers = {
}
response = client.request(
'GET',
'/user/{username}'.format(username='username_example'),
headers=headers,
)
assert response.status_code == 200
def test_login_user(client: TestClient):
"""Test case for login_user
Logs user into the system
"""
params = [("username", 'username_example'),
("password", 'password_example')]
headers = {
}
response = client.request(
'GET',
'/user/login',
headers=headers,
params=params,
)
assert response.status_code == 200
def test_logout_user(client: TestClient):
"""Test case for logout_user
Logs out current logged in user session
"""
headers = {
'api_key': 'special-key',
}
response = client.request(
'GET',
'/user/logout',
headers=headers,
)
assert response.status_code == 200
def test_update_user(client: TestClient):
"""Test case for update_user
Updated user
"""
user = {"first_name":"firstName","last_name":"lastName","password":"password","user_status":6,"phone":"phone","id":0,"email":"email","username":"username"}
headers = {
'api_key': 'special-key',
}
response = client.request(
'PUT',
'/user/{username}'.format(username='username_example'),
headers=headers,
json=user,
)
assert response.status_code == 200