14 KiB
iklim.co Python sandbox istemcileri
Bu klasör HMAC imzalı istek, otomatik login/refresh ve .env token saklama
özelliklerini ortak bir istemci katmanında toplar. Geo alarm registration istemcisi
bu ortak yapıyı kullanarak noktalı virgüllü CSV satırlarını sırayla işler.
Dosyalar
common/: tekrar kullanılabilir API, HMAC, retry ve authentication katmanılogin.py: manuel login komutunowcast-geo-register.py: CSV geo alarm registration istemcisinowcast-point-page.py,nowcast-point-get.py,nowcast-point-register.py,nowcast-point-update.py,nowcast-point-unregister.py: nokta alarm (/v1/alarms/points) istemcilerinowcast-point-alarm-filter.example.json,nowcast-point-registrations.example.csv,nowcast-point-update.example.csv: nokta alarm şablonları.env.example: güvenli ortam değişkeni şablonuwebhook.example.json: dört webhook authentication seçeneğini içeren şablonnowcast-geo-alarm-filter.example.json: ortak nowcast geo alarm filtreleri şablonunowcast-geo-alarm-registrations.example.csv: CSV şablonu
Gerçek değerler için .env, webhook.json ve
nowcast-geo-alarm-filter.json kullanılır. .env ile webhook.json kaynak kod
deposuna eklenmemelidir.
Kurulum
cd iklim-sandbox
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
Yeni kurulumda şablonları kopyalayın ve gerçek değerlerle düzenleyin:
cp .env.example .env
cp webhook.example.json webhook.json
cp nowcast-geo-alarm-filter.example.json nowcast-geo-alarm-filter.json
cp nowcast-geo-alarm-registrations.example.csv nowcast-geo-alarm-registrations.csv
CSV biçimi
Girdi UTF-8 ve noktalı virgül ayracına sahip olmalıdır:
city;district;recipientId
Ankara;Çankaya;recipient-001
İstanbul;Kadıköy;recipient-002
Script aynı dosyaya şu üç sonuç sütununu ekler veya mevcut değerlerini günceller:
city;district;recipientId;status;httpStatus;registrationId
Ankara;Çankaya;recipient-001;SUCCESS;HTTP_200;f7587d9e-2481-4b4c-818d-c8d1946851b7
- İl ve ilçe adları trim edilip Türkçe büyük/küçük harf kurallarıyla kesin eşleştirilir.
- Bulunamayan konumlar
FAILED;NOT_SENT;olarak kaydedilir. - Daha önce
SUCCESSolmuş satırlar konsola bilgi yazılarak atlanır. - Her satırdan sonra CSV aynı dizinde geçici dosyayla atomik olarak güncellenir.
recipientIdboş olamaz ve US-ASCII karakterlerinden oluşmalıdır.
İl ve ilçe sorgu cache'i
Şehir listesi her script çalıştırmasında yalnızca bir kez API'den alınır ve isim-ID eşleştirmesi bellekte tutulur. İlçe listesi de her benzersiz şehir için yalnızca ilk karşılaşmada alınır; aynı şehirdeki sonraki CSV satırlarında bellekteki sonuç kullanılır. Cache diske yazılmaz ve script kapandığında temizlenir.
Webhook yapılandırması
webhook.json içindeki authentication.selected şu değerlerden biri olmalıdır:
BASICJWT_TOKENAPI_KEYHMAC_SIGNATURE
Yalnızca seçilen seçeneğin options altındaki alanları API'ye gönderilir. İlk
initialization isteğinde tam webhook config gönderilir ve accountId kesinlikle
gönderilmez. İlk başarılı kayıttan sonra .env içindeki
IKLIM_WEBHOOK_INITIALIZED=true yapılır. Sonraki kayıtlar webhook altında yalnızca
API'nin /v1/users/me yanıtındaki account.id değerini gönderir. Webhook'u yeniden
tanımlamak için bu değeri elle false yapın.
Test/prod ortamını veya kullanıcı hesabını değiştirirken de yeni ortamın webhook'u
ilk kayıtla tanımlayabilmesi için IKLIM_WEBHOOK_INITIALIZED=false yapın.
Nowcast geo alarm filter yapılandırması
Tüm CSV satırlarına uygulanacak ortak nowcast filtreleri
nowcast-geo-alarm-filter.json içinde tutulur. Yıldırım, thunderstorm ve yağış
filtrelerinden ihtiyaç duyulmayan nesneler dosyadan çıkarılabilir. API isteğindeki
alan adı doküman gereği yine filter olarak gönderilir.
Otomatik authentication
Ortak istemci her yetkili istekten önce access token'ı kontrol eder:
- Access token yoksa
.envkullanıcı bilgileriyle login olur. - Access token'ın bitmesine 60 saniyeden az kaldıysa geçerli refresh token ile yeniler.
- Refresh token yoksa/geçersizse yeniden login olur.
- Sunucu
401döndürürse refresh veya login yapıp isteği bir kez daha gönderir. - Yeni tokenları ve JWT
expdeğerlerini.envdosyasına kaydeder.
Yetkili isteklerde Authorization: Bearer <accessToken> ile HMAC başlıkları birlikte
gönderilir. Tokenlar ve parolalar konsola yazılmaz.
Retry davranışı
Ağ hataları ile 429, 500, 502, 503 ve 504 yanıtları ilk istekten sonra en
fazla üç kez, varsayılan olarak 2, 4 ve 8 saniye beklenerek tekrar edilir. 429
yanıtındaki Retry-After varsa ona uyulur. Bir operasyonun retry isteklerinde aynı
idempotency key; yeni timestamp, nonce ve HMAC imzası kullanılır.
Belirsiz sonuç veya 409 sonrasında kayıt recipientId ile sorgulanır. Kayıt
bulunursa registrationId kurtarılır ve satır SUCCESS yapılır.
Debug HTTP logları
Her çalıştırmada maskelenmiş HTTP istek ve yanıtları aşağıdaki dosyaya yazılır:
logs/iklim-api-debug.log
Log; istek metodu, URL, deneme numarası, başlıklar, istek gövdesi, HTTP durum kodu,
yanıt başlıkları ve yanıt gövdesini içerir. Parola, kullanıcı adı, JWT, refresh
token, API key, webhook secret, Authorization, cookie ve X-Signature değerleri
maskelenir. Dosya 5 MB'a ulaştığında döndürülür ve en fazla üç eski dosya tutulur.
Başarılı API yanıtındaki warning/warnings alanları ayrıca konsola yazılır.
Çalıştırma
Manuel login:
python login.py
CSV registration:
python nowcast-geo-register.py nowcast-geo-alarm-registrations.csv
Farklı config dosyaları vermek için:
python nowcast-geo-register.py nowcast-geo-alarm-registrations.csv \
--webhook-config another-webhook.json \
--nowcast-filter-config another-nowcast-geo-alarm-filter.json \
--debug-log logs/custom-debug.log
Nokta alarm (nowcast point) istemcileri
Nokta alarm istemcileri BE-NowcastPointAlarm servisinin /v1/alarms/points endpoint'lerini çağırır. Tüm komutlarda --help seçeneklerin tam dökümünü verir. Gerçek filtre değerleri için nowcast-point-alarm-filter.example.json dosyasını nowcast-point-alarm-filter.json olarak kopyalayın (git'e eklenmez). Webhook için mevcut webhook.json kullanılır, ancak geo alarmdan farklı olarak her register isteğinde webhook.json içindeki tam webhook (deliveryPolicy dahil) gönderilir; IKLIM_WEBHOOK_INITIALIZED ve /v1/users/me kullanılmaz. Backend nokta alarm kaydında webhook ve deliveryPolicy zorunlu tutar, hesabı kullanıcıdan kendisi bulur ve hesapta kayıtlı webhook varsa onu yeniden kullanır.
| Komut | Ne yapar |
|---|---|
nowcast-point-page.py |
Kayıtları sayfa sayfa listeler; SQLite'a (iklim-sandbox.db, registrationId anahtarlı) yazar, ekrana basar veya --output ile CSV/TXT üretir |
nowcast-point-get.py |
CSV/TXT içindeki registrationId (--by id) veya recipientId (--by recipient) değerlerini sorgular |
nowcast-point-register.py |
CSV satırlarından kayıt oluşturur |
nowcast-point-update.py |
CSV satırlarıyla kayıtları kısmen günceller (--dry-run destekler) |
nowcast-point-unregister.py |
Listedeki kayıtları siler (onay ve yedekle) |
Önemli uyarılar
- Page endpoint'inde sıralama (ORDER BY) yoktur. Tüm sayfalar gezilirken kayıtların sırası garanti değildir; bu yüzden sayfa kayması yaşanabilir (bir kayıt iki kez gelebilir, bir kayıt hiç gelmeyebilir).
- Tüm kayıtlar çekilirken aynı anda register, update veya unregister yapmayın. Veri değişirse sayfalar kayar.
nowcast-point-page.pysonunda sunucunun bildirdiğitotalRecordsile alınan benzersiz kayıt sayısını karşılaştırır ve fark varsa uyarı verir; bu durumda komutu yeniden çalıştırın. SQLiteregistrationIdile upsert yaptığı için tekrar çalıştırmak kayıt çoğaltmaz. nowcast-point-page.pyvarsayılan olarakaccountIdgöndermez; sunucu listeyi çağıranın kendi hesabına daraltır ve normal kullanıcılar için doğru kullanım budur.--account-idyalnızca en az POWER_USER yetkisiyle verilebilir; aksi halde HTTP 403 döner ve betik--account-idvermemenizi söyleyen bir hata yazar. ADMIN kullanıcıaccountIdvermezse tüm hesapları görür.- Backend her
RuntimeException'ı HTTP 400 yapar; kayıt bulunamaması da 400 döner. Yalnızca gerçek 404NOT_FOUNDolarak işaretlenir.
page
python3 nowcast-point-page.py # tüm sayfalar, ekrana
python3 nowcast-point-page.py --output point-alarm-registrations.csv # point-alarm-registrations-YYYYmmdd-HHMMSS.csv
python3 nowcast-point-page.py --page-number 2 --page-size 50 # yalnızca tek sayfa
python3 nowcast-point-page.py --account-id 2f04f1b5-1c0a-4c4e-b0a7-0ba6e9b7f2e1 # yalnızca POWER_USER ve üstü
python3 nowcast-point-page.py --recipient-id musteri-1 --recipient-id musteri-2
python3 nowcast-point-page.py --polygon "32.8,39.9;32.9,39.9;32.9,40.0;32.8,39.9"
- Poligon
lng,latçiftlerinden oluşan düz halkadır, en az 4 nokta ve kapalı olmalıdır. Filtre, kayıt noktasının poligonla kesişimine bakar; yarıçap yok sayılır. - Çıktıda webhook bilgisi dosya başında bir kez yer alır (CSV'de
#webhooksatırı);password,jwtToken,apiKeyvesecretalanları***ile maskelenir. Her filtre ayrı bir sütundur. API yanıtındacreatedAt/updatedAtbulunmadığı için çıktıda da yoktur. - Etkileşimli terminalde ve
--outputverilmediğinde sonunda "SQLite verisi CSV/TXT dosyasına aktarılsın mı?" sorulur.
get
python3 nowcast-point-get.py idler.txt --output sonuc.csv # registrationId listesi (TXT), CSV çıktı
python3 nowcast-point-get.py idler.csv --output sonuc.txt # registrationId sütunlu CSV, JSON Lines çıktı
python3 nowcast-point-get.py alicilar.txt --by recipient --output sonuc.csv # recipientId ile sorgu
TXT girdi örneği (idler.txt):
# bu satır atlanır
f7587d9e-2481-4b4c-818d-c8d1946851b7
57d1e2ba-bf2d-4ef3-b078-523060b2000c
Girdi CSV ise başlıkta registrationId (veya recipientId) sütunu aranır; TXT ise satır başına bir ID yazılır, boş satırlar ve # ile başlayanlar atlanır. --output zorunludur; uzantı .csv ise noktalı virgüllü CSV, .txt ise JSON Lines yazılır. Satır durumları SUCCESS, NOT_FOUND (HTTP 404) ve FAILED'dır (httpStatus ve errorBody dolar). Bir recipientId birden çok kayıt dönerse her kayıt ayrı satırdır.
register
cp nowcast-point-alarm-filter.example.json nowcast-point-alarm-filter.json # filtreleri düzenleyin
python3 nowcast-point-register.py nowcast-point-registrations.example.csv
python3 nowcast-point-register.py kayitlar.csv --filter-config baska-filtre.json --webhook-config baska-webhook.json
Girdi CSV örneği (sonuç sütunları işlem sonunda aynı dosyaya eklenir):
recipientId;lat;lng;radius
musteri-001;39.9208;32.8541;1000
musteri-002;41.0082;28.9784;5000
CSV sütunları yalnızca recipientId;lat;lng;radius değerleridir (radius metre, 0-50000). Filtre CSV'de tekrarlanmaz; ortak nowcast-point-alarm-filter.json dosyasından okunur ve her kayda uygulanır (--filter-config ile değiştirilir). Sonuç sütunları aynı dosyaya yazılır: status;httpStatus;registrationId;errorBody. HTTP 200 dışındaki yanıtlarda cevap gövdesi errorBody içine yazılır. SUCCESS satırlar yeniden çalıştırmada atlanır. Sonucu belirsiz kalan istek yalnızca recipientId, nokta ve yarıçap birebir eşleşirse mevcut kayıtla kurtarılır. Aynı hesap, recipientId, nokta ve yarıçap ikinci kez kaydedilemez (400).
update
python3 nowcast-point-update.py guncelle.csv --dry-run # gövdeleri gösterir, istek göndermez
python3 nowcast-point-update.py guncelle.csv # gerçekten günceller
Girdi CSV örneği (boş hücre gönderilmez):
registrationId;recipientId;lat;lng;radius;lightningType;peakCurrent;inCloudHeight;intersectsAffectedPolygon;intersectsCellPolygon;severityThreshold;speedThreshold;precipitationIntensities
f7587d9e-2481-4b4c-818d-c8d1946851b7;;;;2500;;;;;;HIGH;;LIGHT|MODERATE
57d1e2ba-bf2d-4ef3-b078-523060b2000c;;40.0;33.0;;PULSE_IN_CLOUD;;;;true;;;
CSV'de registrationId zorunludur; recipientId;lat;lng;radius ve filtre sütunları (lightningType;peakCurrent;inCloudHeight;intersectsAffectedPolygon;intersectsCellPolygon;severityThreshold;speedThreshold;precipitationIntensities, liste | ile ayrılır) isteğe bağlıdır. Boş hücre gönderilmez; lat ve lng birlikte verilmelidir. Önce --dry-run ile gövdeleri kontrol edin.
- Backend PATCH'i bir alanı temizleyemez (null = dokunma).
thunderstorm.speedThresholdbackend PATCH'inde işlenmiyor, değer gönderilse de güncellenmeyebilir (GAIA-476).- Backend sınır güncellemesinde doğrulama yapmaz; yarıçap ve koordinat aralıkları istemcide yerelde doğrulanır.
- Webhook güncellemesi bu sürümde desteklenmez.
unregister
python3 nowcast-point-unregister.py silinecekler.txt # yedek alır, SİL onayı ister
python3 nowcast-point-unregister.py silinecekler.csv --output sonuc.csv # sonuçları dosyaya da yazar
python3 nowcast-point-unregister.py silinecekler.txt --backup yedek/point-yedek.csv # yedek yolu
python3 nowcast-point-unregister.py silinecekler.txt --no-backup # yedeksiz (önerilmez)
Girdi registrationId içeren bir CSV veya satır başına bir ID içeren TXT olabilir.
Başlamadan önce ortam adı ve URL, silinecek kayıt sayısı ve "geri alınamaz" uyarısı gösterilir; bir hesabın son kaydı silinirse webhook tanımı da silinir. Onay için SİL yazılmalıdır (--yes yoktur). prod ortamında ek olarak ortam adı (prod) yazdırılır. Silmeden önce her kayıt get-by-id ile yedeklenir (--backup, kapatmak için --no-backup); yedek yazılamazsa hiçbir kayıt silinmez.