Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Flask automatically generated Swagger/OpenAPI 3.0 [closed]

Im trying to generate swagger document for my existing Flask app, I tried with Flask-RESTPlus initially and found out the project is abundant now and checked at the forked project flask-restx https://github.com/python-restx/flask-restx but still i dont think they support openapi 3.0

Im a bit confused to choose the package for my need. Im looking to solve a problem where we dont want to manually create swagger doc for our API, instead we would like to generate automatically using a packages.

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)

The above code is a combination of my try on different packages, but it can generate swagger 2.0 doc but im trying to generate doc for openapi 3.0

Can some one suggest a good package which is supporting openapi 3.0 way of generating swagger yaml or json.

like image 418
DonOfDen Avatar asked May 28 '20 13:05

DonOfDen


People also ask

Is Swagger auto generated?

You can write a Swagger spec for your API manually, or have it generated automatically from annotations in your source code.

What is the difference between Swagger and OpenAPI?

OpenAPI and Swagger used to refer to the same thing. While there are differences today (OpenAPI refers to RESTful API design and Swagger refers to a set of SmartBear tools), this blog will use the terms interchangeably. If you develop software today, chances are you are developing web APIs as well.


1 Answers

I found a package to generate openapi 3.0 document

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

This package serves the purpose neatly. Find the below code for detailed usage.

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="[email protected]"
            ), 
        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())

Hope this helps someone!! :)

Update: More Detailed Documents

Python Flask automatically generated Swagger 3.0/Openapi Document - http://donofden.com/blog/2020/06/14/Python-Flask-automatically-generated-Swagger-3-0-openapi-Document

Python Flask automatically generated Swagger 2.0 Document - http://donofden.com/blog/2020/05/30/Python-Flask-automatically-generated-Swagger-2-0-Document

like image 134
DonOfDen Avatar answered Oct 12 '22 20:10

DonOfDen