Skip to content

ramon-bernardo/task-vault

Repository files navigation

Build Test Format Lint Release Typos Python License: MIT

Task Vault

A RESTful API built with FastAPI for managing personal tasks, with JWT-based authentication and full user isolation.

Technology Stack

Library Version Purpose
FastAPI ≥ 0.111.0 Web framework
SQLAlchemy 2.0+ ORM
Alembic ≥ 1.13.0 Database migrations
Pydantic ≥ 2.7.0 Data validation
python-jose ≥ 3.3.0 JWT tokens
bcrypt Password hashing
Uvicorn ≥ 0.29.0 ASGI server
pytest ≥ 8.2.0 Testing
Ruff ≥ 0.4.4 Linting
Black ≥ 24.4.2 Formatting

Architecture

The project follows a layered architecture with clear separation of concerns:

app/
├── core/          # Config, database, security, dependency injection
├── models/        # SQLAlchemy ORM entities
├── repositories/  # Data access layer (CRUD)
├── services/      # Business logic and validation
├── schemas/       # Pydantic request/response models
└── routers/       # HTTP endpoints

Each layer depends only on the layer below it. Routers call services, services call repositories, repositories talk to the database.

Getting Started

Prerequisites

  • Python 3.14+
  • PostgreSQL

Setup

# Clone the repository
git clone https://github.com/ramon-bernardo/task-vault.git
cd task-vault

# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt

# Configure environment variables
cp .env.example .env
# Edit .env with your database URL and secret key

# Run database migrations
alembic upgrade head

# Start the server
uvicorn app.main:app --reload

The API will be available at http://localhost:8000. Interactive docs at http://localhost:8000/docs.

API Operations

Health

Method Endpoint Description
GET / Health check

Auth

Method Endpoint Description
POST /auth/register Register a new user
POST /auth/login Login and obtain a JWT token

RegisterPOST /auth/register

{
  "email": "[email protected]",
  "password": "strongpassword"
}

LoginPOST /auth/login

Content-Type: application/x-www-form-urlencoded

[email protected]&password=strongpassword

Response:

{
  "access_token": "<jwt>",
  "token_type": "bearer"
}

Tasks

All task endpoints require an Authorization: Bearer <token> header.

Method Endpoint Description
GET /tasks List tasks (paginated via skip / limit)
POST /tasks Create a task
GET /tasks/{id} Get a task by ID
PATCH /tasks/{id} Partially update a task
DELETE /tasks/{id} Delete a task

Create TaskPOST /tasks

{
  "title": "Buy groceries",
  "description": "Milk, eggs, bread"
}

Update TaskPATCH /tasks/{id}

All fields are optional:

{
  "title": "Buy groceries",
  "description": "Milk, eggs, bread, butter",
  "done": true
}

Error Handling

The API returns standard HTTP status codes with a JSON detail message:

Status Meaning
400 Validation error
401 Missing or invalid credentials
403 Authenticated but not the task owner
404 Resource not found
409 Conflict (duplicate email or task title)
422 Unprocessable entity (request body schema error)

Example error response:

{
  "detail": "Task not found"
}

Testing

Tests use an in-memory SQLite database so no external database is required.

pytest

The test suite covers:

  • Auth: registration, login, duplicate email handling
  • Tasks: full CRUD, ownership enforcement, pagination, task isolation between users

Postman

A Postman collection is available at Postman/Collection.json.

Import it into Postman, set base_url to http://localhost:8000, and run the Login request first — the collection's test script automatically saves the JWT token to the access_token variable for all subsequent requests.

License

This project is licensed under the MIT License.

About

A personal task manager with user authentication

Topics

Resources

License

Stars

Watchers

Forks