Introduction

Frontend and backend are two essential components of a web application. The frontend is the part of the application that interacts with the user, whereas the backend is the part that handles the logic and data processing behind the scenes.

The frontend, also known as the client-side, typically consists of HTML, CSS, and JavaScript code that runs in the user's web browser. The frontend handles the user interface, page layout, and overall look of the application. It also handles user interactions, such as submitting forms, clicking buttons, and navigating between pages.

On the other hand, the backend, also known as the server-side, typically consists of a server, a database, and, in our case, APIs. The backend handles the processing and storage of data, manages user authentication and authorization, and handles business logic and rules. The backend also communicates with the frontend, providing the necessary data to render the user interface and processing user inputs.

Backend

In our class we mainly use Python and SQL/JSON to create APIs and databases. Here is a simple example of creating a SQL database and using CRUD as well.

What is CRUD

  • C: The 'C' stands for create, meaning to create a new entry in a database. In this case, creating a new entry about a certain movie or TV show.

  • R: Read, or to retrieve data from the database. In this case it is selecting the movie/TV show that you choose to display.

  • U: Update, or changing an existing entry in the database. In this case it is selecting the preexisting movie/TV show and changing the values to match what you want.

  • D: Delete, or removing data from the database. In this case it is selecting the preexisting movie/TV show and removing the entry from the database.

Films API

This API is intended to be used as a list of movies and TV shows that a person has watched. It includes attributes for the Film name(key), the year released, the language, the number of episodes, A list of the number of episodes(using pickletype), and a youtube url for the trailer. The CRUD works as follows: Create: Enter the above mentioned attributes Read: Returns all of the films and their attributes Update: Takes in new episodes watched, and a list of their names, and adds them to their respective attributes Delete: Option for deleting every film, also takes in a name to delete that film if it exists

from flask import Flask
import sqlite3

app = Flask(__name__)
# Connect to the SQLite database using SQLite3
conn = sqlite3.connect('films.db')

# Create a cursor object to execute SQL commands
cursor = conn.cursor()

# Create a table in the database
cursor.execute('''CREATE TABLE movies
                 (id INTEGER PRIMARY KEY, title TEXT, year INTEGER, epcount INTEGER, language TEXT, trailer TEXT, eplist TEXT)''')

# Commit the changes to the database and close the connection
conn.commit()
conn.close()
import sqlite3

def create():
    # Ask the user for movie details
    title = input("Enter the movie/tv show title: ")
    year = input("Enter the movie/tv show release year: ")
    epcount = input("Enter the movie/tv show epcount: ")
    language = input("Enter the movie/tv show language: ")
    eplist = input("Enter the movie/tv show episode names: ")
    trailer = input("Enter the link movie/tv show trailer: ")

    # Connect to the database and create a cursor to execute SQL commands
    database = 'films.db'
    connection = sqlite3.connect(database)
    cursor = connection.cursor()

    try:
        # Execute SQL to insert record into db
        cursor.execute("INSERT INTO movies (title, year, epcount, language, eplist, trailer) VALUES (?, ?, ?, ?, ?, ?)", (title, year, epcount, language, eplist, trailer))
        # Commit the changes
        connection.commit()
        print(f"{title} has been added to the list of movies.")

    except sqlite3.Error as error:
        print("Error while inserting record:", error)

    # Close cursor and connection
    cursor.close()
    connection.close()

create()
Never Have I Ever has been added to the list of movies.
def read(id):
    # Connect to the database and create a cursor to execute SQL commands
    database = 'films.db'
    connection = sqlite3.connect(database)
    cursor = connection.cursor()

    # Execute SQL to select a record from db by id
    cursor.execute("SELECT * FROM movies WHERE id=?", (id,))

    # Fetch the record from the cursor
    movie = cursor.fetchone()

    # If movie exists, print its details, else print message
    if movie:
        print(f"{movie[0]}. {movie[1]}, {movie[2]}, {movie[3]}, {movie[4]}, {movie[5]}, {movie[6]}")
    else:
        print("Movie not found.")

    # Close cursor and connection
    cursor.close()
    connection.close()

