Technologies used: Flask, PostgreSQL, Python, SQLAlchemy.
Source code: https://github.com/jmoujaes/skedjit
Give people an easy way to create events and share them with friends.
This section will go over the tools that were used, the tasks that had to be completed, and some interesting features that were implemented.
Skedjit was a weekend project between me and a friend. We split the work into backend and frontend. I took the backend. I wanted something that could get us started quickly on the backend, so these were the tools I chose.
First my friend and I thought up the minimum requirements for the project. At a bare minimum, we wanted anonymous users to be able to:
Based on those requirements, it became clear that I needed an Event class. This Event class would map to an Event table in the database. And I would need a place in the webapp to create these events, view them, update them, and delete them.
The Event itself needed a date, time, and description that the user would provide. It also needed a random unique id that could be used as a shareable link (interesting feature #1). And it needed a secret code so the owner could edit and delete the event after creating it (interesting feature #2).
So, with the help of SQLAlchemy, I created an Event class in my Flask app as well as an Event table in the database. See the models.py file. Next, I wanted to expose these events to the internet so that users could create and share them! So, using Flask, I created some views.
First was the create view. The create view was set up to handle requests made to the “https://skedjit-url/create" endpoint. This was easy to specify in Flask, using just a Python decorator. See app.py line 137.
When creating an event, I wanted to give it a random and unique id that could be used as a shareable link. This was the first interesting feature. I wanted to keep this logic simple so that I could finish it fairly quickly and revisit it if necessary. So I used the python uuid module to come up with a random link that was six characters long. Then I made sure the database enforced this link to be unique. If it was not unique, the database would complain, and I would generate another random link. This allowed me to implement the feature in a quick and simple way. I could revisit this logic in the future if necessary. For example if I started seeing a lot of link collissions, a possible solution would be to increase the length of the link from six characters to something longer. Additionally, I could allow more characters to be part of the link, such as uppercase letters. But for now the current design is enough. You can see the link generation code here.
The second interesting feature to implement was to give events a password. This would allow users to edit and delete events after having created them. To do this, I asked the user for a password at event creation time. This password had to be hashed, salted, and stored in the database. Then when the user wanted to edit or delete an event, they would provide the password. If the password matched our record in the database, the user could edit or delete the event. Otherwise, they were given an error. To hash and salt the password, I used bcrypt a third-party python module. Here is how I used it.
Now let’s go back to the views. Aside from the create view, I created views for looking at, updating, and deleting events. Those were set up to handle requests at the “https://skedjit-url/events/unique-event-link" endpoint. Viewing events was fairly straightforward. Updating and deleting events was a bit more involved, since the user needed to provide the secret key mentioned above, and we needed to verify it. You can see the code for these views here.
Finally I will mention writing automated tests and creating an automated build for for the webapp. Although I mention these last, they were part of the coding process from the very beginning.
First, the tests. As you can imagine, all the work I mentioned before was done in parts. And as I built out each part, I wrote automated tests around it. After writing the first few tests, my testing infrastructure became more fleshed out. This allowed me to start writing tests for new code before writing the new code.You might have to read that one again. It sounds funny but it is effective. Writing tests for functions that don’t even exist yet helps design those functions better. The reason is that it becomes clear how other code (e.g. test code) will call the functions, and so they become more usable. Flask provides a test_client class that helps with testing the Flask application. It allowed me to make requests to the web application the same way a browser would. See tests.py for some test code.
Now, the automated build. The automated build would allow new developers to quickly get set up on the project. It also made sure the application functioned correctly with every code change that was introduced. When errors occurred in the build, the build would fail. That way errors did not get pushed to the project. Furthermore, the developers were alerted of the potential errors. Skedjit’s automated build ran as a shell script, and I made sure it exited on errors by setting the -e flag at the beginning of the script. So for the automated build to pass in our case, the project’s dependencies must have all been installed correctly and the project’s tests must’ve all passed. Once that happened, it was safe to merge in new code, and deploy it to users.
After some days of coding and learning, I created the backend for Skedjit. At the time of writing, Skedjit had over 90% test code coverage.
coverage report
Name Stmts Miss Cover
---------------------------------
app.py 165 13 92%
database.py 11 0 100%
models.py 30 1 97%
---------------------------------
TOTAL 206 14 93%
Skedjit was designed to be an easy and simple way of sharing events with friends. The web application was built with Flask, PostgreSQL, Python, and SQLAlchemy.
Next steps for the application could include adding:
Thank you for reading along! I hope you enjoyed. Feel free to email me feedback and see more projects.