|
import gradio as gr |
|
import regex as re |
|
import csv |
|
import pandas as pd |
|
from typing import List, Dict, Tuple, Optional |
|
import logging |
|
from datetime import datetime |
|
import os |
|
from huggingface_hub import HfApi, SpaceCard |
|
|
|
|
|
logging.basicConfig(level=logging.INFO) |
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
CSV_FILE = "repo_ids.csv" |
|
CHATBOT_SYSTEM_PROMPT = """You are a helpful AI assistant that analyzes Hugging Face repositories. |
|
Your task is to help users understand repositories, extract key information, and provide insights. |
|
Be concise, clear, and focus on the most important aspects of each repository.""" |
|
|
|
class AppState: |
|
"""Simple state management for the application.""" |
|
def __init__(self): |
|
self.repo_ids: List[str] = [] |
|
self.current_repo_idx: int = 0 |
|
self.chat_history: List[Dict[str, str]] = [] |
|
|
|
def read_csv_as_text(filename: str) -> pd.DataFrame: |
|
"""Read CSV file and return as DataFrame.""" |
|
try: |
|
return pd.read_csv(filename) |
|
except Exception as e: |
|
logger.error(f"Error reading CSV: {e}") |
|
return pd.DataFrame(columns=["repo id", "strength", "weaknesses", "speciality", "relevance rating"]) |
|
|
|
def write_repos_to_csv(repo_ids: List[str]) -> None: |
|
"""Write repository IDs to CSV file.""" |
|
try: |
|
with open(CSV_FILE, 'w', newline='') as f: |
|
writer = csv.writer(f) |
|
writer.writerow(["repo id", "strength", "weaknesses", "speciality", "relevance rating"]) |
|
for repo_id in repo_ids: |
|
writer.writerow([repo_id, "", "", "", ""]) |
|
except Exception as e: |
|
logger.error(f"Error writing to CSV: {e}") |
|
|
|
def search_top_spaces(keyword: str, limit: int = 5) -> List[str]: |
|
"""Search for repositories by keyword.""" |
|
try: |
|
api = HfApi() |
|
spaces = api.list_spaces(search=keyword, limit=limit) |
|
return [space.id for space in spaces] |
|
except Exception as e: |
|
logger.error(f"Error searching spaces: {e}") |
|
return [] |
|
|
|
def analyze_repo(repo_id: str) -> Tuple[str, str]: |
|
"""Analyze a single repository.""" |
|
try: |
|
api = HfApi() |
|
space = api.get_space(repo_id) |
|
card = SpaceCard.load(repo_id) |
|
|
|
content = f""" |
|
Repository: {repo_id} |
|
Title: {card.title} |
|
Description: {card.description} |
|
Tags: {', '.join(card.tags)} |
|
""" |
|
|
|
summary = f"Analysis of {repo_id}:\n" |
|
summary += f"- Title: {card.title}\n" |
|
summary += f"- Main focus: {card.description[:200]}...\n" |
|
summary += f"- Key tags: {', '.join(card.tags[:5])}\n" |
|
|
|
return content, summary |
|
except Exception as e: |
|
logger.error(f"Error analyzing repo {repo_id}: {e}") |
|
return f"Error analyzing {repo_id}", f"Error: {str(e)}" |
|
|
|
def chat_with_user(message: str, history: List[Dict[str, str]], system_prompt: str) -> str: |
|
"""Simple chat response.""" |
|
try: |
|
|
|
return f"I understand you're asking about: {message}. How can I help you analyze this repository?" |
|
except Exception as e: |
|
logger.error(f"Error in chat: {e}") |
|
return "I apologize, but I encountered an error. Please try again." |
|
|
|
def create_ui() -> gr.Blocks: |
|
"""Create a simplified Gradio interface.""" |
|
state = gr.State(AppState()) |
|
|
|
with gr.Blocks(title="Hugging Face Repo Analyzer", theme=gr.themes.Soft()) as app: |
|
gr.Markdown("# Hugging Face Repository Analyzer") |
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
|
|
gr.Markdown("### Enter Repository Information") |
|
repo_input = gr.Textbox( |
|
label="Enter repo IDs (comma or newline separated) or keywords to search", |
|
lines=5, |
|
placeholder="Enter repository IDs or keywords to search" |
|
) |
|
submit_btn = gr.Button("Submit", variant="primary") |
|
status = gr.Textbox(label="Status", visible=True) |
|
|
|
|
|
df_output = gr.Dataframe( |
|
headers=["repo id", "strength", "weaknesses", "speciality", "relevance rating"], |
|
datatype=["str", "str", "str", "str", "str"] |
|
) |
|
|
|
|
|
content_output = gr.Textbox(label="Repository Content", lines=10) |
|
summary_output = gr.Textbox(label="Analysis Summary", lines=5) |
|
|
|
|
|
chatbot = gr.Chatbot(label="Chat with Assistant", height=400) |
|
msg = gr.Textbox(label="Message", placeholder="Ask about the repository...") |
|
with gr.Row(): |
|
send_btn = gr.Button("Send", variant="primary") |
|
clear_btn = gr.Button("Clear Chat", variant="secondary") |
|
|
|
def process_input(text: str, state: AppState) -> Tuple[pd.DataFrame, str, str, str]: |
|
"""Process input and return results.""" |
|
try: |
|
|
|
if any(kw in text.lower() for kw in ['search', 'find', 'look for']): |
|
|
|
keywords = [k.strip() for k in re.split(r'[\n,]+', text) if k.strip()] |
|
repo_ids = [] |
|
for kw in keywords: |
|
repo_ids.extend(search_top_spaces(kw, limit=5)) |
|
else: |
|
|
|
repo_ids = [rid.strip() for rid in re.split(r'[\n,]+', text) if rid.strip()] |
|
|
|
|
|
repo_ids = list(dict.fromkeys(repo_ids)) |
|
|
|
if not repo_ids: |
|
return pd.DataFrame(), "No repositories found", "", "" |
|
|
|
|
|
state.repo_ids = repo_ids |
|
state.current_repo_idx = 0 |
|
write_repos_to_csv(repo_ids) |
|
|
|
|
|
content, summary = analyze_repo(repo_ids[0]) |
|
|
|
return read_csv_as_text(CSV_FILE), f"Found {len(repo_ids)} repositories", content, summary |
|
|
|
except Exception as e: |
|
logger.error(f"Error processing input: {e}") |
|
return pd.DataFrame(), f"Error: {str(e)}", "", "" |
|
|
|
def send_message(message: str, history: List[Dict[str, str]], state: AppState) -> Tuple[List[Dict[str, str]], str]: |
|
"""Send message to chat.""" |
|
if not message: |
|
return history, "" |
|
history.append({"role": "user", "content": message}) |
|
response = chat_with_user(message, history, CHATBOT_SYSTEM_PROMPT) |
|
history.append({"role": "assistant", "content": response}) |
|
return history, "" |
|
|
|
def clear_chat() -> Tuple[List[Dict[str, str]], str]: |
|
"""Clear chat history.""" |
|
return [], "" |
|
|
|
|
|
submit_btn.click( |
|
fn=process_input, |
|
inputs=[repo_input, state], |
|
outputs=[df_output, status, content_output, summary_output] |
|
) |
|
|
|
send_btn.click( |
|
fn=send_message, |
|
inputs=[msg, chatbot, state], |
|
outputs=[chatbot, msg] |
|
) |
|
|
|
clear_btn.click( |
|
fn=clear_chat, |
|
inputs=[], |
|
outputs=[chatbot, msg] |
|
) |
|
|
|
return app |
|
|
|
if __name__ == "__main__": |
|
app = create_ui() |
|
app.launch() |
|
|