Python SDK for publishing media on Slike platform
Project description
slike
Python and TypeScript/JavaScript SDK for the Slike platform.
Supports chunked file upload (4 MiB chunks), editor-video registration, publish-by-URL (Google Drive, YouTube, direct links), media status checks, and upload cancellation (local + server-side). Two auth flows: direct Slike token or Denmark JWT.
- Python requires 3.7+
- TypeScript/JS requires Node 18+ (or modern browser with Fetch API)
Install
Python
pip3 install slike
JavaScript / TypeScript
npm install slike
Python SDK
Quick start
from slike import SlikeMedia
client = SlikeMedia(token="your-slike-token", environment="prod")
client.initialize() # validates token; raises SlikeAPIError on failure
# Upload a local file (blocking)
result = client.register_media(
file_path="/path/to/video.mp4",
title="My Video",
description="Description",
on_progress=lambda done, total: print(f"{done}/{total} chunks"),
)
print("Media ID:", result["id"])
Denmark JWT auth
client = SlikeMedia(
denmark_token="<jwt>",
service="slike", # optional, default: "slike"
environment="prod",
)
client.initialize() # exchanges JWT for a Slike session token
print(client.token) # resolved Slike session token
Provide exactly one of token or denmark_token.
Methods
initialize()
Validates credentials. Must be called once before any other method.
client.initialize()
register_media
Register media on Slike. Provide exactly one of file_path (chunked upload) or editor_settings (editor-generated video — no bytes uploaded).
Blocking file upload (waits for all chunks to finish):
result = client.register_media(
file_path="/path/to/video.mp4",
title="My Video",
description="Description",
asset_type="video", # optional, default: "video"
tags=["news", "sports"], # optional
preset_config={"meta": "", "social": ""}, # optional
on_progress=lambda done, total: print(f"{done}/{total} chunks"),
)
print("Media ID:", result["id"])
Non-blocking file upload (upload runs in a background thread; callback fires the moment chunks finish):
def on_done(res, err):
if err:
print("Upload failed:", err)
else:
print("Upload complete! ID:", res["id"])
result = client.register_media(
file_path="/path/to/video.mp4",
title="My Video",
description="Description",
on_upload_complete=on_done, # fires immediately when chunks finish
)
# result["id"] is available right away — no need to wait
print("Registered, ID:", result["id"])
Editor video (no file — server renders from spec):
client.register_media(
title="My Editor Video",
description="Description",
tags=["news", "sports"],
editor_settings={
"source_width": 1080,
"source_height": 1920,
"clips": [...],
"background_music": {...},
},
)
get_status
Get basic media details and processing readiness by media ID.
status = client.get_status("media_id_here")
print(status["media_id"]) # media ID
print(status["title"]) # media title
print(status["desc"]) # media description
print(status["tags"]) # list of tags
print(status["status"]) # raw status code
print(status["is_ready"]) # True when status==5 and state==10
print(status["msg"]) # "Media is ready." or "Media is not ready yet."
Media is ready when is_ready is True (status == 5 and state == 10).
cancel
Cancel all in-progress background uploads on this client (local abort only).
import threading
result = client.register_media(
file_path="/path/to/video.mp4",
title="My Video",
description="Description",
on_upload_complete=lambda res, err: print("cancelled" if isinstance(err, CancelError) else err or res["id"]),
)
# Cancel from a UI button handler or another thread:
threading.Timer(5.0, client.cancel).start()
cancel() is a no-op if nothing is in progress. All background uploads on the client are stopped; retry backoff sleeps are woken immediately.
cancel_upload
Cancel a specific upload and notify the Slike server to mark the media as cancelled (calls media.update with cancel status values). Use this when the user explicitly cancels from the UI.
result = client.register_media(
file_path="/path/to/video.mp4",
title="My Video",
description="Description",
on_upload_complete=lambda res, err: print(err or "done"),
)
media_id = result["id"]
# When user clicks Cancel in the UI:
client.cancel_upload(media_id)
This performs two actions atomically:
- Stops all local chunk upload threads
- Calls
media.updateon the Slike server to mark the media as cancelled
publish_media
Publish media by URL (Google Drive, YouTube, direct link).
client.publish_media(
url="https://drive.google.com/file/d/FILE_ID/view",
title="My Video",
description="Description",
type="gdrive", # gdrive | youtube | url
asset_type="video", # optional
tags=["news", "sports"], # optional
auto_publish=True, # optional, default: True
)
Error handling
from slike import SlikeMedia, SlikeAPIError, CancelError
try:
client = SlikeMedia(token="...", environment="prod")
client.initialize()
result = client.register_media(file_path="video.mp4", title="T", description="D")
except ValueError as e:
print(f"Bad input: {e}")
except CancelError:
print("Upload was cancelled")
except SlikeAPIError as e:
print(f"API error: {e} (code: {e.code})")
TypeScript / JavaScript SDK
Quick start
import { SlikeMedia } from 'slike';
const client = new SlikeMedia({ token: 'your-slike-token', environment: 'prod' });
await client.initialize();
// Upload a file (blocking — waits for all chunks)
const result = await client.uploadMedia({
file, // File object
title: 'My Video',
description: 'Description',
onProgress: (done, total) => console.log(`${done}/${total} chunks`),
});
console.log('Media ID:', result.id);
Denmark JWT auth
const client = new SlikeMedia({
denmarkToken: '<jwt>',
service: 'slike', // optional
environment: 'prod',
});
await client.initialize();
console.log(client.token);
Methods
initialize()
await client.initialize();
uploadMedia(opts) — blocking upload
Registers and uploads all chunks. Returns when complete.
const result = await client.uploadMedia({
file,
title: 'My Video',
description: 'Description',
tags: ['news', 'sports'],
onProgress: (done, total) => console.log(`${done}/${total}`),
signal: abortController.signal, // optional AbortSignal
});
uploadMediaBackground(opts) — non-blocking upload
Returns an UploadHandle immediately. onUploadComplete fires the moment chunks finish — caller does not need to wait.
const handle = await client.uploadMediaBackground({
file,
title: 'My Video',
description: 'Description',
onProgress: (done, total) => console.log(`${done}/${total}`),
onUploadComplete: (result, error) => {
if (error) console.error('Upload failed:', error);
else console.log('Upload complete! ID:', result.id);
},
});
console.log('Media ID (available now):', handle.mediaId);
// Cancel from UI — stops chunks locally AND marks media cancelled on Slike server:
cancelButton.onclick = () => handle.cancel();
// Or await completion:
const result = await handle.completion;
UploadHandle:
| Property | Type | Description |
|---|---|---|
mediaId |
string |
Media ID (available immediately) |
cancel() |
() => void |
Abort chunks + notify Slike server |
completion |
Promise<RegisterMediaResult> |
Resolves when upload finishes |
getStatus(mediaId, signal?)
Get basic media details and processing readiness.
const status = await client.getStatus('media_id_here');
console.log(status.mediaId); // media ID
console.log(status.title); // media title
console.log(status.desc); // media description
console.log(status.tags); // string[] | undefined
console.log(status.status); // raw status code
console.log(status.isReady); // true when status===5 and state===10
console.log(status.msg); // "Media is ready." or "Media is not ready yet."
cancelUpload(mediaId, signal?)
Mark a specific media as cancelled on the Slike server (calls media.update with cancel status values). Use when the user explicitly cancels from the UI and you need the server to reflect that.
await client.cancelUpload('media_id_here');
Note:
UploadHandle.cancel()already calls this automatically. UsecancelUpload()directly only when you have amediaIdwithout a handle (e.g. cancelling a previously registered upload on page reload).
publishMedia(opts)
await client.publishMedia({
url: 'https://drive.google.com/file/d/FILE_ID/view',
title: 'My Video',
description: 'Description',
type: 'gdrive', // 'gdrive' | 'youtube' | 'url'
tags: ['news', 'sports'],
autoPublish: true,
});
Error handling (TypeScript)
import { SlikeMedia, SlikeAPIError, CancelError } from 'slike';
try {
await client.uploadMedia({ file, title: 'T', description: 'D' });
} catch (err) {
if (err instanceof CancelError) {
console.log('Upload cancelled');
} else if (err instanceof SlikeAPIError) {
console.error('API error:', err.message);
}
}
Use Cases
1. Upload a file and check status after
# Python
client.initialize()
result = client.register_media(file_path="video.mp4", title="T", description="D")
status = client.get_status(result["id"])
print(status["msg"]) # "Media is not ready yet." (processing takes time)
// TypeScript
await client.initialize();
const result = await client.uploadMedia({ file, title: 'T', description: 'D' });
const status = await client.getStatus(result.id);
console.log(status.msg); // "Media is not ready yet."
2. Background upload with completion callback + cancel from UI
# Python
result = client.register_media(
file_path="video.mp4",
title="My Video",
description="Description",
on_upload_complete=lambda res, err: (
print("failed:", err) if err else print("ready to process, ID:", res["id"])
),
)
# Store media_id for potential cancel
media_id = result["id"]
# When user clicks Cancel:
client.cancel_upload(media_id)
// TypeScript
const handle = await client.uploadMediaBackground({
file,
title: 'My Video',
description: 'Description',
onUploadComplete: (result, error) => {
if (error) console.error('failed:', error);
else console.log('chunks done, media processing started:', result.id);
},
});
// Wire to UI cancel button — aborts chunks AND marks cancelled on server:
cancelBtn.onclick = () => handle.cancel();
3. Check if media is ready before serving
# Python
status = client.get_status(media_id)
if status["is_ready"]:
print("Serve URL from your CDN using media_id:", status["media_id"])
else:
print(status["msg"])
// TypeScript
const status = await client.getStatus(mediaId);
if (status.isReady) {
serveMedia(status.mediaId);
} else {
showMessage(status.msg);
}
4. Cancel a previously registered upload (e.g. on page reload)
// If you stored the mediaId in localStorage before the page unloaded:
const mediaId = localStorage.getItem('pendingMediaId');
if (mediaId) {
await client.cancelUpload(mediaId);
localStorage.removeItem('pendingMediaId');
}
Configuration (CLI / Python only)
Priority (highest wins)
- CLI flags (
--token,--denmark-token,--env,--config) - Environment variables (
SLIKE_TOKEN,SLIKE_ENVIRONMENT,SLIKE_CONFIG) ./config.toml→~/.slike/config.toml
Config file
token = "your-token-here"
environment = "prod" # "dev" or "prod"
Environment variables
| Variable | Description |
|---|---|
SLIKE_TOKEN |
Slike auth token |
SLIKE_ENVIRONMENT |
dev or prod |
SLIKE_CONFIG |
Path to a specific config file |
CLI
# Upload a local file
slike-upload video.mp4 --title "My Video" --desc "Description"
# Publish by URL (Google Drive)
slike-upload --url https://drive.google.com/file/d/FILE_ID/view \
--type gdrive --title "My Video" --desc "Description"
# Denmark JWT auth
slike-upload video.mp4 --title "T" --desc "D" --denmark-token <jwt>
| Flag | Description |
|---|---|
--url |
Media URL to ingest (publish mode) |
--type |
gdrive, youtube, or url (default: url) |
--title |
Media title |
--desc |
Media description |
--asset-type |
e.g. video, shorts (default: video) |
--tags |
Comma-separated tags |
--no-publish |
Save as draft, skip auto-publish |
--token |
Slike auth token |
--denmark-token |
Denmark JWT (exchanged for a Slike session token) |
--service |
Service name for Denmark auth (default: slike) |
--env |
dev or prod |
--config |
Path to config file |
Environments
| Environment | RPC endpoint | Upload endpoint | Auth endpoint |
|---|---|---|---|
prod |
https://b2b.sli.ke/rpc |
https://asset.sli.ke/upload |
https://accounts.sli.ke/login |
dev |
https://app-dev.sli.ke/rpc |
https://asset-dev.sli.ke/upload |
https://accounts-dev.sli.ke/login |
How it works
Auth (initialize()):
token: callsuser.meRPC to verify validity.denmark_token: POSTs{type: 4, jwt, service}to/login, readsdata.token.
Chunked file upload:
media.registerRPC → returnsmedia_id+ short-lived upload JWT- File split into 4 MiB chunks, each POSTed as
multipart/form-data - Failed chunks retry up to 3 times with exponential backoff (interruptible by cancel)
Editor video: media.register with type: "videoeditor" + editor spec. No bytes uploaded.
Status check (get_status / getStatus): calls media.get RPC, returns shaped object with is_ready (status==5 AND state==10) and a human-readable msg.
Cancel upload (cancel_upload / cancelUpload): stops local chunk threads and calls media.update RPC with status=-2, state=-2, media_status=-1 to mark the media cancelled on the server.
Development
git clone <repo>
cd slike-media-package
# Python
python3 -m pip install -e .
python3 -m unittest test_slike -v
# TypeScript
cd js
npm install
npx tsc --noEmit # type-check
npm run build # compile to dist/
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file slike-0.2.0.tar.gz.
File metadata
- Download URL: slike-0.2.0.tar.gz
- Upload date:
- Size: 18.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6446a39c66371e8980620898994e8ec24bad53cad8c198f94647f79700d3a999
|
|
| MD5 |
ec92d1b8d9d1e1deb59854dbb5084cb8
|
|
| BLAKE2b-256 |
64c9fa2d335ae5291ea3e26c3e0c8c3aa99981f1be0d6090b276cfcfb6ebde8a
|
File details
Details for the file slike-0.2.0-py3-none-any.whl.
File metadata
- Download URL: slike-0.2.0-py3-none-any.whl
- Upload date:
- Size: 17.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f3011899c28a8b626eeb9705ce919f217e85e0638fcfd964a9c028cf4be9adf
|
|
| MD5 |
1bf9683ce7429b356949dfb0d58c6813
|
|
| BLAKE2b-256 |
4cd30e0c6da7d8e2cded30ac7f27a1ba594f95c234bc6bffb090f096b1c67cec
|