This is a simple guide on how to add Swagger UI to your plain flask API project without using any additional libraries.
As I wanted a way to get Swagger UI implemented in my POC work in order to quickly show the intended functions to stakeholders. And there was no simple way to do it. All the youtube videos or online articles pointed to using libraries like flask-swagger-ui or FastAPI etc. I didn’t want to use any of those and even the official Swagger UI recommends running it as a docker container, which is overkill for something so simple. So this is the way I managed to do it.
Step 1: Download Swagger UI GitHub repo
Download Swagger UI from GitHub and extract it. We are basically interested in the dist directory in this archive.
Step 2: Copy the files from dist to your project directory
- In your project directory create 2 directories
templatesandstatic - Move
index.htmlfromdisttotemplatesdirectory and rename it toswaggerui.html - Inside
staticdirectory, create 3 more directories,css,imgandjs - Move
.jsfiles fromdisttostatic/js - Move
.cssfiles fromdisttostatic/css - Move
.pngfiles fromdisttostatic/img
Your project directory should now look like this
.
├── static
│ ├── css
│ │ └── swagger-ui.css
│ ├── img
│ │ ├── favicon-16x16.png
│ │ └── favicon-32x32.png
│ └── js
│ ├── swagger-ui-bundle.js
│ ├── swagger-ui-standalone-preset.js
│ └── swagger-ui.js
└── templates
├── swaggerui.html
Step 3: Edit swaggerui.html and replace all static url with Jinja2 template tags
7 <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/swagger-ui.css') }}">
8 <link rel="icon" type="image/png" href="{{ url_for('static', filename='img/favicon-32x32.png') }}" sizes="32x32"/>
9 <link rel="icon" type="image/png" href="{{ url_for('static', filename='img/favicon-16x16.png') }}" sizes="16x16"/>
36 <script src="{{ url_for('static', filename='js/swagger-ui-bundle.js') }}"> </script>
37 <script src="{{ url_for('static', filename='js/swagger-ui-standalone-preset.js') }}"> </script>
Step 4: Write your API spec in OpenAPI format
- Go to swagger editor and write your API spec in YAML. Here is a Sample API spec:
- Go to
Filemenu in Swagger editor and click onConvert and save as JSON - Place the downloaded
openapi.jsonfile in your projects'staticdirectory - Update the reference for the source json file (line 42) in
swaggerui.htmlfile to refer to the spec file in static directory
url: "{{ url_for('static', filename='openapi.json') }}",
Step 5: Return swaggerui.html with flask render_template in your preferred route
- Create
hello_api.pyin your project directory with the following code
- Run the app with command:
python3 hello_api.pyfrom your project directory - Your SwaggerUI documentation should be accessible on http://localhost:5000/api/docs
I have created a boilerplate flask app for anyone to use this setup with ease.
Top comments (7)
Hi Sanjan, I'm trying to change the names of static, templates folder to my desired name. But, it's not accepting.
I have changed the name of directories used in the swaggerui.html also. Still the same issue.
Is there any way we can use our desired name for these two folders ?
these are the default folders looked at by flask's render template. but you can customize them if you want. have a look at: stackoverflow.com/questions/310028...
You sir, deserve a trophy!
This was really easy to follow! Big thanks
God sent thanks
For those who reads this in 2022.
1) The URL to
openapi.jsonis now defined inswagger-initializer.js, so, to get the URL, you, for example, have to render it first as a custom node attribute in yourswaggerui.html:And then obtain the URL in
swagger-initializer.js, like that:2) You may use
openapi.yamldirectly, no need to convert to JSON.And, btw, this way of using swagger in you Flask app is the most generic, clean and easy. Packages like flasgger, flask-apispec etc., are great, but buggy and brings unnecessary semantics to your code. Thank you Sanjan to share it.
Hi Sanjan,
I am using connexion to create FlaskAPP and then adding my yaml to it using something like
app = connexion.App(...)
app.add_api('openapi.yaml', arguments={'title': 'testapp'})
This properly serves my endpoints on a beautiful swagger page with all the documentation. But I need to do some customization on the swagger page, like change the color coding on the endpoints and change the page logo.
It is not picking my static files, although I found a solution on the readthedocs website for using SwaggerUIOptions class, it doesnt work for me.
Do u happen to know a way to serve the static files with connexion app?