This is a proof of concept app of an online Video Club utilizing a RESTful API. Users can register/login and perform various requests in order to search, rent and pay for an online movie.
The app is built using Flask. It comprises three Docker containers included in Docker-Compose which is used to deploy the app. Gunicorn is used as a WSGI server and NGINX as a reverse proxy. Finally, PostgreSQL is used as database.
The app also utilizes JWT authentication. Thus, to use most request the user needs to use an appropriate token.
nginx
contains the configuration used by the nginx container
app
contains the source code of the flask app
tests
contains the unit tests
docker-compose.yml
contains instructions used to build and connect the containers
.env
contains environment variables that are passed to docker-compose
The dataset, located in app\API\dataset\tmdb_5000_movies.csv
was taken from
Kaggle. It contains ~5,000 movies and after appropriate
data cleaning and transformations, it is used to populate the database.
First, please use git clone to get a copy of the repo:
git clone https://github.com/orestislampridis/online-movies-rent-store.git
After ensuring you have the latest Docker version installed, enter the cloned dir and simply run:
docker-compose up --build -d
Go inside the tests dir and run the following:
pip install unittest
pip install requests
python test_unittest_api.py
The REST API to the app is documented in detail below.
Post http://127.0.0.1/create_user
{
"email": "[email protected]",
"password": "1234",
"first_name": "john",
"last_name": "marston"
}
HTTP 201 CREATED
{
"message": "User successfully created!",
"ok": true
}
HTTP 400 BAD REQUEST
{
"message": "Current email already exists!",
"ok": False
}
HTTP 400 BAD REQUEST
{
"message": "email and / or password is missing",
"ok": False
}
Post http://127.0.0.1/login
{
"email": "[email protected]",
"password": "1234"
}
HTTP 201 CREATED
{
"ok": true,
"token": "eJiOiOiJ1J9.ey1c22zh9.03Pbp-fbj7rZWPCy-rY2Da74FE"
}
HTTP 400 BAD REQUEST
{
"message": "email and / or password is missing",
"ok": False
}
HTTP 403 FORBIDDEN
{
"message": "Could not verify. Incorrect password given",
"ok": False
}
HTTP 404 NOT FOUND
{
"message": "User does not exist",
"ok": False
}
GET http://127.0.0.1/get_all_movie_titles
Key | Value | Description |
---|---|---|
x-access-token |
string |
Required. Your JWT token |
HTTP 200 OK
{
"movies": [
{
"movie_id": 0,
"title": "Avatar"
},
{
"movie_id": 1,
"title": "Pirates of the Caribbean: At World's End"
},
...
]
}
GET http://127.0.0.1/get_movies_by_category?category=History
Key | Value | Description |
---|---|---|
x-access-token |
string |
Required. Your JWT token |
Key | Value | Description |
---|---|---|
category |
string |
Category/genre of the movie |
HTTP 200 OK
{
"movies": [
{
"movie_id": 109,
"title": "Pearl Harbor"
},
{
"movie_id": 111,
"title": "Alexander"
},
...
]
}
HTTP 400 BAD REQUEST
{
"message": "Category parameter is missing",
"ok": False
}
HTTP 404 NOT FOUND
{
"message": "Genre does not exist",
"ok": False
}
GET http://127.0.0.1/navigate?title=Pulp+Fiction
Key | Value | Description |
---|---|---|
x-access-token |
string |
Required. Your JWT token |
Key | Value | Description |
---|---|---|
title |
string |
Title of the movie. Add '+' for spaces. |
HTTP 200 OK
{
"budget": "$8,000,000",
"genres": "Thriller,Crime",
"original_language": "en",
"original_title": "Pulp Fiction",
"overview": "A burger-loving hit man, his philosophical partner, ...
"popularity": 121.463076,
"release_date": "1994-10-08",
"revenue": "$213,928,762",
"runtime": "154 minutes",
"title": "Pulp Fiction",
"vote_average": 8.3,
"vote_count": 8428
}
HTTP 400 BAD REQUEST
{
"message": "Title parameter is missing",
"ok": False
}
HTTP 404 NOT FOUND
{
"message": "Movie does not exist",
"ok": False
}
POST http://127.0.0.1/rent
Key | Value | Description |
---|---|---|
x-access-token |
string |
Required. Your JWT token |
{
"title": "Pulp Fiction"
}
HTTP 200 OK
{
"message": "Pulp Fiction successfully rented!",
"ok": true
}
HTTP 400 BAD REQUEST
{
"message": "Body title is missing",
"ok": False
}
HTTP 400 BAD REQUEST
{
"message": "You are already renting this movie!",
"ok": False
}
HTTP 404 NOT FOUND
{
"message": "Movie does not exist",
"ok": False
}
POST http://127.0.0.1/return_movie
Key | Value | Description |
---|---|---|
x-access-token |
string |
Required. Your JWT token |
{
"title": "Pulp Fiction"
}
HTTP 200 OK
{
"message": "Pulp Fiction (rental id: 1) successfully returned!",
"ok": true
}
HTTP 400 BAD REQUEST
{
"message": "Body title is missing",
"ok": False
}
HTTP 404 NOT FOUND
{
"message": "You have not rented this movie!",
"ok": False
}
HTTP 404 NOT FOUND
{
"message": "Movie does not exist",
"ok": False
}
Note: Contains both paid and unpaid rentals
GET http://127.0.0.1/get_rentals
Key | Value | Description |
---|---|---|
x-access-token |
string |
Required. Your JWT token |
HTTP 200 OK
{
"rentals": [
{
"date_end": "Thu, 21 Apr 2022 00:00:00 GMT",
"date_start": "Thu, 21 Apr 2022 00:00:00 GMT",
"movie_id": 2573,
"paid": true,
"rental_id": 1,
"user_id": 1
},
...
]
}
Note: This is calculated by adding up the charge of all the movies the current user has not returned yet. The user is charged 1 euro per day for the first three days and 0,5 euro per day for the days after the first three.
GET http://127.0.0.1/get_charge
Key | Value | Description |
---|---|---|
x-access-token |
string |
Required. Your JWT token |
HTTP 200 OK
{
"charge": "€1.0"
}