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 # Configuration mise à jour avec les derniers modèles (juin 2025) UPDATED_MODELS = { "OpenAI": [ # Série GPT-4.1 (2025) "gpt-4.1", "gpt-4.1-mini", "gpt-4.1-nano", # Série o (reasoning models) "o3-pro", "o3", "o3-mini", "o4-mini", "o1", "o1-preview", "o1-pro", "o1-mini", # GPT-4.5 et autres "gpt-4.5-preview", "gpt-4o", "gpt-4o-mini", "gpt-4-turbo", "gpt-3.5-turbo", # Anciens modèles encore disponibles "gpt-4", "gpt-4-vision-preview", "gpt-3.5-turbo-16k" ], "Anthropic": [ # Claude 4 (mai 2025) "claude-opus-4-20250514", "claude-sonnet-4-20250514", # Claude 3.7 (février 2025) "claude-3-7-sonnet-20250219", "claude-3-7-sonnet-latest", # Claude 3.5 "claude-3-5-sonnet-20241022", "claude-3-5-sonnet-20240620", "claude-3-5-haiku-20241022", # Claude 3 "claude-3-opus-20240229", "claude-3-sonnet-20240229", "claude-3-haiku-20240307" ], "Google AI": [ # Gemini 2.5 (2025) - GRATUIT via Google AI Studio "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 - GRATUIT via Google AI Studio "gemini-2.0-flash 🆓", "gemini-2.0-flash-preview-image-generation", "gemini-2.0-flash-lite 🆓", "gemini-2.0-pro-experimental", # Gemini 1.5 "gemini-1.5-pro", "gemini-1.5-flash", "gemini-1.5-flash-8b", # Anciens modèles "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"] } # Informations détaillées sur les modèles gratuits 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 } } # Variables globales pour le quota 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(" 🆓", "") # SÉCURITÉ : Gestion des clés API api_config_section = "" api_status = "" if model == "gemini-2.5-flash 🆓" and use_default_api and default_api_available: # Utilisation de l'API par défaut - PAS DE CLÉ DANS LE FICHIER 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: # Utilisateur a fourni sa propre clé api_status = "🔑 Votre clé API sera utilisée" # Masquer partiellement la clé pour sécurité 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 """ # Création du contenu du fichier 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} """ # Ajout d'informations sur l'API par défaut si applicable 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 """ # Ajout d'exemples de code sécurisés 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) """ # Création du fichier temporaire 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}" # Chargement des modèles au démarrage CURRENT_MODELS, LAST_UPDATE = load_updated_models() # CSS personnalisé pour un design moderne et classe 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; } } """ # Interface Gradio avec design moderne 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: # Titre centré moderne gr.HTML("""
🤖 Sélecteur de LLM Premium - 2025
""") # Statut de l'API par défaut en haut with gr.Row(): quota_display = gr.HTML( value=f'
{get_quota_display()}
', elem_id="quota-display" ) refresh_quota_btn = gr.Button("🔄 Actualiser", size="sm", elem_classes=["modern-button"]) # Interface avec onglets modernes with gr.Tabs() as tabs: # ONGLET 1: Configuration du modèle 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): # Déterminer les valeurs par défaut 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): # Informations sur le modèle sélectionné 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"] ) # ONGLET 2: Configuration API 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) """) # ONGLET 3: Génération et résultats 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 ) # ONGLET 4: Guide d'utilisation 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 """) # ONGLET 5: Modèles disponibles 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) # Événements 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] ) # Mise à jour de la checkbox selon le modèle sélectionné 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] ) # Lancement de l'app 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")