如何生成用 flask-restplus 编写的现有 API 的机器可读 yaml 规范?
How to generate a machine readable yaml specification of an existing API written in flask-restplus?
我有一个简单的 API 在 flask-restplus 的帮助下编写的:
from flask import Flask
from flask_restplus import Resource, Api
app = Flask(__name__) # Create a Flask WSGI application
api = Api(app) # Create a Flask-RESTPlus API
@api.route('/hello') # Create a URL route to this resource
class HelloWorld(Resource): # Create a RESTful resource
def get(self): # Create GET endpoint
return {'hello': 'world'}
if __name__ == '__main__':
app.run(debug=True)
当我在浏览器中导航到 loacalhost:5000/
时,我得到了一个基本的 Swagger 文档,但我找不到我在哪里可以获得 API 的机器可读的纯 yaml 表示,应该'是不是也自动生成了?
我在官方 flask-restplus docs 中找不到有关 "Swagger Yaml documentation generation" 的任何信息。因此,我决定检查源代码,发现 Swagger
class 为 API 实例实现了 Swagger 文档生成。
flask-restplus 源代码中的 Swagger
class 是 API 实例的 Swagger 文档包装器。 class 中的所有方法都建议将 API 数据序列化为 JSON 字典。例如,考虑此 class 的 as_dict()
函数,它将完整的 Swagger 规范序列化为可序列化的字典。查看此函数的文档字符串:
from flask import Flask
from flask_restplus import Resource, Api
from flask_restplus.api import Swagger
app = Flask(__name__)
api = Api(app)
swag = Swagger(api)
print(swag.as_dict.__doc__)
#Output:
Output the specification as a serializable ``dict``.
:returns: the full Swagger specification in a serializable format
:rtype: dict
我可能错了,但源代码表明 API 文档仅作为 JSON
返回,默认情况下在 http://localhost:5000/swagger.json
可用。我找不到 YAML 的任何内容。
但是有一个解决方法可以为您的 API 生成 YAML 文档。我使用 json
和 yaml
库将 /swagger.json
的 json 响应转储到 YAML 中并将其保存到 yamldoc.yml
。您可以通过转到 http://localhost:5000/swagger.yml
来调用它。完整代码:
from flask import Flask
from flask_restplus import Resource, Api
from flask_restplus.api import Swagger
import requests
import json, yaml
app = Flask(__name__) # Create a Flask WSGI application
api = Api(app) # Create a Flask-RESTPlus API
@api.route('/hello') # Create a URL route to this resource
class HelloWorld(Resource): # Create a RESTful resource
def get(self):
return {'hello': 'world'}
@api.route('/swagger.yml')
class HelloWorld(Resource):
def get(self):
url = 'http://localhost:5000/swagger.json'
resp = requests.get(url)
data = json.loads(resp.content)
with open('yamldoc.yml', 'w') as yamlf:
yaml.dump(data, yamlf, allow_unicode=True)
return {"message":"Yaml document generated!"}
if __name__ == '__main__':
app.run(debug=True)
希望对您有所帮助。
根据@amanb 的回答,我将我的 api return 制作成了一个 yaml 文件,但没有提出任何请求。
根据 flask restplus 的文档(或者,最近的分支,flask restx) it is possible to export the Swagger specififcations corresponding to your API 使用:
from flask import json
from myapp import api
print(json.dumps(api.__schema__))
所以,我更喜欢使用 api.__schema__
。
而不是使用 requests
由于我的目标是在请求时提供文件下载,所以需要使用Flask
的send_file
功能。此外,此文件稍后可以从目录中删除,因此我们可以使用 Flask
的 after_this_request
装饰器来调用将删除该文件的注释函数。完整代码:
import os
import json
import yaml
from flask import Flask, after_this_request, send_file, safe_join, abort
from flask_restplus import Resource, Api
from flask_restplus.api import Swagger
app = Flask(__name__) # Create a Flask WSGI application
api = Api(app) # Create a Flask-RESTPlus API
@api.route('/hello') # Create a URL route to this resource
class HelloWorld(Resource): # Create a RESTful resource
def get(self):
return {'hello': 'world'}
@api.route('/swagger.yml')
class HelloWorld(Resource):
def get(self):
data = json.loads(json.dumps(api.__schema__))
with open('yamldoc.yml', 'w') as yamlf:
yaml.dump(data, yamlf, allow_unicode=True, default_flow_style=False)
file = os.path.abspath(os.getcwd())
try:
@after_this_request
def remove_file(resp):
try:
os.remove(safe_join(file, 'yamldoc.yml'))
except Exception as error:
log.error("Error removing or closing downloaded file handle", error)
return resp
return send_file(safe_join(file, 'yamldoc.yml'), as_attachment=True, attachment_filename='yamldoc.yml', mimetype='application/x-yaml')
except FileExistsError:
abort(404)
if __name__ == '__main__':
app.run(debug=True)
我有一个简单的 API 在 flask-restplus 的帮助下编写的:
from flask import Flask
from flask_restplus import Resource, Api
app = Flask(__name__) # Create a Flask WSGI application
api = Api(app) # Create a Flask-RESTPlus API
@api.route('/hello') # Create a URL route to this resource
class HelloWorld(Resource): # Create a RESTful resource
def get(self): # Create GET endpoint
return {'hello': 'world'}
if __name__ == '__main__':
app.run(debug=True)
当我在浏览器中导航到 loacalhost:5000/
时,我得到了一个基本的 Swagger 文档,但我找不到我在哪里可以获得 API 的机器可读的纯 yaml 表示,应该'是不是也自动生成了?
我在官方 flask-restplus docs 中找不到有关 "Swagger Yaml documentation generation" 的任何信息。因此,我决定检查源代码,发现 Swagger
class 为 API 实例实现了 Swagger 文档生成。
flask-restplus 源代码中的 Swagger
class 是 API 实例的 Swagger 文档包装器。 class 中的所有方法都建议将 API 数据序列化为 JSON 字典。例如,考虑此 class 的 as_dict()
函数,它将完整的 Swagger 规范序列化为可序列化的字典。查看此函数的文档字符串:
from flask import Flask
from flask_restplus import Resource, Api
from flask_restplus.api import Swagger
app = Flask(__name__)
api = Api(app)
swag = Swagger(api)
print(swag.as_dict.__doc__)
#Output:
Output the specification as a serializable ``dict``.
:returns: the full Swagger specification in a serializable format
:rtype: dict
我可能错了,但源代码表明 API 文档仅作为 JSON
返回,默认情况下在 http://localhost:5000/swagger.json
可用。我找不到 YAML 的任何内容。
但是有一个解决方法可以为您的 API 生成 YAML 文档。我使用 json
和 yaml
库将 /swagger.json
的 json 响应转储到 YAML 中并将其保存到 yamldoc.yml
。您可以通过转到 http://localhost:5000/swagger.yml
来调用它。完整代码:
from flask import Flask
from flask_restplus import Resource, Api
from flask_restplus.api import Swagger
import requests
import json, yaml
app = Flask(__name__) # Create a Flask WSGI application
api = Api(app) # Create a Flask-RESTPlus API
@api.route('/hello') # Create a URL route to this resource
class HelloWorld(Resource): # Create a RESTful resource
def get(self):
return {'hello': 'world'}
@api.route('/swagger.yml')
class HelloWorld(Resource):
def get(self):
url = 'http://localhost:5000/swagger.json'
resp = requests.get(url)
data = json.loads(resp.content)
with open('yamldoc.yml', 'w') as yamlf:
yaml.dump(data, yamlf, allow_unicode=True)
return {"message":"Yaml document generated!"}
if __name__ == '__main__':
app.run(debug=True)
希望对您有所帮助。
根据@amanb 的回答,我将我的 api return 制作成了一个 yaml 文件,但没有提出任何请求。 根据 flask restplus 的文档(或者,最近的分支,flask restx) it is possible to export the Swagger specififcations corresponding to your API 使用:
from flask import json
from myapp import api
print(json.dumps(api.__schema__))
所以,我更喜欢使用 api.__schema__
。
requests
由于我的目标是在请求时提供文件下载,所以需要使用Flask
的send_file
功能。此外,此文件稍后可以从目录中删除,因此我们可以使用 Flask
的 after_this_request
装饰器来调用将删除该文件的注释函数。完整代码:
import os
import json
import yaml
from flask import Flask, after_this_request, send_file, safe_join, abort
from flask_restplus import Resource, Api
from flask_restplus.api import Swagger
app = Flask(__name__) # Create a Flask WSGI application
api = Api(app) # Create a Flask-RESTPlus API
@api.route('/hello') # Create a URL route to this resource
class HelloWorld(Resource): # Create a RESTful resource
def get(self):
return {'hello': 'world'}
@api.route('/swagger.yml')
class HelloWorld(Resource):
def get(self):
data = json.loads(json.dumps(api.__schema__))
with open('yamldoc.yml', 'w') as yamlf:
yaml.dump(data, yamlf, allow_unicode=True, default_flow_style=False)
file = os.path.abspath(os.getcwd())
try:
@after_this_request
def remove_file(resp):
try:
os.remove(safe_join(file, 'yamldoc.yml'))
except Exception as error:
log.error("Error removing or closing downloaded file handle", error)
return resp
return send_file(safe_join(file, 'yamldoc.yml'), as_attachment=True, attachment_filename='yamldoc.yml', mimetype='application/x-yaml')
except FileExistsError:
abort(404)
if __name__ == '__main__':
app.run(debug=True)