Python Flask自动生成Swagger/OpenAPI 3.0

18
我正试图为现有的Flask应用生成Swagger文档,最初尝试使用Flask-RESTPlus,发现该项目已不再维护,并转到了分支项目flask-restx https://github.com/python-restx/flask-restx,但我仍然认为它们不支持OpenAPI 3.0。
我有点困惑该选择哪个软件包满足我的需求。 我正在寻找解决方案,我们不想为API手动创建Swagger文档,而是希望使用软件包自动生成。
import os
import requests
import json, yaml


from flask import Flask, after_this_request, send_file, safe_join, abort
from flask_restx import Resource, Api, fields
from flask_restx.api import Swagger

app = Flask(__name__)
api = Api(app=app, doc='/docs', version='1.0.0-oas3', title='TEST APP API',
          description='TEST APP API')


response_fields = api.model('Resource', {
    'value': fields.String(required=True, min_length=1, max_length=200, description='Book title')
})


@api.route('/compiler/', endpoint='compiler')
# @api.doc(params={'id': 'An ID'})
@api.doc(responses={403: 'Not Authorized'})
@api.doc(responses={402: 'Not Authorized'})
# @api.doc(responses={200: 'Not Authorized'})
class DemoList(Resource):
    @api.expect(response_fields, validate=True)
    @api.marshal_with(response_fields, code=200)
    def post(self):
        """
        returns a list of conferences
        """
        api.payload["value"] = 'Im the response ur waiting for'
        return api.payload


@api.route('/swagger')
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)


# main driver function
if __name__ == '__main__':
    app.run(port=5003, debug=True)

以上代码是我尝试使用不同的包组合而成的,它可以生成Swagger 2.0文档,但我正在尝试生成OpenAPI 3.0的文档。

有人能否推荐一个支持以OpenAPI 3.0方式生成Swagger YAML或JSON的好包?


apiflask(https://apiflask.com/openapi/)似乎也是一个不错的选择。 - Renato Byrro
3
像这样的问题不应该被关闭。这个问题并不是在寻求意见上的建议,而只是指出某个软件系统没有最新的功能,并询问规范的替代方案在哪里。 - NeilG
1个回答

23

我找到了一个生成openapi 3.0文档的包。

https://apispec.readthedocs.io/en/latest/install.html

这个包非常方便。以下是详细使用代码。

from apispec import APISpec
from apispec.ext.marshmallow import MarshmallowPlugin
from apispec_webframeworks.flask import FlaskPlugin
from marshmallow import Schema, fields
from flask import Flask, abort, request, make_response, jsonify
from pprint import pprint
import json


class DemoParameter(Schema):
    gist_id = fields.Int()


class DemoSchema(Schema):
    id = fields.Int()
    content = fields.Str()


spec = APISpec(
    title="Demo API",
    version="1.0.0",
    openapi_version="3.0.2",
    info=dict(
        description="Demo API",
        version="1.0.0-oas3",
        contact=dict(
            email="admin@donofden.com"
            ), 
        license=dict(
            name="Apache 2.0",
            url='http://www.apache.org/licenses/LICENSE-2.0.html'
            )
        ),
    servers=[
        dict(
            description="Test server",
            url="https://resources.donofden.com"
            )
        ],
    tags=[
        dict(
            name="Demo",
            description="Endpoints related to Demo"
            )
        ],
    plugins=[FlaskPlugin(), MarshmallowPlugin()],
)

spec.components.schema("Demo", schema=DemoSchema)

# spec.components.schema(
#     "Gist",
#     {
#         "properties": {
#             "id": {"type": "integer", "format": "int64"},
#             "name": {"type": "string"},
#         }
#     },
# )
#
# spec.path(
#     path="/gist/{gist_id}",
#     operations=dict(
#         get=dict(
#             responses={"200": {"content": {"application/json": {"schema": "Gist"}}}}
#         )
#     ),
# )
# Extensions initialization
# =========================
app = Flask(__name__)


@app.route("/demo/<gist_id>", methods=["GET"])
def my_route(gist_id):
    """Gist detail view.
    ---
    get:
      parameters:
      - in: path
        schema: DemoParameter
      responses:
        200:
          content:
            application/json:
              schema: DemoSchema
        201:
          content:
            application/json:
              schema: DemoSchema
    """
    # (...)
    return jsonify('foo')


# Since path inspects the view and its route,
# we need to be in a Flask request context
with app.test_request_context():
    spec.path(view=my_route)
# We're good to go! Save this to a file for now.
with open('swagger.json', 'w') as f:
    json.dump(spec.to_dict(), f)

pprint(spec.to_dict())
print(spec.to_yaml())

希望这可以帮助到某人!! :)

更新:更详细的文档

Python Flask自动生成Swagger 3.0/Openapi文档 - http://donofden.com/blog/2020/06/14/Python-Flask-automatically-generated-Swagger-3-0-openapi-Document

Python Flask自动生成Swagger 2.0文档 - http://donofden.com/blog/2020/05/30/Python-Flask-automatically-generated-Swagger-2-0-Document


1
apiflask(https://apiflask.com/openapi/)似乎也是一个不错的选择。 - Renato Byrro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接