Most fashionable internet functions are powered by a REST API underneath the hood. That approach, builders can separate the front-end code from the back-end logic, and customers can work together with the interface dynamically. On this three-part tutorial sequence, you’ll construct a REST API with the Flask internet framework.
You’ll create a basis with a primary Flask venture then add endpoints and join them to a SQLite database. You’ll check your API with Swagger UI API documentation that you simply’ll construct alongside the best way.
Within the first a part of this tutorial sequence, you’ll discover ways to:
- Construct a base Flask venture with a REST API
- Deal with HTTP requests with Connexion
- Outline API endpoints utilizing the OpenAPI specification
- Work together along with your API to handle knowledge
- Construct API documentation with Swagger UI
After ending the primary a part of this sequence, you’ll transfer on to the second half, the place you’ll be taught to make use of a correct database to retailer your knowledge completely as a substitute of counting on in-memory storage.
This tutorial sequence is a hand-on information on the right way to create a REST API with Flask and work together with it utilizing CRUD operations. If you wish to refresh your information on working with APIs, then you definately can provide Python and REST APIs: Interacting With Web Services a learn.
You possibly can obtain the code for the primary a part of this venture by clicking the hyperlink under:
Demo
On this three-part tutorial sequence, you’ll construct a REST API to maintain observe of notes for those that might go to you all year long. On this tutorial, you’ll create folks just like the Tooth Fairy, the Easter Bunny, and Knecht Ruprecht.
Ideally, you wish to be on good phrases with all three of them. That’s why you’ll ship them notes, to extend the prospect of getting priceless items from them.
You possibly can work together along with your utility by leveraging the API documentation. Alongside the best way, you’ll construct a primary entrance finish that displays the contents of your database:
Within the first a part of this sequence, you’ll create a base Flask venture and plug in your first API endpoints. On the finish of this half, you’ll be capable of see a listing of individuals within the entrance finish and handle every particular person within the again finish:
By leveraging Swagger UI, you’ll create useful documentation to your API alongside the best way. That approach, you’ll have the chance to check how your API works at every stage of this tutorial and get a helpful overview of all of your endpoints.
Planning Half One
Moreover constructing the Flask venture basis, you’re going to create a REST API that gives entry to a group of individuals and to the people inside that assortment. Right here’s the API design for the folks assortment:
Motion | HTTP Verb | URL Path | Description |
---|---|---|---|
Learn | GET |
/api/folks |
Learn a group of individuals. |
Create | POST |
/api/folks |
Create a brand new particular person. |
Learn | GET |
/api/folks/<lname> |
Learn a selected particular person. |
Replace | PUT |
/api/folks/<lname> |
Replace an present particular person. |
Delete | DELETE |
/api/folks/<lname> |
Delete an present particular person. |
The REST API that you simply’ll be constructing will serve a easy folks knowledge construction the place the individuals are keyed to the final title, and any updates are marked with a brand new timestamp.
The dataset that you simply’ll be working with seems to be like this:
PEOPLE =
"Fairy":
"fname": "Tooth",
"lname": "Fairy",
"timestamp": "2022-10-08 09:15:10",
,
"Ruprecht":
"fname": "Knecht",
"lname": "Ruprecht",
"timestamp": "2022-10-08 09:15:13",
,
"Bunny":
"fname": "Easter",
"lname": "Bunny",
"timestamp": "2022-10-08 09:15:27",
One of many functions of an API is to decouple the information from the applying that makes use of it, thereby hiding the information implementation particulars. Later on this tutorial sequence, you’ll save your knowledge in a database. However for the beginning, an in-memory knowledge construction works advantageous.
Getting Began
On this part, you’ll put together the event atmosphere to your Flask REST API venture. First, you’ll create a digital atmosphere and set up all of the dependencies that you simply want to your venture.
Create a Digital Surroundings
On this part, you’ll construct your venture construction. You possibly can title the foundation folder of your venture any approach you want. For instance, you possibly can title it rp_flask_api/
. Create the folder and navigate into it:
$ mkdir rp_flask_api
$ cd rp_flask_api
On this case, you title the foundation folder of your venture rp_flask_api/
. The recordsdata and folders that you simply create over the course of this sequence might be situated in both this folder or its subfolders.
After you navigate to the venture folder, it’s a good suggestion to create and activate a virtual environment. That approach, you’re putting in any venture dependencies not system-wide however solely in your venture’s digital atmosphere.
Choose your working system under and use your platform-specific command to arrange a digital atmosphere:
With the instructions proven above, you create and activate a digital atmosphere named venv
by utilizing Python’s built-in venv
module. The parenthesized (venv)
in entrance of the immediate point out that you simply’ve efficiently activated the digital atmosphere.
Add Dependencies
After you’ve created and activated your digital atmosphere, it’s time to put in Flask with pip
:
(venv) $ python -m pip set up Flask==2.2.2
The Flask micro internet framework is the the primary dependency that your venture requires. On high of Flask, set up Connexion to deal with the HTTP requests:
(venv) $ python -m pip set up "connexion[swagger-ui]==2.14.1"
To additionally make use of auto-generated API documentation, you put in Connexion with the added assist for Swagger UI. Later on this tutorial, you’ll be taught extra in regards to the Python packages that you simply simply put in.
Provoke Your Flask Undertaking
The primary file of your Flask venture might be app.py
. Create app.py
in rp_flask_api/
and add the next content material:
# app.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def residence():
return render_template("residence.html")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000, debug=True)
You import the Flask
module, giving the applying entry to the Flask performance. You then create a Flask utility occasion named app
. Subsequent, you join the URL route "https://realpython.com/"
to the residence()
perform by decorating it with @app.route("https://realpython.com/")
. This perform calls the Flask render_template()
perform to get the residence.html
file from the templates listing and return it to the browser.
Briefly, this code will get a primary internet server up and working and makes it reply with a residence.html
template, which might be served to a browser when navigating to the URL "https://realpython.com/"
.
Flask expects residence.html
in a template listing named templates/
. Create the templates/
listing and add residence.html
:
<!-- templates/residence.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>RP Flask REST API</title>
</head>
<physique>
<h1>
Whats up, World!
</h1>
</physique>
</html>
Flask comes with the Jinja Templating Engine, which allows you to improve your templates. However your residence.html
template is a primary HTML file with none Jinja options. That’s okay for now, as a result of the aim of residence.html
is to confirm that your Flask venture responds as meant.
With the Python digital atmosphere energetic, you may run your utility with this command line within the listing containing the app.py
file:
Once you run app.py
, an online server will begin on port 8000. In the event you open a browser and navigate to http://localhost:8000
, you need to see Whats up, World! displayed:

