The Points System API is a RESTful web application designed to track and manage points for users across different payers. The application allows adding points, spending points according to specific rules, and retrieving the current balance of points for each payer. Built with Flask, Python, and MongoDB, this API is lightweight, scalable, and easy to extend.
- Add Points: Add points for a specific payer at a given timestamp.
- Spend Points: Spend points using a "first-in, first-out" policy while ensuring no payer's balance goes negative.
- Get Balances: Retrieve the current point balance grouped by payer.
- Flask: Framework for building the RESTful API.
- Python: Handles business logic and validation.
- MongoDB: Stores transactions in a dynamic, JSON-like format for flexibility.
- pymongo: Integrates MongoDB with Python for data operations.
-
Clone the Repository:
git clone <repository-url> cd <repository-folder>
-
Set Up a Virtual Environment:
python3 -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install Dependencies:
pip install -r requirements.txt
-
Run the Application:
python app.py
The application will be available at http://127.0.0.1:8000/.
-
Root Endpoint:
-
URL:
/ -
Method:
GET -
Description: Verifies the API is running.
-
Response:
{"message": "Welcome to the Points System API! Ready to track your points"}
-
-
Add Points:
-
URL:
/add -
Method:
POST -
Payload:
{ "payer": "DANNON", "points": 5000, "timestamp": "2020-11-02T14:00:00Z" } -
Response:
- Success:
Transaction added successfully. - Error: Validation error messages with status
400.
- Success:
-
-
Spend Points:
-
URL:
/spend -
Method:
POST -
Payload:
{"points": 5000} -
Response:
[ {"payer": "DANNON", "points": -100}, {"payer": "UNILEVER", "points": -200} ]
-
-
Get Balances:
-
URL:
/balance -
Method:
GET -
Response:
{ "DANNON": 1000, "UNILEVER": 0, "MILLER COORS": 5300 }
-
To inspect the database and verify stored transactions, you can use MongoDB Compass:
-
Download and Install MongoDB Compass:
-
Connect to MongoDB:
- Open MongoDB Compass and connect to the local database using the connection string:
mongodb://localhost:27017/
- Open MongoDB Compass and connect to the local database using the connection string:
-
Navigate to the Database:
- Select the
points_systemdatabase and thetransactionscollection to view, update, or delete data manually.
- Select the
-
Verify Data:
- Check that transactions are added correctly when you test the
/addendpoint. - Confirm that points are deducted as expected when testing the
/spendendpoint.
- Check that transactions are added correctly when you test the
Using MongoDB Compass makes it easier to debug and understand how the API interacts with the database.
-
Test
/addEndpoint:-
File:
test_add_endpoint.py -
Run:
python test_add_endpoint.py
-
Tests adding valid and invalid transactions.
-
-
Test
/spendEndpoint:-
File:
test_spend_endpoint.py -
Run:
python test_spend_endpoint.py
-
Tests various spending scenarios, including edge cases.
-
Note: Make sure the database is empty ensuring accurate results.
Simulate the add_sample_transactions() function by sending the sample transactions:
curl -X POST http://localhost:8000/add \
-H "Content-Type: application/json" \
-d '{"payer": "DANNON", "points": 300, "timestamp": "2022-10-31T10:00:00Z"}'
curl -X POST http://localhost:8000/add \
-H "Content-Type: application/json" \
-d '{"payer": "UNILEVER", "points": 200, "timestamp": "2022-10-31T11:00:00Z"}'
curl -X POST http://localhost:8000/add \
-H "Content-Type: application/json" \
-d '{"payer": "MILLER COORS", "points": 10000, "timestamp": "2022-11-01T14:00:00Z"}'
curl -X POST http://localhost:8000/add \
-H "Content-Type: application/json" \
-d '{"payer": "DANNON", "points": 1000, "timestamp": "2022-11-02T14:00:00Z"}'Run curl commands for various scenarios to test the /spend endpoint:
-
Spend 5000 Points:
curl -X POST http://localhost:8000/spend \ -H "Content-Type: application/json" \ -d '{"points": 5000}'
-
Spend More Points Than Available (20000 Points):
curl -X POST http://localhost:8000/spend \ -H "Content-Type: application/json" \ -d '{"points": 20000}'
-
Spend a Small Valid Amount (100 Points):
curl -X POST http://localhost:8000/spend \ -H "Content-Type: application/json" \ -d '{"points": 100}'
-
Spend more number of points than available (10500 points):
curl -X POST http://localhost:8000/spend \ -H "Content-Type: application/json" \ -d '{"points": 10500}'
-
Spend Zero Points:
curl -X POST http://localhost:8000/spend \ -H "Content-Type: application/json" \ -d '{"points": 0}'
-
Spend Negative Points (Invalid Input):
curl -X POST http://localhost:8000/spend \ -H "Content-Type: application/json" \ -d '{"points": -100}'
-
Spend 6300 Points:
curl -X POST http://localhost:8000/spend \ -H "Content-Type: application/json" \ -d '{"points": 6300}'
-
Spend With Missing
PointsField:curl -X POST http://localhost:8000/spend \ -H "Content-Type: application/json" \ -d '{}'
-
Spend 100 Points:
curl -X POST http://localhost:8000/spend \ -H "Content-Type: application/json" \ -d '{"points": 100}'
After each test, use this command to verify the current balances:
curl -X GET http://localhost:8000/balanceThe project requires the following Python libraries:
- Flask==2.1.3
- pymongo==4.4.1
Install them using pip install -r requirements.txt.