Skip to content

uz9ai/a1

Repository files navigation

Task Management API

A production-ready Task Management API built with FastAPI, SQLModel, and PostgreSQL (Neon).

Demo

▶️ Watch demo video

Features

  • Full CRUD operations for tasks
  • Async database operations with SQLModel
  • Type-safe Pydantic schemas
  • Comprehensive test suite with pytest
  • Environment-based configuration

Tech Stack

  • Framework: FastAPI
  • Database: PostgreSQL (Neon cloud-hosted)
  • ORM: SQLModel
  • Testing: pytest + httpx
  • Async Driver: asyncpg

Project Structure

task-manager/
├── app/
│   ├── __init__.py
│   ├── config.py          # Settings and environment variables
│   ├── database.py        # Database engine and session setup
│   ├── models.py          # SQLModel database models
│   ├── schemas.py         # Pydantic request/response schemas
│   └── main.py            # FastAPI application and routes
├── tests/
│   ├── __init__.py
│   └── test_tasks.py      # CRUD endpoint tests
├── .env.example           # Environment template
├── requirements.txt       # Python dependencies
└── README.md              # This file

Prerequisites

  • Python 3.10+
  • PostgreSQL database (Neon cloud)
  • pip or uv package manager

Setup Instructions

1. Clone and Create Virtual Environment

# Create virtual environment
python -m venv venv
source venv/bin/activate  # Linux/Mac
# or
.\venv\Scripts\activate   # Windows

# Install dependencies
pip install -r requirements.txt

2. Configure Environment

Copy the example environment file and update with your Neon credentials:

cp .env.example .env

Edit .env with your Neon PostgreSQL credentials:

# Database (Neon PostgreSQL)
DATABASE_HOST=your-host.neon.tech
DATABASE_PORT=5432
DATABASE_NAME=neondb
DATABASE_USER=your-username
DATABASE_PASSWORD=your-password

Or use a single DATABASE_URL:

DATABASE_URL=postgresql+asyncpg://user:password@host:5432/database

3. Database Setup via SQLModel

SQLModel automatically creates tables based on your model definitions. The tables will be created when the application starts.

Task Table Schema:

CREATE TABLE tasks (
    id SERIAL PRIMARY KEY,
    task VARCHAR(255) NOT NULL,
    time_estimate INTEGER NULL
);

The SQLModel model definition (app/models.py):

from sqlmodel import SQLModel, Field

class Task(SQLModel, table=True):
    id: int | None = Field(default=None, primary_key=True)
    task: str = Field(max_length=255, nullable=False)
    time_estimate: int | None = Field(default=None, nullable=True)

4. Initialize Database Tables

You can initialize the database tables using one of these methods:

Option A: Run the application (auto-creates tables on startup)

uvicorn app.main:app --reload

Option B: Run the init script directly

# scripts/init_db.py
import asyncio
from app.database import engine
from app.models import SQLModel

async def init_db():
    async with engine.begin() as conn:
        await conn.run_sync(SQLModel.metadata.create_all)
    print("Database tables created successfully!")

if __name__ == "__main__":
    asyncio.run(init_db())
python scripts/init_db.py

5. Run the Application

# Development with auto-reload
uvicorn app.main:app --reload

# Production
uvicorn app.main:app --host 0.0.0.0 --port 8000

The API will be available at http://localhost:8000

6. API Documentation

Once running, access the interactive API docs:

API Endpoints

Method Endpoint Description
GET /tasks/ List all tasks
GET /tasks/{task_id} Get a single task
POST /tasks/ Create a new task
PUT /tasks/{task_id} Update a task
DELETE /tasks/{task_id} Delete a task

Example Requests

Create a task:

curl -X POST "http://localhost:8000/tasks/" \
  -H "Content-Type: application/json" \
  -d '{"task": "Complete project report", "time_estimate": 120}'

Response:

{
  "id": 1,
  "task": "Complete project report",
  "time_estimate": 120
}

List all tasks:

curl "http://localhost:8000/tasks/"

Update a task:

curl -X PUT "http://localhost:8000/tasks/1" \
  -H "Content-Type: application/json" \
  -d '{"task": "Updated task name", "time_estimate": 60}'

Delete a task:

curl -X DELETE "http://localhost:8000/tasks/1"

Running Tests

The project uses pytest for testing with async support.

Run all tests:

pytest -v

Run with coverage:

pytest --cov=app --cov-report=term-missing

Run specific test file:

pytest tests/test_tasks.py -v

Test fixtures

The test suite uses:

  • In-memory SQLite for fast testing (configured in tests/conftest.py)
  • Fresh database session per test
  • Automatic table creation before tests

Configuration

All configuration is managed through environment variables via Pydantic Settings:

Variable Description Default
DATABASE_HOST PostgreSQL host localhost
DATABASE_PORT PostgreSQL port 5432
DATABASE_NAME Database name tasks_db
DATABASE_USER Database username postgres
DATABASE_PASSWORD Database password -
DATABASE_URL Full connection URL (overrides individual settings) -
APP_HOST Application host 0.0.0.0
APP_PORT Application port 8000
APP_DEBUG Enable debug mode false

Neon PostgreSQL Setup

  1. Create a free account at Neon
  2. Create a new project
  3. Get your connection string from the dashboard
  4. Update your .env file with the credentials

Example Neon connection string:

postgresql+asyncpg://username:password@ep-xyz.us-east-1.aws.neon.tech/neondb?sslmode=require

Development

Code Style

The project follows Python and FastAPI best practices:

  • Type hints for all functions
  • Async/await for database operations
  • Pydantic v2 for validation
  • SQLModel for ORM

Adding New Features

  1. Define the model in app/models.py
  2. Create schemas in app/schemas.py
  3. Add endpoints in app/main.py
  4. Write tests in tests/test_tasks.py

License

MIT

Testing Custom Skills

Draft Email for boss Draft Email for friend Draft Email for self

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages