Ce document fournit des exemples concrets d'utilisation de l'API Re:Member avec différents langages et outils.
Toutes les requêtes (sauf /auth/register et /auth/login) nécessitent un token JWT dans le header Authorization.
curl -X POST http://localhost:5000/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"username": "john_doe",
"password": "secure_password123"
}'Réponse :
{
"message": "Utilisateur créé avec succès",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 1,
"username": "john_doe",
"created_at": "2025-10-14T12:00:00"
}
}curl -X POST http://localhost:5000/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "john_doe",
"password": "secure_password123"
}'curl -X POST http://localhost:5000/api/media/upload \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "file=@/path/to/photo.jpg" \
-F "file_type=photo" \
-F "entry_date=2025-10-14"import requests
url = "http://localhost:5000/api/media/upload"
headers = {"Authorization": "Bearer YOUR_TOKEN"}
files = {
'file': open('/path/to/video.mp4', 'rb')
}
data = {
'file_type': 'video',
'entry_date': '2025-10-14'
}
response = requests.post(url, headers=headers, files=files, data=data)
print(response.json())const formData = new FormData();
formData.append('file', fileInput.files[0]);
formData.append('file_type', 'photo');
formData.append('entry_date', '2025-10-14');
fetch('http://localhost:5000/api/media/upload', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`
},
body: formData
})
.then(response => response.json())
.then(data => console.log(data));curl -X GET http://localhost:5000/api/media/daily/2025-10-14 \
-H "Authorization: Bearer YOUR_TOKEN"Réponse :
{
"entry": {
"id": 1,
"user_id": 1,
"entry_date": "2025-10-14",
"summary": {
"location": "Paris",
"events": ["Visite du Louvre", "Dîner au restaurant"],
"people": ["Marie", "Pierre"],
"emotions": "joyful"
},
"picture_of_day_path": "/uploads/pictures_of_day/picture_20251014.png",
"media_count": 5
},
"media_files": [
{
"id": 1,
"file_type": "photo",
"file_path": "/uploads/photos/20251014_120000_louvre.jpg",
"uploaded_at": "2025-10-14T12:00:00"
}
]
}curl -X GET http://localhost:5000/api/media/entries \
-H "Authorization: Bearer YOUR_TOKEN"curl -X POST http://localhost:5000/api/ai/generate-summary \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"entry_id": 1
}'Réponse :
{
"message": "Résumé généré avec succès",
"summary": {
"date": "2025-10-14",
"location": "Paris, France",
"people": ["Marie", "Pierre"],
"events": ["Visite du Louvre", "Dîner au restaurant"],
"emotions": "joyful",
"key_moments": [
"Découverte de la Joconde",
"Coucher de soleil sur la Seine"
],
"tags": ["culture", "art", "gastronomie", "amis"]
}
}curl -X POST http://localhost:5000/api/ai/picture-of-day \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"entry_id": 1
}'curl -X POST http://localhost:5000/api/ai/extract-voice \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"video_path": "/uploads/videos/20251014_150000_interview.mp4",
"voice_name": "Ma Voix Interview"
}'Réponse :
{
"message": "Voix extraite et clonée avec succès",
"voice": {
"id": 1,
"label": "Ma Voix Interview",
"audio_file_path": "/uploads/audio/20251014_150000_interview_extracted.mp3",
"elevenlabs_voice_id": "voice_abc123xyz",
"created_at": "2025-10-14T15:30:00"
}
}curl -X POST http://localhost:5000/api/ai/extract-audio \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"video_path": "/uploads/videos/20251014_150000_vlog.mp4"
}'curl -X POST http://localhost:5000/api/chat/message \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": "Où étais-je le 14 octobre ?"
}'Réponse :
{
"response": "Le 14 octobre, vous étiez à Paris. Vous avez visité le Louvre avec Marie et Pierre, puis vous avez dîné dans un restaurant. La journée semble avoir été joyeuse, avec des moments marquants comme la découverte de la Joconde et un magnifique coucher de soleil sur la Seine.",
"context_entries": [1]
}curl -X GET "http://localhost:5000/api/chat/history?limit=20" \
-H "Authorization: Bearer YOUR_TOKEN"import requests
url = "http://localhost:5000/api/chat/message"
headers = {
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json"
}
data = {
"message": "Quels sont mes souvenirs avec Marie ?"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
print(f"Réponse: {result['response']}")
print(f"Entrées utilisées: {result['context_entries']}")curl -X GET http://localhost:5000/api/voices/ \
-H "Authorization: Bearer YOUR_TOKEN"curl -X POST http://localhost:5000/api/voices/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"label": "Voix Professionnelle",
"audio_file_path": "/uploads/audio/voice_sample.mp3",
"elevenlabs_voice_id": "voice_xyz789"
}'curl -X PUT http://localhost:5000/api/voices/1 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"label": "Voix Professionnelle V2"
}'curl -X DELETE http://localhost:5000/api/voices/1 \
-H "Authorization: Bearer YOUR_TOKEN"curl -X GET http://localhost:5000/api/admin/config \
-H "Authorization: Bearer YOUR_TOKEN"Réponse :
{
"config": {
"id": 1,
"user_id": 1,
"has_elevenlabs_key": true,
"has_gemini_key": true,
"system_prompt": "You are a helpful AI assistant...",
"updated_at": "2025-10-14T12:00:00"
}
}curl -X PUT http://localhost:5000/api/admin/config \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"elevenlabs_key": "sk_elevenlabs_...",
"gemini_key": "AIza...",
"system_prompt": "Tu es un assistant IA français qui aide les utilisateurs à se souvenir de leurs souvenirs."
}'curl -X GET http://localhost:5000/api/admin/stats \
-H "Authorization: Bearer YOUR_TOKEN"Réponse :
{
"stats": {
"total_entries": 15,
"total_media": 47,
"total_voices": 3,
"total_chats": 28,
"media_by_type": {
"photo": 25,
"video": 12,
"audio": 8,
"text": 2
}
}
}Voici un exemple de workflow complet avec Python :
import requests
from datetime import date
BASE_URL = "http://localhost:5000/api"
# 1. Inscription
register_data = {
"username": "alice",
"password": "secure123"
}
response = requests.post(f"{BASE_URL}/auth/register", json=register_data)
token = response.json()["token"]
headers = {"Authorization": f"Bearer {token}"}
# 2. Configuration des clés API
config_data = {
"elevenlabs_key": "sk_elevenlabs_...",
"gemini_key": "AIza...",
"system_prompt": "Tu es mon assistant mémoire personnel."
}
requests.put(f"{BASE_URL}/admin/config", headers=headers, json=config_data)
# 3. Upload d'une photo
with open("vacation_photo.jpg", "rb") as f:
files = {"file": f}
data = {
"file_type": "photo",
"entry_date": str(date.today())
}
response = requests.post(f"{BASE_URL}/media/upload", headers=headers, files=files, data=data)
print(f"Photo uploadée: {response.json()}")
# 4. Upload d'une vidéo
with open("vacation_video.mp4", "rb") as f:
files = {"file": f}
data = {
"file_type": "video",
"entry_date": str(date.today())
}
response = requests.post(f"{BASE_URL}/media/upload", headers=headers, files=files, data=data)
video_path = response.json()["media"]["file_path"]
# 5. Récupérer l'entrée du jour
response = requests.get(f"{BASE_URL}/media/daily/{date.today()}", headers=headers)
entry = response.json()["entry"]
entry_id = entry["id"]
# 6. Générer le résumé
summary_data = {"entry_id": entry_id}
response = requests.post(f"{BASE_URL}/ai/generate-summary", headers=headers, json=summary_data)
summary = response.json()["summary"]
print(f"Résumé généré: {summary}")
# 7. Générer l'image du jour
picture_data = {"entry_id": entry_id}
response = requests.post(f"{BASE_URL}/ai/picture-of-day", headers=headers, json=picture_data)
print(f"Image générée: {response.json()}")
# 8. Extraire la voix de la vidéo
voice_data = {
"video_path": video_path,
"voice_name": "Ma voix de vacances"
}
response = requests.post(f"{BASE_URL}/ai/extract-voice", headers=headers, json=voice_data)
print(f"Voix extraite: {response.json()}")
# 9. Poser une question au chat
chat_data = {"message": "Qu'ai-je fait aujourd'hui ?"}
response = requests.post(f"{BASE_URL}/chat/message", headers=headers, json=chat_data)
print(f"Réponse du chat: {response.json()['response']}")
# 10. Consulter les statistiques
response = requests.get(f"{BASE_URL}/admin/stats", headers=headers)
stats = response.json()["stats"]
print(f"Statistiques: {stats}")L'API retourne des codes HTTP standard :
- 200 : Succès
- 201 : Créé avec succès
- 400 : Requête invalide
- 401 : Non authentifié
- 403 : Accès refusé
- 404 : Ressource non trouvée
- 409 : Conflit (ex: username déjà utilisé)
- 500 : Erreur serveur
Exemple de gestion d'erreur en Python :
try:
response = requests.post(url, headers=headers, json=data)
response.raise_for_status()
result = response.json()
except requests.exceptions.HTTPError as e:
print(f"Erreur HTTP: {e}")
print(f"Message: {response.json().get('message', 'Erreur inconnue')}")
except requests.exceptions.RequestException as e:
print(f"Erreur de connexion: {e}")Actuellement, l'API n'implémente pas de rate limiting. En production, il est recommandé d'ajouter des limites pour éviter les abus.
Dans une version future, l'API pourrait supporter des webhooks pour notifier des événements :
- Résumé généré
- Image du jour créée
- Voix extraite avec succès
Pour plus d'informations, consultez le fichier README.md principal.