Stuff to hit

CODE:

  1. AWS deployment struggles and reworking
  2. Few application organization(Matching tabs and such) + Merge conflicts
  3. API experiments and finalization of Movie Database

BLOG:

  1. Show how student lessons are organized and how refer to materials to studying (highlight pseudocode)
  2. Plans for collegeboard quiz notes
  3. Reflection

CODE ISSUES

  1. AWS DEPLOYMENT

When firsting booting up this project, my first task was to get the Flask backend working on localhost on dockerps, then deployed fully on AWS. This took quite a while, because I couldn’t configure the ports to match the new registered port on ec2 instance.

https://github.com/jntpham/jphamblog/blob/main/images/Screenshot%202023-11-02%20162605.png

Eventually, I registered with the right port on Route 53 and AWS and moved on verifying the website with NGINX.

I cannot find the NGINX file that I had problems with, but I spent all of time combing through the AWS deployment instructions to solve the issues with the NGINX config file. This took about half the week to resolve and backend works now locally and on AWS (at the time of writing).

  1. MERGE CONFLICTS

After finishing deployment, I worked on the frontend matter, such as tidying up the pages and organizing the APIs to the proper categories.

https://github.com/jntpham/jphamblog/blob/main/images/Screenshot%202023-11-02%20214634.png

However, when working on the Python Lessons, I ran into save and merge issues, as there was a lot of people commiting and pushing at the same time. It turns out that my save was also not functional, which hampered my progress with the assignment.

https://github.com/jntpham/jphamblog/blob/main/images/Screenshot%202023-11-02%20214634.png https://github.com/jntpham/jphamblog/blob/main/images/Screenshot%202023-11-02%20221358.png

Fortunately, the merge issues got cleared up once I got the hang of it, the python libraries assignment as completed to schedule.

  1. API EXPERIMENTS

I worked on experimenting with different API calling applications similar to the javascript API requests we have. This API was the first attempt to replicate that process, first using Deezer.

from flask import Flask, jsonify
import requests

app = Flask(__name)

@app.route('/top-songs', methods=['GET'])
def get_top_songs():
    deezer_api_key = 'YOUR_DEEZER_API_KEY'
    headers = {
        'X-RapidAPI-Key': deezer_api_key
    }

    response = requests.get('https://api.deezer.com/chart/0/tracks', headers=headers)

    if response.status_code == 200:
        top_10_songs = response.json()
        return jsonify(top_10_songs)
    else:
        return "Error: Unable to retrieve data."

if __name__ == '__main__':
    app.run()



This API uses GET function to request Deezer for data, which it allows by the API Key under the function get_top_songs. Deezer then retrieves data, specifically the top 10 songs at the time of the request. Unfortunately, I needed to get permission to use Deezer API keys they have, and I didn’t want to fill out a lengthy application agreeing to the terms and conditions using the key. Thus, I turned to Spotify and Shazam to utilize a Rapid API key.

import requests

def fetch_songs_by_artist_genre(artist, genre):
    url = "https://shazam.p.rapidapi.com/artists/get-top-songs"

    querystring = {"id":"567072","l":"en-US"}

    headers = {
        "X-RapidAPI-Key": "50ed2e0992msh34f550a1d72fefcp1ecc97jsn139df4f8c488",
	    "X-RapidAPI-Host": "shazam.p.rapidapi.com"
    }

    params = {
        "artist": artist,
        "genre": genre,
    }

    try:
        response = requests.get(url, headers=headers, params=params)

        if response.status_code == 200:
            data = response.json()
            songs = data.get("tracks", {}).get("hits", [])

            return songs
        else:
            print('Failed to fetch songs. Status code:', response.status_code)
            return None
    except Exception as e:
        print('An error occurred:', str(e))
        return None

# Example usage
artist_name = input("Enter the artist's name: ")
genre = input("Enter the genre: ")

songs = fetch_songs_by_artist_genre(artist_name, genre)

if songs:
    print(f"Songs by {artist_name} in the {genre} genre:")
    for song in songs:
        print(f"Title: {song.get('track', {}).get('title', 'N/A')}, Length: {song.get('track', {}).get('duration', 'N/A')} seconds")
else:
    print("No songs found.")

This API uses Shazam to fetch. songs by artist and genre, which is dictated by the user in a python snippet. Once the song is fetched from Shazam through RapidAPI (through a GET request), the program would display the track, title and duration in seconds. Instead of tucking the key in vairable called API Key, this uses a RapidAPI Key for Shazam, which I got and it is placed under RapidAPI headers containing the key and the host.

These APIs originate from RapidApi, which I actually got one of the keys from shazam from. Unfortuntely, it got leaked and I didn’t go through with the in fear that the project might be hijacked and ruin the entire backend. While thinking aobut what to do for the backend, one of my group members suggested creating database using SQLite to store favorited movies from a movie search service. In the span of 3 days, we worked on database to reach these goals.

from flask_cors import CORS
from flask import Flask, request, jsonify
import sqlite3

app = Flask(__name__)

DATABASE = 'movies.db'


