UdacityFullStackWebCourse Capstone Project.
The frontend app client is live at: https://nickanthony-casting-agency-c.herokuapp.com/
The backend server is live at: https://nickanthony-casting-agency.herokuapp.com/
This project is the Capstone in the Udacity Full Stack Web Developer Nanodegree. I was hoping to leverage many of the different skills I learned in the course and create a project that incorporates all the different pieces of the course.
The Casting Agency models a company that is responsible for creating movies and managing and assigning actors to those movies. You are an Executive Producer within the company and are creating a system to simplify and streamline your process.
The frontend of this app is a react application. Please see the
frontend/README.md
for more information.
- Movies with attributes title and release date
- Table name:
movies
- Columns:
id
: Integer, Primary keytitle
: String, Movie titlerelease_date
: Date, Release dateactors
: Backref to actors table; list of actors in movie
- Table name:
req_release_date = datetime.datetime.strptime("2022-01-15",
"%Y-%m-%d").date()
movie = Movie(title=req_title, release_date=req_release_date)
movie.insert()
movie = Movie.query.filter(Movie.id == id).one_or_none()
new_release_date = datetime.datetime.strptime("2022-01-15",
"%Y-%m-%d").date()
movie.release_date = new_release_date
movie.update()
- Actors with attributes name, age and gender
- Table name:
actors
- Columns:
name
: String, actor's nameage
: Integer, agegender
: String, gentermovies
: Backref to movies table; list of movies actor is in
- Table name:
actor = Actor(name=req_name, age=req_age, gender=req_gender)
actor.insert()
actor = Actor.query.filter(Actor.id == id).one_or_none()
actor.age = 28
actor.update()
- Association table between movies and actors
- Table name:
movie_actor_association
- Associates many-to-many relationship between movies and actors
- Table name:
- A Public Endpoint that fetches a list of all actors. If there are no actors, it will return an empty list.
- Permissions required: None
- Request Arguments: None
- Returns:
- Status code 200 and json {"success": True, "actors": actors} where actors is a list of all actors.
- A Public Endpoint that deletes an existing actor from the database.
Returns a 404 if the actor
<id>
is not found. - Permissions required:
- `'delete:actors'``
- Request Arguments: None
- Returns:
- Status code 200 and json
{"success": True, "delete": id}
where id is the id of the deleted record or appropriate status code indicating reason for failure.
- Status code 200 and json
- Creates a new actors and stores it in the database. It will throw a 400 if the incorrect parameters are passed.
- Permissions required:
'post:actors'
- Request Arguments:
'name'
: A string that is the full name of the actor.'age'
: An Integer that is the age of the actor.'gender'
: A string that is the gender of the actor.
- Returns:
- Status code 200 and json
{"success": True, "actors": [actor]}
where actors is an array containing only the newly created actor or appropriate status code indicating reason for failure
- Status code 200 and json
- Updates an existing actor. It will throw a 404 if
<id>
is not found. - Permissions required:
'patch:actors'
- Request Arguments:
- [Optional]
'name'
: A string that is the full name of the actor. - [Optional]
'age'
: An Integer that is the age of the actor. - [Optional]
'gender'
: A string that is the gender of the actor. - The actor information will not change if none of the request arguments are supplied. However, a 200 will still be returned.
- [Optional]
- Returns:
- Status code 200 and json
{"success": True, "actors": [actor]}
where actors is an array containing only the updated actor or appropriate status code indicating reason for failure.
- Status code 200 and json
- A Public Endpoint that fetches a list of all movies. If there are no movies, it will return an empty list.
- Permissions required: None
- Request Arguments: None
- Returns:
- Status code 200 and json
{"success": True, "movies": movies}
where movies is a list of all movies.
- Status code 200 and json
- A Public Endpoint that deletes an existing movie from the database.
Returns a 404 if the movie
<id>
is not found. - Permissions required:
'delete:movies'
- Request Arguments: None
- Returns:
- Status code 200 and json
{"success": True, "delete": id}
where id is the id of the deleted record or appropriate status code indicating reason for failure.
- Status code 200 and json
- Creates a new movies and stores it in the database. It will throw a 400 if the incorrect parameters are passed.
- Permissions required:
'post:movies'
- Request Arguments:
'title'
: A string that is the full title of the movie.'release_date'
: A string of the release date of the movie, in the format "YYYY-MM-DD"
- Returns:
- Status code 200 and json
{"success": True, "movies": [movie]}
where movies is an array containing only the newly created movie or appropriate status code indicating reason for failure
- Status code 200 and json
- Updates an existing movie. It will throw a 404 if
<id>
is not found. - Permissions required:
'patch:movies'
- Request Arguments:
- [Optional]
'title'
: A string that is the full title of the movie. - [Optional]
'release_date'
: A string of the release date of the movie, in the format "YYYY-MM-DD" - The movie information will not change if none of the request arguments are supplied. However, a 200 will still be returned.
- [Optional]
- Returns:
- Status code 200 and json
{"success": True, "movies": [movie]}
where movies is an array containing only the updated movie or appropriate status code indicating reason for failure.
- Status code 200 and json
post:actors
: create a new actorpatch:actors
: modify an existing actordelete:actors
: delete an actorpost:movies
: create a new moviepatch:movies
: modify an existing moviedelete:movies
: delete a movie
- Casting Assistant
- Can view actors and movies.
- Has permissions:
- None, get actors/movies are public endpoints
- Casting Director
- All permissions a Casting Assistant has and…
- Add or delete an actor from the database
- Modify actors or movies
- Has permissions:
post:actors
patch:actors
delete:actors
patch:movies
- Executive Producer
- All permissions a Casting Director has and…
- Add or delete a movie from the database
- Has permissions:
post:actors
patch:actors
delete:actors
post:movies
patch:movies
delete:movies
Generate a new token:
-
Casting Assistant
N/A
-
Casting Director
See setup.sh, CASTING_DIRECTOR_TOKEN
-
Executive Producer
See setup.sh, EXECUTIVE_PRODUCER_TOKEN
Follow instructions to install the correct version of Python for your platform in the python docs.
We recommend working within a virtual environment whenever using Python for projects. This keeps your dependencies for each project separate and organaized. Instructions for setting up a virual enviornment for your platform can be found in the python docs.
python -m venv venv
venv/bin/activate
Once you have your venv
setup and running, install dependencies by navigating
to the root directory and running:
pip install -r requirements.txt
This will install all of the required packages included in the requirements.txt file.
Create your database using PostgreSQL. Ensure that you have PostgreSQL installed with:
psql --version
Once that is done, create your local database:
createdb casting_agency
Once you create the database, open your terminal, navigate to the root folder, and run:
flask db init
flask db migrate -m "Initial migration."
flask db upgrade
After running, don't forget modify 'SQLALCHEMY_DATABASE_URI'
variable.
From within the root directory, first ensure you're working with your created
venv
. To run the server, execute the following:
export FLASK_APP=app
export FLASK_DEBUG=true
export FLASK_ENV=development
source setup.sh
flask run
Setting the FLASK_ENV variable to development will detect file changes and restart the server automatically.
Running the following command from the root directory will ensure you have a working local server running:
python test_local_app.py
Create a testing database usg psql.
createdb casting_agency_test
If the testing db was already created:
dropdb casting_agency_test && createdb casting_agency_test
Make sure the environment variables are set:
source setup.sh
To test the local install, run the following command from the root folder.
python test_app.py
All tests will run with the default executive director token above. If more than 50% of the tests are failing with 401, then it is likely the the JWTs have expired.
Because there is no front end, I wrote this script to test out the endpoints live on heroku!
python test_heroku_app.py --help
The script will run queries against the live heroku application! You can try a couple pre-populated movies and actors.
All python files have been checked with pycodestyle
.
Using the following to double check code style:
pycodestyle <filename.py>
This is the full tech stack for this application.
I wrote this application using macOS Catalina 10.15.7. It should work on most UNIX-based Operating Systems.
All dependencies can be installed using either the pip
package manager or
the brew
package manager.
The web server technology I used is Flask.
I am using Flask
, Flask CORS
for Cross-Origin Resource Sharing, and
gunicorn
for Heroku deployment.
I am using PostgreSQL 13.1
for the Database system. For integration with
flask and python, I am using SQLAlchemy
and Flask-SQLAlchemy
.
I am using Flask-Migrate
to manage database versions. Then I'm using
alembic
for the actual versioning scheme. Finally, I'm using psycopg2
to manage the database upgrades.
I am using Python 3.7.7
. As well as the following python modules:
pycodestyle
for codestylePyJWT
andpython-jose
for JWG authentication managementpytest
for the local python test suite