OCR — Dokumentenerkennung¶
Uebersicht¶
Der OCR-Service bietet universelle Dokumentenerkennung mit austauschbaren Providern.
Verfuegbare Provider:
| Provider | Typ | Default | Strukturierte Extraktion | Beschreibung |
|---|---|---|---|---|
| Surya OCR | Lokal (GPU) | Ja | Nein | GPU-beschleunigte lokale OCR — kein Cloud-Dienst, keine API-Kosten |
| Mistral OCR 3 | Cloud-API | Nein | Ja (JSON-Schema) | Mistral AI Cloud OCR mit strukturierter Datenextraktion |
- Prefix:
/api/v1/ocr/ - Permissions:
ocr.read,ocr.process - Provider-Architektur: Abstract Factory — neue Provider ohne API-Aenderung ergaenzbar
Unterstuetzte Formate¶
| Format | Surya | Mistral |
|---|---|---|
| ✔ | ✔ | |
| PNG | ✔ | ✔ |
| JPEG | ✔ | ✔ |
| WebP | ✔ | ✔ |
| GIF | ✔ | ✔ |
| BMP | ✔ | ✔ |
| TIFF | ✔ | ✔ |
| AVIF | — | ✔ |
| DOCX | — | ✔ |
| PPTX | — | ✔ |
Max. Dateigroesse: 50 MB
Endpoints¶
Provider auflisten¶
Permission: ocr.read
Gibt alle registrierten OCR-Provider mit Verfuegbarkeitsstatus zurueck.
Response:
[
{
"type": "surya",
"name": "Surya OCR (Lokal)",
"description": "Lokale Dokumentenerkennung mit GPU-Beschleunigung — kein Cloud-Dienst",
"supported_formats": ["pdf", "png", "jpg", "jpeg", "webp", "gif", "bmp", "tiff"],
"supports_structured": false,
"available": true,
"is_default": true
},
{
"type": "mistral",
"name": "Mistral OCR 3 (Cloud)",
"description": "Mistral AI Dokumentenerkennung — Cloud-API, strukturierte Extraktion",
"supported_formats": ["pdf", "png", "jpg", "jpeg", "webp", "gif", "bmp", "tiff", "avif", "docx", "pptx"],
"supports_structured": true,
"available": true,
"is_default": false
}
]
Dokument verarbeiten¶
Permission: ocr.process
OCR-Verarbeitung eines Dokuments. Gibt Markdown pro Seite zurueck.
Request Body:
{
"document": {
"type": "url",
"data": "https://example.com/rechnung.pdf",
"filename": "rechnung.pdf",
"mime_type": "application/pdf"
},
"provider": "surya",
"pages": [0, 1],
"table_format": "markdown",
"include_images": false,
"extract_headers": true,
"extract_footers": true,
"language_hint": "de"
}
Eingabe-Typen (document.type):
| Typ | Beschreibung | data-Feld |
|---|---|---|
url |
Dokument-URL | HTTPS-URL zum Dokument |
base64 |
Base64-kodiert | Base64-String des Dokuments |
file_id |
Mistral File-ID | ID einer hochgeladenen Datei (nur Mistral) |
Optionen:
| Feld | Typ | Default | Beschreibung |
|---|---|---|---|
provider |
string | surya |
OCR-Provider (surya oder mistral) |
pages |
int[] | alle | Bestimmte Seiten (0-basiert) |
table_format |
string | null | markdown oder html |
include_images |
bool | false | Bilder als Base64 extrahieren (nur Mistral) |
extract_headers |
bool | false | Kopfzeilen extrahieren (nur Mistral) |
extract_footers |
bool | false | Fusszeilen extrahieren (nur Mistral) |
language_hint |
string | null | Sprachhinweis (z.B. de) |
Response:
{
"pages": [
{
"index": 0,
"markdown": "# Rechnung Nr. 2025-001\n\n| Position | Betrag |\n|---|---|\n| Hosting | 29,90 EUR |",
"images": [],
"header": null,
"footer": null,
"dimensions": {
"dpi": 300,
"height": 3507,
"width": 2480
}
}
],
"usage": {
"pages_processed": 1,
"provider": "surya",
"model": "surya"
},
"document_annotation": null,
"processed_at": "2026-03-12T14:30:00Z"
}
Strukturierte Extraktion¶
Permission: ocr.process
Extrahiert strukturierte Daten anhand eines JSON-Schemas (z.B. Rechnungsdaten).
Nur Mistral
Strukturierte Extraktion ist nur mit dem Mistral-Provider verfuegbar. Surya gibt null als document_annotation zurueck.
Request Body:
{
"document": {
"type": "url",
"data": "https://example.com/rechnung.pdf"
},
"provider": "mistral",
"schema_definition": {
"name": "invoice",
"schema": {
"type": "object",
"properties": {
"invoice_number": {"type": "string"},
"date": {"type": "string"},
"total": {"type": "number"},
"line_items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"description": {"type": "string"},
"amount": {"type": "number"}
}
}
}
}
}
},
"extraction_prompt": "Extrahiere alle Rechnungsdaten"
}
Datei hochladen + OCR¶
Permission: ocr.process
Datei direkt hochladen (Multipart) und OCR verarbeiten. Ideal fuer Frontend-Integration.
Form-Parameter:
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
file |
File | ja | Dokument (max. 50 MB) |
provider |
string | nein | Provider (default: surya) |
table_format |
string | nein | markdown oder html |
include_images |
bool | nein | Bilder extrahieren |
cURL Beispiel:
# Surya (lokal, Default)
curl -X POST https://platform.xynap.tech/api/v1/ocr/upload \
-H "Authorization: Bearer <token>" \
-F "file=@rechnung.pdf"
# Mistral (Cloud)
curl -X POST https://platform.xynap.tech/api/v1/ocr/upload \
-H "Authorization: Bearer <token>" \
-F "file=@rechnung.pdf" \
-F "provider=mistral" \
-F "table_format=markdown"
Architektur¶
Provider-Pattern¶
BaseOcrProvider (Abstract)
|
+-- SuryaOcrProvider (lokal, GPU — Default)
+-- MistralOcrProvider (mistral-ocr-latest, Cloud)
+-- [Kuenftige Provider] (z.B. Google Document AI, PaddleOCR)
Neue Provider implementieren BaseOcrProvider mit zwei Methoden:
process()— Standard-OCR (Markdown-Ausgabe)process_structured()— OCR mit JSON-Schema-Extraktion
Dateien¶
| Datei | Beschreibung |
|---|---|
app/core/ocr/base.py |
Abstrakte Provider-Schnittstelle |
app/core/ocr/factory.py |
Provider-Factory |
app/core/ocr/surya.py |
Surya OCR (lokal, GPU) |
app/core/ocr/mistral.py |
Mistral OCR 3 (Cloud) |
app/core/ocr/schemas.py |
Pydantic Request/Response Modelle |
app/core/ocr/router.py |
FastAPI Endpoints |
Konfiguration¶
Surya (Lokal)¶
Surya benoetigt keinen API-Key. GPU-Einstellungen:
TORCH_DEVICE=cuda # GPU-Backend (cuda/cpu)
RECOGNITION_BATCH_SIZE=128 # Batch-Groesse OCR (RTX 4000: 128)
DETECTOR_BATCH_SIZE=18 # Batch-Groesse Detektion
Modelle werden beim ersten Aufruf automatisch heruntergeladen (~1.5 GB) und unter /root/.cache/datalab gecacht.
Im Docker-Container wird /var/lib/xynap/surya-models als persistentes Volume gemountet.
Mistral (Cloud)¶
Der Mistral API-Key wird ueber eine der folgenden Quellen geladen (Prioritaet):
- Secret Store:
ocr.mistral_api_key - Umgebungsvariable:
MISTRAL_API_KEY
Berechtigungen¶
| Permission | Rollen | Beschreibung |
|---|---|---|
ocr.read |
admin, reseller, customer, user | Provider-Liste abrufen |
ocr.process |
admin, reseller, customer, user | Dokumente verarbeiten |
super_admin
Super-Admins haben implizit Zugriff auf alle Permissions.
Neuen Provider hinzufuegen¶
- Provider-Klasse erstellen (erbt von
BaseOcrProvider) OcrProviderTypeEnum erweitern inschemas.py- Factory in
factory.pyerweitern - API-Key ueber Secret Store oder Env-Var bereitstellen (falls Cloud-Provider)
- Provider-Info in
list_providers()ergaenzen - Tests erweitern
- Service-Register aktualisieren (
/home/admin/docs/services/ocr.md)