Rate Limit Reset Credits (Standalone)
Query https://chatgpt.com/backend-api/wham/rate-limit-reset-credits and return a sanitized summary. This skill contains the complete implementation; no bundled scripts, references, assets, metadata files, or other skills are required.
Runtime Requirements
uvand a uv-managed Python 3.10 or newer. The implementation uses only Python's standard library and OpenSSL-backed HTTPS.- The current user's Codex credential at
~/.codex/auth.json, withtokens.access_tokenpopulated. - Permission to read that credential and send an HTTPS GET request to the endpoint.
Workflow
- Inspect the current session permissions. If outbound network access or credential access is explicitly restricted, request the tool's supported escalated execution for the first query attempt. Otherwise, attempt the query normally. On a credible sandbox or network denial, retry once with escalation; do not repeat TLS failures in the same restricted sandbox. Respect a rejected escalation. HTTP 401/403 alone is not evidence of a local sandbox failure.
- Copy the complete Python block below verbatim into a temporary
.pyfile, using UTF-8 without BOM. Run it withuv run python <temporary-file-path>, passing the path as one argument. This temporary file is generated from this document at execution time; do not look for installed companion files. Delete only the temporary file created for this query when finished. If a Python file already exists at the chosen path, choose a fresh temporary path. - Keep certificate verification enabled. The implementation uses Python's normal proxy behavior; if diagnosing connectivity, account for configured proxies without printing credentials or secret-bearing proxy URLs.
- Return only the program output. Add no commentary around a successful JSON result. Exit code
0means success; a nonzero code means a sanitized failure. If execution itself is blocked, report that blocker without inventing query results.
Embedded Query Implementation
from __future__ import annotations
import json
import socket
import ssl
import sys
import urllib.error
import urllib.request
from datetime import datetime, timedelta, timezone
from http import HTTPStatus
from pathlib import Path
from typing import Any
ENDPOINT = "https://chatgpt.com/backend-api/wham/rate-limit-reset-credits"
AUTH_PATH = Path.home() / ".codex" / "auth.json"
SHANGHAI = timezone(timedelta(hours=8), "Asia/Shanghai")
TIMEOUT_SECONDS = 20
MSG_UNEXPECTED = "\u54cd\u5e94\u7ed3\u6784\u4e0d\u7b26\u5408\u9884\u671f"
MSG_UNAUTHORIZED = (
"\u51ed\u8bc1\u5931\u6548\uff0c\u6216\u8bf7\u6c42\u6ca1\u6709\u5e26\u5bf9"
" Authorization header\u3002"
)
MSG_NO_STATUS = "\u65e0"
MSG_REQUEST_FAILED = "\u8bf7\u6c42\u5931\u8d25"
MSG_MISSING_ACCESS_TOKEN = "\u672a\u627e\u5230 access_token"
MSG_LOCAL_PREP_FAILED = (
"\u672c\u5730\u51ed\u8bc1\u8bfb\u53d6\u6216\u8bf7\u6c42\u51c6\u5907\u5931\u8d25"
)
MSG_STATUS_CODE = "\u72b6\u6001\u7801"
MSG_ERROR = "\u9519\u8bef"
MSG_TLS_FAILURE = "HTTPS/TLS \u8fde\u63a5\u5931\u8d25\uff08\u53ef\u80fd\u88ab\u6c99\u7bb1\u6216\u4ee3\u7406\u963b\u6b62\uff09"
MSG_DNS_FAILURE = "\u57df\u540d\u89e3\u6790\u5931\u8d25"
MSG_TIMEOUT = "\u8bf7\u6c42\u8d85\u65f6"
MSG_CONNECTION_FAILURE = "\u7f51\u7edc\u8fde\u63a5\u5931\u8d25"
class UnexpectedResponseError(Exception):
pass
def write_failure(status_code: int | str | None, reason: str) -> None:
status = MSG_NO_STATUS if status_code is None else str(status_code)
safe_reason = reason or MSG_REQUEST_FAILED
print(f"{MSG_STATUS_CODE}: {status}; {MSG_ERROR}: {safe_reason}")
def exception_chain(exception: BaseException) -> list[BaseException]:
chain: list[BaseException] = []
pending: list[BaseException] = [exception]
seen: set[int] = set()
while pending and len(chain) < 8:
current = pending.pop(0)
if id(current) in seen:
continue
seen.add(id(current))
chain.append(current)
for linked in (current.__cause__, current.__context__):
if isinstance(linked, BaseException):
pending.append(linked)
if isinstance(current, urllib.error.URLError) and isinstance(
current.reason, BaseException
):
pending.append(current.reason)
return chain
def safe_request_reason(exception: BaseException) -> str:
chain = exception_chain(exception)
details = " | ".join(str(item) for item in chain).lower()
if any(isinstance(item, (ssl.SSLError, ssl.CertificateError)) for item in chain):
return MSG_TLS_FAILURE
if any(isinstance(item, socket.gaierror) for item in chain):
return MSG_DNS_FAILURE
if any(isinstance(item, (TimeoutError, socket.timeout)) for item in chain):
return MSG_TIMEOUT
if any(isinstance(item, ConnectionError) for item in chain):
return MSG_CONNECTION_FAILURE
if any(term in details for term in ("ssl", "tls", "certificate")):
return MSG_TLS_FAILURE
if any(term in details for term in ("dns", "no such host", "name resolution")):
return MSG_DNS_FAILURE
if any(term in details for term in ("timed out", "timeout")):
return MSG_TIMEOUT
if any(term in details for term in ("connection", "network", "proxy", "socket")):
return MSG_CONNECTION_FAILURE
return MSG_REQUEST_FAILED
def read_access_token() -> str:
with AUTH_PATH.open("r", encoding="utf-8") as stream:
auth = json.load(stream)
tokens = auth.get("tokens") if isinstance(auth, dict) else None
token = tokens.get("access_token") if isinstance(tokens, dict) else None
return token if isinstance(token, str) else ""
def request_payload(access_token: str) -> Any:
request = urllib.request.Request(
ENDPOINT,
headers={"Authorization": f"Bearer {access_token}"},
method="GET",
)
context = ssl.create_default_context()
with urllib.request.urlopen(
request,
timeout=TIMEOUT_SECONDS,
context=context,
) as response:
return json.load(response)
def find_value(payload: Any, names: tuple[str, ...]) -> Any:
if not isinstance(payload, dict):
raise UnexpectedResponseError
sources = [payload]
nested = payload.get("data")
if isinstance(nested, dict):
sources.append(nested)
for source in sources:
for name in names:
if name in source:
return source[name]
raise UnexpectedResponseError
def convert_to_shanghai(value: Any) -> str:
if not isinstance(value, str) or not value.strip():
raise UnexpectedResponseError
normalized = value.strip()
if normalized.endswith(("Z", "z")):
normalized = normalized[:-1] + "+00:00"
try:
parsed = datetime.fromisoformat(normalized)
except ValueError as error:
raise UnexpectedResponseError from error
if parsed.tzinfo is None:
parsed = parsed.replace(tzinfo=timezone.utc)
return parsed.astimezone(SHANGHAI).strftime("%Y-%m-%d %H:%M:%S")
def summarize(payload: Any) -> dict[str, Any]:
available_count = find_value(payload, ("available_count",))
credits = find_value(payload, ("credits", "rate_limit_reset_credits"))
if isinstance(available_count, bool) or not isinstance(available_count, int):
raise UnexpectedResponseError
if not isinstance(credits, list):
raise UnexpectedResponseError
safe_credits = []
for credit in credits:
if not isinstance(credit, dict):
raise UnexpectedResponseError
status = credit.get("status")
title = credit.get("title")
if not isinstance(status, str) or not isinstance(title, str):
raise UnexpectedResponseError
safe_credits.append(
{
"status": status,
"title": title,
"granted_at": convert_to_shanghai(credit.get("granted_at")),
"expires_at": convert_to_shanghai(credit.get("expires_at")),
}
)
return {"available_count": available_count, "credits": safe_credits}
def http_reason(status_code: int) -> str:
try:
return HTTPStatus(status_code).phrase
except ValueError:
return MSG_REQUEST_FAILED
def main() -> int:
try:
access_token = read_access_token()
except (OSError, UnicodeError, json.JSONDecodeError):
write_failure(None, MSG_LOCAL_PREP_FAILED)
return 1
if not access_token.strip():
write_failure(None, MSG_MISSING_ACCESS_TOKEN)
return 1
try:
payload = request_payload(access_token)
except urllib.error.HTTPError as error:
if error.code == HTTPStatus.UNAUTHORIZED:
print(MSG_UNAUTHORIZED)
else:
write_failure(error.code, http_reason(error.code))
return 1
except (urllib.error.URLError, TimeoutError, OSError) as error:
write_failure(None, safe_request_reason(error))
return 1
except (json.JSONDecodeError, UnicodeError):
print(MSG_UNEXPECTED)
return 1
except Exception:
write_failure(None, MSG_REQUEST_FAILED)
return 1
try:
result = summarize(payload)
except (UnexpectedResponseError, TypeError, ValueError, OverflowError):
print(MSG_UNEXPECTED)
return 1
print(json.dumps(result, ensure_ascii=False, indent=2))
return 0
if __name__ == "__main__":
sys.exit(main())
Output Contract
On success, output only this JSON shape:
{
"available_count": 0,
"credits": [
{
"status": "available",
"title": "Full reset (Weekly + 5 hr)",
"granted_at": "YYYY-MM-DD HH:mm:ss",
"expires_at": "YYYY-MM-DD HH:mm:ss"
}
]
}
Preserve the server's count, credit order, status, and title. Accept available_count and credits (or rate_limit_reset_credits) at the top level or under data, as implemented above. Convert the two timestamps to Asia/Shanghai (UTC+08:00); treat timestamps without a time zone as UTC. An empty credits array is valid. Reject malformed fields instead of guessing or returning the raw response.
Use the embedded implementation's fixed failure messages:
- Invalid JSON or unexpected response fields:
响应结构不符合预期 - HTTP 401:
凭证失效,或请求没有带对 Authorization header。 - Other request failures:
状态码: <HTTP status or 无>; 错误: <sanitized reason> - Local credential read/preparation failure:
状态码: 无; 错误: 本地凭证读取或请求准备失败 - Missing access token:
状态码: 无; 错误: 未找到 access_token
TLS, DNS, timeout, and connection failures map to the fixed sanitized reasons in the code. Never substitute raw exception details or response bodies.
Credential and Response Handling
Read the credential only at execution time. Never print, log, quote, summarize, or echo token values, refresh tokens, cookies, Authorization header contents, raw response bodies, or complete unique IDs from the response. Do not persist credentials in temporary files, source code, command arguments, or URLs. The temporary Python file contains implementation only.
<!-- OB-S:zq_bxTTjMP34UM3j3cisbA -->
微信扫一扫