Congratulations, your internet server is working! You’ll lengthen the residence.html
file later to work with the REST API that you simply’re creating.
By now, your Flask venture construction ought to seem like this:
rp_flask_api/
│
├── templates/
│ └── residence.html
│
└── app.py
It is a nice construction for beginning any Flask venture. You might discover that the supply code will turn out to be useful while you’re engaged on future initiatives. You possibly can obtain it right here:
Within the subsequent sections, you’ll broaden the venture and add your first REST API endpoints.
Including Your First REST API Endpoint
Now that you simply’ve bought a working internet server, you may add your first REST API endpoint. To do that, you’ll use Connexion, which you put in within the earlier part.
The Connexion module permits a Python program to make use of the OpenAPI specification with Swagger. The OpenAPI Specification is an API description format for REST APIs and supplies lots of performance, together with:
- Validation of enter and output knowledge to and out of your API
- Configuration of the API URL endpoints and the anticipated parameters
Once you use OpenAPI with Swagger, you may create a consumer interface (UI) to discover the API. All of this will occur while you create a configuration file that your Flask utility can entry.
Create the API Configuration File
The Swagger configuration file is a YAML or JSON file containing your OpenAPI definitions. This file incorporates all the info essential to configure your server to offer enter parameter validation, output response knowledge validation, and URL endpoint definition.
Create a file named swagger.yml
and start including metadata to it:
# swagger.yml
openapi: 3.0.0
data:
title: "RP Flask REST API"
description: "An API about folks and notes"
model: "1.0.0"
Once you outline an API, you need to embody the model of your OpenAPI definition. You utilize the openapi
key phrase for this. The model string is vital as a result of some components of the OpenAPI construction might change over time.
Additionally, similar to every new Python model consists of new features, there could also be key phrases added or deprecated within the OpenAPI specification.
The data
key phrase begins the scope of the API info block:
title:
Title included within the Connexion-generated UI systemdescription:
Description of what the API supplies or is aboutmodel:
Model worth for the API
Subsequent, add servers
and url
, which outline the foundation path of your API:
# swagger.yml
# ...
servers:
- url: "/api"
By offering "/api"
as the worth of url
, you’ll be capable of entry your whole API paths relative to http://localhost:8000/api
.
You outline your API endpoints in a paths
block:
# swagger.yml
# ...
paths:
/folks:
get:
operationId: "folks.read_all"
tags:
- "Individuals"
abstract: "Learn the listing of folks"
responses:
"200":
description: "Efficiently learn folks listing"
The paths
block begins the configuration of the API URL endpoint paths:
/folks:
The relative URL of your API endpointget:
The HTTP methodology that this URL endpoint will reply to
Along with the url
definition in servers
, this creates the GET /api/folks
URL endpoint that you could entry at http://localhost:8000/api/folks
.
The get
block begins the configuration of the one /api/folks
URL endpoint:
operationId:
The Python perform that’ll reply to the requesttags:
The tags assigned to this endpoint, which let you group the operations within the UIabstract
: The UI show textual content for this endpointresponses
: The standing codes that the endpoint responds with
operationId
should comprise a string. Connexion will use "folks.read_all"
to discover a Python perform named read_all()
in a folks
module of your venture. You’ll create the corresponding Python code later on this tutorial.
The responses
block defines the configuration of the doable standing codes. Right here, you outline a profitable response for the standing code "200"
, containing some description
textual content.
You will discover the whole content material of the swagger.yml
file within the collapsible under:
Under, you’ll discover the total supply code of your OpenAPI definition:
# swagger.yml
openapi: 3.0.0
data:
title: "RP Flask REST API"
description: "An API about folks and notes"
model: "1.0.0"
servers:
- url: "/api"
paths:
/folks:
get:
operationId: "folks.read_all"
tags:
- "Individuals"
abstract: "Learn the listing of folks"
responses:
"200":
description: "Efficiently learn folks listing"
You’ve organized this file in a hierarchical method. Every indentation degree represents a degree of possession, or scope.
For instance, paths
marks the start of the place all of the API URL endpoints are outlined. The /folks
worth indented underneath that represents the beginning of the place all of the /api/folks
URL endpoints might be outlined. The get:
scope indented underneath /folks
holds the definitions related to an HTTP GET request to the /api/folks
URL endpoint. This sample goes on for your complete configuration.
The swagger.yml
file is sort of a blueprint to your API. With the specs that you simply embody in swagger.yml
, you outline what knowledge your internet server can count on and the way your server ought to reply to requests. However up to now, your Flask venture doesn’t learn about your swagger.yml
file. Learn on to make use of Connexion to attach your OpenAPI specification along with your Flask app.
Add Connexion to the App
There are two steps to including a REST API URL endpoint to your Flask utility with Connexion:
- Add an API configuration file to your venture.
- Join your Flask app with the configuration file.
You already added a configuration file named swagger.yml
within the final part. To attach the API configuration file along with your Flask app, you need to reference swagger.yml
in your app.py
file:
1# app.py
2
3from flask import render_template # Take away: import Flask
4import connexion
5
6app = connexion.App(__name__, specification_dir="./")
7app.add_api("swagger.yml")
8
9@app.route("/")
10def residence():
11 return render_template("residence.html")
12
13if __name__ == "__main__":
14 app.run(host="0.0.0.0", port=8000, debug=True)
The import connexion
assertion provides the module to this system. The subsequent step is creating the applying occasion utilizing Connexion quite than Flask. Internally, the Flask app remains to be created, nevertheless it now has further performance added to it.
A part of the app occasion creation consists of the parameter specification_dir
in line 6. This tells Connexion which listing to look in for its configuration file. On this case, it’s the identical listing that you simply run app.py
from.
In line 7, you inform the app occasion to learn the swagger.yml
file from the specification listing and configure the system to offer the Connexion performance.
Return Knowledge From Your Individuals Endpoint
Within the swagger.yml
file, you configured Connexion with the operationId
worth "folks.read_all"
. So, when the API will get an HTTP request for GET /api/folks
, your Flask app calls a read_all()
perform inside a folks
module.
To make this work, create a folks.py
file with a read_all()
perform:
1# folks.py
2
3from datetime import datetime
4
5def get_timestamp():
6 return datetime.now().strftime(("%Y-%m-%d %H:%M:%S"))
7
8PEOPLE =
9 "Fairy":
10 "fname": "Tooth",
11 "lname": "Fairy",
12 "timestamp": get_timestamp(),
13 ,
14 "Ruprecht":
15 "fname": "Knecht",
16 "lname": "Ruprecht",
17 "timestamp": get_timestamp(),
18 ,
19 "Bunny":
20 "fname": "Easter",
21 "lname": "Bunny",
22 "timestamp": get_timestamp(),
23
24
25
26def read_all():
27 return listing(PEOPLE.values())
In line 5, you create a helper perform named get_timestamp()
that generates a string illustration of the present timestamp.
You then outline the PEOPLE
dictionary knowledge construction in line 8, which is the information you’ll work with on this a part of the tutorial sequence.
The PEOPLE
dictionary stands in for a correct database. As PEOPLE
is a module variable, its state persists between REST API calls. Nevertheless, any knowledge that you simply change might be misplaced while you restart your internet utility. This isn’t splendid, nevertheless it’s advantageous for now.
You then create the read_all()
perform in line 26. Your server will run read_all()
when it receives an HTTP request to GET /api/folks
. The return worth of read_all()
is a listing of dictionaries with details about an individual.
Working your server code and navigating your browser to http://localhost:8000/api/folks
will show the listing of individuals on-screen:

