Friday, March 29, 2024
HomePythonPython REST APIs With Flask, Connexion, and SQLAlchemy – Half 2 –...

Python REST APIs With Flask, Connexion, and SQLAlchemy – Half 2 – Actual Python


Most fashionable net purposes are powered by a REST API underneath the hood. That means, 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 collection, you’re constructing a REST API with the Flask net framework.

You’ve created a basis with a fundamental Flask challenge and added endpoints, which you’ll hook up with a SQLite database. You’re additionally testing your API with Swagger UI API documentation that you simply’re constructing alongside the best way.

Within the first half, you used Flask and Connexion to create a REST API offering CRUD operations to an in-memory construction referred to as PEOPLE. By doing so, you discovered how the Connexion module helps you construct a pleasant REST API and interactive documentation.

Within the second a part of this tutorial collection, you’ll learn to:

  • Write SQL instructions in Python
  • Configure a SQLite database in your Flask challenge
  • Use SQLAlchemy to save lots of Python objects to your database
  • Leverage the Marshmallow library to serialize knowledge
  • Join your REST API along with your database

After ending the second a part of this collection, you’ll transfer on to the third half, the place you’ll prolong your REST API with the performance so as to add notes to an individual.

You’ll be able to obtain the code for the second a part of this challenge by clicking the hyperlink beneath:

Demo

On this three-part tutorial collection, you’re constructing a REST API to maintain monitor of notes for those who might go to you all year long. 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 possibility of getting worthwhile items from them.

You’ll be able to work together along with your software by leveraging the API documentation. Alongside the best way, you’re additionally constructing a fundamental entrance finish that displays the contents of your database:

Within the second a part of this collection, you’ll improve the again finish of your software by including a correct database. That means, you’ll persist your knowledge even if you restart your app:

Along with your Swagger UI documentation, you’ll be capable of work together along with your REST API and make it possible for every thing works as meant.

Planning Half Two

Within the first a part of this tutorial collection, you labored with a PEOPLE dictionary to retailer your knowledge. The dataset appeared 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",
    }
}

This knowledge construction was useful to get your challenge in control. Nonetheless, any knowledge that you simply added along with your REST API to PEOPLE acquired misplaced if you restarted your app.

On this half, you’ll be translating your PEOPLE knowledge construction right into a database desk that’ll appear to be 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

You gained’t make any modifications to your REST API endpoints on this tutorial. However the modifications that you simply’ll make within the again finish will probably be vital, and also you’ll find yourself with a way more versatile codebase to assist scale your Flask challenge up sooner or later.

Getting Began

On this part, you’ll test in with the Flask REST API challenge that you simply’re engaged on. You wish to make it possible for it’s prepared for the following steps on this tutorial collection.

To transform complicated knowledge sorts to and from Python knowledge sorts, you’ll want a serializer. For this tutorial, you’ll use Flask-Marshmallow. Flask-Marshmallow extends the Marshmallow libary and gives further options if you work with Flask.

Seize the Conditions

Ideally, you adopted the first half of this tutorial collection earlier than persevering with with the second half, which you’re studying proper now. Alternatively, you too can obtain the supply code from half one by clicking the hyperlink beneath:

For those who downloaded the supply code from the hyperlink above, then make sure that to observe the set up directions throughout the supplied README.md file.

Earlier than you proceed with the tutorial, confirm that your folder construction seems to be like this:

rp_flask_api/
│
├── templates/
│   └── dwelling.html
│
├── app.py
├── folks.py
└── swagger.yml

When you’ve acquired the Flask REST API folder construction in place, you may learn on to put in the dependencies that you simply’ll want on this a part of the tutorial collection.

Add New Dependencies

Earlier than you proceed working in your Flask challenge, it’s a good suggestion to create and activate a digital atmosphere. That means, you’re putting in any challenge dependencies not system-wide however solely in your challenge’s digital atmosphere.

Choose your working system beneath and use your platform-specific command to arrange a digital atmosphere:

PS> python -m venv venv
PS> .venvScriptsactivate
(venv) PS>
$ python -m venv venv
$ supply venv/bin/activate
(venv) $

With the instructions proven above, you create and activate a digital atmosphere named venv through the use of 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.

