Download tools/github.py from 1990two/XTOOLS: direct link, hf CLI and curl.
- Browser
- Download file 2.33 kB
-
https://huggingface.co/spaces/1990two/XTOOLS/resolve/main/tools/github.py
- Command line
-
hf download hf://spaces/1990two/XTOOLS/tools/github.py
-
curl -L -o github.py https://huggingface.co/spaces/1990two/XTOOLS/resolve/main/tools/github.py
2.33 kB
| """ | |
| GitHub -- REST API, free token, no scopes needed for public data. | |
| """ | |
| import httpx | |
| from supabase_client import require_tool_keys | |
| BASE = "https://api.github.com" | |
| def run(params: dict) -> dict: | |
| creds = require_tool_keys("github") | |
| token = creds["api_key"] | |
| headers = {"Authorization": f"token {token}", "Accept": "application/vnd.github+json"} | |
| mode = params.get("mode", "search") | |
| if mode == "org": | |
| org = params.get("org") | |
| if not org: | |
| raise ValueError("org is required for mode='org'") | |
| resp = httpx.get(f"{BASE}/orgs/{org}/repos", headers=headers, params={"per_page": 100}, timeout=15.0) | |
| resp.raise_for_status() | |
| repos = resp.json() | |
| results = [ | |
| {"name": r["name"], "stars": r["stargazers_count"], "forks": r["forks_count"], "language": r["language"], "updated_at": r["updated_at"]} | |
| for r in repos | |
| ] | |
| return {"mode": "org", "org": org, "count": len(results), "results": results} | |
| if mode == "commit_activity": | |
| owner = params.get("owner") | |
| repo = params.get("repo") | |
| if not (owner and repo): | |
| raise ValueError("owner and repo are required for mode='commit_activity'") | |
| resp = httpx.get(f"{BASE}/repos/{owner}/{repo}/stats/commit_activity", headers=headers, timeout=15.0) | |
| resp.raise_for_status() | |
| return {"mode": "commit_activity", "owner": owner, "repo": repo, "weeks": resp.json()} | |
| # default: keyword search | |
| query = params.get("query") | |
| if not query: | |
| raise ValueError("query is required for mode='search'") | |
| sort = params.get("sort", "stars") | |
| per_page = int(params.get("per_page", 30)) | |
| resp = httpx.get( | |
| f"{BASE}/search/repositories", | |
| headers=headers, | |
| params={"q": query, "sort": sort, "per_page": min(per_page, 100)}, | |
| timeout=15.0, | |
| ) | |
| resp.raise_for_status() | |
| items = resp.json().get("items", []) | |
| results = [ | |
| { | |
| "name": r["full_name"], | |
| "description": r["description"], | |
| "stars": r["stargazers_count"], | |
| "forks": r["forks_count"], | |
| "language": r["language"], | |
| "url": r["html_url"], | |
| } | |
| for r in items | |
| ] | |
| return {"mode": "search", "count": len(results), "results": results} | |