Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Expense Tracker API

A small FastAPI service for logging expenses in multiple currencies and computing their total converted into a single base currency using live exchange rates.

Built as a clean, self-contained REST API demonstrating request validation, SQLite persistence, external API integration, and proper error handling.

Features

  • Log expenses with amount, currency, category, and date
  • Automatic input validation (rejects non-positive amounts, malformed dates)
  • Persistent storage via SQLite (survives restarts)
  • Convert and total all expenses into any base currency using live rates from the Frankfurter API
  • Gracefully skips unknown/unsupported currencies and reports them
  • Delete expenses by ID with proper 404 handling

Tech stack

  • FastAPI — web framework
  • Pydantic — request validation
  • SQLite (sqlite3) — persistence
  • httpx — async HTTP client for the exchange-rate API

Setup

python3 -m venv venv
source venv/bin/activate        # Windows: venv\Scripts\activate
pip install -r requirements.txt
uvicorn main:app --reload

The API runs at http://localhost:8000. Interactive docs at http://localhost:8000/docs.

Endpoints

Method Path Description
GET / Health check
POST /expenses Log a new expense
GET /expenses List all expenses
GET /expenses/total Total all expenses in a base currency (default USD)
DELETE /expenses/{expense_id} Delete an expense by ID

Example: log an expense

curl -X POST http://localhost:8000/expenses \
  -H "Content-Type: application/json" \
  -d '{"amount": 45.50, "currency": "USD", "category": "food", "date": "2026-07-25"}'

Example: get the total in EUR

curl "http://localhost:8000/expenses/total?base_currency=EUR"

Response:

{
  "base_currency": "EUR",
  "total": 123.45,
  "expenses_count": 7,
  "skipped": []
}

Running tests

The test suite uses pytest, with an isolated temporary database per test and a mocked exchange-rate API (so tests run offline and produce deterministic totals).

pip install -r requirements.txt
python -m pytest tests/ -v

Notes

  • Currency codes are normalized to uppercase on input.
  • The exchange-rate lookup makes a single API call per total request, regardless of how many expenses or currencies are involved.
  • The SQLite database file (expenses.db) is created automatically on first run and is excluded from version control.

About

A small FastAPI service for logging expenses in multiple currencies and computing their total converted into a single base currency using live exchange rates. Built as a clean, self-contained REST API demonstrating request validation, SQLite persistence, external API integration, and proper error handling.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages