Added files

This commit is contained in:
Antonio de la Rosa 2025-04-26 16:50:27 +02:00
commit aaf3c17220
24 changed files with 1614 additions and 0 deletions

8
.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
*~
*.pyc
__pycache__
modules/*
!modules/welcome
!modules/admin
themes/*
!themes/default/

18
__apidoc__.py Normal file
View file

@ -0,0 +1,18 @@
from modules.apidoc2.libraries.apidoc import AppDoc
from modules.apidoc2 import apidoc_app
description="""
This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about Swagger at [http://swagger.io](http://swagger.io). In the third iteration of the pet store, we've switched to the design first approach! You can now help us improve the API whether it's by making changes to the definition itself or to the code. That way, with time, we can improve the API in general, and expose some of the new features in OAS3.
Some useful links:
- [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)
- [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)
"""
appdoc=AppDoc(apidoc_app, description)
appdoc.url='/'
#appdoc.routes['apidoc_app.item'].summary='Summary item'
#appdoc.routes['apidoc_app.item'].description='Description item'
#appdoc.tags['apidoc']='An example of description'

4
__init__.py Normal file
View file

@ -0,0 +1,4 @@
from flask import Blueprint, g, request, session, redirect, url_for, current_app
apidoc_app=Blueprint('apidoc_app', __name__)

101
app.py Normal file
View file

@ -0,0 +1,101 @@
from paramecio2.libraries.mtemplates import env_theme, PTemplate
from paramecio2.libraries.urls import make_url
from paramecio2.libraries.db import corefields
from paramecio2.libraries.db.extrafields.datetimefield import DateTimeField
from flask import request
from settings import config
#from paramecio2.wsgiapp import app
from modules.apidoc2 import apidoc_app
from flask import abort
import os
try:
import ujson as json
except:
import json
import inspect
import re
from typing import Annotated
from modules.apidoc2.libraries.apidoc import AppDoc
from importlib import import_module
env=env_theme(__file__)
t=PTemplate(env)
import json
class Object:
def toJSON(self):
return json.dumps(
self,
default=lambda o: o.__dict__,
sort_keys=True,
indent=4)
class General(Object):
name: int = None
gen=General()
class Item:
name=corefields.CharField('name', '')
item_id=corefields.IntegerField('item_id', '')
date_added=DateTimeField('date_added', '')
@apidoc_app.route('/apidoc/<module>')
def apidocs(module):
if os.path.isfile('modules/{}/__apidoc__.py'.format(module)):
return t.load_template('api.phtml', module=module)
else:
abort(404)
@apidoc_app.route('/apidoc/<module>/api.yaml')
def json_spec(module):
module_api='modules/{}/__apidoc__.py'.format(module)
if os.path.isfile(module_api):
module_api=module_api.replace('/', '.').replace('.py', '')
appdoc=import_module(module_api)
api_json=t.load_template('openapi.yaml', appdoc=appdoc.appdoc, version="1.0", title="Apidoc specification for paramecio2", terms_of_service='', email='antonio.delarosa@salirdelhoyo.com',license={'name': 'AGPLV3', 'url': 'https://www.gnu.org/licenses/agpl-3.0.html'})
#return json.loads(api_json)
return api_json
else:
abort(404)
# Api test
# FullArgSpec(args=['item_id'], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={'item_id': <class 'int'>}
@apidoc_app.route('/apidoc/v1/item/<int:item_id>')
def item(item_id: Annotated[int, 'Id of the item in database'], tag='apidoc') -> Item:
"""
A method for get item using id from database
A method for get item using id from database. You can access to one object.
"""
return { "date_added": "2024-06-01 12:24:11", "item_id": item_id, "name": "Tree" }
@apidoc_app.post('/apidoc/v1/item')
def item_post(tag='apidoc', post: Annotated[Item, 'Insert a item in db'] = Item):
error=0
message=''
code_error=0
return {'error': error, 'message': message, 'code_error': code_error}

442
libraries/apidoc.py Normal file
View file

@ -0,0 +1,442 @@
import inspect
import re
from typing import Annotated, get_type_hints
from paramecio2.libraries.responsesapi import ListItem
from settings import config
wsgi_type='flask'
if hasattr(config, 'wsgi_type'):
wsgi_type=config.wsgi_type
if wsgi_type=='flask':
from flask import current_app
#from app import app
"""
import app
for key, view in app.app.view_functions.items():
#print(key)
#print(url_for(key), key, view)
if key.find('.')!=-1:
#print(url_for(key))
print(rule, view)
for rule in app.app.url_map.iter_rules():
print(rule.endpoint, rule)
"""
class AppDoc:
def __init__(self, app, api_description):
self.routes={}
self.description=api_description
self.tags={}
self.components={}
arr_apidocs=[]
arr_components=[]
rules={}
if wsgi_type=='flask':
for rule in current_app.url_map.iter_rules():
#print(rule.endpoint, rule)
if rule.endpoint.startswith(app.name+'.'):
rules[rule.endpoint]=rule
#print(rules)
for key, view in current_app.view_functions.items():
#print(app.name)
#print(key)
if key.startswith(app.name+'.'):
#print(view.get_callback_args())
#if 'tag' in inspect.getmembers(view, lambda a:not(inspect.isroutine(a))):
# print(key)
if 'tag' in list(inspect.signature(view).parameters.keys()):
route=re.sub(r'<\w+[:](\w+)?>', '{\\1}', rules[key].rule)
#print(route)
if 'GET' in rules[key].methods:
method='get'
if 'POST' in rules[key].methods:
method='post'
if 'PUT' in rules[key].methods:
method='put'
if 'DELETE' in rules[key].methods:
method='delete'
apidoc=ApiDoc(view, route, method, 'Action summary', 'Description')
self.routes[key]=apidoc
if not apidoc.tag in arr_apidocs:
arr_apidocs.append(apidoc.tag)
self.tags[apidoc.tag]=apidoc.tag.capitalize()
if len(apidoc.component)>0:
self.components.update(apidoc.component)
type_hints=get_type_hints(view)
if 'return' in type_hints:
return_obj=type_hints['return']
name_comp=return_obj.__name__
self.components=get_fields(return_obj, name_comp, self.components)
else:
for entry in app.routes:
#print(entry.args)
# Function is added to doc api if tag inside
if 'tag' in entry.get_callback_args():
route=re.sub(r'<(\w+)[:]?.*?>', '{\\1}', entry.rule)
#print(entry.name)
#routes.append({'route': orule, 'method': entry.method.lower(), 'api_description': api_description, 'tag': tag})
method=entry.method.lower()
apidoc=ApiDoc(entry.callback, route, method, 'Action summary', 'Description')
self.routes[entry.name]=apidoc
#{'name': 'apidoc', 'description': 'apidoc description'}
if not apidoc.tag in arr_apidocs:
arr_apidocs.append(apidoc.tag)
self.tags[apidoc.tag]=apidoc.tag.capitalize()
if len(apidoc.component)>0:
#print(apidoc.component)
self.components.update(apidoc.component)
#if not apidoc.components
# Get return from route function called entry.callback
type_hints=get_type_hints(entry.callback)
if 'return' in type_hints:
return_obj=type_hints['return']
name_comp=return_obj.__name__
#fields_return=inspect.getmembers(return_obj, lambda a:not(inspect.isroutine(a)))
self.components=get_fields(return_obj, name_comp, self.components)
def get_fields(return_obj, name_comp, components):
if not name_comp in components and name_comp!='StandardResponse':
components[name_comp]={}
fields_return=inspect.getmembers(return_obj, lambda a:not(inspect.isroutine(a)))
for f in [field for field in fields_return if not field[0].startswith('__')]:
name_prop=f[0]
if type(f[1]).__bases__[0] is not ListItem:
components[name_comp][name_prop]={}
components[name_comp][name_prop]['type']=getattr(f[1], 'jtype')
try:
components[name_comp][name_prop]['format']=getattr(f[1], 'jformat')
except AttributeError:
components[name_comp][name_prop]['format']=''
try:
components[name_comp][name_prop]['example']=getattr(f[1], 'jexample')
except AttributeError:
components[name_comp][name_prop]['example']=''
else:
#components=get_fields(f[1]
components[name_comp][name_prop]={}
components[name_comp][name_prop]['type']='array'
name_comp_sub=type(f[1]).__name__
components[name_comp][name_prop]['object']=name_comp_sub
components=get_fields(f[1], name_comp_sub, components)
pass
return components
#print(self.tags)
class ApiDoc:
def __init__(self, func_api, route, method, summary, description):
self.route=route
self.method=method
self.summary=summary
self.description=description
#self.tag_name=tag_name
self.operationId="".join([f.capitalize() for f in func_api.__name__.split('_')])
self.parameters=[]
self.tag=''
self.bearer=False
self.post={}
sign=inspect.signature(func_api)
# The return object
self.return_obj=None
self.component={}
#if hasattr(sign, 'return_annotation'):
if sign.return_annotation.__name__!='_empty':
self.return_obj=sign.return_annotation.__name__
#print(self.return_obj)
args=inspect.getfullargspec(func_api)
annotations=func_api.__annotations__
# The parameters
#print(annotations)
params=sign.parameters
#print(params)
args_len=len(tuple(re.finditer(r'\{(\w+)[:]?.*?\}', route)))
#print(args_len)
z=0
for k, f in params.items():
if k!='tag' and k!='post' and z<args_len:
required='false'
#print(type(f).__name__)
if type(f.default).__name__=='type':
required='true'
description=''
if k in annotations:
"""
for property, value in vars(annotations[k]).items():
print(property, ":", value)
"""
#print(annotations[k].__name__)
if annotations[k].__name__=='Annotated':
description=annotations[k].__metadata__[0]
type_arg=annotations[k].__args__[0].__name__
else:
description=k.capitalize()
type_arg=annotations[k].__name__
else:
description=k.capitalize()
type_arg='string'
if type_arg=='int':
type_arg='integer'
if type_arg=='str':
type_arg='string'
self.parameters.append({'name': k, 'in': 'path', 'description': description, 'required': required, 'schema': {'type': type_arg}})
z+=1
if 'tag' in params:
self.tag=params['tag'].default
if 'bearer' in params:
self.bearer=True
# Set json object if method=post
if method=='post' or method=='put':
#print(params)
if 'post' in annotations:
#print(params['post'])
#print(annotations['post'])
self.post['description']=annotations['post'].__metadata__[0]
self.post['content']=annotations['post'].__args__[0].__name__
# Add to self.component
post_obj=annotations['post'].__args__[0]
name_comp=post_obj.__name__
self.component[name_comp]={}
fields_post=inspect.getmembers(post_obj, lambda a:not(inspect.isroutine(a)))
for f in [field for field in fields_post if not field[0].startswith('__')]:
name_prop=f[0]
self.component[name_comp][name_prop]={}
self.component[name_comp][name_prop]['type']=getattr(f[1], 'jtype')
try:
self.component[name_comp][name_prop]['format']=getattr(f[1], 'jformat')
except AttributeError:
self.component[name_comp][name_prop]['format']=''
try:
self.component[name_comp][name_prop]['example']=getattr(f[1], 'jexample')
except AttributeError:
self.component[name_comp][name_prop]['example']=''
pass
#self.post['description']=
"""
requestBody:
description: Create a new pet in the store
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
"""
pass
#print(get_type_hints(func_api, include_extras=True))
# api_description=metadata.default['api_description']
#print(self.parameters)
#for k,f in params:
#metadata=signature.parameters.get('metadata')
self.response={}
self.response[200]={'description': 'successful operation'}
self.response[400]={'description': 'Invalid ID supplied'}
self.response[404]={'description': 'Element not found'}
def add_parameter(self, name, in_type, description, required, type_arg):
self.parameters.append({'name': name, 'in': in_type, 'description': description, 'required': required, 'schema': {'type': type_arg}})
class JsonObject:
def toJSON(self):
return json.dumps(
self,
default=lambda o: o.__dict__,
sort_keys=True,
indent=4)
class Schema:
properties=[]
class Property:
name=''
type=''
format=''
example=''
# If type==array you neeed fill items.
items=None
"""
Item:
type: object
properties:
reference:
type: string
part_number:
type: string
name:
type: string
manufacturer:
type: string
description:
type: string
unit_price:
type: number
format: float
category:
type: string
family:
type: string
accounting_account:
type: string
discount:
type: number
format: float
tax_type:
type: number
format: float
tax_total:
type: number
format: float
subtotal:
type: number
format: float
total:
type: number
format: float
serial_numbers:
type: array
items:
type: string
"""
"""
% for route in routes:
'${route['route']}':
${route['method']}:
tags:
- item
summary: Find item by ID
description: Returns a single item
operationId: getItemById
parameters:
- name: itemId
in: path
description: ID of item to return
required: true
schema:
type: integer
format: int64
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Item'
'400':
description: Invalid ID supplied
'404':
description: Pet not found
security:
- api_key: []
% endfor
"""

16
media/css/index.css Normal file
View file

@ -0,0 +1,16 @@
html {
box-sizing: border-box;
overflow: -moz-scrollbars-vertical;
overflow-y: scroll;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 0;
background: #fafafa;
}

3
media/css/swagger-ui.css Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 665 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

View file

@ -0,0 +1,20 @@
window.onload = function() {
//<editor-fold desc="Changeable Configuration Block">
// the following lines will be replaced by docker/configurator, when it runs in a docker-container
window.ui = SwaggerUIBundle({
url: "https://petstore.swagger.io/v2/swagger.json",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
});
//</editor-fold>
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
media/js/swagger-ui.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

59
templates/api.phtml Normal file
View file

@ -0,0 +1,59 @@
<!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="stylesheet" type="text/css" href="${make_media_url('css/swagger-ui.css', 'apidoc2')}" />
<link rel="stylesheet" type="text/css" href="${make_media_url('css/index.css', 'apidoc2')}" />
<!--<link rel="icon" type="image/png" href="${make_media_url('images/favicon-32x32.png', 'apidoc')}" sizes="32x32" />
<link rel="icon" type="image/png" href="${make_media_url('images/favicon-16x16.png', 'apidoc')}" sizes="16x16" />-->
<!--<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.9.0/swagger-ui.css">-->
</head>
<body>
<div id="swagger-ui"></div>
<script src="${make_media_url('js/swagger-ui-bundle.js', 'apidoc2')}" charset="UTF-8"> </script>
<script src="${make_media_url('js/swagger-ui-standalone-preset.js', 'apidoc2')}" charset="UTF-8"> </script>
<!--<script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.9.0/swagger-ui-bundle.js"></script>-->
<script>
window.onload = function() {
//<editor-fold desc="Changeable Configuration Block">
// the following lines will be replaced by docker/configurator, when it runs in a docker-container
/*window.ui = SwaggerUIBundle({
url: "",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
});*/
const ui = SwaggerUIBundle({
url: "${url_for('apidoc_app.json_spec', module=module)}",
"dom_id": "#swagger-ui",
"layout": "BaseLayout",
//"deepLinking": true,
"showExtensions": true,
"showCommonExtensions": true,
//oauth2RedirectUrl: window.location.origin + '/docs/oauth2-redirect',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIBundle.SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
})
//</editor-fold>
};
</script>
</body>
</html>

