Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Upload 4 files
Browse files
README.md
CHANGED
|
@@ -133,7 +133,7 @@ See `CHANGELOG_V194.md` for the Model Pre-scan Decision Card UI pass.
|
|
| 133 |
See `CHANGELOG_V195.md` for the Runtime CSS Cleanup with Legacy Safety Net pass.
|
| 134 |
|
| 135 |
|
| 136 |
-
Current release: Agentic Space Factory v198.26.
|
| 137 |
|
| 138 |
## v198.26.87 — Runs Explorer Badge Rail Alignment
|
| 139 |
|
|
|
|
| 133 |
See `CHANGELOG_V195.md` for the Runtime CSS Cleanup with Legacy Safety Net pass.
|
| 134 |
|
| 135 |
|
| 136 |
+
Current release: Agentic Space Factory v198.26.94.
|
| 137 |
|
| 138 |
## v198.26.87 — Runs Explorer Badge Rail Alignment
|
| 139 |
|
app.py
CHANGED
|
@@ -11,7 +11,7 @@ from fastapi import FastAPI, HTTPException, Request
|
|
| 11 |
from fastapi.responses import HTMLResponse, JSONResponse, FileResponse, RedirectResponse
|
| 12 |
from huggingface_hub import HfApi, attach_huggingface_oauth
|
| 13 |
|
| 14 |
-
from src.bucket import RunPaths, check_user_bucket, create_user_bucket, delete_run_folder, read_run_bundle, list_recent_runs, read_json, write_json, write_launch_metadata
|
| 15 |
from src.config import settings, user_bucket_source
|
| 16 |
from src.eval_config import activate_eval_archive_config, disable_eval_archive_config, flush_eval_archive_records, public_eval_config
|
| 17 |
from src.eval_archive import maybe_publish_eval_record
|
|
@@ -144,6 +144,53 @@ def _auth_recovery_payload(reason: str = "not_authenticated", detail: str | None
|
|
| 144 |
},
|
| 145 |
}
|
| 146 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
def _json_error(exc: Exception) -> HTTPException:
|
| 148 |
if isinstance(exc, HTTPException):
|
| 149 |
return exc
|
|
@@ -707,28 +754,38 @@ def register_custom_routes(fastapi_app: FastAPI) -> None:
|
|
| 707 |
payload = _auth_recovery_payload(str(exc.detail), str(exc.detail))
|
| 708 |
payload["anonymous_eval"] = public_eval_config(None)
|
| 709 |
return JSONResponse(payload, status_code=401)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 710 |
return JSONResponse(
|
| 711 |
{
|
| 712 |
-
"
|
| 713 |
-
"
|
| 714 |
-
"
|
| 715 |
-
|
| 716 |
-
"
|
| 717 |
-
"
|
| 718 |
-
"
|
| 719 |
-
"
|
| 720 |
},
|
| 721 |
-
"
|
| 722 |
-
"
|
| 723 |
-
|
| 724 |
-
|
| 725 |
-
"anonymous_eval": public_eval_config(ctx["username"] if ctx else None),
|
| 726 |
-
"expires_at": ctx.get("expires_at"),
|
| 727 |
-
"login_url": "/oauth/huggingface/login",
|
| 728 |
-
"refresh_login_url": "/auth/refresh-login",
|
| 729 |
-
"reset_url": "/auth/logout-local",
|
| 730 |
-
"logout_url": "/auth/logout-local",
|
| 731 |
-
}
|
| 732 |
)
|
| 733 |
|
| 734 |
|
|
@@ -1173,6 +1230,7 @@ def register_custom_routes(fastapi_app: FastAPI) -> None:
|
|
| 1173 |
write_json(paths.state, cancelled_state, token=ctx["token"])
|
| 1174 |
write_json(f"{paths.root}/summary.json", cancelled_summary, token=ctx["token"])
|
| 1175 |
write_json(f"{paths.root}/cancel.json", cancel_meta, token=ctx["token"])
|
|
|
|
| 1176 |
append_run_event(
|
| 1177 |
run_id,
|
| 1178 |
bucket_source=bucket_source,
|
|
@@ -1944,6 +2002,28 @@ def _write_parent_linked_validation_state(parent_run_id: str, linked: list[dict[
|
|
| 1944 |
linked_payload["effective_status"] = "validated_after_manual_space_test"
|
| 1945 |
write_json(f"{paths.root}/linked_validations.json", linked_payload, token=token)
|
| 1946 |
write_json(f"{paths.root}/manual_validation_status.json", manual_status, token=token)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1947 |
return {"linked_validations": linked_payload, "manual_validation_status": manual_status}
|
| 1948 |
|
| 1949 |
def create_app() -> FastAPI:
|
|
@@ -1970,4 +2050,3 @@ def create_app() -> FastAPI:
|
|
| 1970 |
|
| 1971 |
|
| 1972 |
app = create_app()
|
| 1973 |
-
|
|
|
|
| 11 |
from fastapi.responses import HTMLResponse, JSONResponse, FileResponse, RedirectResponse
|
| 12 |
from huggingface_hub import HfApi, attach_huggingface_oauth
|
| 13 |
|
| 14 |
+
from src.bucket import RunPaths, check_user_bucket, create_user_bucket, delete_run_folder, read_run_bundle, list_recent_runs, read_json, upsert_run_index_entry, write_json, write_launch_metadata
|
| 15 |
from src.config import settings, user_bucket_source
|
| 16 |
from src.eval_config import activate_eval_archive_config, disable_eval_archive_config, flush_eval_archive_records, public_eval_config
|
| 17 |
from src.eval_archive import maybe_publish_eval_record
|
|
|
|
| 144 |
},
|
| 145 |
}
|
| 146 |
|
| 147 |
+
|
| 148 |
+
def _api_me_payload(ctx: dict[str, Any]) -> dict[str, Any]:
|
| 149 |
+
return {
|
| 150 |
+
"authenticated": True,
|
| 151 |
+
"username": ctx["username"],
|
| 152 |
+
"profile": {
|
| 153 |
+
"name": ctx["profile"].get("name"),
|
| 154 |
+
"preferred_username": ctx["profile"].get("preferred_username"),
|
| 155 |
+
"picture": ctx["profile"].get("picture"),
|
| 156 |
+
"is_pro": ctx.get("is_pro"),
|
| 157 |
+
"can_pay": ctx.get("can_pay"),
|
| 158 |
+
},
|
| 159 |
+
"scopes": ctx.get("scopes", []),
|
| 160 |
+
"missing_scopes": ctx.get("missing_scopes", []),
|
| 161 |
+
"warnings": ctx.get("warnings", []),
|
| 162 |
+
"auth_lifetime": ctx.get("auth_lifetime"),
|
| 163 |
+
"anonymous_eval": public_eval_config(ctx["username"] if ctx else None),
|
| 164 |
+
"expires_at": ctx.get("expires_at"),
|
| 165 |
+
"login_url": "/oauth/huggingface/login",
|
| 166 |
+
"refresh_login_url": "/auth/refresh-login",
|
| 167 |
+
"reset_url": "/auth/logout-local",
|
| 168 |
+
"logout_url": "/auth/logout-local",
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
|
| 172 |
+
def _resumable_payload_from_runs(
|
| 173 |
+
runs: list[dict[str, Any]],
|
| 174 |
+
*,
|
| 175 |
+
bucket_source: str,
|
| 176 |
+
token: str | None,
|
| 177 |
+
) -> dict[str, Any]:
|
| 178 |
+
resumable = find_latest_resumable_run(runs)
|
| 179 |
+
selected = resumable or (runs[0] if runs else None)
|
| 180 |
+
if not selected:
|
| 181 |
+
return {"run": None, "view": None, "bucket_source": bucket_source, "reason": "no_run"}
|
| 182 |
+
run_id = validate_run_id(str(selected.get("run_id")))
|
| 183 |
+
snapshot = _build_live_run_snapshot(run_id, bucket_source=bucket_source, token=token, include_heavy=False)
|
| 184 |
+
return {
|
| 185 |
+
"run": selected,
|
| 186 |
+
"view": snapshot["view"],
|
| 187 |
+
"summary": snapshot["summary"],
|
| 188 |
+
"state": snapshot["state"],
|
| 189 |
+
"bucket_source": bucket_source,
|
| 190 |
+
"reason": "latest_resumable_run" if resumable else "latest_run",
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
|
| 194 |
def _json_error(exc: Exception) -> HTTPException:
|
| 195 |
if isinstance(exc, HTTPException):
|
| 196 |
return exc
|
|
|
|
| 754 |
payload = _auth_recovery_payload(str(exc.detail), str(exc.detail))
|
| 755 |
payload["anonymous_eval"] = public_eval_config(None)
|
| 756 |
return JSONResponse(payload, status_code=401)
|
| 757 |
+
return JSONResponse(_api_me_payload(ctx))
|
| 758 |
+
|
| 759 |
+
@fastapi_app.get("/api/bootstrap")
|
| 760 |
+
async def api_bootstrap(request: Request, bucket_name: str = settings.bucket_name, limit: int = 100): # type: ignore[no-untyped-def]
|
| 761 |
+
try:
|
| 762 |
+
ctx = _oauth_context_from_request(request)
|
| 763 |
+
except HTTPException as exc:
|
| 764 |
+
payload = _auth_recovery_payload(str(exc.detail), str(exc.detail))
|
| 765 |
+
payload["anonymous_eval"] = public_eval_config(None)
|
| 766 |
+
return JSONResponse(payload, status_code=401)
|
| 767 |
+
bucket_source = user_bucket_source(username=ctx["username"], bucket_name=bucket_name)
|
| 768 |
+
bucket_status = check_user_bucket(username=ctx["username"], bucket_name=bucket_name, token=ctx["token"])
|
| 769 |
+
runs: list[dict[str, Any]] = []
|
| 770 |
+
resumable = {"run": None, "view": None, "bucket_source": bucket_source, "reason": "bucket_not_ready"}
|
| 771 |
+
if bucket_status.get("ok"):
|
| 772 |
+
runs = list_recent_runs(bucket_source=bucket_source, token=ctx["token"], limit=limit)
|
| 773 |
+
resumable = _resumable_payload_from_runs(runs, bucket_source=bucket_source, token=ctx["token"])
|
| 774 |
return JSONResponse(
|
| 775 |
{
|
| 776 |
+
"schema_version": "asf_bootstrap.v1",
|
| 777 |
+
"me": _api_me_payload(ctx),
|
| 778 |
+
"bucket": bucket_status,
|
| 779 |
+
"runs": {
|
| 780 |
+
"runs": runs,
|
| 781 |
+
"bucket_source": bucket_source,
|
| 782 |
+
"bucket_uri": f"hf://buckets/{bucket_source}",
|
| 783 |
+
"limit": limit,
|
| 784 |
},
|
| 785 |
+
"resumable": resumable,
|
| 786 |
+
"bucket_source": bucket_source,
|
| 787 |
+
},
|
| 788 |
+
headers={"Cache-Control": "no-store, no-cache, must-revalidate", "Pragma": "no-cache"},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 789 |
)
|
| 790 |
|
| 791 |
|
|
|
|
| 1230 |
write_json(paths.state, cancelled_state, token=ctx["token"])
|
| 1231 |
write_json(f"{paths.root}/summary.json", cancelled_summary, token=ctx["token"])
|
| 1232 |
write_json(f"{paths.root}/cancel.json", cancel_meta, token=ctx["token"])
|
| 1233 |
+
upsert_run_index_entry(run_id, bucket_source=bucket_source, summary=cancelled_summary, token=ctx["token"])
|
| 1234 |
append_run_event(
|
| 1235 |
run_id,
|
| 1236 |
bucket_source=bucket_source,
|
|
|
|
| 2002 |
linked_payload["effective_status"] = "validated_after_manual_space_test"
|
| 2003 |
write_json(f"{paths.root}/linked_validations.json", linked_payload, token=token)
|
| 2004 |
write_json(f"{paths.root}/manual_validation_status.json", manual_status, token=token)
|
| 2005 |
+
try:
|
| 2006 |
+
index_summary = {
|
| 2007 |
+
"run_id": parent_run_id,
|
| 2008 |
+
"updated_at": linked_payload.get("updated_at"),
|
| 2009 |
+
"linked_validation_count": len(compact),
|
| 2010 |
+
"linked_validations_count": len(compact),
|
| 2011 |
+
}
|
| 2012 |
+
if manual_status.get("status") == "success":
|
| 2013 |
+
index_summary.update({
|
| 2014 |
+
"manual_validation_passed": True,
|
| 2015 |
+
"post_build_status": linked_payload.get("effective_status") or "validated_after_manual_space_test",
|
| 2016 |
+
"effective_status": linked_payload.get("effective_status") or "validated_after_manual_space_test",
|
| 2017 |
+
"latency_seconds": manual_status.get("latency_seconds"),
|
| 2018 |
+
"observed_latency_seconds": manual_status.get("observed_latency_seconds"),
|
| 2019 |
+
"recommended_zero_gpu_duration_seconds": manual_status.get("recommended_zero_gpu_duration_seconds"),
|
| 2020 |
+
"recommendation_source": manual_status.get("recommendation_source") or "linked_space_test",
|
| 2021 |
+
"recommendation_hardware": manual_status.get("recommendation_hardware"),
|
| 2022 |
+
"hardware_used_for_validation": manual_status.get("hardware_used_for_validation"),
|
| 2023 |
+
})
|
| 2024 |
+
upsert_run_index_entry(parent_run_id, bucket_source=bucket_source, summary=index_summary, token=token)
|
| 2025 |
+
except Exception:
|
| 2026 |
+
pass
|
| 2027 |
return {"linked_validations": linked_payload, "manual_validation_status": manual_status}
|
| 2028 |
|
| 2029 |
def create_app() -> FastAPI:
|
|
|
|
| 2050 |
|
| 2051 |
|
| 2052 |
app = create_app()
|
|
|