Spaces:
Build error
Build error
| #!/usr/bin/env python | |
| # -*- coding: utf-8 -*- | |
| """ | |
| SmoLAgent Parser - Extrait le premier modèle de chaque leaderboard Hugging Face | |
| en utilisant Playwright et smolagents. | |
| """ | |
| import json | |
| import os | |
| import asyncio | |
| from pathlib import Path | |
| from typing import List, Dict, Any, Optional | |
| from dotenv import load_dotenv | |
| from huggingface_hub import login | |
| from playwright.async_api import async_playwright | |
| from smolagents import CodeAgent | |
| from smolagents.models import HfApiModel | |
| from smolagents.tools import Tool | |
| # Charger les variables d'environnement depuis le fichier .env | |
| load_dotenv() | |
| # Récupérer le token Hugging Face | |
| hf_token = os.getenv("HUGGING_FACE_HUB_TOKEN") | |
| # Charger les leaderboards depuis le fichier JSON | |
| def load_leaderboards() -> List[str]: | |
| """Charger les URLs des leaderboards depuis le fichier JSON.""" | |
| with open("leaderboards.json", "r") as f: | |
| return json.load(f) | |
| # Définir un outil pour utiliser Playwright | |
| class PlaywrightBrowserTool(Tool): | |
| """Outil pour interagir avec un navigateur web via Playwright.""" | |
| name = "browser" | |
| description = "Outil pour interagir avec un navigateur web via Playwright." | |
| inputs = { | |
| "goto": { | |
| "url": { | |
| "type": "string", | |
| "description": "L'URL vers laquelle naviguer" | |
| } | |
| }, | |
| "get_content": {}, | |
| "get_title": {}, | |
| "take_screenshot": { | |
| "path": { | |
| "type": "string", | |
| "description": "Le chemin où enregistrer la capture d'écran" | |
| } | |
| }, | |
| "run_js": { | |
| "script": { | |
| "type": "string", | |
| "description": "Le code JavaScript à exécuter dans le contexte de la page" | |
| } | |
| }, | |
| "wait_for": { | |
| "selector": { | |
| "type": "string", | |
| "description": "Le sélecteur CSS à attendre" | |
| }, | |
| "timeout": { | |
| "type": "integer", | |
| "description": "Le temps maximum d'attente en millisecondes" | |
| } | |
| }, | |
| "click": { | |
| "selector": { | |
| "type": "string", | |
| "description": "Le sélecteur CSS de l'élément à cliquer" | |
| } | |
| }, | |
| "fill": { | |
| "selector": { | |
| "type": "string", | |
| "description": "Le sélecteur CSS du champ de formulaire" | |
| }, | |
| "value": { | |
| "type": "string", | |
| "description": "La valeur à remplir dans le champ de formulaire" | |
| } | |
| } | |
| } | |
| output_type = "any" | |
| def __init__(self, page): | |
| self.page = page | |
| async def goto(self, url: str) -> str: | |
| """Naviguer vers une URL.""" | |
| await self.page.goto(url, wait_until="networkidle", timeout=60000) | |
| return f"Navigué vers {url}" | |
| async def get_content(self) -> str: | |
| """Obtenir le contenu HTML de la page.""" | |
| return await self.page.content() | |
| async def get_title(self) -> str: | |
| """Obtenir le titre de la page.""" | |
| return await self.page.title() | |
| async def take_screenshot(self, path: str = "screenshot.png") -> str: | |
| """Prendre une capture d'écran de la page.""" | |
| await self.page.screenshot(path=path) | |
| return f"Capture d'écran enregistrée dans {path}" | |
| async def run_js(self, script: str) -> Any: | |
| """Exécuter du JavaScript dans le contexte de la page.""" | |
| return await self.page.evaluate(script) | |
| async def wait_for(self, selector: str, timeout: int = 30000) -> str: | |
| """Attendre qu'un élément correspondant au sélecteur apparaisse.""" | |
| await self.page.wait_for_selector(selector, timeout=timeout) | |
| return f"Élément avec le sélecteur '{selector}' trouvé" | |
| async def click(self, selector: str) -> str: | |
| """Cliquer sur un élément correspondant au sélecteur.""" | |
| await self.page.click(selector) | |
| return f"Cliqué sur l'élément avec le sélecteur '{selector}'" | |
| async def fill(self, selector: str, value: str) -> str: | |
| """Remplir un champ de formulaire.""" | |
| await self.page.fill(selector, value) | |
| return f"Rempli '{value}' dans l'élément avec le sélecteur '{selector}'" | |
| async def extract_first_model(url: str) -> Optional[Dict[str, Any]]: | |
| """ | |
| Extraire le premier modèle d'un leaderboard en utilisant un agent. | |
| Args: | |
| url: L'URL du leaderboard | |
| Returns: | |
| Un dictionnaire contenant les informations sur le premier modèle, ou None si l'extraction a échoué | |
| """ | |
| async with async_playwright() as p: | |
| browser = await p.chromium.launch(headless=False) # Mettre à True pour la production | |
| page = await browser.new_page() | |
| try: | |
| # Créer l'outil Playwright | |
| browser_tool = PlaywrightBrowserTool(page) | |
| # Créer l'agent | |
| agent = CodeAgent( | |
| tools=[browser_tool], | |
| model=HfApiModel() | |
| ) | |
| # Exécuter l'agent | |
| prompt = f""" | |
| Extrais les informations sur le premier modèle du leaderboard à l'URL suivante: {url} | |
| Utilise l'outil browser pour naviguer sur la page et extraire les informations suivantes: | |
| - Nom du modèle | |
| - Score | |
| - Position/rang | |
| - Créateur/auteur | |
| Retourne les informations sous forme de dictionnaire Python. | |
| """ | |
| result = await agent.run(prompt) | |
| print(f"Résultat brut de l'agent: {result}") | |
| # Essayer de parser le résultat comme un dictionnaire | |
| try: | |
| # L'agent peut retourner une représentation textuelle d'un dictionnaire | |
| if isinstance(result, str): | |
| # Essayer de trouver une structure de dictionnaire dans la chaîne | |
| import re | |
| dict_match = re.search(r'\{.*\}', result, re.DOTALL) | |
| if dict_match: | |
| dict_str = dict_match.group(0) | |
| # Remplacer les guillemets simples par des guillemets doubles pour un JSON valide | |
| dict_str = dict_str.replace("'", '"') | |
| return json.loads(dict_str) | |
| return {"raw_result": result} | |
| return result | |
| except Exception as e: | |
| print(f"Erreur lors du parsing du résultat: {e}") | |
| return {"raw_result": str(result)} | |
| except Exception as e: | |
| print(f"Erreur lors de l'extraction des données de {url}: {e}") | |
| await page.screenshot(path=f"error_{url.replace('://', '_').replace('/', '_')}.png") | |
| return {"error": str(e)} | |
| finally: | |
| await browser.close() | |
| async def main(): | |
| """Fonction principale pour traiter tous les leaderboards.""" | |
| # Se connecter à Hugging Face | |
| if hf_token: | |
| print("Token Hugging Face trouvé dans le fichier .env") | |
| login(token=hf_token) | |
| print("Connexion à Hugging Face réussie!") | |
| else: | |
| print("Erreur: Token Hugging Face non trouvé dans le fichier .env") | |
| return | |
| leaderboards = load_leaderboards() | |
| results = {} | |
| for url in leaderboards: | |
| print(f"Traitement du leaderboard: {url}") | |
| result = await extract_first_model(url) | |
| results[url] = result | |
| print(f"Résultat: {result}") | |
| # Sauvegarder les résultats dans un fichier JSON | |
| with open("results_smolagent.json", "w") as f: | |
| json.dump(results, f, indent=2) | |
| print(f"Résultats sauvegardés dans results_smolagent.json") | |
| if __name__ == "__main__": | |
| asyncio.run(main()) |