Python SDK for Brickly brick runtimes.
Project description
brickly-sdk-python
Python SDK for Brickly brick runtimes. It speaks BPP over stdin/stdout and keeps stdout reserved for protocol messages.
Quick Start
from brickly import BricklyRuntime
brick = BricklyRuntime("com.example.python")
@brick.on_command("hello")
def hello(ctx, input):
ctx.progress(0.5, "working...")
ctx.chunk("hello\n")
return {"ok": True, "input": input}
brick.run()
The SDK handles:
host.hello->runtime.readyruntime.ping->runtime.pongcommand.invokedispatchcommand.cancelviactx.cancel_event,ctx.is_cancelled(), andctx.on_cancel(...)command.progress,command.chunk, andcommand.outputhost.*request id allocation andhost.result/host.errorroutingruntime.shutdown-> optional shutdown hook ->runtime.byeui.create_browser_window,WindowHandle.call(...), and event routing forwindow.*events.publish(...)andevents.on(...)brick.platform.system.*/ctx.platform.system.*, plusbrick.system.*/ctx.system.*aliasesbrick.invoke(...)/ctx.invoke(...)for child cross-brick command calls inside command scopebrick.invoke_root(...)for root cross-brick command calls outside command scopebrick.invoke_stream(...)/ctx.invoke_stream(...)for streaming child cross-brick command callsbrick.open_session(...)/ctx.open_session(...)for stateful cross-brick sessionsbrick.platform.clipboard.read_content()/set_content(...)
Logging
brick.log(...) writes plain messages to stderr. Stdout is reserved for BPP protocol messages. The Brickly host log center attaches the brick id, source, stream, and scope metadata when collecting stderr, so brick code should not add a [brickId] prefix by itself.
Window Example
from brickly import BricklyRuntime
brick = BricklyRuntime("com.example.window")
@brick.on_command("open")
def open_window(ctx, input):
win = ctx.ui.create_browser_window("ui/index.html", {"width": 640, "height": 480})
win.on("closed", lambda payload: brick.log("closed", payload))
win.set_title("Hello from Python")
return {"windowId": win.id}
brick.run()
Cross-Brick Invoke
Inside a command handler, use ctx.invoke to call another brick command. The SDK automatically sends the current parentRequestId, so the host attaches the child call to the same invocation graph. Brickly starts, reuses, and recycles the target brick instance automatically. Pass profile_id when the target brick should run with a specific Profile; omit it to use the target brick's default Profile.
result = ctx.invoke(
"com.brickly.openai",
"chat",
{"prompt": "hello"},
profile_id="work",
)
Use invoke_stream when the target command emits progress, chunks, or named outputs before its final result. The SDK sends host.invoke with stream: true and yields events in host order:
for event in ctx.invoke_stream("com.brickly.openai", "chat", {"prompt": "hello"}):
if event["type"] == "progress":
ctx.progress(event.get("progress", 0), event.get("message"))
elif event["type"] == "chunk":
ctx.chunk(event.get("chunk"))
elif event["type"] == "output":
ctx.output(event["name"], event.get("value"))
elif event["type"] == "result":
return event["result"]
If the host returns host.error, invoke_stream raises BppError, matching normal invoke error handling.
To create a top-level cross-brick call outside command scope, use the explicit root API:
result = brick.invoke_root(
"com.brickly.openai",
"chat",
{"prompt": "hello"},
profile_id="work",
)
The caller manifest must declare the target brick and allowed commands in dependencies:
"dependencies": {
"com.brickly.openai": {
"commands": ["chat"]
}
}
Platform System API
brick.platform.system.*, brick.system.*, ctx.platform.system.*, and ctx.system.* call host system capabilities through BPP host.platform.system.*:
@brick.on_command("show-app-info")
def show_app_info(ctx, _input):
return {
"appName": ctx.system.get_app_name(),
"appVersion": ctx.system.get_app_version(),
"userData": ctx.system.get_path("userData"),
"isMacOS": ctx.system.is_macos(),
}
Current methods are show_notification, shell_open_path, shell_trash_item, shell_show_item_in_folder, shell_open_external, shell_beep, get_native_id, get_app_name, get_app_version, get_path, get_file_icon, read_current_folder_path, read_current_browser_url, is_dev, is_macos, is_windows, and is_linux.
get_path() supports home, appData, assets, userData, sessionData, temp, exe, module, desktop, documents, downloads, music, pictures, videos, recent, logs, and crashDumps. Runtime calls are still checked by manifest permissions on the host side: notifications require os.notification; Shell capabilities require os.exec; app info, paths, native ID, platform checks, and current folder path reads require os.env; file icons require fs.read. read_current_folder_path() works when Finder is frontmost on macOS or Explorer is frontmost on Windows; it raises CURRENT_FOLDER_UNAVAILABLE when no readable foreground file-manager folder is available. read_current_browser_url() is reserved and currently returns UNSUPPORTED_PLATFORM.
Platform Clipboard API
brick.platform.clipboard.* and ctx.platform.clipboard.* call host clipboard capabilities through BPP host.platform.clipboard.*:
@brick.on_command("replace-clipboard")
def replace_clipboard(ctx, _input):
previous = ctx.platform.clipboard.read_content()
updated = ctx.platform.clipboard.set_content({"kind": "text", "text": "Updated by Python"})
return {"previous": previous, "updated": updated}
Current methods are read_content() and set_content(content).
Cross-Brick Sessions
Use ctx.open_session when the target brick keeps in-memory state that must survive across multiple command calls. Calls through the same session are routed to the same target brick instance, and each session.invoke automatically carries the current parentRequestId, until close() is called or the caller brick instance exits.
session = ctx.open_session("com.brickly.openai", profile_id="work")
try:
session.invoke("start-thread", {"title": "Draft"})
reply = session.invoke("chat", {"prompt": "continue the thread"})
finally:
session.close()
profile_id is the target brick Profile ID. Session invokes are checked against the caller manifest's dependencies[target].commands on every command call.
Errors
Raise BppError to preserve a specific Brickly error code:
from brickly import BppError
raise BppError("INVALID_INPUT", "url is required")
Project details
Release history Release notifications | RSS feed
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 brickly_sdk-0.1.0.tar.gz.
File metadata
- Download URL: brickly_sdk-0.1.0.tar.gz
- Upload date:
- Size: 13.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f71e10ca1637b34e48a95be4672a636efde451aa8a66812a2022fb543bcd674
|
|
| MD5 |
f5f75aea27d710c05cf5b0e7394395f6
|
|
| BLAKE2b-256 |
46a935f97a700a7a79e7f43d03a57c53da271528a5dcd09e599a4398b0fa5d09
|
File details
Details for the file brickly_sdk-0.1.0-py3-none-any.whl.
File metadata
- Download URL: brickly_sdk-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ebe10ed0883e5706cdbd7dc71c35e238513c2f90f86bd406f128d7e2bf4c7b68
|
|
| MD5 |
8e0f8c2fcf6b661103fc5e6df4299e94
|
|
| BLAKE2b-256 |
5a49992e0ca573dfeba8e5581dd7a2a7c99287420009856b03ed847d545d8bb1
|