Subsequent, set up flask-marshmallow with the sqlalchemy possibility:

(venv) $ python -m pip set up "flask-marshmallow[sqlalchemy]==0.14.0"

Flask-Marshmallow additionally installs marshmallow, which gives performance to serialize and deserialize Python objects as they move out and in of your REST API, which is predicated on JSON. Marshmallow converts Python class situations to things that may be transformed to JSON.

Through the use of the sqlalchemy possibility, you additionally set up packages that helps your Flask app leverage the powers of SQLAlchemy.

SQLAlchemy gives an object-relational mannequin (ORM), which shops every Python object to a database illustration of the thing’s knowledge. That may enable you proceed to suppose in a Pythonic means and never be involved with how the thing knowledge will probably be represented in a database.

Examine Your Flask Venture

After following the steps above, you may confirm that your Flask software is working with out errors. Execute the next command within the listing containing the app.py file:

Whenever you run this software, an internet server will begin on port 8000, which is the default port utilized by Flask. For those who open a browser and navigate to http://localhost:8000, you must see Hiya, World! displayed:

Screenshot of Flask Hello World Website.

Excellent, your app is working flawlessly! Now it’s time to enter the again finish and work with a correct database.

Initializing the Database

At the moment, you’re storing the info of your Flask challenge in a dictionary. Storing knowledge like this isn’t persistent. That implies that any knowledge modifications get misplaced if you restart your Flask software. On prime of that, the construction of your dictionary isn’t excellent.

On this part, you’ll add a correct database to your Flask challenge to repair these shortcomings.

Examine Your Present Knowledge Construction

At the moment, you’re storing your knowledge within the PEOPLE dictionary in folks.py. The information construction seems to be like this within the code:

# folks.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(),
    }
}

# ...

The modifications that you simply’ll make to this system will transfer all the info to a database desk. Which means that the info will probably be saved to your disk and can exist between runs of the app.py program.

Conceptualize Your Database Desk

Conceptually, you may consider a database desk as a two-dimensional array the place the rows are data, and the columns are fields in these data.

Database tables often have an auto-incrementing integer worth because the lookup key to rows. That is referred to as the major key. Every report within the desk could have a major key whose worth is exclusive throughout your complete desk. Having a major key impartial of the info saved within the desk provides you the liberty to change another subject within the row.

You’re going to observe a database conference of naming the desk as singular, so the desk will probably be referred to as particular person.

Translating your PEOPLE construction above right into a database desk named particular person will appear to be 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

Every column within the desk has a subject title as follows:

  • id: Main key subject for every particular person
  • lname: Final title of the particular person
  • fname: First title of the particular person
  • timestamp: Timestamp of the final change

With this database idea in place, it’s time to construct the database.

Construct Your Database

You’re going to make use of SQLite because the database engine to retailer the PEOPLE knowledge. SQLite is a broadly used relational database administration system (RDBMS) that doesn’t want a SQL server to work.

In distinction to different SQL database engines, SQLite works with a single file to keep up all of the database performance. Subsequently, to make use of the database, a program simply must know easy methods to learn and write to a SQLite file.

Python’s built-in sqlite3 module lets you work together with SQLite databases with none exterior packages. This makes SQLite notably helpful when beginning new Python initiatives.

Begin a brand new Python interactive shell to create the folks.db SQLite database:

>>>

>>> import sqlite3
>>> conn = sqlite3.join("folks.db")
>>> columns = [
...     "id INTEGER PRIMARY KEY",
...     "lname VARCHAR UNIQUE",
...     "fname VARCHAR",
...     "timestamp DATETIME",
... ]
>>> create_table_cmd = f"CREATE TABLE particular person ({','.be part of(columns)})"
>>> conn.execute(create_table_cmd)
<sqlite3.Cursor object at 0x1063f4dc0>

After you import the sqlite3 module, you may create a brand new database with .join(). When you’ve got a have a look at your file system after defining the conn variable, then you definately’ll discover that Python created the folks.db database file straight away.

With conn.execute() you’re working the SQL command to create a particular person desk with the columns id, lname, fname, and timestamp.

Word that you simply embrace a UNIQUE constraint for lname. That’s vital since you use the final title in your REST API to establish an individual. Subsequently, your database should guarantee the individuality of lname to forestall inconsistencies in your knowledge.

