Ajout Effi-OCR (Tesseract) + Web Scraper pour OpenWebUI
- Effi-OCR: Service OCR avec Tesseract (multilingue FR/EN) * API FastAPI sur port 8300 * Prétraitement images (contraste, niveaux de gris) * Tool OpenWebUI intégré - Web Scraper: Service Python (BeautifulSoup) sur port 11235 * Alternative à Crawl4AI (incompatible ARM64/J5040) * Scraping HTML basique mais fonctionnel * Intégré au docker-compose d'effi-server - Documentation: * ROADMAP-FONCTIONNALITES.md: Plan des 9 fonctionnalités * WEB-SCRAPER-CONFIG.md: Configuration OpenWebUI * WEB-SCRAPER-TOOL.md: Code du Tool - Script start-all-services.sh mis à jour (6 services)
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
# Tool OCR pour OpenWebUI
|
||||
|
||||
## Configuration
|
||||
|
||||
Dans OpenWebUI (http://192.168.1.27:3000) :
|
||||
|
||||
1. **Aller dans** : Admin → Tools → Create Tool
|
||||
2. **Nom** : OCR Extracteur de Texte
|
||||
3. **ID** : ocr_extractor
|
||||
4. **Description** : Extrait le texte des images pour les livres et documents
|
||||
|
||||
## Code du Tool
|
||||
|
||||
```python
|
||||
from typing import Optional
|
||||
import requests
|
||||
import base64
|
||||
import os
|
||||
|
||||
class Tools:
|
||||
def __init__(self):
|
||||
"""Initialize OCR Tool"""
|
||||
self.ocr_url = os.getenv("OCR_URL", "http://192.168.1.11:8300")
|
||||
|
||||
def extract_text_from_image(self, image_path: str, language: str = "fra") -> str:
|
||||
"""
|
||||
Extract text from an image file using OCR
|
||||
|
||||
Args:
|
||||
image_path: Path to the image file (jpg, png, etc.)
|
||||
language: Language code (fra, eng, fra+eng, etc.)
|
||||
|
||||
Returns:
|
||||
Extracted text from the image
|
||||
"""
|
||||
try:
|
||||
# Read image file
|
||||
with open(image_path, 'rb') as f:
|
||||
files = {'file': f}
|
||||
data = {'lang': language}
|
||||
|
||||
response = requests.post(
|
||||
f"{self.ocr_url}/ocr",
|
||||
files=files,
|
||||
data=data,
|
||||
timeout=30
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
if result.get('success'):
|
||||
text = result.get('text', '')
|
||||
char_count = result.get('characters_count', 0)
|
||||
word_count = result.get('words_count', 0)
|
||||
return f"Texte extrait ({char_count} caractères, {word_count} mots):\n\n{text}"
|
||||
else:
|
||||
return f"Erreur OCR: {result.get('error', 'Unknown error')}"
|
||||
else:
|
||||
return f"Erreur HTTP {response.status_code}: {response.text}"
|
||||
|
||||
except FileNotFoundError:
|
||||
return f"Erreur: Fichier non trouvé: {image_path}"
|
||||
except Exception as e:
|
||||
return f"Erreur lors de l'OCR: {str(e)}"
|
||||
|
||||
def extract_text_from_base64(self, image_base64: str, language: str = "fra") -> str:
|
||||
"""
|
||||
Extract text from a base64 encoded image
|
||||
|
||||
Args:
|
||||
image_base64: Base64 encoded image string
|
||||
language: Language code (fra, eng, fra+eng, etc.)
|
||||
|
||||
Returns:
|
||||
Extracted text from the image
|
||||
"""
|
||||
try:
|
||||
response = requests.post(
|
||||
f"{self.ocr_url}/ocr/base64",
|
||||
json={
|
||||
'image_base64': image_base64,
|
||||
'lang': language,
|
||||
'preprocess': True
|
||||
},
|
||||
timeout=30
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
if result.get('success'):
|
||||
text = result.get('text', '')
|
||||
char_count = result.get('characters_count', 0)
|
||||
word_count = result.get('words_count', 0)
|
||||
return f"Texte extrait ({char_count} caractères, {word_count} mots):\n\n{text}"
|
||||
else:
|
||||
return f"Erreur OCR: extraction échouée"
|
||||
else:
|
||||
return f"Erreur HTTP {response.status_code}: {response.text}"
|
||||
|
||||
except Exception as e:
|
||||
return f"Erreur lors de l'OCR: {str(e)}"
|
||||
|
||||
def get_available_languages(self) -> str:
|
||||
"""
|
||||
Get list of available OCR languages
|
||||
|
||||
Returns:
|
||||
List of available language codes
|
||||
"""
|
||||
try:
|
||||
response = requests.get(f"{self.ocr_url}/languages", timeout=10)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
languages = result.get('available_languages', [])
|
||||
return f"Langues disponibles: {', '.join(languages)}"
|
||||
else:
|
||||
return f"Erreur: {response.status_code}"
|
||||
|
||||
except Exception as e:
|
||||
return f"Erreur: {str(e)}"
|
||||
```
|
||||
|
||||
## Variables d'environnement
|
||||
|
||||
Dans les Settings d'OpenWebUI (Admin → Settings → Environment Variables) :
|
||||
|
||||
```
|
||||
OCR_URL=http://192.168.1.11:8300
|
||||
```
|
||||
|
||||
## Utilisation
|
||||
|
||||
Une fois le Tool créé, les agents pourront l'utiliser avec ces fonctions :
|
||||
|
||||
- `extract_text_from_image("/chemin/vers/image.jpg", "fra")` - Extraire le texte d'un fichier image
|
||||
- `extract_text_from_base64("base64encoded...", "fra")` - Extraire d'une image encodée en base64
|
||||
- `get_available_languages()` - Lister les langues disponibles
|
||||
|
||||
## Exemple de prompt
|
||||
|
||||
```
|
||||
"Effi, lis-moi ce texte" [upload d'image]
|
||||
→ L'agent utilise automatiquement le Tool OCR
|
||||
```
|
||||
|
||||
## Langues disponibles
|
||||
|
||||
- `fra` - Français
|
||||
- `eng` - Anglais
|
||||
- `fra+eng` - Français + Anglais (bilingue)
|
||||
- `deu` - Allemand
|
||||
- `spa` - Espagnol
|
||||
- `ita` - Italien
|
||||
|
||||
## Dépannage
|
||||
|
||||
**Erreur de connexion** :
|
||||
```bash
|
||||
# Vérifier que le service OCR tourne
|
||||
curl http://192.168.1.11:8300/health
|
||||
|
||||
# Redémarrer si nécessaire
|
||||
cd ~/Documents/OpenCode/Projets/Effi/effi-ocr
|
||||
sudo docker compose restart
|
||||
```
|
||||
|
||||
**Texte mal extrait** :
|
||||
- Essayer `fra+eng` pour les documents bilingues
|
||||
- Vérifier la qualité de l'image (résolution, contraste)
|
||||
- L'OCR fonctionne mieux avec des images bien éclairées
|
||||
|
||||
---
|
||||
|
||||
*Tool créé le 6 Avril 2026*
|
||||
Reference in New Issue
Block a user