59 lines
2.5 KiB
Markdown
59 lines
2.5 KiB
Markdown
# Task API
|
||
|
||
A containerized FastAPI task REST API backed by PostgreSQL and SQLAlchemy.
|
||
|
||
## Quick start
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
docker compose up --build
|
||
curl http://localhost:8000/health
|
||
```
|
||
|
||
The API is available at `http://localhost:8000`; interactive OpenAPI docs are at `/docs`.
|
||
|
||
For local development, create a virtual environment and run:
|
||
|
||
```bash
|
||
pip install -r requirements.txt
|
||
uvicorn app.main:app --reload
|
||
pytest -q
|
||
```
|
||
|
||
The default local database URL is PostgreSQL. Tests override the database dependency with isolated SQLite databases, so no database server is required for the test suite.
|
||
|
||
## Configuration
|
||
|
||
| Variable | Default | Description |
|
||
|---|---|---|
|
||
| `DATABASE_URL` | `postgresql+psycopg2://tasks:tasks@db:5432/tasks` | SQLAlchemy database URL |
|
||
| `APP_NAME` | `Task API` | API display name |
|
||
| `LOG_LEVEL` | `INFO` | Uvicorn log level |
|
||
|
||
Do not commit production secrets. The Compose database uses the `POSTGRES_*` variables from `.env` and persists data in the `postgres_data` volume.
|
||
|
||
## API contract
|
||
|
||
Tasks have a UUID `id`, required `title` (1–200 characters), optional `description` (maximum 5000), `status` (`pending`, `in_progress`, or `completed`), optional timezone-aware `due_at`, and server-managed UTC `created_at` and `updated_at` timestamps.
|
||
|
||
- `POST /tasks` — create; returns `201`
|
||
- `GET /tasks` — list, with optional `status`, `skip`, and `limit`; returns `200`
|
||
- `GET /tasks/{id}` — fetch; returns `200`, or `404` if absent
|
||
- `PATCH /tasks/{id}` — partial update; returns `200`, or `404`
|
||
- `DELETE /tasks/{id}` — delete; returns `204`, or `404`
|
||
- `GET /health` — database-backed readiness check; returns `200` or `503`
|
||
|
||
Invalid JSON, fields, UUIDs, or query parameters return a structured `422` response:
|
||
|
||
```json
|
||
{"error":{"code":"VALIDATION_ERROR","message":"Request validation failed","details":[...]}}
|
||
```
|
||
|
||
Not-found and database failures use the same envelope with codes `TASK_NOT_FOUND` and `DATABASE_ERROR`. The API does not expose database internals.
|
||
|
||
## Operations
|
||
|
||
`docker compose up --build` waits for the PostgreSQL health check before starting the API. On startup the API calls `Base.metadata.create_all`; this is convenient for this small service. For production, replace it with reviewed Alembic migrations before deploying schema changes. `docker compose down` preserves data; `docker compose down -v` removes the database volume.
|
||
|
||
Run `pytest -q` for CRUD, validation, status semantics, error envelopes, and persistence-isolation coverage.
|