Congratulations, you’ve created your first API endpoint! Earlier than persevering with in your strategy to constructing out your REST API with a number of endpoints, take a second and discover the API a bit extra within the subsequent part.
Discover Your API Documentation
Presently you’ve gotten a REST API working with a single URL endpoint. Your Flask app is aware of what to serve based mostly in your API specification in swagger.yml
. Moreover, Connexion makes use of swagger.yml
to create API documentation for you.
Navigate to localhost:8000/api/ui
to see your API documentation in motion:

That is the preliminary Swagger interface. It exhibits the listing of URL endpoints supported at your http://localhost:8000/api
endpoint. Connexion builds this robotically when it parses the swagger.yml
file.
In the event you click on on the /folks
endpoint within the interface, then the interface will broaden to indicate extra details about your API:
This shows the construction of the anticipated response, the content-type
of that response, and the outline textual content that you simply entered in regards to the endpoint within the swagger.yml
file. Any time the configuration file adjustments, the Swagger UI adjustments as nicely.
You possibly can even attempt the endpoint out by clicking the Attempt it out button. This characteristic could be extraordinarily helpful when your API grows. The Swagger UI API documentation offers you a strategy to discover and experiment with the API with out having to jot down any code to take action.
Utilizing OpenAPI with the Swagger UI provides a pleasant, clear strategy to create the API URL endpoints. To date, you’ve solely created one endpoint to serve all folks. Within the subsequent part, you’ll add further endpoints to create, replace, and delete folks in your assortment.
Constructing Out the Full API
To date, your Flask REST API has one endpoint. Now it’s time to construct out an API offering full CRUD entry to your folks construction. As you recall, the definition of your API seems to be like this:
Motion | HTTP Verb | URL Path | Description |
---|---|---|---|
Learn | GET |
/api/folks |
Learn a group of individuals. |
Create | POST |
/api/folks |
Create a brand new particular person. |
Learn | GET |
/api/folks/<lname> |
Learn a selected particular person. |
Replace | PUT |
/api/folks/<lname> |
Replace an present particular person. |
Delete | DELETE |
/api/folks/<lname> |
Delete an present particular person. |
To realize this, you’ll lengthen each the swagger.yml
and folks.py
recordsdata to totally assist the API outlined above.
Work With Parts
Earlier than you outline new API paths in swagger.yml
, you’ll add a brand new block for parts. Components are constructing blocks in your OpenAPI specification that you could reference from different components of your specification.
Add a parts
block with schemas
for a single particular person:
# swagger.yml
openapi: 3.0.0
data:
title: "RP Flask REST API"
description: "An API about folks and notes"
model: "1.0.0"
servers:
- url: "/api"
parts:
schemas:
Particular person:
kind: "object"
required:
- lname
properties:
fname:
kind: "string"
lname:
kind: "string"
# ...
To keep away from code duplication, you create a parts
block. For now, you save solely the Particular person
knowledge mannequin within the schemas
block:
kind:
The information kind of the schemarequired:
The required properties
The sprint (-
) in entrance of - lname
signifies that required
can comprise a listing of properties. Any property that you simply outline as required
should additionally exist in properties
, which incorporates the next:
fname:
The primary title of an individuallname:
The final title of an individual
The kind
key defines the worth related to its mum or dad key. For Particular person
, all properties are strings. You’ll characterize this schema in your Python code as a dictionary later on this tutorial.
Create a New Particular person
Prolong your API endpoints by including a brand new block for the publish
request within the /folks
block:
# swagger.yml
# ...
paths:
/folks:
get:
# ...
publish:
operationId: "folks.create"
tags:
- Individuals
abstract: "Create a particular person"
requestBody:
description: "Particular person to create"
required: True
content material:
utility/json:
schema:
x-body-name: "particular person"
$ref: "#/parts/schemas/Particular person"
responses:
"201":
description: "Efficiently created particular person"
The construction for publish
seems to be just like the present get
schema. One distinction is that you simply additionally ship requestBody
to the server. In any case, it is advisable inform Flask the data that it must create a brand new particular person. One other distinction is operationId
, which you set to folks.create
.
Inside content material
, you outline utility/json
because the knowledge alternate format of your API.
You possibly can serve totally different media sorts in your API requests and API responses. These days APIs generally use JSON as the information alternate format. That is excellent news for you as a Python developer, as a result of JSON objects look very very similar to Python dictionaries. For instance:
"fname": "Tooth",
"lname": "Fairy"
This JSON object resembles the Particular person
part that you simply have been defining earlier in swagger.yml
and that you simply’re referencing with $ref
in schema
.
You’re additionally utilizing a 201 HTTP standing code, which is successful response that signifies the creation of a brand new useful resource.
Be aware: If you wish to be taught extra about HTTP standing codes, then you may take a look at Mozilla’s documentation about HTTP response status codes.
With folks.create
, you’re telling your server to search for a create()
perform within the folks
module. Open folks.py
and add create()
to the file:
1# folks.py
2
3from datetime import datetime
4from flask import abort
5
6# ...
7
8def create(particular person):
9 lname = particular person.get("lname")
10 fname = particular person.get("fname", "")
11
12 if lname and lname not in PEOPLE:
13 PEOPLE[lname] =
14 "lname": lname,
15 "fname": fname,
16 "timestamp": get_timestamp(),
17
18 return PEOPLE[lname], 201
19 else:
20 abort(
21 406,
22 f"Particular person with final title lname already exists",
23 )
In line 4, you’re importing Flask’s abort()
perform. Utilizing abort()
helps you ship an error message in line 20. You increase the error response when the request physique doesn’t comprise a final title or when an individual with this final title already exists.
Be aware: An individual’s final title have to be distinctive, since you’re utilizing lname
as a dictionary key of PEOPLE
. Meaning you may’t have two folks with the identical final title in your venture for now.
If the information within the request physique is legitimate, you replace PEOPLE
in line 13 and reply with the brand new object and a 201 HTTP code in line 18.
Deal with a Particular person
To date, you’re in a position to create a brand new particular person and get a listing with all of your folks. On this part, you’ll replace swagger.yml
and folks.py
to work with a brand new path that handles a single present particular person.
Open swagger.yml
and add the code under:
# swagger.yml
# ...
parts:
schemas:
# ...
parameters:
lname:
title: "lname"
description: "Final title of the particular person to get"
in: path
required: True
schema:
kind: "string"
paths:
/folks:
# ...
/folks/lname:
get:
operationId: "folks.read_one"
tags:
- Individuals
abstract: "Learn one particular person"
parameters:
- $ref: "#/parts/parameters/lname"
responses:
"200":
description: "Efficiently learn particular person"
Just like your /folks
path, you begin with the get
operation for the /folks/lname
path. The lname
substring is a placeholder for the final title, which it’s important to go in as a URL parameter. So, for instance, the URL path api/folks/Ruprecht
incorporates Ruprecht
as lname
.
Be aware: The URL parameters are case delicate. Meaning you need to kind a final title like Ruprecht with an uppercase R.
You’ll use the lname
parameter in different operations, too. So it is smart to create a part for it and reference it the place wanted.
operationId
factors to a read_one()
perform in folks.py
, so head over to that file once more and create the lacking perform:
# folks.py
# ...
def read_one(lname):
if lname in PEOPLE:
return PEOPLE.get[lname]
else:
abort(
404, f"Particular person with final title lname not discovered"
)
When your Flask app finds the offered final title in PEOPLE
, then it returns the information for this explicit particular person. In any other case, the server will return a 404 HTTP error.
To replace an present particular person, replace swagger.yml
with this code:
# swagger.yml
# ...
paths:
/folks:
# ...
/folks/lname:
get:
# ...
put:
tags:
- Individuals
operationId: "folks.replace"
abstract: "Replace a particular person"
parameters:
- $ref: "#/parts/parameters/lname"
responses:
"200":
description: "Efficiently up to date particular person"
requestBody:
content material:
utility/json:
schema:
x-body-name: "particular person"
$ref: "#/parts/schemas/Particular person"
With this definition of the put
operation, your server expects replace()
in folks.py
:
# folks.py
# ...
def replace(lname, particular person):
if lname in PEOPLE:
PEOPLE[lname]["fname"] = particular person.get("fname", PEOPLE[lname]["fname"])
PEOPLE[lname]["timestamp"] = get_timestamp()
return PEOPLE[lname]
else:
abort(
404,
f"Particular person with final title lname not discovered"
)
The replace()
perform expects the arguments lname
and particular person
. When an individual with the offered final title exists, then you definately replace the corresponding values in PEOPLE
with the particular person
knowledge.
To eliminate an individual in your dataset, it is advisable work with a delete
operation:
# swagger.yml
# ...
paths:
/folks:
# ...
/folks/lname:
get:
# ...
put:
# ...
delete:
tags:
- Individuals
operationId: "folks.delete"
abstract: "Delete a particular person"
parameters:
- $ref: "#/parts/parameters/lname"
responses:
"204":
description: "Efficiently deleted particular person"
Add the corresponding delete()
perform to particular person.py
:
# folks.py
from flask import abort, make_response
# ...
def delete(lname):
if lname in PEOPLE:
del PEOPLE[lname]
return make_response(
f"lname efficiently deleted", 200
)
else:
abort(
404,
f"Particular person with final title lname not discovered"
)
If the particular person you wish to delete exists in your dataset, then you definately take away the merchandise from PEOPLE
.
Each folks.py
and swagger.yml
are full for this a part of the tutorial. You possibly can obtain the whole recordsdata by clicking the hyperlink under:
With all of the endpoints to handle folks in place, it’s time to check out your API. Because you used Connexion to attach your Flask venture with Swagger, your API documentation is prepared for you while you restart your server.
Discover Your Full API Documentation
When you’ve up to date the swagger.yml
and folks.py
recordsdata to finish the folks API performance, the Swagger UI system will replace accordingly and look one thing like this:
This UI means that you can see all the documentation that you simply’ve included within the swagger.yml
file and to work together with all the URL endpoints making up the CRUD performance of the folks interface.
Sadly, any adjustments that you simply make received’t persist while you restart your Flask utility. That’s why you’ll plug a correct database in to your venture within the subsequent a part of this tutorial sequence.
Conclusion
On this a part of the tutorial sequence, you created a complete REST API with Python’s Flask internet framework. With the Connexion module and a few further configuration work, helpful documentation and an interactive system could be put in place. This makes constructing a REST API a really pleasing expertise.
Within the first a part of this tutorial sequence, you discovered the right way to:
- Construct a base Flask venture with a REST API
- Deal with HTTP requests with Connexion
- Outline API endpoints utilizing the OpenAPI specification
- Work together along with your API to handle knowledge
- Construct API documentation with Swagger UI
Partly two of this sequence, you’ll discover ways to use a correct database to retailer your knowledge completely as a substitute of counting on in-memory storage as you probably did right here.