I am Arnab Sen, a Computer Science undergraduate student of IIEST, Shibpur.
The project was under the mentorship of Anubhav Singh
Since there was no repo for the backend, I worked on a separate repo from scratch
Repo link: https://github.com/dsc-x/omg-frames-api
- Commits: 29
- Pull Requests: 4
2799++ 413--
Commit: b82a098
Implemented the APIs for user registration and user login. The database used for storing the data of the user is Firebase Realtime Database. The reasons for choosing Firebase was:
- It was was to setup.
- Almost zero-configuration required, only the API keys needed to be changed.
At first, I thought of implementing Google Oauth, but later my mentor Anubhav asked me to set up our own user authentication and use JWT tokens(using the jwt
library of python). So all the user data is stored in the database (password is hashed using pbkdf2_sha256
before it is stored).
Registering the user:
Logging in as the user:
Commits: 0d4de73, 135fb64, e8253df
Every user has a frames array, when the user uploads the frame, it gets saved in the array. So, the APIs implemented are:
- Saving new frames
POST
- All the user frames
GET
- Updating an existing frame
PUT
- Deleting a frame
DELETE
Also, every route related to the frame is protected with a JWT token. The token is encoded in a way that it has the user_id
of the user as a payload and is signed with a secret key. So when the token is sent in the Authorization header along with the request, it is first verified with the secret key and then the payload is extracted and all the necessary DB operation is done after that.
PR: #15
For the forget password we needed to setup an Email Service. This was a rough sketch that I made to implement the idea:
Briefly, there will be a URL sent to the user which will have a token. This token was generated using the itsdangerous.serializer
which had an expiry of 24 hours. On clicking that URL the user will be redirected to a new reset password form, which will send a request to another endpoint to update the password. So for this I had to implement two APIs:
- POST /send-reset-mail
- POST /update-password
Also, when the user registers there is a mail sent to the user with a successful registration message. It is implemented in commit e632b57.
The templates of the email are responsive.
Welcome Mail format
Reset Mail format
Commits: 79ecbdc, 1fd7bbe, 7f9fd98
For the ease of testing for the frontend developers and for future contributors, API documentation is very helpful. Anubhav sir suggested me to use Swagger. Swagger is very easy to use, has a simple dashboard, shows the object models, and is widely popular. For every API that is implemented in the server, I have added the routes to swagger so that routes can be tested from the dashboard itself. All the related document files are stored in .yml
format in the docs
.
The apidocs is deployed at: https://api.iwasat.events/apidocs/
For the deploying the backend on the server:
- Created deploy keys for the repo.
- Created a new gunicorn service
/etc/systemd/system/omg-frames-api.service
. - Configured NGINX reverse proxy to map the address
api.iwasat.events
to the service running at a particular port i.e. the flask application. - Secured the application with SSL encryption using Let's Encrypt.
Also implemented a CI/CD pipeline to automate the build and deploy process. Commit: 95224b97. So any changes pushed to master will trigger an action https://github.com/dsc-x/omg-frames-api/actions which will:
- Pull all the latest changes in the server
- Install any necessary package from requirements.txt
- Reload the daemon and restart the gunicorn service.
For every commit I made sure
- The Python files followed the Python Flake8 linting conventions.
- Neccesarry comments and Google styled docstrings for code redability. Commit: 74ce484
I further added a Dockerfile and a Makefile for the ease of deployment and development. Commit: 6e0f81a
I think there is a further scope to improve the performance of the APIs.
-
If a particular User has more than one frame, sending one single GET request with all the images becomes very time-consuming. So Anubhav sir suggested that we could have rather used two different endpoints one with a query and the other without. So a GET request to
/frames
will respond with all the ids of the frame ( not the data ), but the GET request to/frame?id=
will respond with the frame_data of frame whose id is provided in query. This will improve the performance considerably, also the user doesn't have to wait for all the images to load.Issue: #17
-
When a user registers we are not checking the fact if the email they provided was actually theirs, so for that we can implement a mail verification service. There can be different approaches, one would be to send a secret link, and visiting that link will confirm it's their email. Other, would be to use a secret code which they have to enter to verify. Both the methods has its pros and cons.
Issue: #16
-
Using some compression before storing the images in the database. Since we are using base64 encoding for the image, the length increases by approximately 30-35% but using some kind of compression, like
gzip
can reduce the inflation to2-10%
. This can be a minor improvement in fetching the data from the Firebase database. I have also written a script that can demostrate the compression percentage.Issue: #18
I am really thankful to the Winter of Code for giving me this amazing opportunity to work on a nice project under DSC-X. Also, glad to be mentored by Anubhav Singh. I learned a lot throughout the entire process, not just about the project but also about the practices of Open Source. I believe this experience of WoC will definitely help me in my GSoC. I also express my gratitude to Awantika Nigam and Rajinderpal Singh for being so collaborative.