🕵️ SicherheitslückenHak5: Hackers Just Poisoned the Rust Supply Chain | Threat Wire(01.09.2026 um 14:00 Uhr)
🕵️ SicherheitslückenHak5: Hackers Found a Way Into Humanoid Robots | Threat Wire(04.09.2026 um 15:04 Uhr)
🔧 AI Nachrichten Bits und so #1021 (Passwort für Laufwerk)(31.08.2026 um 22:15 Uhr)
🔧 AI Nachrichten Bits und so #1022 (Wie Weißbier)(06.09.2026 um 20:39 Uhr)
🍏 iOS / Mac OSHue-App 6.0 ist da: das sind die Neuerungen(07.09.2026 um 17:21 Uhr)
🕵️ SicherheitslückenHak5: Hackers Just Poisoned the Rust Supply Chain | Threat Wire(01.09.2026 um 14:00 Uhr)
🕵️ SicherheitslückenHak5: Hackers Found a Way Into Humanoid Robots | Threat Wire(04.09.2026 um 15:04 Uhr)
🔧 AI Nachrichten Bits und so #1021 (Passwort für Laufwerk)(31.08.2026 um 22:15 Uhr)
🔧 AI Nachrichten Bits und so #1022 (Wie Weißbier)(06.09.2026 um 20:39 Uhr)
🍏 iOS / Mac OSHue-App 6.0 ist da: das sind die Neuerungen(07.09.2026 um 17:21 Uhr)

🔧 Programmierung 🕛 kürzlich 4 Min Lesezeit
0

Building a Self-Healing GitHub Trending API in One Day

↗ Quelle (dev.to)
🗣️ Stimme:

What happens when you refuse to accept "the source is down" as an answer.



The problem

GitHub's trending page is where millions of developers find new projects every day. But GitHub has never shipped an official API for it — if you want that data programmatically, you have to scrape the HTML.



Every existing scraper I found had the same design: one source, one point of failure. Small HTML change from GitHub → your service is 503 for a week. Rate limited from Cloudflare → same result.



I wanted a trending API that stays up when GitHub's page is down. So I built Hydra, and put it live at hydra9.dev.



The architecture (in one picture)

┌───────────────┐

Request ───▶ │ Router │

└───────┬───────┘

│ tries in order, breaker-guarded

┌───────────────┼────────────────┬─────────────────┐

▼ ▼ ▼ ▼

┌────────┐ ┌──────────┐ ┌──────────────┐ ┌──────────────┐

│Track A │ │ Track B │ │ Track C │ │ Track D │

│HTML │ │Community │ │Search API │ │gitstar- │

│scrape │ │mirror │ │(created:>7d) │ │ranking.com │

└────────┘ └──────────┘ └──────────────┘ └──────────────┘

Any track dead? Circuit breaker opens, next request routes past it.

All tracks dead? Serve most recent Postgres snapshot + fire Prometheus alert.

Four independent sources. A track that fails 3 times in a rolling window gets its breaker opened for 60 seconds — the router jumps to the next track without adding latency to the user's request.



Why 4 sources and not 2

Two sources feels like enough right up until they share a failure mode. The four I picked are architecturally independent:



Track A (github.com/trending HTML): freshest data, but the format changes without warning

Track B (ghapi.huchen.dev community mirror): a nice person maintains this, but it can go quiet for hours

Track C (GitHub Search API created:>7d sort:stars): the most stable, but it's reconstructed trending — not what appears on the actual page

Track D (gitstar-ranking.com): different data model entirely (lifetime stars), useful only as a last-resort cross-check

If A breaks because of a GitHub HTML change, B doesn't (it has its own parser). If B breaks because the maintainer's server goes down, C is a completely different infrastructure at GitHub. If C rate-limits you, D is a totally different site.



Historical data — the thing GitHub won't give you

The official trending page is a snapshot in time. If you refresh, yesterday's list is gone forever.



Hydra runs a Celery beat task every 15 minutes that stores a fresh snapshot to Postgres. That unlocks four analytics endpoints the official page can't offer:






Repos that showed up today but weren't there yesterday



curl






Ranked by stars/hour instead of cumulative fame



curl

velocity in particular has been my favorite — it surfaces projects that are exploding right now, not projects that were famous 6 months ago and still coasting.



The stack (deliberately boring)

API: FastAPI (Python 3.11+)

Task queue: Celery + Redis (broker on db 1, results on db 2)

Storage: PostgreSQL 16 + Alembic

HTTP client: httpx (async everywhere)

HTML parser: selectolax (faster than BeautifulSoup)

Observability: Prometheus + Grafana + 7 alert rules

Deploy: Docker Compose (single file)

The whole thing is 52 Python files and 47 tests that run in 6 seconds.



One lesson: @lru_cache and Pydantic don't mix

The single bug that took me from "green in dev" to "500 in prod" was this innocent-looking function:



@lru_cache

def track_singletons(settings: Settings) -> dict[TrackId, Track]:

return {

TrackId.A: TrackA(settings),

TrackId.B: TrackB(settings),

TrackId.C: TrackC(settings),

TrackId.D: TrackD(settings),

}

Pydantic's BaseSettings is mutable and doesn't implement __hash
_. lru_cache needs hashable arguments. Every real request threw:



TypeError: unhashable type: 'Settings'

Fix: since get_settings() is itself an @lru_cache'd singleton, the parameter was redundant. Call it inside:



@lru_cache

def _track_singletons() -> dict[TrackId, Track]:

settings = get_settings()

return {...}

Silly bug. The tests didn't catch it because they patched Settings with a mock that was hashable. Lesson: your test doubles should mirror the real thing's flaws, not paper over them.



Try it

Live:

Source (MIT):

cd Hydra && cp .env.example .env

docker compose -f infra/docker-compose.prod.yml up -d --build

curl http://localhost:8000/api/v1/trending

If it's useful, a ⭐ on the repo goes a long way. If you have a use case where you'd want more analytics (release velocity? topic clustering? language-specific momentum?), open an issue.



Hydra runs on a single 6GB VPS shared with another project. If the public instance gets hammered, self-hosting is a Docker Compose away.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Hackers Just Poisoned the Rust Supply Chain | Threat Wire
1 Quelle
Hackers Found a Way Into Humanoid Robots | Threat Wire
1 Quelle
Bits und so #1021 (Passwort für Laufwerk)
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Building a Self-Healing GitHub Trending API in One Day

Thematisch verwandte Begriffe: Building, SelfHealing, GitHub, Trending · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...