import gradio as gr import os from huggingface_hub import HfApi, repo_info, space_info, list_models, list_spaces from datetime import datetime import json # Initialize HfApi try: hf_token = os.getenv("HF_TOKEN") if not hf_token: print("Warning: HF_TOKEN not found. Only public repos/spaces can be accessed.") api = HfApi(token=hf_token) except Exception as e: print(f"Error initializing HfApi: {e}") api = HfApi() hf_token = None def get_ranking(repo_id: str, is_space: bool = False): """ Estimate the ranking of a repo/space based on likes. """ try: if is_space: current_space = space_info(repo_id=repo_id, token=hf_token) current_likes = current_space.likes top_spaces = list_spaces(sort="likes", direction=-1, limit=100, token=hf_token) for i, space in enumerate(top_spaces): if space.id == repo_id: return f"## Space Ranking\nThis Space is ranked **#{i + 1}** based on likes among all public Spaces." return f"## Space Ranking\nThis Space has **{current_likes}** likes and is not in the top 100 most liked Spaces." else: current_model = repo_info(repo_id=repo_id, token=hf_token) current_likes = current_model.likes top_models = list_models(sort="likes", direction=-1, limit=100, token=hf_token) for i, model in enumerate(top_models): if model.id == repo_id: return f"## Model Ranking\nThis Model is ranked **#{i + 1}** based on likes among all public Models." return f"## Model Ranking\nThis Model has **{current_likes}** likes and is not in the top 100 most liked Models." except Exception as e: return f"## Ranking\nCould not fetch ranking information: {e}" def search_hf_entity(query: str, entity_type: str): """ Search and fetch detailed information for a Repository or a Space. """ if not query.strip(): return "Please enter an ID to search.", None try: summary_md = "" details_json = {} if entity_type == "Repository": try: info = repo_info(repo_id=query, token=hf_token) except Exception as e: if hasattr(e, 'response') and e.response.status_code == 404: return f"**Error:** **Repository** not found with ID `{query}`. Please check the ID.", None else: return f"**An error occurred while searching for the Repository:** {e}", None # --- SAFE ATTRIBUTE ACCESS --- author = getattr(info, 'author', 'Unknown') license_info = getattr(info, 'license', 'Not specified') pipeline_tag = getattr(info, 'pipeline_tag', None) summary_md = f"### Repository Information: `{info.id}`\n" summary_md += f"- **Author:** [{author}]({author})\n" summary_md += f"- **Likes:** ❤️ {info.likes}\n" summary_md += f"- **Downloads:** 📥 {info.downloads}\n" summary_md += f"- **Tags:** {', '.join(info.tags) if info.tags else 'N/A'}\n" summary_md += f"- **Last Modified:** {info.last_modified.strftime('%Y-%m-%d %H:%M:%S')}\n" summary_md += "\n" + get_ranking(query, is_space=False) details_json = { "id": info.id, "author": author, "sha": info.sha, "last_modified": info.last_modified.isoformat(), "tags": info.tags, "pipeline_tag": pipeline_tag, "siblings": [s.rfilename for s in info.siblings], "likes": info.likes, "downloads": info.downloads, "license": license_info, "cardData": info.cardData, "url": f"https://huggingface.co/{info.id}" } elif entity_type == "Space": try: info = space_info(repo_id=query, token=hf_token) except Exception as e: if hasattr(e, 'response') and e.response.status_code == 404: return f"**Error:** **Space** not found with ID `{query}`. Please check the ID.", None else: return f"**An error occurred while searching for the Space:** {e}", None # --- SAFE ATTRIBUTE ACCESS --- author = getattr(info, 'author', 'Unknown') sdk = getattr(info, 'sdk', 'Unknown') status = getattr(info, 'status', 'Unknown') summary_md = f"### Space Information: `{info.id}`\n" summary_md += f"- **Author:** [{author}]({author})\n" summary_md += f"- **Likes:** ❤️ {info.likes}\n" summary_md += f"- **SDK:** {sdk}\n" summary_md += f"- **Hardware:** {info.hardware.current if info.hardware else 'Not specified'}\n" summary_md += f"- **Status:** {status}\n" summary_md += f"- **Last Modified:** {info.last_modified.strftime('%Y-%m-%d %H:%M:%S')}\n" summary_md += "\n" + get_ranking(query, is_space=True) details_json = { "id": info.id, "author": author, "sha": info.sha, "last_modified": info.last_modified.isoformat(), "likes": info.likes, "sdk": sdk, "hardware": info.hardware.__dict__ if info.hardware else None, "status": status, "url": f"https://huggingface.co/spaces/{info.id}", "cardData": info.cardData } return summary_md, details_json except Exception as e: return f"**An unexpected error occurred:** {e}", None # Build the Gradio interface with custom CSS with gr.Blocks(theme=gr.themes.Soft()) as demo: gr.Markdown("# 🔍 Hugging Face Repo & Space Searcher") gr.Markdown("Search and view detailed information about any Model Repository or Space on Hugging Face. " "This app uses an `HF_TOKEN` with `read` permissions to access private repos/spaces.") with gr.Row(): with gr.Column(scale=3): query_input = gr.Textbox( label="Enter Repo/Space ID", placeholder="e.g., 'google-bert/bert-base-uncased' or 'gradio/ChatGPT'", lines=1 ) with gr.Column(scale=1): type_input = gr.Radio( choices=["Repository", "Space"], label="Search Type", value="Repository" ) search_btn = gr.Button("Search", variant="primary") with gr.Row(): with gr.Column(): summary_output = gr.Markdown(label="Summary & Ranking") with gr.Column(): details_output = gr.JSON(label="Detailed Info (JSON)") search_btn.click( fn=search_hf_entity, inputs=[query_input, type_input], outputs=[summary_output, details_output] ) if __name__ == "__main__": demo.launch()