This is the last project of the Udacity-Full-Stack-Nanodegree
Program.
It covers following technical topics in 1 app:
- Database modeling was done with
PostgreSQL
&SQLAlchemy
(see themodels.py
file) - An API that performs CRUD operations on database with the
Flask
Framework (see theapp.py
file) - There are also automated tests provided with
Unittest
(see thetest_app
file) - Authorization & Role based Authentification was made with the help of
Auth0
and its services (see theauth.py
file) - Final goal to deploy to
Heroku
platform.
To get started, make sure you cd
into the correct directory, where all files of the application are located. Then proceed with the following steps to set it up.
Please take into account that, in order to run successfully the project, you will need the latest version of Python 3
and PostgreSQL installed on your machine.
To start and run the local development server,
- Initialize and activate a virtualenv:
$ pipenv shell
- Install the dependencies:
$ pipenv run pip install -r requirements.txt
Please note that running this project locally means that it can´t access Herokus
env variables.
To fix this, you need to edit a few informations in config.py
, so it can
correctly connect to a local database
- Change database config so it can connect to your local postgres database
- Open
config.py
with your editor of choice. - Here you can see a global variable with the name
DATABASE_URI
:
DATABASE_URL = "postgres://postgres:george2016@localhost:5432/project"
Where the follow syntax is followed:
DATABASE_URL = "postgres://{username}:{password}@{host_and_port}/{database_name}"
- Just change
username
,password
andhost_and_port
to whatever you choose while installing postgres. However, make sure that you already have started the PostgreSQL server in your system and that you have created the corresponding database in your system .tip:
username
usually defaults topostgres
andport
always defaults tolocalhost:5432
while installing PostgreSQL, most of the time you just need to change thepassword
.
- Setup Auth0
If you only want to test the API (i.e. Project Reviewer), you can
simply use the existing bearer tokens located in the
config.py
file.
If you already know your way around Auth0
, just insert your own data
into the config.py
file.
FYI: Here are the steps I followed to enable authentification.
- (optional) Turn DEBUG mode on, which is included in the development environment:
$ export FLASK_ENV=development
- Run the development server on
http://localhost:5000/
:
$ flask run
- (optional) Execute the tests, to make sure everything works correctly:
$ python test_app.py
WARNING!
Before running tests in, please ensure that you have exported an environment variable DATABASE_URL
in your Command Prompt (CMD) or in your Terminal, and you have assigned it the value of your database URL just like in the config.py
file.
If you choose to run all tests, it should give this response, provided the fact that everything works correctly and as expected:
$ python test_app.py
.........................
Ran 25 tests in 15.235s
OK
In this part of the document you can find and explore all existing endpoints, which methods can be used, how to work with them & example responses you will get. Furthermore, you can find about common error status codes, and the message that return.
-
Base URL: https://udacity-fsnd-capstone-project.herokuapp.com/
-
Authentification: Please see API Authentification section for more information and details.
Both /movies
and /actors
endpoints come with all the common HTTP methods (GET
, POST
, DELETE
, PATCH
).
Click on a link to directly get to the ressource.
- Actors
- Movies
Each ressource documentation is clearly structured:
- Description in a few words
curl
example that can directly be used in terminal- More descriptive explanation of input & outputs.
- Required permission
- Example Response.
Errors are return as JSON format in the following format:
{
"success": False,
"error": 404,
"message": "Not found"
}
The API will return six (6) error types when a request fails:
- 400: Bad request
- 401: Permissions not found
- 403: Forbidden
- 404: Not found
- 422: Unprocessable entity
- 500: Internal server error
Query paginated actors.
$ curl -X GET https://udacity-fsnd-capstone-project.herokuapp.com/actors?page1
- Fetches a list of dictionaries of examples in which the keys are the ids with all available fields
- Request Arguments:
- integer
page
(10 actors per page)
- integer
- Request Headers: None
- Requires permission:
read:actors
- Returns:
- List of dict of actors with following attributes:
- integer
id
- string
name
- string
gender
- integer
age
- integer
- boolean
success
- List of dict of actors with following attributes:
{
"actors": [
{
"age": 25,
"gender": "John",
"id": 1,
"name": "Matthew"
}
],
"success": true
}
If you try fetch a page which does not have any actors, you will encounter an error which looks like this:
$ curl https://udacity-fsnd-capstone-project.herokuapp.com/actors?page123124
and it will return:
{
"error": 404,
"message": "Not found",
"success": false
}
Create a new actor and insert it into the database system.
$ curl -X POST https://udacity-fsnd-capstone-project.herokuapp.com/actors
- Request Arguments: None
- Request Headers: (application/json) 1. string
name
(required) 2. integerage
(required) 3. stringgender
- Requires permission:
create:actors
- Returns:
- integer
id from newly created actor
- boolean
success
- integer
{
"created": 5,
"success": true
}
If you try to create a new actor without a requiered field like name
,
and it will throw a 422
error:
$ curl https://udacity-fsnd-capstone-project.herokuapp.com/actors?page123124
will return
{
"error": 422,
"message": "Unprocessable entity",
"success": false
}
Edit an existing Actor
$ curl -X PATCH https://udacity-fsnd-capstone-project.herokuapp.com/actors/1
- Request Arguments: integer
id from actor you want to update
- Request Headers: (application/json) 1. string
name
2. integerage
3. stringgender
- Requires permission:
edit:actors
- Returns:
- integer
id from updated actor
- boolean
success
- List of dict of actors with following fields:
- integer
id
- string
name
- string
gender
- integer
age
- integer
- integer
{
"actor": [
{
"age": 27,
"gender": "Female",
"id": 1,
"name": "Michaella"
}
],
"success": true,
"updated": 1
}
If you try to update an actor with an invalid id, then it will throw an 404
error:
$ curl -X PATCH https://udacity-fsnd-capstone-project.herokuapp.com/actors/125
will return
{
"error": 404,
"message": "Not found",
"success": false
}
Additionally, trying to update an Actor with already existing field values will result in an 422
error:
{
"error": 422,
"message": "Unprocessable entity",
"success": false
}
Delete an existing Actor
$ curl -X DELETE https://udacity-fsnd-capstone-project.herokuapp.com/actors/1
- Request Arguments: integer
id from actor you want to delete
- Request Headers:
None
- Requires permission:
delete:actors
- Returns:
- integer
id from deleted actor
- boolean
success
- integer
{
"deleted": 5,
"success": true
}
If you try to delete actor with an invalid id, then it will throw an 404
error:
$ curl -X DELETE https://udacity-fsnd-capstone-project.herokuapp.com/actors/125
It will return
{
"error": 404,
"message": "Not found",
"success": false
}
Query paginated all movies in the database system.
$ curl https://udacity-fsnd-capstone-project.herokuapp.com/movies?page1
- Fetches a list of dictionaries of examples in which the keys are the ids with all available fields
- Request Arguments:
- integer
page
(optional, 10 movies per page, defaults to1
if not given)
- integer
- Request Headers: None
- Requires permission:
read:movies
- Returns:
- List of dict of movies with following fields:
- integer
id
- string
name
- date
release_date
- integer
- boolean
success
- List of dict of movies with following fields:
{
"movies": [
{
"id": 1,
"release_date": "Sun, 16 Feb 2020 00:00:00 GMT",
"title": "Matthew first Movie"
}
],
"success": true
}
If you try fetch a page which does not have any movies, you will encounter an error which looks like this:
$ curl https://udacity-fsnd-capstone-project.herokuapp.com/movies?page123124
It will return
{
"error": 404,
"message": "Not found",
"success": false
}
Create a new Movie into the database system.
$ curl https://udacity-fsnd-capstone-project.herokuapp.com/movies
- Request Arguments: None
- Request Headers: (application/json) 1. string
title
(required) 2. daterelease_date
(required) - Requires permission:
create:movies
- Returns:
- integer
id from newly created movie
- boolean
success
- integer
{
"created": 5,
"success": true
}
If you try to create a new movie without a requiered field like name
, then
it will throw a 422
error:
$ curl https://udacity-fsnd-capstone-project.herokuapp.com/movies?page123124
will return
{
"error": 422,
"message": "Unprocessable entity",
"success": false
}
Edit an existing Movie information.
$ curl -X PATCH https://udacity-fsnd-capstone-project.herokuapp.com/movies/1
- Request Arguments: integer
id from movie you want to update
- Request Headers: (application/json) 1. string
title
2. daterelease_date
- Requires permission:
edit:movies
- Returns:
- integer
id from updated movie
- boolean
success
- List of dict of movies with following fields:
- integer
id
- string
title
- date
release_date
- integer
- integer
{
"created": 1,
"movie": [
{
"id": 1,
"release_date": "Sun, 16 Feb 2020 00:00:00 GMT",
"title": "Solarity x500"
}
],
"success": true
}
If you try to update an movie with an invalid id, then it will throw an 404
error:
$ curl -X PATCH https://udacity-fsnd-capstone-project.herokuapp.com/movies/125
It will return
{
"error": 404,
"message": "Not found",
"success": false
}
Additionally, trying to update an Movie with already existing field values will result in an 422
error:
{
"error": 422,
"message": "Unprocessable entity",
"success": false
}
Delete an existing Movie.
$ curl -X DELETE https://udacity-fsnd-capstone-project.herokuapp.com/movies/1
- Request Arguments: integer
id from movie you want to delete
- Request Headers:
None
- Requires permission:
delete:movies
- Returns:
- integer
id from deleted movie
- boolean
success
- integer
{
"deleted": 5,
"success": true
}
If you try to delete movie with an invalid id, then it will throw an 404
error:
$ curl -X DELETE https://udacity-fsnd-capstone-project.herokuapp.com/movies/125
It will return
{
"error": 404,
"message": "Not found",
"success": false
}
All API Endpoints are decorated with Auth0 permissions. So, to use the project locally, you need to config Auth0 accordingly.
- Login to https://manage.auth0.com/
- Click on Applications Tab
- Create Application
- Give it a name like
Me
, or something else that you would like, and select "Regular Web Application" - Go to Settings and find
domain
. Copy & paste it intoconfig.py
=> AUTH0_DOMAIN=['AUTH0_DOMAIN'] (i.e. replace with"example-me.eu.auth0.com"
) - Click on API Tab
- Create a new API:
- Name:
Me
- Identifier
Me
- Keep Algorithm as it is
- Name:
- Go to Settings and find
Identifier
. Copy & paste it into config.py => API_AUDIENCE=['API_AUDIENCE'] (i.e. replace with"Me"
)
- Before creating
Roles & Permissions
, you need toEnable RBAC
in your API. To do that go to theAPI
section, click on yourAPI Name
, go to theSettings
tab and switch theEnable RBAC
togle to on and finallySave
those changes and the end of the page. - Also, check the button
Add Permissions in the Access Token
. - First, create a new Role under
Users and Roles
=>Roles
=>Create Roles
- Give it a descriptive name like
Casting Assistant
. - Go back to the API Tab and find your newly created API. Click on Permissions.
- Create & assign all needed permissions accordingly
- After you created all permissions this app needs, go back to
Users and Roles
=>Roles
and select the role you recently created. - Under
Permissions
, assign all permissions you want this role to have.
If you want to access the real, temporary API, bearer tokens for all 3 roles are included in the config.py
file.
They are 3 Roles with distinct permission sets:
- Casting Assistant:
- view:actors: Can see all actors
- view:movies: Can see all movies
- Casting Director (everything from Casting Assistant and)
- create:actors: Can create new Actors
- edit:actors: Can edit existing Actors
- delete:actors: Can remove existing Actors from database
- edit:movies: Can edit existing Movies
- Exectutive Dircector (everything from Casting Director and)
- create:movies: Can create new Movies
- delete:movies: Can remove existing Motives from database
In your API Calls, add them as Header, with Authorization
as key and the Bearer token
as value. Don´t forget to also
prepend Bearer
to the token (seperated by space).
For example: (Bearer token for Executive Director
)
{
"Authorization": "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InM2WDVjWXBzR3lFODlpdmkxUTk4XyJ9.eyJpc3MiOiJodHRwczovL2ZzbmQtcHJvamVjdC5ldS5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NWVhMzMxYTIzZTNiYzIwYzA0NTYzNTM0IiwiYXVkIjoiYXV0aCIsImlhdCI6MTU4Nzg0ODU3MSwiZXhwIjoxNTg3ODU1NzcxLCJhenAiOiJRTXo4N2cwQndsQVBFQVVnNXdwWUF0UVdtVHBrWGx4OCIsInNjb3BlIjoiIiwicGVybWlzc2lvbnMiOlsiY3JlYXRlOmFjdG9ycyIsImNyZWF0ZTptb3ZpZXMiLCJkZWxldGU6YWN0b3JzIiwiZGVsZXRlOm1vdmllcyIsImVkaXQ6YWN0b3JzIiwiZWRpdDptb3ZpZXMiLCJyZWFkOmFjdG9ycyIsInJlYWQ6bW92aWVzIl19.lpYrDvrLemHV34CXxmpezd-K8-lZShcm7p-wwQeeUJ6Rd_TyLB751CYhNWFr6MEuYu6CZncm9F0lqvVU-oHBzsJS4Xo3EXsRSAtZlPEcXexhQgJEDVPxdb7ICFgxkCMMxnZa90KLg4XMHOIHqIQPDO63vP8kwy6g9_RdeMEHB5udzRTDy95Jx7fb55gCIdTrbwfzmTrZvM1nQMV5j74IfrOnohXnu2yHev_Cr-pEaTvBAZ6D1UwfcOX4tmn4ryTWhGOkFdWYC65M-rM4jbwDXBWihim8N3p2PNaLyDTqzFryOD0CXkiJmK4ii3b0rnKbUTSIDzGDUT-jzyxkKNipig"
}