This is a cross-repo issue about unifying the usage of our SDKs across languages. Importantly, we should still follow idiomatic patterns in the target languages, but the concepts and exposed types should be similar and behave as consistently as possible.
There are effectively three different SDKs at this point with varying degrees of compatibility.
- indexd_ffi (python, swift, kotlin, react native)
- indexd (rust)
- sdk (Go)
As an example of indexd_ffi in Python
### Setup SDK
app_id = b'\x01' * 32 # Example app ID to separate app storage while using the same mnemonic
mnemonic = generate_recovery_phrase()
# An AppKey is a struct with a private `PrivateKey` field. It enforces consistent generation and keeps the private key inaccessible to the developer
app_key = AppKey(mnemonic, app_id)
sdk = Sdk("https://app.sia.storage", app_key)
### Connection
if not await sdk.connected(): # kind of lame that these are all on the SDK type. Should reconsider a "builder" type.
print("App not connected")
resp = await sdk.request_app_connection(AppMeta(
name="python example",
description= "an example app",
service_url= "https://example.com",
logo_url=None,
callback_url=None,
))
print(f"Please approve connection {resp.response_url}")
connected = await sdk.wait_for_connect(resp)
if not connected:
fatal("user rejected connection")
print("Connected to indexd")
### Upload
with open("hello.txt", "rb") as f:
# pinned_obj has no public fields, and only exposes some
# helpers to prevent corruption of the internal state
# - id() -> str
# - metadata() -> bytes
# - size() -> u64
# - slabs() -> [Slab]
# - seal(app_key) -> SealedObject
# - update_metdata([]byte)
# - updated_at() -> datetime
pinned_obj = await sdk.upload(f, UploadOptions(
max_inflight=15,
data_shards=10,
parity_shards=20,
metadata=json.dumps({"example": "value"}).encode(),
progress_callback=None,
))
print(f"Uploaded with ID: {pinned_obj.id()}")
### Update Object Metadata
pinned_obj.update_metadata(json.dumps({"example": "new value"}).encode())
await sdk.save_object(pinned_obj)
### Event Syncing
# returns [ObjectEvent] which has three fields:
# - object: PinnedObject
# - deleted: bool
# - timestamp: datetime
object_events = await sdk.objects(ObjectsCursor(
after=datetime.now(timezone.utc) - timedelta(minutes=10),
key=pinned_obj.id(),
), 100)
### Download
with open("hello_downloaded.txt", "wb") as f:
await sdk.download(pinned_obj, f, DownloadOptions(
max_inflight=10,
offset=0,
length=None,
progress_callback=None,
))
sealed = pinned_obj.seal(app_key) # now safe to persist
### Sharing
share_link = sdk.share_object(pinned_obj, datetime.now()+timedelta(days=1)) # make a shareable link valid for 1 day
# Importantly, a SharedObject cannot be converted to a SealedObject and
# similar to PinnedObject has no public fields, only helper methods:
# - size() -> u64
# - metadata() -> bytes
shared_obj = await sdk.shared_object(share_link) # get object metadata from share link
await sdk.pin_shared(shared_obj) # pin shared object to this app's storage
# Download the object
with open("hello_downloaded_shared.txt", "wb") as f:
await sdk.download_shared(shared_obj, f, DownloadOptions(
max_inflight=10,
offset=0,
length=None,
progress_callback=None,
))
Other than just API semantics, logic is also important. Off the top of my head:
-[ ] Uploads and downloads in indexd_ffi will never fail (helps on spotty mobile connections). They will keep retrying until success or the user aborts. Go will error after exhausting its host candidates once.
First task is identifying the patterns we want to keep and what we want to change. Second task is actually implementing them across the SDKs.
This is a cross-repo issue about unifying the usage of our SDKs across languages. Importantly, we should still follow idiomatic patterns in the target languages, but the concepts and exposed types should be similar and behave as consistently as possible.
There are effectively three different SDKs at this point with varying degrees of compatibility.
As an example of
indexd_ffiin PythonOther than just API semantics, logic is also important. Off the top of my head:
-[ ] Uploads and downloads in
indexd_ffiwill never fail (helps on spotty mobile connections). They will keep retrying until success or the user aborts. Go will error after exhausting its host candidates once.Downloadmethod #670)First task is identifying the patterns we want to keep and what we want to change. Second task is actually implementing them across the SDKs.