Now that your database exists, you may add knowledge to it:

>>>

>>> import sqlite3
>>> conn = sqlite3.join("folks.db")
>>> folks = [
...     "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 folks:
...     insert_cmd = f"INSERT INTO particular 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()

When you’re related to the folks.db database, you declare a transaction to insert people_data into the particular person desk. The conn.execute() command creates sqlite3.Cursor objects in reminiscence. Solely if you run conn.commit() do you make the transaction occur.

Work together With the Database

In contrast to programming languages like Python, SQL doesn’t outline easy methods to get the info. SQL describes what knowledge is desired and leaves the how as much as the database engine.

A SQL question that will get the entire knowledge in your particular person desk would look this this:

This question tells the database engine to get all of the fields from the particular person desk. Within the following Python code, you employ SQLite to run the above question and show the info:

>>>

 1>>> import sqlite3
 2>>> conn = sqlite3.join("folks.db")
 3>>> cur = conn.cursor()
 4>>> cur.execute("SELECT * FROM particular person")
 5<sqlite3.Cursor object at 0x102357a40>
 6
 7>>> folks = cur.fetchall()
 8>>> for particular person in folks:
 9...     print(particular 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')

The code above does the next:

  • 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 makes use of the cursor to execute a SQL question expressed as a string.
  • Line 7 will get all of the data returned by the SQL question and assigns them to the folks variable.
  • Strains 8 and 9 iterate over folks and print out the info of every particular person.

Within the above program, the SQL assertion is a string handed on to the database to execute. On this case, that might not be an enormous drawback as a result of the SQL is a string literal fully underneath the management of this system. Nonetheless, the use case in your REST API will probably be taking person enter from the net software and utilizing it to create SQL queries. This will open your software to assault.

Increase the part beneath to learn the way:

You’ll recall from half considered one of this tutorial collection that the REST API endpoint to get a single particular person from the PEOPLE knowledge appeared like this:

This implies your API is anticipating a variable, lname, within the URL endpoint path that it makes use of to discover a single particular person. Modifying the Python SQLite code from above to do that would look one thing like this:

 1lname = "Fairy"
 2cur.execute(f"SELECT * FROM particular person WHERE lname = '{lname}'")

The above code snippet does the next:

  • Line 1 units the lname variable to 'Fairy'. This may come from the REST API URL endpoint path.
  • Line 2 makes use of Python string formatting to create a SQL string and execute it.

To maintain issues easy, the above code units the lname variable to a continuing, however actually it will come from the API URL endpoint path and could possibly be something provided by the person. The SQL generated by the string formatting seems to be like this:

SELECT * FROM particular person WHERE lname = 'Fairy'

When this SQL is executed by the database, it searches the particular person desk for a report the place the final title is the same as 'Fairy'. That is what’s meant, however any program that accepts person enter can be open to malicious customers. This system above, the place the lname variable is ready by user-supplied enter, opens you as much as what’s referred to as a SQL injection assault. You may see such an assault known as Little Bobby Tables:

XKCD Comic #327: Exploits of a Mom
Picture: xkcd.com

For instance, think about {that a} malicious person referred to as your REST API on this means:

GET /api/folks/Fairy';DROP TABLE particular person;

The REST API request above units the lname variable to 'Fairy';DROP TABLE particular person;', which within the code above would generate this SQL assertion:

SELECT * FROM particular person WHERE lname = 'Fairy';DROP TABLE particular person;

The above SQL assertion is legitimate, and when executed by the database, it’ll discover one report the place lname matches 'Fairy'. Then, it’ll discover the SQL assertion delimiter character ; and can go proper forward and drop your complete desk. This may primarily wreck your software.

You’ll be able to defend your program by sanitizing all knowledge that you simply get from the customers of your software. Sanitizing knowledge on this context means having your program study the user-supplied knowledge to make it possible for it doesn’t include something harmful to this system. This may be difficult to do proper and must be completed in all places person knowledge interacts with the database.

It could be significantly better if what you bought again for particular person was a Python object, the place every of the fields is an attribute of the thing. That means, you make it possible for the objects include the anticipated worth sorts and never any malicious instructions.

Whenever you work together with a database in your Python code, you might suppose twice about whether or not you wish to write pure SQL instructions. As you discovered above, writing SQL might not solely really feel inconvenvient, however it could actually trigger safety points. For those who don’t wish to fear an excessive amount of about database interplay, a package deal like SQLAlchemy can assist you out.

Connecting the SQLite Database With Your Flask Venture

On this part, you’ll leverage SQLAlchemy for assist in speaking along with your database and connecting folks.db to your Flask app.

SQLAlchemy handles lots of the interactions particular to explicit databases and allows you to deal with the info fashions in addition to easy methods to use them. SQLAlchemy will sanitize person knowledge for you earlier than creating SQL statements. It’s one other huge benefit and a cause to make use of SQLAlchemy when working with databases.

On this part, you’ll additionally create two Python modules, config.py amd fashions.py:

  1. config.py will get the mandatory modules imported into this system and configured. This consists of Flask, Connexion, SQLAlchemy, and Marshmallow.
  2. fashions.py is the module the place you’ll create SQLAlchemy and Marshmallow class definitions.

On the finish of this part, you’ll be capable of take away the previous PEOPLE knowledge construction and work with the related database.

Configure Your Database

The config.py module is, because the title implies, the place your entire configuration data is created and initialized. On this file, you’re going to configure Flask, Connexion, SQLAlchemy, and Marshmallow.

Create config.py in your rp_flask_api/ challenge folder:

 1# config.py
 2
 3import pathlib
 4import connexion
 5from flask_sqlalchemy import SQLAlchemy
 6from flask_marshmallow import Marshmallow
 7
 8basedir = pathlib.Path(__file__).father or mother.resolve()
 9connex_app = connexion.App(__name__, specification_dir=basedir)
10
11app = connex_app.app
12app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{basedir / 'folks.db'}"
13app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
14
15db = SQLAlchemy(app)
16ma = Marshmallow(app)

Right here’s what the above code is doing:

  • Strains 3 to six import the built-in pathlib in addition to the third-party libraries connexion, SQLAlchemy, and Marshmallow.

  • Line 8 creates the variable basedir pointing to the listing that this system is working in.

  • Line 9 makes use of the basedir variable to create the Connexion app occasion and provides it the trail to the listing that comprises your specification file.

  • Line 11 creates a variable, app, which is the Flask occasion initialized by Connexion.

  • Line 12 inform SQLAlchemy to make use of SQLite because the database and a file named folks.db within the present listing because the database file.

  • Line 13 turns the SQLAlchemy occasion system off. The occasion system generates occasions which can be helpful in event-driven applications, however it provides vital overhead. Because you’re not creating an event-driven program, you flip this function off.

  • Line 15 initializes SQLAlchemy by passing the app configuration data to SQLAlchemy and assigning the consequence to a db variable.

  • Line 16 initializes Marshmallow and permits it to work with the SQLAlchemy elements hooked up to the app.

If you wish to be taught extra concerning the SQLAlchemy configurations which you could implement right here, then you may take a look at the configuration keys documentation of Flask-SQLALchemy.

Mannequin Knowledge With SQLAlchemy

SQLAlchemy is an enormous challenge and gives loads of performance to work with databases utilizing Python. One of many options that it gives is an object-relational mapper (ORM). This ORM lets you work together with the particular person database desk in a extra Pythonic means by mapping a row of fields from the database desk to a Python object.

Create a fashions.py file with a SQLAlchemy class definition for the info within the particular person database desk:

 1# fashions.py
 2
 3from datetime import datetime
 4from config import db
 5
 6class Individual(db.Mannequin):
 7    __tablename__ = "particular person"
 8    id = db.Column(db.Integer, primary_key=True)
 9    lname = db.Column(db.String(32), distinctive=True)
10    fname = db.Column(db.String(32))
11    timestamp = db.Column(
12        db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow
13    )

Right here’s what the above code is doing:

  • Line 3 imports the datetime object from the datetime module that comes with Python. This provides you a technique to create a timestamp within the Individual class in strains 11 to 13.
  • Line 4 imports db, an occasion of SQLAlchemy that you simply outlined within the config.py module. This provides fashions.py entry to SQLAlchemy attributes and strategies.
  • Line 6 defines the Individual class. Inheriting from db.Mannequin provides Individual the SQLAlchemy options to hook up with the database and entry its tables.
  • Line 7 connects the category definition to the particular person database desk.
  • Line 8 declares the id column containing an integer performing as the first key for the desk.
  • Line 9 defines the final title subject with a string worth. This subject should be distinctive since you’re utilizing lname because the identifier for an individual in a REST API URL.
  • Line 10 defines the primary title subject with a string worth.
  • Strains 11 to 13 outline a timestamp subject with a datetime worth.

The default=datetime.utcnow parameter defaults the timestamp worth to the present utcnow worth when a report is created. The onupdate=datetime.utcnow parameter updates the timestamp with the present utcnow worth when the report is up to date. To be taught extra about UTC timestamps, develop the collapsible part beneath:

You could be questioning why the timestamp within the above class defaults to and is up to date by the datetime.utcnow() methodology, which returns a UTC, or Coordinated Common Time. It is a means of standardizing your timestamp’s supply.

The supply, or zero time, is a line working from Earth’s north to south pole by the UK. That is the zero time zone from which all different time zones are offset. Through the use of this because the zero time supply, your timestamps are offsets from this normal reference level.

Ought to your software be accessed from totally different time zones, you’ve a technique to carry out date and time calculations. All you want is a UTC timestamp and the vacation spot time zone.

For those who had been to make use of native time zones as your timestamp supply, then you definately couldn’t carry out date and time calculations with out details about a neighborhood time zone’s offset from zero time. With out the timestamp supply data, you couldn’t do any date and time comparisons or any math in any respect.

Working with a timestamp primarily based on UTC is an efficient normal to observe. Right here’s a instrument package web site to work with with a purpose to higher perceive such timestamps.

Utilizing SQLAlchemy lets you suppose by way of objects with habits reasonably than coping with uncooked SQL. This turns into much more useful when your database tables turn out to be bigger and the interactions extra complicated.

Serialize the Modeled Knowledge With Marshmallow

Working with SQLAlchemy’s modeled knowledge inside your applications could be very handy. Nonetheless, the REST API works with JSON knowledge, and right here you may run into a difficulty with the SQLAlchemy mannequin.

As a result of SQLAlchemy returns knowledge as Python class situations, Connexion can’t serialize these class situations to JSON-formatted knowledge.

You’re utilizing a database as persistent knowledge storage. With SQLAlchemy, you may comfortably talk along with your database from inside your Python program. Nonetheless, there are two challenges that you might want to remedy:

  1. Your REST API works with JSON as an alternative of Python objects.
  2. You need to make it possible for the info that you simply’re including to the database is legitimate.

That’s the place the Marshmallow module comes into play!

Marshmallow lets you create a PersonSchema class, which is just like the SQLAlchemy Individual class you simply created. The PersonSchema class defines how the attributes of a category will probably be transformed into JSON-friendly codecs. Marshmallow additionally makes certain that each one attributes are current and include the anticipated knowledge sort.

Right here’s the Marshmallow class definition for the info in your particular person desk:

# fashions.py

from datetime import datetime
from config import db, ma

class Individual(db.Mannequin):
    __tablename__ = "particular person"
    id = db.Column(db.Integer, primary_key=True)
    lname = db.Column(db.String(32), distinctive=True)
    fname = db.Column(db.String(32))
    timestamp = db.Column(
        db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow
    )

class PersonSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        mannequin = Individual
        load_instance = True
        sqla_session = db.session

person_schema = PersonSchema()
people_schema = PersonSchema(many=True)

You import ma from config.py to allow PersonSchema to inherit from ma.SQLAlchemyAutoSchema. To discover a SQLAlchemy mannequin and a SQLALchemy session, SQLAlchemyAutoSchema seems to be for after which makes use of this inside Meta class.

For PersonSchema, the mannequin is Individual, and sqla_session is db.session. That is how Marshmallow finds attributes within the Individual class and learns the forms of these attributes so it is aware of easy methods to serialize and deserialize them.

With load_instance, you’re in a position to deserialize JSON knowledge and cargo Individual mannequin situations from it. Lastly, you instantiate two schemas, person_schema and people_schema, that you simply’ll use later.

Do Some Cleanup

Now it’s time to do away with the previous PEOPLE knowledge construction. It will make it possible for any modifications you’re making to folks knowledge are carried out on the database reasonably than the out of date PEOPLE dictionary.

Open folks.py and do away with the imports, features, and knowledge constructions that you simply don’t want anymore, and use new imports so as to add db and knowledge from fashions.py:

# folks.py

# Take away: from datetime import datetime
from flask import make_response, abort

from config import db
from fashions import Individual, people_schema, person_schema

# Take away: get_timestamp():
# Take away: PEOPLE

# ...

You take away the datetime import, the get_timestamp() operate, and the PEOPLE dictionary. In alternate, you add objects from config and fashions that you simply’ll use any longer.

The second you eliminated the PEOPLE dictionary, your Python code editor might have complained concerning the undefined PEOPLE variable in your code. Within the subsequent part, you’ll exchange all PEOPLE references with database queries and make your Python editor blissful once more.

Connecting the Database With Your API

Your database is related to your Flask challenge however to not the REST API but. Doubtlessly, you possibly can use the Python interactive shell so as to add extra folks to your database. However it’ll be way more enjoyable to boost your REST API and make the most of present endpoints so as to add knowledge!

On this part, you’ll join your API with the database, so you employ your present endpoints with the database to handle folks. If you wish to recap the way you constructed the API endpoints, then you may jump over to half one of this tutorial collection.

That is how your Flask REST API seems to be in the meanwhile:

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.

Subsequent up, you’ll replace the prevailing features related to the endpoints listed above in order that they’ll work with the folks.db database.

Learn From the Database

First, alter the features in folks.py that learn knowledge from the database with out writing something to the database. Begin with read_all():

# folks.py

# ...

def read_all():
    folks = Individual.question.all()
    return people_schema.dump(folks)

# ...

The read_all() operate responds to the REST API URL endpoint GET /api/folks and returns all of the data within the particular person database desk.

You’re utilizing people_schema which is an occasion of the Marshmallow PersonSchema class the was created with the parameter many=True. With this parameter you inform PersonSchema to count on an interable to serialize. That is vital as a result of the folks variable comprises a listing of database gadgets.

Lastly, you serialize your Python objects with .dump() and return the info of all of the folks as a response to the REST API name.

The opposite operate in folks.py that solely receives knowledge is read_one():

# folks.py

# ...

def read_one(lname):
    particular person = Individual.question.filter(Individual.lname == lname).one_or_none()

    if particular person is not None:
        return person_schema.dump(particular person)
    else:
        abort(404, f"Individual with final title {lname} not discovered")

# ...

The read_one() operate receives an lname parameter from the REST URL path, indicating that the person is searching for a selected particular person.

You utilize lname within the question’s .filter() methodology. Slightly than utilizing .all(), you employ the .one_or_none() methodology to get one particular person, or return None if no match is discovered.

If an individual is discovered, then particular person comprises a Individual object and you come the serialized object. In any other case, you name abort() with an error.

Write to the Database

One other modification to folks.py is creating a brand new particular person within the database. This provides you a chance to make use of the Marshmallow PersonSchema to deserialize a JSON construction despatched with the HTTP request to create a SQLAlchemy Individual object. Right here’s a part of the up to date folks.py module displaying the handler for the REST URL endpoint POST /api/folks:

# folks.py

# ...

def create(particular person):
    lname = particular person.get("lname")
    existing_person = Individual.question.filter(Individual.lname == lname).one_or_none()

    if existing_person is None:
        new_person = person_schema.load(particular person, session=db.session)
        db.session.add(new_person)
        db.session.commit()
        return person_schema.dump(new_person), 201
    else:
        abort(406, f"Individual with final title {lname} already exists")

# ...

As an alternative of receiving solely a final title like in read_one(), create() receives a particular person object. This object should include lname, which should not exist within the database already. The lname worth is your identifier in your particular person, so you may’t have an individual with the identical final title a number of occasions in your database.

If the final title is exclusive, then you definately deserialize the particular person object as new_person and add it db.session. When you commit new_person to the database, your database engine assigns a brand new major key worth and a UTC-based timestamp to the thing. Later, you’ll see the created dataset within the API response.

Modify replace() and delete() equally to the way you adjusted the opposite features:

# folks.py

# ...

def replace(lname, particular person):
    existing_person = Individual.question.filter(Individual.lname == lname).one_or_none()

    if existing_person:
        update_person = person_schema.load(particular 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"Individual with final title {lname} not discovered")

def delete(lname):
    existing_person = Individual.question.filter(Individual.lname == lname).one_or_none()

    if existing_person:
        db.session.delete(existing_person)
        db.session.commit()
        return make_response(f"{lname} efficiently deleted", 200)
    else:
        abort(404, f"Individual with final title {lname} not discovered")

With all these modifications in place, it’s time to replace your front-end code and leverage Swagger UI to check out in case your database works as anticipated.

Show Knowledge in Your Entrance Finish

Now that you simply’ve added the SQLite configuration and outlined your Individual mannequin, your Flask challenge comprises all the knowledge to work along with your database. Earlier than you may show knowledge within the entrance finish, you might want to make some changes to app.py:

 1# app.py
 2
 3from flask import render_template
 4# Take away: import connexion
 5import config
 6from fashions import Individual
 7
 8app = config.connex_app
 9app.add_api(config.basedir / "swagger.yml")
10
11@app.route("/")
12def dwelling():
13    folks = Individual.question.all()
14    return render_template("dwelling.html", folks=folks)
15
16if __name__ == "__main__":
17    app.run(host="0.0.0.0", port=8000, debug=True)

You’re now working with config.py and fashions.py. So that you take away the import within the line 4 and add the imports for config in line 5 and Individual in line 6.

The config module gives the Connexion-flavored Flask app for you. Subsequently, you don’t create a brand new Flask app in app.py anymore, however reference config.connex_app in line 8.

In line 13 you question the Individual mannequin to get all the info from the particular person desk and move it on to render_template() in line 14.

To indicate the folks knowledge within the entrance finish, you might want to alter the dwelling.html template:

<!-- templates/dwelling.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>RP Flask REST API</title>
</head>
<physique>
    <h1>
        Hiya, Folks!
    </h1>
    <ul>
        {% for particular person in folks %}
        <li>{{ particular person.fname }} {{ particular person.lname }}</li>
        {% endfor %}
    </ul>
</physique>
</html>

You’ll be able to run your software with this command within the listing containing the app.py file:

Whenever you run this software, an internet server will begin on port 8000, which is the port that you simply outlined in app.py. For those who open a browser and navigate to http://localhost:8000, you’ll see the info out of your database:

Screenshot of Flask Hello World website with a people list

Superior! Your private home web page lists all three people who find themselves at present in your database. Lastly, you should utilize Swagger UI to create, replace, and delete folks and see the modifications mirrored on the house web page.

Discover Your API Documentation

With the above modifications in place, your database is now purposeful and persists the info even if you restart your software:

You’ll be able to leverage your API so as to add, replace, and take away folks. With the modifications that you simply made to the entrance finish, you’re in a position to see all of the people who find themselves at present saved in your database.

Whenever you restart your Flask app, you don’t reset the info anymore. Because you now have a database hooked up to your Flask challenge, your knowledge is saved.

Conclusion

Congratulations, you’ve lined loads of new materials on this tutorial and added helpful instruments to your arsenal!

Within the second a part of this tutorial collection, you discovered easy methods to:

  • Write SQL instructions in Python
  • Configure a SQLite database in your Flask challenge
  • Use SQLAlchemy to save lots of Python objects to your database
  • Leverage the Marshmallow library to serialize knowledge
  • Join your REST API along with your database

The abilities that you simply’ve discovered have actually been a step up in complexity from the REST API of half one, however that step has given you highly effective instruments to make use of when creating extra complicated purposes. Utilizing them gives you an ideal leg as much as create your individual net purposes backed by a database.

To overview the code for the second a part of this tutorial collection, click on beneath:

Within the subsequent a part of this collection, you’ll prolong your REST API in an effort to create, learn, replace, and delete notes. The notes will probably be saved in a brand new database desk. Each word will probably be related to an individual, so that you’ll add relationships between notes and other people to your database.

Half three will mark the final a part of this tutorial collection. On the finish, you’ll have a full-fledged Flask REST API with associated database tables within the background.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments