"""HF Space 列表助手 - 获取当前登录用户的所有 Space 用法: python scripts/_hf_list_spaces.py [--token TOKEN] [--format text|json] 示例: python scripts/_hf_list_spaces.py --token hf_xxx python scripts/_hf_list_spaces.py --format json """ from __future__ import annotations import argparse import json import sys from datetime import datetime from typing import Any _HF_EXTRA_PATH = "/root/.local/bin" def _ensure_hf_in_path() -> None: """确保 huggingface_hub 可导入。""" import os if _HF_EXTRA_PATH not in os.environ.get("PATH", ""): os.environ["PATH"] = f"{_HF_EXTRA_PATH}:{os.environ.get('PATH', '')}" def list_user_spaces(token: str | None = None) -> list[dict[str, Any]]: """获取当前用户的所有 Space。 返回: [{'id': 'user/space', 'title': 'My Space', 'sdk': 'docker', 'last_modified': '2025-01-01T00:00:00Z', 'likes': 0}, ...] """ _ensure_hf_in_path() from huggingface_hub import HfApi api = HfApi(token=token) if token else HfApi() # 获取当前用户信息 try: user_info = api.whoami() username = user_info.get("name", "") except Exception as e: print(f"[ERROR] 无法获取用户信息 (未登录或 token 无效): {e}", file=sys.stderr) return [] if not username: print("[ERROR] 无法获取用户名", file=sys.stderr) return [] # 列出该用户的所有 Space try: spaces = list(api.list_spaces(author=username)) except Exception as e: print(f"[ERROR] 获取 Space 列表失败: {e}", file=sys.stderr) return [] result = [] for space in spaces: # space 可能是对象或字典,兼容处理 if hasattr(space, "id"): space_id = getattr(space, "id") elif isinstance(space, dict): space_id = space.get("id", "") else: space_id = str(space) # 获取额外信息 title = "" sdk = "" last_modified = "" likes = 0 if hasattr(space, "title"): title = getattr(space, "title") or "" elif isinstance(space, dict): title = space.get("title", "") if hasattr(space, "sdk"): sdk = getattr(space, "sdk") or "" elif isinstance(space, dict): sdk = space.get("sdk", "") if hasattr(space, "last_modified"): lm = getattr(space, "last_modified") if isinstance(lm, datetime): last_modified = lm.strftime("%Y-%m-%dT%H:%M:%SZ") elif lm: last_modified = str(lm) elif isinstance(space, dict): last_modified = str(space.get("last_modified", "")) if hasattr(space, "likes"): likes = getattr(space, "likes") or 0 elif isinstance(space, dict): likes = space.get("likes", 0) result.append({ "id": space_id, "title": title, "sdk": sdk, "last_modified": last_modified, "likes": likes, "username": username, }) # 按最后修改时间排序(最新的在前) result.sort(key=lambda x: x.get("last_modified", ""), reverse=True) return result def main() -> int: parser = argparse.ArgumentParser(description="List user's HF Spaces") parser.add_argument("--token", help="HF API Token", default=None) parser.add_argument( "--format", choices=["text", "json"], default="text", help="输出格式", ) args = parser.parse_args() spaces = list_user_spaces(token=args.token) if args.format == "json": print(json.dumps(spaces, ensure_ascii=False, indent=2)) else: if not spaces: print("未找到任何 Space") return 0 print(f"共找到 {len(spaces)} 个 Space:\n") for i, sp in enumerate(spaces, 1): sdk_display = sp["sdk"].upper() if sp["sdk"] else "N/A" title_display = sp["title"] if sp["title"] else "(无标题)" date_display = sp["last_modified"].split("T")[0] if sp["last_modified"] else "N/A" print(f" [{i}] {sp['id']}") print(f" 标题: {title_display}") print(f" SDK: {sdk_display} | 更新: {date_display} | ❤️ {sp['likes']}") return 0 if __name__ == "__main__": sys.exit(main())