2026-09-09 16:21:13 +03:00
2026-09-09 16:21:13 +03:00
2026-09-09 16:21:13 +03:00
2026-09-09 16:21:13 +03:00

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 komutu
  • nowcast-geo-register.py: CSV geo alarm registration istemcisi
  • nowcast-point-page.py, nowcast-point-get.py, nowcast-point-register.py, nowcast-point-update.py, nowcast-point-unregister.py: nokta alarm (/v1/alarms/points) istemcileri
  • nowcast-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 şablonu
  • webhook.example.json: dört webhook authentication seçeneğini içeren şablon
  • nowcast-geo-alarm-filter.example.json: ortak nowcast geo alarm filtreleri şablonu
  • nowcast-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 SUCCESS olmuş satırlar konsola bilgi yazılarak atlanır.
  • Her satırdan sonra CSV aynı dizinde geçici dosyayla atomik olarak güncellenir.
  • recipientId boş 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:

  • BASIC
  • JWT_TOKEN
  • API_KEY
  • HMAC_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:

  1. Access token yoksa .env kullanıcı bilgileriyle login olur.
  2. Access token'ın bitmesine 60 saniyeden az kaldıysa geçerli refresh token ile yeniler.
  3. Refresh token yoksa/geçersizse yeniden login olur.
  4. Sunucu 401 döndürürse refresh veya login yapıp isteği bir kez daha gönderir.
  5. Yeni tokenları ve JWT exp değerlerini .env dosyası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). Backend tarafında createdAt ardından id ile sıralama önerildi (yeni kayıtlar sona eklenir, id eşit zamanlarda sırayı sabitler).
  • Tüm kayıtlar çekilirken aynı anda register, update veya unregister yapmayın. Veri değişirse sayfalar kayar. nowcast-point-page.py sonunda sunucunun bildirdiği totalRecords ile 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. SQLite registrationId ile upsert yaptığı için tekrar çalıştırmak kayıt çoğaltmaz.
  • nowcast-point-page.py varsayılan olarak accountId göndermez; sunucu listeyi çağıranın kendi hesabına daraltır ve normal kullanıcılar için doğru kullanım budur. --account-id yalnızca en az POWER_USER yetkisiyle verilebilir; aksi halde HTTP 403 döner ve betik --account-id vermemenizi söyleyen bir hata yazar. ADMIN kullanıcı accountId vermezse tüm hesapları görür.
  • Backend her RuntimeException'ı HTTP 400 yapar; kayıt bulunamaması da 400 döner. Yalnızca gerçek 404 NOT_FOUND olarak 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 #webhook satırı); password, jwtToken, apiKey ve secret alanları *** ile maskelenir. Her filtre ayrı bir sütundur. API yanıtında createdAt/updatedAt bulunmadığı için çıktıda da yoktur.
  • Etkileşimli terminalde ve --output verilmediğ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.speedThreshold backend 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.

S
Description
No description provided
Readme
245 KiB
Languages
Python 100%