The flamepy package provides a synchronous client for Flame sessions and tasks, a service base class for host-shim applications, object-cache helpers, the App API for packaging Python workloads, and the Agent Session API for remote script execution.
By default the SDK reads ~/.flame/flame.yaml:
---
current-context: flame
contexts:
- name: flame
cluster:
endpoint: "http://127.0.0.1:8080"
cache:
endpoint: "grpc://127.0.0.1:9090"Environment variables override the file:
FLAME_ENDPOINTFLAME_CACHE_ENDPOINTFLAME_CACHE_STORAGEFLAME_CA_FILE
Top-level helpers use the configured default connection:
import flamepy
session = flamepy.create_session(
"flmping",
min_instances=1,
resreq=flamepy.ResourceRequirement.from_string("cpu=1,mem=1g"),
)
output = session.run(b"hello")
session.close()Public helpers:
connect(addr, tls_config=None) -> Connectioncreate_session(application, common_data=None, session_id=None, min_instances=0, max_instances=None, batch_size=1, resreq=None) -> Sessionopen_session(session_id, spec=None) -> Sessionregister_application(name, app_attrs) -> Noneunregister_application(name) -> Nonelist_applications() -> list[Application]get_application(name) -> Application | Nonelist_sessions() -> list[Session]get_session(session_id) -> Sessionclose_session(session_id) -> Session
Session represents an open or closed Flame session.
Methods:
create_task(input_data: bytes) -> Taskget_task(task_id) -> Tasklist_tasks() -> Iterator[Task]watch_task(task_id, timeout=None) -> TaskWatcherrun(input_data) -> bytessubmit(input_data) -> TaskFutureclose() -> Nonecommon_data() -> bytes | None
create_task() expects bytes. run() blocks until the task completes and
returns its output. submit() returns immediately with a TaskFuture, a
concurrent.futures.Future subclass that resolves with the task output and
dispatches user completion callbacks away from the shared aio loop.
SessionAttributes:
application: strid: str | Nonecommon_data: bytes | Nonemin_instances: intmax_instances: int | Nonebatch_size: int(reserved for future implementation; currently normalized to1)resreq: ResourceRequirement | None
ApplicationAttributes:
shim: Shim | Noneimage: str | Nonedescription: str | Nonelabels: list[str] | Nonecommand: str | Nonearguments: list[str] | Noneenvironments: dict[str, str] | Noneworking_directory: str | Nonemax_instances: int | Nonedelay_release: int | Noneschema: ApplicationSchema | Noneurl: str | Noneinstaller: str | None
ResourceRequirement.from_string("cpu=1,mem=1g,gpu=0") parses user-friendly resource strings into CPU, memory bytes, and GPU counts.
Top-level flamepy exports:
ObjectRefput_object(key_prefix, obj)get_object(ref, deserializer=None)update_object(ref, new_obj)
flamepy.core also exports:
ObjectKeyWILDCARD_SESSIONpatch_object(ref, delta)upload_object(key_or_prefix, file_path)download_object(ref, dest_path)
flamepy.cache exports delete_objects(key_prefix) in addition to the basic cache helpers.
Object references are versioned:
version=0forces a fresh download.version>=1lets the client reuse a cached base object and fetch only newer patches when the server can provide them.- Without a custom deserializer,
get_object()returns only the base object for backward compatibility. - With a deserializer,
get_object(ref, deserializer)callsdeserializer(base, deltas).
Host-shim Python services subclass flamepy.FlameService and run with flamepy.run():
import flamepy
class Echo(flamepy.FlameService):
def on_session_enter(self, context):
self.session_id = context.session_id
def on_task_invoke(self, context):
return context.input
def on_session_leave(self):
pass
if __name__ == "__main__":
flamepy.run(Echo())Service contexts expose bytes-oriented APIs:
SessionContext.session_idSessionContext.applicationSessionContext.common_data()TaskContext.task_idTaskContext.session_idTaskContext.input
The process-wide application API is exported from flamepy.app:
import flamepy.app as app
app.init("add-app")
@app.service()
def add(a, b):
return a + b
print(add(1, 2).get())
app.destroy()A service may invoke another declared service. The captured proxy is restored in the executor as a reference to its existing session:
@app.service()
def fn_a(value):
return value * 2
@app.service()
def fn_b(value):
return fn_a(value).get()Key classes and helpers:
app.session_context()returns the active service-side session context (flamepy.SessionContext) during an App invocation.app.publish_attributes(attrs)adds opaquebyteslocality keys to the current App response; repeated calls in the response accumulate. Session Manager unions every response into the executor's retained set.init(name, fail_if_exists=False, dependencies=None, python_version=None)packages and initializes the application and returns its runtime handle. Repeating it for the same name returns the same handle.dependenciespopulates an auto-generatedpyproject.tomlonly when the project has no existing Python package metadata.python_versionselects the executor Python version through the application template.app.service(autoscale=None, warmup=0, resreq=None)is the canonical service decorator. Functions becomeServiceInstanceproxies. Decorating a class declares a service class without creating a session. CallingDecoratedClass(args...)creates its service handle and session, andflmrunruns the constructor with those arguments in the executor. The decorator accepts functions and classes, not already constructed objects.- Decorated classes do not expose class-level service methods. Invoke methods
directly on a constructed handle, for example
instance.method(...); Flame does not require a.remote()suffix. - Each constructed handle has a unique service ID and its own retained object;
two handles created from the same decorated class do not share object state.
The retained object is executor-local: autoscaling may create one copy per
executor. Use
autoscale=False, warmup=1when mutable state must stay on one executor. - Public class methods must not collide with
ServiceInstanceAPI names such asclose; handle construction rejects such definitions. - The handle returned by
app.init()also exposesservice(...)when direct runtime access is useful. A declaration made during another App invocation is the sole no-init exception; it reuses the current session. ServiceInstanceis the client proxy returned for a decorated function or by calling a decorated class with its remote constructor arguments.- A recursive declaration may call the service decorator without
init()and does not calldestroy(); it reuses and does not own the parent session. Nested submission works at any capacity. If the parent waits synchronously, the session needs enough free executor capacity to run the nested task. get(futures),ref(futures),wait(futures),select(futures)put(obj)stores a shared object under the active application's cache prefix.destroy()closes services. If this process registered the application, it also unregisters it and removes its package/cache. Withfail_if_exists=False, an existing application is borrowed and remains the user's lifecycle responsibility.ObjectFuture.get(),ObjectFuture.ref(),ObjectFuture.wait()
The agent Session lives under flamepy.agent. It runs remote Python or shell scripts through the built-in flmexec application without exposing the core Session or task JSON.
from flamepy.agent import open_session
from flamepy import ResourceRequirement, FlameError
with open_session() as ssn:
print(ssn.run_code("print(1 + 2)").text())Key classes and methods:
open_session(*, ssn_id=None, language="python", runtime=None, min_instances=0, max_instances=None, resreq=None)open_session()creates a Python session using the server-default runtimeopen_session(ssn_id="...")reopens a session by IDSession.run_code(code, input=None) -> SessionOutputblocks for outputSession.submit_code(code, input=None) -> Future[SessionOutput]returns immediatelySession.close()ssn.id,ssn.attrSessionOutput.data,SessionOutput.text()
Creation options are ignored when ssn_id is provided. ssn.attr is a read-only view of the effective creation settings; its type is intentionally not exported. language and runtime are create-time only. close() destroys the session. Reopen works only while the session is still open. ResourceRequirement and FlameError are imported from flamepy.
SessionState.OPEN,SessionState.CLOSEDTaskState.PENDING,TaskState.RUNNING,TaskState.SUCCEED,TaskState.FAILEDApplicationState.ENABLED,ApplicationState.DISABLEDShim.HOST,Shim.WASMFlameErrorCode.INVALID_CONFIG,INVALID_STATE,INVALID_ARGUMENT,INTERNAL,ALREADY_EXISTS,NOT_FOUND
SDK operations raise FlameError with a code and message:
import flamepy
try:
flamepy.connect("invalid://address")
except flamepy.FlameError as exc:
print(exc.code, exc.message)