Initial scaffold: FastAPI micro-services API (forge + founder)
This commit is contained in:
+44
-99
@@ -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
|
## Structure des dossiers
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
```
|
```
|
||||||
┌──────────────────────────────────────────┐
|
micro-api/
|
||||||
│ VPS (82.165.176.5) │
|
├── main.py # Application FastAPI
|
||||||
│ │
|
├── requirements.txt # Dépendances Python
|
||||||
│ ┌─────────┐ ┌──────────────────────┐ │
|
├── Dockerfile # Image Docker
|
||||||
│ │ Traefik │──▶│ micro-api:8000 │ │
|
├── docker-compose.yml # Stack de déploiement
|
||||||
│ │ :443 │ │ (Docker container) │ │
|
├── README.md # Documentation utilisateur
|
||||||
│ └─────────┘ │ FastAPI + Uvicorn │ │
|
├── ARCHITECTURE.md # Ce document
|
||||||
│ │ SQLite /data/ │ │
|
├── tests/ # Tests unitaires & intégration
|
||||||
│ └──────────────────────┘ │
|
│ └── test_health.py
|
||||||
│ │
|
├── app/ # Code applicatif (à venir)
|
||||||
│ ┌──────────────────────────────────┐ │
|
│ ├── routers/ # Endpoints API
|
||||||
│ │ Future services (API v2, ...) │ │
|
│ ├── services/ # Logique métier (transcription, etc.)
|
||||||
│ └──────────────────────────────────┘ │
|
│ ├── models/ # Modèles de données
|
||||||
└──────────────────────────────────────────┘
|
│ └── utils/ # Utilitaires
|
||||||
|
└── data/ # Données persistantes (volumes)
|
||||||
```
|
```
|
||||||
|
|
||||||
## Data Flow
|
## Principes
|
||||||
|
|
||||||
```
|
1. **Stateless** — Chaque requête est indépendante, pas de session serveur
|
||||||
Client ──HTTPS──▶ Traefik ──HTTP──▶ micro-api:8000
|
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
|
||||||
SQLite (file)
|
5. **Zéro coût opérationnel** — Whisper local, pas d'API externe payante
|
||||||
/data/app.db
|
|
||||||
```
|
|
||||||
|
|
||||||
## Database Strategy
|
## Roadmap technique
|
||||||
|
|
||||||
### Phase 1 — SQLite (current)
|
1. ✅ Scaffold (health check, structure)
|
||||||
- Single file: `data/app.db`
|
2. ⬜ Endpoint /api/transcribe (Whisper local, upload fichier)
|
||||||
- WAL mode enabled for concurrent reads
|
3. ⬜ Endpoint /api/summarize (Résumé de texte)
|
||||||
- Docker volume-mounted for persistence
|
4. ⬜ Endpoint /api/convert (Markdown→PDF, JSON→CSV)
|
||||||
- Backups via `sqlite3 .backup` or file copy during VPS backup window
|
5. ⬜ Authentification API keys
|
||||||
|
6. ⬜ Rate limiting + quotas
|
||||||
### Phase 2 — Postgres (optional)
|
7. ⬜ Intégration Lemon Squeezy (paiements)
|
||||||
- Add `psycopg2` to requirements
|
8. ⬜ Dashboard utilisateur
|
||||||
- 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
|
|
||||||
|
|||||||
+7
-20
@@ -1,24 +1,11 @@
|
|||||||
services:
|
services:
|
||||||
api:
|
api:
|
||||||
build:
|
build: .
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
container_name: micro-api
|
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
|
restart: unless-stopped
|
||||||
healthcheck:
|
ports:
|
||||||
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health')"]
|
- "8000:8000"
|
||||||
interval: 30s
|
environment:
|
||||||
timeout: 5s
|
- ENV=production
|
||||||
retries: 3
|
volumes:
|
||||||
start_period: 10s
|
- ./data:/app/data
|
||||||
|
|
||||||
volumes:
|
|
||||||
api_data:
|
|
||||||
driver: local
|
|
||||||
|
|||||||
+3
-22
@@ -1,31 +1,12 @@
|
|||||||
# ---- Build stage ----
|
FROM python:3.11-slim
|
||||||
FROM python:3.12-slim AS builder
|
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Install dependencies in a venv
|
|
||||||
COPY requirements.txt .
|
COPY requirements.txt .
|
||||||
RUN python -m venv /opt/venv && \
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
/opt/venv/bin/pip install --no-cache-dir -r requirements.txt
|
|
||||||
|
|
||||||
# ---- Runtime stage ----
|
COPY . .
|
||||||
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
|
|
||||||
|
|
||||||
EXPOSE 8000
|
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"]
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
|
|||||||
@@ -1,88 +1,34 @@
|
|||||||
# Micro-API
|
# MicroAPI
|
||||||
|
|
||||||
Lightweight FastAPI micro-service foundation. Docker-ready, zero-cost deployment.
|
API de micro-services — transcription audio, résumé automatique, conversion de formats.
|
||||||
|
|
||||||
## 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
|
|
||||||
```
|
|
||||||
|
|
||||||
## Endpoints
|
## Endpoints
|
||||||
|
|
||||||
| Method | Path | Description |
|
| Méthode | Route | Description |
|
||||||
|--------|----------------|-----------------|
|
|---|---|---|
|
||||||
| GET | `/` | Service info |
|
| GET | `/` | Informations du service |
|
||||||
| GET | `/api/health` | Health check |
|
| 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:
|
## Lancer en local
|
||||||
|
|
||||||
| 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.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# On the VPS
|
pip install -r requirements.txt
|
||||||
git clone <repo-url> /opt/micro-api
|
uvicorn main:app --reload
|
||||||
cd /opt/micro-api
|
|
||||||
docker compose up -d --build
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Project Structure
|
## Docker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
```
|
```
|
||||||
micro-api/
|
|
||||||
├── app/
|
## Tests
|
||||||
│ ├── __init__.py
|
|
||||||
│ ├── main.py # FastAPI app entry point
|
```bash
|
||||||
│ ├── routes.py # API routes
|
pytest tests/ -v
|
||||||
│ ├── 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
|
|
||||||
```
|
```
|
||||||
|
|||||||
+4
-4
@@ -1,4 +1,4 @@
|
|||||||
fastapi>=0.115.0,<1.0.0
|
fastapi>=0.115.0
|
||||||
uvicorn[standard]>=0.34.0,<1.0.0
|
uvicorn[standard]>=0.30.0
|
||||||
pydantic>=2.0.0,<3.0.0
|
pytest>=8.0.0
|
||||||
python-dotenv>=1.0.0,<2.0.0
|
httpx>=0.27.0
|
||||||
|
|||||||
Reference in New Issue
Block a user