/CS550P

CS50P Harvard - Introduction to Programming with Python - Final project

Primary LanguagePython

✈ Travelfy

Designed and implemented by Fabio FERNANDES ALVES

Amiens, France - August 2023

πŸ—£ Description

πŸ“– User story


We all know the most stressful part of a trip is its preparation: searching for tickets with the best cost benefit, packing the luggage and making sure it’s not oversized or overweight, planning the commute to the airport, going through customs and getting to the boarding gate on time.. πŸ₯΅ Ouf, we haven’t even got to our destination yet and we feel like we need a break from our own vacations!

Travelfy was designed to make the traveler experience more enjoyable and pleasing from the moment one’s chosen one’s destination πŸ˜ŒπŸƒ

On the click of a button, Travelfy returns you a custom playlist of the Top 20 most played songs in your country’s destination! That way, you can start enjoying your vacations long before the plane lands on your destination, while you pack your bags, commute to the airport, or walk through the duty-free πŸ˜‰ Close your eyes, listen to the music and have a full-on musically immersive experience.. 🎧🎢

πŸ“±App features


πŸ‘€ UI/UX features

The application frontend is composed of the following features:

  • A form, composed of an input box, where the user types in his country's destination; and a submit button, which, as the name suggests, submits the form via a POST request to the backend (Python/Flask) that will handle the appropriate logic

    Travelfy home page in its initial state

    Figure 1: Travelfy home page in its initial state.

  • An alert message, which appears right under the input box, on the event of the user typing an invalid country name

    Alert message after invalid form submission

    Figure 2: Alert message after invalid form submission.

    After valid form submission:

  • A custom list of the top 20 most played songs (track name and artist) in the country after form submition by user

  • A clickable play icon right next to each song through which the user can hear a 30s preview of that song

  • A custom playlist cover image

  • A media player that allows the user to play/stop the current track and adjust the volume

    Travelfy home page after valid form submission

    Figure 3: Travelfy home page after valid form submission.

🧰 Tech stack

β–ͺ️ HMTL

The HTML template was structured using HTML5 boilerplate:

  • HMTL:
    • Head: meta tags for responsiveness, as well as link tags linking the html file to CSS and Bootstrap
    • Body:
      • Header: contains the app name and solgan
      • Main cointainer: styled using Flexbox model, it contains a top section, where the form is; and a bottom section, with a bottom-left section, for the tracks list and a bottom-right section, where the playlist cover image and the media player are
      • Footer: author credits
      • Script tags: links the HTML to JavaScript and Bootstrap
β–ͺ️ CSS

  • Layout: HTML elements were designed on the page using Flexbox model
  • Responsive design: the application was responsively designed according to web-first approach: as the screen size decreases and reach 640px - corresponding to a transition from desktop to a mobile display - a media query changes the app layout: the playlist cover and the media player, originally beside the tracks list, go right underneath it, so those elements do not overlap each other as the screen size decreases
  • Animation: the app name, Travelfy, on the very top of the page, is styled with a "slide-in" animation upon page load using @keyframe rule and CSS animation property
β–ͺ️ JavaScript

JavaScript role was basically to integrate 2 functionalities into the application on the form of Event Listeners:

  • Click events on each of the play icons that basically gets the url encoded as a data-* attribute in each of those icons (which is in fact a link to a 30s preview url in MP3 format), sets the src attribute of the audio tag with that url and plays it.
  • Submit event that compares the country provided as input by the user and an array of countries encoded as a data-* attribute in the p tag named as "alert-message". If the user provides an invalid input (such as "cat", or "123"), JavaScript unhides the alert message, as well as prevents the form from being submitted
β–ͺ️ Python

Python was chosen as backend language to handle all the logic necessary to process information coming from the frontend, as well as for communicating with Spotify server through its different API endpoints. More specifically, the access token request followed Spotify's Client Credentials Flow:

Spotify Client Credentials Flow

Figure 4: Spotify Client Credentials Flow (source: https://developer.spotify.com/documentation/web-api/tutorials/client-credentials-flow)

Authentification and interaction with Spotify API's were implemented in Python in two main steps, as described below:

  1. Requesting an access token:
    • 1.1. Setting a variable environment to safely store Client ID and Client Secret
    • 1.2. Encoding the Client ID and the Client Secret with base64
    • 1.3. Requesting the access token by sending a POST request to the token endpoint URI, with data and headers parameters according to Spotify format
    • 1.4. Retrieving the access token in JSON format
  2. Retrieving Spotify resources (playlist, tracks, etc.) through their corresponding API endpoints:
    • 2.1. Looking for a playlist ID I created a Python function called "search_for_playlist(token, country)" that takes two parameters: the requested token in step 1 and the country submitted by the user via form. It builds a query url using the given country, sends a GET request to the "Search for Item" endpoint and returns a dictionary whose keys correspond to the playlist name, ID and cover image.
    • 2.2. Retrieving the playlist tracks names, artists and preview url
  • Object-Oriented Programming As a playlist can be treated as a real world entity, I decided to create a Playlist class to encapsulate all the playlist-related information in the shape of instance attributes such as:
  • Acces token
  • Country
  • Playlist ID
  • Playlist cover image
  • Tracks preview url

Getter methods were included to provide controlled access to the instance attributes, so the values of those attributes are not exposed directly to the outside world.

  • Unitary tests In the filed called test_project.py, unitary tests were written to assure that all the functions implemented in project.py are behaving as expected (in terms of their parameters and return values), as well as catching exceptions - such as Value and HTTP errors - and handling them accordingly.
β–ͺ️ Flask

Flask was chosen as Python framework to develop Tavelfy web app, because it provides a simple, yet flexible way to handle tasks like routing, request handling an template rendering. In the home route "/", two methods were added to support the different requests coming from the frontend:

  • GET GET request from the home route is basically responsible for rendering the app home page in its initial state.

  • POST POST request is responsible for form submission, backend logic (API requests, object instantiation, etc.) and API response processing before returning it to the frontend.

🌳 Project tree structure


The project folder structure was implemented in such a way that it could be processed with Flask framework:

project β”œβ”€β”€ static β”‚ β”œβ”€β”€ images β”‚ β”‚ β”œβ”€β”€ img1 β”‚ β”‚ β”œβ”€β”€ img2 β”‚ β”‚ └── ... β”‚ β”œβ”€β”€ script.js β”‚ └── style.css β”œβ”€β”€ templates β”‚ └── index.html β”œβ”€β”€ project.py β”œβ”€β”€ README.md β”œβ”€β”€ requirements.txt └── test_project.py

πŸ€”πŸ’­ Ideas to expand the project

  • Add link on the bottom of the page after user gets the playlist recommendation so he/she can log in his/her own Spotify account and add the recommended playlist in his/her library.
  • Create another extension with the help of Bands in Town’s API to give a recommendation to the traveler of the upcoming events/concerts on his/her destination during his/her travel dates