Gestion API avec IA
Creato il: 17 gennaio 2025
Creato il: 17 gennaio 2025
Outlining the user's needs
I’m figuring out how to provide a main menu and guide through adding, listing, modifying, deleting APIs, and testing endpoints, with a specific emphasis on the Groq and Spotify APIs.
Crafting Python code
I’m preparing Python code snippets or a skeleton to handle adding, modifying, and removing APIs, demonstrating possible language processing for these actions.
Integrating Python code
I’m strengthening Python code within the answer, carefully aligning it with instructions and focusing on managing APIs and testing Spotify endpoints.
Thought about gestion des API pendant 9 secondes
Voici un exemple complet de flux de travail et de code Python pour construire un système permettant :
L’exemple ci-dessous met l’accent sur l’API Spotify pour illustrer la lecture d’une playlist et la vérification de la présence d’une musique dans une playlist. Il inclut également l’utilisation de l’API Groq (via la clé gsk_XXXXXXXXXXXXXXX
) pour analyser la documentation ou la description des API que l’utilisateur souhaite ajouter.
Lors du lancement du programme, on propose à l’utilisateur le menu suivant :
Le code Python ci-dessous illustre un squelette d’implémentation :
import requests import json import sys # ----------------------------------------------------------------------------- # Exemple de stockage en mémoire (vous pouvez le remplacer par une base de données ou un fichier) apis_configurees = [] # ----------------------------------------------------------------------------- # Fonction d'appel à l'API Groq pour analyser l'entrée de l'utilisateur def analyser_api_avec_groq(input_text, groq_api_key="gsk_XXXXXXXXXXXXXXX"): """ Envoie le input_text à l'API Groq pour obtenir les informations nécessaires : - Type d'API (REST, GraphQL, SOAP) - URL de base - Authentification (type, nom de la clé, obligatoire ?) - En-têtes communs - Endpoints (nom, chemin, méthode, params requis/optionnels...) - Nom suggéré pour l’API - Limitation de débit - Score de confiance Retourne un dictionnaire contenant ces informations. NOTE : Le code suivant est purement illustratif. Vous devrez l'adapter à la forme réelle du JSON de réponse retourné par l’API Groq. """ # Exemple d'appel fictif à l'API Groq headers = { "Authorization": f"Bearer {groq_api_key}", "Content-Type": "application/json", } payload = { "text": input_text } # Simulation : requête fictive # response = requests.post("https://api.groq.io/v1/analyze", headers=headers, json=payload) # data = response.json() # Simulation d'une réponse plausible de l'API Groq data = { "api_type": "REST", "base_url": "https://api.spotify.com/v1", "auth_info": { "type": "Bearer", "key_name": "Authorization", "required": True }, "common_headers": { "Content-Type": "application/json" }, "endpoints": [ { "name": "Get playlist tracks", "path": "/playlists/{playlist_id}/tracks", "method": "GET", "required_params": ["playlist_id"], "optional_params": [], "description": "Récupère les pistes d’une playlist." } ], "suggested_name": "Spotify", "rate_limit": "N/A", "confidence_score": 0.9 } return data # ----------------------------------------------------------------------------- # 2. Ajouter une API (assisté par IA) def ajouter_api(): print("=== Ajout d’une nouvelle API ===") # 2.1 Demande à l'utilisateur s'il souhaite coller la documentation coller_doc = input("Voulez-vous coller la documentation de l’API ? (o/n) : ") doc_api = "" if coller_doc.lower() == 'o': print("Collez la documentation ci-dessous (finissez par une ligne vide) :") lignes_doc = [] while True: ligne = input() if ligne == "": break lignes_doc.append(ligne) doc_api = "\n".join(lignes_doc) # 2.2 Demandez l’URL ou une description en langage naturel url_ou_description = input("Entrez l’URL de l’API ou une description en langage naturel : ") # 2.3 Analyse via Groq texte_a_analyser = doc_api if doc_api else url_ou_description resultats_analyse = analyser_api_avec_groq(texte_a_analyser) # Extraction des informations confidence_score = resultats_analyse.get("confidence_score", 0) if confidence_score < 0.5: print("Le score de confiance de l’analyse est faible. Veuillez fournir plus d’informations.") # Ici on peut demander plus de détails à l’utilisateur, puis relancer l’analyse # ... api_type = resultats_analyse.get("api_type") base_url = resultats_analyse.get("base_url") auth_info = resultats_analyse.get("auth_info", {}) common_headers = resultats_analyse.get("common_headers", {}) endpoints = resultats_analyse.get("endpoints", []) suggested_name = resultats_analyse.get("suggested_name", "NouvelleAPI") print(f"Nom suggéré pour l’API : {suggested_name}") nom_api = input(f"Entrez le nom de l’API ({suggested_name}) : ") if not nom_api: nom_api = suggested_name # 2.4 Demandez la valeur de la clé API si nécessaire api_key_value = None if auth_info.get("required", False): api_key_value = input("Entrez la valeur de la clé API ou du token d’authentification : ") # Prépare la configuration nouvelle_api = { "name": nom_api, "type": api_type, "base_url": base_url, "auth_info": auth_info, "common_headers": common_headers, "api_key_value": api_key_value, "endpoints": endpoints } # 2.5 Enregistrez la configuration de l’API apis_configurees.append(nouvelle_api) print(f"L’API '{nom_api}' a bien été ajoutée avec l’URL de base : {base_url}\n") # ----------------------------------------------------------------------------- # 3. Lister les API configurées def lister_apis(): print("=== Liste des API configurées ===") if not apis_configurees: print("Aucune API n'est configurée pour le moment.\n") return for i, api in enumerate(apis_configurees): print(f"{i+1}. Nom : {api['name']}") print(f" URL de base : {api['base_url']}") print(" Endpoints :") for endpoint in api["endpoints"]: print(f" - {endpoint['name']} ({endpoint['method']} {endpoint['path']})") print() print() # ----------------------------------------------------------------------------- # 4. Modifier une API def modifier_api(): print("=== Modification d’une API ===") if not apis_configurees: print("Aucune API n’est configurée.\n") return # 4.1 Affichez la liste des API configurées for i, api in enumerate(apis_configurees): print(f"{i+1}. {api['name']}") # 4.2 Demandez laquelle modifier (langage naturel possible, simplifié ici) choix = input("Quelle API souhaitez-vous modifier ? Entrez un nom ou un numéro : ") api_choisie = None # On essaie d'abord de voir si l'utilisateur a tapé un numéro try: index = int(choix) - 1 if 0 <= index < len(apis_configurees): api_choisie = apis_configurees[index] except ValueError: # Sinon on essaie de faire correspondre par nom for api in apis_configurees: if api["name"].lower() == choix.lower(): api_choisie = api break if not api_choisie: print("API introuvable.\n") return print(f"API sélectionnée : {api_choisie['name']}") # 4.3 Demandez ce qu’il faut modifier print("Que voulez-vous modifier ? (URL de base, clé API, ajouter un endpoint, modifier un endpoint, supprimer un endpoint, etc.)") modification = input("> ") # Exemple (logique simplifiée) : if "url" in modification.lower(): nouvelle_url = input("Entrez la nouvelle URL de base : ") api_choisie["base_url"] = nouvelle_url print("URL de base modifiée avec succès.\n") if "clé" in modification.lower() or "key" in modification.lower(): nouvelle_cle = input("Entrez la nouvelle clé API : ") api_choisie["api_key_value"] = nouvelle_cle print("Clé API modifiée avec succès.\n") if "ajouter un endpoint" in modification.lower(): print("=== Ajout d'un endpoint ===") nom_endpoint = input("Nom du nouvel endpoint : ") path_endpoint = input("Chemin (ex: /playlists/{playlist_id}/tracks) : ") methode = input("Méthode HTTP (GET, POST, etc.) : ") params_requis = input("Paramètres requis (séparés par des virgules) : ").split(",") params_op = input("Paramètres optionnels (séparés par des virgules) : ").split(",") nouveau_endpoint = { "name": nom_endpoint, "path": path_endpoint, "method": methode.upper(), "required_params": [p.strip() for p in params_requis if p.strip()], "optional_params": [p.strip() for p in params_op if p.strip()], "description": "" } api_choisie["endpoints"].append(nouveau_endpoint) print(f"Endpoint '{nom_endpoint}' ajouté.\n") if "modifier un endpoint" in modification.lower(): print("=== Modification d'un endpoint existant ===") for i, ep in enumerate(api_choisie["endpoints"]): print(f"{i+1}. {ep['name']} ({ep['method']} {ep['path']})") choix_ep = input("Quel endpoint souhaitez-vous modifier ? (numéro ou nom) : ") endpoint_choisi = None try: ep_index = int(choix_ep) - 1 if 0 <= ep_index < len(api_choisie["endpoints"]): endpoint_choisi = api_choisie["endpoints"][ep_index] except ValueError: for ep in api_choisie["endpoints"]: if ep["name"].lower() == choix_ep.lower(): endpoint_choisi = ep break if not endpoint_choisi: print("Endpoint introuvable.") return print(f"Endpoint sélectionné : {endpoint_choisi['name']}") action_modif = input("Que voulez-vous modifier ? (ex: ajouter un paramètre, changer la méthode, etc.) : ") if "ajouter un paramètre" in action_modif.lower(): nom_param = input("Nom du paramètre : ") type_param = input("Paramètre requis ou optionnel ? (r/o) : ") if type_param.lower() == "r": endpoint_choisi["required_params"].append(nom_param) print(f"Le paramètre requis '{nom_param}' a été ajouté.") else: endpoint_choisi["optional_params"].append(nom_param) print(f"Le paramètre optionnel '{nom_param}' a été ajouté.") if "supprimer un endpoint" in modification.lower(): print("=== Suppression d'un endpoint ===") for i, ep in enumerate(api_choisie["endpoints"]): print(f"{i+1}. {ep['name']} ({ep['method']} {ep['path']})") choix_ep = input("Quel endpoint souhaitez-vous supprimer ? (numéro ou nom) : ") ep_a_supprimer = None try: ep_index = int(choix_ep) - 1 if 0 <= ep_index < len(api_choisie["endpoints"]): ep_a_supprimer = api_choisie["endpoints"][ep_index] except ValueError: for ep in api_choisie["endpoints"]: if ep["name"].lower() == choix_ep.lower(): ep_a_supprimer = ep break if ep_a_supprimer: api_choisie["endpoints"].remove(ep_a_supprimer) print(f"L’endpoint '{ep_a_supprimer['name']}' a été supprimé.") else: print("Endpoint introuvable.") print("Modification(s) terminée(s).\n") # ----------------------------------------------------------------------------- # 5. Supprimer une API def supprimer_api(): print("=== Suppression d’une API ===") if not apis_configurees: print("Aucune API n’est configurée.\n") return # 5.1 Liste des API for i, api in enumerate(apis_configurees): print(f"{i+1}. {api['name']}") # 5.2 Demandez laquelle supprimer (en langage naturel ou numéro) choix = input("Quelle API souhaitez-vous supprimer ? (nom ou numéro) : ") api_a_supprimer = None # On essaie d'abord de voir si l'utilisateur a tapé un numéro try: index = int(choix) - 1 if 0 <= index < len(apis_configurees): api_a_supprimer = apis_configurees[index] except ValueError: # Sinon on essaie de faire correspondre par nom for api in apis_configurees: if api["name"].lower() == choix.lower(): api_a_supprimer = api break if not api_a_supprimer: print("API introuvable.\n") return # 5.3 Demandez confirmation confirm = input(f"Êtes-vous sûr de vouloir supprimer l’API {api_a_supprimer['name']} ? (o/n) : ") if confirm.lower() == 'o': apis_configurees.remove(api_a_supprimer) print(f"L’API {api_a_supprimer['name']} a été supprimée.\n") else: print("Opération annulée.\n") # ----------------------------------------------------------------------------- # 6. Tester un endpoint (Exemple avec Spotify) def tester_endpoint(): print("=== Tester un endpoint ===") if not apis_configurees: print("Aucune API n’est configurée.\n") return # 6.1 Sélection de l’API for i, api in enumerate(apis_configurees): print(f"{i+1}. {api['name']}") choix = input("Sur quelle API souhaitez-vous tester un endpoint ? (nom ou numéro) : ") api_choisie = None try: index = int(choix) - 1 if 0 <= index < len(apis_configurees): api_choisie = apis_configurees[index] except ValueError: for api in apis_configurees: if api["name"].lower() == choix.lower(): api_choisie = api break if not api_choisie: print("API introuvable.\n") return # 6.2 Sélection de l’endpoint if not api_choisie["endpoints"]: print(f"L’API {api_choisie['name']} n’a aucun endpoint configuré.\n") return print(f"Endpoints disponibles pour {api_choisie['name']} :") for i, ep in enumerate(api_choisie["endpoints"]): print(f"{i+1}. {ep['name']} ({ep['method']} {ep['path']})") choix_ep = input("Quel endpoint souhaitez-vous tester ? (numéro ou nom) : ") endpoint_choisi = None try: ep_index = int(choix_ep) - 1 if 0 <= ep_index < len(api_choisie["endpoints"]): endpoint_choisi = api_choisie["endpoints"][ep_index] except ValueError: for ep in api_choisie["endpoints"]: if ep["name"].lower() == choix_ep.lower(): endpoint_choisi = ep break if not endpoint_choisi: print("Endpoint introuvable.") return # Exemple concret pour Spotify : # - Lire une playlist : besoin d’un playlist_id # - Vérifier si une musique est dans une playlist : besoin d’un playlist_id et d’un track_id # 6.3 Récupération des paramètres required_params = {} for rp in endpoint_choisi.get("required_params", []): required_params[rp] = input(f"Entrez la valeur pour '{rp}' : ") optional_params = {} for op in endpoint_choisi.get("optional_params", []): val = input(f"Entrez la valeur (ou laissez vide) pour le paramètre optionnel '{op}' : ") if val: optional_params[op] = val # Construction de l’URL base_url = api_choisie["base_url"] path = endpoint_choisi["path"] # Remplace, si besoin, les variables {playlist_id} dans le chemin for rp_key, rp_value in required_params.items(): path = path.replace(f"{{{rp_key}}}", rp_value) url = base_url + path # 6.4 Préparez la requête headers = dict(api_choisie["common_headers"]) if api_choisie["auth_info"].get("required", False) and api_choisie.get("api_key_value"): if api_choisie["auth_info"]["type"].lower() == "bearer": headers["Authorization"] = f"Bearer {api_choisie['api_key_value']}" else: # Autres types d’authentification headers[api_choisie["auth_info"]["key_name"]] = api_choisie["api_key_value"] # Exemples de gestion des query params (optionnels) params = {} for op_key, op_value in optional_params.items(): params[op_key] = op_value method = endpoint_choisi["method"].upper() print(f"Lancement du test de l'endpoint : {method} {url}") # 6.5 Exécution de la requête response = None try: if method == "GET": response = requests.get(url, headers=headers, params=params) elif method == "POST": # Ex: on peut mettre les params dans le body JSON response = requests.post(url, headers=headers, json=params) else: print(f"Méthode {method} non gérée dans cet exemple.") return if response is not None: print(f"Statut: {response.status_code}") print("Réponse:") try: print(json.dumps(response.json(), indent=2)) except: print(response.text) except Exception as e: print(f"Erreur lors de l’appel à l’endpoint : {e}") # ----------------------------------------------------------------------------- # Fonction principale def main(): while True: print("=== Menu Principal ===") print("1. Ajouter une API (assisté par IA)") print("2. Liste des API configurées") print("3. Modifier une API") print("4. Supprimer une API") print("5. Tester un endpoint") print("6. Quitter") choix = input("Choisissez une option : ") if choix == '1': ajouter_api() elif choix == '2': lister_apis() elif choix == '3': modifier_api() elif choix == '4': supprimer_api() elif choix == '5': tester_endpoint() elif choix == '6': print("Au revoir !") sys.exit(0) else: print("Choix invalide.\n") if __name__ == "__main__": main()
Menu principal :
L’utilisateur est accueilli par un menu principal qui lui permet d’ajouter une API, de voir la liste des APIs configurées, de modifier une API, de la supprimer, de tester un endpoint ou de quitter.
Ajouter une API :
gsk_XXXXXXXXXXXXXXX
), qui renvoie un score de confiance et diverses informations (type d’API, URL de base, endpoints, etc.).apis_configurees
).Lister les API configurées :
Modifier une API :
/playlists/{playlist_id}/tracks
, on demande simplement le nom du paramètre, puis on l’ajoute soit à la liste des paramètres obligatoires, soit à la liste des paramètres optionnels.Supprimer une API :
Tester un endpoint (exemple Spotify) :
playlist_id
, market
, track_id
, etc.).requests
.Ce système, avec son interface en ligne de commande, vous permet de gérer de façon intuitive le cycle de vie (ajout, configuration, modification, suppression) de vos intégrations d’API, tout en testant rapidement les endpoints configurés. Pour des besoins plus avancés, vous pourrez étendre cette logique à l’aide d’une base de données, d’une interface graphique ou d’autres composants pour mieux organiser et partager vos configurations d’API.
Examining the doc contents
I’m curious about the Groq API documentation the user pasted. It could be integrated into our system, likely showing an example with the Groq API.
Integrating the Groq API
I'm thinking through incorporating the Groq API into step 2, focusing on analyzing user input. Producing an example code snippet with the Groq API is necessary.
Crafting final code snippet
Integrating the Groq API into step 2, I’m working through examples and analyzing user input. The goal is a polished, unified code snippet, ready for deployment.
Thought about Groq API usage pendant 18 secondes
Voici comment vous pouvez adapter votre système pour intégrer l’API Groq de Chat Completion dans la phase d’analyse de l’API (étape 2) :
La documentation Groq indique comment faire des requêtes de chat completion. Pour rappel, vous voulez extraire automatiquement les informations suivantes à partir d’un texte (URL, description, documentation API) :
La logique consistera donc à :
Construire un prompt (messages) pour Groq qui décrit la tâche :
Envoyer la requête à Groq en utilisant le client Python (pip install groq
).
Récupérer la réponse en JSON (ou en texte brut si vous ne voulez pas activer le mode JSON bêta).
Extraire les champs (type d’API, base_url, endpoints, etc.) depuis le JSON de Groq.
Les renseigner dans la configuration de votre API.
analyser_api_avec_groq
modifiéeVoici un exemple simplifié d’implémentation, où l’on utilise une chat completion de Groq pour extraire les informations d’une API. Dans cet exemple, nous allons :
groq
pour envoyer la requête.from groq import Groq import json def analyser_api_avec_groq(input_text, groq_api_key="gsk_XXXXXXXXXXXXXXX"): """ Envoie 'input_text' à l’API Groq via un chat completion, et récupère un JSON décrivant les informations d'API. """ # Instanciation du client Groq client = Groq(api_key=groq_api_key) # Préparez les messages pour la conversation # (Rôle "system" : donnez le format de retour désiré, # Rôle "user" : mettez le 'input_text' à analyser) messages = [ { "role": "system", "content": ( "Tu es un assistant d'analyse d'API. " "Retourne un JSON de la forme :\n" "{\n" " \"api_type\": \"REST | GraphQL | SOAP\",\n" " \"base_url\": \"string\",\n" " \"auth_info\": {\n" " \"type\": \"string (Bearer, Basic, etc.)\",\n" " \"key_name\": \"string\",\n" " \"required\": \"bool\"\n" " },\n" " \"common_headers\": {\n" " \"Header-Name\": \"Header-Value\"\n" " },\n" " \"endpoints\": [\n" " {\n" " \"name\": \"string\",\n" " \"path\": \"string\",\n" " \"method\": \"GET | POST | ...\",\n" " \"required_params\": [\"param1\", \"param2\"],\n" " \"optional_params\": [\"param1\", \"param2\"],\n" " \"description\": \"string\"\n" " }\n" " ],\n" " \"suggested_name\": \"string\",\n" " \"rate_limit\": \"string\",\n" " \"confidence_score\": \"number between 0 and 1\"\n" "}\n" "Analyse le texte ci-après et remplis au maximum ces champs." ) }, { "role": "user", "content": input_text } ] try: # Appel à l'API Groq chat_completion = client.chat.completions.create( messages=messages, model="llama-3.3-70b-versatile", temperature=0.0, max_completion_tokens=1024, top_p=1, # Pas de streaming pour simplifier stream=False, # Optionnel : on peut forcer le format JSON si on souhaite # "response_format": {"type": "json_object"}, ) # Récupération du contenu textuel content = chat_completion.choices[0].message.content # Tente de parser le résultat en JSON data = json.loads(content) # Idéalement, on vérifie la présence des clés attendues. return data except Exception as e: print(f"Erreur lors de l'analyse Groq : {e}") # Retour d’un squelette par défaut en cas de souci return { "api_type": None, "base_url": None, "auth_info": {}, "common_headers": {}, "endpoints": [], "suggested_name": "API_Inconnue", "rate_limit": None, "confidence_score": 0.0 }
Groq
du SDK Python pour envoyer une requête Chat Completion à Groq.messages
) avec un rôle system
qui indique clairement le format JSON attendu, et un rôle user
contenant le texte de l’utilisateur.client.chat.completions.create(...)
et récupérons la réponse.json.loads(...)
.confidence_score
, etc.).Le reste du code (menu principal, ajout, modification, suppression, test d’un endpoint) ne change presque pas. Il suffit de remplacer la fonction d’analyse fictive par la nouvelle fonction analyser_api_avec_groq
ci-dessus.
Par exemple, dans la partie « 2. Ajouter une API (assisté par IA) », vous appelez :
resultats_analyse = analyser_api_avec_groq(texte_a_analyser)
… au lieu de la fonction précédente. Le reste de la logique (extraction de api_type
, base_url
, etc.) est le même.
Voici comment le flux se déroulera avec la nouvelle intégration Groq :
system
) le schéma JSON désiré, puis (en user
) le texte fourni.confidence_score < 0.5
, demandez des précisions à l’utilisateur.apis_configurees
).requests.get()
ou requests.post()
, etc., on affiche la réponse.Prenons l’exemple d’une documentation (ou description) assez concise pour l’API Spotify, comme :
« Spotify a une API REST pour gérer les playlists. L’URL de base est
https://api.spotify.com/v1
. Il faut un Bearer token dans l’en-tête Authorization. Un endpoint GET/playlists/{playlist_id}/tracks
permet de lister les pistes. »
Le système :
analyser_api_avec_groq
envoie le prompt à Groq, qui renvoie un JSON avec :
api_type
: "REST"base_url
: "https://api.spotify.com/v1"auth_info
: { "type": "Bearer", "key_name": "Authorization", "required": True }
confidence_score
. Disons qu’il vaut 0.85
.Ensuite, l’utilisateur peut :
market
de type optionnel »).playlist_id
et, si souhaité, market
.En reprenant le squelette de code fourni et en remplaçant la fonction d’analyse par l’exemple ci-dessus qui utilise Groq, vous rendez votre système entièrement opérationnel :
Vous profitez ainsi de la puissance du LLM de Groq pour structurer automatiquement la configuration d’API sans avoir à écrire de règles complexes.
Outlining the solution
I’m detailing a Python script using the Groq SDK to analyze input. The script guides a user through a menu selection, invokes a function to query Groq for analysis, and demonstrates the use of Groq’s ChatCompletion API.
Pensée sur l'intégration de l'API Groq pendant 12 secondes
Voici un exemple de code Python complet qui illustre :
gsk_XXXXXXXXXXXXXXX
).Ce code est pensé pour être facilement adapté et étendu selon vos besoins. Suivez les commentaires pour comprendre chaque partie.
Avant de tester ce script, installez la librairie Groq :
pip install groq
import sys import json import requests # IMPORTANT : importez le SDK Groq from groq import Groq # ----------------------------------------------------------------------------- # Stockage en mémoire des APIs (vous pouvez remplacer par un fichier ou une base de données) apis_configurees = [] # ----------------------------------------------------------------------------- # Fonction d'appel à l'API Groq pour analyser l'entrée de l'utilisateur def analyser_api_avec_groq(input_text, groq_api_key="gsk_XXXXXXXXXXXXXXX"): """ Envoie 'input_text' à l’API Groq via un chat completion, pour en extraire un JSON décrivant les informations d'API. Le JSON renvoyé doit contenir au moins : - api_type (REST, GraphQL, SOAP) - base_url - auth_info (type, key_name, required) - common_headers - endpoints (liste d’endpoints) - suggested_name - rate_limit - confidence_score (nombre entre 0 et 1) """ # Initialisation du client Groq avec la clé fournie client = Groq(api_key=groq_api_key) # Préparez les messages pour la conversation # Rôle "system" : instruction à Groq sur le format JSON désiré # Rôle "user" : le texte de l’utilisateur (doc API, URL, description) messages = [ { "role": "system", "content": ( "Tu es un assistant d'analyse d'API. " "Retourne un JSON de la forme :\n" "{\n" " \"api_type\": \"REST | GraphQL | SOAP\",\n" " \"base_url\": \"string\",\n" " \"auth_info\": {\n" " \"type\": \"string (Bearer, Basic, etc.)\",\n" " \"key_name\": \"string\",\n" " \"required\": true/false\n" " },\n" " \"common_headers\": {\n" " \"Header-Name\": \"Header-Value\"\n" " },\n" " \"endpoints\": [\n" " {\n" " \"name\": \"string\",\n" " \"path\": \"string\",\n" " \"method\": \"GET | POST | ...\",\n" " \"required_params\": [\"param1\", \"param2\"],\n" " \"optional_params\": [\"param1\", \"param2\"],\n" " \"description\": \"string\"\n" " }\n" " ],\n" " \"suggested_name\": \"string\",\n" " \"rate_limit\": \"string\",\n" " \"confidence_score\": 0.x\n" "}\n" "Analyse le texte ci-après et complète ces champs." ) }, { "role": "user", "content": input_text } ] try: # Appel Chat Completion à l'API Groq chat_completion = client.chat.completions.create( messages=messages, model="llama-3.3-70b-versatile", temperature=0.0, # On veut une réponse la plus déterministe possible max_completion_tokens=1024, top_p=1, stream=False, # Vous pouvez activer le mode JSON bêta : # response_format={"type": "json_object"}, ) # Récupère le texte de la réponse content = chat_completion.choices[0].message.content # Tente de parser en JSON data = json.loads(content) return data except Exception as e: print(f"Erreur lors de l'analyse Groq : {e}") # En cas d'erreur, on renvoie un squelette vide return { "api_type": None, "base_url": None, "auth_info": { "type": None, "key_name": None, "required": False }, "common_headers": {}, "endpoints": [], "suggested_name": "API_Inconnue", "rate_limit": None, "confidence_score": 0.0 } # ----------------------------------------------------------------------------- # 2. Ajout d'une API (assisté par IA) def ajouter_api(): print("=== Ajout d’une nouvelle API ===") # 2.1 Demande à l'utilisateur s'il souhaite coller la documentation coller_doc = input("Voulez-vous coller la documentation de l’API ? (o/n) : ") doc_api = "" if coller_doc.lower() == 'o': print("Collez la documentation ci-dessous (validez par une ligne vide) :") lignes_doc = [] while True: ligne = input() if ligne == "": break lignes_doc.append(ligne) doc_api = "\n".join(lignes_doc) # 2.2 Demandez l’URL ou une description en langage naturel url_ou_description = input("Entrez l’URL de l’API ou une description en langage naturel : ") # Prépare le texte à analyser texte_a_analyser = doc_api if doc_api else url_ou_description # 2.3 Analyse via Groq resultats_analyse = analyser_api_avec_groq(texte_a_analyser, groq_api_key="gsk_XXXXXXXXXXXXXXX") confidence_score = resultats_analyse.get("confidence_score", 0) # 2.4 Si le score de confiance est faible, on redemande plus d'infos if confidence_score < 0.5: print("Le score de confiance de l’analyse est faible. Veuillez fournir plus d’informations.") # Optionnel : on pourrait réitérer la demande à l’utilisateur # ... # Récupération des champs api_type = resultats_analyse.get("api_type") base_url = resultats_analyse.get("base_url") auth_info = resultats_analyse.get("auth_info", {}) common_headers = resultats_analyse.get("common_headers", {}) endpoints = resultats_analyse.get("endpoints", []) suggested_name = resultats_analyse.get("suggested_name", "NouvelleAPI") rate_limit = resultats_analyse.get("rate_limit") print(f"Nom suggéré pour l’API : {suggested_name}") nom_api = input(f"Entrez le nom de l’API ({suggested_name}) : ") if not nom_api: nom_api = suggested_name # Authentification api_key_value = None if auth_info.get("required", False): api_key_value = input("Entrez la valeur de la clé API ou du token d’authentification : ") # Construction de la configuration de la nouvelle API nouvelle_api = { "name": nom_api, "type": api_type, "base_url": base_url, "auth_info": auth_info, "api_key_value": api_key_value, "common_headers": common_headers, "endpoints": endpoints, "rate_limit": rate_limit } # 2.5 Enregistrement apis_configurees.append(nouvelle_api) print(f"L’API '{nom_api}' a bien été ajoutée avec l’URL de base : {base_url}\n") # ----------------------------------------------------------------------------- # 3. Lister les API configurées def lister_apis(): print("=== Liste des API configurées ===") if not apis_configurees: print("Aucune API n’est configurée pour le moment.\n") return for i, api in enumerate(apis_configurees): print(f"{i+1}. Nom : {api['name']}") print(f" URL de base : {api['base_url']}") print(f" Type : {api.get('type')}") if api.get("rate_limit"): print(f" Limitation de débit : {api['rate_limit']}") print(" Endpoints :") for endpoint in api["endpoints"]: print(f" - {endpoint['name']} ({endpoint['method']} {endpoint['path']})") print() print() # ----------------------------------------------------------------------------- # 4. Modifier une API def modifier_api(): print("=== Modification d’une API ===") if not apis_configurees: print("Aucune API n’est configurée.\n") return # 4.1 Affichez la liste des API for i, api in enumerate(apis_configurees): print(f"{i+1}. {api['name']}") # 4.2 Demandez laquelle modifier (nom ou numéro) choix = input("Quelle API souhaitez-vous modifier ? Entrez un nom ou un numéro : ") api_choisie = None # Tente la conversion en entier try: index = int(choix) - 1 if 0 <= index < len(apis_configurees): api_choisie = apis_configurees[index] except ValueError: # Sinon on cherche par nom for api in apis_configurees: if api["name"].lower() == choix.lower(): api_choisie = api break if not api_choisie: print("API introuvable.\n") return print(f"API sélectionnée : {api_choisie['name']}") print("Que voulez-vous modifier ? (ex: 'changer l'URL de base', 'mettre à jour la clé API', 'ajouter un endpoint', 'modifier un endpoint', 'supprimer un endpoint')") modification = input("> ") # 4.3 Logique simplifiée d’interprétation du texte modification_lower = modification.lower() if "url" in modification_lower: nouvelle_url = input("Entrez la nouvelle URL de base : ") api_choisie["base_url"] = nouvelle_url print("URL de base modifiée avec succès.\n") if "clé" in modification_lower or "key" in modification_lower: nouvelle_cle = input("Entrez la nouvelle clé API : ") api_choisie["api_key_value"] = nouvelle_cle print("Clé API modifiée avec succès.\n") if "ajouter un endpoint" in modification_lower: print("=== Ajout d'un endpoint ===") nom_endpoint = input("Nom du nouvel endpoint : ") path_endpoint = input("Chemin (ex: /playlists/{playlist_id}/tracks) : ") methode = input("Méthode HTTP (GET, POST, etc.) : ") params_requis = input("Paramètres requis (séparés par des virgules) : ").split(",") params_op = input("Paramètres optionnels (séparés par des virgules) : ").split(",") nouveau_endpoint = { "name": nom_endpoint, "path": path_endpoint, "method": methode.upper(), "required_params": [p.strip() for p in params_requis if p.strip()], "optional_params": [p.strip() for p in params_op if p.strip()], "description": "" } api_choisie["endpoints"].append(nouveau_endpoint) print(f"Endpoint '{nom_endpoint}' ajouté.\n") if "modifier un endpoint" in modification_lower: print("=== Modification d'un endpoint existant ===") for i, ep in enumerate(api_choisie["endpoints"]): print(f"{i+1}. {ep['name']} ({ep['method']} {ep['path']})") choix_ep = input("Quel endpoint souhaitez-vous modifier ? (numéro ou nom) : ") endpoint_choisi = None try: ep_index = int(choix_ep) - 1 if 0 <= ep_index < len(api_choisie["endpoints"]): endpoint_choisi = api_choisie["endpoints"][ep_index] except ValueError: for ep in api_choisie["endpoints"]: if ep["name"].lower() == choix_ep.lower(): endpoint_choisi = ep break if not endpoint_choisi: print("Endpoint introuvable.") return print(f"Endpoint sélectionné : {endpoint_choisi['name']}") action_modif = input("Que voulez-vous modifier ? (ex: 'ajouter un paramètre', 'changer la méthode', etc.) : ") if "ajouter un paramètre" in action_modif.lower(): nom_param = input("Nom du paramètre : ") type_param = input("Paramètre requis ou optionnel ? (r/o) : ") if type_param.lower() == "r": endpoint_choisi["required_params"].append(nom_param) print(f"Le paramètre requis '{nom_param}' a été ajouté.") else: endpoint_choisi["optional_params"].append(nom_param) print(f"Le paramètre optionnel '{nom_param}' a été ajouté.") if "supprimer un endpoint" in modification_lower: print("=== Suppression d'un endpoint ===") for i, ep in enumerate(api_choisie["endpoints"]): print(f"{i+1}. {ep['name']} ({ep['method']} {ep['path']})") choix_ep = input("Quel endpoint souhaitez-vous supprimer ? (numéro ou nom) : ") ep_a_supprimer = None try: ep_index = int(choix_ep) - 1 if 0 <= ep_index < len(api_choisie["endpoints"]): ep_a_supprimer = api_choisie["endpoints"][ep_index] except ValueError: for ep in api_choisie["endpoints"]: if ep["name"].lower() == choix_ep.lower(): ep_a_supprimer = ep break if ep_a_supprimer: api_choisie["endpoints"].remove(ep_a_supprimer) print(f"L’endpoint '{ep_a_supprimer['name']}' a été supprimé.") else: print("Endpoint introuvable.") print("Modification(s) terminée(s).\n") # ----------------------------------------------------------------------------- # 5. Supprimer une API def supprimer_api(): print("=== Suppression d’une API ===") if not apis_configurees: print("Aucune API n’est configurée.\n") return # 5.1 Liste des API for i, api in enumerate(apis_configurees): print(f"{i+1}. {api['name']}") # 5.2 Demandez laquelle supprimer (nom ou numéro) choix = input("Quelle API souhaitez-vous supprimer ? (nom ou numéro) : ") api_a_supprimer = None try: index = int(choix) - 1 if 0 <= index < len(apis_configurees): api_a_supprimer = apis_configurees[index] except ValueError: for api in apis_configurees: if api["name"].lower() == choix.lower(): api_a_supprimer = api break if not api_a_supprimer: print("API introuvable.\n") return # 5.3 Confirmation confirm = input(f"Êtes-vous sûr de vouloir supprimer l’API {api_a_supprimer['name']} ? (o/n) : ") if confirm.lower() == 'o': apis_configurees.remove(api_a_supprimer) print(f"L’API {api_a_supprimer['name']} a été supprimée.\n") else: print("Opération annulée.\n") # ----------------------------------------------------------------------------- # 6. Tester un Endpoint (Exemple avec Spotify) def tester_endpoint(): print("=== Tester un endpoint ===") if not apis_configurees: print("Aucune API n’est configurée.\n") return # 6.1 Sélection de l’API for i, api in enumerate(apis_configurees): print(f"{i+1}. {api['name']}") choix = input("Sur quelle API souhaitez-vous tester un endpoint ? (nom ou numéro) : ") api_choisie = None try: index = int(choix) - 1 if 0 <= index < len(apis_configurees): api_choisie = apis_configurees[index] except ValueError: for api in apis_configurees: if api["name"].lower() == choix.lower(): api_choisie = api break if not api_choisie: print("API introuvable.\n") return # 6.2 Sélection de l’endpoint if not api_choisie["endpoints"]: print(f"L’API {api_choisie['name']} n’a aucun endpoint configuré.\n") return print(f"Endpoints disponibles pour {api_choisie['name']} :") for i, ep in enumerate(api_choisie["endpoints"]): print(f"{i+1}. {ep['name']} ({ep['method']} {ep['path']})") choix_ep = input("Quel endpoint souhaitez-vous tester ? (numéro ou nom) : ") endpoint_choisi = None try: ep_index = int(choix_ep) - 1 if 0 <= ep_index < len(api_choisie["endpoints"]): endpoint_choisi = api_choisie["endpoints"][ep_index] except ValueError: for ep in api_choisie["endpoints"]: if ep["name"].lower() == choix_ep.lower(): endpoint_choisi = ep break if not endpoint_choisi: print("Endpoint introuvable.") return # Exemple concret pour Spotify : # - Lire une playlist : param requis => playlist_id # - Vérifier si une musique est dans une playlist : param requis => playlist_id, track_id (ou music_id) # 6.3 Récupération des paramètres (required et optional) required_params = {} for rp in endpoint_choisi.get("required_params", []): required_params[rp] = input(f"Entrez la valeur pour '{rp}' : ") optional_params = {} for op in endpoint_choisi.get("optional_params", []): val = input(f"Entrez la valeur (ou laissez vide) pour le paramètre optionnel '{op}' : ") if val: optional_params[op] = val # 6.4 Construction de l’URL base_url = api_choisie["base_url"] path = endpoint_choisi["path"] # Remplace les variables {param} dans le path for rp_key, rp_value in required_params.items(): path = path.replace(f"{{{rp_key}}}", rp_value) url = base_url + path # Prépare les en-têtes headers = dict(api_choisie["common_headers"]) auth_info = api_choisie.get("auth_info", {}) if auth_info.get("required") and api_choisie.get("api_key_value"): if auth_info["type"].lower() == "bearer": headers[auth_info["key_name"]] = f"Bearer {api_choisie['api_key_value']}" else: # Autres types (ex: Basic, etc.) headers[auth_info["key_name"]] = api_choisie["api_key_value"] # Prépare les query params (pour GET) ou body (pour POST, etc.) params = {} for op_key, op_value in optional_params.items(): params[op_key] = op_value method = endpoint_choisi["method"].upper() print(f"Lancement du test de l'endpoint : {method} {url}") # 6.5 Exécution de la requête response = None try: if method == "GET": response = requests.get(url, headers=headers, params=params) elif method == "POST": response = requests.post(url, headers=headers, json=params) elif method == "PUT": response = requests.put(url, headers=headers, json=params) elif method == "DELETE": response = requests.delete(url, headers=headers, json=params) else: print(f"Méthode {method} non gérée dans cet exemple.") return if response is not None: print(f"Statut de la réponse : {response.status_code}") print("Corps de la réponse :") try: print(json.dumps(response.json(), indent=2)) except: print(response.text) except Exception as e: print(f"Erreur lors de l’appel à l’endpoint : {e}") # ----------------------------------------------------------------------------- # Fonction principale : menu def main(): while True: print("=== Menu Principal ===") print("1. Ajouter une API (assisté par IA)") print("2. Liste des API configurées") print("3. Modifier une API") print("4. Supprimer une API") print("5. Tester un endpoint") print("6. Quitter") choix = input("Choisissez une option : ") if choix == '1': ajouter_api() elif choix == '2': lister_apis() elif choix == '3': modifier_api() elif choix == '4': supprimer_api() elif choix == '5': tester_endpoint() elif choix == '6': print("Au revoir !") sys.exit(0) else: print("Choix invalide.\n") if __name__ == "__main__": main()
Menu Principal
L’utilisateur est guidé par un menu :
Ajout d’API (assisté par IA)
analyser_api_avec_groq(...)
, qui génère un JSON décrivant l’API.confidence_score
< 0.5, on avertit l’utilisateur qu’on manque d’infos.Liste des APIs
Modification d’API
Suppression d’API
Test d’un endpoint (exemple Spotify)
/playlists/{playlist_id}/tracks
).{playlist_id}
et éventuellement market
, etc.En suivant ce script, vous pouvez gérer tout le cycle de vie d’une intégration d’API (ajout, modification, suppression, test) avec une aide automatique pour extraire les détails d’API grâce à Groq.
Tackling large text
User's data seems too large for Groq API. Let's break it into chunks or multiple requests to prevent JSON parsing errors.
Refining logic
I'm thinking through strategies like summarization before passing data to Groq API and trying smaller models to better handle oversized inputs and avoid empty JSON errors.
Enhancing user experience
I'm exploring options to simplify the code, like trying different models and adopting a chunking approach for handling large documents, ensuring a smoother user experience.
Implementing strategies
I’m focusing on summarizing large documents and conducting partial Groq API calls. This approach aims to enhance user-friendliness and manage extensive text more efficiently.
Enhancing efficiency
I’m detailing methods to manage large documents: automatically chunking them, summarizing first, and conducting partial Groq API calls. This ensures a more efficient and user-friendly process.
Streamlining document handling
I’m setting up a code plan: summarizing larger docs in chunks, then analyzing the final summary with Groq API. Smaller docs will be handled directly, ensuring efficient data processing.
Wrapping up the process
I'm focusing on crafting concise summarizer and analyzer functions, introducing a more informative error message for JSON issues, and ensuring a more user-friendly code execution.
Voici une version améliorée du code qui gère mieux les longs textes de documentation et évite (autant que possible) les erreurs de parsing JSON renvoyées par l’API Groq. Pour cela, nous allons :
"Expecting value: line 1 column 1 (char 0)"
), on la découpe en morceaux et on utilise Groq pour produire un résumé automatique (en plusieurs étapes) avant de réanalyser ce résumé pour extraire les informations d’API.Ainsi, même si l’utilisateur colle un texte très volumineux, on n’envoie à la fin qu’un texte de taille raisonnable à la fonction qui extrait les champs (URL de base, endpoints, etc.). Nous profiterons également de cette occasion pour afficher des messages plus clairs et guider l’utilisateur.
Remarque : La logique de « découpe puis résumé » peut être adaptée à votre convenance. L’exemple ci-dessous illustre une approche basique qui segmente le texte s’il dépasse une certaine taille (par exemple 3000 caractères).
pip install groq
Copiez-collez ce script dans un fichier Python (par exemple main.py
) et exécutez-le.
import sys import json import requests # IMPORTANT : importez le SDK Groq from groq import Groq # ----------------------------------------------------------------------------- # Stockage en mémoire des APIs (vous pouvez remplacer par un fichier ou une base de données) apis_configurees = [] # ----------------------------------------------------------------------------- # CONFIG : seuil de caractères au-delà duquel on tentera un résumé avant l'analyse MAX_CHARS_DIRECT_ANALYSIS = 3000 # ----------------------------------------------------------------------------- def summarizer_groq(long_text, groq_api_key="gsk_XXXXXXXXXXXXXXX"): """ Si le texte est trop long pour être analysé en une fois, on le découpe et on génère un résumé progressif. L'objectif est de réduire le texte à une taille raisonnable pour la suite (analyse des endpoints). """ client = Groq(api_key=groq_api_key) # Découpage en chunks de ~3000 caractères pour rester large # Vous pouvez ajuster la taille selon vos besoins et limites du modèle. chunks = [] start = 0 chunk_size = 3000 while start < len(long_text): end = start + chunk_size chunks.append(long_text[start:end]) start = end # Maintenant, on génère un résumé pour chaque chunk, puis on combine ces résumés summaries = [] for i, chunk_text in enumerate(chunks, start=1): print(f"[INFO] Résumé du chunk {i}/{len(chunks)}...") messages = [ { "role": "system", "content": ( "Tu es un assistant chargé de résumer de la documentation d'API. " "Retourne un résumé concis (quelques phrases) du texte fourni. " "Ne donne pas de structure JSON, juste un résumé en langage naturel." ) }, { "role": "user", "content": chunk_text } ] try: completion = client.chat.completions.create( messages=messages, model="llama-3.3-70b-versatile", # ou un autre modèle temperature=0.2, max_completion_tokens=1024, top_p=1, stream=False ) summaries.append(completion.choices[0].message.content.strip()) except Exception as e: print(f"Erreur lors du résumé du chunk {i}: {e}") summaries.append("") # On combine tous les résumés en un texte plus court combined_summary = "\n".join(summaries) print("[INFO] Résumé global généré. Longueur du résumé :", len(combined_summary), "caractères.") return combined_summary def analyser_api_avec_groq(input_text, groq_api_key="gsk_XXXXXXXXXXXXXXX"): """ Envoie 'input_text' à l’API Groq via un chat completion, pour en extraire un JSON décrivant les informations d'API. Le JSON renvoyé doit contenir au moins : - api_type (REST, GraphQL, SOAP) - base_url - auth_info {type, key_name, required} - common_headers - endpoints (liste) - suggested_name - rate_limit - confidence_score """ # 1) Si le texte est trop long, on le résume d'abord text_for_analysis = input_text if len(input_text) > MAX_CHARS_DIRECT_ANALYSIS: print("[INFO] La documentation est trop volumineuse, on génère un résumé d’abord.") text_for_analysis = summarizer_groq(input_text, groq_api_key=groq_api_key) # 2) On tente maintenant d'analyser ce texte (ou ce résumé) pour extraire un JSON client = Groq(api_key=groq_api_key) messages = [ { "role": "system", "content": ( "Tu es un assistant d'analyse d'API. " "Retourne un JSON de la forme :\n" "{\n" " \"api_type\": \"REST | GraphQL | SOAP\",\n" " \"base_url\": \"string\",\n" " \"auth_info\": {\n" " \"type\": \"string (Bearer, Basic, etc.)\",\n" " \"key_name\": \"string\",\n" " \"required\": true/false\n" " },\n" " \"common_headers\": {\n" " \"Header-Name\": \"Header-Value\"\n" " },\n" " \"endpoints\": [\n" " {\n" " \"name\": \"string\",\n" " \"path\": \"string\",\n" " \"method\": \"GET | POST | ...\",\n" " \"required_params\": [\"param1\", \"param2\"],\n" " \"optional_params\": [\"param1\", \"param2\"],\n" " \"description\": \"string\"\n" " }\n" " ],\n" " \"suggested_name\": \"string\",\n" " \"rate_limit\": \"string\",\n" " \"confidence_score\": 0.x\n" "}\n" "Analyse le texte ci-après et complète ces champs au mieux." ) }, { "role": "user", "content": text_for_analysis } ] try: chat_completion = client.chat.completions.create( messages=messages, model="llama-3.3-70b-versatile", temperature=0.0, max_completion_tokens=1024, top_p=1, stream=False, ) content = chat_completion.choices[0].message.content # Tente de parser en JSON data = json.loads(content) return data except Exception as e: print(f"[ERREUR] Impossible d'analyser en JSON via Groq : {e}") print("[INFO] Nous allons retourner un squelette par défaut.") return { "api_type": None, "base_url": None, "auth_info": { "type": None, "key_name": None, "required": False }, "common_headers": {}, "endpoints": [], "suggested_name": "API_Inconnue", "rate_limit": None, "confidence_score": 0.0 } # ----------------------------------------------------------------------------- # 2. Ajout d'une API (assisté par IA) def ajouter_api(): print("=== Ajout d’une nouvelle API ===") # 2.1 Demande à l'utilisateur s'il souhaite coller la documentation coller_doc = input("Voulez-vous coller la documentation de l’API ? (o/n) : ") doc_api = "" if coller_doc.lower() == 'o': print("Collez la documentation ci-dessous (validez par une ligne vide) :") lignes_doc = [] while True: ligne = input() if ligne == "": break lignes_doc.append(ligne) doc_api = "\n".join(lignes_doc) # 2.2 Demandez l’URL ou une description en langage naturel url_ou_description = input( "Entrez l’URL de l’API ou une description en langage naturel (ou appuyez sur Entrée si tout est dans la doc) : " ) # Prépare le texte à analyser (doc + éventuellement une URL/description succincte) texte_complet = "" if doc_api.strip(): texte_complet += doc_api.strip() if url_ou_description.strip(): # On sépare par 2 sauts de ligne pour rendre le tout plus lisible texte_complet += "\n\n" + url_ou_description.strip() if not texte_complet: print("[ATTENTION] Aucune information fournie, l'analyse risque d'être vide.") texte_complet = "Aucune information sur l'API." # 2.3 Analyse via Groq resultats_analyse = analyser_api_avec_groq(texte_complet, groq_api_key="gsk_XXXXXXXXXXXXXXX") confidence_score = resultats_analyse.get("confidence_score", 0) # 2.4 Si le score de confiance est faible, on redemande plus d'infos if confidence_score < 0.5: print("Le score de confiance de l’analyse est faible. " "Les informations retournées peuvent être incomplètes ou incorrectes.") print("Si besoin, vous pouvez modifier la configuration manuellement après coup.") # Récupération des champs api_type = resultats_analyse.get("api_type") base_url = resultats_analyse.get("base_url") auth_info = resultats_analyse.get("auth_info", {}) common_headers = resultats_analyse.get("common_headers", {}) endpoints = resultats_analyse.get("endpoints", []) suggested_name = resultats_analyse.get("suggested_name", "NouvelleAPI") rate_limit = resultats_analyse.get("rate_limit") print(f"Nom suggéré pour l’API : {suggested_name}") nom_api = input(f"Entrez le nom de l’API ({suggested_name}) : ") if not nom_api.strip(): nom_api = suggested_name # Authentification api_key_value = None if auth_info.get("required", False): api_key_value = input("Entrez la valeur de la clé API ou du token d’authentification : ") # Construction de la configuration de la nouvelle API nouvelle_api = { "name": nom_api, "type": api_type, "base_url": base_url, "auth_info": auth_info, "api_key_value": api_key_value, "common_headers": common_headers, "endpoints": endpoints, "rate_limit": rate_limit } # 2.5 Enregistrement apis_configurees.append(nouvelle_api) print(f"\nL’API '{nom_api}' a bien été ajoutée.") print(f" - Type : {api_type}") print(f" - URL de base : {base_url if base_url else 'Aucune URL détectée'}\n") # ----------------------------------------------------------------------------- # 3. Lister les API configurées def lister_apis(): print("=== Liste des API configurées ===") if not apis_configurees: print("Aucune API n’est configurée pour le moment.\n") return for i, api in enumerate(apis_configurees, start=1): print(f"{i}. Nom : {api['name']}") print(f" URL de base : {api['base_url']}") print(f" Type : {api.get('type')}") if api.get("rate_limit"): print(f" Limitation de débit : {api['rate_limit']}") if api["endpoints"]: print(" Endpoints :") for endpoint in api["endpoints"]: print(f" - {endpoint['name']} ({endpoint['method']} {endpoint['path']})") else: print(" Aucun endpoint configuré.") print() print() # ----------------------------------------------------------------------------- # 4. Modifier une API def modifier_api(): print("=== Modification d’une API ===") if not apis_configurees: print("Aucune API n’est configurée.\n") return # 4.1 Affichez la liste des API for i, api in enumerate(apis_configurees, start=1): print(f"{i}. {api['name']}") # 4.2 Demandez laquelle modifier (nom ou numéro) choix = input("Quelle API souhaitez-vous modifier ? Entrez un nom ou un numéro : ") api_choisie = None # Tente la conversion en entier try: index = int(choix) - 1 if 0 <= index < len(apis_configurees): api_choisie = apis_configurees[index] except ValueError: # Sinon on cherche par nom for api in apis_configurees: if api["name"].lower() == choix.lower(): api_choisie = api break if not api_choisie: print("API introuvable.\n") return print(f"\nAPI sélectionnée : {api_choisie['name']}") print("Que voulez-vous modifier ? (ex: 'changer l'URL de base', 'mettre à jour la clé API', " "'ajouter un endpoint', 'modifier un endpoint', 'supprimer un endpoint')") modification = input("> ") modification_lower = modification.lower() if "url" in modification_lower: nouvelle_url = input("Entrez la nouvelle URL de base : ") api_choisie["base_url"] = nouvelle_url print("URL de base modifiée avec succès.\n") if "clé" in modification_lower or "key" in modification_lower: nouvelle_cle = input("Entrez la nouvelle clé API : ") api_choisie["api_key_value"] = nouvelle_cle print("Clé API modifiée avec succès.\n") if "ajouter un endpoint" in modification_lower: print("=== Ajout d'un endpoint ===") nom_endpoint = input("Nom du nouvel endpoint : ") path_endpoint = input("Chemin (ex: /playlists/{playlist_id}/tracks) : ") methode = input("Méthode HTTP (GET, POST, etc.) : ") params_requis = input("Paramètres requis (séparés par des virgules) : ").split(",") params_op = input("Paramètres optionnels (séparés par des virgules) : ").split(",") nouveau_endpoint = { "name": nom_endpoint, "path": path_endpoint, "method": methode.upper(), "required_params": [p.strip() for p in params_requis if p.strip()], "optional_params": [p.strip() for p in params_op if p.strip()], "description": "" } api_choisie["endpoints"].append(nouveau_endpoint) print(f"Endpoint '{nom_endpoint}' ajouté.\n") if "modifier un endpoint" in modification_lower: print("=== Modification d'un endpoint existant ===") for i, ep in enumerate(api_choisie["endpoints"], start=1): print(f"{i}. {ep['name']} ({ep['method']} {ep['path']})") choix_ep = input("Quel endpoint souhaitez-vous modifier ? (numéro ou nom) : ") endpoint_choisi = None try: ep_index = int(choix_ep) - 1 if 0 <= ep_index < len(api_choisie["endpoints"]): endpoint_choisi = api_choisie["endpoints"][ep_index] except ValueError: for ep in api_choisie["endpoints"]: if ep["name"].lower() == choix_ep.lower(): endpoint_choisi = ep break if not endpoint_choisi: print("Endpoint introuvable.") return print(f"Endpoint sélectionné : {endpoint_choisi['name']}") action_modif = input("Que voulez-vous modifier ? (ex: 'ajouter un paramètre', 'changer la méthode', etc.) : ") if "ajouter un paramètre" in action_modif.lower(): nom_param = input("Nom du paramètre : ") type_param = input("Paramètre requis ou optionnel ? (r/o) : ") if type_param.lower() == "r": endpoint_choisi["required_params"].append(nom_param) print(f"Le paramètre requis '{nom_param}' a été ajouté.") else: endpoint_choisi["optional_params"].append(nom_param) print(f"Le paramètre optionnel '{nom_param}' a été ajouté.") if "supprimer un endpoint" in modification_lower: print("=== Suppression d'un endpoint ===") for i, ep in enumerate(api_choisie["endpoints"], start=1): print(f"{i}. {ep['name']} ({ep['method']} {ep['path']})") choix_ep = input("Quel endpoint souhaitez-vous supprimer ? (numéro ou nom) : ") ep_a_supprimer = None try: ep_index = int(choix_ep) - 1 if 0 <= ep_index < len(api_choisie["endpoints"]): ep_a_supprimer = api_choisie["endpoints"][ep_index] except ValueError: for ep in api_choisie["endpoints"]: if ep["name"].lower() == choix_ep.lower(): ep_a_supprimer = ep break if ep_a_supprimer: api_choisie["endpoints"].remove(ep_a_supprimer) print(f"L’endpoint '{ep_a_supprimer['name']}' a été supprimé.") else: print("Endpoint introuvable.") print("Modification(s) terminée(s).\n") # ----------------------------------------------------------------------------- # 5. Supprimer une API def supprimer_api(): print("=== Suppression d’une API ===") if not apis_configurees: print("Aucune API n’est configurée.\n") return # 5.1 Liste des API for i, api in enumerate(apis_configurees, start=1): print(f"{i}. {api['name']}") # 5.2 Demandez laquelle supprimer (nom ou numéro) choix = input("Quelle API souhaitez-vous supprimer ? (nom ou numéro) : ") api_a_supprimer = None try: index = int(choix) - 1 if 0 <= index < len(apis_configurees): api_a_supprimer = apis_configurees[index] except ValueError: for api in apis_configurees: if api["name"].lower() == choix.lower(): api_a_supprimer = api break if not api_a_supprimer: print("API introuvable.\n") return # 5.3 Confirmation confirm = input(f"Êtes-vous sûr de vouloir supprimer l’API {api_a_supprimer['name']} ? (o/n) : ") if confirm.lower() == 'o': apis_configurees.remove(api_a_supprimer) print(f"L’API {api_a_supprimer['name']} a été supprimée.\n") else: print("Opération annulée.\n") # ----------------------------------------------------------------------------- # 6. Tester un Endpoint (Exemple avec Spotify) def tester_endpoint(): print("=== Tester un endpoint ===") if not apis_configurees: print("Aucune API n’est configurée.\n") return # 6.1 Sélection de l’API for i, api in enumerate(apis_configurees, start=1): print(f"{i}. {api['name']}") choix = input("Sur quelle API souhaitez-vous tester un endpoint ? (nom ou numéro) : ") api_choisie = None try: index = int(choix) - 1 if 0 <= index < len(apis_configurees): api_choisie = apis_configurees[index] except ValueError: for api in apis_configurees: if api["name"].lower() == choix.lower(): api_choisie = api break if not api_choisie: print("API introuvable.\n") return # 6.2 Sélection de l’endpoint if not api_choisie["endpoints"]: print(f"L’API {api_choisie['name']} n’a aucun endpoint configuré.\n") return print(f"Endpoints disponibles pour {api_choisie['name']} :") for i, ep in enumerate(api_choisie["endpoints"], start=1): print(f"{i}. {ep['name']} ({ep['method']} {ep['path']})") choix_ep = input("Quel endpoint souhaitez-vous tester ? (numéro ou nom) : ") endpoint_choisi = None try: ep_index = int(choix_ep) - 1 if 0 <= ep_index < len(api_choisie["endpoints"]): endpoint_choisi = api_choisie["endpoints"][ep_index] except ValueError: for ep in api_choisie["endpoints"]: if ep["name"].lower() == choix_ep.lower(): endpoint_choisi = ep break if not endpoint_choisi: print("Endpoint introuvable.") return # Exemple concret pour Spotify : # - Lire une playlist : param requis => playlist_id # - Vérifier si une musique est dans une playlist : param requis => playlist_id, track_id # 6.3 Récupération des paramètres (required et optional) required_params = {} for rp in endpoint_choisi.get("required_params", []): required_params[rp] = input(f"Entrez la valeur pour '{rp}' : ") optional_params = {} for op in endpoint_choisi.get("optional_params", []): val = input(f"Entrez la valeur (ou laissez vide) pour le paramètre optionnel '{op}' : ") if val: optional_params[op] = val # 6.4 Construction de l’URL base_url = api_choisie["base_url"] path = endpoint_choisi["path"] # Remplace les variables {param} dans le path for rp_key, rp_value in required_params.items(): path = path.replace(f"{{{rp_key}}}", rp_value) url = base_url + path if base_url else path # Prépare les en-têtes headers = dict(api_choisie["common_headers"]) auth_info = api_choisie.get("auth_info", {}) if auth_info.get("required") and api_choisie.get("api_key_value"): # Si c'est un Bearer if auth_info["type"] and "bearer" in auth_info["type"].lower(): bearer_token = api_choisie["api_key_value"] key_name = auth_info.get("key_name", "Authorization") headers[key_name] = f"Bearer {bearer_token}" else: # Basic ou autre key_name = auth_info.get("key_name", "Authorization") headers[key_name] = api_choisie["api_key_value"] # Prépare les query params (GET, etc.) / body (POST, etc.) params = {} for op_key, op_value in optional_params.items(): params[op_key] = op_value method = endpoint_choisi["method"].upper() print(f"\nLancement du test de l'endpoint : {method} {url}") print(f"En-têtes : {headers}") print(f"Paramètres : {params}\n") # 6.5 Exécution de la requête response = None try: if method == "GET": response = requests.get(url, headers=headers, params=params) elif method == "POST": response = requests.post(url, headers=headers, json=params) elif method == "PUT": response = requests.put(url, headers=headers, json=params) elif method == "DELETE": response = requests.delete(url, headers=headers, json=params) else: print(f"Méthode {method} non gérée dans cet exemple.") return if response is not None: print(f"Statut de la réponse : {response.status_code}") print("Corps de la réponse :") try: print(json.dumps(response.json(), indent=2)) except: print(response.text) except Exception as e: print(f"Erreur lors de l’appel à l’endpoint : {e}") # ----------------------------------------------------------------------------- # Fonction principale : menu def main(): while True: print("=== Menu Principal ===") print("1. Ajouter une API (assisté par IA)") print("2. Liste des API configurées") print("3. Modifier une API") print("4. Supprimer une API") print("5. Tester un endpoint") print("6. Quitter") choix = input("Choisissez une option : ") if choix == '1': ajouter_api() elif choix == '2': lister_apis() elif choix == '3': modifier_api() elif choix == '4': supprimer_api() elif choix == '5': tester_endpoint() elif choix == '6': print("Au revoir !") sys.exit(0) else: print("Choix invalide.\n") if __name__ == "__main__": main()
Découpage et Résumé :
summarizer_groq
prend en entrée un très long texte et le coupe en « chunks » de 3000 caractères.analyser_api_avec_groq
.Analyse plus robuste :
Messages utilisateur plus clairs :
Meilleure intégration :
Avec ces modifications, vous devriez éviter les blocages lorsque l’utilisateur colle une très longue documentation, et le système sera plus agréable à utiliser.
Ensuring valid JSON
I'm working on forcing the "response_format":{"type":"json_object"} in the chat completion create call to ensure the model consistently returns valid JSON, preventing JSON parse errors.
Ensuring accurate JSON
I’m piecing together steps to summarize a document in plain text, use "response_format":{"type":"json_object"} for the final call, and address errors with a fallback approach, prioritizing models like "mixtral-7b-instruct".
Ensuring JSON accuracy
I’m finalizing the approach to use "mixtral-7b-instruct" or another model for strict JSON output, including a JSON structure description and error handling.
Ensuring JSON integrity
I’m confirming the use of "mixtral-7b-instruct" for generating JSON and detailing the fallback process for cases where JSON generation fails, aiming to maintain accuracy and user clarity.
Thought about error handling and text summarization pendant 18 secondes
Ci-dessous, vous trouverez une version améliorée qui force Groq à renvoyer de la réponse en JSON en utilisant son mode JSON bêta (via response_format={"type": "json_object"}
). De plus, nous utilisons le modèle Mixtral (indiqué comme meilleur pour la génération de JSON dans la documentation Groq). Ainsi, vous évitez au maximum le risque de recevoir un texte non-JSON et de provoquer l’erreur de parsing :
[ERREUR] Impossible d'analyser en JSON via Groq : Expecting value: line 1 column 1 (char 0)
response_format={"type": "json_object"}
.system
prompt, on décrit le format JSON exact attendu.model="mixtral-7b-instruct"
, qui (d’après la doc) produit mieux du JSON que d’autres.json_validate_failed
, c’est que la réponse n’était pas un JSON valide. Nous gérons cette exception pour éviter le blocage.pip install groq
Vous pouvez remplacer votre code existant par le suivant. L’essentiel des modifications se situe dans la partie analyser_api_avec_groq
et la fonction de résumé.
import sys import json import requests from groq import Groq # Stockage en mémoire des APIs (à adapter au besoin) apis_configurees = [] # Paramètre : longueur max avant de résumer MAX_CHARS_DIRECT_ANALYSIS = 3000 # --------------------------------------------------------------------------- # 1. Fonction de résumé (texte brut) si la doc est trop volumineuse def summarizer_groq(long_text, groq_api_key="gsk_XXXXXXXXXXXXXXX"): """ Découpe la documentation en chunks et génère un résumé global en langage naturel. Ceci n'utilise pas le mode JSON : on veut juste un résumé texte. """ client = Groq(api_key=groq_api_key) chunk_size = 3000 chunks = [] start = 0 while start < len(long_text): end = start + chunk_size chunks.append(long_text[start:end]) start = end summaries = [] for i, chunk_text in enumerate(chunks, start=1): print(f"[INFO] Résumé du chunk {i}/{len(chunks)}...") messages = [ { "role": "system", "content": ( "Tu es un assistant chargé de résumer la documentation d'API. " "Retourne un résumé concis (en langage courant) du texte fourni. " "Ne génère pas de JSON, pas de code, juste un texte résumé clair." ) }, { "role": "user", "content": chunk_text } ] try: completion = client.chat.completions.create( messages=messages, # Mixtral est conseillé pour la génération de JSON, # mais convient également pour la génération de texte court. model="mixtral-7b-instruct", temperature=0.2, max_completion_tokens=1024, top_p=1, stream=False ) summary_text = completion.choices[0].message.content.strip() summaries.append(summary_text) except Exception as e: print(f"[ERREUR] Impossible de résumer le chunk {i} : {e}") # On concatène juste une chaîne vide si échec summaries.append("") combined_summary = "\n".join(summaries) print(f"[INFO] Résumé global généré. Longueur du résumé : {len(combined_summary)} caractères.") return combined_summary # --------------------------------------------------------------------------- # 2. Fonction d'analyse finale en JSON def analyser_api_avec_groq(input_text, groq_api_key="gsk_XXXXXXXXXXXXXXX"): """ 1) Si le texte est trop long, on génère un résumé texte via summarizer_groq. 2) On passe ensuite (ou directement) le texte final dans un prompt qui demande un JSON strict, en utilisant la 'response_format={"type": "json_object"}' pour forcer Groq à renvoyer un JSON valide. """ # 1) Résume si trop volumineux text_for_analysis = input_text if len(input_text) > MAX_CHARS_DIRECT_ANALYSIS: print("[INFO] La documentation est trop volumineuse, on génère un résumé d’abord.") text_for_analysis = summarizer_groq(input_text, groq_api_key=groq_api_key) # 2) Appel Chat Completion en mode JSON client = Groq(api_key=groq_api_key) # Prompt : nous exigeons un JSON strict messages = [ { "role": "system", "content": ( "Tu es un assistant d'analyse d'API, tu dois répondre UNIQUEMENT en JSON valide, sans code superflu. " "Respecte le schéma JSON suivant (toutes les clés doivent exister) :\n\n" "{\n" " \"api_type\": \"REST | GraphQL | SOAP\",\n" " \"base_url\": \"string\",\n" " \"auth_info\": {\n" " \"type\": \"string (Bearer, Basic, etc.)\",\n" " \"key_name\": \"string\",\n" " \"required\": true/false\n" " },\n" " \"common_headers\": {\n" " \"Header-Name\": \"Header-Value\"\n" " },\n" " \"endpoints\": [\n" " {\n" " \"name\": \"string\",\n" " \"path\": \"string\",\n" " \"method\": \"GET | POST | ...\",\n" " \"required_params\": [\"param1\", \"param2\"],\n" " \"optional_params\": [\"param1\", \"param2\"],\n" " \"description\": \"string\"\n" " }\n" " ],\n" " \"suggested_name\": \"string\",\n" " \"rate_limit\": \"string\",\n" " \"confidence_score\": 0.0\n" "}\n\n" "Analyse le texte ci-après et renvoie STRICTEMENT un JSON conforme, sans texte additionnel." ) }, { "role": "user", "content": text_for_analysis } ] try: chat_completion = client.chat.completions.create( messages=messages, model="mixtral-7b-instruct", # Meilleur pour JSON d'après la doc temperature=0.0, max_completion_tokens=1024, top_p=1, stream=False, # Activation du mode JSON : Groq renverra un JSON strict ou renverra une erreur response_format={"type": "json_object"} ) # Puisque response_format={"type":"json_object"} est activé, # le contenu renvoyé EST (en principe) déjà du JSON strict. # On l'obtient via : content = chat_completion.choices[0].message.content # content est déjà une chaîne JSON validée par Groq, on peut la charger directement data = json.loads(content) return data except Exception as e: print(f"[ERREUR] Échec de la conversion en JSON : {e}") print("[INFO] Nous allons retourner un squelette par défaut.") return { "api_type": None, "base_url": None, "auth_info": { "type": None, "key_name": None, "required": False }, "common_headers": {}, "endpoints": [], "suggested_name": "API_Inconnue", "rate_limit": None, "confidence_score": 0.0 } # --------------------------------------------------------------------------- # 3. Fonctions du menu def ajouter_api(): print("=== Ajout d’une nouvelle API ===") coller_doc = input("Voulez-vous coller la documentation de l’API ? (o/n) : ") doc_api = "" if coller_doc.lower() == 'o': print("Collez la documentation ci-dessous (finissez par une ligne vide) :") lignes_doc = [] while True: ligne = input() if ligne == "": break lignes_doc.append(ligne) doc_api = "\n".join(lignes_doc) url_ou_description = input( "Entrez l’URL de l’API ou une description en langage naturel (ou laissez vide si déjà dans la doc) : " ) texte_complet = "" if doc_api.strip(): texte_complet += doc_api.strip() if url_ou_description.strip(): texte_complet += "\n\n" + url_ou_description.strip() if not texte_complet: texte_complet = "Pas d'information sur l'API." # Appel Groq pour analyse resultats_analyse = analyser_api_avec_groq(texte_complet, groq_api_key="gsk_XXXXXXXXXXXXXXX") confidence_score = resultats_analyse.get("confidence_score", 0.0) if confidence_score < 0.5: print( "Le score de confiance de l’analyse est faible. " "Les informations retournées peuvent être partielles ou incorrectes.\n" ) # On lit les champs api_type = resultats_analyse.get("api_type") base_url = resultats_analyse.get("base_url") auth_info = resultats_analyse.get("auth_info", {}) common_headers = resultats_analyse.get("common_headers", {}) endpoints = resultats_analyse.get("endpoints", []) suggested_name = resultats_analyse.get("suggested_name", "NouvelleAPI") rate_limit = resultats_analyse.get("rate_limit") print(f"Nom suggéré pour l’API : {suggested_name}") nom_api = input(f"Entrez le nom de l’API ({suggested_name}) : ") if not nom_api.strip(): nom_api = suggested_name # Si auth_info.required == True, on demande la clé api_key_value = None if auth_info.get("required", False): api_key_value = input("Entrez la valeur de la clé API ou du token : ") # Construction de la config nouvelle_api = { "name": nom_api, "type": api_type, "base_url": base_url, "auth_info": auth_info, "api_key_value": api_key_value, "common_headers": common_headers, "endpoints": endpoints, "rate_limit": rate_limit } apis_configurees.append(nouvelle_api) print(f"\n[OK] L’API '{nom_api}' a été ajoutée.") print(f" - Type : {api_type}") print(f" - URL de base : {base_url}\n") def lister_apis(): print("=== Liste des API configurées ===") if not apis_configurees: print("Aucune API n’est configurée.\n") return for i, api in enumerate(apis_configurees, start=1): print(f"{i}. Nom : {api['name']}") print(f" URL de base : {api['base_url'] or 'Non renseignée'}") print(f" Type : {api['type'] or 'Inconnu'}") if api["rate_limit"]: print(f" Limitation de débit : {api['rate_limit']}") if api["endpoints"]: print(" Endpoints :") for ep in api["endpoints"]: print(f" - {ep['name']} ({ep['method']} {ep['path']})") else: print(" Aucun endpoint configuré.") print() print() def modifier_api(): print("=== Modification d’une API ===") if not apis_configurees: print("Aucune API n’est configurée.\n") return for i, api in enumerate(apis_configurees, start=1): print(f"{i}. {api['name']}") choix = input("Quelle API souhaitez-vous modifier ? (nom ou numéro) : ") api_choisie = None try: idx = int(choix) - 1 if 0 <= idx < len(apis_configurees): api_choisie = apis_configurees[idx] except ValueError: for a in apis_configurees: if a["name"].lower() == choix.lower(): api_choisie = a break if not api_choisie: print("API introuvable.\n") return print(f"\nAPI sélectionnée : {api_choisie['name']}") print("Que voulez-vous modifier ? (ex: 'changer l'URL de base', 'changer la clé API', " "'ajouter un endpoint', 'modifier un endpoint', 'supprimer un endpoint')") action = input("> ").lower() if "url" in action: new_url = input("Nouvelle URL de base : ") api_choisie["base_url"] = new_url print("URL de base modifiée.\n") if "clé" in action or "key" in action: new_key = input("Nouvelle clé API : ") api_choisie["api_key_value"] = new_key print("Clé API modifiée.\n") if "ajouter un endpoint" in action: print("=== Ajout d'un endpoint ===") nom_ep = input("Nom du nouvel endpoint : ") path_ep = input("Chemin (ex: /playlists/{playlist_id}/tracks) : ") methode = input("Méthode HTTP (GET, POST, etc.) : ") params_req = [p.strip() for p in input("Paramètres requis (séparés par des virgules) : ").split(",") if p.strip()] params_opt = [p.strip() for p in input("Paramètres optionnels (séparés par des virgules) : ").split(",") if p.strip()] new_ep = { "name": nom_ep, "path": path_ep, "method": methode.upper(), "required_params": params_req, "optional_params": params_opt, "description": "" } api_choisie["endpoints"].append(new_ep) print(f"Endpoint '{nom_ep}' ajouté.\n") if "modifier un endpoint" in action: print("=== Modification d'un endpoint ===") for i, ep in enumerate(api_choisie["endpoints"], start=1): print(f"{i}. {ep['name']} ({ep['method']} {ep['path']})") choix_ep = input("Quel endpoint ? (numéro ou nom) : ") ep_choisi = None try: eidx = int(choix_ep) - 1 if 0 <= eidx < len(api_choisie["endpoints"]): ep_choisi = api_choisie["endpoints"][eidx] except: for ep in api_choisie["endpoints"]: if ep["name"].lower() == choix_ep.lower(): ep_choisi = ep break if not ep_choisi: print("Endpoint introuvable.") return print(f"Endpoint sélectionné : {ep_choisi['name']}") modif_ep = input("Que voulez-vous faire ? (ex: 'ajouter un paramètre', 'changer la méthode', etc.) : ").lower() if "ajouter un paramètre" in modif_ep: nom_p = input("Nom du paramètre : ") r_o = input("Paramètre requis ou optionnel ? (r/o) : ") if r_o.lower() == 'r': ep_choisi["required_params"].append(nom_p) else: ep_choisi["optional_params"].append(nom_p) print(f"Paramètre '{nom_p}' ajouté.\n") # Vous pouvez ajouter d’autres modifications au besoin (méthode, path, etc.) if "supprimer un endpoint" in action: print("=== Suppression d'un endpoint ===") for i, ep in enumerate(api_choisie["endpoints"], start=1): print(f"{i}. {ep['name']} ({ep['method']} {ep['path']})") choix_ep = input("Quel endpoint supprimer ? (numéro ou nom) : ") ep_asup = None try: eidx = int(choix_ep) - 1 if 0 <= eidx < len(api_choisie["endpoints"]): ep_asup = api_choisie["endpoints"][eidx] except: for ep in api_choisie["endpoints"]: if ep["name"].lower() == choix_ep.lower(): ep_asup = ep break if ep_asup: api_choisie["endpoints"].remove(ep_asup) print(f"Endpoint '{ep_asup['name']}' supprimé.") else: print("Endpoint introuvable.") print("Modification(s) terminée(s).\n") def supprimer_api(): print("=== Suppression d’une API ===") if not apis_configurees: print("Aucune API n’est configurée.\n") return for i, api in enumerate(apis_configurees, start=1): print(f"{i}. {api['name']}") choix = input("Quelle API supprimer ? (nom ou numéro) : ") api_asup = None try: idx = int(choix) - 1 if 0 <= idx < len(apis_configurees): api_asup = apis_configurees[idx] except: for a in apis_configurees: if a["name"].lower() == choix.lower(): api_asup = a break if not api_asup: print("API introuvable.\n") return confirm = input(f"Êtes-vous sûr de vouloir supprimer '{api_asup['name']}' ? (o/n) : ") if confirm.lower() == 'o': apis_configurees.remove(api_asup) print(f"L’API '{api_asup['name']}' a été supprimée.\n") else: print("Opération annulée.\n") def tester_endpoint(): print("=== Tester un endpoint ===") if not apis_configurees: print("Aucune API n’est configurée.\n") return for i, api in enumerate(apis_configurees, start=1): print(f"{i}. {api['name']}") choix = input("Sur quelle API tester un endpoint ? (nom ou numéro) : ") api_choisie = None try: idx = int(choix) - 1 if 0 <= idx < len(apis_configurees): api_choisie = apis_configurees[idx] except: for a in apis_configurees: if a["name"].lower() == choix.lower(): api_choisie = a break if not api_choisie: print("API introuvable.\n") return if not api_choisie["endpoints"]: print("Cette API n’a aucun endpoint configuré.\n") return print(f"Endpoints disponibles pour {api_choisie['name']} :") for i, ep in enumerate(api_choisie["endpoints"], start=1): print(f"{i}. {ep['name']} ({ep['method']} {ep['path']})") choix_ep = input("Quel endpoint tester ? (nom ou numéro) : ") ep_choisi = None try: eidx = int(choix_ep) - 1 if 0 <= eidx < len(api_choisie["endpoints"]): ep_choisi = api_choisie["endpoints"][eidx] except: for ep in api_choisie["endpoints"]: if ep["name"].lower() == choix_ep.lower(): ep_choisi = ep break if not ep_choisi: print("Endpoint introuvable.") return required_params = {} for rp in ep_choisi.get("required_params", []): required_params[rp] = input(f"Entrez la valeur pour '{rp}' : ") optional_params = {} for op in ep_choisi.get("optional_params", []): val = input(f"Valeur pour '{op}' (laisser vide si aucun) : ") if val: optional_params[op] = val base_url = api_choisie.get("base_url") or "" path = ep_choisi["path"] for k, v in required_params.items(): path = path.replace(f"{{{k}}}", v) url = base_url + path headers = dict(api_choisie.get("common_headers", {})) auth_info = api_choisie.get("auth_info", {}) if auth_info.get("required") and api_choisie.get("api_key_value"): # Si Bearer if auth_info["type"] and "bearer" in auth_info["type"].lower(): key_name = auth_info.get("key_name", "Authorization") headers[key_name] = f"Bearer {api_choisie['api_key_value']}" else: # Basic ou autre key_name = auth_info.get("key_name", "Authorization") headers[key_name] = api_choisie["api_key_value"] method = ep_choisi["method"].upper() params = optional_params print(f"\nTest de l'endpoint : {method} {url}") print(f"En-têtes : {headers}") print(f"Paramètres : {params}\n") try: if method == "GET": r = requests.get(url, headers=headers, params=params) elif method == "POST": r = requests.post(url, headers=headers, json=params) elif method == "PUT": r = requests.put(url, headers=headers, json=params) elif method == "DELETE": r = requests.delete(url, headers=headers, json=params) else: print("Méthode non gérée.") return print(f"Statut : {r.status_code}") try: print("Réponse JSON :") print(json.dumps(r.json(), indent=2)) except: print("Réponse brute :") print(r.text) except Exception as e: print(f"Erreur lors de l’appel : {e}") def main(): while True: print("=== Menu Principal ===") print("1. Ajouter une API (assisté par IA)") print("2. Liste des API configurées") print("3. Modifier une API") print("4. Supprimer une API") print("5. Tester un endpoint") print("6. Quitter") choix = input("Choisissez une option : ") if choix == '1': ajouter_api() elif choix == '2': lister_apis() elif choix == '3': modifier_api() elif choix == '4': supprimer_api() elif choix == '5': tester_endpoint() elif choix == '6': print("Au revoir.") sys.exit(0) else: print("Choix invalide.\n") if __name__ == "__main__": main()
Mode JSON Bêta :
Nous ajoutons response_format={"type": "json_object"}
à l’appel client.chat.completions.create(...)
. Cela force Groq à valider la structure JSON avant de renvoyer la réponse.
Modèle mixtral-7b-instruct
:
Selon la documentation Groq, ce modèle gère mieux la génération JSON que d’autres.
Prompt system
strict :
Nous insistons sur le fait que l’assistant doit uniquement renvoyer un JSON conforme. Aucune phrase, aucun code supplémentaire.
Bloc try/except
:
json_validate_failed
(HTTP 400), on l’attrapera ici.Double appel :
Avec cette structure, vous devriez fortement réduire l’erreur Expecting value: line 1 column 1 (char 0)
et obtenir un JSON valide, même avec des textes longs.