Deadline:
Changelog:
The World Wide Web has revolutionized many areas and activities previously requiring physical interaction. The retail industry started a paradigm shift in 1994 with its first online sale, marking the beginning of what would become a global e-commerce strategy. Today, platforms like Amazon, Etsy, and Shopify enable millions of transactions daily, blending convenience with personalized user experiences.
In this assignment, you will build a simple web application using HTML, CSS (Bootstrap) and Python (Flask). The goal is to create a basic e-commerce-style website where users can browse a list of products, add selected items to a shopping cart and proceed to a checkout form to finally place an order.
You'll get hands-on experience with routing, templating, forms, and (optionally) storing data using files or a simple database (there are multiple bonus opportunities!).
In the following subsections, we define the minimal (required) aspects to be followed (especially to make the grading process easy to automate), plus some recommendations for the easiest approaches.
Overall requirements:
Readme.(md|txt)
, a requirements.txt
containing Python dependencies, a Docker container image with all dependencies to quickly start up the web application (important for making the evaluation process error-proof – a container will work everywhere else!) + other misc. files (see the archive structure in the last section);We recommend starting this assignment with a HTML template for your design (plus various pages, e.g., specific forms), then porting it to Jinja2 templates and writing Flask route functions with the desired functionality last.
Now carefully read below for a description & recommendations for each of these requirements!
The design (aspect) of the web pages does not really matter as long as it meets the functionality requirements described in this document (just don't make it too ugly).
As a minimum, you must display photo thumbnails for each product listed on the front page.
Although you can use whatever CSS framework you'd like, we recommend Bootstrap. If you wish, you could base it on the lab's template, though you should further personalize it.
All requested pages must have a common menu bar directly linking to eachother. The currently active item must be differentiated (e.g., different background or text colors). A human should able to easily figure out which link to press for accessing the required functionality (add to cart, view shopping cart & order items).
Bootstrap design element recommendations:
The use of JavaScript-based templating/rendering (e.g., React, EJS and 1000 others like them) is forbidden (not studied here). Stick to HTML + CSS for now ;) you can, of course, optionally use some JavaScript to make some UX prettier as bonus (e.g., cart add animation).
Here's some screenshots for example & inspiration:
The URL (route) for this page must be /
, though it is allowed to redirect to another route (e.g., /products/promo
) if you wish to implement categories (for bonus). If you wish to make individual dynamic pages for each product, no further routing restrictions will apply there (as it is a bonus feature).
The product listing must be dynamically rendered from Python data (e.g., using a Jinja2 for
loop). The products may either be hardcoded in a separate Python module, loaded from a configuration file (ofc, a more elegant approach) or database (for bonus points).
Each of the products must have a “Add to cart” button/icon beside it to add the item to cart (see the next section for specifics).
Bonus ideas: filtering / ordering the products, multiple categories, database storage (SQL/NoSQL).
As the shopping cart represents the main functionality of such websites, this is also where the assignment's main complexity comes from. At minimum, you should display the product name, order count and price in tabular-like fashion, have a total price computed plus a button to proceed with the order (which must open the Checkout form described in the next sub-section).
You must route /cart
for displaying the current shopping cart.
As mentioned before, a product may be added from the front page (and, optionally, from each product's page, if implemented as bonus). For this, you must use a REST-ful route named /cart/add-item
with a id
GET parameter, e.g., /cart/add-item/?id=123
. This is important as we will use automation for quickly testing the website's functionality (a simple script will be supplied later for testing this convention).
A product may be added multiple times, each time incrementing its count. You may (optionally) have modification buttons / text field for editing .
You MUST have a deletion link/button for each product inside the shopping cart. Use /cart/remove-item?id=PRODUCT_ID
, which will also be used as REST-ful API for automation.
As a final step before ordering, you will implement a page with a form where the user will see the products to be ordered and the totals and fill with the user's contact info. Please don't forget the submit button!
The checkout form MUST be reachable using GET (i.e., the usual browser navigation) at the /checkout
URL.
The checkout form must submit the data using the POST method at the same /checkout
URL, with the following field names (obligatory! use them for naming the inputs):
full_name
: user's full name;email
: the email of the user;phone
: the phone number;address
: the full address (for simplicity), you may use a <textarea>
for it;payment_method
: multiple choices between card
, bank_transfer
and cash
(don't worry, you won't have to implement any of them, just make the server store them as such).You may add more fields if desired, but please make them optional (since the automation script will NOT submit them).
Note: data validation is optional, but nice to have nevertheless ;)
On checkout form submission, at minimum, you should print all of the data in any human readable format (i.e., NOT binary!) on the Flask console, which should also help you with debugging.
For a more realistic implementation and obtaining full points for this task, we require you to also save the order on the server, either by creating small text-based files in a directory (e.g., ./submitted-data/<date>.txt
), use a structured format (e.g. json / yaml
) or, for an extensive bonus, insert them into a database.
First of all, you must use a virtual environment for development and declare all of your Python dependencies in a requirements.txt
file. You can easily obtain this by using pip freeze > requirements.txt
command inside your virtual environment (obligatory, otherwise it will output ALL of your system installed packages!) or by manually inserting the name of each installed package.
Obligatory / common sense: use Flask's standard port of 5000
when serving from any of your scripts. PLEASE DO NOT CHANGE IT, otherwise we will have to manually edit the http://localhost:<port>
URL for each non-conforming solution and will be greatly penalized!
In order for your web application to be easily shared (with us :P), you should add a proper Dockerfile that can be used to readily build + run it.
You may start from any base image, although we recommend ''python:<version>-alpine'' due to its low disk footprint.
Thus, a containerized solution must work using the following steps:
docker build -t iap1-tema ./
command should run successfully;docker run -p 5000:5000 -it iap1-tema
should start the Flask server and make it accessible on http://localhost:5000
.
server.py
and make it runnable using python3 server.py
(a proper virtual environment with the declared requirements.txt
will be automatically setup by our scripts beforehand).
The base assignment constitutes 4p out of your final grade (100p homework = 4p final grade). The 100p are split between the following tasks:
You must also write a Readme (.txt / .md) containing a description of your implementation, design choices, third party libraries (and the whys), challenges you encountered, bonuses you thought of etc.
The project's source code (i.e., no binary / generated files need to be included) must be archived (.zip
, please) and make sure the scripts (incl. Dockerfile) are placed directly in the root folder (i.e. depth=0) of the archive! Otherwise, the grading process will be encumbered ⇒ penalizations++ :(
Dockerfile
) inside its root directory!
Also, please double-check if you followed all naming conventions!
TODO: some automation scripts / conventions checker will be posted here in a couple of days! Please stand by :D
Q: Can I write the tool in something other than Python?
A: No, please use Python. You can have some (but not exceedingly) JavaScript for enhancing your frontend, but the sever-side and all dynamic functionality must be done on the server-side, in Python.
Q: What platform will this assignment be tested on?
A: Linux (though, you don't need to use any platform-specific APIs + containers/Docker is the pinnacle of portability!).