Building Restful apis with Python and Flask Fastapi
Building RESTful APIs has become an important part of web development, as it allows developers to create web services that can be easily consumed by other applications. In this blog, we will explore how to build RESTful APIs using Python and two popular frameworks - Flask and FastAPI.
What is RESTful API?
REST stands for Representational State Transfer, which is a software architectural style for building scalable and loosely coupled web services. RESTful APIs are designed to be lightweight, scalable, and easily consumable by other applications. RESTful APIs use HTTP requests to perform CRUD (Create, Read, Update, Delete) operations on data resources.
Why use Python for RESTful API development?
Python is a popular programming language with a large and active community. It offers a wide range of libraries and frameworks that make it easy to develop RESTful APIs. Python is also known for its simplicity, readability, and ease of use, which makes it a great choice for building web services.
Flask vs FastAPI: Which one to choose?
Flask and FastAPI are two popular Python frameworks for building RESTful APIs. Flask is a lightweight and flexible framework that is easy to use and can be used to build small to medium-sized APIs. On the other hand, FastAPI is a modern and fast framework that is built on top of the latest Python features and can be used to build large and complex APIs.
Both Flask and FastAPI have their own advantages and disadvantages. Flask is a mature and stable framework that has been around for a long time and has a large community. FastAPI, on the other hand, is a relatively new framework that is gaining popularity due to its speed and modern features.
In this blog, we will explore both Flask and FastAPI and learn how to build RESTful APIs using both frameworks.
Building a RESTful API with Flask
To get started with Flask, we need to install it using pip:
pip install Flask
After installing Flask, we can create a new Flask application:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello World!'
if __name__ == '__main__':
app.run()
In this example, we created a new Flask application and defined a simple route that returns 'Hello World!' when the root URL is accessed. We then started the application using the run()
method.
To create a RESTful API with Flask, we need to define routes that map to different HTTP methods. For example, to create a route for creating a new resource, we can use the POST
method:
@app.route('/api/users', methods=['POST'])
def create_user():
# create a new user
return 'User created!'
In this example, we defined a new route /api/users
that maps to the create_user()
function. We also specified that this route should only be accessible using the POST
method.
To read data from a resource, we can use the GET
method:
@app.route('/api/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
# get the user with the specified ID
return f'User {user_id} fetched!'
In this example, we defined a new route /api/users/<int:user_id>
that maps to the get_user()
function. We also specified that this route should only be accessible using the GET
method. The <int:user_id>
part of the route specifies that the user_id
parameter should be an integer.
To update a resource, we can use the PUT
method:
@app.route('/api/users/int:user_id', methods=['PUT'])
def update_user(user_id):
# update the user with the specified ID
return f'User {user_id} updated!'
In this example, we defined a new route /api/users/<int:user_id>
that maps to the update_user()
function. We also specified that this route should only be accessible using the PUT
method. The <int:user_id>
part of the route specifies that the user_id
parameter should be an integer.
To delete a resource, we can use the DELETE
method:
@app.route('/api/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
# delete the user with the specified ID
return f'User {user_id} deleted!'
In this example, we defined a new route /api/users/<int:user_id>
that maps to the delete_user()
function. We also specified that this route should only be accessible using the DELETE
method. The <int:user_id>
part of the route specifies that the user_id
parameter should be an integer.
We can also return JSON data from our API using the jsonify()
method:
from flask import jsonify
@app.route('/api/users', methods=['GET'])
def get_users():
# get a list of users
users = [{'id': 1, 'name': 'John Doe'}, {'id': 2, 'name': 'Jane Doe'}]
return jsonify(users)
In this example, we defined a new route /api/users
that maps to the get_users()
function. We returned a list of users in JSON format using the jsonify()
method.
Building a RESTful API with FastAPI
To get started with FastAPI, we need to install it using pip:
pip install fastapi
We also need to install the uvicorn server, which is used to run FastAPI applications:
pip install uvicorn
After installing FastAPI, we can create a new FastAPI application:
from fastapi import FastAPI
app = FastAPI()
@app.get('/')
def hello():
return {'message': 'Hello World!'}
In this example, we created a new FastAPI application and defined a simple route that returns a JSON object containing the message 'Hello World!' when the root URL is accessed.
To create a RESTful API with FastAPI, we need to define routes that map to different HTTP methods. For example, to create a route for creating a new resource, we can use the POST
method:
@app.post('/api/users')
def create_user():
# create a new user
return {'message': 'User created!'}
In this example, we defined a new route /api/users
that maps to the create_user()
function. We also specified that this route should only be accessible using the POST
method.
To read data from a resource, we can use the GET
method:
@app.get('/api/users/{user_id}')
def get_user(user_id: int):
# get the user with the specified ID
return {'message': f'User {user_id} fetched!'}
In this example, we defined a new route /api/users/{user_id}
that maps to the get_user()
function. We also specified that this route should only be accessible using the GET
method. The {user_id}
part of the route specifies that the user_id
parameter should be a path parameter of type integer.
To update a resource, we can use the PUT
method:
@app.put('/api/users/{user_id}')
def update_user(user_id: int):
# update the user with the specified ID
return {'message': f'User {user_id} updated!'}
In this example, we defined a new route /api/users/{user_id}
that maps to the update_user()
function. We also specified that this route should only be accessible using the PUT
method. The {user_id}
part of the route specifies that the user_id
parameter should be a path parameter of type integer.
To delete a resource, we can use the DELETE
method:
@app.delete('/api/users/{user_id}')
def delete_user(user_id: int):
# delete the user with the specified ID
return {'message': f'User {user_id} deleted!'}
In this example, we defined a new route /api/users/{user_id}
that maps to the delete_user()
function. We also specified that this route should only be accessible using the DELETE
method. The {user_id}
part of the route specifies that the user_id
parameter should be a path parameter of type integer.
We can also use FastAPI's data models to define the structure of our data. For example, we can define a data model for a user like this:
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
email: str
In this example, we defined a User
data model that has three fields: id
, name
, and email
.
We can use this data model to define the structure of the data that is sent in requests and responses. For example, we can update our create_user()
function to accept a User
object in the request body:
@app.post('/api/users')
def create_user(user: User):
# create a new user
return {'message': 'User created!', 'user': user}
In this example, we updated our create_user()
function to accept a User
object in the request body. We also updated the response to include the created user in the response body.
We can also use FastAPI's Response
class to return custom HTTP responses. For example, we can return a 201 Created
response when a new resource is created:
from fastapi import Response
@app.post('/api/users')
def create_user(user: User, response: Response):
# create a new user
response.status_code = 201
response.headers['Location'] = f'/api/users/{user.id}'
return {'message': 'User created!', 'user': user}
In this example, we updated our create_user()
function to return a custom 201 Created
response. We set the status code to 201
and added a Location
header to indicate the URL of the created resource.
Conclusion
In this blog post, we learned how to build RESTful APIs with Python and two popular web frameworks: Flask and FastAPI. We learned how to define routes that map to different HTTP methods, how to work with JSON data, and how to use data models to define the structure of our data. We also learned how to return custom HTTP responses using Flask and FastAPI.
RESTful APIs are a powerful tool for building web applications and services. They allow us to create resources that can be accessed and manipulated using standard HTTP methods, making it easy to build applications that can be consumed by a wide range of clients. By using Python and Flask/FastAPI, we can build robust and scalable RESTful APIs that can be used in a variety of contexts.
You may also like
Building RESTful APIs with Python Flask
This comprehensive guide explores the process of building RESTful AP...
Continue readingDjango RESTful APIs: High-Level Framework for API Development
Django RESTful APIs are a high-level framework for API development u...
Continue readingFastAPI for APIs: Modern & Fast API Development with Python
FastAPI is a modern and fast Python web framework designed for build...
Continue reading