Claude commited on
Commit
ed312af
·
unverified ·
1 Parent(s): 0d49af3

feat(sprint5-session-a): Dockerisation + configuration HuggingFace Spaces

Browse files

- infra/Dockerfile : image python:3.11-slim, WORKDIR /app, PYTHONPATH=/app/backend,
port 7860, workers=1, data/ en volume, secrets en variables d'env (R06)
- Dockerfile (racine) : copie identique requise par HF Spaces SDK docker
- infra/docker-compose.yml : dev local, build context=repo root, volume ../data
- README.md : YAML front matter HF + docs développeur (lancer, tester, profils, providers)
- .huggingface/README.md : config Space HF (secrets, stockage Datasets, endpoints)

Convention HF Spaces : Dockerfile obligatoire à la racine → double fichier.
Structure image : /app/backend/app/ + /app/profiles/ + /app/prompts/ + /app/data/ (volume).

https://claude.ai/code/session_018woyEHc8HG2th7V4ewJ4Kg

Files changed (5) hide show
  1. .huggingface/README.md +40 -0
  2. Dockerfile +47 -0
  3. README.md +110 -2
  4. infra/Dockerfile +49 -0
  5. infra/docker-compose.yml +25 -0
.huggingface/README.md ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Scriptorium AI
3
+ emoji: 📜
4
+ colorFrom: blue
5
+ colorTo: gold
6
+ sdk: docker
7
+ app_port: 7860
8
+ pinned: false
9
+ ---
10
+
11
+ ## Configuration HuggingFace Spaces
12
+
13
+ Ce Space utilise le SDK Docker. L'image est construite depuis le `Dockerfile`
14
+ à la racine du dépôt au moment du push.
15
+
16
+ ### Secrets à configurer
17
+
18
+ Dans **Settings → Repository secrets**, renseigner selon le provider choisi :
19
+
20
+ | Secret | Description |
21
+ |--------|-------------|
22
+ | `AI_PROVIDER` | `google_ai_studio` \| `google_ai_api` \| `google_vertex` |
23
+ | `GOOGLE_AI_STUDIO_API_KEY` | Clé API Google AI Studio (si `AI_PROVIDER=google_ai_studio`) |
24
+ | `GOOGLE_AI_API_KEY` | Clé API Google AI (si `AI_PROVIDER=google_ai_api`) |
25
+ | `GOOGLE_VERTEX_PROJECT` | ID du projet GCP (si `AI_PROVIDER=google_vertex`) |
26
+ | `GOOGLE_VERTEX_LOCATION` | Région Vertex (défaut : `us-central1`) |
27
+
28
+ ### Stockage des artefacts
29
+
30
+ Les images, JSON maîtres et exports XML sont stockés sur un **HuggingFace Dataset**
31
+ associé (pas dans l'image Docker). Le volume `/app/data` doit être monté via
32
+ le Dataset persistant du Space ou un Dataset dédié.
33
+
34
+ ### Endpoints de vérification
35
+
36
+ ```
37
+ GET /api/v1/profiles → liste les 4 profils de corpus disponibles
38
+ GET /docs → documentation Swagger interactive
39
+ GET /api/v1/corpora → liste des corpus ingérés
40
+ ```
Dockerfile ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Scriptorium AI — image de production
2
+ # Ce fichier est la copie exacte de infra/Dockerfile.
3
+ # Il est requis à la racine du dépôt pour HuggingFace Spaces (SDK docker).
4
+ #
5
+ # Build depuis la racine du dépôt :
6
+ # docker build -t scriptorium-ai .
7
+ #
8
+ # Structure attendue dans l'image :
9
+ # /app/backend/app/ ← source Python (importable via PYTHONPATH)
10
+ # /app/profiles/ ← profils JSON
11
+ # /app/prompts/ ← templates de prompts
12
+ # /app/data/ ← créé vide ; à monter en volume pour les artefacts
13
+
14
+ FROM python:3.11-slim
15
+
16
+ WORKDIR /app
17
+
18
+ # ── Dépendances Python ─────────────────────────────────────────────────────
19
+ # On copie uniquement pyproject.toml pour exploiter le cache de layers Docker.
20
+ # Un stub app/__init__.py satisfait setuptools (discover packages) sans avoir
21
+ # besoin de copier tout le code source à ce stade.
22
+ COPY backend/pyproject.toml /tmp/build/
23
+ RUN mkdir -p /tmp/build/app \
24
+ && touch /tmp/build/app/__init__.py \
25
+ && pip install --no-cache-dir /tmp/build/ \
26
+ && rm -rf /tmp/build
27
+
28
+ # ── Code source ────────────────────────────────────────────────────────────
29
+ COPY backend/app ./backend/app
30
+ COPY profiles/ ./profiles/
31
+ COPY prompts/ ./prompts/
32
+
33
+ # ── Répertoire des artefacts (vide dans l'image ; monté en volume) ─────────
34
+ RUN mkdir -p /app/data
35
+
36
+ # ── Secrets Google AI : JAMAIS dans l'image (R06) ─────────────────────────
37
+ # Passer au runtime via -e ou les Secrets HuggingFace Spaces :
38
+ # AI_PROVIDER, GOOGLE_AI_STUDIO_API_KEY, GOOGLE_AI_API_KEY,
39
+ # GOOGLE_VERTEX_PROJECT, GOOGLE_VERTEX_LOCATION
40
+
41
+ # PYTHONPATH permet l'import `app.main:app` depuis /app/backend/app/
42
+ ENV PYTHONPATH=/app/backend
43
+
44
+ EXPOSE 7860
45
+
46
+ # 1 worker au MVP — pas de Gunicorn, pas de multiprocessing
47
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "1"]
README.md CHANGED
@@ -1,2 +1,110 @@
1
- # Scriptorium-AI
2
- AI-Enhanced Scholarly Edition Generation Platform
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Scriptorium AI
3
+ emoji: 📜
4
+ colorFrom: blue
5
+ colorTo: gold
6
+ sdk: docker
7
+ app_port: 7860
8
+ pinned: false
9
+ ---
10
+
11
+ # Scriptorium AI
12
+
13
+ Plateforme générique de génération d'éditions savantes augmentées pour documents
14
+ patrimoniaux numérisés : manuscrits médiévaux, incunables, cartulaires, archives,
15
+ chartes, papyri — tout type de document, toute époque, toute langue.
16
+
17
+ ---
18
+
19
+ ## Structure du dépôt
20
+
21
+ ```
22
+ scriptorium-ai/
23
+ ├── backend/ # API FastAPI + pipeline Python
24
+ │ ├── app/
25
+ │ │ ├── api/v1/ # endpoints REST (/api/v1/...)
26
+ │ │ ├── models/ # tables SQLAlchemy (SQLite async)
27
+ │ │ ├── schemas/ # modèles Pydantic v2
28
+ │ │ └── services/ # ingest / image / ai / export / search
29
+ │ ├── tests/ # suite pytest (477 tests)
30
+ │ └── pyproject.toml
31
+ ├── profiles/ # 4 profils de corpus JSON
32
+ ├── prompts/ # templates de prompts par profil
33
+ ├── infra/ # Dockerfile + docker-compose (dev local)
34
+ ├── Dockerfile # copie du Dockerfile pour HuggingFace Spaces
35
+ └── data/ # artefacts runtime — NON versionné
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Lancer en local (Docker)
41
+
42
+ ```bash
43
+ # 1. Cloner le dépôt
44
+ git clone https://github.com/<org>/scriptorium-ai && cd scriptorium-ai
45
+
46
+ # 2. Définir les variables d'environnement
47
+ cp .env.example .env # puis renseigner les clés dans .env
48
+
49
+ # 3. Démarrer le service
50
+ docker compose -f infra/docker-compose.yml up --build
51
+
52
+ # 4. Vérifier
53
+ curl http://localhost:7860/api/v1/profiles
54
+ ```
55
+
56
+ L'API est accessible sur `http://localhost:7860`. La documentation interactive
57
+ Swagger est disponible sur `http://localhost:7860/docs`.
58
+
59
+ ---
60
+
61
+ ## Lancer les tests
62
+
63
+ ```bash
64
+ cd backend
65
+ pip install -e ".[dev]"
66
+ pytest tests/ -v --cov=app
67
+ ```
68
+
69
+ Résultat attendu : **477 passed, 3 skipped**.
70
+
71
+ ---
72
+
73
+ ## Profils disponibles
74
+
75
+ | Profil | Description |
76
+ |--------|-------------|
77
+ | `medieval-illuminated` | Manuscrits médiévaux enluminés (OCR diplomatique, iconographie, commentaire) |
78
+ | `medieval-textual` | Manuscrits médiévaux textuels (OCR, traduction, commentaire savant) |
79
+ | `early-modern-print` | Imprimés anciens (incunables, livres des XVIe–XVIIIe siècles) |
80
+ | `modern-handwritten` | Documents manuscrits modernes (cursive, archives, chartes) |
81
+
82
+ ```bash
83
+ # Lister les profils via l'API
84
+ curl http://localhost:7860/api/v1/profiles
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Providers Google AI
90
+
91
+ Trois modes d'authentification sont supportés. Sélectionner via `AI_PROVIDER`.
92
+
93
+ | Provider | Variable `AI_PROVIDER` | Variables d'environnement requises |
94
+ |----------|------------------------|-------------------------------------|
95
+ | Google AI Studio (clé API) | `google_ai_studio` | `GOOGLE_AI_STUDIO_API_KEY` |
96
+ | Google AI API (legacy) | `google_ai_api` | `GOOGLE_AI_API_KEY` |
97
+ | Google Vertex AI | `google_vertex` | `GOOGLE_VERTEX_PROJECT`, `GOOGLE_VERTEX_LOCATION` |
98
+
99
+ Les clés ne doivent **jamais** figurer dans le code, les commits ou l'image Docker.
100
+ Sur HuggingFace Spaces, les renseigner dans **Settings → Repository secrets**.
101
+
102
+ ---
103
+
104
+ ## Déploiement HuggingFace Spaces
105
+
106
+ Ce dépôt est configuré pour HuggingFace Spaces (SDK Docker, port 7860).
107
+ Les artefacts de traitement (images, JSON maîtres, exports XML) sont stockés
108
+ sur HuggingFace Datasets — pas dans l'image Docker.
109
+
110
+ Voir `.huggingface/README.md` pour la configuration spécifique du Space.
infra/Dockerfile ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Scriptorium AI — image de production
2
+ # Build depuis la racine du dépôt :
3
+ # docker build -f infra/Dockerfile -t scriptorium-ai .
4
+ #
5
+ # Structure attendue dans l'image :
6
+ # /app/backend/app/ ← source Python (importable via PYTHONPATH)
7
+ # /app/profiles/ ← profils JSON
8
+ # /app/prompts/ ← templates de prompts
9
+ # /app/data/ ← créé vide ; à monter en volume pour les artefacts
10
+
11
+ FROM python:3.11-slim
12
+
13
+ WORKDIR /app
14
+
15
+ # ── Dépendances système (lxml utilise des wheels binaires pré-compilés ;
16
+ # aucun outil de build requis sur cette image) ─────────────────────────────
17
+ # Aucun paquet système supplémentaire nécessaire.
18
+
19
+ # ── Dépendances Python ─────────────────────────────────────────────────────
20
+ # On copie uniquement pyproject.toml pour exploiter le cache de layers Docker.
21
+ # Un stub app/__init__.py satisfait setuptools (discover packages) sans avoir
22
+ # besoin de copier tout le code source à ce stade.
23
+ COPY backend/pyproject.toml /tmp/build/
24
+ RUN mkdir -p /tmp/build/app \
25
+ && touch /tmp/build/app/__init__.py \
26
+ && pip install --no-cache-dir /tmp/build/ \
27
+ && rm -rf /tmp/build
28
+
29
+ # ── Code source ────────────────────────────────────────────────────────────
30
+ # Copié APRÈS l'installation des dépendances pour conserver le cache.
31
+ COPY backend/app ./backend/app
32
+ COPY profiles/ ./profiles/
33
+ COPY prompts/ ./prompts/
34
+
35
+ # ── Répertoire des artefacts (vide dans l'image ; monté en volume) ─────────
36
+ RUN mkdir -p /app/data
37
+
38
+ # ── Secrets Google AI : JAMAIS dans l'image (R06) ─────────────────────────
39
+ # Passer au runtime via -e ou docker-compose environment :
40
+ # AI_PROVIDER, GOOGLE_AI_STUDIO_API_KEY, GOOGLE_AI_API_KEY,
41
+ # GOOGLE_VERTEX_PROJECT, GOOGLE_VERTEX_LOCATION
42
+
43
+ # PYTHONPATH permet l'import `app.main:app` depuis /app/backend/app/
44
+ ENV PYTHONPATH=/app/backend
45
+
46
+ EXPOSE 7860
47
+
48
+ # 1 worker au MVP — pas de Gunicorn, pas de multiprocessing
49
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "1"]
infra/docker-compose.yml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # docker-compose pour développement local UNIQUEMENT.
2
+ # Lancer depuis la racine du dépôt :
3
+ # docker compose -f infra/docker-compose.yml up --build
4
+ #
5
+ # Les secrets ne doivent jamais figurer dans ce fichier (R06).
6
+ # Copier .env.example → .env et y renseigner les clés.
7
+
8
+ services:
9
+ api:
10
+ build:
11
+ context: .. # racine du dépôt = contexte de build
12
+ dockerfile: infra/Dockerfile
13
+ ports:
14
+ - "7860:7860"
15
+ volumes:
16
+ - ../data:/app/data # artefacts montés en volume, hors image
17
+ environment:
18
+ # Provider IA : google_ai_studio | google_vertex | google_ai_api
19
+ - AI_PROVIDER=${AI_PROVIDER:-google_ai_studio}
20
+ # Clés selon le provider choisi — à définir dans .env
21
+ - GOOGLE_AI_STUDIO_API_KEY=${GOOGLE_AI_STUDIO_API_KEY:-}
22
+ - GOOGLE_AI_API_KEY=${GOOGLE_AI_API_KEY:-}
23
+ - GOOGLE_VERTEX_PROJECT=${GOOGLE_VERTEX_PROJECT:-}
24
+ - GOOGLE_VERTEX_LOCATION=${GOOGLE_VERTEX_LOCATION:-us-central1}
25
+ restart: unless-stopped