IronFlock SDK
IronFlock SDK, edge uygulamalarınızın IronFlock platformuyla etkileşim kurmasını sağlar. Kayıtlı bir cihazda çalışırken kimlik doğrulamayı otomatik olarak yönetir; veri yayımlama, geçmiş sorgulama, cihazlar arası uzak prosedür çağırma ve cihaz meta verisini güncelleme işlevleri sunar.
| SDK | Paket | Gereklilik |
|---|---|---|
| Python | ironflock on PyPI | Python 3.8+ |
| JavaScript | ironflock on npm | Node.js 18+ veya modern tarayıcı |
Kurulum
Python
pip install ironflockYa da uygulamanızın requirements.txt dosyasına ironflock ekleyin.
Hızlı Başlangıç
Python
import asyncio
from ironflock import IronFlock
async def main():
while True:
await ironflock.publish_to_table("sensordata", {
"temperature": 22.5,
"humidity": 60
})
await asyncio.sleep(5)
ironflock = IronFlock(mainFunc=main)
ironflock.run()Bir IronFlock uygulama container’ı içinde kullanıldığında SDK, bağlantı kimlik bilgilerini ortamdan otomatik olarak okur — manuel yapılandırma gerekmez.
Yapıcı Seçenekleri
Python
ironflock = IronFlock(
mainFunc=main, # async function to run after connecting
serial_number="abc123" # override device serial (optional)
)| Parametre | Açıklama |
|---|---|
mainFunc | Bağlantı kurulduktan sonra çalışan bir async fonksiyon |
serial_number | Cihaz seri numarasını geçersiz kılar. Varsayılan: DEVICE_SERIAL_NUMBER ortam değişkeni |
Veri Yayımlama
publishToTable / publish_to_table
Bir filo tablosuna veri kaydı yayımlar. Tablo adı, uygulamanızın data-template.yml dosyasında tanımlanan bir tabloyla eşleşmelidir. SDK, veriyi doğru proje veritabanına otomatik olarak yönlendirir.
Python
await ironflock.publish_to_table("sensordata", {
"temperature": 22.5,
"humidity": 60,
"device_id": "sensor-001"
})appendToTable / append_to_table
Yayımla/abone ol yerine uzak prosedür çağrısı kullanarak filo tablosuna veri ekler. Verinin kalıcı hale getirildiğine dair onay gerektiğinde bunu kullanın.
Python
result = await ironflock.append_to_table("sensordata", {
"temperature": 22.5,
"humidity": 60
})publishRowsToTable / publish_rows_to_table
Bir filo tablosuna tek bir mesajda birden çok satır (toplu ekleme) yayımlar. Platform, tüm yığını tek bir işlemde atomik olarak (ya hep ya hiç) ekler. Satır başına bir gidiş-dönüşün çok maliyetli olacağı yüksek frekanslı veriler için bunu kullanın. publishToTable gibi bu da gönder-unut prensibiyle çalışır — onay, veritabanı eklemesini değil, yönlendiriciye teslimi doğrular.
Python
await ironflock.publish_rows_to_table("sensordata", [
{"tsp": "2024-01-15T10:30:00.000Z", "temperature": 22.5},
{"tsp": "2024-01-15T10:30:01.000Z", "temperature": 22.7},
])İkinci argüman, eklenecek satır nesnelerinden oluşan boş olmayan bir listedir.
appendRowsToTable / append_rows_to_table
Bir filo tablosuna tek bir uzak prosedür çağrısında birden çok satır (toplu ekleme) ekler. Platform, tüm yığını atomik olarak (ya hep ya hiç) ekler: herhangi bir satır geçersizse tüm yığın reddedilir ve hiçbir şey kalıcı hale getirilmez. Ekleme sonucuna ihtiyacınız olduğunda bunu publishRowsToTable / publish_rows_to_table yerine tercih edin.
Python
result = await ironflock.append_rows_to_table("sensordata", [
{"tsp": "2024-01-15T10:30:00.000Z", "temperature": 22.5},
{"tsp": "2024-01-15T10:30:01.000Z", "temperature": 22.7},
])
# result -> {"success": True, "count": 2}reportError / report_error
Bir uygulama hatasını filonuzun error-logs tablosuna raporlar. Bu, publishToTable / appendToTable üzerine kullanışlı bir sarmalayıcıdır: satırı source: "app", bir önem level değeri ve bir zaman damgasıyla işaretler, ardından onu herhangi bir normal tablo satırı gibi yazar. Hata, fleetdb sistem hatalarının kullandığı (source: "system" olarak etiketlenmiş) aynı error-logs tablosuna düşer; bu nedenle getHistory ile sorgulanabilir, subscribeToTable / subscribe_to_table ile akışa alınabilir, board-template’lerde kullanılabilir ve transformed.error-logs üzerinde gerçek zamanlı olarak teslim edilir — platformun sistem hatası bildirimini tetiklemeden.
Python
# Fire-and-forget (default): publishes to the error-logs table
await ironflock.report_error("Sensor read timed out", level="warn")
# Pass an exception to capture its traceback (falls back to the message)
try:
risky_operation()
except Exception as err:
await ironflock.report_error(err)
# Use the append RPC when you want to await the insert outcome
await ironflock.report_error("Calibration failed", level="error", append=True)Parametreler:
| Parametre | Tür | Açıklama |
|---|---|---|
error | str / string veya istisna / Error | Hata mesajı veya traceback/stack (ya da mesajı) kaydedilen bir istisna |
level | str / string, isteğe bağlı | Önem düzeyi: "error", "warn", "info" veya "debug". Varsayılan "error" |
append | bool / boolean, isteğe bağlı | true olduğunda append RPC kullanılır (ekleme sonucunu döndürür). Varsayılan false (fire-and-forget yayımlama) |
tsp | str / string, isteğe bağlı | ISO-8601 zaman damgası geçersiz kılması. Varsayılan olarak geçerli zaman |
Python’da seçenekler anahtar kelime argümanlarıdır (
report_error(error, level=..., append=..., tsp=...)); JavaScript’te bir seçenekler nesnesi aracılığıyla geçilir (reportError(error, { level, append, tsp })).
publish
Herhangi bir WAMP konusuna mesaj yayımlar. Veritabanı tablosuna eşlenmeyen özel mesajlaşma veya olaylar için bunu kullanın.
Python
await ironflock.publish("com.myapp.alerts", {
"level": "warning",
"message": "Temperature threshold exceeded"
})Geçmiş Veri Sorgulama
getHistory
Bir filo tablosundan geçmiş verileri getirir. Filtreleme, zaman aralığı ve sayfalama desteklenir.
Python
# Simple query
data = await ironflock.getHistory("sensordata", {"limit": 100})
# Query with time range and filters
data = await ironflock.getHistory("sensordata", {
"limit": 500,
"offset": 0,
"timeRange": {
"start": "2026-01-01T00:00:00Z",
"end": "2026-03-01T00:00:00Z"
},
"filterAnd": [
{"column": "temperature", "operator": ">", "value": 20},
{"column": "humidity", "operator": "<=", "value": 80}
]
})
# Current value(s) only: the "latest" marker returns the newest row per entity
current = await ironflock.getHistory("sensordata", {
"limit": 100,
"filterAnd": [{"latest": True}]
})Sorgu parametreleri:
| Alan | Tür | Açıklama |
|---|---|---|
limit | int / number | Döndürülecek maksimum satır sayısı (1–10.000, zorunlu) |
offset | int / number | Sayfalama için kaydırma |
timeRange | dict / object | {"start": "<ISO datetime>", "end": "<ISO datetime>"} |
filterAnd | list / array | AND filtre koşulları ve/veya latest işareti (aşağıya bakın) |
columns | list / array | Döndürülecek sütunlar (isteğe bağlı). tsp, device_key ve authid her zaman dahil edilir; tüm sütunlar için bu alanı atlayın |
Filtre operatörleri: =, !=, >, <, >=, <=, LIKE, ILIKE, IN, NOT IN, IS, IS NOT
Her filtre column, operator ve value anahtarlarına sahip bir nesnedir.
Güncel değerleri okuma. filterAnd içindeki bir {"latest": true} girdisi bir filtre koşulu değil, bir mod anahtarıdır: veri arka ucu yalnızca varlık başına en yeni satırı döndürür; bu satır, tablonun maintainLatestFlagFor ile bildirdiği varlık anahtarından SQL’de türetilir. Varlık anahtarı olmayan bir tablo, yalnızca en son tek satırını döndürür.
Diğer koşullar bu işaretle beklediğiniz gibi birleşir: varlık anahtarı sütunları üzerindeki koşullar hangi varlıkların döndürüleceğini daraltır; diğer tüm koşullar ve timeRange ise elde edilen en son satırlara uygulanır. Yani {"latest": true} ile bir deleted filtresini birleştirmek, silinen varlıkların önceki satırını yeniden ortaya çıkarmak yerine bu varlıkları gizler.
IronFlock’un önceki sürümleri fiziksel bir latest_flag sütunu saklıyordu. Bu sütun artık mevcut değil — eski bir latest_flag = true filtresi hâlâ kabul edilir ve bu işaret gibi ele alınır, ancak yeni kodlar {"latest": true} kullanmalıdır. latest işareti getSeriesHistory içinde kullanılamaz.
getSeriesHistory / get_series_history
Bir filo tablosundan alt örneklenmiş zaman serisi verileri alır: zaman kovalarında toplanan sayısal sütunlar (ör. saatlik ortalamalar). Uzun zaman aralıklarını kapsayan grafikler için idealdir. Tablolar için kullanılabilir (transform’lar için değil).
Python
series = await ironflock.get_series_history("sensordata", {
"metrics": ["temperature", "humidity"],
"method": "AVG",
"limit": 500,
"timeRange": ["2026-01-01T00:00:00Z", "2026-03-01T00:00:00Z"],
"groupBy": ["device_id"]
})Sorgu parametreleri:
| Alan | Tür | Açıklama |
|---|---|---|
metrics | list / array | Alt örneklenecek sayısal sütunlar |
method | str / string | Kova başına toplama: "AVG", "SUM", "COUNT", "MIN", "MAX", "FIRST" veya "LAST" |
limit | int / number | Maksimum kova sayısı (1–10.000) |
timeRange | list / array | [start, end] — ISO datetime dizeleri veya epoch-ms sayıları; null = açık uç (zorunlu) |
groupBy | list / array | Serinin gruplanacağı sütunlar (isteğe bağlı) |
filterAnd | list / array | AND filtre koşulları (isteğe bağlı). Yalnızca filtre koşulları — latest işareti burada desteklenmez; güncel değerleri okumak için getHistory kullanın |
Veriye Abone Olma
subscribeToTable / subscribe_to_table
Bir filo tablosundaki gerçek zamanlı güncellemelere abone olur. Tabloya yeni veri yayımlandığında işleyici çağrılır. Toplu ekleme yolu (publishRowsToTable / appendRowsToTable) üzerinden yazılan satırlar işleyicinize birer birer teslim edilir, böylece verinin nasıl yazıldığından bağımsız olarak işleyici kodu aynı kalır.
Python
def on_sensor_data(*args, **kwargs):
print("New reading:", args, kwargs)
await ironflock.subscribe_to_table("sensordata", on_sensor_data)subscribe
Özel gerçek zamanlı mesajlaşma için herhangi bir WAMP konusuna abone olur.
Python
def on_alert(*args, **kwargs):
print("Alert received:", args, kwargs)
await ironflock.subscribe("com.myapp.alerts", on_alert)Uygulamalar Arası Veri Erişimi
Başka bir uygulamanın filo verilerini, aynı proje içinde kendi uygulamanızın içinden okuyun. Sağlayıcı uygulama, data-template.yml dosyasının consumes: bölümünde sizin uygulamanızı belirtmeli ve proje kullanıcısı erişim izni vermelidir. Erişim salt okunurdur: sağlayıcının paylaştığı tabloların ve transform’ların geçmişini sorgulayabilir ve satırlarına gerçek zamanlı olarak abone olabilirsiniz, ancak bunlara yazamazsınız. Tüketilen uygulamalara yapılan bağlantılar uygulama başına önbelleğe alınır ve örneğiniz durduğunda otomatik olarak kapatılır.
Uygulamanız joker karakter (wildcard) iznine (consumes: [{ app: "*" }]) sahipse, sağlayıcıları listConsumableApps / list_consumable_apps ve connectToAllApps / connect_to_all_apps (aşağıda) ile dinamik olarak keşfedebilir ve açabilirsiniz.
connectToApp / connect_to_app
Başka bir uygulamanın veri arka ucuna salt okunur bir bağlantı açar ve bir tanıtıcı (handle) döndürür. Tanıtıcı getHistory / get_history, subscribeToTable / subscribe_to_table ve getSeriesHistory / get_series_history (yalnızca tablolar) işlevlerini sunar — kendi tablolarınızda kullandığınız sorgulama ve abone olma işlemlerinin aynısı — ayrıca close ile paylaşılan tables / transforms kataloglarını da sağlar.
Python
# Open a read-only handle on another app's data backend
weather = await ironflock.connect_to_app("weather-app")
# Inspect what the provider shares
print([t["tablename"] for t in weather.tables])
# Query history and subscribe, just like your own tables
rows = await weather.get_history("forecasts", {"limit": 100})
def on_forecast(*args, **kwargs):
print("New forecast:", args)
await weather.subscribe_to_table("forecasts", on_forecast)Parametreler:
| Parametre | Tür | Açıklama |
|---|---|---|
app_name / appName | str / string | consumes: bölümünüzde belirtildiği gibi sağlayıcı uygulamanın adı |
stage | str / string, isteğe bağlı | Sağlayıcı aşaması (stage): "dev" veya "prod". Varsayılan olarak kendi uygulamanızın aşaması |
on_error / onError | callable, isteğe bağlı | Bağlantı kurulduktan sonra erişim reddedilirse (ör. izin daha sonra iptal edilirse) bir CrossAppAccessError ile çağrılır |
Erişim reddedilir veya yanlış kullanılırsa, code alanına sahip bir CrossAppAccessError yükseltilir (Python) / fırlatılır (JavaScript): NO_GRANT, PROVIDER_NOT_INSTALLED, UNKNOWN_APP, PRIVATE_TABLE veya NOT_AUTHORIZED.
Python’da
stageveon_erroranahtar kelime argümanlarıdır; JavaScript’te bir seçenekler nesnesi aracılığıyla geçilir (connectToApp(appName, { stage, onError })).
listConsumableApps / list_consumable_apps
Projedeki her özel olmayan sağlayıcıyı listeler — bu, joker karakter tüketim iznine (data-template.yml dosyanızdaki consumes: [{ app: "*" }], proje kullanıcısı tarafından verilir) sahip uygulamalar için temel keşif işlevidir. Tek bir çağrı yapar ve hiçbir bağlantı açmaz: döndürülen katalogları bir seçicide gösterin, ardından istediğiniz sağlayıcılar için connectToApp / connect_to_app çağırın — veya hepsini tek seferde açmak için connectToAllApps / connect_to_all_apps çağırın.
Not: İzni uygulamanızın
data-template.ymldosyasında belirtin ve*işaretini tırnak içine alın — tırnaksız bir*, bir YAML takma adıdır ve ayrıştırılamaz:
consumes:
- app: "*"Python
providers = await ironflock.list_consumable_apps()
for p in providers:
print(p["app"], list(p["stages"].keys())) # e.g. "weather-app" ["dev", "prod"]Her giriş bir sağlayıcıyı tanımlar:
| Alan | Tür | Açıklama |
|---|---|---|
app | str / string | Sağlayıcı uygulama adı |
provider_app_key | int / number | Sağlayıcının uygulama anahtarı |
stages | dict / object | Aşama başına katalog { dev?, prod? }; bir aşama yalnızca sağlayıcının o aşama için bir veri arka ucu varsa mevcuttur. Her katalog, paylaştığı özel olmayan tables ve transforms öğelerini içerir |
Uygulamanızın hiçbir joker karakter izni yoksa, code: NO_GRANT içeren bir CrossAppAccessError yükseltilir (Python) / fırlatılır (JavaScript).
connectToAllApps / connect_to_all_apps
Projedeki her özel olmayan sağlayıcıya tek bir çağrıda salt okunur tanıtıcılar (handle) açar (yalnızca joker karakter tüketicileri). Sağlayıcıları listConsumableApps / list_consumable_apps aracılığıyla numaralandırır ve her birini açar; istenen aşama için veri arka ucu bulunmayanları atlar. Her tanıtıcı, connectToApp / connect_to_app ile aynı anahtar altında önbelleğe alınır, böylece daha sonraki bir connectToApp(name) çağrısı zaten hazırlanmış tanıtıcıyı döndürür. Döndürülen tanıtıcılar, örneğiniz durduğunda birlikte kapatılır.
Python
apps = await ironflock.connect_to_all_apps(
on_error=lambda err: print("Provider skipped:", err)
)
for app in apps:
rows = await app.get_history(app.tables[0]["tablename"], {"limit": 10})
print(app.app, rows)Parametreler:
| Parametre | Tür | Açıklama |
|---|---|---|
stage | str / string, isteğe bağlı | Sağlayıcı aşaması (stage): "dev" veya "prod". Varsayılan olarak kendi uygulamanızın aşaması |
continue_on_error / continueOnError | bool / boolean, isteğe bağlı | true olduğunda (varsayılan), açılamayan bir sağlayıcı on_error / onError’a bildirilir ve sonuçtan çıkarılır. false olduğunda, ilk hata yükseltilir/fırlatılır |
on_error / onError | callable, isteğe bağlı | Açılamayan her sağlayıcı ile çağrılır (continue_on_error / continueOnError true iken) ve zaten açılmış bir bağlantı daha sonra reddedilirse (ör. izin daha sonra iptal edilirse) bir CrossAppAccessError ile çağrılır |
Başarıyla açılan sağlayıcı tanıtıcılarını döndürür (connectToApp / connect_to_app ile aynı tanıtıcı türü). Uygulamanızın hiçbir joker karakter izni yoksa, code: NO_GRANT içeren bir CrossAppAccessError yükseltilir (Python) / fırlatılır (JavaScript).
Python’da
stage,on_errorvecontinue_on_erroranahtar kelime argümanlarıdır; JavaScript’te bir seçenekler nesnesi aracılığıyla geçilir (connectToAllApps({ stage, onError, continueOnError })).
Yönetilen Dosya Depolama
Her uygulama veri arka ucu, tablolarının yanı sıra files özelliği üzerinden erişilen özel bir nesne depolama alanı edinir. Bunu görüntüler, PDF’ler, kamera kareleri, firmware blob’ları — kısacası bir tablo satırına ait olmayan her şey — için kullanın. Kurulum gerekmez: veri şablonunda files: bölümü bulunmayan bir uygulama bile default adında bir ad alanı edinir.
Temel fikir şudur: bir nesneyi sakladığınızda size aynı çağrıda doğrudan bir tablo sütununa yazabileceğiniz kalıcı bir URL döner; böylece bir pano widget’ı onu başka hiçbir iş yapmadan görüntüleyebilir:
Python
# Store an object and get a permanent URL back in the same call
info = await ironflock.files.put("part-1.jpg", jpeg_bytes, content_type="image/jpeg")
# The URL is safe to store in a table column — a dashboard widget can then
# render <img src="{{photo_url}}"> without any extra round trip
await ironflock.publish_to_table("inspections", part_id="1", photo_url=info.url)
# Read it back
data = await ironflock.files.get("part-1.jpg")
# Walk every object under a prefix (pages are fetched for you)
async for obj in ironflock.files.iter(prefix="2026/"):
print(obj.key, obj.size)Bu URL hiçbir zaman sona ermez, ancak herkese açık bir bağlantı değildir: yalnızca bu veri arka ucu üzerinde READ erişimine sahip, kimliği doğrulanmış bir istek sahibi tarafından okunabilir kalır ve bir kimlik doğrulama proxy’si bunu her istekte yeniden denetler. Bu nedenle veritabanında saklanması güvenlidir.
Ad Alanları
Bir ad alanı (namespace), politika taşıyan bir anahtar önekidir — saklama süresi, paylaşım kuralları, izin verilen içerik türleri. Ayrı bir bucket değildir; bir uygulamanın her ad alanı, o uygulamanın tek depolama alanının içinde yer alır. Yalnızca bir nesne kümesinin farklı kurallara ihtiyacı olduğunda yeni bir tane tanımlayın; aksi halde default içinde kalın ve nesnelerinizi 2026/03/part-1.jpg gibi anahtar yollarıyla düzenleyin.
Ek ad alanlarını data-template.yml dosyasında tanımlayın:
files:
# Storage budget the app suggests for itself. The project user can change it,
# and their setting is the one that gets enforced.
quotaBytes: 5368709120
namespaces:
- name: frames
description: Raw camera frames, one JPEG per inspected part.
contentTypes: ["image/jpeg"]
maxObjectBytes: 20971520
retention: { deleteAfter: 30 days }Bütçenin ad alanı başına değil, uygulamanın tamamı için bir kez tanımlandığına dikkat edin. Bir ad alanı yalnızca uygulamanın tek depolama alanı içindeki bir anahtar önekidir, dolayısıyla önek başına bir bütçenin uygulanabileceği bir şey yoktur. maxObjectBytes ise ad alanı başınadır — bir toplamı değil, tek bir nesneyi sınırlar.
Aşağıdaki her metot ad alanını isteğe bağlı bir argüman olarak alır ve varsayılan olarak default kullanır.
Nesneleri Saklama ve Okuma
Python
# Bytes in, bytes out
info = await ironflock.files.put("reports/march.pdf", pdf_bytes, content_type="application/pdf")
data = await ironflock.files.get("reports/march.pdf")
# Or straight from/to a local file — these stream on the large-object path,
# so a multi-gigabyte file never has to fit in memory
await ironflock.files.put_file("firmware/v2.bin", "/data/build/v2.bin")
await ironflock.files.get_to_file("firmware/v2.bin", "/tmp/v2.bin")| Metot | Açıklama |
|---|---|
put(key, data, …) | Bir nesneyi saklar (Python’da bytes, JavaScript’te Uint8Array). Nesnenin url değeri dahil meta verilerini döndürür |
get(key, namespace?) | Nesnenin içeriğini döndürür |
put_file(key, path, …) / get_to_file(key, path, …) | Yalnızca Python. Yerel bir dosyadan saklar ya da yerel bir dosyaya yazar. Büyük nesne yolunda akış (stream) olarak aktarır |
delete(key, namespace?) | Bir nesneyi siler |
copy(key, to, …) | Bir nesneyi, isteğe bağlı olarak başka bir ad alanına kopyalar |
move(key, to, …) | Önce kopyalar, sonra siler. Atomik değildir — serviste bir taşıma fiili yoktur, bu nedenle başarısız bir silme her iki kopyayı da bırakır |
JavaScript’te dosya yolu yardımcıları yoktur, çünkü paket hem Node hem de tarayıcı için tek bir derleme yayımlar — yerel dosyaları fs ile kendiniz okuyup yazın.
put şunları kabul eder: content_type / contentType (MIME türü; ad alanı hangilerine izin verildiğini kısıtlayabilir) ve namespace. Python’da bunlar anahtar kelime argümanlarıdır; JavaScript’te bir seçenekler nesnesinin içine girer.
Listeleme ve İnceleme
| Metot | Açıklama |
|---|---|
list(…) | Nesnelerin tek bir sayfası. objects, prefixes, is_truncated / isTruncated ve sonraki sayfa için geri geçirilecek bir cursor döndürür |
iter(…) / iterate(…) | Bir önek altındaki her nesne üzerinde, sayfalamayı otomatik yaparak ilerleyen asenkron yineleyici. Python’da iter, JavaScript’te iterate olarak adlandırılır |
stat(key, namespace?) | İçeriğini aktarmadan tek bir nesnenin meta verileri |
exists(key, namespace?) | Bir nesnenin var olup olmadığı |
namespaces() | Bu uygulamanın kullanabileceği ad alanları |
usage(…) | Uygulamanın ne kadar depolama alanı kullandığı — aşağıya bakın |
catalog() | Ad alanları ile sunucunun bildirdiği limitler ve kotalar. İlk çağrıdan sonra önbelleğe alınır |
Nesneler her iki SDK’da da aynı alanlarla, her dilin adlandırma stiline uygun olarak tanımlanır: namespace, key, size, etag, content_type / contentType, last_modified / lastModified, checksum_sha256 / checksumSha256 ve url.
Depolama Kullanımı ve Kota
usage, tek bir çağrıyla doğrudan nesne deposundan yanıt alır; bu nedenle toplamlar SDK tarafından toplanmış değil, kesindir:
Python
u = await ironflock.files.usage()
print(u.size_bytes, u.object_count, u.quota_bytes, u.free_bytes)
# Break the total down per namespace (costs one listing per namespace)
detailed = await ironflock.files.usage(detail=True)
print(detailed.per_namespace) # {"default": 1048576, "frames": 73400320}| Alan | Anlamı |
|---|---|
size_bytes / sizeBytes | Şu anda saklanan bayt miktarı |
object_count / objectCount | Saklanan nesne sayısı |
quota_bytes / quotaBytes | Uygulanan bütçe. 0 sınırsız anlamına gelir |
free_bytes / freeBytes | Kalan bayt miktarı. -1 sınırsız anlamına gelir — burada 0 bildirmek “dolu” gibi okunurdu |
per_namespace / perNamespace | Ad alanı başına bayt miktarı. Yalnızca ayrıntılı dökümü istediğinizde bulunur |
Ad alanı başına döküm varsayılan olarak kapalıdır, çünkü depo bunu doğrudan yanıtlayamaz: hesabı depolama alanı başına tutar ve bir ad alanı yalnızca bir önektir, dolayısıyla SDK’nın boyutları toplamak için her ad alanını listelemesi gerekir. Bunu istediğinizde isteyin, sıcak bir kod yolunda değil.
Birbirinden ayrı tutulması gereken iki farklı kota vardır. catalog() her ikisini de bildirir:
| Alan | Anlamı |
|---|---|
quota_bytes / quotaBytes | Gerçekte uygulanan değer; nesne deposundan okunur — proje kullanıcısının ayarı |
suggested_quota_bytes / suggestedQuotaBytes | Uygulamanın veri şablonunun istediği değer. Hiçbir şey istemediyse 0 |
Bir kullanıcı uygulamanın bütçesini yükselttiğinde ya da düşürdüğünde bu iki değer birbirinden ayrılır; uygulanan değerin şablondan değil depodan okunmasının nedeni de budur — uygulamanın yeniden dağıtılması, kullanıcının seçimini sessizce sıfırlamamalıdır. Bir arayüz her ikisini de gösterebilir (“uygulama X öneriyor, siz Y ayarladınız”). Uygulama her zaman ilkini kullanır.
Nesneleri Paylaşma
İki tür bağlantı vardır ve aradaki fark önemlidir:
| Metot | Ömür | Kimler okuyabilir |
|---|---|---|
url(key, …) | Kalıcı | Yalnızca bu veri arka ucu üzerinde READ yetkisine sahip, kimliği doğrulanmış bir istek sahibi — her istekte yeniden denetlenir. Bir tablo sütununda saklanması güvenlidir |
share_url / shareUrl | Süreli (varsayılan 15 dakika, sunucu tarafından sınırlanır) | Bağlantıyı elinde tutan herkes. Kullanıldığında yetkilendirmeyi yeniden denetleyen hiçbir şey yoktur |
share_url / shareUrl bir taşıyıcı (bearer) yetkidir: geçici erişime ihtiyacı olan bir kişiye verin ve veritabanında saklamayın. Bir panonun görüntülediği her şey için url kullanın.
url, dağıtımın bir HTTP kenarı bulunmadığı durumlarda (örneğin düz HTTP çalışan bir appliance) None / undefined döndürür — bu, get’e geri dönmeniz gerektiğinin işaretidir. Nesnenin etag değerini version argümanı olarak geçmek, tarayıcıların yanıtı değişmez (immutable) biçimde önbelleğe almasını sağlar.
upload_url / uploadUrl, doğrudan yükleme kabul eden süreli bir URL üretir ve url, method, headers ile expires_in / expiresIn döndürür. Tam olarak döndürdüğü başlıkları gönderin, aksi halde imza doğrulanmaz.
Büyük Nesneler
SDK aktarım yolunu boyuta göre otomatik olarak seçer — yapılandırılacak bir şey yoktur:
| Nesne boyutu | Nasıl aktarılır |
|---|---|
| Satır içi limite kadar (şu anda 6 MiB) | Mesaj yönlendiricisi üzerinden tek bir çağrı |
| Daha büyük | Yönlendiriciyi atlayarak, HTTPS üzerinden doğrudan nesne depolamaya |
Kesin limit, sunucu tarafından çalışma zamanında catalog() içinde inline_max_bytes / inlineMaxBytes olarak bildirilir; böylece yeni bir SDK sürümü çıkmadan yükseltilebilir.
Geriye iki tavan kalır ve her ikisi de hangisine takıldığınızı belirten bir nedenle TOO_LARGE bildirir:
- 5 GiB — nesne deposunun tek seferlik yükleme limiti. Çok parçalı (multipart) yükleme henüz uygulanmadı.
- Doğrudan uç noktanın bulunmadığı yerlerde satır içi limit — hava boşluklu (air-gapped) bir appliance büyük bir nesneyi hiç aktaramaz. Hiçbir yeniden deneme ya da daha küçük parça işe yaramaz ve mesaj bunu açıkça söyler.
Doğrudan yol, cihazın yalnızca yönlendiriciye değil, nesne depolama sunucusuna da erişebilmesini gerektirir. Sahada sık görülen iki arıza, yetkilendirme sorunu gibi görünmek yerine kendi kodlarını alır: PRESIGN_UNREACHABLE (yalnızca yönlendiriciye izin veren bir proxy) ve CLOCK_SKEW (nesne deposu, 15 dakikadan fazla sapmış istekleri reddeder — cihazdaki NTP’yi kontrol edin).
Dosya Depolama Hataları
Her dosya işlemi, kararlı bir code ve insan tarafından okunabilir bir reason taşıyan bir FileStoreError yükseltir (Python) / fırlatır (JavaScript). reason üzerinde değil, her zaman code üzerinde dallanın.
Python
from ironflock.filestore import FileStoreError
try:
await ironflock.files.put("huge.bin", payload)
except FileStoreError as e:
if e.code == "QUOTA_EXCEEDED":
print("Filestore is full:", e.reason)
else:
raise| Kod | Anlamı |
|---|---|
NOT_AUTHORIZED | Çağıran taraf bu işlemi gerçekleştiremez |
NO_SUCH_NAMESPACE | Ad alanı veri şablonunda tanımlı değil |
NO_SUCH_OBJECT | Anahtar mevcut değil |
TOO_LARGE | Tek çağrılık aktarım limitini aşıyor |
OBJECT_TOO_LARGE | Ad alanının kendi maxObjectBytes değerini aşıyor |
QUOTA_EXCEEDED | Dosya deposu dolu |
CONTENT_TYPE_NOT_ALLOWED | Ad alanı contentTypes değerini kısıtlıyor |
NOT_SUPPORTED | Arka uç bunu yapamıyor |
NOT_AVAILABLE | Bu dağıtımda dosya servisi yok |
PRESIGN_UNREACHABLE | Nesne depolamaya doğrudan erişilemiyor (bir proxy mi?) |
CLOCK_SKEW | Cihaz saati fazlaca sapmış |
INTERNAL | Bunların dışındaki her şey |
Daha yeni bir sunucu, bu SDK sürümünün bilmediği kodlar sunabilir. Bunlar tek bir kategoriye indirgenmeden code olarak geçirilir; bu nedenle tanınmayan bir değeri genel bir hata olarak ele alın.
Python’da
FileStoreError,ironflock.filestoreiçinden içe aktarılır; JavaScript’te ise paket kökünden dışa aktarılır (import { FileStoreError } from "ironflock").
Cihazlar Arası İletişim
registerDeviceFunction / register_device_function
Aynı projedeki diğer cihazların çağırabiledği bir prosedür kaydeder. SDK, prosedürü mevcut cihaza otomatik olarak ad alanı ataştırır.
Python
def add(a, b):
return a + b
await ironflock.register_device_function("com.myapp.add", add)
register(),register_device_function()için bir takma addır.
callDeviceFunction / call_device_function
Başka bir cihaz tarafından kaydedilmiş bir prosedürü çağırır. SDK, hedef cihazın anahtarını kullanarak tam WAMP konusunu otomatik olarak oluşturur.
Python
result = await ironflock.call_device_function(
42, # target device key
"com.myapp.add", # procedure name
args=[3, 5] # arguments
)
print(result) # 8call
Tam bir WAMP URI kullanarak uzak prosedür çağırır. Tam konuyu bildiğinizde doğrudan çağrılar için bunu kullanın.
Python
result = await ironflock.call("some.full.wamp.topic", args=[42])Cihaz Meta Verisi
setDeviceLocation / set_device_location
Cihazın GPS konumunu platformda günceller. Değişiklikler IronFlock haritalarda gerçek zamanlı olarak yansıtılır.
Python
await ironflock.set_device_location(long=8.6821, lat=50.1109)| Parametre | Aralık |
|---|---|
long | -180 ile 180 |
lat | -90 ile 90 |
Konum geçmişi saklanmaz. Konumu zaman içinde takip etmek için ayrı bir tablo oluşturun ve
publish_to_table/publishToTablekullanın.
getRemoteAccessUrlForPort
Cihazın belirtilen portu için genel uzaktan erişim URL’sini döndürür.
Python
url = ironflock.getRemoteAccessUrlForPort(8080)
# "https://<device_key>-<app_name>-8080.app.ironflock.com"Bağlantı Özellikleri & Yaşam Döngüsü
Python
| Özellik | Tür | Açıklama |
|---|---|---|
is_connected | bool | Platform bağlantısının aktif olup olmadığı |
connection | CrossbarConnection | Altta yatan bağlantı örneği (gelişmiş kullanım) |
| Metot | Açıklama |
|---|---|
run() | Bağlantıyı başlatır ve mainFunc’ı çalıştırır (engelleme) |
await start() | Bağlantıyı asenkron olarak başlatır |
await stop() | Bağlantıyı durdurur ve çalışan görevleri iptal eder |
await run_async() | Bağlantıyı başlatır ve asenkron olarak çalıştırmaya devam eder |
Hata Yönetimi
Her SDK metodu hatayı açıkça bildirir: geçersiz argümanlarda, kopan bir bağlantıda veya platformdan gelen bir reddetmede, işlemi, konuyu ve nedeni belirten bir mesajla bir istisna yükseltir (Python) ya da reddeder (JavaScript). Hiçbir şey sessizce yutulmaz; bu nedenle hayatta kalmasını istediğiniz çağrıları bir try bloğuna sarın.
Python
try:
rows = await ironflock.getHistory("sensordata", {"limit": 100})
except ValueError as e:
# Invalid parameters — e.g. limit out of range, or a malformed filter
print(f"Bad query: {e}")
except RuntimeError as e:
# Not connected, table not in the data-template, or the platform rejected the call
print(f"Query failed: {e}")JavaScript’te platformdan kaynaklanan hatalar WampError örnekleridir — ek olarak WAMP hata URI’sini error içinde, hata yükünü ise args / kwargs içinde taşıyan normal bir Error alt sınıfı. Bunun dışındaki her şey (hatalı parametreler, bağlantı olmaması) düz bir Error’dır.
Yükseltme: Eski SDK sürümleri bir çağrı başarısız olduğunda bir mesaj kaydedip
None/nulldöndürüyordu. Artık bunun yerine hata yükseltiyorlar; bu nedenleif result is None:biçimindeki kodlar hataları artık yakalamaz —try/except(ya datry/catch) kullanın.
Tarayıcı Kullanımı (Yalnızca JavaScript)
JavaScript SDK modern tarayıcılarda çalışır. Tarayıcılarda ortam değişkenleri bulunmadığından, tüm yapılandırmayı yapıcı aracılığıyla geçin:
import { IronFlock } from "ironflock";
const ironflock = new IronFlock({
serialNumber: "device-serial-from-server",
deviceKey: "my-device-key",
appName: "MyWebApp",
swarmKey: 10,
appKey: 20,
env: "PROD",
});
await ironflock.start();
await ironflock.publishToTable("sensordata", [{ temperature: 22 }]);Kimlik bilgilerini sabit kodlamak yerine arka ucunuzdan yapılandırma almak için IronFlock.fromServer()’ı kullanın:
const ironflock = await IronFlock.fromServer("/api/ironflock-config");
await ironflock.start();Arka uç uç noktanız, bağlantı seçenekleriyle (serialNumber, deviceKey, appName, swarmKey, appKey, env) bir JSON nesnesi döndürmelidir.
AI Ajan Fonksiyonlarını Kaydetme
SDK, AI ajanları tarafından çağrılabilecek fonksiyonlar kaydedebilir. Bir prosedür kaydedin ve ai-template.yml dosyanızdaki konusunu referans alın:
Python
def get_sensor_reading(sensor_id):
"""Returns the latest reading from a sensor."""
reading = read_from_hardware(sensor_id)
return {
"sensor_id": sensor_id,
"temperature": reading.temp,
"humidity": reading.hum,
"timestamp": reading.ts
}
await ironflock.register_device_function("sensors.get_latest", get_sensor_reading)AI ajanı, kullanıcı canlı sensör verisi gerektiren bir soru sorduğunda bu fonksiyonu çağırabilir.
Kayıtlı WAMP konusunu bir AI ajanına bağlamak için, uygulamanızın .ironflock/ai-template.yml dosyasında referans alın:
sensor_agent:
tool_description: |
Delegate to this agent when the user asks about sensor readings,
live device data, or current environmental conditions.
system_prompt: |
You are a sensor data specialist. Use get_current to retrieve
the latest reading from any sensor. Always include the unit in
your response.
main: true
max_context_tokens: 30000
max_iterations: 5
tools:
get_current:
description: Returns the latest reading from a sensor.
topic: sensors.get_latest
parameters:
sensor_id:
type: string
description: The sensor identifier to query.
required: truetopic değeri (sensors.get_latest), edge kodunuzdaki register_device_function / registerDeviceFunction’ına geçirilen adla eşleşmelidir. IronFlock, çağrıyı otomatik olarak fonksiyonun kaydedildiği cihaza yönlendirir.
Tam ai-template.yml referansı için bkz. Ajan & Araç Tanımlama.
Ortam Değişkenleri
Bu değişkenler IronFlock runtime tarafından uygulama container’ı içinde otomatik olarak ayarlanır:
| Değişken | Açıklama |
|---|---|
DEVICE_NAME | Cihaz görüntülenme adı |
DEVICE_SERIAL_NUMBER | Benzersiz, değişmez cihaz tanımlayıcısı |
DEVICE_KEY | Kimlik doğrulama için cihaz anahtarı |
SWARM_KEY | Proje tanımlayıcısı |
APP_KEY | Uygulama tanımlayıcısı |
APP_NAME | Uygulama adı |
ENV | Ortam: DEV veya PROD |
Python
import os
device_name = os.environ.get("DEVICE_NAME")
serial = os.environ.get("DEVICE_SERIAL_NUMBER")
project_key = os.environ.get("SWARM_KEY")