import gradio as gr from huggingface_hub import InferenceClient import os import requests from typing import List, Dict, Union import traceback from PIL import Image from io import BytesIO import asyncio from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.chrome.options import Options HF_TOKEN = os.getenv("HF_TOKEN") hf_client = InferenceClient("CohereForAI/c4ai-command-r-plus-08-2024", token=HF_TOKEN) def get_headers(): if not HF_TOKEN: raise ValueError("Hugging Face token not found in environment variables") return {"Authorization": f"Bearer {HF_TOKEN}"} def get_most_liked_spaces(limit: int = 300) -> Union[List[Dict], str]: url = "https://huggingface.co/api/spaces" params = { "sort": "likes", "direction": -1, "limit": limit, "full": "true" } try: response = requests.get(url, params=params, headers=get_headers()) response.raise_for_status() return response.json() except requests.RequestException as e: return f"API request error: {str(e)}" except ValueError as e: return f"JSON decoding error: {str(e)}" def format_space(space: Dict) -> Dict: space_id = space.get('id', 'Unknown') space_name = space_id.split('/')[-1] if '/' in space_id else space_id space_author = space.get('author', 'Unknown') if isinstance(space_author, dict): space_author = space_author.get('user', space_author.get('name', 'Unknown')) space_likes = space.get('likes', 'N/A') space_url = f"https://huggingface.co/spaces/{space_id}" return { "id": space_id, "name": space_name, "author": space_author, "likes": space_likes, "url": space_url, } def format_spaces(spaces: Union[List[Dict], str]) -> List[Dict]: if isinstance(spaces, str): return [{"error": spaces}] return [format_space(space) for space in spaces if isinstance(space, dict)] def summarize_space(space: Dict) -> str: system_message = "당신은 Hugging Face Space의 내용을 요약하는 AI 조수입니다. 주어진 정보를 바탕으로 간결하고 명확한 요약을 제공해주세요." user_message = f"다음 Hugging Face Space를 요약해주세요: {space['name']} by {space['author']}. 좋아요 수: {space['likes']}. URL: {space['url']}" messages = [ {"role": "system", "content": system_message}, {"role": "user", "content": user_message} ] try: response = hf_client.chat_completion(messages, max_tokens=400, temperature=0.7) return response.choices[0].message.content except Exception as e: return f"요약 생성 중 오류 발생: {str(e)}" def get_app_py_content(space_id: str) -> str: app_py_url = f"https://huggingface.co/spaces/{space_id}/raw/main/app.py" try: response = requests.get(app_py_url, headers=get_headers()) if response.status_code == 200: content = response.text if len(content) > 500: # 내용을 500자로 제한합니다 content = content[:497] + "..." return content else: return f"app.py file not found or inaccessible for space: {space_id}" except requests.RequestException: return f"Error fetching app.py content for space: {space_id}" async def on_select(space): try: summary = summarize_space(space) app_content = get_app_py_content(space['id']) screenshot = await take_screenshot(space['url']) info = f"선택된 Space: {space['name']} (ID: {space['id']})\n" info += f"Author: {space['author']}\n" info += f"Likes: {space['likes']}\n" info += f"URL: {space['url']}\n\n" info += f"요약:\n{summary}" return info, app_content, screenshot except Exception as e: print(f"Error in on_select: {str(e)}") print(traceback.format_exc()) return f"오류가 발생했습니다: {str(e)}", "", Image.new('RGB', (1080, 720), color='lightgray') async def take_screenshot(url): options = webdriver.ChromeOptions() options.add_argument('--headless') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') try: service = Service(ChromeDriverManager().install()) driver = webdriver.Chrome(service=service, options=options) driver.set_window_size(1080, 720) driver.get(url) await asyncio.sleep(5) # Wait for the page to load screenshot = driver.get_screenshot_as_png() return Image.open(BytesIO(screenshot)) except Exception as e: print(f"Screenshot error: {str(e)}") return Image.new('RGB', (1080, 720), color='lightgray') finally: if 'driver' in locals(): driver.quit() def create_ui(): try: spaces_list = get_most_liked_spaces() print(f"Type of spaces_list: {type(spaces_list)}") formatted_spaces = format_spaces(spaces_list) print(f"Total spaces loaded: {len(formatted_spaces)}") css = """ footer {visibility: hidden;} .minimal-button {min-width: 30px !important; height: 25px !important; line-height: 1 !important; font-size: 12px !important; padding: 2px 5px !important;} .space-row {margin-bottom: 5px !important;} """ with gr.Blocks(css=css, theme="Nymbo/Nymbo_Theme") as demo: gr.Markdown("# Hugging Face Most Liked Spaces") with gr.Row(): with gr.Column(scale=1): space_rows = [] for space in formatted_spaces: with gr.Row(elem_classes="space-row") as space_row: with gr.Column(): gr.Markdown(f"{space['name']} by {space['author']} (Likes: {space['likes']})", elem_classes="space-info") button = gr.Button("클릭", elem_classes="minimal-button") space_rows.append((space_row, button, space)) with gr.Column(scale=1): info_output = gr.Textbox(label="Space 정보 및 요약", lines=20) screenshot_output = gr.Image(type="pil", label="Space 스크린샷", height=360, width=540) app_py_content = gr.Code(language="python", label="app.py 내용") for _, button, space in space_rows: button.click( lambda s=space: asyncio.run(on_select(s)), inputs=[], outputs=[info_output, app_py_content, screenshot_output] ) return demo except Exception as e: print(f"Error in create_ui: {str(e)}") print(traceback.format_exc()) raise if __name__ == "__main__": try: demo = create_ui() demo.launch() except Exception as e: print(f"Error in main: {str(e)}") print(traceback.format_exc())