feat(governance): refresh AI agent market radar
Some checks failed
Code Review / ai-code-review (push) Successful in 15s
CD Pipeline / tests (push) Successful in 1m42s
CD Pipeline / build-and-deploy (push) Successful in 3m58s
CD Pipeline / post-deploy-checks (push) Has been cancelled
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled
Some checks failed
Code Review / ai-code-review (push) Successful in 15s
CD Pipeline / tests (push) Successful in 1m42s
CD Pipeline / build-and-deploy (push) Successful in 3m58s
CD Pipeline / post-deploy-checks (push) Has been cancelled
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled
This commit is contained in:
@@ -19,7 +19,7 @@ from dataclasses import dataclass
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any
|
||||
from urllib.error import HTTPError, URLError
|
||||
from urllib.parse import urljoin
|
||||
from urllib.parse import urljoin, urlparse
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
FetchSource = Callable[[str, int], "FetchedSource"]
|
||||
@@ -234,9 +234,24 @@ def _evaluate_source(
|
||||
}
|
||||
|
||||
fetched = fetcher(url, timeout_seconds)
|
||||
previous = previous_sources.get((candidate_id, source_id), {})
|
||||
if _is_github_rate_limited(url, fetched) and previous:
|
||||
return {
|
||||
"source_id": source_id,
|
||||
"type": source_type,
|
||||
"url": url,
|
||||
"status": "carried_forward_rate_limited",
|
||||
"http_status": fetched.http_status,
|
||||
"version": previous.get("version"),
|
||||
"published_at": previous.get("published_at"),
|
||||
"content_hash": previous.get("content_hash"),
|
||||
"changed_since_reference": False,
|
||||
"reference_version": reference_version,
|
||||
"error": None,
|
||||
"carried_forward_from_previous": True,
|
||||
}
|
||||
parsed = _parse_source(source_type, fetched.body) if fetched.body else {}
|
||||
content_hash = _content_hash(fetched.body, source_type) if fetched.body else None
|
||||
previous = previous_sources.get((candidate_id, source_id), {})
|
||||
version = parsed.get("version")
|
||||
published_at = parsed.get("published_at")
|
||||
changed = _changed_since_reference(
|
||||
@@ -260,6 +275,16 @@ def _evaluate_source(
|
||||
}
|
||||
|
||||
|
||||
def _is_github_rate_limited(url: str, fetched: FetchedSource) -> bool:
|
||||
if fetched.status != "error" or fetched.http_status != 403:
|
||||
return False
|
||||
host = urlparse(url).netloc.lower()
|
||||
if host != "api.github.com":
|
||||
return False
|
||||
body = fetched.body.decode("utf-8", errors="ignore").lower()
|
||||
return "rate limit" in body or "api rate limit exceeded" in body
|
||||
|
||||
|
||||
def _parse_source(source_type: str, body: bytes) -> dict[str, str | None]:
|
||||
if source_type == "pypi":
|
||||
payload = _loads_json(body)
|
||||
|
||||
Reference in New Issue
Block a user