首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何为用flask-restplus编写的现有API生成机器可读的yaml规范?

如何为用flask-restplus编写的现有API生成机器可读的yaml规范?
EN

Stack Overflow用户
提问于 2019-01-13 18:56:03
回答 2查看 2K关注 0票数 4

在flask-restplus的帮助下,我编写了一个简单的API:

代码语言:javascript
复制
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文档,但我找不到哪里可以获得机器可读的简单的yaml表示,它不应该也自动生成吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-01-13 22:14:58

我在官方flask-restplus docs中找不到任何关于"Swagger Yaml文档生成“的信息。因此,我决定检查源代码,并发现Swagger类实现了应用程序接口实例的Swagger文档生成。

flask restplus源代码中的Swagger类是一个API实例的Swagger文档包装器。该类中的所有方法都建议将API数据序列化为JSON字典。例如,考虑这个类的as_dict()函数,它将完整的Swagger规范序列化为可序列化的dict。看一下这个函数的文档字符串:

代码语言:javascript
复制
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文档。我使用jsonyaml库将/swagger.json的json响应转储到YAML中,并将其保存到yamldoc.yml中。您可以通过转到http://localhost:5000/swagger.yml来调用它。完整的代码:

代码语言:javascript
复制
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) 

我希望这能帮到你。

票数 5
EN

Stack Overflow用户

发布于 2020-03-12 16:46:54

在@amanb answer中,我让我的api返回一个yaml文件,而没有发出任何请求。根据flask restplus (或者,最新的分支,flask restx)的文档,可以使用export the Swagger specififcations corresponding to your API

代码语言:javascript
复制
from flask import json

from myapp import api

print(json.dumps(api.__schema__))

因此,我更喜欢使用api.__schema__,而不是使用requests

由于我的目标是在请求时提供供下载的文件,因此有必要使用Flasksend_file函数。此外,这个文件可以在以后从目录中删除,这样我们就可以使用Flaskafter_this_request装饰器来调用将删除该文件的带注释的函数。完整的代码:

代码语言:javascript
复制
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) 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54168159

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档