Skip to content
mohdmuqsithPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Task API

Description

A CRUD Task API built with FastAPI, Postgres, Docker Compose, and Redis.

The public API stayed the same:

  • GET /tasks
  • GET /tasks/{task_id}
  • POST /tasks
  • PUT /tasks/{task_id}
  • DELETE /tasks/{task_id}

The storage implementation changed from local SQLite code in main.py to a Postgres repository in repositories.py. The routes still expose the same URLs and request bodies, while the SQL-specific code lives behind TaskService.

Architecture

Client -> FastAPI routes -> TaskService -> PostgresTaskRepository -> Postgres

Redis is included as an optional stretch service. The app pings Redis from /health, but tasks are stored only in Postgres.

Environment

Copy .env.example to .env before running locally:

cp .env.example .env

The app reads:

DATABASE_URL=postgresql://task_user:task_password@db:5432/task_api
REDIS_URL=redis://redis:6379/0

.env is gitignored. .env.example is committed so other developers know which settings are required.

Database

Postgres runs in Docker with a named volume:

postgres_data

That volume keeps the database data after containers restart.

The table is created by init.sql:

CREATE TABLE IF NOT EXISTS tasks (
    id SERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    done BOOLEAN NOT NULL DEFAULT FALSE
);

An index is also included for the optional stretch:

CREATE INDEX IF NOT EXISTS idx_tasks_done ON tasks (done);

Run The Whole Stack

Start the app, Postgres, and Redis together:

docker compose up --build

The API will run at:

http://localhost:8000

Swagger docs:

http://localhost:8000/docs

Stop the stack without deleting the database volume:

docker compose down

Delete the database volume only when you intentionally want to reset all data:

docker compose down -v

Endpoints

Method Endpoint Description
GET / API information
GET /health Health check for app, database, and Redis
GET /tasks Get all tasks
GET /tasks/{task_id} Get one task
POST /tasks Create a task
PUT /tasks/{task_id} Update a task
DELETE /tasks/{task_id} Delete a task

Example Requests

Create a task:

curl -i -X POST http://localhost:8000/tasks \
  -H "Content-Type: application/json" \
  -d "{\"title\":\"Persist through Docker restart\"}"

PowerShell:

Invoke-WebRequest -UseBasicParsing `
  -Uri "http://localhost:8000/tasks" `
  -Method POST `
  -ContentType "application/json" `
  -Body '{"title":"Persist through Docker restart"}'

List tasks:

curl http://localhost:8000/tasks

Prove Persistence

Use this flow to prove persistence:

  1. Start the stack with docker compose up --build.
  2. Create a task through POST /tasks.
  3. Stop the stack with docker compose down.
  4. Start it again with docker compose up.
  5. Run GET /tasks and confirm the task is still present.

The data survives because Postgres stores it in the Docker volume named postgres_data.

Example SQL Queries

Open a SQL shell inside the Postgres container:

docker compose exec db psql -U task_user -d task_api

List every task:

SELECT * FROM tasks;

Show only completed tasks:

SELECT * FROM tasks WHERE done = TRUE;

Count all tasks:

SELECT COUNT(*) FROM tasks;

Show the query plan that can use the done index:

EXPLAIN ANALYZE SELECT * FROM tasks WHERE done = TRUE;

Screenshots

Swagger:

Swagger UI

Previous SQLite database viewer from the earlier assignment:

Database viewer

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages