The Casting Agency API is modelled for a company that is responsible for creating movies and managing and assigning actors to those movies. The application leverages Auth0 to provide JWT Token based authentication and authorization, and uses RBAC (Role Based Access Control) to assign permission based on roles. The API is responsible for checking permissions and handling CRUD operations for Actor and Movie models. Only authorized users will be able to avail the Casting Agency API service.
Note: the specification for this capstone project is provided by Udacity and the main objective of this project is to demonstrate all the learned concepts as part of Udacity Full Stack Web Developer Nanodegree program including data modelling with Flask-SQLAlchemy
, API development and testing using Python Flask
, generation of migration scripts with Flask-Migrate
, JWT based authentication and authorization with RBAC and API deployment with Heroku.
The application is deployed on Heroku and can be accessed via the link
Follow instructions to install the latest version of python for your platform in the python docs
- virtualenv as a tool to create isolated Python environments
- It is recommended to work with 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
Once you have your virtual environment setup and running, install dependencies by running:
pip3 install -r requirements.txt
This will install all of the required packages as mentioned within the requirements.txt
file.
Note: If we do not mention the specific version of a package, then the default latest stable package will be installed.
-
Flask is a lightweight backend microservices framework. Flask is required to handle requests and responses.
-
SQLAlchemy and Flask-SQLAlchemy are libraries to handle the lightweight sqlite database.
app.py
is the entrypoint of the application and database models can be referenced inmodels.py
-
Flask-Migrate for creating and running schema migrations
-
Flask-CORS is the extension we'll use to handle cross origin requests from our frontend server.
-
jose JavaScript Object Signing and Encryption for JWTs. Useful for encoding, decoding, and verifying JWTS.
-
pycodestyle pycodestyle is a tool to check Python code against PEP 8 coding styleguide.
- PostgreSQL has been chosen as the database of choice for this project
- start postgres server(if not already running) and login to postgres
service postgresql start
sudo -u <username> -i
- create two databases, one for development and the other for testing
createdb casting-agency
createdb casting-agency-test
- Run the setup file to create the environment variables.
- Note: Before running the script, please update the DATABASE_URL as needed based on your local postgres setup.
source setup.sh
- Run the following commands from the project directory to setup the initial database using migration files
python manage.py db init
python manage.py db upgrade
- Populate db tables with seed data:
python manage.py seed
- From within the project directory first ensure you are working using your created virtual environment.
- Run the setup file to create the environment variables (if not already run in the precceding section).
- Note: The
setup.sh
will create DATABASE_URL, AUTH0 and FLASK_APP related environment variables.
source setup.sh
To run the development server, execute:
flask run
- Create a new Auth0 Account
- Select a unique tenant domain
- Create a new, single page web application
- Create a new API
- in API Settings:
- Enable RBAC
- Enable Add Permissions in the Access Token
- in API Settings:
- Create new API permissions:
get:actors
get:movies
post:actors
post:movies
patch:actors
patch:movies
delete:actors
delete:movies
- Create new roles for:
- Public
- No Access
- Casting Assistant
- can view only actors and movies
- Permission:
get:actors
,get:movies
- Casting Director
- can do all actions as performed by Casting Assistant
- can also add or delete an actor from the database
- can also modify actors or movies
- Permission:
get:actors
,get:movies
,post:actors
,patch:actors
,delete:actors
,patch:movies
- Executive Producer
- can do all actions as performed by Casting Director
- additionally can also add or delete a movie from the database
- Permission:
get:actors
,get:movies
,post:actors
,post:movies
,patch:actors
,patch:movies
,delete:actors
,delete:movies
- Public
- Test endpoints with below registered users:
- Register 3 users - assign the Assistant role, Director role and Producer role to each user respectively.
Users need to be authenticated via Auth0 to avail the Casting Agency API service. JWT Tokens will be generated after successful authentication. The users will be granted access to the API endpoints based on the permissions in the JWT payload data.
- Base URL: This app can be run locally at the default URL
http://127.0.0.1:5000/
- External URL: The app is also hosted on Heroku and can be accessed via the link
- Authentication: This version of the application supports authentication and authorization using Auth0.
The API will return the following error codes when requests fail:
- 400: Bad Request
- 400: Permissions not included in JWT
- 400: Unable to parse authentication token
- 400: Unable to find the appropriate key
- 401: unauthorized
- 401: Authorization header is expected
- 401: Authorization header must start with "Bearer
- 401: Token not found
- 401: Authorization header must be bearer token
- 401: Authorization malformed
- 401: Token expired
- 401: Incorrect claims. Please, check the audience and issuer
- 403: permission not found
- 404: Resource Not Found
- 422: Not Processable
- 500: Internal Server Error
An example of 401 error due to RBAC returned as JSON objects in the following format:
{
"error": 401,
"message": {
"code": "authorization_header_missing",
"description": "Authorization header is expected."
},
"success": false
}
Other errors are returned as JSON objects in the following format:
{
"success": False,
"error": 400,
"message": "bad request"
}
- Before running the commands, please remember to update the ACCESS_TOKEN placeholder with valid JWT token
- General:
- Returns a list of movies.
- Authorized Roles: Casting Assistant, Casting Director, Executive Producer.
- Required permission: get:movies
- Sample:
curl -X GET http://127.0.0.1:5000/movies -H "Content-Type: application/json" -H "Authorization: Bearer ACCESS_TOKEN"
{
"movies": [
{
"id": 1,
"release_date": "Wed, 16 Dec 2020 00:00:00 GMT",
"title": "Wonder Woman 1984"
},
{
"id": 2,
"release_date": "Fri, 05 Feb 2021 00:00:00 GMT",
"title": "Space Sweepers"
},
{
"id": 3,
"release_date": "Thu, 19 Dec 2019 00:00:00 GMT",
"title": "Star Wars: The Rise of Skywalker (Episode IX)"
},
{
"id": 4,
"release_date": "Thu, 15 May 2003 00:00:00 GMT",
"title": "The Matrix Reloaded"
},
{
"id": 5,
"release_date": "Tue, 21 May 2019 00:00:00 GMT",
"title": "Parasite"
}
],
"success": true
}
- General:
- This route returns the movie with specified movie id.
- Authorized Roles: Casting Assistant, Casting Director, Executive Producer.
- Required permission: get:movies
- Sample:
curl -X GET http://127.0.0.1:5000/movies/1 -H "Content-Type: application/json" -H "Authorization: Bearer ACCESS_TOKEN"
{
"movie": {
"id": 1,
"release_date": "Wed, 16 Dec 2020 00:00:00 GMT",
"title": "Wonder Woman 1984"
},
"success": true
}
- General:
- Creates a new new movie using json request parameter - title and release_date.
- Authorized Roles: Executive Producer.
- Required permission: post:movies
- Sample:
curl -X POST http://127.0.0.1:5000/movies -H "Content-Type: application/json" -H "Authorization: Bearer ACCESS_TOKEN" -d '{"title": "The White Tiger", "release_date": "2021-01-22"}'
{
"movie": {
"id": 6,
"release_date": "Fri, 22 Jan 2021 00:00:00 GMT",
"title": "The White Tiger"
},
"success": true
}
- General:
- Patches the movie of the given ID if it exists. Returns the id of the movie and success value.
- Authorized Roles: Casting Director, Executive Producer.
- Required permission: patch:movies
- Sample:
curl -X PATCH http://127.0.0.1:5000/movies/2 -H "Content-Type: application/json" -H "Authorization: Bearer ACCESS_TOKEN" -d '{"title": "Space Sweepers Victory", "release_date": "2021-02-05"}'
{
"movie": [
{
"id": 2,
"release_date": "Fri, 05 Feb 2021 00:00:00 GMT",
"title": "Space Sweepers Victory"
}
],
"success": true
}
- General:
- Deletes the movie of the given ID if it exists. Returns the id of the deleted movie and success value.
- Authorized Roles: Executive Producer.
- Required permission: delete:movies
- Sample:
curl -X DELETE http://127.0.0.1:5000/movies/6 -H "Authorization: Bearer ACCESS_TOKEN"
{
"delete": 6,
"success": true
}
- General:
- Returns a list of actors.
- Authorized Roles: Casting Assistant, Casting Director, Executive Producer.
- Required permission: get:actors
- Sample:
curl -X GET http://127.0.0.1:5000/actors -H "Content-Type: application/json" -H "Authorization: Bearer ACCESS_TOKEN"
{
"actors": [
{
"age": 58,
"gender": "male",
"id": 1,
"name": "Tom Cruise"
},
{
"age": 45,
"gender": "female",
"id": 2,
"name": "Angelina Jolie"
},
{
"age": 64,
"gender": "male",
"id": 3,
"name": "Tom Hanks"
},
{
"age": 71,
"gender": "female",
"id": 4,
"name": "Meryl Streep"
},
{
"age": 53,
"gender": "female",
"id": 5,
"name": "Nicole Kidman"
}
],
"success": true
}
- General:
- This route returns the actor with specified actor id.
- Authorized Roles: Casting Assistant, Casting Director, Executive Producer.
- Required permission: get:actors
- Sample:
curl -X GET http://127.0.0.1:5000/actors/1 -H "Content-Type: application/json" -H "Authorization: Bearer ACCESS_TOKEN"
{
"actor": {
"age": 58,
"gender": "male",
"id": 1,
"name": "Tom Cruise"
},
"success": true
}
- General:
- Creates a new actor using json request parameter - name, age and gender.
- Authorized Roles: Casting Director, Executive Producer.
- Required permission: post:actors
- Sample:
curl -X POST http://127.0.0.1:5000/actors -H "Content-Type: application/json" -H "Authorization: Bearer ACCESS_TOKEN" -d '{"name": "Brad Pitt", "gender": "male", "age": 65}'
{
"actor": {
"age": 65,
"gender": "male",
"id": 6,
"name": "Brad Pitt"
},
"success": true
}
- General:
- Patches the actor data if it exists. Returns the id of the actor and success value.
- Authorized Roles: Casting Director, Executive Producer.
- Required permission: patch:actors
- Sample:
curl -X PATCH http://127.0.0.1:5000/actors/6 -H "Content-Type: application/json" -H "Authorization: Bearer ACCESS_TOKEN" -d '{"name": "Brad Pitt BP", "gender": "male" , "age": 55}'
{
"actor": [
{
"age": 55,
"gender": "male",
"id": 6,
"name": "Brad Pitt BP"
}
],
"success": true
}
- General:
- Deletes the actor with the specified ID if it exists. Returns the id of the deleted actor and success value.
- Authorized Roles: Casting Director, Executive Producer
- Required permission: delete:actors
- Sample:
curl -X DELETE http://127.0.0.1:5000/actors/6 -H "Authorization: Bearer ACCESS_TOKEN"
{
"delete": 6,
"success": true
}
- From within the project directory first ensure you are working using your created virtual environment.
- Run the setup file to create the environment variables (if not already run in the precceding section).
- Note: The
setup.sh
will export TEST_DATABASE_URL, Test JWT token for each user as environment variables.
source setup.sh
Run the unittest using below command
python test_app.py
The Application is deployed on Heroku and can be accessed via the link
Create an account with Heroku here and then we need to download the Heroku CLI (Command Line Interface) in order to run commands from the terminal that enable us to create a Heroku application and manage it.
Create your Heroku app
heroku create name_of_your_app
Add git remote for Heroku to local repository
git remote add heroku heroku_git_url
Add postgresql add on for our database
heroku addons:create heroku-postgresql:hobby-dev --app name_of_your_application
Go to your Heroku Dashboard and access your application's settings. Reveal your config variables and start adding all the required environment variables for your project
git push heroku main
Once your app is deployed, run migrations:
heroku run python manage.py db upgrade --app name_of_your_application
heroku logs --tail
On Heroku Dashboard, go to your project and click on Open app. Note: The deployed app for this project is available at the below link: https://udacity-casting-agency-app.herokuapp.com/
Author name: Sayantani Chaudhuri