Python REST APIs With Flask, Connexion, and SQLAlchemy - Real Python PDF
Python REST APIs With Flask, Connexion, and SQLAlchemy - Real Python PDF
Table of Contents
What REST Is
What REST Is Not
The People REST API
Getting Started
Using Connexion to Add a REST API Endpoint
Adding Connexion to the Server
The Swagger Configuration File
Handler for People Endpoint
The Swagger UI
Building Out the Complete API
The Swagger UI Completed
Demonstration Single-Page Application
Static Files
JavaScript File
Demo Application
Example Code
Conclusion
If you’re writing a web application, then you’re probably thinking about making HTTP calls to your server to get data
to populate the dynamic parts of your application.
The goal of this article is to show you how to use Python 3, Flask, and Connexion to build useful REST APIs that can
include input and output validation, and provide Swagger documentation as a bonus. Also included is a simple but
useful single page web application that demonstrates using the API with JavaScript and updating the DOM with it.
The REST API you’ll be building will serve a simple people data structure where the people are keyed to the last name,
and any updates are marked with a new timestamp. Improve Your Python
https://realpython.com/flask-connexion-rest-api/ 1/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
This data could be represented in a database, saved in a file, or be accessible through some network protocol, but for
us an in-memory data structure works fine. One of the purposes of an API is to decouple the data from the application
that uses it, hiding the data implementation details.
Free Bonus: Click here to download a copy of the "REST in a Nutshell" Guide with a hands-on introduction
to REST API principles and examples.
What REST Is
Before you get started creating an API server, I want to talk about REST a little bit. There’s lots of information about
REST available through some quick Google searches, and my intent is not to duplicate that here.Improve Your Python
...with
I just want to share how I view REST and use it to build APIs. I see REST as a set of a fresh 🐍 Python Trick 💌
conventions
taking advantage of the
HTTP protocol to provide CRUD (Create, Read, Update, and Delete) behavior on code thingssnippet every couple
and collections of days:
of those things.
The CRUD behavior maps nicely to the HTTP protocol method verbs like this:
Email Address
Action HTTP Verb Description
You can perform these actions on a thing or resource. It’s useful to think about a resource as something a noun can be
applied to: a person, an order for something, a person’s address. This idea of a resource lines up nicely with a URL
(Unique Resource Locator).
A URL should identify a unique resource on the web, something that will work with the same thing over and over
again for the same URL. With these two ideas, we have a way to take common application actions on something
uniquely identified on the web. This is a very useful way of working.
This idea goes a long way towards creating clean APIs and performing the actions many applications want from the
API.
/api/substituteString/<string>/<search_string>/<sub_string>
Here, string is the string to make the substitution in, search_string is the string to replace, and sub_string is the
string to replace search_string with. This can certainly be tied to some code in the server that does the intended
work. But this has some problems in REST terms.
One problem that comes to mind is that this URL doesn’t point to a unique resource, so what it returns is entirely
dependent on the path variable sections. Also, there is no concept of CRUD against this URL. It really only needs one
HTTP method, and the method name conveys nothing about the action to take.
As an API, it’s not great either. The meaning of the path variables is dependent on their position in the URL. This could
be addressed by changing the URL to use a query string instead, like this:
/api/substituteString?string=<string>&search_string=<search_string>&sub_string=<sub_string>
Improve Your Python
https://realpython.com/flask-connexion-rest-api/ 2/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
But the URL portion /api/substituteString isn’t a thing (noun) or collection of things at all: it’s an action (verb).
This doesn’t fit well in the REST conventions, and trying to force it to do so makes for a poor API. What the above
really represents is an RPC, or Remote Procedure Call. Thinking about this as an RPC makes much more sense.
The beauty is that both REST and RPC conventions can coexist in an API without any problems! By keeping in mind
the intention of each, you can use both to compliment each other in your API design. There are many situations where
it would be useful to perform CRUD operations on something. There are also many situations where it would be
useful to take an action with a thing (as a parameter) but not necessarily a ect the thing itself.
HTTP
Action Verb URL Path Description Email Address
Read GET /api/people/Farrell Defines a unique URL to read a particular person in the people
collection
Getting Started
First, you’ll create a simple web server using the Flask Micro Framework. To get started, create a directory where you
can create the code. You should also work in a virtualenv so you can install modules later on, which you’ll need to do.
In addition, create a templates directory.
The Python code below gets a very basic web server up and running, and responding with Hello World for a request
for the home page:
Python
https://realpython.com/flask-connexion-rest-api/ 3/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
You should also create a home.html in the templates folder, as this is what will be served to a browser when navigating
to the URL '/'. Here is the contents of the home.html file:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Application Home Page</title>
</head>
<body>
<h2>
</h2>
Hello World!
Improve Your Python
</body>
...with a fresh 🐍 Python Trick 💌
</html>
code snippet every couple of days:
You’ll notice the HTML file is named home.html rather than index.html. This is intentional because having an
Email Address
index.html file in the templates directory causes problems once you import the Connexion module in your program.
You can run your application with this command line in the directory containing theSend
server.py file with the Python
Python Tricks »
VirtualEnv active:
Shell
python server.py
When you run this application, a web server will start on port 5000, which is the default port used by Flask. If you open
a browser and navigate to localhost:5000, you should see Hello World! displayed. Right now, this is useful to see the
web server is running. You’ll extend the home.html file later to become a full single page web application using the
REST API you’re developing.
In your Python program, you’ve imported the Flask module, giving the application access to the Flask functionality.
You then created a Flask application instance, the app variable. Next, you connected the URL route '/' to the home()
function by decorating it with @app.route('/'). This function calls the Flask render_template() function to get the
home.html file from the templates directory and return it to the browser.
All of the example code is available from a link provided at the end of this article.
Shell
This makes the Connexion module available to your program. The Connexion module allows a Python program to use
the Swagger specification. This provides a lot of functionality: validation of input and output data to and from your
API, an easy way to configure the API URL endpoints and the parameters expected, and a really nice UI interface to
work with the created API and explore it.
All of this can happen when you create a configuration file your application can access. The Swagger site even
provides an online configuration editor tool to help create and/or syntax check the configuration file you will create.
Python
Improve Your Python
https://realpython.com/flask-connexion-rest-api/ 4/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
# If we're running in stand alone mode, run the application Email Address
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
Part of the app instance creation includes the parameter specification_dir. This informs Connexion what directory to
look in for its configuration file, in this case our current directory. Right a er this, you’ve added the line:
app.add_api('swagger.yml')
This tells the app instance to read the file swagger.yml from the specification directory and configure the system to
provide the Connexion functionality.
YAML
https://realpython.com/flask-connexion-rest-api/ 5/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
swagger: "2.0"
info:
description: This is the swagger file that goes with our server code
version: "1.0.0"
title: Swagger REST Article
consumes:
- "application/json"
produces:
- "application/json"
basePath: "/api"
This file is organized in a hierarchical manner: the indentation levels represent a level of ownership, or scope.
For example, paths defines the beginning of where all the API URL endpoints are defined. The /people value indented
under that defines the start of where all the /api/people URL endpoints will be defined. The get: indented under that
defines the section of definitions associated with an HTTP GET request to the /api/people URL endpoint. This goes on
for the entire configuration.
Here are the meanings of the fields in this section of the swagger.yml file:
1. swagger: tells Connexion what version of the Swagger API is being used
2. info: begins a new ‘scope’ of information about the API being built
3. description: a user defined description of what the API provides or is about. This is in the Connexion generated
UI system
4. version: a user defined version value for the API
5. title: a user defined title included in the Connexion generated UI system
6. consumes: tells Connexion what MIME type is expected by the API.
7. produces: tells Connexion what content type is expected by the caller of the API.
8. basePath: "/api" defines the root of the API, kind of like a namespace the REST API will come from.
This section begins the configuration of the API URL endpoint paths:
1. paths: defines the section of the configuration containing all of the API REST endpoints.
2. /people: defines one path of your URL endpoint.
3. get: defines the HTTP method this URL endpoint will respond to. Together with the previous definitions, this
creates the GET /api/people URL endpoint.
This section begins the configuration of the single /api/people URL endpoint:
https://realpython.com/flask-connexion-rest-api/ 6/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
1. operationId: "people.read" defines the Python import path/function that will respond to an HTTP GET
/api/people request. The "people.read" portion can go as deep as you need to in order to connect a function to
the HTTP request. Something like "<package_name>.<package_name>.<package_name>.<function_name>" would
work just as well. You’ll create this shortly.
2. tags: defines a grouping for the UI interface. All the CRUD methods you’ll define for the people endpoint will
share this tag definition.
3. summary defines the UI interface display text for this endpoint.
4. description: defines what the UI interface will display for implementation notes.
This section defines the section of the configuration of a successful response from the URL endpoint:
Python
https://realpython.com/flask-connexion-rest-api/ 7/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
def get_timestamp():
return datetime.now().strftime(("%Y-%m-%d %H:%M:%S"))
In this code, you’ve created a helper function called get_timestamp() that generates a string representation of the
current timestamp. This is used to create your in-memory structure and modify the data when you start modifying it
with the API.
You then created the PEOPLE dictionary data structure, which is a simple names database, keyed on the last name. This
is a module variable, so its state persists between REST API calls. In a real application, the PEOPLE data would exist in a
database, file, or network resource, something that persists the data beyond running/stopping the web application.
Then you created the read() function. This is called when an HTTP request to GET /api/people is received by the
server. The return value of this function is converted to a JSON string (recall the produces: definition in the
swagger.yml file). The read() function you created builds and returns a list of people sorted by last name.
Running your server code and navigating in a browser to localhost:5000/api/people will display the list of people on
screen:
JavaScript
[
{
"fname": "Kent",
"lname": "Brockman",
"timestamp": "2018-05-10 18:12:42"
},
{
"fname": "Bunny",
"lname": "Easter",
"timestamp": "2018-05-10 18:12:42"
},
{
"fname": "Doug",
"lname": "Farrell",
"timestamp": "2018-05-10 18:12:42"
}
]
https://realpython.com/flask-connexion-rest-api/ 8/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
Congratulations, you’ve created a nice API and are on your way to building out a complete one!
The Swagger UI
Now you have a simple web API running with a single URL endpoint. At this point, it would be reasonable to think,
“configuring this with the swagger.yml file was cool and all, but what did it get me?”
You’d be right to think that. We haven’t taken advantage of the input or output validation. All that swagger.yml gave us
was a definition for the code path connected to the URL endpoint. However, what you also get for the extra work is the
creation of the Swagger UI for your API.
Email Address
This is the initial Swagger interface and shows the list of URL endpoints supported at our localhost:5000/api
endpoint. This is built automatically by Connexion when it parses the swagger.yml file.
If you click on the /people endpoint in the interface, the interface will expand to show a great deal more information
about your API and should look something like this:
This displays the structure of the expected response, the content-type of that response, and the description text you
entered about the endpoint in the swagger.yml file.
You can even try the endpoint out by clicking the Try It Out! button at the bottom of the screen. That will further
expand the interface to look something like this: Improve Your Python
https://realpython.com/flask-connexion-rest-api/ 9/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
Email Address
This can be extremely useful when the API is complete as it gives you and your API users a way to explore and
experiment with the API without having to write any code to do so.
Building an API this way is very useful to me at work. Not only is the Swagger UI useful as a way to experiment with
the API and read the provided documentation, but it’s also dynamic. Any time the configuration file changes, the
Swagger UI changes as well.
In addition, the configuration o ers a nice, clean way to think about and create the API URL endpoints. I know from
experience that APIs can develop in a sometimes random manner over time, making finding the code that supports
the endpoints, and coordinating them, di icult at best.
By separating the code from the API URL endpoint configuration, we decouple one from the other. This alone has
been very useful to me in my work building API systems supporting single page web applications.
https://realpython.com/flask-connexion-rest-api/ 10/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
Our original goal was to build out an API providing full CRUD access to our people structure. As you recall, the
definition of our API looks like this:
HTTP
Action Verb URL Path Description
Read GET /api/people/Farrell Defines a unique URL to read a particular person in the people
collection
Improve Your Python
...with a fresh 🐍 Python Trick 💌
Update PUT /api/people/Farrell Defines a unique URL to update an snippet
code existing every
order couple of days:
To achieve this, you’ll extend both the swagger.yml and people.py files to fully support the API defined above. For the
sake of brevity, only a link will be provided for both files: Send Python Tricks »
swagger.yml
people.py
This UI allows you to see all of the documentation you’ve included in the swagger.yml file and interact with all of the
URL endpoints making up the CRUD functionality of the people interface.
You’ll create a web application that displays the people on screen as well as allows the user to create new people,
update existing people, and delete people. This will all be handled by AJAX calls from JavaScript to the people API
URL endpoints.
To begin, you need to extend the home.html file to look like this:
HTML
Improve Your Python
https://realpython.com/flask-connexion-rest-api/ 11/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Application Home Page</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css">
<link rel="stylesheet" href="static/css/home.css">
<script
src="http://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous">
</script>
</head>
<body> Improve Your Python
<div class="container">
<h1 class="banner">People Demo Application</h1> ...with a fresh 🐍 Python Trick 💌
<div class="section editor"> code snippet every couple of days:
<label for="fname">First Name
<input id="fname" type="text" />
</label> Email Address
<br />
<label for="lname">Last Name
<input id="lname" type="text" />
Send Python Tricks »
</label>
<br />
<button id="create">Create</button>
<button id="update">Update</button>
<button id="delete">Delete</button>
<button id="reset">Reset</button>
</div>
<div class="people">
<table>
<caption>People</caption>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Update Time</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<div class="error">
</div>
</div>
</body>
<script src="static/js/home.js"></script>
</html>
The above HTML code extends the home.html file to pull in the external normalize.min.css file, which is a CSS reset file
to normalize the formatting of elements across browsers.
It also pulls in the external jquery-3.3.1.min.js file to provide the jQuery functionality you’ll use to create the single-
page application interactivity.
The HTML code above creates the static framework of the application. The dynamic parts appearing in the table
structure will be added by JavaScript at load time and as the user interacts with the application.
Static Files
In the home.html file you’ve created, there are references to two static files: static/css/home.css and
static/js/home.js. To add these, you’ll need to add the following directory structure to the application:
https://realpython.com/flask-connexion-rest-api/ 12/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
static/
│
├── css/
│ └── home.css
│
└── js/
└── home.js
Because a directory named static will automatically be served by the Flask application, any files you place in the css
and js folders will be available to the home.html file. For the sake of brevity, here are links to the home.css and home.js
files:
Improve Your Python
home.css
Each object is created by a self-invoking function returning its own API for use by the other pieces. For instance, the
Controller is passed the instances of the Model and View as parameters in its instantiation. It interacts with those
objects through their exposed API methods.
The only other connection is between the Model and Controller by means of custom events on the AJAX method calls:
1. The Model provides the connection to the people API. Its own API is what the Controller calls to interact with the
server when a user interaction event requires it.
2. The View provides the mechanism to update the web application DOM. Its own API is what the Controller calls
to update the DOM when a user interaction event requires it.
3. The Controller provides all the event handlers for user interaction with the web application. This allows it to
make calls to the Model to make requests to the people API, and to the View to update the DOM with new
information received from the people API.
It also handles the custom events generated by the asynchronous AJAX requests made by the Model to the people
API.
The idea is that the Controller has a strong link to both the Model and the View. The Model has a weak link (the
custom events) to the Controller and no connection to the View at all. The weak link from the Model to the Controller
reduces coupling and dependence, which is useful in this case.
Demo Application
When created, the web application will look like this in the browser:
Improve Your Python
https://realpython.com/flask-connexion-rest-api/ 13/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
The Create button allows the user to create a new person in the people structure on the Address
Email server. When you enter a First
and Last Name and hit Create, the Controller calls the Model to make a request to the POST /api/people URL
endpoint. This will verify that the last name doesn’t already exist. If it doesn’t, it will create a new person in the people
structure. Send Python Tricks »
This generates a custom event in the Model that causes the Controller to call the Model again to request a GET
/api/people, which will return the complete list of people sorted. The Controller then passes that onto the View to
redraw the table of people.
Double clicking on any row in the table will populate the First and Last Name fields in the editor section of the
application. At this point, the user can either update or delete the person.
To update successfully, the user must change something about the First Name. The Last Name must remain the same
as it’s the lookup key for the person to update. When Update is clicked, the Controller calls the Model to make a
request to the PUT /api/people/{lname} URL endpoint. This will verify that the Last Name does currently exist. If so, it
will update that person in the people structure.
This generates a custom event in the Model that causes the Controller to call the Model again to request a GET
/api/people, which will return the complete list of people sorted. The Controller then passes that onto the View to
redraw the table of people.
To delete successfully, the user need only click Delete. When Delete is clicked, the Controller calls the Model to make
a request to the DELETE /api/people/{lname} URL endpoint. This will verify that the last name does currently exist. If
so, it will delete that person from the people structure.
This generates a custom event in the Model that causes the Controller to call the Model again to request a GET
/api/people, which will return the complete list of people sorted. The Controller then passes that onto the View to
redraw the table of people.
Try making intentional errors in the editor, like misspelling a Last Name, and see the errors generated by the API
represented on the web application.
Example Code
All of the example code for this article is available here. There are four versions of the code, each in a version_#
directory, where # ranges from 1 to 4. The four versions correspond to the article sections in this manner:
1. version_1: This version contains the initial web server that serves up the home.html file.
2. version_2: This version contains the web server with Connexion added and the first people API URL endpoint.
3. version_3: This version contains the completed people API with all supported URL endpoints.
4. version_4: This version contains the completed API and a single page web application to demonstrate it.
Free Bonus: Click here to download a copy of the "REST in a Nutshell" Guide with a hands-on introduction
to REST API principles and examples.
Improve Your Python
https://realpython.com/flask-connexion-rest-api/ 14/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
Conclusion
In this tutorial, you saw how relatively easy it is to create a comprehensive REST API with Python. With the Connexion
module and some additional configuration work, a useful documentation and interactive system can be put in place,
making your API a much more enjoyable experience for your users to interface with and understand.
In Part 2 of this series, you’ll learn how to use a proper database to store your data permanently instead of relying on
in-memory storage as we did here:
Get a short & sweet Python Trick delivered to your inbox every couple of Email Address
days. No spam ever. Unsubscribe any time. Curated by the Real Python
team.
Send Python Tricks »
Email Address
Doug is a Python developer with more than 25 years of experience. He writes about Python on
his personal website and works as a Senior Web Engineer with Shutterfly.
Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who
worked on this tutorial are:
https://realpython.com/flask-connexion-rest-api/ 15/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
Real Python Comment Policy: The most useful comments are those written with the goal of learning
from or helping out other readers—a er reading the whole article and all the earlier comments.
Complaints and insults generally won’t make the cut here.
Improve Your Python
65 Comments Real Python ...with a fresh 🐍 Python Trick 💌
1 Login
code snippet every couple of days:
Recommend 8 t Tweet f Share Sort by Best
Email Address
Join the discussion…
LOG IN WITH
OR SIGN UP WITH DISQUS ?
Send Python Tricks »
Name
https://github.com/zalando/...
4△ ▽ • Reply • Share ›
swagger: "2.0"
info:
description: This is the swagger file that goes with our server code
version: "1.0.0"
title: Swagger ReST Article
1△ ▽ • Reply • Share ›
Thanks
Gav
△ ▽ • Reply • Share ›
Since I'm a newbie, I'm unable to figure out the fix. Please help. Send Python Tricks »
△ ▽ • Reply • Share ›
Shameless plug: I have made a lib which lets you organize your Connexion schema into multiple files in a nested
directory structure:https://pypi.org/project/co...
△ ▽ • Reply • Share ›
I fixed this. Flask detected that swagger UI could not be accessed and suggested to install connexion with 'pip install
connexion[swagger-ui]'
△ ▽ • Reply • Share ›
Firs of all, thanks for this amazing tutorial. It helped me understand what an API is and how to code it.
Improve Your Python
But still I have a problem: I'm just coding it myself and, when I connect to the browser and put the url /api/ui, the
https://realpython.com/flask-connexion-rest-api/ 18/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
swagger ui does not appear. Also, the localhost:5000/ does not show the home.html, it actually raises the exception:
jinja2.exceptions.TemplateNotFound
TemplateNotFound: home.html
The swagger.yml file is unfortunately written from scratch. However, there Email
is anAddress
online tool here that I've used
to help me find syntax errors in the file. It's a useful editor, but it doesn't auto-generate the configuration file for
you.
One of the things see happening all the time is a URL endpoint being proposed as being REST, but in reality it
has nothing to do with CRUD operations. Instead it is a RPC (Remote Procedure Call) that doesn't apply to a
resource, but takes some action based on the parameters passed to it. I write lots of these as well, but I never
think of them as REST and I always code them the same way: as a PUT method, passing the parameters as
a JSON string in the body of the request. To me this has much more flexibility than putting the parameters in
the path (which I consider misleading) or encoding them into a query_string.
Doug
△ ▽ • Reply • Share ›
app = connexion.App(__name__)
app.add_api('swagger.yaml')
application = app.app
This works for me now. Does the tutorial work for others as originally written and I've missed something?
2△ ▽ • Reply • Share ›
13 Project Ideas for Intermediate Python Developers Using PyInstaller to Easily Distribute Python
6 comments • 3 months ago Applications
3RI Technologies Pvt. Ltd. — Informative post on ideas for 5 comments • 3 months ago
AvatarIntermediate Python Developers ! Alfa_Q — Interesting post. I'm definitely going to have to
Avatargive this a try 😁👍
How to Stand Out in a Python Coding Interview Get Started With Django Part 1: Build a Portfolio App
12 comments • 3 months ago 49 comments • 2 months ago
Geir Arne Hjelle — Hi Nitin. That's a cool story :) I think datalearner88 — yes, that is correct it is located in the
Avataryour solution is a very good one. It's readable and shows Avatarpersonal_portfolio folder
that you …
✉ Subscribe d Add Disqus to your siteAdd DisqusAdd 🔒 Disqus' Privacy PolicyPrivacy PolicyPrivacy
https://realpython.com/flask-connexion-rest-api/ 21/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
Email Address
Keep Learning
Send Python Tricks »
Related Tutorial Categories: api flask intermediate web-dev
🐍 Python Tricks 💌
Email…
https://realpython.com/flask-connexion-rest-api/ 22/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
https://realpython.com/flask-connexion-rest-api/ 23/24
5/29/2019 Python REST APIs With Flask, Connexion, and SQLAlchemy – Real Python
Email Address
https://realpython.com/flask-connexion-rest-api/ 24/24