@app.route('/favorites', methods=['POST'])
def add_favorite():
    movie_data = request.get_json()
    title = movie_data.get('title')
    release_date = movie_data.get('release_date')
    rating = movie_data.get('rating')

    with sqlite3.connect(DATABASE) as conn:
        cursor = conn.cursor()
        cursor.execute("INSERT INTO favorites (title, release_date, rating) VALUES (?, ?, ?)", (title, release_date, rating))
        conn.commit()
        conn.close()

        return jsonify({"message": "Movie added to favorites"}), 201

if __name__ == '__main__':
    app.run(debug=True)

<html>
<head>
    <title>Movie Details</title>
</head>

<body>
    <h1>Movie Details</h1>

    <label for="actorName">Actor's Name:</label>
    <input type="text" id="actorName" placeholder="Enter actor's name">

    <label for="genre">Genre:</label>
    <select id="genre">
        <option value="">All Genres</option> <!-- Add an option to select all genres -->
        <option value="horror">Horror</option>
        <option value="comedy">Comedy</option>
        <option value="action">Action</option>
        <option value="thriller">Thriller</option>
    </select>

    <button type="button" onclick="getMovieDetails()">Get Movie Details</button>

    <h2>Movie:</h2>
    <ul id="movieDetails"></ul>

This is the front matter supporting the backend code. This structure helps to display given by the API and sorts them into categories the user can interact with, such as the 4 genres and also including an option to sort by all movies (ALSO by ACTOR) Plus, there is a favorite button to sort any of the movies in the generated list into a separate category, called favorited movies. However, these need a backend to communicate with websites to fetch the data and also store the avorited movies in the database.

  const apiKey = 'bd74380ad0f3a6bc2db537543036493a'; // Replace with your actual API key

        function getMovieDetails() {
            const actorName = document.getElementById('actorName').value;
            const genre = document.getElementById('genre').value;
            let apiUrl = `https://api.themoviedb.org/3/search/movie?api_key=${apiKey}&query=${actorName}`;
            // If a genre is selected, add it to the API URL
            if (genre) {
                apiUrl += `&with_genres=${genre}`;
            }

            fetch(apiUrl)
                .then(response => response.json())
                .then(data => {
                    const movies = data.results;
                    const movieDetailsList = document.getElementById('movieDetails');
                    movieDetailsList.innerHTML = '';

                    movies.forEach(movie => {
                        const movieTitle = movie.title;
                        const releaseDate = movie.release_date ? new Date(movie.release_date).getFullYear() : 'N/A';
                        const rating = movie.vote_average || 'N/A';
                        const listItem = document.createElement('li');
                        listItem.innerHTML = `${movieTitle} (Release Date: ${releaseDate}, Rating: ${rating}/10) 
                                              <button onclick="addFavorite('${movieTitle}', '${releaseDate}', '${rating}')">Favorite</button>`;
                        movieDetailsList.appendChild(listItem);
                    });
                })
                .catch(error => console.error('Error:', error));

As you can, it requests using the api key to the backend GET Request, receiving information on the date, title, and genre, allowing the rest of the code to feed into the checkbox for the user to interact and select from. This not only prints out a list of movies accordingly with the user’s inputs, but laos allows the user to favorite movies which would be saved in the SQlite database.

PSEUDOCODE NOTES

During the lessons, I picked up on examples on psuedocode for various topics, such as if and while loops as shown below.

IF (condition)
{
	<block of statements>
}

The code in <block of statements> is executed if the Boolean expression condition evaluates to true; no action is taken if condition evaluates to false.

IF (condition)
{
	<block of statements>
}
ELSE
{
	<second block of statements>
}

The code in the first <block of statements> is executed if the Boolean expression condition evaluates to true; otherwise, the code in <second block of statements> is executed.

This pseudocode of an if statment shows how a paricular condition, whether it is a boolean or verifying a variable, can determine what path the program takes, manifested in the if(conditions to be met) and else (if conditions not met, execute else code). This simple structure provides a basis for complex programs, such as this snippet from a quiz, which revolved around the answer checking mechanic.

if answer.lower() == "yes":
    print("You are ready, let's get started.")
elif answer.lower() == "no":
    print("Go back and study until you are prepared.")
    sys.exit()
else:
    print("Invalid response, please try again.")

BLOG PLANS

CollegeBoard Stuff

See timebox

REFLECTION

Looking back on the progress I made, I was suprised on how much other stuff I learned from the work projects and lessons we had. When first taking this course, I thought it was going to be a coding class, concentrating on the key components of Python, javascript, etc. But, as a project focused course, I had to take into consideration the full picture and the sum of the parts, which forced me to learn how to deploy and manage web servers and work in html or javascript in the frontend. The biggest accommplishments for me is getting the server deployed on AWS, which took a frustratingly amount of time, and also developing and working on a backend API in order to cover my team’s frontend projects. (Plus maybe creating the python lesson, but once I got it, it was straightforward)

TRI 2 ASPIRATIONS

After looking at all the other projects, I’m defintiely going to explore more into coding in the backend, looking into how to create and properly store data in the backend with even more formats. I have a long way to go to becoming a self sufficient programmer but with time and experience, I feel that my skills will improve vastly in 2nd Trimester, putting 1st Trimester work in shame. Also, I may look in DevOps, since that project took nearly half of the time in the Passion Project, which unfortunalty did not come in useful in the final preparations for N@tm. Overall, I want to get better at this stuff not only getting the skills for my career, but also to satisfy myself with a project I can take pride in.