815
templates/openapi-orig.yaml Normal file
View file

@ -0,0 +1,815 @@
openapi: 3.0.2
servers:
- url: /v3
info:
description: |-
This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about Swagger at [http://swagger.io](http://swagger.io). In the third iteration of the pet store, we've switched to the design first approach! You can now help us improve the API whether it's by making changes to the definition itself or to the code. That way, with time, we can improve the API in general, and expose some of the new features in OAS3.
Some useful links:
- [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)
- [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)
version: 1.0.20-SNAPSHOT
title: Swagger Petstore - OpenAPI 3.0
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'
tags:
- name: pet
description: Everything about your Pets
externalDocs:
description: Find out more
url: 'http://swagger.io'
- name: store
description: Access to Petstore orders
externalDocs:
description: Find out more about our store
url: 'http://swagger.io'
- name: user
description: Operations about user
paths:
/pet:
post:
tags:
- pet
summary: Add a new pet to the store
description: Add a new pet to the store
operationId: addPet
responses:
'200':
description: Successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/json:
schema:
$ref: '#/components/schemas/Pet'
'405':
description: Invalid input
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
description: Create a new pet in the store
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/Pet'
put:
tags:
- pet
summary: Update an existing pet
description: Update an existing pet by Id
operationId: updatePet
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
'404':
description: Pet not found
'405':
description: Validation exception
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
description: Update an existent pet in the store
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/Pet'
/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: false
explode: true
schema:
type: string
enum:
- available
- pending
- sold
default: available
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
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
/pet/findByTags:
get:
tags:
- pet
summary: Finds Pets by tags
description: >-
Multiple 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: false
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
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
'404':
description: Pet not found
security:
- api_key: []
- petstore_auth:
- 'write:pets'
- 'read:pets'
post:
tags:
- pet
summary: Updates a pet in the store with form data
description: ''
operationId: updatePetWithForm
parameters:
- name: petId
in: path
description: ID of pet that needs to be updated
required: true
schema:
type: integer
format: int64
- name: name
in: query
description: Name of pet that needs to be updated
schema:
type: string
- name: status
in: query
description: Status of pet that needs to be updated
schema:
type: string
responses:
'405':
description: Invalid input
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
delete:
tags:
- pet
summary: Deletes a pet
description: ''
operationId: deletePet
parameters:
- name: api_key
in: header
description: ''
required: false
schema:
type: string
- name: petId
in: path
description: Pet id to delete
required: true
schema:
type: integer
format: int64
responses:
'400':
description: Invalid pet value
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
'/pet/{petId}/uploadImage':
post:
tags:
- pet
summary: uploads an image
description: ''
operationId: uploadFile
parameters:
- name: petId
in: path
description: ID of pet to update
required: true
schema:
type: integer
format: int64
- name: additionalMetadata
in: query
description: Additional Metadata
required: false
schema:
type: string
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
content:
application/octet-stream:
schema:
type: string
format: binary
/store/inventory:
get:
tags:
- store
summary: Returns pet inventories by status
description: Returns a map of status codes to quantities
operationId: getInventory
x-swagger-router-controller: OrderController
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
description: Place a new order in the store
operationId: placeOrder
x-swagger-router-controller: OrderController
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'405':
description: Invalid input
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
application/xml:
schema:
$ref: '#/components/schemas/Order'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/Order'
'/store/order/{orderId}':
get:
tags:
- store
summary: Find purchase order by ID
x-swagger-router-controller: OrderController
description: >-
For valid response try integer IDs with value <= 5 or > 10. Other values
will generate exceptions.
operationId: getOrderById
parameters:
- name: orderId
in: path
description: ID of order that needs to be fetched
required: true
schema:
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
'404':
description: Order not found
delete:
tags:
- store
summary: Delete purchase order by ID
x-swagger-router-controller: OrderController
description: >-
For valid response try integer IDs with value < 1000. Anything above
1000 or nonintegers will generate API errors
operationId: deleteOrder
parameters:
- name: orderId
in: path
description: ID of the order that needs to be deleted
required: true
schema:
type: integer
format: int64
responses:
'400':
description: Invalid ID supplied
'404':
description: Order not found
/user:
post:
tags:
- user
summary: Create user
description: This can only be done by the logged in user.
operationId: createUser
responses:
default:
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/User'
application/xml:
schema:
$ref: '#/components/schemas/User'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/User'
application/xml:
schema:
$ref: '#/components/schemas/User'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/User'
description: Created user object
/user/createWithList:
post:
tags:
- user
summary: Creates list of users with given input array
description: 'Creates list of users with given input array'
x-swagger-router-controller: UserController
operationId: createUsersWithListInput
responses:
'200':
description: Successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/User'
application/json:
schema:
$ref: '#/components/schemas/User'
default:
description: successful operation
requestBody:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
/user/login:
get:
tags:
- user
summary: Logs user into the system
description: ''
operationId: loginUser
parameters:
- name: username
in: query
description: The user name for login
required: false
schema:
type: string
- name: password
in: query
description: The password for login in clear text
required: false
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
/user/logout:
get:
tags:
- user
summary: Logs out current logged in user session
description: ''
operationId: logoutUser
parameters: []
responses:
default:
description: successful operation
'/user/{username}':
get:
tags:
- user
summary: Get user by user name
description: ''
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
'404':
description: User not found
put:
tags:
- user
summary: Update user
x-swagger-router-controller: UserController
description: This can only be done by the logged in user.
operationId: updateUser
parameters:
- name: username
in: path
description: name that needs to be updated
required: true
schema:
type: string
responses:
default:
description: successful operation
requestBody:
description: Update an existent user in the store
content:
application/json:
schema:
$ref: '#/components/schemas/User'
application/xml:
schema:
$ref: '#/components/schemas/User'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/User'
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
'404':
description: User not found
externalDocs:
description: Find out more about Swagger
url: 'http://swagger.io'
components:
schemas:
Order:
x-swagger-router-model: io.swagger.petstore.model.Order
properties:
id:
type: integer
format: int64
example: 10
petId:
type: integer
format: int64
example: 198772
quantity:
type: integer
format: int32
example: 7
shipDate:
type: string
format: date-time
status:
type: string
description: Order Status
enum:
- placed
- approved
- delivered
example: approved
complete:
type: boolean
xml:
name: order
type: object
Customer:
properties:
id:
type: integer
format: int64
example: 100000
username:
type: string
example: fehguy
address:
type: array
items:
$ref: '#/components/schemas/Address'
xml:
wrapped: true
name: addresses
xml:
name: customer
type: object
Address:
properties:
street:
type: string
example: 437 Lytton
city:
type: string
example: Palo Alto
state:
type: string
example: CA
zip:
type: string
example: 94301
xml:
name: address
type: object
Category:
x-swagger-router-model: io.swagger.petstore.model.Category
properties:
id:
type: integer
format: int64
example: 1
name:
type: string
example: Dogs
xml:
name: category
type: object
User:
x-swagger-router-model: io.swagger.petstore.model.User
properties:
id:
type: integer
format: int64
example: 10
username:
type: string
example: theUser
firstName:
type: string
example: John
lastName:
type: string
example: James
email:
type: string
example: john@email.com
password:
type: string
example: 12345
phone:
type: string
example: 12345
userStatus:
type: integer
format: int32
example: 1
description: User Status
xml:
name: user
type: object
Tag:
x-swagger-router-model: io.swagger.petstore.model.Tag
properties:
id:
type: integer
format: int64
name:
type: string
xml:
name: tag
type: object
Pet:
x-swagger-router-model: io.swagger.petstore.model.Pet
required:
- name
- photoUrls
properties:
id:
type: integer
format: int64
example: 10
name:
type: string
example: doggie
category:
$ref: '#/components/schemas/Category'
photoUrls:
type: array
xml:
wrapped: true
items:
type: string
xml:
name: photoUrl
tags:
type: array
xml:
wrapped: true
items:
$ref: '#/components/schemas/Tag'
xml:
name: tag
status:
type: string
description: pet status in the store
enum:
- available
- pending
- sold
xml:
name: pet
type: object
ApiResponse:
properties:
code:
type: integer
format: int32
type:
type: string
message:
type: string
xml:
name: '##default'
type: object
requestBodies:
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
UserArray:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
description: List of user object
securitySchemes:
petstore_auth:
type: oauth2
flows:
implicit:
authorizationUrl: 'https://petstore.swagger.io/oauth/authorize'
scopes:
'write:pets': modify pets in your account
'read:pets': read your pets
api_key:
type: apiKey
name: api_key
in: header

108
templates/openapi.yaml Normal file
View file

@ -0,0 +1,108 @@
openapi: 3.0.2
servers:
- url: ${appdoc.url}
info:
description: |-
${appdoc.description}
version: ${version}
title: ${title}
termsOfService: '${terms_of_service}'
contact:
email: ${email}
license:
name: ${license['name']}
url: ${license['url']}
tags:
% for tag, tag_description in appdoc.tags.items():
- name: ${tag}
description: ${tag_description}
% endfor
paths:
% for route in appdoc.routes.values():
${route.route}:
${route.method}:
% if route.bearer:
security:
- Bearer: [] # use the same name as above
% endif
tags:
- ${route.tag}
summary: ${route.summary}
description: ${route.description}
operationId: ${route.operationId}
% if len(route.parameters)>0:
parameters:
% for param in route.parameters:
- name: ${param['name']}
in: ${param['in']}
description: ${param['description']}
required: ${param['required']}
schema:
type: ${param['schema']['type']}
%endfor
% endif
responses:
'200':
description: successful operation
content:
application/json:
schema:
%if not route.return_obj:
$ref: '#/components/schemas/StandardResponse'
% else:
$ref: '#/components/schemas/${route.return_obj}'
% endif
'400':
description: Invalid ID supplied
'404':
description: Element not found
'405':
description: Invalid input
% if route.method=='post' or route.method=='put':
requestBody:
description: ${route.post['description']}
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/${route.post['content']}'
% endif
% endfor
components:
securitySchemes:
Bearer: # arbitrary name for the security scheme
type: http
scheme: bearer
bearerFormat: JWT # optional, arbitrary value for documentation purposes
schemas:
StandardResponse:
type: object
properties:
error:
type: boolean
example: 0
message:
type: string
code_error:
type: integer
error_form:
type: object
% for name_component, properties in appdoc.components.items():
${name_component}:
type: object
properties:
% for prop_name, prop in properties.items():
${prop_name}:
% if prop['type']!='array':
type: ${prop['type']}
format: ${prop['format']}
% if prop['example']!='':
example: ${prop['example']}
%endif
%else:
type: array
items:
$ref: '#/components/schemas/${prop['object']}'
%endif
%endfor
% endfor