A simple Flask API for tracking lawn mowing income and expenses for tax purposes.
# Setup
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
# Run
python app.pyServer runs at http://localhost:5000.
Upload a CSV file containing transaction data.
curl -X POST http://localhost:5000/transactions \
-F "data=@data.csv"Response:
{
"message": "Transactions processed successfully",
"count": 2
}Get financial summary.
curl http://localhost:5000/reportResponse:
{
"gross-revenue": 75.00,
"expenses": 68.27,
"net-revenue": 6.73
}- Flask 3.0.0 - Web framework
- Marshmallow 3.20.1 - Validation
- Pytest 7.4.3 - Testing framework
summer-break/
├── app.py # Flask app initialization
├── controllers/ # HTTP request handlers
│ ├── transactions_controller.py # Transactions endpoint
│ └── report_controller.py # Report endpoint
├── models/ # Data models
│ └── transaction.py # Transaction class
├── storage/ # Data storage layer
│ └── transaction_store.py # In-memory storage
├── validators/ # Marshmallow schemas
│ └── transaction.py
├── services/ # Business logic
│ └── transaction_service.py
├── tests/ # Test suite
│ ├── conftest.py # Pytest fixtures
│ ├── controllers/ # Controller tests
│ ├── services/ # Service tests
│ └── validators/ # Validator tests
├── pytest.ini # Pytest configuration
└── requirements.txt
- Controllers - HTTP request/response handling (Flask Blueprints)
- Models - Data structures and domain entities
- Storage - Data persistence layer (in-memory storage)
- Validators - Input validation (Marshmallow)
- Services - Business logic (CSV processing, reports)
CSV → Marshmallow validates → Stored in memory (Python list)
Date, Type, Amount($), Memo
2020-07-01, Expense, 18.77, Gas
2020-07-04, Income, 40.00, 347 Woodrow
- Date: YYYY-MM-DD format
- Type: "Income" or "Expense"
- Amount: Positive number
- Memo: 1-200 characters
- Comments: Lines starting with
#are ignored
# Run all tests
pytest
# Run with verbose output
pytest -v
# Run specific test file
pytest tests/services/test_transaction_service.py
# Run specific test
pytest tests/controllers/test_transactions_controller.py::TestTransactionsController::test_post_transactions_success# Upload CSV file
curl -X POST http://localhost:5000/transactions \
-F "data=@data.csv"
# Get report
curl http://localhost:5000/report- In-memory storage: Simple Python list stores transactions
- File upload only: Accepts CSV files via multipart/form-data with 'data' field
- Streaming CSV processing: Handles large files without loading entire file into memory
- Decimal for currency: Uses Python's
Decimaltype to avoid floating-point precision issues - Schema reuse: Single Marshmallow schema instance for all CSV rows (better performance)
- Lenient CSV parsing: Skips invalid rows and collects all validation errors
- Marshmallow validation: Flask ecosystem standard for validation
- No persistence: Data is lost when server restarts (by design for MVP)
- No authentication
- No date filtering on reports
- Invalid rows silently skipped
- No CRUD for individual transactions
- Add persistence (SQLite/PostgreSQL) with Flask-Migrate for migrations
- Implement authentication (JWT) and authorization
- Add caching layer (Redis/Memcached) for reports and frequently accessed data
- Make API resilient with retry logic, circuit breakers, and rate limiting
- Add date range filtering and pagination to endpoints
- Support CRUD operations for individual transactions
- Add detailed financial reports (monthly/yearly summaries, category breakdowns)
- Generate PDF reports and export to CSV/Excel
- Add transaction search, filtering, and deduplication
- Implement CI/CD pipeline with testing and linting (GitHub Actions)
- Add API documentation (Swagger/OpenAPI)
- Dockerize application with docker-compose for deployment
- Add monitoring, logging, and health check endpoints
- Support transaction categories, tags, and recurring templates