These days, a REST API is the unsung hero behind the scenes of almost every cutting-edge online project. This allows for dynamic interfaces and allows developers to keep their back-end code distinct from their front-end code. In this three-part series, you’ll learn how to use the Flask web framework to create a REST API.
You’ve laid the groundwork with a simple Flask project and endpoints, and now you’re ready to hook it up to a SQLite database. Along the process, you are also creating Swagger UI API documentation and using it to test your API.
In the last section, you learned how to use Flask and Connexion to build a REST API that allows users to perform CRUD operations on a PEOPLE data structure stored in memory. You’ve just discovered how the Connexion module may aid you in developing both a beautiful REST API and engaging, dynamic documentation. Part 2 of this instructional series teaches you how to:
-
Write
SQL commands
in Python -
Configure a
SQLite database
for your Flask project -
Use
SQLAlchemy
to save Python objects to your database -
Leverage the
Marshmallow library
to serialize data -
Connect your
REST API
with your database
In the third and last installment of this series, you’ll add the ability to add comments to a person using your REST API.
The code for the continuation of this project is available for download at the following URL.
below:
Demo
In this three-part series, you’ll learn how to create a REST API that can be used to store information about potential visitors and their visits. You’ll give birth to characters with names like the Easter Bunny, the Tooth Fairy, and Knecht Ruprecht.
You should maintain cordial relationships with all three of them. You’ll write them messages in the hopes that they’ll shower you with expensive presents.
The Application Programming Interface (API) documentation may be used to connect with your app. You’re also creating a simple interface that will display your database’s data as you go:
Adding a good database to the back end of your application is the focus of Part 2 of this series. That way, your data will stay there even when you restart the programme.
You may test the functionality of your REST API by interacting with it using the Swagger UI documentation you’ve created.
intended.
Planning Part Two
Part 1 of this course introduced you to working with a PEOPLE dictionary. What the data set really
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",
}
}
You might have used this data structure to get your project moving faster. After you restarted your app, all changes you made to PEOPLE using your REST API disappeared.
Your PEOPLE data structure will be converted into a database table that looks like
this:
id | lname | fname | timestamp |
---|---|---|---|
1 | Fairy | Tooth | 2022-10-08 09:15:10 |
2 | Ruprecht | Knecht | 2022-10-08 09:15:13 |
3 | Bunny | Easter | 2022-10-08 09:15:27 |
In this guide, you won’t be modifying your REST API’s endpoints in any way. The modifications you make on the back end, however, will be substantial, and the increased flexibility of your code will allow your Flask project grow to new heights.
future.
Getting Started
Here, you’ll take stock of the Flask REST API you’ve been developing thus far. You need to check if it’s prepared for the following lesson section.
A serializer is required to transform complicated data types to and from Python data types. Flask-Marshmallow is what you’ll be using for this lesson. When used with Flask, Flask-Marshmallow adds functionality to the Marshmallow library.
Flask.
Grab the Prerequisites
You should have read the introduction to this instructional series before reading this second installment. The source code for Part 1 is available for download at the following URL.
Please refer to the README.md file for installation instructions if you obtained the source code from the aforementioned URL.
To ensure a smooth training experience, please check that your folder structure resembles
this:
rp_flask_api/
│
├── templates/
│ └── home.html
│
├── app.py
├── people.py
└── swagger.yml
When you’ve set up the folder structure for the Flask REST API, you can go on to the next section of the tutorial and learn how to install the necessary dependencies.
series.
Add New Dependencies
It is recommended that a virtual environment be set up and activated prior to continuing work on your Flask project. By doing so, you confine the installation of any necessary dependencies for your project to its own virtual environment rather than the whole system.
To create a virtual machine on your system, follow the instructions for your operating system below.
environment:
PS> python -m venv venv
PS> .\venv\Scripts\activate
(venv) PS>
$ python -m venv venv
$ source venv/bin/activate
(venv) $
The below instructions use Python’s venv module to set up and run a virtual environment with the name venv. The prompt will now have (venv) in parentheses, indicating that the virtual environment has been successfully enabled. Download the source code from the following link if you haven’t already worked through Part 1 of this instructional series:
Follow the README.md file’s instructions to install the necessary dependencies before proceeding.
Next, run the sqlalchemy-flask-marshmallow installation.
option:
(venv) $ python -m pip install "flask-marshmallow[sqlalchemy]==0.14.0"
In addition to Flask, the marshmallow package is installed, which may be used to serialise and deserialize Python objects as they are sent over your JSON-based REST API. Marshmallow alters instances of Python classes to objects suitable for JSON transformation.
When you run Flask with the sqlalchemy option, you’ll also install a set of packages that will let you to take use of SQLAlchemy’s features.
With the object-relational model (ORM) that SQLAlchemy offers, data from Python objects may be persisted in a relational database. As a result, you can keep your Pythonic train of thought going without having to worry about the internal representation of your objects’ data.
database.
Check Your Flask Project
If you’ve followed the instructions above, you should be able to test and ensure that your Flask app is functioning correctly. Run this command in the same folder that the app.py was extracted to.
file:
(venv) $ python app.py
Flask’s default port is 8000, thus a web server will launch there when you launch this app. Hello, World! should load if you point your browser to http://localhost:8000. displayed:
All systems are go, your app is functioning perfectly! We must now go to the back end and use an appropriate
database.
Initializing the Database
The information for your Flask project is now being kept in a dictionary. Such a method of storing data is temporary. When you restart your Flask app, all modifications you made to the data will be erased. Moreover, your dictionary’s organisation leaves a lot to be desired.
Adding a database to your Flask project is the next step in fixing these issues.
shortcomings.
Inspect Your Current Data Structure
You are currently using the PEOPLE dictionary in people.py to keep track of your information. This is how the data is organised in the
code:
# people.py
# ...
PEOPLE = {
"Fairy": {
"fname": "Tooth",
"lname": "Fairy",
"timestamp": get_timestamp(),
},
"Ruprecht": {
"fname": "Knecht",
"lname": "Ruprecht",
"timestamp": get_timestamp(),
},
"Bunny": {
"fname": "Easter",
"lname": "Bunny",
"timestamp": get_timestamp(),
}
}
# ...
As part of your software updates, all information will be transferred to a database table. This indicates that the information will be persistent across app.py restarts since it has been written to disc.
programme.
Conceptualize Your Database Table
A database table may be seen as a two-dimensional array, with rows representing records and columns representing fields inside those entries.
A database table’s row lookup key is typically an auto-incrementing integer value. The term for this is “primary key.” A primary key will be assigned to each entry in the table, and that key’s value will be unique inside the database itself. You may change any other field in the row if you have a primary key that isn’t tied to the data in the table.
The table will be named “person” in accordance with database naming conventions, which requires the use of the singular form.
This is what a database table called “person” based on your PEOPLE structure above would look like
this:
id | lname | fname | timestamp |
---|---|---|---|
1 | Fairy | Tooth | 2022-10-08 09:15:10 |
2 | Ruprecht | Knecht | 2022-10-08 09:15:13 |
3 | Bunny | Easter | 2022-10-08 09:15:27 |
The field names for each table column are as follows:
follows:
-
id
:
Primary key field for each person -
lname
:
Last name of the person -
fname
:
First name of the person -
timestamp
:
Timestamp of the last change
Now that we have this idea for a database, we can begin construction on the
database.
Build Your Database
To keep track of the PEOPLE records, you’ll use SQLite as your database engine. Being an RDBMS that can function independently of an actual SQL server, SQLite has found widespread adoption.
SQLite, in contrast to other SQL database engines, stores all database data in a single file. Hence, all a software needs to access the database is the ability to read and write SQLite files.
Python’s sqlite3 module provides native support for working with SQLite databases. Because of this, SQLite is a great tool for anybody creating a new Python project.
Create the people.db SQLite database in a new Python interactive shell.
database:
>>>
>>> import sqlite3
>>> conn = sqlite3.connect("people.db")
>>> columns = [
... "id INTEGER PRIMARY KEY",
... "lname VARCHAR UNIQUE",
... "fname VARCHAR",
... "timestamp DATETIME",
... ]
>>> create_table_cmd = f"CREATE TABLE person ({','.join(columns)})"
>>> conn.execute(create_table_cmd)
<sqlite3.Cursor object at 0x1063f4dc0>
After the sqlite3 module has been imported, a new database may be created using the.connect() function. The people.db database file will appear in your file system immediately after you define the conn variable in Python.
Running the SQL statement to construct a people table with the fields id, lname, fname, and timestamp is what conn.execute() does.
Make sure that lname has a UNIQUE constraint. That’s significant since your REST API relies on the surname to uniquely identify a user. Hence, in order to avoid inconsistencies, it is essential that your database protect the uniqueness of lname.
You may start adding information to your database immediately.
it:
>>>
>>> import sqlite3
>>> conn = sqlite3.connect("people.db")
>>> people = [
... "1, 'Fairy', 'Tooth', '2022-10-08 09:15:10'",
... "2, 'Ruprecht', 'Knecht', '2022-10-08 09:15:13'",
... "3, 'Bunny', 'Easter', '2022-10-08 09:15:27'",
... ]
>>> for person_data in people:
... insert_cmd = f"INSERT INTO person VALUES ({person_data})"
... conn.execute(insert_cmd)
...
<sqlite3.Cursor object at 0x104ac4dc0>
<sqlite3.Cursor object at 0x104ac4f40>
<sqlite3.Cursor object at 0x104ac4fc0>
>>> conn.commit()
Declare a transaction to insert people data into the person table after you’ve established a connection to the people.db database. With the help of the conn.execute() method, sqlite3.Cursor objects may be created in RAM. Until conn.commit() is called, the transaction will not be finalised.
happen.
Interact With the Database
In contrast to languages like Python, SQL does not provide a method for retrieving the data. With SQL, the user specifies what information is needed while the database engine handles the implementation details.
Here is how a complete SQL query for your people table would look:
this:
SELECT * FROM person;
The database will retrieve all fields from the “person” table per this query. Python code to execute the aforementioned query in SQLite and show its results follows.
data:
>>>
1>>> import sqlite3
2>>> conn = sqlite3.connect("people.db")
3>>> cur = conn.cursor()
4>>> cur.execute("SELECT * FROM person")
5<sqlite3.Cursor object at 0x102357a40>
6
7>>> people = cur.fetchall()
8>>> for person in people:
9... print(person)
10...
11(1, 'Fairy', 'Tooth', '2022-10-08 09:15:10')
12(2, 'Ruprecht', 'Knecht', '2022-10-08 09:15:13')
13(3, 'Bunny', 'Easter', '2022-10-08 09:15:27')
What the above code achieves is
following:
-
Line 1
imports the
sqlite3
module. -
Line 2
creates a connection to the database file. -
Line 3
creates a cursor from the connection. -
Line 4
uses the cursor to execute a
SQL
query expressed as a string. -
Line 7
gets all the records returned by the
SQL
query and assigns them to the
people
variable
. -
Lines 8 and 9
iterate over
people
and print out the data of each person.
The SQL statement in the above code is a string that is sent to the database as a command. As the SQL is a string literal, it is entirely within the control of the application, therefore this may not be a major issue. But, your REST API’s primary function will be to collect data from the web app’s users and transform it into SQL queries. This might create a security hole in your software.
Click on the link to expand and read about how:
The best possible result for the person query would be a Python object with all of the information as attributes. In this approach, you can check that the objects have the correct value types and don’t contain any harmful code.
You should give some thought to whether or not you really want to write pure SQL statements whenever your Python code interacts with a database. As you’ve read, writing SQL may be cumbersome at best and a security risk at worst. A software like SQLAlchemy may help you avoid unnecessary stress while working with databases.
out.
Connecting the SQLite Database With Your Flask Project
Here, you’ll use SQLAlchemy to link people.db to your Flask app and facilitate communication with your database.
You can concentrate on the data models and how to utilise them since SQLAlchemy takes care of many of the interactions that are database-specific. Before generating SQL statements, SQLAlchemy will cleanse user input. It’s another another significant benefit of using SQLAlchemy with databases.
Two Python modules (config.py and models.py) will also be developed in this stage.
:
-
config.py
gets the necessary modules imported into the program and configured. This includes Flask, Connexion, SQLAlchemy, and Marshmallow. -
models.py
is the module where you’ll create SQLAlchemy and Marshmallow class definitions.
After reading this, you’ll be able to do away with the PEOPLE data structure and start working with the linked data instead.
database.
Configure Your Database
All of your configuration settings will be produced and initialised in the config.py module. You’ll set up Flask, Connexion, SQLAlchemy, and Marshmallow in this file.
In your rp flask api/ project, build a config.py file.
folder:
1# config.py
2
3import pathlib
4import connexion
5from flask_sqlalchemy import SQLAlchemy
6from flask_marshmallow import Marshmallow
7
8basedir = pathlib.Path(__file__).parent.resolve()
9connex_app = connexion.App(__name__, specification_dir=basedir)
10
11app = connex_app.app
12app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{basedir / 'people.db'}"
13app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
14
15db = SQLAlchemy(app)
16ma = Marshmallow(app)
A definition of the above code follows.
doing:
-
Lines 3 to 6
import the built-in
pathlib
as well as the third-party libraries
connexion
,
SQLAlchemy
, and
Marshmallow
. -
Line 8
creates the variable
basedir
pointing to the directory that the program is running in. -
Line 9
uses the
basedir
variable to create the Connexion app instance and give it the path to the directory that contains your specification file. -
Line 11
creates a variable,
app
, which is the Flask instance initialized by Connexion. -
Line 12
tell SQLAlchemy to use SQLite as the database and a file named
people.db
in the current directory as the database file. -
Line 13
turns the
SQLAlchemy event system
off. The event system generates events that are useful in event-driven programs, but it adds significant overhead. Since you’re not creating an event-driven program, you turn this feature off. -
Line 15
initializes SQLAlchemy by passing the
app
configuration information to
SQLAlchemy
and assigning the result to a
db
variable. -
Line 16
initializes Marshmallow and allows it to work with the SQLAlchemy components attached to the app.
The configuration keys documentation of SQLAlchemy can tell you more about the options available to you in this scenario.
Flask-SQLALchemy.
Model Data With SQLAlchemy
SQLAlchemy is a sizable Python database project that offers a wide range of features. It also has an object-relational mapper, which is a useful tool (ORM). This ORM provides a more Pythonic interface to the people database table by translating each row of the people table into a Python object.
Make sure that the person database’s information is defined as a SQLAlchemy class in a models.py file.
table:
1# models.py
2
3from datetime import datetime
4from config import db
5
6class Person(db.Model):
7 __tablename__ = "person"
8 id = db.Column(db.Integer, primary_key=True)
9 lname = db.Column(db.String(32), unique=True)
10 fname = db.Column(db.String(32))
11 timestamp = db.Column(
12 db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow
13 )
A definition of the above code follows.
doing:
-
Line 3
imports the
datetime
object from
the
datetime
module
that comes with Python. This gives you a way to create a timestamp in the
Person
class in lines 11 to 13. -
Line 4
imports
db
, an instance of
SQLAlchemy
that you defined in the
config.py
module. This gives
models.py
access to SQLAlchemy attributes and methods. -
Line 6
defines the
Person
class. Inheriting from
db.Model
gives
Person
the SQLAlchemy features to connect to the database and access its tables. -
Line 7
connects the class definition to the
person
database table. -
Line 8
declares the
id
column containing an integer acting as the primary key for the table. -
Line 9
defines the last name field with a string value. This field must be unique because you’re using
lname
as the identifier for a person in a REST API URL. -
Line 10
defines the first name field with a string value. -
Lines 11 to 13
define a
timestamp
field with a
datetime
value.
When a record is created, the default=datetime.utcnow argument sets the timestamp to the current utcnow value. When a record is changed, the onupdate=datetime.utcnow argument causes the timestamp to be modified to reflect the current utcnow time. Expansion of the following section reveals further information regarding UTC time stamps:
Instead of working with raw SQL, SQLAlchemy lets you conceive in terms of objects with behaviour. As your database tables grow in size and complexity, this becomes more and more useful.
complex.
Serialize the Modeled Data With Marshmallow
SQLAlchemy makes it easy to work with modelled data directly in your code. The SQLAlchemy model may cause problems, however, since the REST API processes data in JSON format.
Connexion is unable to convert the data returned by SQLAlchemy as Python class instances to the JSON format. The term “serialising” refers to the process of transforming Python objects, which may itself include other Python objects and complicated data types, into more compact and easily understood structures.
Types of information in JSON are described below.
here:
-
string
:
A string type -
number
:
Numbers supported by Python (integers, floats, longs) -
object
:
A JSON object, which is roughly equivalent to a Python dictionary -
array
:
Roughly equivalent to a Python List -
boolean
:
Represented in JSON as
true
or
false
, but in Python as
True
or
False
-
null
:
Essentially
None
in Python
The timestamp in your Person class is stored in a Python DateTime object. As JSON lacks a definition for DateTime, string representations of timestamps are required for storage in JSON documents.
You are relying on a database to save information indefinitely. Using SQLAlchemy, your Python app can easily interact with your database. There are, however, two obstacles you’ll need overcome
solve:
- Your REST API works with JSON instead of Python objects.
- You must make sure that the data that you’re adding to the database is valid.
The Marshmallow component can help with that!
The PersonSchema class that Marshmallow helps you create is similar to the Person class that you just made with SQLAlchemy. The PersonSchema class provides the mapping from class attributes to JSON object representations. All characteristics are checked for presence and for the correct data type by Marshmallow.
The class description for your personal information in Marshmallow is as follows:
table:
# models.py
from datetime import datetime
from config import db, ma
class Person(db.Model):
__tablename__ = "person"
id = db.Column(db.Integer, primary_key=True)
lname = db.Column(db.String(32), unique=True)
fname = db.Column(db.String(32))
timestamp = db.Column(
db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow
)
class PersonSchema(ma.SQLAlchemyAutoSchema):
class Meta:
model = Person
load_instance = True
sqla_session = db.session
person_schema = PersonSchema()
people_schema = PersonSchema(many=True)
You may make PersonSchema inherit from ma.SQLAlchemyAutoSchema by importing ma from config.py. Whenever SQLAlchemyAutoSchema needs to locate a SQLAlchemy model or session, it first consults this private Meta class.
The Person model is used for PersonSchema, while db.session is used for sqla session. Marshmallow is able to serialise and deserialize attributes of the Person class since it has discovered these characteristics and learned their kinds.
With load instance, you may take Person model instances from JSON data and deserialize them. At last, you’ll create instances of the two schemas you’ll need to work with your data: person schema and people schema.
later.
Do Some Cleanup
The outdated Persons database must be deleted immediately. This will ensure that the database, rather not the deprecated PEOPLE dictionary, is used for any updates to people data.
Remove unused imports, functions, and data structures from people.py and replace them with imports from models.py’s database and data.
:
# people.py
# Remove: from datetime import datetime
from flask import make_response, abort
from config import db
from models import Person, people_schema, person_schema
# Remove: get_timestamp():
# Remove: PEOPLE
# ...
All references to datetime, get timestamp(), and the PEOPLE dictionary are discarded. In exchange, you’re able to import the configuration and model objects you’ll be using in the future.
You may have received a warning from your Python code editor about the undefined PEOPLE variable as soon as you deleted the PEOPLE dictionary. To make your Python editor happy, you’ll be replacing any references to PEOPLE with database queries in the next section.
again.
Connecting the Database With Your API
Your Flask project and database are linked, but not to the REST API just yet. You might expand your database by using the Python interactive shell. But, expanding your REST API by making use of its current endpoints to include new data would be a lot more exciting.
Here, you’ll link your API to the database so that you may manage personnel using the API’s preexisting endpoints. Go back to the first installment of this series if you need a refresher on how you created the API endpoints.
This is the current state of your Flask REST API.
moment:
Action | HTTP Verb | URL Path | Description |
---|---|---|---|
Read |
|
|
Read a collection of people. |
Create |
|
|
Create a new person. |
Read |
|
|
Read a particular person. |
Update |
|
|
Update an existing person. |
Delete |
|
|
Delete an existing person. |
The next step is to modify the previously established connections to the aforementioned endpoints so that they are compatible with the people.db.
database.
Read From the Database
Before doing anything further, modify the people.py methods that only read data from the database. First, type read all ()
:
# people.py
# ...
def read_all():
people = Person.query.all()
return people_schema.dump(people)
# ...
When used using the GET /api/people REST API endpoint, the read all() method will return every single entry from the table containing user information.
People schema is a Marshmallow PersonSchema object that was initialised with the many=True option. By passing in an interable here, you may instruct PersonSchema to treat it as the serialisation target. This is significant since it is the persons variable that stores the data from the database.
Lastly, using.dump(), you serialise your Python objects and send back all the people’s information in answer to the REST API request.
Read one is the other function in people.py that does nothing except take in information ()
:
# people.py
# ...
def read_one(lname):
person = Person.query.filter(Person.lname == lname).one_or_none()
if person is not None:
return person_schema.dump(person)
else:
abort(404, f"Person with last name {lname} not found")
# ...
When the user is doing a search for a particular individual, the REST URL route will include a lname argument, which will be sent to the read one() method.
The lname variable is used in the.filter() function of the query. The.one or none() function may be used in place of.all() to get a single person or to return None if no such person is found.
If a person is located, the object person will have a Person property, and you may return it instead of the serialised version. Instead, you would use an abort() function if
error.
Write to the Database
Adding a new user to the database is also updated in people.py. The HTTP request’s JSON payload may be deserialized into a SQLAlchemy Person object using the Marshmallow PersonSchema. See the new REST URL endpoint handler in action at POST /api/people in this section of the revised people.py module.
:
# people.py
# ...
def create(person):
lname = person.get("lname")
existing_person = Person.query.filter(Person.lname == lname).one_or_none()
if existing_person is None:
new_person = person_schema.load(person, session=db.session)
db.session.add(new_person)
db.session.commit()
return person_schema.dump(new_person), 201
else:
abort(406, f"Person with last name {lname} already exists")
# ...
create() takes in a whole person object, as opposed to only a surname as in read one(). The key lname must be unique in the database and present in this object. No two people in your database can have the same lname value since that is how you identify them.
Deserialize the person object as new person and insert it into db.session if the last name is not already there. The database engine generates a new primary key and a timestamp in Coordinated Universal Time (UTC) for the object new person after you commit it to the database. At a later time, the API response will include the newly produced dataset.
Make changes to update() and remove() exactly as you did before.
functions:
# people.py
# ...
def update(lname, person):
existing_person = Person.query.filter(Person.lname == lname).one_or_none()
if existing_person:
update_person = person_schema.load(person, session=db.session)
existing_person.fname = update_person.fname
db.session.merge(existing_person)
db.session.commit()
return person_schema.dump(existing_person), 201
else:
abort(404, f"Person with last name {lname} not found")
def delete(lname):
existing_person = Person.query.filter(Person.lname == lname).one_or_none()
if existing_person:
db.session.delete(existing_person)
db.session.commit()
return make_response(f"{lname} successfully deleted", 200)
else:
abort(404, f"Person with last name {lname} not found")
Now is the time to update your front-end code and use Swagger UI to test whether your database functions as expected in light of all these modifications.
expected.
Display Data in Your Front End
Your Flask project now has everything it needs to interact with your database, thanks to the addition of the SQLite settings and the definition of the Person model. Several tweaks to app.py are required before data can be shown on the front end.
:
1# app.py
2
3from flask import render_template
4# Remove: import connexion
5import config
6from models import Person
7
8app = config.connex_app
9app.add_api(config.basedir / "swagger.yml")
10
11@app.route("/")
12def home():
13 people = Person.query.all()
14 return render_template("home.html", people=people)
15
16if __name__ == "__main__":
17 app.run(host="0.0.0.0", port=8000, debug=True)
The files config.py and models.py are now in your working directory. Line 4’s import is removed, while lines 5 and 6 have new imports for config and Person, respectively.
The config module gives you a Flask app with a Connexion flavour. Thus instead of creating a new Flask app in app.py, you should instead refer to config.connex app on line 8.
The data from the persons database is retrieved through a query to the Person model in line 13, and then sent to render template() in line 14.
You’ll need to make some changes to home.html in order to see the persons data in the front end.
template:
<!-- templates/home.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>RP Flask REST API</title>
</head>
<body>
<h1>
Hello, People!
</h1>
<ul>
{% for person in people %}
<li>{{ person.fname }} {{ person.lname }}</li>
{% endfor %}
</ul>
</body>
</html>
This command may be used to launch an application from the same folder as the app.py file.
file:
(venv) $ python app.py
When this programme is executed, a web server will launch on the port specified in app.py, in this case 8000. Data from your database may be seen in a browser by going to http://localhost:8000.
Awesome! The three persons that are presently in your database are shown on your homepage. The home page will immediately reflect any changes made using Swagger UI, including new profiles, updated information, and deleted profiles.
page.
Explore Your API Documentation
After you’ve made the aforementioned adjustments, your database will be fully operational and its data will be preserved throughout programme restarts:
You may use your API to make changes to existing users or delete them entirely. The modifications you made to the user interface now allow you to see every single person in your database.
No longer will your data be lost if you restart your Flask app. Your data is secured in a database that is synced with your Flask app.