The Software Engineering & Agile module of my degree apprenticeship is coming to a close. With that in mind I think I can now share the coding I’ve done for the assignment especially as I needed to store it in a public repository (it’s on my GitHub at https://github.com/geektechdude/qa-se-webapp ) as part of the submissions and I can reflect a little on the project.
My web application is an asset tracker – it simply tracks who has which asset. It’s expected to be used by a team tracking assets assigned to end customers.
The assignment had some requirements / restrictions that had to be adhered to, these are listed in the repositories README.md but for blog post purposes they included:
It had to be a web application. Web has been (and is) the forefront of a lot of technology, so focusing on a web based application made sense.
It had to be written in Python. I personally liked this, as I’m a big fan of Python. It’s a language that scores highly on many of the “top languages to learn / know” lists and can be used for so many different things (e.g. web, machine learning, data analytics).
It must feature a relational database (e.g. SQL) backend. I tackled SQL vs NoSQL at the beginning of Summer 2022, and although a NoSQL database has its place I think it would have been hard to implement for small project, especially when…
The database must contain a minimum of 2 tables and a maximum of 4 tables. I think this was to make students (i.e. me) consider database design. Which was a good call, as once I settled on an app idea I then went through the steps of database design (tables, primary keys, relationships). I settled on two tables for the initial release – one for users (e.g. those that update the asset details) and one for assets (e.g. the technology being assigned), with a relationship between the two to track who assigned the asset. For future releases I could expand this with maybe a table of customers, or a table of asset types (storing specifications) but as I’m following an Agile mindset I wanted to progress with a minimal viable product (MVP) before adding more features.
Python Web Framework
The Python framework that could be used was left as an open choice. I considered Django and Flask, as I’ve used them before, and FastAPI, which is new to me. I will point out that everyone has a favourite framework, and each framework has positives / negatives to consider.
I then ruled out FastAPI as learning a new framework whilst carrying out the assignment, learning the module materials and holding down a full time job would probably destroy my personal time.
Django was next to be ruled out. I’ve built in Django before and like it, but I wanted to keep this project light and was a little concerned about the default database tables that Django installs (would they count towards the 2-4 requirement? ). Although on reflection having the framework create the administrator / user roles and tables would have made the assignment a little easier, and security is more present by default with Django.
I settled on Flask. It would mean a little more effort in getting the user roles correct (I needed to implement an Admin and a regular User role) but would give me more control over the database and the Python libraries used for the project.
Web Application = HTML and CSS
I think regular readers may know that HTML (Hyper Text Markup Language) and CSS (Cascading Style Sheets) and me have a varied history. At one point I would just launch a basic Flask server to serve some information, but this changed a little early 2021 when I decided to put some HTML/CSS skills to use and build a testing site template. Thankfully Flask allowed me to template a design and have it serve the required Python via Jinja (e.g. to show / hide data depending on the user).
SQLAlchemy – SQL Made Easier
My original run at the project included trying to write the various bits of SQL needed to interact with the backend SQL database, including a database schema file and the database commands written, such as “INSERT INTO user (username, password) VALUES (?,?)”, into the Python functions. I’ve left some of the early branches in the repository that show this earlier work.
SQLAlchemy made interacting with a SQL database easier for me as it managed the database session and reduced full on SQL commands down to something along the lines of db.session.add(user). SQLAlchemy also supports lots of SQL database types, so although my project utilises a SQLite database it could be altered to use a MySQL database or an Oracle database with only a little change.
Whilst playing around with how to display data (in this case) I wanted to find a simple way to show the assets, maybe in a list or a table. I originally thought, hey I bet there is a Python library for that, and after a quick search found Flask-Table. It didn’t need much set up, just a new view called tables.py detailing what tables should exist and what should be in them. I left this to show the results of an asset search but was not 100% sold on it. A list (ordered or unordered) also didn’t look right.
With this is mind I took it right back to basics, using a HTML table (with tr, th and td tags!) and some Jinja logic. I personally thought this looked better so left that to show all assets.
Admin vs Regular User
I created a field in the user database table that monitored if a user was also an admin. If true then they were given admin powers, if false (the default) then they had regular user abilities. The main difference is that admin users have the full CRUD (Create, Read, Update, Delete) range when editing an asset, where as the regular users only have CRU (Create, Read, Update).
Model, View, Controller (MVC)
Flask doesn’t exactly follow the Model, View, Controller (MVC) pattern that ASP.NET prefers or the Model, View, Template (MVT) pattern that Django prefers. In fact Flask leaves a lot of the design pattern up to the coder. I tried to use my learnings around ASP.NET and Django so that my Flask project layout (hopefully) made some sense.
User Stories to Tests
I’ve already blogged about adding tests and using GitHub Actions to automatically run them. However, I should have also added that User Stories should be turned into tests. Taking the “As a user I want to be able to add an asset” or “As an admin I want to be able to delete an asset” stories and turning those into tests means that User Stories can easily be shown to have been completed. This is great for resolving the “definition of done” discussions that can sometimes occur at the end of a project.
Whilst writing about User Stories I should also give a mention to GitHub Projects. Having a place within the code repository to list the To-Dos, In Actions and Completed tasks helped keep me on track.
The Minimal Viable Product (MVP) has been built and is live, so what next? The product has lots of potential features that could be added. Tables for customers and models would help limit errors that can occur with free text entry fields. Currently the logon requires a user to register, however a lot of modern (2022) web apps use sign in methods such as Google, Facebook and Azure, so the implementation of OAuth could be carried out.