Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| import argparse | |
| import os | |
| import sys | |
| from dataclasses import dataclass | |
| import httpx | |
| class Result: | |
| name: str | |
| method: str | |
| path: str | |
| status: str | |
| ok: bool | |
| detail: str | None = None | |
| def _print_results(results: list[Result]) -> None: | |
| for item in results: | |
| status = "OK" if item.ok else "FAIL" | |
| print(f"{status:4} {item.method:6} {item.path:50} {item.status}") | |
| if item.detail: | |
| print(f" {item.detail}") | |
| def _request( | |
| client: httpx.Client, | |
| results: list[Result], | |
| name: str, | |
| method: str, | |
| path: str, | |
| headers: dict[str, str], | |
| params: dict[str, str] | None = None, | |
| ) -> httpx.Response | None: | |
| try: | |
| response = client.request(method, path, headers=headers, params=params) | |
| except Exception as exc: # pragma: no cover - runtime/network error | |
| results.append(Result(name=name, method=method, path=path, status="ERR", ok=False, detail=str(exc))) | |
| return None | |
| ok = response.status_code == 200 | |
| detail = None | |
| if not ok: | |
| snippet = response.text[:200].replace("\n", " ") | |
| detail = f"{response.status_code} {snippet}" | |
| results.append( | |
| Result( | |
| name=name, | |
| method=method, | |
| path=path, | |
| status=str(response.status_code), | |
| ok=ok, | |
| detail=detail, | |
| ) | |
| ) | |
| return response | |
| def main() -> int: | |
| parser = argparse.ArgumentParser(description="Smoke test admin API endpoints.") | |
| parser.add_argument("--base-url", default=os.getenv("BASE_URL", "http://127.0.0.1:7860")) | |
| parser.add_argument("--email", default=os.getenv("ADMIN_EMAIL")) | |
| parser.add_argument("--password", default=os.getenv("ADMIN_PASSWORD")) | |
| parser.add_argument("--group-id", default=os.getenv("ADMIN_GROUP_ID")) | |
| parser.add_argument("--timeout", type=float, default=10.0) | |
| args = parser.parse_args() | |
| if not args.email or not args.password: | |
| print("Missing credentials. Provide --email/--password or set ADMIN_EMAIL/ADMIN_PASSWORD.") | |
| return 1 | |
| base_url = args.base_url | |
| results: list[Result] = [] | |
| with httpx.Client(base_url=base_url, timeout=args.timeout) as client: | |
| login_res = client.post( | |
| "/auth/login", | |
| json={"email": args.email, "password": args.password}, | |
| ) | |
| if login_res.status_code != 200: | |
| snippet = login_res.text[:200].replace("\n", " ") | |
| print(f"Login failed: {login_res.status_code} {snippet}") | |
| return 1 | |
| token = login_res.json().get("token") | |
| if not token: | |
| print("Login response missing token.") | |
| return 1 | |
| headers = {"Authorization": f"Bearer {token}"} | |
| groups_res = _request(client, results, "groups.list", "GET", "/groups", headers) | |
| group_id = args.group_id | |
| if not group_id: | |
| if not groups_res: | |
| _print_results(results) | |
| return 1 | |
| try: | |
| items = groups_res.json().get("items", []) | |
| except Exception: | |
| items = [] | |
| if items: | |
| group_id = items[0].get("id") | |
| if not group_id: | |
| _print_results(results) | |
| print("No group_id available. Create a group in /admin/groups or pass --group-id.") | |
| return 2 | |
| gid = group_id | |
| endpoints = [ | |
| ("group.get", "GET", f"/groups/{gid}", None), | |
| ("config.get", "GET", f"/groups/{gid}/config", None), | |
| ("ad_filter.get", "GET", f"/groups/{gid}/ad-filter/config", None), | |
| ("ad_filter.reports", "GET", f"/groups/{gid}/ad-filter/reports", {"range": "day"}), | |
| ("spam.get", "GET", f"/groups/{gid}/spam/config", None), | |
| ("verification.get", "GET", f"/groups/{gid}/verification/config", None), | |
| ("auto_replies.list", "GET", f"/groups/{gid}/auto-replies", None), | |
| ("ban_rules.list", "GET", f"/groups/{gid}/ban-rules", None), | |
| ("delete_rules.list", "GET", f"/groups/{gid}/delete-rules", None), | |
| ("posts.list", "GET", f"/groups/{gid}/posts", None), | |
| ("posts.search", "GET", f"/groups/{gid}/posts/search", None), | |
| ("schedules.list", "GET", f"/groups/{gid}/schedules", None), | |
| ("broadcasts.list", "GET", f"/groups/{gid}/broadcasts", None), | |
| ("logs.actions", "GET", f"/groups/{gid}/logs/actions", None), | |
| ("logs.deletions", "GET", f"/groups/{gid}/logs/deletions", None), | |
| ("logs.admin", "GET", f"/groups/{gid}/logs/admin", None), | |
| ("stats.messages", "GET", f"/groups/{gid}/stats/messages", {"range": "day"}), | |
| ("stats.wordcloud", "GET", f"/groups/{gid}/stats/wordcloud", {"range": "day"}), | |
| ("invites.list", "GET", f"/groups/{gid}/invites", None), | |
| ("invites.rankings", "GET", f"/groups/{gid}/invites/rankings", {"range": "day"}), | |
| ("verified_users.list", "GET", f"/groups/{gid}/verified-users", None), | |
| ("verified_users.forms", "GET", f"/groups/{gid}/verified-users/forms", None), | |
| ("verified_users.reviews", "GET", f"/groups/{gid}/verified-users/reviews", None), | |
| ("verified_users.nearby", "GET", f"/groups/{gid}/verified-users/nearby", None), | |
| ("member_events.list", "GET", f"/groups/{gid}/member-events", None), | |
| ] | |
| for name, method, path, params in endpoints: | |
| _request(client, results, name, method, path, headers, params=params) | |
| _print_results(results) | |
| failed = [item for item in results if not item.ok] | |
| if failed: | |
| print(f"Failures: {len(failed)}") | |
| return 1 | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |