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()) |