FuelBoard Relay: keyless OAuth proxy for UK Fuel Finder API (FastAPI, token + snapshot cache, demo mode)
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
# FuelBoard Relay
|
||||
|
||||
Keyless proxy for the **UK Fuel Finder API**. Holds the GOV.UK OAuth 2.0
|
||||
client credentials server-side so the FuelBoard iOS app and widget never embed
|
||||
a secret (secrets inside an IPA are extractable by anyone).
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
FuelBoard app / widget
|
||||
│ GET http://192.168.1.131:8788/api/v1/stations?fuel=e10&lat=..&lng=..
|
||||
▼
|
||||
FuelBoard Relay (this repo, runs on the Mac Mini)
|
||||
│ OAuth 2.0 client_credentials grant (token cached ~1h)
|
||||
│ GET https://api.fuelfinder.service.gov.uk/v1/prices (snapshot, cached 5 min)
|
||||
▼
|
||||
UK Fuel Finder API (official gov.uk open data)
|
||||
```
|
||||
|
||||
- Token refreshed automatically before expiry (60s buffer).
|
||||
- Station snapshot cached `FUEL_CACHE_TTL` (default 300s); stale cache is
|
||||
served on upstream failure so the app never sees a hard outage.
|
||||
- No credentials are exposed to clients — the app calls the relay keyless.
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
cp .env.example .env # then fill in FUEL_API_CLIENT_ID / FUEL_API_CLIENT_SECRET
|
||||
./scripts/run.sh
|
||||
```
|
||||
|
||||
Without credentials the relay runs in **demo mode**: `/health` reports
|
||||
`demo_mode: true` and `/api/v1/stations` returns a clean 503 with a hint —
|
||||
useful for testing the app→relay path before credentials exist.
|
||||
|
||||
## Endpoints
|
||||
|
||||
| Endpoint | Description |
|
||||
|---|---|
|
||||
| `GET /health` | Cache status, last sync, failure counters |
|
||||
| `GET /api/v1/stations` | All stations with prices (keyless) |
|
||||
| `GET /api/v1/stations?fuel=e10&lat=53.72&lng=-1.85&radius=10&limit=10` | Filter by fuel, radius around a point, sorted nearest-first |
|
||||
| `GET /api/v1/stations?fuel=diesel` (no lat/lng) | Sorted cheapest-first |
|
||||
|
||||
Fuel grades: `e10`, `e5`, `diesel`.
|
||||
|
||||
## Getting credentials
|
||||
|
||||
1. Sign in at <https://developer.fuel-finder.service.gov.uk/get-started-ifr/onelogin> with GOV.UK One Login.
|
||||
2. Register an application → get `client_id` + `client_secret`.
|
||||
3. Put them in `.env` (never in git, never in the app).
|
||||
|
||||
## Fair use notes (from the Fuel Finder developer guideline)
|
||||
|
||||
- Refresh at least every 5 minutes — we do (cron-style refresh on request + TTL cache).
|
||||
- Serve data unmodified — this relay only filters/sorts, never alters prices.
|
||||
- Keep timestamps — `price_updated` is passed through untouched.
|
||||
|
||||
## Integration point (FuelBoard app)
|
||||
|
||||
`Shared/FuelPriceProvider.swift` has `FuelFinderProvider` stubbed with a
|
||||
`TODO`. When the relay is live, point it at:
|
||||
|
||||
```
|
||||
http://192.168.1.131:8788/api/v1/stations?fuel=<e10|e5|diesel>&lat=..&lng=..
|
||||
```
|
||||
|
||||
and map `stations[].price` / `stations[].distance_km` into `FuelStation`.
|
||||
Reference in New Issue
Block a user