In the previous post Create an API using Flask in Python, we discussed how to create an API using Flask and saw some HTTP methods like GET, POST in action. In this post, we will create a RESTful API service for To-Do list application. So first let us outline the endpoints we are going to create in this service to support the app for To-Do list application. We are going to use Flask - SQLAlchemy (Extension for Flask that adds support for SQLAlchemy in applications) for database interactions.
/signup - This endpoint is for new users to sign up for a to-do list application. We can make User model according to our needs i.e what kind of information we need from user during sign up. For tutorial purpose we will keep it to a bare minimum. We would ask for username, password and email.
/add_task - This endpoint is used for users to add new tasks to their to-do list.
/remove_task - This endpoint is used for users to deleted tasks which they added previously to their to-do list.
/mark_task_as_done - This endpoint is used for users to mark status of their task on their to-do list as complete.
/show_tasks - This endpoint returns a json of all the tasks of user who made the request to this endpoint.
To secure the APIs, we will use flask-HTTPAuth module. It is a simple module that provides the basic and digest HTTP authentication for any flask routes. We just need to add a decorator (@auth.login_required) before function definition. Install flask-HTTPAuth package via pip by the following command-
Before going into the details of how to use flask-httpauth module to authenticate requests, we would have a look at User and Task database model that we will use in this post.
User model - We require username, password and email from any user who wants to sign up for our to-do list service. In the code snippet below, you can see that the columns named id, username, password and email are created. id is declared as the primary key of the User table. If we want non-repeated entries in some column we have to give attribute unique=True. For not-null values in a column nullable=False attribute is used.
Task model - As we can clearly see, there is one-to-many relationship between user and tasks i.e one user can have many tasks in his/her to-do list. Following attributes are required for a basic Task model -
content - this is the text part of a particular task in the to-do list.
id - this is a unique identifier/primary key of the task table.
add_date - this is the date when the task was added on the to-do list.
end_date - this is the date when the task was completed successfully.
done - this is a boolean that is False if task is incomplete and True if task is completed.
In the code snippet below, we have implemented authentication logic that flask-HTTPAuth module uses for authentication. get_pw() is called by authentication module to match with the password that user has entered while making request. So we query for user by providing username as a filter and return the password if a user is found with queried username else we return None.
See documentation of flask-HTTPAuth for more details.
Sign Up (/signup)
During signup, we create a User object with username, password and email. And after user object is successfully created, we add it to database and update database. Json is returned as a response which tells client (webapp / mobile app) that user is created successfully. We can have complex signup functionalities like adding a check if username/email already exists and take actions accordingly.
For different ways of querying the database, have a look here.
Add Task (/add_task)
Task object is created by the content which is provided by user who is making the request. Observe we have used @auth.login_required decorator, this implies that we can access this api endpoint only if we are authorised, so we need to provide username and password while making request to this api endpoint. Json object containing task-id have been returned to the client, so that the client can refer to this task for updation or deletion.
Remove Task (/remove_task)
To remove any task, client needs to make a POST request with the task-id. Once the task with provided task-id is found, it is deleted from the database and the database is updated after deletion. Deleted task details have been returned as a json object to the client.
Mark Task as Done (/mark_task_as_done)
To update the status of whether the task is complete or incomplete, client needs to make a POST request with the task-id. Once task with provided task-id has been found in the database, it's status is updated and end time of task is also assigned. The database is then updated with the new task details.
Show Tasks (/show_tasks)
Using this api endpoint user can see their complete to-do list.
I added tasks with the same content to increase the task list. But you can see they are different tasks by looking at their task-id.
So we made 5 api endpoints in this demo application. You can extend the number of APIs and support many other operations like adding image urls to your task or adding links to your task which involve reading blog posts, etc. The complete code for above to-do application can be found here. Generally, the people who make the APIs in the backend, also document what all information we need to provide while making the request to server and what kind of responses to expect. Going through the documentation, we can implement any client-side application be it a web app or a mobile app.