read(id=1)
1. Never Have I Ever, 2021, 40, English, link, Davi/Ben
def update(id):
    # Connect to the database and create a cursor to execute SQL commands
    database = 'films.db'
    connection = sqlite3.connect(database)
    cursor = connection.cursor()

    # Ask the user for movie details to update
    title = input("Enter the updated movie/tv show title: ")
    year = input("Enter the updated movie/tv show release year: ")
    epcount = input("Enter the updated movie/tv show epcount: ")
    language = input("Enter the updated movie/tv show language: ")
    eplist = input("Enter the updated movie/tv show episode names: ")
    trailer = input("Enter the updated link movie/tv show trailer: ")

    try:
        # Execute SQL to update the record in db
        cursor.execute("UPDATE movies SET title=?, year=?, epcount=?, language=?, eplist=?, trailer=? WHERE id=?", (title, year, epcount, language, eplist, trailer, id))
        # Commit the changes
        connection.commit()
        print("Movie updated successfully.")

    except sqlite3.Error as error:
        print("Error while updating record:", error)

    # Close cursor and connection
    cursor.close()
    connection.close()

update(id=1)
Movie updated successfully.
def delete(id):
    # Connect to the database and create a cursor to execute SQL commands
    database = 'films.db'
    connection = sqlite3.connect(database)
    cursor = connection.cursor()

    try:
        # Execute SQL to delete the record from db by id
        cursor.execute("DELETE FROM movies WHERE id=?", (id,))
        # Commit the changes
        connection.commit()
        print("Movie deleted successfully.")

    except sqlite3.Error as error:
        print("Error while deleting record:", error)

    # Close cursor and connection
    cursor.close()
    connection.close()

delete(id=2)
Movie deleted successfully.

Fetching

Overview

  • Involves retrieving data from a server or database
  • Can use different HTTP methods, such as GET, POST, PUT, and DELETE, to perform different types of operations on the server.
  • Fetching can be done through a variety of ways including AJAX, XHR, and Axios
  • In APCSP we tend to use the Fetch API over anything else
  • Fetching involves sending a request to a server using a URL (Uniform Resource Locator), which identifies the location of the resource being requested.
  • Can receive data in various formats, including JSON
  • JSON data can be parsed into objects and arrays in JavaScript, making it easy to work with and manipulate in the frontend

Python Fetch Using Request

import requests

url = "https://moviesdatabase.p.rapidapi.com/titles"

headers = {
	"content-type": "application/octet-stream",
	"X-RapidAPI-Key": "8401db6433msh3a46dd5bf23ad2ep19a280jsn48536a994246",
	"X-RapidAPI-Host": "moviesdatabase.p.rapidapi.com"
}

response = requests.get(url, headers=headers)

print(response.json())
{'page': 1, 'next': '/titles?page=2', 'entries': 10, 'results': [{'id': 'tt0001922', 'primaryImage': {'id': 'rm736959488', 'width': 800, 'height': 563, 'url': 'https://m.media-amazon.com/images/M/MV5BZDI4MmJiMmMtMzQ3Mi00N2Y0LTlkYmUtYmQ0ZTQ1NzVlZmVjXkEyXkFqcGdeQXVyMDUyOTUyNQ@@._V1_.jpg', 'caption': {'plainText': 'Darwin Karr and Gertrude McCoy in That Winsome Winnie Smile (1911)', '__typename': 'Markdown'}, '__typename': 'Image'}, 'titleType': {'text': 'Short', 'id': 'short', 'isSeries': False, 'isEpisode': False, '__typename': 'TitleType'}, 'titleText': {'text': 'That Winsome Winnie Smile', '__typename': 'TitleText'}, 'releaseYear': {'year': 1911, 'endYear': None, '__typename': 'YearRange'}, 'releaseDate': {'day': 9, 'month': 9, 'year': 1911, '__typename': 'ReleaseDate'}}, {'id': 'tt0001539', 'primaryImage': {'id': 'rm1311052544', 'width': 800, 'height': 582, 'url': 'https://m.media-amazon.com/images/M/MV5BZGY5NzI0MzQtM2EwYi00NzY2LThiYjYtYTM5YmViZDEwMzkzXkEyXkFqcGdeQXVyMDUyOTUyNQ@@._V1_.jpg', 'caption': {'plainText': 'Caïn et Abel (1911)', '__typename': 'Markdown'}, '__typename': 'Image'}, 'titleType': {'text': 'Short', 'id': 'short', 'isSeries': False, 'isEpisode': False, '__typename': 'TitleType'}, 'titleText': {'text': 'Caïn et Abel', '__typename': 'TitleText'}, 'releaseYear': {'year': 1911, 'endYear': None, '__typename': 'YearRange'}, 'releaseDate': {'day': None, 'month': None, 'year': 1911, '__typename': 'ReleaseDate'}}, {'id': 'tt0001636', 'primaryImage': None, 'titleType': {'text': 'Short', 'id': 'short', 'isSeries': False, 'isEpisode': False, '__typename': 'TitleType'}, 'titleText': {'text': 'Galileo', '__typename': 'TitleText'}, 'releaseYear': {'year': 1911, 'endYear': None, '__typename': 'YearRange'}, 'releaseDate': {'day': None, 'month': 7, 'year': 1911, '__typename': 'ReleaseDate'}}, {'id': 'tt0002148', 'primaryImage': {'id': 'rm1303852544', 'width': 700, 'height': 526, 'url': 'https://m.media-amazon.com/images/M/MV5BMWY2ODg0YWEtZDVmYy00OTEwLTkxN2YtYzY5ZmRmNjVlZWYyXkEyXkFqcGdeQXVyMDUyOTUyNQ@@._V1_.jpg', 'caption': {'plainText': "Fred Mace and Mabel Normand in The Drummer's Vacation (1912)", '__typename': 'Markdown'}, '__typename': 'Image'}, 'titleType': {'text': 'Short', 'id': 'short', 'isSeries': False, 'isEpisode': False, '__typename': 'TitleType'}, 'titleText': {'text': "The Drummer's Vacation", '__typename': 'TitleText'}, 'releaseYear': {'year': 1912, 'endYear': None, '__typename': 'YearRange'}, 'releaseDate': {'day': 23, 'month': 12, 'year': 1912, '__typename': 'ReleaseDate'}}, {'id': 'tt0001702', 'primaryImage': None, 'titleType': {'text': 'Short', 'id': 'short', 'isSeries': False, 'isEpisode': False, '__typename': 'TitleType'}, 'titleText': {'text': "The Indian Maiden's Lesson", '__typename': 'TitleText'}, 'releaseYear': {'year': 1911, 'endYear': None, '__typename': 'YearRange'}, 'releaseDate': {'day': 22, 'month': 4, 'year': 1911, '__typename': 'ReleaseDate'}}, {'id': 'tt0001856', 'primaryImage': {'id': 'rm970923264', 'width': 800, 'height': 597, 'url': 'https://m.media-amazon.com/images/M/MV5BYmVhNGZlZTEtNjFmMS00MjEyLThkZmMtMTIwZjRjNzFkYjU3XkEyXkFqcGdeQXVyMDUyOTUyNQ@@._V1_.jpg', 'caption': {'plainText': 'Edwin August and Dorothy West in The Revenue Man and the Girl (1911)', '__typename': 'Markdown'}, '__typename': 'Image'}, 'titleType': {'text': 'Short', 'id': 'short', 'isSeries': False, 'isEpisode': False, '__typename': 'TitleType'}, 'titleText': {'text': 'The Revenue Man and the Girl', '__typename': 'TitleText'}, 'releaseYear': {'year': 1911, 'endYear': None, '__typename': 'YearRange'}, 'releaseDate': {'day': 25, 'month': 9, 'year': 1911, '__typename': 'ReleaseDate'}}, {'id': 'tt0001790', 'primaryImage': {'id': 'rm635370240', 'width': 1748, 'height': 1340, 'url': 'https://m.media-amazon.com/images/M/MV5BMjAzMzQ3MjQxOV5BMl5BanBnXkFtZTgwMDQzNzExMzE@._V1_.jpg', 'caption': {'plainText': 'Eugénie Nau in Les misérables - Époque 1: Jean Valjean (1913)', '__typename': 'Markdown'}, '__typename': 'Image'}, 'titleType': {'text': 'Movie', 'id': 'movie', 'isSeries': False, 'isEpisode': False, '__typename': 'TitleType'}, 'titleText': {'text': 'Les misérables - Époque 1: Jean Valjean', '__typename': 'TitleText'}, 'releaseYear': {'year': 1913, 'endYear': None, '__typename': 'YearRange'}, 'releaseDate': {'day': 3, 'month': 1, 'year': 1913, '__typename': 'ReleaseDate'}}, {'id': 'tt0000543', 'primaryImage': None, 'titleType': {'text': 'Short', 'id': 'short', 'isSeries': False, 'isEpisode': False, '__typename': 'TitleType'}, 'titleText': {'text': 'Christian IXS bisættelse', '__typename': 'TitleText'}, 'releaseYear': {'year': 1906, 'endYear': None, '__typename': 'YearRange'}, 'releaseDate': {'day': 19, 'month': 2, 'year': 1906, '__typename': 'ReleaseDate'}}, {'id': 'tt0002089', 'primaryImage': None, 'titleType': {'text': 'Movie', 'id': 'movie', 'isSeries': False, 'isEpisode': False, '__typename': 'TitleType'}, 'titleText': {'text': 'Carmen', '__typename': 'TitleText'}, 'releaseYear': {'year': 1912, 'endYear': None, '__typename': 'YearRange'}, 'releaseDate': None}, {'id': 'tt0000548', 'primaryImage': None, 'titleType': {'text': 'Short', 'id': 'short', 'isSeries': False, 'isEpisode': False, '__typename': 'TitleType'}, 'titleText': {'text': 'Fiskerliv i Norden', '__typename': 'TitleText'}, 'releaseYear': {'year': 1906, 'endYear': None, '__typename': 'YearRange'}, 'releaseDate': {'day': 15, 'month': 9, 'year': 1906, '__typename': 'ReleaseDate'}}]}

This is a functional fetch of a movies API from Rapid API, but the data isn't very readable. Below is an example of using Pandas to format the key values as a dataframe.

import requests
import pandas as pd

url = "https://moviesdatabase.p.rapidapi.com/titles"

headers = {
    "content-type": "application/octet-stream",
    "X-RapidAPI-Key": "8401db6433msh3a46dd5bf23ad2ep19a280jsn48536a994246",
    "X-RapidAPI-Host": "moviesdatabase.p.rapidapi.com"
}

response = requests.get(url, headers=headers)
data = response.json()

# Create an empty DataFrame
df = pd.DataFrame()

# Extract the required information and store it in a list of dictionaries
results = data["results"]
entries = []
for result in results:
    entry = {
        "id": result["id"],
        "title": result["titleText"]["text"],
        "release_year": result["releaseYear"]["year"],
    }
    entries.append(entry)

# Convert the list of dictionaries into a DataFrame
df = pd.DataFrame(entries)

print("Old dataframe: ",  df)

ratings = [4.5, 3.8, 2.5, 4.2, 3.7, 2.9, 10.0, 7.6, 5.5, 8.2]

# Add the ratings list as a new column to the DataFrame
df['rating'] = ratings

# Print the updated DataFrame
print("Dataframe with new column: ", df)

# ADD YOUR OWN COLUMN TO THE DATAFRAME
Old dataframe:            id                                    title  release_year
0  tt0001922                That Winsome Winnie Smile          1911
1  tt0001539                             Caïn et Abel          1911
2  tt0001636                                  Galileo          1911
3  tt0002148                   The Drummer's Vacation          1912
4  tt0001702               The Indian Maiden's Lesson          1911
5  tt0001856             The Revenue Man and the Girl          1911
6  tt0001790  Les misérables - Époque 1: Jean Valjean          1913
7  tt0000543                 Christian IXS bisættelse          1906
8  tt0002089                                   Carmen          1912
9  tt0000548                       Fiskerliv i Norden          1906
Dataframe with new column:            id                                    title  release_year  rating
0  tt0001922                That Winsome Winnie Smile          1911     4.5
1  tt0001539                             Caïn et Abel          1911     3.8
2  tt0001636                                  Galileo          1911     2.5
3  tt0002148                   The Drummer's Vacation          1912     4.2
4  tt0001702               The Indian Maiden's Lesson          1911     3.7
5  tt0001856             The Revenue Man and the Girl          1911     2.9
6  tt0001790  Les misérables - Époque 1: Jean Valjean          1913    10.0
7  tt0000543                 Christian IXS bisættelse          1906     7.6
8  tt0002089                                   Carmen          1912     5.5
9  tt0000548                       Fiskerliv i Norden          1906     8.2

Using Pandas to format a request obtained from a 3rd Party API makes it much easier to read and you can select what you want to display as well. Pandas makes it easy to access data that you feel is important.

Backend and Frontend Example

Write notes below

Hacks

CRUD:

- Create, Read, Update, Delete 
- Functions in the database where we can manage an object class
- You can use cursor connect ot connect to the database and run SQL commands in code or terminal
- Uses user input to modify the backend

Frontend Development:

- User interface, where the user can interact and give input that reaches backend using HTML, CSS, and JavaScript
- Makes sure that the frontend (website/app) is user friendly and visually appealing 

Backend Development:

- Server-side programming using languages like Python, Ruby, Java, or PHP
- Handling data processing, database management, and server-side functions
- Ensuring scalability, security, and data management

Fetching:

- Retrieving data from a server using AJAX, Fetch API, or third-party libraries like Axios
- Specific methods for certain requests 
    - POST, PUT (update), GET...
  1. Create a completely unique API with all 4 CRUD features (Create, Read, Update, Delete)
  2. Create a Fetch API request for your corresponding API
  3. Attempt a complete website on GitHub Pages including HTML (optional)

Takeaways/Notes

  • Frontend is the interface that the user interacts with
  • Backend is all of the behind the scenes part
  • Use CRUD functions to connect the frontend and backend
  • data cleaning:
    • input youtube link and change to embed link
    • ensure inputs are correct data type: integer for year...
  • Fetching
    • request to server using url to receive data (usually in JSON) --> can manipulate it into arrays/lists/dataframes (pandas)
    • apparent in API's
import sqlite3

def create_database():
    # Connect to the database (will create it if it doesn't exist)
    connection = sqlite3.connect('instance/Dogs.db')
    cursor = connection.cursor()

    # Create the professors table if it doesn't already exist
    cursor.execute('''CREATE TABLE IF NOT EXISTS Dogs (
                    name TEXT,
                    breed TEXT,
                    age INTEGER
                )''')

    # Commit changes and close the connection
    connection.commit()
    connection.close()

# Call the function to create the database
create_database()
from flask import Flask
import sqlite3

# Create a Flask application
app = Flask(__name__)

# Connect to the SQLite database using SQLite3
conn = sqlite3.connect('instance/Dogs.db')

# Create a cursor object to execute SQL commands
cursor = conn.cursor()

# Create a table in the database using SQL commands
cursor.execute('''CREATE TABLE Dogs
                 (id INTEGER PRIMARY KEY, name TEXT, breed TEXT, age INTEGER)''')

# Commit the changes to the database
conn.commit()

# Close the connection
conn.close()
import sqlite3

def create():
   database = 'instance/Dogs.db'
   name = input("Enter the dog's name: ")
   breed = input("Enter the dog's breed: ")
   age = input("Enter the dog's age (in human years): ")


   # Connect to the database and create a cursor to execute SQL commands
   connection = sqlite3.connect(database)
   cursor = connection.cursor()


   try:
       # Execute SQL to insert record into db
       cursor.execute("INSERT INTO Dogs (name, breed, age) VALUES (?, ?, ?)", (name, breed, age))
       # Commit the changes
       connection.commit()
       print(f"{name} has been added to the list of dogs.")
              
   except sqlite3.Error as error:
       print("Error while inserting record", error)


   # Close cursor and connection
   cursor.close()
   connection.close()

create()
Polly has been added to the list of dogs.
import sqlite3

def read():
    try:
        # Open a connection to the database and create a cursor
        connection = sqlite3.connect('instance/Dogs.db')
        cursor = connection.cursor()

        # Fetch all records from the dog table
        cursor.execute("SELECT * FROM Dogs")
        rows = cursor.fetchall()

        # If there are any records, print them
        if len(rows) > 0:
            print("List of dogs :")
            for row in rows:
                print(f"Name: {row[1]}\nBreed: {row[2]}\nAge: {row[3]}\n")
        else:
            print("There are no dogs in the list.")

    except sqlite3.Error as error:
        print("Error while connecting to the database:", error)

    finally:
        # Close the cursor and the connection to the database
        cursor.close()
        connection.close()

read()
List of dogs :
Name: Elly
Breed: Rottweiler
Age: 10

Name: Athyna
Breed: Pitbull
Age: 9

Name: Oakley
Breed: Mixed
Age: 0

Name: Pippy
Breed: Mixed GS/Boxer
Age: 2

Name: Polly
Breed: Blue Herder dog
Age: 4

import sqlite3

def update():
    database = 'instance/Dogs.db'
    connection = sqlite3.connect(database)
    cursor = connection.cursor()
    
    try:
        # Get the dog's name to update
        name = input("Enter the name of the dog to update: ")
        
        # Retrieve the current record from the database
        cursor.execute("SELECT * FROM Dogs WHERE name=?", (name,))
        record = cursor.fetchone()
        
        # If the dog is found, update the record
        if record:
            print("Enter the new information for the dog:")
            breed = input(f"Current breed: {record[2]}\nNew breed: ")
            age = input(f"Current age: {record[3]}\nNew age: ")
            
            # Execute SQL to update the record
            cursor.execute("UPDATE Dogs SET breed=?, age=? WHERE name=?", (breed, age, name))
            connection.commit()
            
            print(f"{name}'s record has been updated.")
        
        # If the dog is not found, notify the user
        else:
            print(f"No record found for {name}.")
    
    except sqlite3.Error as error:
        print("Error while updating record", error)
    
    # Close cursor and connection
    cursor.close()
    connection.close()
update ()
Enter the new information for the dog:
Pippy's record has been updated.
import sqlite3


def delete():
    # Connect to the database and create a cursor
    connection = sqlite3.connect('instance/Dogs.db')
    cursor = connection.cursor()

    # Prompt the user for the name of the dog to delete
    name = input("Enter the name of the dog you want to delete: ")

    # Use a SQL query to find the dog with the given name
    cursor.execute("SELECT * FROM Dogs WHERE name=?", (name,))
    row = cursor.fetchone()

    # If the professor exists, confirm deletion and delete the record
    if row:
        confirm = input(f"Are you sure you want to delete {name}? (y/n): ")
        if confirm.lower() == 'y':
            cursor.execute("DELETE FROM Dogs WHERE name=?", (name,))
            connection.commit()
            print(f"{name} has been deleted from the list of dogs.")
    else:
        print(f"{name} not found in the list of dogs.")

    # Close the cursor and the connection to the database
    cursor.close()
    connection.close()

delete()
Polly has been deleted from the list of dogs.
import requests
import pandas as pd

url = "http://localhost:8731/api/users/"

response = requests.get(url)
data = response.json()

df = pd.DataFrame()
attributes = []
for result in data:
    user = {
        "age": result["age"],
        "cities": result["cities"],
        "dob": result["dob"],
        "email": result["email"],
        "name": result["name"],
        "id": result["id"],
        "phone": result["phone"],

    }
    attributes.append(user)

df = pd.DataFrame(attributes)

print(df)
   age               cities         dob                  email           name  \
0   17  Escondido, Carlsbad  01-15-2006     joseanda@gmail.com  Joselyn Anda2   
1   16          Los Angeles  10-03-2006      linaaaa@gmail.com     Lina Awad2   
2   15            Encinitas  10-05-2007       najaAF@gmail.com  Naja Fonseca2   
3   17                Poway  10-21-1959  amithaaaaas@gmail.com  Amitha Sanka2   
4   48                 None  12-09-1975        danda@gmail.com  Derryck Anda    

   id       phone  
0   1  8586197777  
1   2  8886665555  
2   3  8587360021  
3   4  8584320098  
4   5  8583490000