On the wire · 04:47:35 UTC Live 550 · Prematch 14,364 · Markets 57,042 Vol. I · No. 5 · Friday 13 November 2026 wss://pinnfeed.io/v1/stream
PinnFeed
Tutorial · Python · FastAPI

Proxy quote Pinnacle con FastAPI

Aggiornato il · PinnFeed · 2 min di lettura

Risposta: esegui una piccola app FastAPI che legge PINNFEED_KEY dall'ambiente, chiama /v1/odds con httpx, mette in cache il risultato per pochi secondi e restituisce solo i campi utili. Il browser parla alla tua API; la chiave non lascia il server e la cache tiene molti visitatori dentro il rate limit.

app.py#

import os, time
import httpx
from fastapi import FastAPI, HTTPException

KEY = os.environ["PINNFEED_KEY"]            # ps_live_...
API = "https://pinnfeed.io/v1"
TTL = 5                                     # seconds
cache: dict[str, tuple[float, list]] = {}
app = FastAPI()
client = httpx.AsyncClient(headers={"x-api-key": KEY}, timeout=10)

@app.get("/odds/{sport}")
async def odds(sport: str, q: str | None = None):
    ck = f"{sport}|{q}"
    hit = cache.get(ck)
    if hit and time.time() - hit[0] < TTL:
        return hit[1]
    params = {"sport": sport, "market": "moneyline", "main": "true", "limit": 100}
    if q:
        params["q"] = q
    r = await client.get(f"{API}/odds", params=params)
    if r.status_code != 200:
        raise HTTPException(r.status_code, r.json().get("error", {}).get("message", "upstream error"))
    rows = [
        {"id": e["id"], "home": e["home"], "away": e["away"], "start": e["startTime"], "live": e["live"],
         "prices": {o["name"]: o["decimal"] for m in e["markets"] for o in m["outcomes"]},
         "maxStake": max((m["maxStake"] or 0) for m in e["markets"]) if e["markets"] else None}
        for e in r.json()["events"]
    ]
    cache[ck] = (time.time(), rows)
    return rows

Avvia con pip install fastapi uvicorn httpx e uvicorn app:app --port 8000, poi chiama /odds/soccer?q=arsenal.

Note prod#

  • Aggiungi auth o rate limit sul proxy se è pubblico.
  • Rispetta 429 con Retry-After da PinnFeed; piani: 1 (Free), 2 (Hobby), 10 (Builder) o 30 (Pro) req/s.
  • Per board live, un WebSocket server (Builder) e fan-out: WebSocket Python.

CTA#

Builder (99 €/mese). Prova 3 giorni; carta richiesta. REST gratis: signup. Altri host: Cloudflare Worker, Supabase. Correlato: JS browser / CORS.

Domande frequenti#

Perché non chiamare PinnFeed da JavaScript?#

CORS lo consente, ma la chiave sarebbe pubblica: JS browser e CORS.

La cache rende le quote stale?#

Fino a TTL secondi. 1–5 s per prematch; WebSocket per il live.

Posso usare Flask?#

Sì; stesso pattern con requests e un dict cache.

Contenuto educativo per maggiorenni (18+): non pronostici né promesse di guadagno. In Italia scommetti solo con operatori autorizzati ADM.

Il piano WebSocket: Builder, 99 €/mese.

Quote Pinnacle in tempo reale su un unico WebSocket: tutti i 13 sport, tutti i mercati, quote eque senza margine e quote di chiusura. 3 giorni gratis, disdici con un clic.

Form K-1 · Free API key

Get your free API key.

One field. No password, no card: enter your email, click the link we send, and your key is on screen.

By continuing you agree to the Terms and Privacy Policy.

One free key per email. Link valid for 20 minutes.