3.9 KiB
PPL CPL API — přehled služby
Stateless multi-tenant proxy nad PPL CPL API (Create Package Label).
Upstream: https://api.dhl.com/ecs/ppl/myapi2 (production),
https://api-dev.dhl.com/ecs/ppl/myapi2 (test).
Dokumentace PPL: https://ppl-cpl-api.apidog.io/
Autentizace
Každý request nese hlavičky:
X-Client-Id— PPL ClientId (secret)X-Client-Secret— PPL ClientSecret (secret)X-Environment—production(default) nebotestAccept-Language— volitelně, předává se do PPL (např.cs-CZ)
Služba z údajů získá OAuth Bearer token (POST {base}/login/getAccessToken,
grant client_credentials, scope myapi2) a cachuje ho in-memory pod
SHA-256 hashem údajů. Důvod: PPL vydá max. 12 tokenů/min a token platí 30 minut.
Token se obnovuje 60 s před expirací; na HTTP 401 z PPL se jednou obnoví
a request se zopakuje.
Limity PPL, které služba respektuje
- min. 40 ms rozestup mezi requesty (globální throttle v procesu),
- max. 1000 zásilek / 100 objednávek v jednom batchi,
- batchId platí 30 dní,
- pouze Latin znaky bez diakritiky — viz transliterace níže.
Transliterace diakritiky
CPL API odmítá texty s diakritikou. Těla POST /shipments/batch,
/shipments/create-and-wait, /orders/batch a /orders/create-and-wait
se defaultně rekurzivně transliterují přes unidecode (Jiří Dvořák →
Jiri Dvorak). Chování:
- query parametr
transliterate=true|falsena requestu má přednost, - jinak platí env
CPL_TRANSLITERATE(defaulttrue), - generická
/proxy/...NEtransliteruje nikdy (předává 1:1).
Chybové odpovědi
Jednotný JSON {error, message, detail}; detail obsahuje původní
problem+json z PPL (typ, title, errors...).
| Status | Význam |
|---|---|
| 400 | validační chyba (vstup zde nebo v PPL) |
| 401 | chybějící X- hlavičky nebo PPL odmítlo údaje/token |
| 403 | chybí oprávnění (role) k metodě v PPL |
| 404 | batch/zásilka/objednávka neexistuje |
| 429 | rate limit PPL |
| 502 | výpadek / neočekávaná chyba PPL |
Všechny chyby se logují (bez secrets) — žádná tichá selhání.
Konfigurace (environment variables)
| Proměnná | Default | Význam |
|---|---|---|
ROOT_PATH |
"" |
prefix za reverse proxy (/apps/pplcplapi) |
CPL_DEFAULT_ENVIRONMENT |
production |
prostředí bez hlavičky X-Environment |
CPL_PRODUCTION_BASE_URL / CPL_TEST_BASE_URL |
viz výše | base URL upstreamu |
CPL_OAUTH_SCOPE |
myapi2 |
OAuth scope |
CPL_TRANSLITERATE |
true |
default transliterace diakritiky |
UPSTREAM_TIMEOUT_SECONDS |
60 |
timeout volání PPL |
TOKEN_REFRESH_MARGIN_SECONDS |
60 |
předstih obnovy tokenu |
MIN_REQUEST_INTERVAL_SECONDS |
0.04 |
rozestup requestů na PPL |
BATCH_POLL_INTERVAL_SECONDS |
1.0 |
interval pollingu create-and-wait |
BATCH_WAIT_TIMEOUT_SECONDS |
30 |
default timeout create-and-wait |
LOG_LEVEL |
INFO |
úroveň logování |
Žádné secrets se nekonfigurují přes env — vše chodí per-request v hlavičkách.
Struktura kódu
app/
main.py — FastAPI aplikace, root_path, popis pro Swagger
config.py — env konfigurace
credentials.py — X- hlavičky -> Credentials (dependency)
token_cache.py — in-memory cache OAuth tokenů
cpl_client.py — autentizovaný httpx klient, throttle, relay helpery
transliterate.py — rekurzivní unidecode JSON těl
errors.py — typované chyby + handlery
routers/
meta.py — /health, /version
shipments.py — zásilky, etikety, tracking, storno, celní dokumenty
orders.py — objednávky svozu/přepravy
codelists.py — číselníky, /version-information, /cpl-info
lookups.py — /access-points, /address-whisper, /routing, /data/{guid}
customer.py — /customer, /customer/addresses, /customer/number-range
proxy.py — generická proxy /proxy/{cesta}