Search code examples
pythonflaskswagger-uiopenapi

How to generate OpenAPI docs (Swagger UI) page using static .yaml file with Flask?


I'm working on RESTful API flask server and I need to make endpoint to render my API using static file (.yaml). I've tried flask_swagger_ui, but I couldn't get how to specify path to local file. I'm quite new to develop RESTful API and flask servers, so I'd be happy to get some advices how to do what I want the right way.


Solution

  • Assuming you have a spec file called openapi.yaml. If you want to host the API docs by yourself, you can follow the following steps:

    1. Create a file called app.py, then create two view to serve the spec file and the Swagger UI page:
    from flask import Flask, render_template, send_from_directory
    
    app = Flask(__name__)
    
    
    @app.route('/docs')
    def swagger_ui():
        return render_template('swagger_ui.html')
    
    
    @app.route('/spec')
    def get_spec():
        return send_from_directory(app.root_path, 'openapi.yaml')
    
    1. Create a template called swagger_ui.html in the templates folder with the following content:
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <title>Swagger UI</title>
        <link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@3//swagger-ui.css" >
        <style>
          html
          {
            box-sizing: border-box;
            overflow: -moz-scrollbars-vertical;
            overflow-y: scroll;
          }
    
          *,
          *:before,
          *:after
          {
            box-sizing: inherit;
          }
    
          body
          {
            margin:0;
            background: #fafafa;
          }
        </style>
      </head>
    
      <body>
        <div id="swagger-ui"></div>
    
        <script src="https://unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js"></script>
        <script src="https://unpkg.com/swagger-ui-dist@3/swagger-ui-standalone-preset.js"></script>
        <script>
          window.onload = function() {
          const ui = SwaggerUIBundle({
            url: "{{ url_for('get_spec') }}",
            dom_id: '#swagger-ui',
            deepLinking: true,
            presets: [
              SwaggerUIBundle.presets.apis,
              SwaggerUIStandalonePreset
            ],
            plugins: [
              SwaggerUIBundle.plugins.DownloadUrl
            ],
            layout: "BaseLayout"
          })
        }
        </script>
      </body>
    </html>
    

    The final file structure will be like this:

    - app.py
    - templates
        - swagger_ui.html
    - openapi.yaml
    
    1. Now run the app with:
    $ flask run
    
    1. Then go to http://localhost:5000/docs.