问题陈述:我希望自动生成JSON API的机器和人类可读规范,以便任何人都可以使用我们的API进行可视化和交互。
一个可行的解决方案是使用OpenAPISpecification(fka swagger)。我无法找到一个易于理解的指南,特别是龙卷风使用招摇,所以我的问题是:
我的API是用龙卷风4.3在python 2.7.11中编写的。 如果您有任何其他建议,请提出建议,而不是使用招摇。
答案 0 :(得分:0)
我们最近有这项要求。我们制作了自己的生成器,该生成器从Google样式文档字符串生成OpenAPI 3.0 API规范。您只需要装饰处理程序和模型类即可。有关更多信息:https://pypi.org/project/tornado-swirl/-尽管仍在进行中,但我们正在积极进行中。
import tornado.web
import tornado_swirl as swirl
@swirl.restapi('/item/(?P<itemid>\d+)')
class ItemHandler(tornado.web.RequestHandler):
def get(self, itemid):
"""Get Item data.
Gets Item data from database.
Path Parameter:
itemid (int) -- The item id
"""
pass
@swirl.schema
class User(object):
"""This is the user class
Your usual long description.
Properties:
name (string) -- required. Name of user
age (int) -- Age of user
"""
pass
def make_app():
return swirl.Application(swirl.api_routes())
if __name__ == "__main__":
app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
答案 1 :(得分:0)
我写了一个与python2.7兼容的插件。您可以使用pip install -U tornado-rest-swagger
直接安装它。它使用openapi3.0的语法。这是一个示例:
import tornado.ioloop
import tornado.options
import tornado.web
from tornado_swagger.components import components
from tornado_swagger.setup import setup_swagger
class BaseHandler(tornado.web.RequestHandler):
def data_received(self, chunk):
pass
class PostsHandler(BaseHandler):
def get(self):
"""
---
tags:
- Posts
summary: List posts
description: List all posts in feed
operationId: getPost
responses:
'200':
description: A list of users
content:
application/json:
schema:
$ref: '#/components/schemas/ArrayOfPostModel'
application/xml:
schema:
$ref: '#/components/schemas/ArrayOfPostModel'
text/plain:
schema:
type: string
"""
def post(self):
"""
---
tags:
- Posts
summary: Add a new Post to the blog
operationId: addPost
requestBody:
description: Post object that needs to be added to the blog
content:
application/json:
schema:
$ref: '#/components/schemas/PostModel'
application/xml:
schema:
$ref: '#/components/schemas/PostModel'
required: true
responses:
'405':
description: Invalid input
content: {}
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
"""
class PostsDetailsHandler(BaseHandler):
def get(self, posts_id):
"""
---
tags:
- Posts
summary: Find Post by ID
description: Returns a single post
operationId: getPostById
parameters:
- name: post_id
in: path
description: ID of post to return
required: true
schema:
type: integer
format: int64
responses:
'200':
description: successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/PostModel'
application/json:
schema:
$ref: '#/components/schemas/PostModel'
'400':
description: Invalid ID supplied
content: {}
'404':
description: Pet not found
content: {}
security:
- api_key: []
"""
def patch(self, posts_id):
"""
---
tags:
- Posts
summary: Find Post by ID
description: Returns a single post
operationId: getPostById
parameters:
- name: post_id
in: path
description: ID of post to return
required: true
schema:
type: integer
format: int64
requestBody:
description: Post object that needs to be added to the blog
content:
application/json:
schema:
$ref: '#/components/schemas/PostModel'
application/xml:
schema:
$ref: '#/components/schemas/PostModel'
required: true
responses:
'400':
description: Invalid ID supplied
content: {}
'404':
description: Pet not found
content: {}
security:
- api_key: []
"""
def delete(self, posts_id):
"""
---
tags:
- Posts
summary: Delete Post by ID
description: Returns a single post
operationId: getPostById
parameters:
- name: post_id
in: path
description: ID of post to return
required: true
schema:
type: integer
format: int64
responses:
'200':
description: successful operation
content:
application/json:
schema:
type: object
description: Post model representation
properties:
id:
type: integer
format: int64
title:
type: string
text:
type: string
is_visible:
type: boolean
default: true
'400':
description: Invalid ID supplied
content: {}
'404':
description: Pet not found
content: {}
"""
@components.schemas.register
class PostModel(object):
"""
---
type: object
description: Post model representation
properties:
id:
type: integer
format: int64
title:
type: string
text:
type: string
is_visible:
type: boolean
default: true
"""
@components.schemas.register
class ArrayOfPostModel(object):
"""
---
type: array
description: Array of Post model representation
items:
$ref: '#/components/schemas/PostModel'
"""
@components.security_schemes.register
class JWTToken(object):
"""
---
type: http
scheme: bearer
bearerFormat: JWT
"""
class Application(tornado.web.Application):
_routes = [tornado.web.url(r"/api/posts", PostsHandler), tornado.web.url(r"/api/posts/(\w+)", PostsDetailsHandler)]
def __init__(self):
settings = {"debug": True}
setup_swagger(
self._routes,
swagger_url="/doc",
description="",
api_version="1.0.0",
title="Journal API",
contact=dict(name="test", email="test@domain.com", url="https://www.cluas.me"),
)
super(Application, self).__init__(self._routes, **settings)
if __name__ == "__main__":
tornado.options.define("port", default="8080", help="Port to listen on")
tornado.options.parse_command_line()
app = Application()
app.listen(port=8080)
tornado.ioloop.IOLoop.current().start()
如果您的函数是一个装饰器并使用python2.7,则可以尝试用decorator(pip install decorator
)包装装饰器,以便获得正确的行为。