Příklady#
Kompletní průchody. Adresu vas-web.cz nahraďte svou. Klíč aplikace od administrátora
webu držte v proměnné API_KEY — každý příklad ho posílá v hlavičce X-API-Key.
Přihlášení a první čtení#
# 1. přihlášení — POZOR: formulářové tělo
TOKEN=$(curl -s -X POST https://vas-web.cz/api/system/auth/login \
-H "X-API-Key: $API_KEY" \
-d "username=partner" -d "password=tajne" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['data']['token'])")
# 2. výpis článků
curl -s "https://vas-web.cz/api/blog/article/get-all?limit=5&computeTotalCount=1" \
-H "X-API-Key: $API_KEY" \
-H "Authorization: Bearer $TOKEN"
Rozbalení odpovědi#
import json, urllib.request
def rozbal(odpoved):
"""Vrátí seznam plných záznamů z odpovědi s _references."""
reference = odpoved.get('_references', {})
def dohledej(odkaz):
if not isinstance(odkaz, dict) or 'id' not in odkaz:
return odkaz
klic = '-'.join(str(v) for v in odkaz['id'].values())
for trida in reference.values():
if klic in trida:
return {k: dohledej(v) for k, v in trida[klic].items()}
return odkaz
return [dohledej(p) for p in odpoved.get('items', [])]
Rozbalování je rekurzivní
Vazby uvnitř _references jsou zase odkazy.
Filtrovaný výpis#
Aktivní produkty s „notebook“ v názvu, seřazené sestupně podle ceny:
/api/eshop/product-set/get-all
?filters[0][0]=equal&filters[0][1]=activated&filters[0][2]=1
&filters[1][0]=like&filters[1][1]=name&filters[1][2]=notebook&filters[1][matchType]=both
&orderBys[price]=0
&limit=20&computeTotalCount=1
&includes[]=translations
orderBys[price]=0 znamená sestupně
Nula je nepravda. 1 je vzestupně.
Uložení#
curl -s -X POST "https://vas-web.cz/api/bazaar/watchdog/save\
?data[email]=zajemce@example.com\
&data[category][id]=12\
&data[active]=1" \
-H "X-API-Key: $API_KEY" \
-H "Authorization: Bearer $TOKEN"
Data jsou v adrese, ne v těle
POST s JSON tělem vrátí „chybí data“.
Ověření zápisu:
curl -s "https://vas-web.cz/api/bazaar/watchdog/get?id=<id>&includes[]=category" \
-H "X-API-Key: $API_KEY" \
-H "Authorization: Bearer $TOKEN"
Po zápisu s vazbami vždy načtěte znovu
Odpověď na uložení vrací jen ploché hodnoty.
Obnova tokenu#
ODPOVED=$(curl -s -X POST https://vas-web.cz/api/system/auth/refresh \
-H "X-API-Key: $API_KEY" \
-d "refreshToken=$REFRESH")
TOKEN=$(echo "$ODPOVED" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['token'])")
REFRESH=$(echo "$ODPOVED" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['refreshToken'])")
Přepište si OBĚ hodnoty
Ponecháte-li starý obnovovací token a použijete ho, systém vás odhlásí úplně.
Ošetření chyb#
def zpracuj(odpoved_http, telo):
if 'application/json' not in odpoved_http.headers.get('Content-Type', ''):
raise RuntimeError('Server vrátil HTML — chyba 404 nebo 500')
if odpoved_http.status == 429:
cekej = int(odpoved_http.headers.get('Retry-After', '1'))
raise RuntimeError(f'Limit; zkuste za {cekej} s')
data = json.loads(telo)
if odpoved_http.status == 401:
if data.get('code') == 501:
raise RuntimeError('Klíč aplikace chybí nebo neplatí')
raise RuntimeError('Token uživatele neplatí nebo vypršel — obnovte ho')
if odpoved_http.status == 403:
raise RuntimeError('Zamítnuté oprávnění')
if 'success' in data: # zápis
if not data['success']:
raise RuntimeError(f"Chyba {data.get('code')}: {data.get('message')}")
return data.get('data')
return rozbal(data) # čtení
Volání, které posílá klíč aplikace (a token, je-li) a odpověď předá funkci zpracuj:
import os, urllib.error, urllib.request
ZAKLAD = 'https://vas-web.cz'
API_KEY = os.environ['API_KEY']
def zavolej(cesta, token=None):
hlavicky = {'X-API-Key': API_KEY}
if token:
hlavicky['Authorization'] = f'Bearer {token}'
pozadavek = urllib.request.Request(ZAKLAD + cesta, headers=hlavicky)
try:
with urllib.request.urlopen(pozadavek) as odpoved_http:
return zpracuj(odpoved_http, odpoved_http.read())
except urllib.error.HTTPError as chyba: # 4xx a 5xx
return zpracuj(chyba, chyba.read())
Stránkování#
offset, limit, vse = 0, 100, []
while True:
d = zavolej(f'/api/blog/article/get-all?offset={offset}&limit={limit}&computeTotalCount=1')
vse += rozbal(d)
if offset + limit >= d.get('totalCount', 0):
break
offset += limit
Bez computeTotalCount=1 je totalCount nula a cyklus skončí hned