Perga API
Personal organizer backend that provides the core functionality for the Perga system.
Overview
Perga API is a FastAPI-based backend that powers the Perga personal organizer. It exposes REST API consumed by the standalone web client Perga Web.
Features
- Daily planner
- Monthly and custom agendas
- RESTful API with FastAPI
- User authentication with JWT tokens
- Interactive docs (Swagger UI / ReDoc)
Demo and Documentation
Tech Stack
- FastAPI
- SQLAlchemy
- Alembic
- PostgreSQL
- Pydantic Settings
- JWT-based auth
- Pytest
Requirements
- Python 3.10+
- PostgreSQL 15+
Installation (local)
- Clone and enter the repo
git clone https://github.com/dbtiunov/perga-api.git
cd perga-api
- 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
cp .env.example .env
# then edit .env
Important variables (from .env.example):
SECRET_KEY— any secure random stringPOSTGRES_HOST,POSTGRES_USER,POSTGRES_PASSWORD,POSTGRES_DBCORS_ORIGINS— JSON array of allowed origins (e.g. ["http://localhost:5173"])ROOT_URL_REDIRECT— optional URL to redirect/to (used by nginx demo)
- Run migrations
alembic upgrade head
- Start the app
uvicorn app.main:app --reload
- Base URL: http://localhost:8000
- Swagger UI: http://localhost:8000/docs
Docker
A Docker Compose setup is included. It runs:
db: PostgreSQL 15app: the FastAPI app (exposed on host port 8000)nginx: reverse proxy that serves the app on host port 8080
Start/stop:
docker-compose up -d
# ...
docker-compose down
Default ports and health:
- App direct: http://localhost:8000 (health:
GET /health/) - Via nginx: http://localhost:8080 (health inside nginx:
GET /health/)
API Documentation
- Swagger UI: http://localhost:8080/docs (via nginx) or http://localhost:8000/docs (direct)
API Endpoints (v1)
Authentication
POST /api/v1/auth/signup/— Register a new userPOST /api/v1/auth/access_token/— Get access token (form data)POST /api/v1/auth/access_token_json/— Get access token (JSON)POST /api/v1/auth/refresh_token/— Refresh access tokenGET /api/v1/auth/user/— Get current userPUT /api/v1/auth/user/— Update current userPUT /api/v1/auth/user/password/— Change password
Planner Days
GET /api/v1/planner/days/items/?days=YYYY-MM-DD&days=YYYY-MM-DD— Get items for multiple days; returns a dictionary keyed by date stringPOST /api/v1/planner/days/items/— Create a new day itemPUT /api/v1/planner/days/items/{item_id}/— Update a day itemDELETE /api/v1/planner/days/items/{item_id}/— Delete a day itemPOST /api/v1/planner/days/items/reorder/— Reorder items for a dayPOST /api/v1/planner/days/items/{item_id}/copy/— Copy a day item to another dayPOST /api/v1/planner/days/items/{item_id}/snooze/— Snooze a day item to another day
Agendas (monthly, custom, archived)
GET /api/v1/planner/agendas/?agenda_types=monthly&selected_day=YYYY-MM-DD&with_counts=false— List agendas (filters optional)POST /api/v1/planner/agendas/— Create an agendaPUT /api/v1/planner/agendas/{agenda_id}/— Update an agenda (including archive/unarchive)DELETE /api/v1/planner/agendas/{agenda_id}/— Delete an agendaPOST /api/v1/planner/agendas/reorder/— Reorder agendasPOST /api/v1/planner/agendas/{agenda_id}/action/— Perform an action on agenda (e.g., resolve monthly)
Agenda items:
GET /api/v1/planner/agendas/items/?agenda_ids=1&agenda_ids=2— Get items for multiple agendas; returns a dictionary keyed by agenda idPOST /api/v1/planner/agendas/items/— Create an agenda itemPUT /api/v1/planner/agendas/items/{item_id}/— Update an agenda itemDELETE /api/v1/planner/agendas/items/{item_id}/— Delete an agenda itemPOST /api/v1/planner/agendas/items/reorder/— Reorder items within an agendaPOST /api/v1/planner/agendas/items/{item_id}/copy/— Copy an item (optionally to another agenda)POST /api/v1/planner/agendas/items/{item_id}/move/— Move an item to another agenda
Development
Project Structure
app/api/— API endpoints and routerscore/— config, DBmodels/— SQLAlchemy modelsschemas/— Pydantic modelsservices/— business logictests/— test suite
Testing
python -m pytest
# or
python -m pytest app/tests/test_services/test_user_service.py
Database Migrations
./scripts/create_migration.sh <migration_name>
# then
alembic upgrade head
License
This project is licensed under the MIT License - see the LICENSE file for details.