Commit ·
8c4f619
1
Parent(s): d69af77
Fix _fetch_user_plan after JobsAccess.plan removal
Browse filesPR #172 removed the `plan` attribute from `JobsAccess`, but
`backend/dependencies.py` still called `jobs_access_from_whoami(whoami).plan`.
Every authenticated request hit `AttributeError: 'JobsAccess' object has no
attribute 'plan'` and returned 500 — the live Space went down right after
deploying #172.
Inline the Pro/free/org derivation directly off the whoami payload so the
Claude daily-cap tier no longer depends on the HF-Jobs JobsAccess shape
(those concerns split with #172). Behaviour matches the pre-#172 mapping:
isPro / `pro|enterprise|team` plan strings → "pro", any org membership →
"org", everything else → "free".
- backend/dependencies.py +19 -2
backend/dependencies.py
CHANGED
|
@@ -14,7 +14,7 @@ from fastapi import HTTPException, Request, status
|
|
| 14 |
|
| 15 |
from agent.core.hf_tokens import bearer_token_from_header
|
| 16 |
|
| 17 |
-
from agent.core.hf_access import fetch_whoami_v2
|
| 18 |
|
| 19 |
logger = logging.getLogger(__name__)
|
| 20 |
|
|
@@ -108,7 +108,24 @@ async def _fetch_user_plan(token: str) -> str:
|
|
| 108 |
|
| 109 |
if not isinstance(whoami, dict):
|
| 110 |
return "free"
|
| 111 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
|
| 113 |
|
| 114 |
async def _extract_user_from_token(token: str) -> dict[str, Any] | None:
|
|
|
|
| 14 |
|
| 15 |
from agent.core.hf_tokens import bearer_token_from_header
|
| 16 |
|
| 17 |
+
from agent.core.hf_access import fetch_whoami_v2
|
| 18 |
|
| 19 |
logger = logging.getLogger(__name__)
|
| 20 |
|
|
|
|
| 108 |
|
| 109 |
if not isinstance(whoami, dict):
|
| 110 |
return "free"
|
| 111 |
+
|
| 112 |
+
# OAuth whoami sets `type: "user"` and surfaces Pro via the `isPro` boolean
|
| 113 |
+
# — see Space discussion #21. HF-Jobs eligibility (PR #172) ignores plan
|
| 114 |
+
# entirely; the Claude daily-cap tier is still a free vs pro/org split.
|
| 115 |
+
if whoami.get("isPro") is True or whoami.get("is_pro") is True:
|
| 116 |
+
return "pro"
|
| 117 |
+
plan_str = ""
|
| 118 |
+
for key in ("plan", "type", "accountType"):
|
| 119 |
+
value = whoami.get(key)
|
| 120 |
+
if isinstance(value, str) and value:
|
| 121 |
+
plan_str = value.lower()
|
| 122 |
+
break
|
| 123 |
+
if any(tag in plan_str for tag in ("pro", "enterprise", "team")):
|
| 124 |
+
return "pro"
|
| 125 |
+
orgs = whoami.get("orgs") or []
|
| 126 |
+
if isinstance(orgs, list) and orgs:
|
| 127 |
+
return "org"
|
| 128 |
+
return "free"
|
| 129 |
|
| 130 |
|
| 131 |
async def _extract_user_from_token(token: str) -> dict[str, Any] | None:
|