|
import gradio as gr |
|
import json |
|
import requests |
|
import tempfile |
|
from datetime import datetime, time |
|
import os |
|
import google.generativeai as genai |
|
from typing import Optional, Tuple |
|
|
|
|
|
UPDATED_MODELS = { |
|
"OpenAI": [ |
|
|
|
"gpt-4.1", "gpt-4.1-mini", "gpt-4.1-nano", |
|
|
|
"o3-pro", "o3", "o3-mini", "o4-mini", "o1", "o1-preview", "o1-pro", "o1-mini", |
|
|
|
"gpt-4.5-preview", "gpt-4o", "gpt-4o-mini", "gpt-4-turbo", "gpt-3.5-turbo", |
|
|
|
"gpt-4", "gpt-4-vision-preview", "gpt-3.5-turbo-16k" |
|
], |
|
"Anthropic": [ |
|
|
|
"claude-opus-4-20250514", "claude-sonnet-4-20250514", |
|
|
|
"claude-3-7-sonnet-20250219", "claude-3-7-sonnet-latest", |
|
|
|
"claude-3-5-sonnet-20241022", "claude-3-5-sonnet-20240620", "claude-3-5-haiku-20241022", |
|
|
|
"claude-3-opus-20240229", "claude-3-sonnet-20240229", "claude-3-haiku-20240307" |
|
], |
|
"Google AI": [ |
|
|
|
"gemini-2.5-pro 🆓", "gemini-2.5-flash 🆓", "gemini-2.5-flash-lite 🆓", |
|
"gemini-2.5-flash-preview-native-audio-dialog", "gemini-2.5-flash-preview-tts", "gemini-2.5-pro-preview-tts", |
|
|
|
"gemini-2.0-flash 🆓", "gemini-2.0-flash-preview-image-generation", "gemini-2.0-flash-lite 🆓", "gemini-2.0-pro-experimental", |
|
|
|
"gemini-1.5-pro", "gemini-1.5-flash", "gemini-1.5-flash-8b", |
|
|
|
"gemini-pro", "gemini-pro-vision" |
|
], |
|
"Cohere": [ |
|
"command-r", "command-r-plus", "command-r-08-2024", "command-r-plus-08-2024", |
|
"command", "command-light", "command-nightly", "aya-23-35b", "aya-23-8b" |
|
], |
|
"Mistral AI": [ |
|
"mistral-medium-3", "mistral-small-3", "mistral-tiny-3", "magistral-medium", "magistral-small", |
|
"ministral-3b 🆓", "ministral-8b 🆓", "mistral-large", "mistral-medium", "mistral-small", "mistral-tiny", |
|
"mixtral-8x7b-instruct", "mixtral-8x22b-instruct" |
|
], |
|
"Together AI": [ |
|
"meta-llama/Llama-4-Scout 🆓", "meta-llama/Llama-4-Maverick 🆓", |
|
"meta-llama/Llama-3.3-70B-Instruct 🆓", "meta-llama/Llama-3.3-Nemotron-Super-49B", |
|
"meta-llama/Llama-3.1-405B-Instruct", "meta-llama/Llama-3.1-70B-Instruct", "meta-llama/Llama-3.1-8B-Instruct 🆓", |
|
"Qwen/Qwen3-235B", "Qwen/Qwen3-32B 🆓", "Qwen/Qwen3-14B 🆓", "Qwen/Qwen3-8B 🆓", "Qwen/Qwen3-4B", |
|
"Qwen/QwQ-32B-Preview 🆓", "Qwen/Qwen2.5-Max", |
|
"deepseek-ai/DeepSeek-V3 🆓", "deepseek-ai/DeepSeek-R1 🆓", "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B 🆓" |
|
], |
|
"Groq": [ |
|
"llama-3.3-70b-versatile 🆓", "llama-3.1-405b-reasoning", "llama-3.1-70b-versatile 🆓", "llama-3.1-8b-instant 🆓", |
|
"mixtral-8x7b-32768 🆓", "mixtral-8x22b-instruct", "gemma2-9b-it 🆓", "gemma-7b-it 🆓" |
|
], |
|
"xAI": [ |
|
"grok-3", "grok-3-mini", "grok-3-reasoning-beta", "grok-2", "grok-2-mini", "grok-2-vision" |
|
], |
|
"DeepSeek": [ |
|
"deepseek-r1 🆓", "deepseek-r1-distill-qwen-32b 🆓", "deepseek-r1-distill-qwen-14b 🆓", "deepseek-r1-distill-llama-70b 🆓", |
|
"deepseek-v3 🆓", "deepseek-v2.5", "deepseek-v2", "deepseek-coder-v2", "deepseek-coder-33b" |
|
], |
|
"Perplexity AI": [ |
|
"sonar-reasoning", "sonar", "sonar-pro", "pplx-7b-online", "pplx-70b-online", "pplx-7b-chat", "pplx-70b-chat" |
|
], |
|
"Amazon": ["nova-premier", "nova-pro", "nova-lite", "nova-micro"], |
|
"Reka AI": ["reka-flash-3", "reka-core", "reka-edge"] |
|
} |
|
|
|
|
|
FREE_MODELS_INFO = { |
|
"gemini-2.5-flash 🆓": { |
|
"provider": "Google AI Studio", |
|
"performance": "⭐⭐⭐⭐⭐ (Excellent, multimodal, très rapide)", |
|
"specialties": "Texte + images, vitesse, conversations longues", |
|
"limits": "1M tokens/min, 1500 req/jour", |
|
"conditions": "Compte Google gratuit. Données utilisées pour entraînement (hors UE/UK)", |
|
"signup": "https://ai.google.dev", |
|
"recommended": True, |
|
"default_available": True |
|
}, |
|
"deepseek-r1 🆓": { |
|
"provider": "DeepSeek + OpenRouter", |
|
"performance": "⭐⭐⭐⭐⭐ (Rivalise avec GPT-4o)", |
|
"specialties": "Raisonnement, mathématiques, programmation", |
|
"limits": "OpenRouter: 50 req/jour (1000 avec $10 crédit) | DeepSeek direct: Limites généreuses", |
|
"conditions": "Compte gratuit requis. Sur OpenRouter: données utilisées pour entraînement", |
|
"signup": "DeepSeek: https://platform.deepseek.com | OpenRouter: https://openrouter.ai", |
|
"recommended": True |
|
} |
|
} |
|
|
|
|
|
DEFAULT_API_QUOTA = 1500 |
|
current_quota = DEFAULT_API_QUOTA |
|
quota_reset_time = None |
|
default_api_available = True |
|
|
|
def load_updated_models(): |
|
"""Charge les modèles depuis le fichier JSON mis à jour ou utilise la configuration actualisée""" |
|
try: |
|
if os.path.exists('models_config.json'): |
|
with open('models_config.json', 'r', encoding='utf-8') as f: |
|
data = json.load(f) |
|
return data.get('models', UPDATED_MODELS), data.get('last_updated', 'Inconnu') |
|
|
|
config_url = "https://raw.githubusercontent.com/votre-username/votre-repo/main/models_config.json" |
|
response = requests.get(config_url, timeout=5) |
|
if response.status_code == 200: |
|
data = response.json() |
|
return data.get('models', UPDATED_MODELS), data.get('last_updated', 'Inconnu') |
|
|
|
except Exception as e: |
|
print(f"Erreur lors du chargement des modèles mis à jour: {e}") |
|
|
|
return UPDATED_MODELS, "Configuration mise à jour - Juin 2025" |
|
|
|
def get_default_api_key() -> Optional[str]: |
|
"""Récupère la clé API par défaut depuis les secrets Hugging Face""" |
|
return os.getenv("GOOGLE_API_KEY") |
|
|
|
def check_quota_status() -> Tuple[bool, int, str]: |
|
"""Vérifie le statut du quota de l'API par défaut""" |
|
global current_quota, quota_reset_time, default_api_available |
|
|
|
now = datetime.now() |
|
|
|
if quota_reset_time is None or now.date() > quota_reset_time.date(): |
|
current_quota = DEFAULT_API_QUOTA |
|
quota_reset_time = datetime.combine(now.date().replace(day=now.day + 1), time.min) |
|
default_api_available = True |
|
|
|
if current_quota <= 0: |
|
default_api_available = False |
|
hours_until_reset = (quota_reset_time - now).total_seconds() / 3600 |
|
status_msg = f"🚫 API par défaut épuisée. Réinitialisation dans {hours_until_reset:.1f}h" |
|
else: |
|
default_api_available = True |
|
status_msg = f"✅ API par défaut disponible" |
|
|
|
return default_api_available, current_quota, status_msg |
|
|
|
def update_models(company): |
|
"""Met à jour la liste des modèles selon l'entreprise sélectionnée""" |
|
global default_api_available |
|
|
|
if company in CURRENT_MODELS: |
|
models = CURRENT_MODELS[company] |
|
default_value = None |
|
if default_api_available and company == "Google AI": |
|
default_value = "gemini-2.5-flash 🆓" |
|
elif models: |
|
default_value = models[0] if not default_api_available else None |
|
|
|
return gr.Dropdown( |
|
choices=models, |
|
value=default_value, |
|
label="🧠 Modèle LLM", |
|
interactive=True |
|
) |
|
return gr.Dropdown(choices=[], label="🧠 Modèle LLM", interactive=True) |
|
|
|
def update_model_info(model): |
|
"""Met à jour les informations du modèle sélectionné""" |
|
if not model: |
|
return "Sélectionnez un modèle pour voir ses informations." |
|
|
|
if model in FREE_MODELS_INFO: |
|
info = FREE_MODELS_INFO[model] |
|
default_api_info = "" |
|
|
|
if model == "gemini-2.5-flash 🆓" and default_api_available: |
|
default_api_info = f""" |
|
### 🎁 **API PAR DÉFAUT DISPONIBLE** |
|
Cette app fournit une clé API Google gratuite pour ce modèle ! |
|
- **Quota partagé:** {current_quota}/{DEFAULT_API_QUOTA} requêtes restantes aujourd'hui |
|
- **Réinitialisation:** Chaque jour à minuit |
|
- **Alternative:** Vous pouvez utiliser votre propre clé API Google |
|
|
|
""" |
|
|
|
return f""" |
|
{default_api_info} |
|
### 🆓 **{model}** - MODÈLE GRATUIT |
|
|
|
**🏢 Provider:** {info['provider']} |
|
**📊 Performance:** {info['performance']} |
|
**🎯 Spécialités:** {info['specialties']} |
|
**⏱️ Limites d'usage:** {info['limits']} |
|
**📋 Conditions:** {info['conditions']} |
|
**🔗 Inscription:** {info['signup']} |
|
|
|
{'🌟 **RECOMMANDÉ** - Excellent rapport qualité/gratuité' if info.get('recommended') else ''} |
|
""" |
|
elif "🆓" in model: |
|
return f""" |
|
### 🆓 **{model}** - MODÈLE GRATUIT |
|
|
|
Ce modèle est disponible gratuitement sous certaines conditions. |
|
Consultez la documentation du provider pour les détails spécifiques. |
|
|
|
**⚠️ Important:** Les modèles gratuits nécessitent généralement : |
|
- Un compte gratuit chez le provider |
|
- Acceptation que vos données puissent être utilisées pour l'entraînement |
|
- Respect des limites d'usage quotidiennes/mensuelles |
|
""" |
|
else: |
|
return f""" |
|
### 💰 **{model}** - MODÈLE PAYANT |
|
|
|
Ce modèle nécessite un abonnement ou un paiement à l'usage. |
|
Consultez la tarification du provider pour les coûts exacts. |
|
|
|
**💡 Conseil:** Vérifiez si le provider offre des crédits gratuits pour tester le modèle. |
|
""" |
|
|
|
def generate_selection_file(company, model, user_api_key, use_default_api): |
|
"""Génère un fichier avec les choix effectués - SÉCURISÉ""" |
|
if not company or not model: |
|
return "Veuillez sélectionner une entreprise et un modèle", None, get_quota_display() |
|
|
|
try: |
|
is_free = "🆓" in model |
|
model_clean = model.replace(" 🆓", "") |
|
|
|
|
|
api_config_section = "" |
|
api_status = "" |
|
|
|
if model == "gemini-2.5-flash 🆓" and use_default_api and default_api_available: |
|
|
|
api_status = "🎁 API par défaut utilisée" |
|
api_config_section = """ |
|
🔐 CONFIGURATION API - SÉCURISÉE |
|
=============================== |
|
Type d'API utilisée: API par défaut de l'application |
|
Clé API: [FOURNIE PAR L'APPLICATION - NON AFFICHÉE POUR SÉCURITÉ] |
|
|
|
⚠️ POURQUOI LA CLÉ N'EST PAS AFFICHÉE ? |
|
- La clé API par défaut est stockée de manière sécurisée |
|
- Elle ne doit jamais être exposée aux utilisateurs |
|
- Cela protège le quota partagé contre les abus |
|
|
|
🔑 POUR VOIR UNE CLÉ API DANS CETTE CONFIGURATION : |
|
1. Créez votre compte gratuit sur https://ai.google.dev |
|
2. Générez votre clé API personnelle |
|
3. Saisissez-la dans le champ "Votre clé API" de l'interface |
|
4. Régénérez cette configuration |
|
|
|
AVANTAGES DE VOTRE PROPRE CLÉ API : |
|
✅ Quota personnel complet (1500 req/jour) |
|
✅ Clé visible dans la configuration générée |
|
✅ Contrôle total sur vos données |
|
✅ Pas de partage avec d'autres utilisateurs |
|
|
|
""" |
|
elif user_api_key: |
|
|
|
api_status = "🔑 Votre clé API sera utilisée" |
|
|
|
masked_key = user_api_key[:8] + "..." + user_api_key[-4:] if len(user_api_key) > 12 else "***" |
|
api_config_section = f""" |
|
🔐 CONFIGURATION API - VOTRE CLÉ PERSONNELLE |
|
========================================== |
|
Type d'API: Clé personnelle fournie |
|
Clé API: {user_api_key} |
|
Clé masquée: {masked_key} |
|
|
|
✅ AVANTAGES DE VOTRE CLÉ PERSONNELLE : |
|
- Quota personnel complet |
|
- Contrôle total sur vos données |
|
- Pas de partage avec d'autres utilisateurs |
|
- Clé visible dans cette configuration |
|
|
|
""" |
|
else: |
|
api_status = "⚠️ Aucune clé API configurée" |
|
api_config_section = """ |
|
⚠️ AUCUNE CLÉ API CONFIGURÉE |
|
============================ |
|
Vous devez configurer une clé API pour utiliser ce modèle. |
|
|
|
OPTIONS DISPONIBLES : |
|
1. Utiliser l'API par défaut (Gemini 2.5 Flash uniquement) |
|
2. Créer votre compte et utiliser votre propre clé API |
|
|
|
POUR OBTENIR VOTRE CLÉ API : |
|
- Google AI: https://ai.google.dev |
|
- OpenAI: https://platform.openai.com |
|
- Anthropic: https://console.anthropic.com |
|
- DeepSeek: https://platform.deepseek.com |
|
|
|
""" |
|
|
|
|
|
content = f"""Configuration LLM sélectionnée |
|
===================================== |
|
|
|
Entreprise: {company} |
|
Modèle: {model_clean} |
|
Type: {'GRATUIT 🆓' if is_free else 'PAYANT 💰'} |
|
Statut API: {api_status} |
|
Date de génération: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} |
|
Dernière mise à jour des modèles: {LAST_UPDATE} |
|
|
|
{api_config_section} |
|
""" |
|
|
|
|
|
if model == "gemini-2.5-flash 🆓": |
|
content += f""" |
|
🎁 INFORMATION API PAR DÉFAUT |
|
============================ |
|
Cette application fournit une clé API Google gratuite pour Gemini 2.5 Flash. |
|
- Quota quotidien: {DEFAULT_API_QUOTA} requêtes (partagé) |
|
- Quota restant: {current_quota} requêtes |
|
- Réinitialisation: Chaque jour à minuit |
|
|
|
⚠️ IMPORTANT - CONDITIONS D'USAGE : |
|
- API partagée entre tous les utilisateurs de l'app |
|
- Vos conversations peuvent être utilisées pour l'entraînement Google |
|
- Pour un usage privé, utilisez votre propre clé API Google |
|
- Quota limité - peut être épuisé rapidement |
|
|
|
🔄 PASSER À VOTRE PROPRE API : |
|
1. Aller sur https://ai.google.dev |
|
2. Créer un compte Google gratuit |
|
3. Générer votre clé API personnelle |
|
4. Utiliser votre clé dans l'interface de l'app |
|
5. Profiter de votre quota personnel de 1500 req/jour |
|
|
|
""" |
|
|
|
|
|
if company == "Google AI": |
|
if use_default_api and not user_api_key: |
|
content += f""" |
|
Exemple d'utilisation (avec votre propre clé API): |
|
------------------------------------------------ |
|
import google.generativeai as genai |
|
|
|
# ⚠️ REMPLACEZ PAR VOTRE VRAIE CLÉ API |
|
genai.configure(api_key="VOTRE_CLE_API_GOOGLE_ICI") |
|
model = genai.GenerativeModel('{model_clean}') |
|
|
|
response = model.generate_content("Votre prompt ici") |
|
print(response.text) |
|
|
|
# Avec LangChain |
|
from langchain_google_genai import ChatGoogleGenerativeAI |
|
llm = ChatGoogleGenerativeAI( |
|
model="{model_clean}", |
|
google_api_key="VOTRE_CLE_API_GOOGLE_ICI" |
|
) |
|
|
|
🔑 POUR OBTENIR VOTRE CLÉ API GOOGLE : |
|
1. Aller sur https://ai.google.dev |
|
2. Se connecter avec un compte Google |
|
3. Cliquer sur "Get API Key" |
|
4. Créer un nouveau projet si nécessaire |
|
5. Copier la clé générée |
|
""" |
|
else: |
|
content += f""" |
|
Exemple d'utilisation avec votre clé API: |
|
--------------------------------------- |
|
import google.generativeai as genai |
|
|
|
# Votre clé API configurée |
|
genai.configure(api_key="{user_api_key if user_api_key else 'VOTRE_CLE_API_GOOGLE'}") |
|
model = genai.GenerativeModel('{model_clean}') |
|
|
|
response = model.generate_content("Votre prompt ici") |
|
print(response.text) |
|
""" |
|
|
|
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False, encoding='utf-8') as f: |
|
f.write(content) |
|
temp_file_path = f.name |
|
|
|
return content, temp_file_path, get_quota_display() |
|
|
|
except Exception as e: |
|
error_msg = f"Erreur lors de la génération du fichier: {str(e)}" |
|
return error_msg, None, get_quota_display() |
|
|
|
def get_quota_display(): |
|
"""Retourne l'affichage du quota actuel""" |
|
available, quota, status = check_quota_status() |
|
return f"📊 {status} | Quota: {quota}/{DEFAULT_API_QUOTA}" |
|
|
|
def refresh_models(): |
|
"""Rafraîchit la liste des modèles""" |
|
global CURRENT_MODELS, LAST_UPDATE |
|
CURRENT_MODELS, LAST_UPDATE = load_updated_models() |
|
return f"Modèles rafraîchis - Dernière mise à jour: {LAST_UPDATE}" |
|
|
|
|
|
CURRENT_MODELS, LAST_UPDATE = load_updated_models() |
|
|
|
|
|
custom_css = """ |
|
/* Design moderne et élégant */ |
|
.gradio-container { |
|
max-width: 1200px !important; |
|
margin: 0 auto !important; |
|
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif !important; |
|
} |
|
|
|
/* Titre centré avec style moderne */ |
|
.main-title { |
|
text-align: center !important; |
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; |
|
-webkit-background-clip: text !important; |
|
-webkit-text-fill-color: transparent !important; |
|
background-clip: text !important; |
|
font-size: 2.5rem !important; |
|
font-weight: 700 !important; |
|
margin: 1rem 0 2rem 0 !important; |
|
letter-spacing: -0.02em !important; |
|
} |
|
|
|
/* Onglets modernes */ |
|
.tab-nav { |
|
border-bottom: 2px solid #e5e7eb !important; |
|
margin-bottom: 1.5rem !important; |
|
} |
|
|
|
.tab-nav button { |
|
background: none !important; |
|
border: none !important; |
|
padding: 0.75rem 1.5rem !important; |
|
font-weight: 600 !important; |
|
color: #6b7280 !important; |
|
border-bottom: 3px solid transparent !important; |
|
transition: all 0.3s ease !important; |
|
} |
|
|
|
.tab-nav button.selected { |
|
color: #4f46e5 !important; |
|
border-bottom-color: #4f46e5 !important; |
|
} |
|
|
|
.tab-nav button:hover { |
|
color: #4f46e5 !important; |
|
background: rgba(79, 70, 229, 0.05) !important; |
|
} |
|
|
|
/* Contenu des onglets */ |
|
.tab-content { |
|
width: 100% !important; |
|
padding: 1.5rem !important; |
|
background: #ffffff !important; |
|
border-radius: 12px !important; |
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1) !important; |
|
border: 1px solid #e5e7eb !important; |
|
} |
|
|
|
/* Cartes d'information */ |
|
.info-card { |
|
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%) !important; |
|
border: 1px solid #e2e8f0 !important; |
|
border-radius: 12px !important; |
|
padding: 1.5rem !important; |
|
margin: 1rem 0 !important; |
|
} |
|
|
|
/* Statut du quota */ |
|
.quota-status { |
|
background: linear-gradient(135deg, #10b981 0%, #059669 100%) !important; |
|
color: white !important; |
|
padding: 0.75rem 1.5rem !important; |
|
border-radius: 8px !important; |
|
text-align: center !important; |
|
font-weight: 600 !important; |
|
margin-bottom: 1rem !important; |
|
} |
|
|
|
.quota-status.exhausted { |
|
background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%) !important; |
|
} |
|
|
|
/* Boutons modernes */ |
|
.modern-button { |
|
background: linear-gradient(135deg, #4f46e5 0%, #7c3aed 100%) !important; |
|
border: none !important; |
|
color: white !important; |
|
padding: 0.75rem 2rem !important; |
|
border-radius: 8px !important; |
|
font-weight: 600 !important; |
|
transition: all 0.3s ease !important; |
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1) !important; |
|
} |
|
|
|
.modern-button:hover { |
|
transform: translateY(-2px) !important; |
|
box-shadow: 0 8px 15px -3px rgba(0, 0, 0, 0.2) !important; |
|
} |
|
|
|
/* Dropdowns et inputs */ |
|
.gradio-dropdown, .gradio-textbox { |
|
border-radius: 8px !important; |
|
border: 2px solid #e5e7eb !important; |
|
transition: border-color 0.3s ease !important; |
|
} |
|
|
|
.gradio-dropdown:focus, .gradio-textbox:focus { |
|
border-color: #4f46e5 !important; |
|
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1) !important; |
|
} |
|
|
|
/* Badges gratuits */ |
|
.free-badge { |
|
background: linear-gradient(135deg, #10b981 0%, #059669 100%) !important; |
|
color: white !important; |
|
padding: 0.25rem 0.5rem !important; |
|
border-radius: 4px !important; |
|
font-size: 0.75rem !important; |
|
font-weight: 600 !important; |
|
} |
|
|
|
/* Accordéons */ |
|
.gradio-accordion { |
|
border: 1px solid #e5e7eb !important; |
|
border-radius: 12px !important; |
|
overflow: hidden !important; |
|
margin: 1rem 0 !important; |
|
} |
|
|
|
.gradio-accordion summary { |
|
background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%) !important; |
|
padding: 1rem 1.5rem !important; |
|
font-weight: 600 !important; |
|
color: #374151 !important; |
|
} |
|
|
|
/* Responsive */ |
|
@media (max-width: 768px) { |
|
.gradio-container { |
|
max-width: 100% !important; |
|
padding: 0 1rem !important; |
|
} |
|
|
|
.main-title { |
|
font-size: 2rem !important; |
|
} |
|
|
|
.tab-content { |
|
padding: 1rem !important; |
|
} |
|
} |
|
""" |
|
|
|
|
|
with gr.Blocks( |
|
title="🤖 Sélecteur de LLM Premium - 2025", |
|
theme=gr.themes.Soft( |
|
primary_hue="indigo", |
|
secondary_hue="blue", |
|
neutral_hue="slate", |
|
font=gr.themes.GoogleFont("Inter") |
|
), |
|
css=custom_css |
|
) as app: |
|
|
|
|
|
gr.HTML(""" |
|
<div class="main-title"> |
|
🤖 Sélecteur de LLM Premium - 2025 |
|
</div> |
|
""") |
|
|
|
|
|
with gr.Row(): |
|
quota_display = gr.HTML( |
|
value=f'<div class="quota-status">{get_quota_display()}</div>', |
|
elem_id="quota-display" |
|
) |
|
refresh_quota_btn = gr.Button("🔄 Actualiser", size="sm", elem_classes=["modern-button"]) |
|
|
|
|
|
with gr.Tabs() as tabs: |
|
|
|
|
|
with gr.Tab("🎯 Configuration du modèle", elem_classes=["tab-content"]): |
|
gr.Markdown(""" |
|
### 🚀 Sélectionnez votre modèle LLM |
|
|
|
Choisissez l'entreprise et le modèle qui correspondent à vos besoins. |
|
**Gemini 2.5 Flash** est pré-sélectionné avec notre API gratuite par défaut. |
|
""") |
|
|
|
with gr.Row(): |
|
with gr.Column(scale=1): |
|
|
|
default_company = "Google AI" if default_api_available else None |
|
default_model = "gemini-2.5-flash 🆓" if default_api_available else None |
|
|
|
company_dropdown = gr.Dropdown( |
|
choices=list(CURRENT_MODELS.keys()), |
|
label="🏢 Entreprise / Provider", |
|
value=default_company, |
|
info="Google AI sélectionné par défaut (API gratuite fournie)", |
|
elem_classes=["gradio-dropdown"] |
|
) |
|
|
|
model_dropdown = gr.Dropdown( |
|
choices=CURRENT_MODELS.get("Google AI", []) if default_api_available else [], |
|
value=default_model, |
|
label="🧠 Modèle LLM", |
|
info="🆓 = Gratuit sous conditions | 💰 = Payant", |
|
elem_classes=["gradio-dropdown"] |
|
) |
|
|
|
with gr.Column(scale=1): |
|
|
|
model_info = gr.Markdown( |
|
value=update_model_info(default_model) if default_model else "Sélectionnez un modèle pour voir ses informations.", |
|
elem_classes=["info-card"] |
|
) |
|
|
|
|
|
with gr.Tab("🔑 Configuration API", elem_classes=["tab-content"]): |
|
gr.Markdown(""" |
|
### 🔐 Configurez votre accès API |
|
|
|
**Option 1** : Utilisez notre API gratuite par défaut (Gemini 2.5 Flash uniquement) |
|
**Option 2** : Utilisez votre propre clé API pour plus de contrôle et de quota |
|
""") |
|
|
|
with gr.Column(): |
|
use_default_api = gr.Checkbox( |
|
label="🎁 Utiliser l'API par défaut (Gemini 2.5 Flash uniquement)", |
|
value=default_api_available and default_model == "gemini-2.5-flash 🆓", |
|
interactive=default_api_available, |
|
info="API Google gratuite fournie par l'app - Quota partagé" |
|
) |
|
|
|
user_api_key = gr.Textbox( |
|
label="🔑 Votre clé API personnelle (optionnel si API par défaut utilisée)", |
|
type="password", |
|
placeholder="Collez votre clé API ici pour un quota personnel...", |
|
info="Votre clé API personnelle pour ce provider", |
|
elem_classes=["gradio-textbox"] |
|
) |
|
|
|
gr.Markdown(""" |
|
#### 🎯 Pourquoi utiliser votre propre clé API ? |
|
|
|
- **🎯 Quota personnel complet** : 1500 req/jour pour Google (vs quota partagé) |
|
- **🎯 Disponibilité garantie** : Pas de risque d'épuisement par d'autres utilisateurs |
|
- **🎯 Accès à tous les modèles** : Pas limité à Gemini 2.5 Flash |
|
- **🎯 Contrôle des données** : Vos conversations selon vos conditions |
|
- **🎯 Évolutivité** : Possibilité d'upgrade vers des plans payants |
|
|
|
#### 🔗 Liens pour obtenir vos clés API : |
|
- **Google AI Studio** : [ai.google.dev](https://ai.google.dev) (gratuit) |
|
- **OpenAI** : [platform.openai.com](https://platform.openai.com) |
|
- **Anthropic** : [console.anthropic.com](https://console.anthropic.com) |
|
- **DeepSeek** : [platform.deepseek.com](https://platform.deepseek.com) (gratuit) |
|
""") |
|
|
|
|
|
with gr.Tab("📄 Génération de configuration", elem_classes=["tab-content"]): |
|
gr.Markdown(""" |
|
### 📋 Générez votre fichier de configuration |
|
|
|
Cliquez sur le bouton pour générer un fichier de configuration complet avec : |
|
- Informations sur le modèle sélectionné |
|
- Configuration API sécurisée |
|
- Exemples de code prêts à utiliser |
|
- Instructions d'intégration |
|
""") |
|
|
|
generate_btn = gr.Button( |
|
"📄 Générer la configuration complète", |
|
variant="primary", |
|
size="lg", |
|
elem_classes=["modern-button"] |
|
) |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
output_text = gr.Textbox( |
|
label="📋 Configuration générée", |
|
lines=25, |
|
interactive=False, |
|
show_copy_button=True, |
|
elem_classes=["gradio-textbox"] |
|
) |
|
|
|
download_file = gr.File( |
|
label="📥 Fichier de configuration téléchargeable (.txt)", |
|
interactive=False |
|
) |
|
|
|
|
|
with gr.Tab("📖 Guide d'utilisation", elem_classes=["tab-content"]): |
|
gr.Markdown(f""" |
|
## 🎁 **API PAR DÉFAUT GRATUITE !** |
|
|
|
Cette application fournit **gratuitement** une clé API Google pour utiliser **Gemini 2.5 Flash** ! |
|
|
|
### ✨ Avantages de l'API par défaut : |
|
- **🆓 Totalement gratuit** : Aucune inscription requise de votre part |
|
- **📊 Quota généreux** : {DEFAULT_API_QUOTA} requêtes par jour |
|
- **🔄 Réinitialisation quotidienne** : Chaque jour à minuit |
|
- **⚡ Très rapide** : Gemini 2.5 Flash optimisé pour la vitesse |
|
- **🖼️ Multimodal** : Traite texte et images |
|
|
|
### 🚀 Comment utiliser l'app : |
|
|
|
1. **Vérifiez le quota** en haut de la page |
|
2. **Onglet "Configuration du modèle"** : Sélectionnez provider et modèle |
|
3. **Onglet "Configuration API"** : Choisissez API par défaut ou votre clé |
|
4. **Onglet "Génération"** : Créez et téléchargez votre configuration |
|
|
|
### ⚠️ **Quand l'API par défaut est épuisée** : |
|
- L'app vous informe que le quota est atteint |
|
- L'API par défaut n'est plus proposée jusqu'à minuit |
|
- **Solution simple** : Utilisez votre propre clé API Google |
|
- Ou choisissez un autre provider avec votre clé API |
|
|
|
### 🔐 **Sécurité et confidentialité** : |
|
- **API par défaut** : Clé stockée de manière sécurisée (jamais exposée) |
|
- **Vos données** : Peuvent être utilisées par Google pour l'entraînement |
|
- **Conseil** : Ne jamais envoyer de données sensibles ou confidentielles |
|
- **Usage professionnel** : Utilisez votre propre clé API |
|
""") |
|
|
|
|
|
with gr.Tab("📊 Modèles disponibles", elem_classes=["tab-content"]): |
|
gr.Markdown(f""" |
|
## 📈 **Statistiques des modèles** |
|
|
|
- **Total des providers** : {len(CURRENT_MODELS)} |
|
- **Total des modèles** : {sum(len(models) for models in CURRENT_MODELS.values())} |
|
- **Modèles gratuits identifiés** : {sum(1 for models in CURRENT_MODELS.values() for model in models if '🆓' in model)} |
|
- **Dernière mise à jour** : {LAST_UPDATE} |
|
|
|
## 🆕 **Nouveautés 2025** |
|
|
|
### 🔥 **Modèles gratuits recommandés** : |
|
- **Gemini 2.5 Flash** 🆓 : Multimodal, très rapide (API par défaut) |
|
- **DeepSeek R1** 🆓 : Excellent en raisonnement et programmation |
|
- **Llama 4 Scout/Maverick** 🆓 : Contexte ultra-long (10M tokens) |
|
- **QwQ-32B** 🆓 : Spécialisé en mathématiques et logique |
|
|
|
### 🚀 **Nouveaux modèles 2025** : |
|
- **OpenAI** : Série GPT-4.1, modèles o3/o4 (reasoning) |
|
- **Anthropic** : Claude 4 Opus/Sonnet, Claude 3.7 |
|
- **Google** : Gemini 2.5 Pro/Flash avec thinking |
|
- **xAI** : Grok 3 avec reasoning |
|
- **DeepSeek** : R1 series (gratuits et performants) |
|
|
|
## 🏢 **Providers supportés** |
|
|
|
{chr(10).join([f"### **{provider}**" + chr(10) + chr(10).join([f"- {model}" for model in models[:5]]) + (f"- ... et {len(models)-5} autres" if len(models) > 5 else "") for provider, models in CURRENT_MODELS.items()])} |
|
|
|
## 🔧 **Sources et références** |
|
|
|
Cette application se base sur : |
|
- **GitHub** : [free-llm-api-resources](https://github.com/cheahjs/free-llm-api-resources) |
|
- **Hugging Face** : [Guide LLM gratuits 2025](https://huggingface.co/blog/lynn-mikami/llm-free) |
|
- **Documentation officielle** des providers |
|
|
|
Les informations sont mises à jour régulièrement pour refléter les dernières offres. |
|
""") |
|
|
|
refresh_btn = gr.Button("🔄 Rafraîchir la liste des modèles", elem_classes=["modern-button"]) |
|
refresh_status = gr.Textbox(label="Statut de la mise à jour", visible=False) |
|
|
|
|
|
company_dropdown.change( |
|
fn=update_models, |
|
inputs=[company_dropdown], |
|
outputs=[model_dropdown] |
|
) |
|
|
|
model_dropdown.change( |
|
fn=update_model_info, |
|
inputs=[model_dropdown], |
|
outputs=[model_info] |
|
) |
|
|
|
|
|
def update_default_api_checkbox(model): |
|
if model == "gemini-2.5-flash 🆓" and default_api_available: |
|
return gr.Checkbox(value=True, interactive=True) |
|
else: |
|
return gr.Checkbox(value=False, interactive=False) |
|
|
|
model_dropdown.change( |
|
fn=update_default_api_checkbox, |
|
inputs=[model_dropdown], |
|
outputs=[use_default_api] |
|
) |
|
|
|
generate_btn.click( |
|
fn=generate_selection_file, |
|
inputs=[company_dropdown, model_dropdown, user_api_key, use_default_api], |
|
outputs=[output_text, download_file, quota_display] |
|
) |
|
|
|
refresh_btn.click( |
|
fn=refresh_models, |
|
outputs=[refresh_status] |
|
).then( |
|
fn=lambda: gr.Dropdown(choices=list(CURRENT_MODELS.keys())), |
|
outputs=[company_dropdown] |
|
) |
|
|
|
refresh_quota_btn.click( |
|
fn=get_quota_display, |
|
outputs=[quota_display] |
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
app.launch(share=True) |
|
|
|
print("🎉 App Gradio Premium avec design moderne créée avec succès!") |
|
print(f"📊 Modèles chargés: {sum(len(models) for models in CURRENT_MODELS.values())} modèles de {len(CURRENT_MODELS)} providers") |
|
print(f"🎁 API par défaut: Gemini 2.5 Flash (quota: {current_quota}/{DEFAULT_API_QUOTA})") |
|
print(f"🆓 Modèles gratuits identifiés: {sum(1 for models in CURRENT_MODELS.values() for model in models if '🆓' in model)}") |
|
print("🎨 Design moderne avec onglets et CSS personnalisé appliqué") |
|
print("🔐 Sécurité renforcée - Clé API par défaut jamais exposée") |