Nowadays, the problem of writing APIs in various frameworks and programming languages arises very often. This applies to both small projects for internal needs and enterprise-level projects, which are now being built on the basis of microservices architecture. A lot of tools have now appeared on the market for creating APIs, both proprietary and open source. In this regard, the developer can choose a reliable and correct framework to meet exactly his needs for a specific project.
The Python language is no exception in this series. A lot of frameworks and micro-frameworks have been developed for it, which solve the problems of building a web-oriented system. The very first thing that comes to mind is Django; in addition, Flask and FastAPI are gaining popularity as of late. Of course, these are different frameworks and micro-frameworks, and they perform different tasks. There are projects where each framework will show its best side and will allow you to quickly and efficiently solve the task. That's why, in this article, we will try to avoid direct comparison and consider the advantages of the libraries for building a web application API. Let’s take a look at which tools are suitable for specific projects, all while considering Flask and FastAPI.
Why do we need to build an API?
API and its implementation are one of the most important parts of modern information systems. Around the API, a front-end for web systems is now being built, as well as mobile applications, IoT systems, and so on. That is, the stability and convenience of the entire information system will depend on the quality and reliability of the API execution.
When using the API in the context of web development, the API is typically defined by a set of HTTP request messages, and the structure of response messages is also defined, usually in an XML markup language extension or in a JavaScript object format (JSON). While the Web API has historically been synonymous with the Web service, recently the trend has changed (so-called Web 2.0) to move away from the Simple Object Access Protocol (SOAP) based on Web services and service-oriented architecture) to more direct representations (REST) of web resource styles and resource-oriented architecture (ROA).
Among other things, many users will want to integrate your information system to themselves, and for this they will be happy to use your official API. From the quality of writing documentation and a logical, thoughtful mechanism of communication with your system, clients will make a decision whether to work with your information system or go to competitors.
As mentioned in the great article “Why You Should Care About Building APIs” by Andrew Bodis: “Having a successful digital strategy requires a long-term vision. At the core, this means building and supporting multiple platforms with continuity. An API (Application Programming Interface) is an important method for defining the interactions of a particular product (i.e. what it does/how it can be used) and allowing those interactions to be easily integrated into other platforms. APIs extend the reach of your company.”
Flask and FastAPI for creating HTTP based Application Programming Interface
Flask
Flask is a micro web framework based entirely on WSGI (Web Server Gateway Interface). It is based on Werkzeug tools and the Jinja2 template engine. It lacks the level of abstraction for working with a database, form validation, or other components that provide widely used functions through third-party libraries. However, Flask has support for extensions that provide additional properties as if they were available in Flask from the beginning. There are extensions for establishing object-relational links, validating forms, controlling the download process, supporting a variety of open authentication technologies, and several common tools for the framework.
Although Flask is a microframework, it really does a lot:
- Application Object
- Blueprint Objects
- Incoming Request Data
- Response Objects
- Sessions
- Session Interface
- Test Client
- Test CLI Runner
- Application Globals
- Useful Functions and Classes
- Message Flashing
- JSON Support
- Template Rendering
- Configuration
- Stream Helpers
- Useful Internals
- Signals
- Class-Based Views
- URL Route Registrations
- View Function Options
- Command Line Interface
Installing Flask is incredibly simple as you can do it in one line:
pip install flask
In the following example, you can easily process requests from a client with various routes and quickly launch it into operation, with the possibility of expanding the functionality to a workable web system with a client part, since Flask supports both static files and stratum templates.
from flask import Flask, url_for
from markupsafe import escape
app = Flask(__name__)
@app.route('/')
def index():
return 'index'
@app.route('/login')
def login():
return 'login'
@app.route('/user/<username>')
def profile(username):
return '{}\'s profile'.format(escape(username))
with app.test_request_context():
print(url_for('index'))
print(url_for('login'))
print(url_for('login', next='/'))
print(url_for('profile', username='John Doe'))
Code language: JavaScript (javascript)
This will process the following requests:
/
/login
/login?next=/
/user/John%20Doe
The ability to handle HTTP requests by means of the request library from Flask is also very good and convenient.
from flask import request
@app.route('/login', methods=['POST', 'GET'])
def login():
error = None
if request.method == 'POST':
if valid_login(request.form['username'],
request.form['password']):
return log_the_user_in(request.form['username'])
else:
error = 'Invalid username/password'
# the code below is executed if the request method
# was GET or the credentials were invalid
return render_template('login.html', error=error)
Code language: PHP (php)
As for the asynchronous work of a web server under Flask, then we can recommend using, for example, asyncio. This allows, in principle and without changing the architecture and approach in the project, to switch to servicing asynchronous requests to the server, if you have such a need.
FastAPI
FastAPI was released much later in Flask and is now becoming the de facto choice for building high-performance data processing applications using Python. The official documentation describes the following key features of FastAPI:
- Fast: very high performance, on par with NodeJS and Go.
- Fast Code: Increases the speed of feature development by about 200-300%.
- Fewer errors: Reduces human (developer) errors by about 40%.
- Intuitive: Excellent editor support. Doesn't take a lot of time to debug.
- Ease: Easy to learn and easy to use. It doesn't take long to read the documentation.
- Brevity: Minimizes code duplication. Multiple objects from each parameter declaration. Less bugs.
- Reliability: Produces working code with automatic interactive documentation.
- Standards Based: Based on (and fully compatible with) open API standards such as OpenAPI (formerly known as Swagger) and JSON Schema.
As mentioned in the article ”Comparison of FastAPI and Flask. Simple Explanation!”: “FastAPI provides us with a powerful dependency injection system that means infinite plug-ins. When you are using FastAPI your API will be compatible with OpenAPI, JSON Schema and OAuth2.0 which will be handled by FastAPI.” FastAPI is based on Starlette and implements the ASGI specification. ASGI (Asynchronous Server Gateway Interface), is the successor to WSGI because it is capable of achieving high throughput in I/O contexts and provides support for HTTP/2 and WebSockets that cannot be handled by WSGI. System installation for using FastAPI is extremely simple:
pip install fastapi
pip install uvicorn[standard]
Code language: CSS (css)
The FastAPI framework takes full advantage of Starlette's functionality and Flask's programming style, thus becoming an ASGI web framework “a la Flask”. In addition, it includes the following features that make it an ideal web framework for building RESTful APIs:
- Data Validation: Uses the Pydantic library which applies type hints at runtime. It also provides user-friendly error descriptions in cases where data is invalid.
- Documentation: There is support for automatically documenting data models using JSON schema. Comes with either UI Swagger or ReDoc.
Let’s demonstrate how FastAPI can easily build API with using model by pydantic. Save the following Python code to the file fastapitest.py:
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
@app.get("/")
def read_root():
return {"FastAPI test"}
@app.get("/items/{id}")
def read_item(id: int, query: Optional[str] = None):
return {"id": id, "query": query}
@app.post("/items/{id}")
def create_item(id: int, item: Item):
return {"name": item.name, "id": id, "price": item.price}
@app.put("/items/{id}")
def update_item(id: int, item: Item):
return {"name": item.name, "id": id, "price": item.price}
Running as a Python command, it can produce a syntax error, so please use uvicorn. Uvicorn is a lightning-fast ASGI server implementation, and it provides a minimal low-level server/application interface for asyncio frameworks. Let’s run this file (fastapitest.py):
uvicorn fastapitest:app --reload
Code language: CSS (css)
In order to test the functionality of this wonderful code, open the browser using the link at
http://127.0.0.1:8000/items/1?query=somequery
Code language: JavaScript (javascript)
You will be able to see the JSON file of the response from the server.
In the FastAPI library, to work in asynchronous mode, you can use the already built-in feature, and you need to add an additional async instruction to the calls of the path methods, and in principle the code will become asynchronous. But this is just part of the work, and in more detail you will need to monitor the work of the entire application code for simultaneous work and so that these changes do not affect the functioning of the project. On the other hand, though, it may be better to write code asynchronously right away if you really need this kind of application behavior. You can learn more about this in the documentation in FastAPI.
Documenting API with Swagger and redoc with FastAPI
Documentation plays a very important role in the creation of APIs, which is updated in a timely manner with each release of the project and in a convenient form, allowing users to receive all the necessary information on requests and formats of input-output data. FastAPI developers made it possible to generate documentation from code in the Swagger format (OpenAPI). This significantly improves project documentation and saves a lot of time. Open the browser to http://127.0.0.1:8000/docs#/
In addition, you can also open the redoc documentation.
Unit-testing Flask and FastAPI
Fortunately, developers immediately thought about unit testing and made a very good module for writing tests for the API. This saves effort and resources when debugging the system and adding new functionality.
So, to organize unit testing in Flask, you can very quickly connect pytest, which allows you to approach the task of building unit tests in a completely familiar way. Check out how nicely and conveniently the unit testing system is done in this example from the Flask documentation:
def login(client, username, password):
return client.post('/login', data=dict(
username=username,
password=password
), follow_redirects=True)
def logout(client):
return client.get('/logout', follow_redirects=True)
Code language: PHP (php)
Now we can easily test that logging in and out works and that it fails with invalid credentials. Add this new test function:
def test_login_logout(client):
"""Make sure login and logout works."""
rv=login(client,flaskr.app.config['USERNAME'],flaskr.app.config['PASSWORD'])
assert b'You were logged in' in rv.data
rv = logout(client)
assert b'You were logged out' in rv.data
rv = login(client, flaskr.app.config['USERNAME'] + 'x',
flaskr.app.config['PASSWORD'])
assert b'Invalid username' in rv.data
rv = login(client, flaskr.app.config['USERNAME'],
flaskr.app.config['PASSWORD'] + 'x')
assert b'Invalid password' in rv.data
Code language: JavaScript (javascript)
Similarly, in FastAPI, the code is so good that it is readable with almost no additional calls to manuals, which is very good for an intuitive understanding of the structure and strategy of the system.
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_main():
return {"msg": "Hello World"}
Code language: JavaScript (javascript)
Then you can create a file test_main.py with your tests, and import your app from the main module (main.py):
from fastapi.testclient import TestClient
from .main import app
client = TestClient(app)
def test_read_main():
response = client.get("/")
assert response.status_code == 200
assert response.json() == {"msg": "Hello World"}
Code language: JavaScript (javascript)
That is, in this case, assert will compare the system response and the JSON string {"msg": "Hello World"}.
Using FastAPI and Flask in the Сlouds
Basically, both FastAPI and Flask are very well designed and can be easily integrated into cloud systems like AWS, Google Cloud, Azure, Intel Cloud, IBM Cloud and others. Among other things, there are also libraries that facilitate tasks for these libraries in cloud systems. An example of such a library is, say, the FastAPI Cloud Drives library, which greatly facilitates working with cloud storage: https://pypi.org/project/fastapi-cloud-drives/. Another example would be the described authentication technology for FastAPI, as described in the next article “Intel Cloud Services Authentication on FastAPI App with LoginRadius”. You can also very well use cloud systems of the PaaS class for deploying FastAPI and Flask projects. For example, the Heroku cloud system is very suitable for this.
Conclusion
In conclusion, we note that each tool is valuable for performing its tasks. So both FastAPI and Flask will be useful for you to solve exactly your specific task in the project. If you set yourself the task of creating a web system with a client side, using static files, using templates and at the same time making a fairly fast and high-quality API, then you should use Flask. For larger projects, you should already consider using Django or similar full-blown frameworks. If you set yourself the task of making a very fast backend (with a speed as NodeJs and Go) for a web system and/or for a mobile application, with automatic preparation of API documentation, or write a microservice that handles Cookies, Headers, Forms, Files out of the box, then you need to use FastAPI. By the way, which will very well cope with the high load on the servers and scale in cloud systems.
At Svitla Systems Our engineers and system analysts, project managers and senior developers, testers pay special attention to building an API regardless of the chosen technology and framework. High-quality execution of the software interface, and even more so using HTTP, is necessary for the stable operation of the entire project in the future. Therefore, you can contact our specialists for the development and testing of all classes of information systems, which we have been doing in the company for almost 20 years. In addition, our qualified devops engineers will set up the entire development and deployment process in cloud systems.
Svitla Systems also provides qualified testing services both in the field of manual testing and in the field of automated testing of complex information systems. You can apply for qualified advice and project development to Svitla Systems using the most modern tools and technologies in information systems.