How to Sanic : Python Asynchronous Web Framework
Introducing Sanic: The Async Python Web Framework
Let’s Build a CRUD App with Sanic
1. What is Sanic?
Sanic is a Python 3.7+ web server and web framework that’s written to go fast. It allows the usage of the async/await syntax added in Python 3.5, which makes your code non-blocking and speedy.
Goal: To provide a simple way to get up and running a high-performance HTTP server that is easy to build, expand, and ultimately to scale.
Features
- Built-in fast webserver
- Production-ready
- Highly scalable
- ASGI compliant
- Simple and intuitive API design
- By the community, for the community
2. How to Sanic
In this tutorial, we will create Restful API using Sanic. Data formats of the REST API include application/JSON.
Prerequisites:
- Python 3.7+
- Postman/Insomnia
- Your preferred Code editor, I will be using VS Code and Pycharm Community Edition
3. Project Setup
Before getting our hands dirty, we need to configure our project.
The following steps are followed for project configuration.
Create new project
Create a project directory named learnsanic and enter the folder.
Configure Virtual environment
To isolate each development environment we will be using a virtual environment.
Before creating the virtual environment we need to ensure we have virtualenv installed. For that execute the following:
virtualenv --version
If we get an error, execute the following:
pip install virtualenv
Now again execute:
virtualenv --version
And you can see the version of your virtual environment.
Now, create a virtual environment named venv
by executing the following command:
virtualenv venv
After creating a virtual environment, the new directory can be visualized by executing the following command in the terminal:
ls
After creating a virtual environment, activate the virtual environment by running the following command:
source venv/bin/activate
Now you can see that in the terminal your virtual environment is activated:
Install Required Packages
After activating our virtual environment, install packages that are required for the project.
To install the sanic package in our virtual environment using the pip package manager, execute the following command:
pip install sanic
Create app.py file
Execute the following:
touch app.py
And open the file in your preferred editor. If you are using VSCode executing the below command will do the work:
code app.py
Configure Environment
First, create an instance of our Sanic application.
For that import Sanic and create an instance as follows:
4. Develop RESTful API
Before developing API let us know what we are building.
Our School is planning to make a RESTful API using Sanic so that they can add, get, update the details of their students. Initially, we will be focusing on an in-memory database i.e considering a variable as a database and later we will move to an actual SQL database.
Our School wants to have details of students and the fields contain a name, grade, roll, email, phone, subjects, friends initially.
Let’s create our in-memory DB and provide the data in dictionary format and save it in in_memory_student_db
variable like in the figure.
To get the data that is just created i.e in_memory_student_db
.
Create a get method.
@app.get("/")
async def get_student(request):
return in_memory_student_db
If you are wondering what is @app.get(“/”)
, then they are called decorators.
For getting the response we will just create a get_student function like above and run the sanic app:
sanic app.app
This will run your server and when you hit the route in insomnia you will get the error as mentioned below:
Sanic.exceptions.ServerError: Invalid response type (need HTTPResponse)
This mentions that we cannot return our list of dictionaries the return type must be HTTPResponse. For that we will import a response from sanic:
from sanic import response
---
---
async def get_student(request):
return response.json(in_memory_student_db)
---
---
@app.post("/")
async def post_student(request):
student = request.json
in_memory_student_db.append(student)
return response.json(student)
Similarly, we write a program for update and delete:
@app.put("/<id_:int>")
async def update_student(request,id_):
student = request.json
in_memory_student_db[id_] = student
return response.json(student)
@app.delete("/<id_:int>")
async def delete_student(request,id_):
del in_memory_student_db[id_]
return response.json({"message":"Deleted student successfully"})
This completes the simplest version of our CRUD operation in Sanic. But is it enough?
- What if we want to get data if the database is empty?
- what if we want to update a student that is not in the database?
- What if we want to delete a student that is not in the database?
- What if we want to get data by id, not whole data?
Now, remodeling the functions as follows:
To get data by id or whole data, Change get function as follows:
@app.get("/")
async def get_student(request):
id_ = request.args.get("id")
if id_:
if int(id_) in range(len(in_memory_student_db)):
return response.json(in_memory_student_db[int(id_)])
else:
return response.json(
{
"status": "error",
"message": f"data with id {id_} not found. Try with different id!!!"
}
)
return response.json(in_memory_student_db)
To update student that is not in the database, provide a message that there is no data with given id or specification. Change update function as follows:
@app.put("/<id_:int>")
async def update_student(request,id_):
student = request.json
if id_ in range(len(in_memory_student_db)):
in_memory_student_db[id_] = student
else:
return response.json({"error":"No Student with given id"})
return response.json(student)
To delete a student that is not in the database, provide the message that there is no data with the given id or specification. Change delete function as follows:
@app.delete("/<id_:int>")
async def delete_student(request,id_):
if id_ in range(len(in_memory_student_db)):
del in_memory_student_db[id_]
else:
return response.json({"error": "No Student with given id"})
return response.json({"message": "Deleted student successfully"})
This completes CRUD operations.
Join the conversation