Add admin panel, WebSocket support, and API versioning
Introduce an admin portal (React + Nginx), WebSocket routing, and API versioning middleware with `/api/v1/` prefix deprecation. Add master API key authentication, new Prometheus metrics for AI token consumption and active WebSockets, and extend S3 config with a public endpoint URL. Update test paths and fixtures to align with the new routing structure.
This commit is contained in:
@@ -0,0 +1,245 @@
|
||||
# Guide d'utilisation de l'API Imago
|
||||
|
||||
Bienvenue dans la documentation officielle de l'API REST d'Imago.
|
||||
**Note :** Tous les terminaux (endpoints) principaux présentés ici sont désormais servis sous le préfixe `/api/v1/` dans l'application locale.
|
||||
|
||||
## 📍 Sommaire
|
||||
- [🔐 Authentification](#-Authentification)
|
||||
- [🛡️ Scopes (Permissions)](#-scopes-permissions)
|
||||
- [📊 Plans et Rate Limiting](#-plans-et-rate-limiting)
|
||||
- [👥 Gestion des Clients (Admin uniquement)](#-gestion-des-clients-admin-uniquement)
|
||||
- [📁 Multi-tenancy et Isolation](#-multi-tenancy-et-isolation)
|
||||
- [📖 Référence des Endpoints](#-référence-des-endpoints)
|
||||
- [📸 Gestion des Images](#-gestion-des-images)
|
||||
- [🤖 Intelligence Artificielle](#-intelligence-artificielle)
|
||||
- [🔑 Administration (Admin uniquement)](#-administration-admin-uniquement)
|
||||
- [🏥 Santé et Status](#-santé-et-status)
|
||||
- [🚀 Exemples Rapides](#-exemples-rapides)
|
||||
|
||||
---
|
||||
|
||||
## 🔐 Authentification
|
||||
|
||||
Tous les endpoints (sauf `/health` et `/`) nécessitent une authentification via une **Clé API**.
|
||||
|
||||
### Header Authorization
|
||||
|
||||
Vous devez inclure votre clé dans le header `Authorization` de chaque requête :
|
||||
|
||||
```http
|
||||
Authorization: Bearer VOTRE_CLE_API_SECRET
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Traitez votre clé API comme un mot de passe. Ne la partagez jamais et ne l'incluez pas dans du code client (frontend) accessible publiquement.
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ Scopes (Permissions)
|
||||
|
||||
L'accès aux fonctionnalités est contrôlé par des **scopes**. Chaque clé API est limitée à un ensemble de permissions :
|
||||
|
||||
| Scope | Description | Fonctions incluses |
|
||||
|-------|-------------|-------------------|
|
||||
| `images:read` | Lecture seule | Lister les images, voir les détails, EXIF, OCR, AI. |
|
||||
| `images:write` | Écriture | Uploader des images, relancer le pipeline de traitement. |
|
||||
| `images:delete`| Suppression | Supprimer définitivement des images. |
|
||||
| `ai:use` | Utilisation IA | Résumé d'URL, rédaction de tâches. |
|
||||
| `admin` | Administration | Gérer les clients API, voir les clés, modifier les plans. |
|
||||
|
||||
---
|
||||
|
||||
## 📊 Plans et Rate Limiting
|
||||
|
||||
Le système applique des limites de requêtes (Rate Limits) basées sur le **Plan** de votre client. Les compteurs sont réinitialisés toutes les heures.
|
||||
|
||||
| Plan | Uploads / heure | Requêtes AI / heure |
|
||||
|------|-----------------|---------------------|
|
||||
| `free` | 20 | 50 |
|
||||
| `standard` | 100 | 200 |
|
||||
| `premium` | 500 | 1000 |
|
||||
|
||||
*Les requêtes de lecture (`GET`) ne sont pas limitées par défaut.*
|
||||
|
||||
---
|
||||
|
||||
## 👥 Gestion des Clients (Admin uniquement)
|
||||
|
||||
Si vous avez le scope `admin`, vous pouvez gérer les accès.
|
||||
|
||||
### Créer un nouveau client
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/auth/clients \
|
||||
-H "Authorization: Bearer CLE_ADMIN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "Application Mobile",
|
||||
"scopes": ["images:read", "images:write", "ai:use"],
|
||||
"plan": "standard"
|
||||
}'
|
||||
```
|
||||
|
||||
**Réponse (Importante) :**
|
||||
```json
|
||||
{
|
||||
"id": "uuid-...",
|
||||
"api_key": "cle_generee_en_clair_une_seule_fois",
|
||||
"name": "Application Mobile",
|
||||
...
|
||||
}
|
||||
```
|
||||
> [!CAUTION]
|
||||
> La clé API n'est affichée **qu'une seule fois** à la création. Stockez-la immédiatement de manière sécurisée.
|
||||
|
||||
### Régénérer une clé (Rotation)
|
||||
|
||||
En cas de compromission, invalidez l'ancienne clé et générez-en une nouvelle :
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/auth/clients/{id}/rotate-key \
|
||||
-H "Authorization: Bearer CLE_ADMIN"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📁 Multi-tenancy et Isolation
|
||||
|
||||
L'API est **multi-tenant**. Cela signifie que :
|
||||
- Vous ne voyez **que** les images uploadées avec votre clé.
|
||||
- Les IDs d'images sont globaux, mais si vous tentez d'accéder à l'ID d'un autre client, vous recevrez une erreur `404 Not Found`.
|
||||
- Vos fichiers physiques sont stockés dans un sous-répertoire dédié sur le serveur (`/data/uploads/{votre_client_id}/`).
|
||||
|
||||
---
|
||||
|
||||
## 📖 Référence des Endpoints
|
||||
|
||||
### 📸 Gestion des Images
|
||||
|
||||
#### Lister les images
|
||||
`GET /api/v1/images`
|
||||
- **Scope required** : `images:read`
|
||||
- **Query Params** :
|
||||
- `page` : Numéro de page (défaut: 1)
|
||||
- `page_size` : Taille de page (défaut: 20, max: 100)
|
||||
- `tag` : Filtrer par tag AI
|
||||
- `status` : Filtrer par statut (`pending`, `processing`, `done`, `error`)
|
||||
- `search` : Recherche textuelle dans le nom, la description AI ou l'OCR.
|
||||
|
||||
#### Uploader une image
|
||||
`POST /api/v1/images/upload`
|
||||
- **Scope required** : `images:write`
|
||||
- **Body** : `multipart/form-data`
|
||||
- `file` : Le fichier image (JPEG, PNG, WebP, etc.)
|
||||
- **Note** : Lance automatiquement le pipeline AI en arrière-plan.
|
||||
|
||||
#### Détail complet d'une image
|
||||
`GET /api/v1/images/{id}`
|
||||
- **Scope required** : `images:read`
|
||||
- **Description** : Retourne toutes les données (Source, EXIF, OCR, AI).
|
||||
|
||||
#### Statut du traitement
|
||||
`GET /api/v1/images/{id}/status`
|
||||
- **Scope required** : `images:read`
|
||||
- **Description** : Pour savoir si l'analyse par l'IA est terminée.
|
||||
|
||||
#### Métadonnées spécifiques
|
||||
- `GET /api/v1/images/{id}/exif` : Données techniques de l'appareil et GPS.
|
||||
- `GET /api/v1/images/{id}/ocr` : Texte extrait de l'image.
|
||||
- `GET /api/v1/images/{id}/ai` : Description textuelle et tags générés.
|
||||
|
||||
#### Retraitement
|
||||
`POST /api/v1/images/{id}/reprocess`
|
||||
- **Scope required** : `images:write`
|
||||
- **Description** : Réinitialise et relance le pipeline d'analyse AI.
|
||||
|
||||
#### Suppression
|
||||
`DELETE /api/v1/images/{id}`
|
||||
- **Scope required** : `images:delete`
|
||||
- **Description** : Supprime l'entrée en base et les fichiers sur le disque.
|
||||
|
||||
#### Tags globaux
|
||||
`GET /api/v1/images/tags/all`
|
||||
- **Scope required** : `images:read`
|
||||
- **Description** : Liste tous les tags uniques utilisés par le client.
|
||||
|
||||
---
|
||||
|
||||
### 🤖 Intelligence Artificielle
|
||||
|
||||
#### Résumé d'URL
|
||||
`POST /api/v1/ai/summarize`
|
||||
- **Scope required** : `ai:use`
|
||||
- **Body** (JSON) :
|
||||
```json
|
||||
{
|
||||
"url": "https://...",
|
||||
"language": "français"
|
||||
}
|
||||
```
|
||||
|
||||
#### Rédaction de tâche
|
||||
`POST /api/v1/ai/draft-task`
|
||||
- **Scope required** : `ai:use`
|
||||
- **Body** (JSON) :
|
||||
```json
|
||||
{
|
||||
"description": "Texte libre décrivant la tâche",
|
||||
"context": "Contexte optionnel",
|
||||
"language": "fr"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 🔑 Administration (Admin uniquement)
|
||||
*Nécessite le scope `admin`.*
|
||||
|
||||
- `POST /api/v1/auth/clients` : Créer un client (retourne la clé).
|
||||
- `GET /api/v1/auth/clients` : Lister tous les clients.
|
||||
- `GET /api/v1/auth/clients/{id}` : Voir les détails d'un client.
|
||||
- `PATCH /api/v1/auth/clients/{id}` : Modifier un client (nom, scopes, plan).
|
||||
- `POST /api/v1/auth/clients/{id}/rotate-key` : Changer la clé API.
|
||||
- `DELETE /api/v1/auth/clients/{id}` : Désactiver un client (suspension d'accès).
|
||||
|
||||
---
|
||||
|
||||
### 🏥 Santé et Status
|
||||
Ces endpoints sont **publics** et ne nécessitent aucune clé API.
|
||||
|
||||
- `GET /` : Informations de base sur l'application (Version, Status).
|
||||
- `GET /health` : Vérification complète de l'état (AI configurée, OCR actif, Modèle utilisé).
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Exemples Rapides
|
||||
|
||||
### Lister mes images (Python / httpx)
|
||||
|
||||
```python
|
||||
import httpx
|
||||
|
||||
headers = {"Authorization": "Bearer ma_super_cle"}
|
||||
r = httpx.get("http://localhost:8000/images", headers=headers)
|
||||
|
||||
for img in r.json()["items"]:
|
||||
print(f"ID: {img['id']} | Name: {img['original_name']}")
|
||||
```
|
||||
|
||||
### Uploader une image (Node.js / Axios)
|
||||
|
||||
```javascript
|
||||
const axios = require('axios');
|
||||
const fs = require('fs');
|
||||
const FormData = require('form-data');
|
||||
|
||||
const form = new FormData();
|
||||
form.append('file', fs.createReadStream('vacances.jpg'));
|
||||
|
||||
axios.post('http://localhost:8000/images/upload', form, {
|
||||
headers: {
|
||||
...form.getHeaders(),
|
||||
'Authorization': 'Bearer ma_super_cle'
|
||||
}
|
||||
}).then(console.log);
|
||||
```
|
||||
@@ -0,0 +1,60 @@
|
||||
# Architecture Technique - Imago Hub
|
||||
|
||||
Ce document détaille l'architecture logicielle, les flux de données et les choix technologiques d'Imago Hub. Il s'adresse aux développeurs, architectes et contributeurs du projet.
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ 1. Vue d'Ensemble des Composants
|
||||
|
||||
Imago s'articule autour de plusieurs services distincts orchestrés via Docker, communiquant par des interfaces asynchrones et résilientes.
|
||||
|
||||
### La Stack Technique
|
||||
- **Backend API Layer :** `FastAPI` (Python 3.10+) pour des performances maximales, des endpoints asynchrones (`async/await`) et une validation native (Pydantic). L'API répond vite, elle ne bloque jamais sur l'IO réseau.
|
||||
- **Frontend Admin :** `React` (JavaScript/TypeScript) propulsé par Vite et servi via Nginx. Interface Single-Page minimaliste, rapide.
|
||||
- **Worker Queue :** `ARQ` (Async Redis Queue). Une alternative moderne s'appuyant sur l'Event Loop natif d'asyncio Python au lieu de frameworks lourds.
|
||||
- **Broker & Cache :** `Redis` stocke les jobs temporaires, limite les taux (Rate Limiting) et gère le pub/sub des requêtes websocket.
|
||||
- **Base de données :** `PostgreSQL` interrogé via `SQLAlchemy` (orm asynchrone : `asyncpg`).
|
||||
- **Objets & Médias :** `MinIO` implémentant le standard S3 (ou un volume filesystem classique) pour isoler les données binaires massives.
|
||||
|
||||
---
|
||||
|
||||
## 🔄 2. Flux de Traitement Asynchrone (Le Pipeline)
|
||||
|
||||
Toute la valeur d'Imago réside dans sa capacité à dépiler un flux lourd d'images de façon déconnectée des appels HTTP des utilisateurs finaux.
|
||||
|
||||
### Chronologie d'un événement `Upload`
|
||||
1. Le client effectue un `POST /upload`. L'API FastAPI, en streaming mémoire, pousse l'image vers le backend de stockage (S3).
|
||||
2. L'API enregistre dans PostgreSQL l'image avec un statut `PENDING`.
|
||||
3. L'API publie un message **enqueue** vers ARQ/Redis : `analyse_image(db_id=124)`.
|
||||
4. L'API répond immédiatement au client HTTP avec `202 Accepted` et l'UUID généré.
|
||||
|
||||
### Boucle du Worker ARQ (processus séparé)
|
||||
Une fois le message attrapé par le démon `worker.py` :
|
||||
1. **Verrouillage** : Le statut passe à `PROCESSING`.
|
||||
2. **Étape EXIF** : (via `exifread` / modules Python) analyse purement metadata, parse le GPS et écrit dans les tables reliées.
|
||||
3. **Étape OCR** : Tesseract est encapsulé. Il scanne l'image et met à jour l'entité PostgreSQL.
|
||||
4. **Étape IA Vision** : Un client HTTP asynchrone (`httpx`) effectue un appel API vers Google (Gemini) ou OpenRouter. Une demande de structuration en prompt pur JSON assure des typages clairs.
|
||||
5. **Clôture** : Le statut passe à `COMPLETED`.
|
||||
|
||||
*(En cas d'échec sur une étape isolée comme le réseau IA, le worker utilise la retry-policy asynchrone native d'ARQ).*
|
||||
|
||||
---
|
||||
|
||||
## 🗄️ 3. Modèle de Données & Multi-tenancy
|
||||
|
||||
La BDD relationnelle s'articule pour cloisonner (isolation de locataire) les données de façon logicielle :
|
||||
|
||||
- **Table Clients** : Représente le "Tenant". Un Client possède plusieurs clés API hashées (Bcrypt) et un "plan" définissant ses quotas.
|
||||
- **Table Image** : Clé principale. Chaque Image possède une `client_id` liant la ressource directement au Tenant. C'est l'essence du filtrage (Aucune requête RDBM vers Images ne démarre sans `WHERE client_id = X`).
|
||||
- **Tables Satellites (Exif, OCR, AITasks)** : Héritent des dépendances (Cascade Deletes) liant l'information technique à l'uuid Image.
|
||||
|
||||
### Le Rate Limiting Distribué
|
||||
Le limiter applicatif s'appuie sur `slowapi` et le backend Redis. L'ID du tenant (Client Object) sert de clé dans Redis pour évaluer le bucket algorithmique :
|
||||
- Permet de bloquer avant l'appel FastAPI les clients abusifs en respectant strictement l'architecture distribuée.
|
||||
|
||||
---
|
||||
|
||||
## 🔌 4. Observabilité et Temps Réel
|
||||
|
||||
- **FastAPI Websockets Pub/Sub :** L'API monte des sessions WebSockets bidirectionnelles. Lors d'un changement dans PostgreSQL (Via un event déclenché par ARQ en fin de boucle), un hook publie un patch JSON aux websockets écoutants. L'UI (Shaarli / Admin) est ré-invalider sans actualisation HTTP.
|
||||
- **Prometheus Metrics :** Le endpoint `/metrics` expose via un middleware des données quantitatives brutes de latence et volumétries. Facilement gratté (scraped) par des tableaux Grafana ou Datadog.
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
# Imago SDK - `imago-client`
|
||||
|
||||
The official Python SDK provides an asynchronous, strongly-typed interface to the Imago API.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
cd sdk
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
## Basic Usage
|
||||
|
||||
The SDK provides an asynchronous Context Manager (`HubClient`) which handles connection pooling, retries, and authentication.
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
from imago_client import HubClient
|
||||
|
||||
async def main():
|
||||
async with HubClient("http://localhost:8000/api/v1", api_key="sk-test-secret-key") as client:
|
||||
# 1. Upload an image
|
||||
image = await client.images.upload("photo.jpg")
|
||||
print(f"Uploaded! UUID: {image.uuid}")
|
||||
|
||||
# 2. Get status
|
||||
details = await client.images.get(image.uuid)
|
||||
print(f"Status: {details.processing_status}")
|
||||
|
||||
# 3. Use AI
|
||||
summary = await client.ai.draft_task("https://example.com/article", "Summarize this quickly.")
|
||||
print(summary)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
## Advanced Features
|
||||
|
||||
### 1. Resilient Retries
|
||||
By default, the SDK automatically retries requests on timeouts, TCP connection errors, `429 Too Many Requests`, and `5xx Server Errors`. It uses exponential backoff with jitter to ensure safe recovery.
|
||||
|
||||
### 2. Real-Time Pipeline Streaming
|
||||
The SDK natively wraps the WebSockets API. You can `async for` over events until the pipeline finishes:
|
||||
|
||||
```python
|
||||
async with HubClient(url, api_key) as client:
|
||||
async for event in client.images.stream_pipeline_events("IMAGE_UUID"):
|
||||
print(event["event"])
|
||||
if event["event"] == "pipeline.done":
|
||||
break
|
||||
```
|
||||
|
||||
### 3. Error Handling
|
||||
All specific cases throw custom exceptions inherited from `ImagoError`:
|
||||
- `AuthError` (401)
|
||||
- `QuotaError` (403 or 429 quota exhaustion)
|
||||
- `NotFoundError` (404)
|
||||
- `PipelineError` (WebSockets specific)
|
||||
@@ -0,0 +1,45 @@
|
||||
# Shaarli Integration
|
||||
|
||||
The **Imago Hub** can be integrated directly with **Shaarli** (the PHP-based bookmark manager) to automatically process and enhance your bookmarks when you save them.
|
||||
|
||||
## Overview
|
||||
|
||||
When you save a new bookmark in Shaarli, you might want to:
|
||||
1. Automatically fetch the URL and summarize the page content using AI
|
||||
2. Generate tags automatically based on the page content
|
||||
3. Archive full-page screenshots to Imago for offline reading
|
||||
|
||||
This repository includes a reference implementation for this architecture using the Imago Python SDK.
|
||||
|
||||
## Components
|
||||
|
||||
The `integration/shaarli/` directory contains:
|
||||
- `hub_plugin.py` — A Python class (`ShaarliHubPlugin`) that acts as a middleware interacting with the `imago-client` SDK.
|
||||
- `config_example.env` — Example environment variable file for the plugin layer.
|
||||
- `example_usage.py` — A standalone script demonstrating how the plugin summarizes URLs.
|
||||
|
||||
## Setup Instructions
|
||||
|
||||
1. **Install the SDK:** The script requires the Imago Python SDK.
|
||||
```bash
|
||||
cd sdk
|
||||
pip install imago-client
|
||||
```
|
||||
|
||||
2. **Configure Environment variables:**
|
||||
Copy `integration/shaarli/config_example.env` to `.env` and fill it with your **Imago Admin API Key** or a specific Client API Key provisioned with `ai:use` and `images:write` scopes.
|
||||
|
||||
3. **Deploy as a microservice or hook:**
|
||||
Since Shaarli is written in PHP, to hook python scripts into Shaarli you have a few options:
|
||||
|
||||
- **Option A (WebHook):** Deploy a small FastAPI/Flask wrapper around `hub_plugin.py` and configure Shaarli's WebHook plugin to POST data to your wrapper whenever a new link is created.
|
||||
- **Option B (Cron/Background Job):** Have a Python daemon watch the Shaarli RSS/Atom feed or poll its REST API, grab new entries, process them via `hub_plugin.py`, and PATCH the bookmark back in Shaarli with the newly generated Description and Tags using the Shaarli REST API.
|
||||
|
||||
## Example Flow (Option B)
|
||||
|
||||
1. You save `https://github.com/imago-project/imago` to Shaarli.
|
||||
2. The Python daemon detects the new bookmark via Shaarli's API.
|
||||
3. The daemon calls `plugin.process_bookmark(url)`.
|
||||
4. Imago leverages OpenRouter/Gemini to fetch and summarize the GitHub page.
|
||||
5. Imago returns `{"title": "...", "description": "...", "suggested_tags": ["github", "python", "ai"]}`.
|
||||
6. The daemon PATCHes the Shaarli API to enrich the bookmark.
|
||||
@@ -0,0 +1,79 @@
|
||||
# Guide d'Utilisation - Imago Hub
|
||||
|
||||
Bienvenue dans le guide d'utilisation d'**Imago Hub**. Ce document vous accompagnera dans l'utilisation des principales fonctionnalités de la plateforme, que vous interagissiez via l'API, le panel d'administration ou les SDKs.
|
||||
|
||||
---
|
||||
|
||||
## 📸 1. Gestion des Images
|
||||
|
||||
### Upload et Traitement Asynchrone
|
||||
Imago est conçu pour ingérer rapidement des images et déléguer les traitements lourds (redimensionnement, IA, OCR) en arrière-plan (via les workers ARQ).
|
||||
|
||||
Lorsqu'une image est uploadée :
|
||||
1. **Stockage immédiat** : L'image originale est sauvegardée localement (ou sur S3/MinIO).
|
||||
2. **Création Miniature** : Une version allégée est générée.
|
||||
3. **Mise en file d'attente** : L'image passe par un pipeline d'analyse :
|
||||
- Extraction EXIF.
|
||||
- Passage dans le moteur OCR.
|
||||
- Analyse par la Vision IA.
|
||||
|
||||
### Suivre l'état d'un traitement
|
||||
Étant donné que les IA (comme Gemini/OpenRouter) et l'OCR prennent du temps, l'upload retourne instantanément un `id` avec un statut `processing` ou `pending`.
|
||||
Vous pouvez surveiller ce statut via :
|
||||
- Le polling de l'endpoint : `GET /api/v1/images/{id}/status`
|
||||
- Le streaming d'événements : Les applications frontend peuvent se connecter aux websockets d'Imago pour être notifiées en temps réel à chaque étape du pipeline. *(Voir [websocket.md](websocket.md))*
|
||||
|
||||
---
|
||||
|
||||
## 🤖 2. Intelligence Artificielle et OCR
|
||||
|
||||
### L'OCR (Reconnaissance Optique de Caractères)
|
||||
Si activé, le moteur **Tesseract** parcourt chaque image pour en extraire le texte. Cela est particulièrement utile pour :
|
||||
- Effectuer des recherches en texte intégral sur des captures d'écran, factures ou mémos photographiés.
|
||||
- Lier ces données textuelles à l'image sans intervention humaine.
|
||||
|
||||
### Vision IA (Gemini / OpenRouter)
|
||||
Imago est "AI-Native". Lorsqu'une image est traitée, elle est envoyée au fournisseur configuré (par exemple : `gemini-1.5-pro` ou `qwen2.5-vl` via OpenRouter).
|
||||
L'IA réalise deux opérations clés :
|
||||
1. **Description enrichie** : Elle rédige un résumé détaillé de la scène ou du document pour améliorer l'accessibilité et la compréhension.
|
||||
2. **Génération de Tags** : Elle attribue entre 5 et 10 mots-clés (tags) pertinents qui seront indexés en base de données, rendant l'image facilement trouvable lors des recherches futures.
|
||||
|
||||
---
|
||||
|
||||
## 💻 3. Le Portail d'Administration
|
||||
|
||||
Le panel Admin (React) est accessible par défaut sur `http://localhost:3000`.
|
||||
|
||||
### Tableau de Bord
|
||||
Le tableau de bord centralise toutes les images importées. Il permet de :
|
||||
- Naviguer paginer parmi les milliers d'images gérées.
|
||||
- Voir en un coup d'œil quelles images sont encore en cours de traitement, ont échoué ou sont validées.
|
||||
- Filtrer par les Tags générés par l'IA.
|
||||
|
||||
### Visionneuse Détaillée
|
||||
En cliquant sur une image, vous avez accès à une vue à 360° :
|
||||
- L'image originale et sa miniature.
|
||||
- **L'onglet "Sources & EXIF"** : Données de géolocalisation pour retracer le parcours de la photo, spécificités techniques (ouverture, ISO, modèle d'appareil).
|
||||
- **L'onglet "Texte & IA"** : Le dictionnaire des termes générés par l'OCR et le résumé humain traduit.
|
||||
|
||||
### Gestion des Clients (Multi-tenancy)
|
||||
*(Si vous possédez la permission `admin`)*
|
||||
- Vous pouvez gérer les accès API directement depuis l'interface.
|
||||
- Créer de nouveaux espaces (clients), générer des clés API et imputer des quotas (free, standard, premium) limitant le taux horaire de requêtes par tenant.
|
||||
|
||||
---
|
||||
|
||||
## 🔗 4. Interagir avec l'API
|
||||
|
||||
Tous les endpoints nécessitent une clé API valide (fournie par l'admin) transmise via le header d'Auth :
|
||||
`Authorization: Bearer <votre_cle>`
|
||||
|
||||
Pour le catalogue exhaustif des endpoints (Upload, Recherche, AI standalone), référez-vous au :
|
||||
👉 **[Guide détaillé de l'API (API_GUIDE.md)](API_GUIDE.md)**
|
||||
|
||||
### Résumé rapide des endpoints utiles :
|
||||
| Action | Endpoint REST | Exemple d'Usage |
|
||||
|--------|----------------------|-----------------|
|
||||
| Envoyer | `POST /api/v1/images/upload` | Intégrer depuis votre app mobile. |
|
||||
| Chercher| `GET /api/v1/images?search=voiture` | Trouver une image via l'OCR ou les tags IA. |
|
||||
| Santé | `GET /health/detailed` | Surveiller l'état de Redis, DB, et MinIO. |
|
||||
@@ -0,0 +1,33 @@
|
||||
# WebSockets & Real-Time Events
|
||||
|
||||
Imago uses WebSockets and Redis Pub/Sub to provide real-time updates for asynchronous tasks (e.g. image OCR, EXIF extraction, AI summarization).
|
||||
|
||||
## Endpoints
|
||||
|
||||
All WebSockets endpoints wait for events from the `arq` queue. They require an authentication token to be passed via the `token` query parameter.
|
||||
|
||||
### 1. Per-Image Pipeline Events
|
||||
**Endpoint:** `ws://localhost:8000/ws/pipeline/{image_id}?token=YOUR_API_KEY`
|
||||
|
||||
This endpoint streams events related to a specific image. If the image is already fully processed when you connect, the server will immediately yield an artificial `{"event": "pipeline.done", "status": "completed"}` event and the connection may close, ensuring you never miss the final state.
|
||||
|
||||
**Required Scopes:** `images:read` AND the image must belong to the client (unless the client is an Admin).
|
||||
|
||||
#### Example Events
|
||||
```json
|
||||
{"event": "pipeline.started"}
|
||||
{"event": "task.exif.started"}
|
||||
{"event": "task.exif.done"}
|
||||
{"event": "pipeline.done", "status": "completed"}
|
||||
```
|
||||
|
||||
### 2. Global Admin Monitor
|
||||
**Endpoint:** `ws://localhost:8000/ws/admin/monitor?token=YOUR_ADMIN_KEY`
|
||||
|
||||
This endpoint streams high-level pipeline events (start, done, error) for ALL images across the system. It is meant for admin dashboards to display live activity feeds.
|
||||
|
||||
**Required Scopes:** `admin`
|
||||
|
||||
## Event Buffering
|
||||
|
||||
If your client disconnects and reconnects briefly, it might miss events. Imago buffers the last 10 events for each active image pipeline in Redis with a 60-second TTL. When a client connects to the per-image endpoint, any buffered events that were recorded before the WebSocket fully opened are immediately flushed down the socket, enabling seamless UI updates.
|
||||
Reference in New Issue
Block a user