|
import requests |
|
import gradio as gr |
|
from datetime import datetime |
|
|
|
|
|
USERNAME = "gradio" |
|
|
|
def format_timestamp(timestamp): |
|
if timestamp: |
|
dt = datetime.fromisoformat(timestamp.replace('Z', '+00:00')) |
|
return dt.strftime('%Y-%m-%d %H:%M') |
|
return 'N/A' |
|
|
|
def search_spaces(): |
|
"""Search for spaces using the Hugging Face search API""" |
|
url = "https://huggingface.co/api/spaces" |
|
headers = {"Accept": "application/json"} |
|
|
|
try: |
|
|
|
response = requests.get(url, headers=headers) |
|
if response.status_code == 200: |
|
all_spaces = response.json() |
|
|
|
user_spaces = [space for space in all_spaces |
|
if space.get('author', '').lower() == USERNAME.lower()] |
|
return user_spaces |
|
except Exception as e: |
|
print(f"Error in search_spaces: {e}") |
|
return [] |
|
|
|
def get_space_card(space): |
|
"""Generate HTML card for a space""" |
|
space_id = space.get('id', '') |
|
space_name = space_id.split('/')[-1] if space_id else 'Unknown' |
|
|
|
return f""" |
|
<div style='border: 1px solid #ddd; padding: 15px; margin: 10px; border-radius: 8px; |
|
background-color: white; box-shadow: 2px 2px 5px rgba(0,0,0,0.1); |
|
transition: transform 0.2s ease-in-out;' |
|
onmouseover='this.style.transform="scale(1.02)"' |
|
onmouseout='this.style.transform="scale(1)"'> |
|
<h3 style='color: #2d2d2d; margin: 0 0 10px 0;'> |
|
<a href='https://huggingface.co/spaces/{space_id}' target='_blank' |
|
style='text-decoration: none; color: #2d2d2d;'> |
|
{space_name} |
|
</a> |
|
</h3> |
|
<p style='margin: 5px 0;'><strong>Author:</strong> {space.get('author', 'Unknown')}</p> |
|
<p style='margin: 5px 0;'><strong>SDK:</strong> {space.get('sdk', 'N/A')}</p> |
|
<p style='margin: 5px 0;'><strong>Likes:</strong> {space.get('likes', 0)} ❤️</p> |
|
<div style='margin-top: 10px;'> |
|
<a href='https://huggingface.co/spaces/{space_id}' target='_blank' |
|
style='background-color: #0084ff; color: white; padding: 5px 10px; |
|
border-radius: 5px; text-decoration: none; display: inline-block;'> |
|
View Space |
|
</a> |
|
</div> |
|
</div> |
|
""" |
|
|
|
def get_user_spaces(): |
|
|
|
spaces = search_spaces() |
|
|
|
if not spaces: |
|
|
|
try: |
|
response = requests.get( |
|
f"https://huggingface.co/search/full-text", |
|
params={"q": f"user:{USERNAME} type:space"}, |
|
headers={"Accept": "application/json"} |
|
) |
|
if response.status_code == 200: |
|
search_results = response.json() |
|
if 'hits' in search_results: |
|
spaces = search_results['hits'] |
|
except Exception as e: |
|
print(f"Error in alternative search: {e}") |
|
|
|
if not spaces: |
|
return """ |
|
<div style='padding: 20px; text-align: center; color: #666;'> |
|
<h2>No public Spaces found for user: {USERNAME}</h2> |
|
<p>This could be because:</p> |
|
<ul style='list-style: none; padding: 0;'> |
|
<li>The user has no public spaces</li> |
|
<li>The username might be incorrect</li> |
|
<li>There might be an issue with the API</li> |
|
</ul> |
|
</div> |
|
""" |
|
|
|
|
|
html_content = f""" |
|
<div style='padding: 20px; background-color: #f5f5f5;'> |
|
<div style='margin-bottom: 20px;'> |
|
<p style='color: #666; margin: 0;'>Found {len(spaces)} public spaces for {USERNAME}</p> |
|
</div> |
|
<div style=' |
|
display: grid; |
|
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); |
|
gap: 20px; |
|
'> |
|
{"".join(get_space_card(space) for space in spaces)} |
|
</div> |
|
</div> |
|
""" |
|
|
|
return html_content |
|
|
|
|
|
app = gr.Interface( |
|
fn=get_user_spaces, |
|
inputs=None, |
|
outputs=gr.HTML(), |
|
title=f"Hugging Face Public Spaces - {USERNAME}", |
|
description=f"Displays public Spaces from {USERNAME}", |
|
theme=gr.themes.Soft(), |
|
css=""" |
|
.gradio-container { |
|
max-width: 100% !important; |
|
} |
|
""" |
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
app.launch() |