A structured E-commerce REST API built to be the foundational backbone of a production-grade web app. Dev for hosting & new features such as a cart & payment is still ongoing.
Table of Contents
This project is the Capstone Project for the Udacity Full-Stack Web Developer Nanodegree program. The purpose of this REST API is to develop a template for the creation of custom modern E-commerce websites.
A list of helpful resources are listed in the acknowledgements.
- Python-3.7.9
- Flask
- PostgreSQL
- SQLAlchemy
- Auth0
- Heroku Backend Deployment
- Netlify Frontend Deployment
- Postman
- Next.js
Follow the instructions to install Python 3.7.9 for your platform in the python docs
Follow the instructions to install PostgreSQL locally for your platform on the PostgreSQL website
It is recommended to work within a virtual environment using venv for this project. This keeps dependencies organized for each project. Instructions for setting this up can be found here
Once the virtual environment is setup and running, install the pip dependencies by navigating to the root directory of the project and running:
pip3 install -r requirements.txt
This will install all required packages that are used for the Flask backend.
Follow the instructions to install npm
at the following
link
While in the root directory of the project, run the following:
npm install
This will install the node-modules
needed by referencing the package.json
file.
To set up Auth0 for this project, refer to the following steps:
- Sign up for a free account on the Auth0 website.
- Next, create a new single-page application with the name Flask-Ecommerce.
- In Application settings, input your root URL to Allowed Callback URLs,
Allowed Logout URLs, and Allowed
Web Origins. For example:
a.http://localhost:3000
on all of the above for local hosting, or
b.https://HEROKU_APP_NAME.herokuapp.com
for your Heroku deployment. - Create an API in Auth0 with
RBAC
andAdd Permissions in the Access Token
enabled in the API settings. - In the API's
Permissions
tab, add the following permissions:
Permission | Description |
---|---|
post:products | Adds new products |
patch:products | Edits products |
delete:products | Deletes products |
- Finally, add the
Role
of Admin to the API that has all of the above permissions. AddUsers
with the Admin role in order for them to be authenticated to use the above HTTP requests.
- Admin: This role includes permissions for all endpoints in the Table of
Endpoints, as well as the
POST
,PATCH
, &DELETE
requests shown above inStep 5
. - Public: This role includes only
GET
request permissions, as this will be for the users of the world to use. This role excludes any rights to manipulating the PostgreSQL database.
Create 2 .env
files in the following locations following the .env.example
file format:
- In the directory
/backend/src
and - in the root directory.
NOTE: These environment variables will need to be added to the
Configure Vars
Settings on your Heroku deployment app if using Heroku.
Currently, the Frontend is still in development, but the Backend REST API can be used/tested with Postman.
The preferred way to test the backend HTTP requests are to use Postman,
however, the Python Unittest file is included in /backend/src
folder and is
titled test_app.py
.
Refer to the documentation within the Postman Collection for details regarding setup.
NOTE: A JWT access token is needed for Postman testing. The JWT token must be from an authenticated user with the role of
Admin
, which has all the necessary permissions.
The Python Unittest is located in the /backend
folder titled test_app.py
.
Run the tests following these steps:
-
Run the Flask server from the
/backend/src
directory virtual environment using these terminal bash commands:# This will run the flask app on port 5000 # On Linux: use `export` # On Windows: use `set` export FLASK_APP=app.py export FLASK_ENV=development flask run
-
Now that the Flask server is running locally, the python unit tests can be run with:
python3 test_app.py
- Base URL: The backend can only be run locally or viewed at the URL:
https://flask-ecommerce-rest-api.herokuapp.com/. When running locally, the backend app is
hosted at the default URL, http://127.0.0.1:5000/, which is set as a proxy in
the frontend configuration. This is the domain which must be used when making
API requests via
postman
orcurl
. - Authentication: This version of the application does not require authentication or API keys.
Errors are returned as JSON objects in the following format:
{
"success": False,
"error": 400,
"message": "bad request"
}
The API will return the five error type default responses when requests fail (unless custom response is assigned):
- 400: Bad Request
- 401: Unauthorized
- 403: Forbidden
- 404: Resource Not Found
- 422: Not Processable
- 500: Internal Server Error
Below is a table of the methods allowed for each of the 3 endpoints.
Endpoints | Methods | |||
---|---|---|---|---|
GET | POST | PATCH | DELETE | |
/ | X | |||
/collections | X | |||
/collections/category_id | X | |||
/collections/mens-apparel | X | |||
/collections/mens-apparel/product_id | X | |||
/collections/womens-apparel | X | |||
/collections/womens-apparel/product_id | X | |||
/collections/holiday | X | |||
/collections/holiday/product_id | X | |||
/collections/misc | X | |||
/collections/misc/product_id | X | |||
/products | X | X | X | X |
/products/product_id | X |
- Collections:
- GET /collections
- GET /collections/category_id
- GET /collections/mens-apparel
- GET /collections/mens-apparel/product_id
- GET /collections/womens-apparel
- GET /collections/womens-apparel/product_id
- GET /collections/holiday
- GET /collections/holiday/product_id
- GET /collections/misc
- GET /collections/misc/product_id
- Products:
- Index:
Retrieves category collections from database:
$ curl -X GET http://127.0.0.1:5000/collections
{
"category_info": [
{
"active": true,
"category_name": "Mens-Apparel",
"description": "This category is for mens apparel",
"id": 1,
"picture": "static/images/categories/mens_apparel"
},
{
"active": true,
"category_name": "Womens-Apparel",
"description": "This category is for womens apparel",
"id": 2,
"picture": "static/images/categories/womens_apparel"
},
{
"active": true,
"category_name": "Holiday",
"description": "This category is for holiday items",
"id": 3,
"picture": "static/images/categories/holiday"
},
{
"active": true,
"category_name": "Misc",
"description": "This category is for miscellaneous items",
"id": 4,
"picture": "static/images/categories/misc"
}
],
"success": true
}
Retrieves specific category collection from database:
$ curl -X GET http://127.0.0.1:5000/collections/1
{
"category_info": {
"active": true,
"category_name": "Mens-Apparel",
"description": "This category is for mens apparel",
"id": 1,
"picture": "static/images/categories/mens_apparel"
},
"success": true
}
Retrieves mens-apparel collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/mens-apparel
{{
"mens_apparel_data": [
{
"category_id": [
1
],
"id": 1,
"msrp": 25.0,
"picture": "static/images/products/1",
"product_description": "This is a tapered mens summer blue t-shirt.",
"product_name": "Mens Summer Blue Tee"
},
{
"category_id": [
1,
3
],
"id": 3,
"msrp": 40.0,
"picture": "static/images/products/3",
"product_description": "This is a husky red mens holiday sweater.",
"product_name": "Mens Holiday Sweater"
},
{
"category_id": [
1,
2,
3,
4
],
"id": 4,
"msrp": 12.0,
"picture": "static/images/products/4",
"product_description": "This is a pair of black holiday unisex socks.",
"product_name": "Holiday Unisex Socks"
}
],
"success": true
}
Retrieves specific mens-apparel collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/mens-apparel/1
{
"mens_apparel_data": {
"category_id": [
1
],
"id": 1,
"msrp": 25.0,
"picture": "static/images/products/1",
"product_description": "This is a tapered mens summer blue t-shirt.",
"product_name": "Mens Summer Blue Tee"
},
"success": true
}
Retrieves womens-apparel collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/womens-apparel
{
"success": true,
"womens_apparel_data": [
{
"category_id": [
2
],
"id": 2,
"msrp": 40.0,
"picture": "static/images/products/2",
"product_description": "This is a white wool womens sweater",
"product_name": "Womens Sweater"
},
{
"category_id": [
1,
2,
3,
4
],
"id": 4,
"msrp": 12.0,
"picture": "static/images/products/4",
"product_description": "This is a pair of black holiday unisex socks.",
"product_name": "Holiday Unisex Socks"
},
{
"category_id": [
2,
4
],
"id": 5,
"msrp": 120.0,
"picture": "static/images/products/5",
"product_description": "This is a womens watch in gold.",
"product_name": "Womens Watch"
}
]
}
Retrieves specific womens-apparel collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/womens-apparel/2
{
"success": true,
"womens_apparel_data": {
"category_id": [
2
],
"id": 2,
"msrp": 40.0,
"picture": "static/images/products/2",
"product_description": "This is a white wool womens sweater",
"product_name": "Womens Sweater"
}
}
Retrieves holiday collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/holiday
{
"holiday_products_data": [
{
"category_id": [
1,
3
],
"id": 3,
"msrp": 40.0,
"picture": "static/images/products/3",
"product_description": "This is a husky red mens holiday sweater.",
"product_name": "Mens Holiday Sweater"
},
{
"category_id": [
1,
2,
3,
4
],
"id": 4,
"msrp": 12.0,
"picture": "static/images/products/4",
"product_description": "This is a pair of black holiday unisex socks.",
"product_name": "Holiday Unisex Socks"
}
],
"success": true
}
Retrieves specific holiday collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/holiday/3
{
"holiday_products_data": {
"category_id": [
1,
3
],
"id": 3,
"msrp": 40.0,
"picture": "static/images/products/3",
"product_description": "This is a husky red mens holiday sweater.",
"product_name": "Mens Holiday Sweater"
},
"success": true
}
Retrieves miscellaneous collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/misc
{
"misc_products_data": [
{
"category_id": [
1,
2,
3,
4
],
"id": 4,
"msrp": 12.0,
"picture": "static/images/products/4",
"product_description": "This is a pair of black holiday unisex socks.",
"product_name": "Holiday Unisex Socks"
},
{
"category_id": [
2,
4
],
"id": 5,
"msrp": 120.0,
"picture": "static/images/products/5",
"product_description": "This is a womens watch in gold.",
"product_name": "Womens Watch"
}
],
"success": true
}
Retrieves specific miscellaneous collection of products from database:
$ curl -X GET http://127.0.0.1:5000/collections/misc/4
{
"misc_products_data": {
"category_id": [
1,
2,
3,
4
],
"id": 4,
"msrp": 12.0,
"picture": "static/images/products/4",
"product_description": "This is a pair of black holiday unisex socks.",
"product_name": "Holiday Unisex Socks"
},
"success": true
}
Retrieves all products from database:
$ curl -X GET http://127.0.0.1:5000/products
{
"products": [
{
"category_id": [
1
],
"id": 1,
"msrp": 25.0,
"picture": "static/images/products/1",
"product_description": "This is a tapered mens summer blue t-shirt.",
"product_name": "Mens Summer Blue Tee"
},
{
"category_id": [
2
],
"id": 2,
"msrp": 40.0,
"picture": "static/images/products/2",
"product_description": "This is a white wool womens sweater",
"product_name": "Womens Sweater"
},
{
"category_id": [
1,
3
],
"id": 3,
"msrp": 40.0,
"picture": "static/images/products/3",
"product_description": "This is a husky red mens holiday sweater.",
"product_name": "Mens Holiday Sweater"
},
{
"category_id": [
1,
2,
3,
4
],
"id": 4,
"msrp": 12.0,
"picture": "static/images/products/4",
"product_description": "This is a pair of black holiday unisex socks.",
"product_name": "Holiday Unisex Socks"
},
{
"category_id": [
2,
4
],
"id": 5,
"msrp": 120.0,
"picture": "static/images/products/5",
"product_description": "This is a womens watch in gold.",
"product_name": "Womens Watch"
}
],
"success": true
}
Retrieves specific product from database:
$ curl -X GET http://127.0.0.1:5000/products/2
{
"products": {
"category_id": [
2
],
"id": 2,
"msrp": 40.0,
"picture": "static/images/products/2",
"product_description": "This is a white wool womens sweater",
"product_name": "Womens Sweater"
},
"success": true
}
Redirects you to the index.html
file for the frontend:
$ curl -X GET http://127.0.0.1:5000/
This will return the `index.html` file.
- Frontend will be developed further using React.js
- The /search endpoint will be implemented to work with the frontend
- Since the UI and Authentication for the frontend was created using Auth0's Sample Project, a new UI/UX will be designed in the future upon further learning the React.js Framework.
Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the Apache 2.0 License. See LICENSE
for more information.
Jonathan Gutierrez - [email protected]
Project Link: https://github.com/jonnyg23/flask-rest-ecommerce