diff --git a/architecture.md b/architecture.md index 378c485..c9e40fe 100644 --- a/architecture.md +++ b/architecture.md @@ -1,109 +1,54 @@ -# ARCHITECTURE.md — Micro-API +# Architecture — MicroAPI -## Overview +## Stack -Micro-API is the foundation service of the organization's micro-services platform. It provides a lightweight HTTP API designed to be deployed on a single VPS and scaled horizontally as needs grow. +| Couche | Technologie | Justification | +|---|---|---| +| Framework | FastAPI | Performant, async, documentation auto (Swagger) | +| Serveur | Uvicorn | ASGI, production-ready | +| Runtime | Python 3.11+ | Écosystème riche, gratuit | +| Base de données | SQLite (phase 1) | Zéro ops, migration vers PostgreSQL si besoin | +| Conteneurisation | Docker | Isolation, déploiement reproductible | +| Reverse proxy | Caddy (existant) | Routing, HTTPS | +| Paiements | Lemon Squeezy | MoR, 0€/mois, gère TVA | +| Emails | Resend (gratuit 3K/mois) | Transactionnel | +| Monitoring | Uptime Kuma (existant) | Health checks | -## Design Principles - -1. **Zero cost** — No paid services, no cloud dependencies. Runs on the existing VPS behind Traefik/Caddy. -2. **Simplicity first** — SQLite for local dev and single-node deploys. Postgres optional when multi-service. -3. **Containerized** — Every service ships as a Docker container, orchestrated via docker-compose. -4. **Stateless API** — Health-checkable, horizontally scalable behind a reverse proxy. -5. **Tested from day one** — pytest on every service before deploy. - -## System Architecture +## Structure des dossiers ``` -┌──────────────────────────────────────────┐ -│ VPS (82.165.176.5) │ -│ │ -│ ┌─────────┐ ┌──────────────────────┐ │ -│ │ Traefik │──▶│ micro-api:8000 │ │ -│ │ :443 │ │ (Docker container) │ │ -│ └─────────┘ │ FastAPI + Uvicorn │ │ -│ │ SQLite /data/ │ │ -│ └──────────────────────┘ │ -│ │ -│ ┌──────────────────────────────────┐ │ -│ │ Future services (API v2, ...) │ │ -│ └──────────────────────────────────┘ │ -└──────────────────────────────────────────┘ +micro-api/ +├── main.py # Application FastAPI +├── requirements.txt # Dépendances Python +├── Dockerfile # Image Docker +├── docker-compose.yml # Stack de déploiement +├── README.md # Documentation utilisateur +├── ARCHITECTURE.md # Ce document +├── tests/ # Tests unitaires & intégration +│ └── test_health.py +├── app/ # Code applicatif (à venir) +│ ├── routers/ # Endpoints API +│ ├── services/ # Logique métier (transcription, etc.) +│ ├── models/ # Modèles de données +│ └── utils/ # Utilitaires +└── data/ # Données persistantes (volumes) ``` -## Data Flow +## Principes -``` -Client ──HTTPS──▶ Traefik ──HTTP──▶ micro-api:8000 - │ - ▼ - SQLite (file) - /data/app.db -``` +1. **Stateless** — Chaque requête est indépendante, pas de session serveur +2. **Async-first** — Tous les endpoints sont async par défaut +3. **API-first** — Documentation Swagger automatique sur `/docs` +4. **12-factor** — Configuration par variables d'environnement +5. **Zéro coût opérationnel** — Whisper local, pas d'API externe payante -## Database Strategy +## Roadmap technique -### Phase 1 — SQLite (current) -- Single file: `data/app.db` -- WAL mode enabled for concurrent reads -- Docker volume-mounted for persistence -- Backups via `sqlite3 .backup` or file copy during VPS backup window - -### Phase 2 — Postgres (optional) -- Add `psycopg2` to requirements -- Set `DATABASE_URL=postgresql://...` -- Add a `postgres` service to `docker-compose.yml` -- Run migrations via Alembic - -## Deployment Plan - -### Target -- VPS: `82.165.176.5` (founder@82.165.176.5) -- Path: `/opt/micro-api/` -- Managed via: `docker compose` - -### Steps (not yet executed) -1. Push repo to Gitea: `http://82.165.176.5` -2. SSH to VPS, clone to `/opt/micro-api/` -3. `cp .env.example .env` and adjust -4. `docker compose up -d --build` -5. Verify: `curl http://localhost:8000/api/health` -6. Add Traefik route label to docker-compose - -### Reverse Proxy Integration - -Add these labels to `docker-compose.yml` when Traefik is running: - -```yaml -labels: - - "traefik.enable=true" - - "traefik.http.routers.micro-api.rule=Host(`api.your-domain.com`)" - - "traefik.http.services.micro-api.loadbalancer.server.port=8000" -``` - -## Security - -- No secrets in code — everything via env vars -- `.env` is gitignored, `.env.example` is the template -- CORS is open (`*`) for now — restrict in production -- Container runs as non-root in future iteration - -## Testing Strategy - -- **Unit tests**: pytest on all routes, models, and DB utilities -- **Integration**: `TestClient` against the FastAPI app -- **Smoke test**: `curl /api/health` after deploy -- **CI**: GitHub Actions / Gitea Actions (future) - -## Future Services - -Each new micro-service follows the same scaffold: -1. Copy this template -2. Add service-specific routes/models -3. Add to the main `docker-compose.yml` -4. Register with Traefik - -## Maintainers - -- **Founder** — architecture decisions, deployment -- **AutoClaw (forge agent)** — initial scaffold, CI/CD +1. ✅ Scaffold (health check, structure) +2. ⬜ Endpoint /api/transcribe (Whisper local, upload fichier) +3. ⬜ Endpoint /api/summarize (Résumé de texte) +4. ⬜ Endpoint /api/convert (Markdown→PDF, JSON→CSV) +5. ⬜ Authentification API keys +6. ⬜ Rate limiting + quotas +7. ⬜ Intégration Lemon Squeezy (paiements) +8. ⬜ Dashboard utilisateur diff --git a/docker-compose.yml b/docker-compose.yml index eed84b2..16a16f8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,24 +1,11 @@ services: api: - build: - context: . - dockerfile: Dockerfile + build: . container_name: micro-api - ports: - - "${API_PORT:-8000}:8000" - environment: - - DEBUG=${DEBUG:-false} - - DATABASE_URL=${DATABASE_URL:-sqlite:///data/app.db} - volumes: - - api_data:/app/data restart: unless-stopped - healthcheck: - test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health')"] - interval: 30s - timeout: 5s - retries: 3 - start_period: 10s - -volumes: - api_data: - driver: local + ports: + - "8000:8000" + environment: + - ENV=production + volumes: + - ./data:/app/data diff --git a/dockerfile b/dockerfile index 259863f..94825db 100644 --- a/dockerfile +++ b/dockerfile @@ -1,31 +1,12 @@ -# ---- Build stage ---- -FROM python:3.12-slim AS builder +FROM python:3.11-slim WORKDIR /app -# Install dependencies in a venv COPY requirements.txt . -RUN python -m venv /opt/venv && \ - /opt/venv/bin/pip install --no-cache-dir -r requirements.txt +RUN pip install --no-cache-dir -r requirements.txt -# ---- Runtime stage ---- -FROM python:3.12-slim AS runtime - -WORKDIR /app - -# Copy virtualenv from builder -COPY --from=builder /opt/venv /opt/venv -ENV PATH="/opt/venv/bin:$PATH" - -# Copy application code -COPY app/ ./app/ - -# Create data dir for SQLite -RUN mkdir -p /app/data && chmod 777 /app/data +COPY . . EXPOSE 8000 -HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ - CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health')" || exit 1 - CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/readme.md b/readme.md index 355926d..f5d67a9 100644 --- a/readme.md +++ b/readme.md @@ -1,88 +1,34 @@ -# Micro-API +# MicroAPI -Lightweight FastAPI micro-service foundation. Docker-ready, zero-cost deployment. - -## Stack - -- **Python 3.12** — slim Docker image -- **FastAPI** — async web framework -- **Uvicorn** — ASGI server -- **SQLite** — local database (swap to Postgres via `DATABASE_URL`) -- **Docker + Docker Compose** — containerized deployment - -## Quick Start - -### Local dev - -```bash -python -m venv .venv -source .venv/bin/activate # Windows: .venv\Scripts\activate -pip install -r requirements.txt -r requirements-dev.txt -uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 -``` - -Open http://localhost:8000/api/health - -### Docker - -```bash -docker compose up --build -``` - -### Tests - -```bash -pytest -v -``` +API de micro-services — transcription audio, résumé automatique, conversion de formats. ## Endpoints -| Method | Path | Description | -|--------|----------------|-----------------| -| GET | `/` | Service info | -| GET | `/api/health` | Health check | +| Méthode | Route | Description | +|---|---|---| +| GET | `/` | Informations du service | +| GET | `/api/health` | Health check | -## Environment +### À venir +- `POST /api/transcribe` — Transcription audio (Whisper local) +- `POST /api/summarize` — Résumé de texte +- `POST /api/convert` — Conversion Markdown↔PDF, JSON↔CSV -Copy `.env.example` to `.env` and adjust: - -| Variable | Default | Description | -|----------------|-------------------------|----------------------| -| `DATABASE_URL` | `sqlite:///data/app.db` | Database connection | -| `DEBUG` | `false` | Enable debug mode | -| `API_PORT` | `8000` | Host port binding | - -## Deployment - -See [ARCHITECTURE.md](ARCHITECTURE.md) for the full deployment plan. +## Lancer en local ```bash -# On the VPS -git clone /opt/micro-api -cd /opt/micro-api -docker compose up -d --build +pip install -r requirements.txt +uvicorn main:app --reload ``` -## Project Structure +## Docker +```bash +docker compose up -d ``` -micro-api/ -├── app/ -│ ├── __init__.py -│ ├── main.py # FastAPI app entry point -│ ├── routes.py # API routes -│ ├── models.py # Pydantic schemas -│ ├── database.py # SQLite utilities -│ └── config.py # App settings -├── tests/ -│ ├── __init__.py -│ └── test_main.py # API tests -├── Dockerfile -├── docker-compose.yml -├── requirements.txt -├── requirements-dev.txt -├── .env.example -├── .gitignore -├── README.md -└── ARCHITECTURE.md + +## Tests + +```bash +pytest tests/ -v ``` diff --git a/requirements.txt b/requirements.txt index 4e208b9..3a4da97 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -fastapi>=0.115.0,<1.0.0 -uvicorn[standard]>=0.34.0,<1.0.0 -pydantic>=2.0.0,<3.0.0 -python-dotenv>=1.0.0,<2.0.0 +fastapi>=0.115.0 +uvicorn[standard]>=0.30.0 +pytest>=8.0.0 +httpx>=0.27.0