Spaces:
Sleeping
Sleeping
| import os | |
| import httpx | |
| from fastapi import FastAPI, Request | |
| from fastapi.responses import HTMLResponse | |
| app = FastAPI() | |
| HF_TOKEN = os.environ.get("HF_TOKEN", "") | |
| def build_agent_prompt(space_info: dict) -> str: | |
| space_id = space_info.get("id", "") | |
| subdomain = space_info.get("subdomain", "") | |
| description = space_info.get("ai_short_description") or (space_info.get("cardData") or {}).get("short_description") | |
| base_url = f"https://{subdomain}.hf.space" | |
| desc_part = f" ({space_id}: {description})" if description else f" ({space_id})" | |
| return ( | |
| f'This is a Hugging Face Space{desc_part}. ' | |
| f'Immediately fetch its API schema (GET {base_url}/gradio_api/info) to discover available endpoints, ' | |
| f'then ask the user what they want to do. ' | |
| f'Call endpoint: POST {base_url}/gradio_api/call/{{endpoint}} {{"data": [...]}} — ' | |
| f'Poll result: GET {base_url}/gradio_api/call/{{endpoint}}/{{event_id}} — ' | |
| f'auth: Bearer $HF_TOKEN' | |
| ) | |
| async def proxy_space(namespace: str, repo: str, request: Request): | |
| space_id = f"{namespace}/{repo}" | |
| headers = {} | |
| if HF_TOKEN: | |
| headers["Authorization"] = f"Bearer {HF_TOKEN}" | |
| async with httpx.AsyncClient(follow_redirects=True) as client: | |
| # Fetch space info from API | |
| api_resp = await client.get(f"https://huggingface.co/api/spaces/{space_id}", headers=headers) | |
| if api_resp.status_code != 200: | |
| return HTMLResponse(f"<html><body>Space not found: {space_id}</body></html>", status_code=404) | |
| space_info = api_resp.json() | |
| if space_info.get("sdk") != "gradio": | |
| return HTMLResponse(f"<html><body>Only Gradio spaces are supported. This space uses: {space_info.get('sdk')}</body></html>", status_code=400) | |
| # Fetch ai_short_description from semantic search | |
| search_resp = await client.get( | |
| f"https://huggingface.co/api/spaces/semantic-search?q={space_id}&sdk=gradio", | |
| headers=headers, | |
| ) | |
| results = search_resp.json() if search_resp.status_code == 200 else [] | |
| match = next((r for r in results if r.get("id") == space_id), None) | |
| if match: | |
| space_info["ai_short_description"] = match.get("ai_short_description") | |
| # Fetch the actual space page HTML | |
| page_resp = await client.get(f"https://huggingface.co/spaces/{space_id}", headers=headers) | |
| html = page_resp.text | |
| # Build the meta tag | |
| prompt = build_agent_prompt(space_info) | |
| meta_tag = f'<meta name="agent-instructions" content="{prompt}">' | |
| # Inject meta tag after <head> or at the start | |
| if "<head>" in html: | |
| html = html.replace("<head>", f"<head>\n{meta_tag}", 1) | |
| elif "<HEAD>" in html: | |
| html = html.replace("<HEAD>", f"<HEAD>\n{meta_tag}", 1) | |
| else: | |
| html = f"{meta_tag}\n{html}" | |
| return HTMLResponse(html) | |
| async def agent_instructions(namespace: str, repo: str): | |
| space_id = f"{namespace}/{repo}" | |
| headers = {} | |
| if HF_TOKEN: | |
| headers["Authorization"] = f"Bearer {HF_TOKEN}" | |
| async with httpx.AsyncClient(follow_redirects=True) as client: | |
| api_resp = await client.get(f"https://huggingface.co/api/spaces/{space_id}", headers=headers) | |
| if api_resp.status_code != 200: | |
| return {"error": f"Space not found: {space_id}"} | |
| space_info = api_resp.json() | |
| if space_info.get("sdk") != "gradio": | |
| return {"error": f"Only Gradio spaces supported. This uses: {space_info.get('sdk')}"} | |
| return {"instructions": build_agent_prompt(space_info)} | |
| async def home(): | |
| return HTMLResponse(""" | |
| <html> | |
| <head><title>Agent Meta Tag Proxy</title></head> | |
| <body style="font-family: sans-serif; max-width: 600px; margin: 40px auto; padding: 0 20px;"> | |
| <h1>Agent Meta Tag Proxy</h1> | |
| <p>This Space injects a <code><meta name="agent-instructions"></code> tag into Gradio Space pages for AI agent discovery.</p> | |
| <h3>Usage</h3> | |
| <pre>/proxy/{namespace}/{repo}</pre> | |
| <h3>Example</h3> | |
| <a href="/proxy/mrfakename/Z-Image-Turbo">/proxy/mrfakename/Z-Image-Turbo</a> | |
| </body> | |
| </html> | |
| """) | |