Flask Python- Swagger for rest apis

Dipto Chakrabarty
5 min readMay 14, 2023

We build a simple flask api with get and post methods based api requests.

Link for the code present at end of the blog.

from crypt import methods
from flask import Flask,jsonify,request

app = Flask(__name__)

@app.route("/")
def home():
return jsonify({
"Message": "app up and running successfully"
})

@app.route("/access",methods=["POST"])
def access():
data = request.get_json()
name = data.get("name", "dipto")
server = data.get("server","server1")

message = f"User {name} received access to server {server}"

return jsonify({
"Message": message
})


if __name__=="__main__":
app.run(debug=True,host="0.0.0.0",port=8080)

The api runs at port 8080 , run the api using the command python3 app.py.

The endpoints present are

  • / -> returns simple response no parameters
  • /access -> returns custom message expects a name and server

Send curl requests to verify api working

- Get Request

curl http://localhost:8080/


- POST Request

curl -X POST -H "Content-Type: application/json" \
-d '{"name": "ezio", "server": "dchost"}' \
http://localhost:8080/access
API working for both endpoints

To use swagger with the api we require the flask_swagger_ui package

pip3 install flask_swagger_ui

Once installed add this section to the flask code

from flask_swagger_ui import get_swaggerui_blueprint

SWAGGER_URL="/swagger"
API_URL="/static/swagger.json"

swagger_ui_blueprint = get_swaggerui_blueprint(
SWAGGER_URL,
API_URL,
config={
'app_name': 'Access API'
}
)
app.register_blueprint(swagger_ui_blueprint, url_prefix=SWAGGER_URL)

We mention the endpoint we want swagger docs to be visible using SWAGGER_URL variable , in this case it be /swagger

We mention the json file which contains the endpoints definition for the api under API_URL

Finally the get_swaggerui_blueprint is used to create a config for the swagger endpoint and it is registered within the app using the register_blueprint method.

Building the swagger docs definition file

Create a directory static and create a file swagger.json.

(Complete json file is present at the end if you want to skip to that part)

Add the initial part for the swagger file which is added at the starting of a swagger file.

{
"swagger": "2.0",
"info": {
"title": "Access API",
"version": "1.0.0"
},

Now we go ahead and add the paths , the first path is the get request which is at ‘/’ endpoint.

  • It does not take any parameters from request
  • It returns a single response a json

Paths/endpoints are added under the paths key in the json

The simple get request will look like this

"paths": {
"/": {
"get": {
"description": "Returns message showing app is up",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Successful operation"
}
}
}
},

We mention what will be endpoint -> ‘/’

The method is mentioned first under which all other information is provided which includes

  • description for the endpoint
  • produces: what is response from the endpoint
  • responses: the expected responses

Run the app and head to port 8080/swagger to view the swagger endpoints

GET request added to swagger docs

Send the request using the ‘try it out’ and execute button

Request Successful

Let us now get into the post request which is complicated reliatively

Since we parse the data from json for the post request we need to add two components

  • paths: similar to get request this will contain all the information about the endpoint
  • definitions: this contains the type of schema to be expected for json requests

The definitions will be defined like this

"definitions": {
"AccessData": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"server": {
"type": "string"
}
}
}
}

As the api expects the user to provide values for ‘name’ and ‘server’ in its payload we define the parameters under properties.

The ‘AccessData’ is the name of the schema , we can have multiple schemas under definitions if we require different variations of payloads in different endpoints.

This schema will be mapped to the endpoints path so swagger is aware of what to expect.

"/access": {
"post": {
"description": "Grants access to an user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"name": "access data",
"in": "body",
"description": "JSON data for the api",
"required": true,
"schema": {
"$ref": "#/definitions/AccessData"
}
}
],
"responses": {
"200": {
"description": "User granted access"
},
"400": {
"description": "Invalid request data"
}
}
}
}

We define the endpoint under which we define the type of request

  • produces: the type of response to expect
  • consumes: the type of request that it will accept
  • parameters: the data about the endpoint , the schema defined above is mapped here so swagger is aware what type of requests to pickup and what type of requests to deny
  • responses : based on the type of data provided either return 200 or 400

Running the app again and heading to /swagger endpoint

Execute the api using custom data

Send payload
Response obtained

Complete Swagger doc

{
"swagger": "2.0",
"info": {
"title": "Access API",
"version": "1.0.0"
},
"paths": {
"/": {
"get": {
"description": "Returns message showing app is up",
"produces": [
"application/json"
],
"responses": {
"200": {
"description": "Successful operation"
}
}
}
},
"/access": {
"post": {
"description": "Grants access to an user",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"name": "access data",
"in": "body",
"description": "JSON data for the api",
"required": true,
"schema": {
"$ref": "#/definitions/AccessData"
}
}
],
"responses": {
"200": {
"description": "User granted access"
},
"400": {
"description": "Invalid request data"
}
}
}
}
},
"definitions": {
"AccessData": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"server": {
"type": "string"
}
}
}
}
}

Code can be found here -> Link to github repository.

--

--

Dipto Chakrabarty

Site Reliability Engineer , I talk about Devops Backend and AI. Tech Doctor making sure to diagnose and make your apps run smoothly in production.