Skip to content

ContentGardeningStudio/expenses-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

31 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“˜ Expense Tracker API

A simple and clean FastAPI backend for managing personal expenses with user authentication, category management, and comprehensive expense tracking.


✨ Features

  • πŸ” JWT Authentication - Secure user registration and login with Argon2 password hashing
  • πŸ‘€ User Management - User registration, authentication
  • πŸ“‚ Category Management - Create, list, and delete expense categories
  • πŸ’° Expense Tracking - Full CRUD operations for expenses with:
    • Multiple currency support (EUR, USD)
    • Pagination and filtering
    • Amount range queries
    • Category-based filtering
  • πŸ“Š Reporting - Summary views by category and month
  • πŸ”„ Optimistic Locking - Prevents concurrent update conflicts
  • βœ… Comprehensive Testing - Full test coverage with pytest
  • πŸ—„οΈ SQLite Database - Easy setup with SQLAlchemy ORM

πŸš€ Quick Start

Prerequisites

  • Python 3.12+
  • uv package manager

Installation

  1. Clone the repository
   git clone https://github.com/ContentGardeningStudio/expenses-api
   cd expenses-api
  1. Create virtual environment
   uv venv
   source .venv/bin/activate  # On Windows: .venv\Scripts\activate
  1. Install dependencies
   uv sync
  1. Run the application
   fastapi dev src/expenses_api/main.py
  1. Access the API

πŸ“‚ Project Structure

expenses-api/
β”œβ”€β”€ src/expenses_api/
β”‚   β”œβ”€β”€ main.py              # FastAPI application entry point
β”‚   β”œβ”€β”€ database.py          # Database configuration
β”‚   β”œβ”€β”€ models.py            # SQLAlchemy models
β”‚   β”œβ”€β”€ schemas.py           # Pydantic schemas
β”‚   β”œβ”€β”€ crud.py              # Database operations
β”‚   β”œβ”€β”€ security.py          # Authentication & password hashing
β”‚   β”œβ”€β”€ settings.py          # Configuration management
β”‚   β”œβ”€β”€ deps.py              # Dependency injection
β”‚   β”œβ”€β”€ seed.py              # Database seeding script
β”‚   └── routers/
β”‚       β”œβ”€β”€ auth.py          # Authentication endpoints
β”‚       β”œβ”€β”€ categories.py    # Category endpoints
β”‚       └── expenses.py      # Expense endpoints
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ conftest.py          # Test fixtures
β”‚   β”œβ”€β”€ test_crud.py         # CRUD logic tests
β”‚   └── test_routers.py      # API endpoint tests
β”œβ”€β”€ pyproject.toml           # Project dependencies
β”œβ”€β”€ README.md
└── CONTRIBUTING.md

πŸ”‘ Authentication

Register a New User

POST /auth/register
Content-Type: application/json

{
  "username": "johndoe",
  "password": "securepass123"
}

Login

POST /auth/token
Content-Type: application/x-www-form-urlencoded

username=johndoe&password=securepass123

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer"
}

Using the Token

Include the token in all protected endpoints:

Authorization: Bearer <your_access_token>

πŸ“‘ API Endpoints

Categories

Method Endpoint Description Auth Required
GET /categories List all categories βœ…
POST /categories Create a new category βœ…
DELETE /categories/{id} Delete a category βœ…

Create Category Example:

POST /categories
{
  "name": "Groceries"
}

Expenses

Method Endpoint Description Auth Required
GET /expenses List expenses (paginated) βœ…
GET /expenses/{id} Get expense by ID βœ…
POST /expenses Create a new expense βœ…
DELETE /expenses/{id} Delete an expense βœ…

Create Expense Example:

POST /expenses
{
  "category_id": 1,
  "amount": "125.50",
  "currency": "EUR",
  "name": "Weekly groceries"
}

List Expenses with Filters:

GET /expenses?page=1&size=20&category_id=1&min_amount=50&max_amount=200

Query Parameters:

  • page - Page number (default: 1)
  • size - Items per page (default: 50, max: 200)
  • category_id - Filter by category
  • min_amount - Minimum amount filter
  • max_amount - Maximum amount filter

πŸ§ͺ Testing

Run the test suite:

# Run all tests
pytest

# Run with coverage
pytest --cov=expenses_api

# Run specific test file
pytest tests/test_routers.py

# Run with verbose output
pytest -v

Test Coverage Includes:

  • βœ… User registration and authentication
  • βœ… JWT token generation and validation
  • βœ… Category CRUD operations
  • βœ… Expense CRUD operations
  • βœ… Pagination and filtering
  • βœ… Optimistic locking
  • βœ… Error handling
  • βœ… Database constraints

πŸ—„οΈ Database

Initialize Database

The database is automatically created on first run. Tables:

  • users - User accounts
  • categories - Expense categories
  • expenses - Expense records

Seed Sample Data

python -m expenses_api.seed

This creates:

  • 15 random categories
  • 200 sample expenses

βš™οΈ Configuration

Create a .env file in the project root:

# Database
DATABASE_URL=sqlite:///./expenses.db

# Security
SECRET_KEY=your-secret-key-change-this-in-production
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=30

# Debug
DEBUG=True

πŸ› οΈ Tech Stack

Technology Purpose
FastAPI Modern web framework
SQLAlchemy ORM for database operations
Pydantic Data validation
Argon2 Password hashing
Python-JOSE JWT token handling
Pytest Testing framework
UV Fast dependency management
SQLite Lightweight database

πŸ—ΊοΈ Roadmap

βœ… Phase 1 - Foundations (DONE)

  • Base project structure
  • User authentication
  • Categories & expenses CRUD
  • Database initialization
  • Comprehensive tests

πŸ”œ Phase 2 - Stability

  • Custom error handling
  • Enhanced validation rules
  • Advanced pagination
  • Structured logging
  • Environment configuration

🚧 Phase 3 - Features

  • Date range filtering
  • Monthly/yearly reports
  • Soft delete functionality
  • CSV/Excel export
  • Expense summaries

πŸ” Phase 4 - Multi-tenancy

  • User-specific data isolation
  • Role-based permissions
  • User β†’ Categories β†’ Expenses hierarchy

πŸ“¦ Phase 5 - Deployment

  • Docker containerization
  • Production server setup (Gunicorn + Uvicorn)
  • Cloud deployment (Railway, Render, Fly.io)
  • CI/CD pipeline

🀝 Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

Steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is open source and available under the MIT License.


πŸ‘¨β€πŸ’» Author

Leonel Noan
Email: leonelnoan@contentgardening.com


πŸ™ Acknowledgments

  • FastAPI for the excellent framework
  • SQLAlchemy for robust ORM capabilities
  • The Python community for amazing tools

πŸ“ž Support


Happy expense tracking! πŸ’°πŸ“Š

About

Minimal expenses tracker with categories

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages