Developer docs / AI Fabric SDK / Core API

Functions & calls

Invoke registered functions with .local(), .remote() and .spawn(), fan out over the fleet with .map()/.starmap(), and reach deployed endpoints via Function.from_name().

Function.local()

Runs the wrapped Python function in-process, with no fleet involvement — identical to calling the undecorated function. Useful for unit tests and local debugging where you do not want to provision a container.

Signature
Function.local(*args, **kwargs) -> Any

*args, **kwargs Any

Forwarded verbatim to the decorated function and executed synchronously in the current process.

Local vs remote
import bladekit

app = bladekit.app("embeddings")

@app.function(gpu="RTX-A4500", image="fabric/torch")
def embed(text: str) -> list[float]:
    ...

embed.local("hello")   # in-process, no container
embed.remote("hello")  # runs on the fleet

Function.remote()

Enqueues a single call on the GPU fleet and blocks until it finishes, returning the result. A remote exception is re-raised locally: the original exception object when it can be unpickled (so your except clauses keep working), otherwise a RemoteFunctionError — in both cases the remote traceback is attached.

Signature
Function.remote(*args, **kwargs) -> Any

*args, **kwargs Any

Arguments for the function, serialized and sent to the container.

Function.spawn() → FunctionCall

Fire-and-forget: enqueues a call and returns a FunctionCall handle immediately, without blocking. Await the result later with .get().

Signature
Function.spawn(*args, **kwargs) -> FunctionCall

*args, **kwargs Any

Arguments for the function; the call is appended to this function's run and processed FIFO.

FunctionCall

The handle returned by .spawn(). Exposes the run and call ids as the run_id and call_id attributes, plus:

Signature
FunctionCall.get(timeout: float | None = None) -> Any
FunctionCall.cancel() -> None

timeout float | NoneDefault: None

.get() blocks until the call finishes and returns the result (or re-raises the remote exception). With a timeout, raises FabricError if the call has not finished in time; None waits indefinitely.

Spawn and await
call = embed.spawn("hello")
# ... do other work ...
vec = call.get(timeout=60)

Function.map() / Function.starmap()

Fan a function out over an iterable across the GPU fleet, yielding results lazily as a generator. .map() passes each element as the sole positional argument (f(x)); .starmap() splats each element — a tuple — as positional arguments (f(*args)), like itertools.starmap. The batch is persisted server-side, so a client disconnect does not lose work, and inputs are streamed to the server in chunks so a million-item iterable never sits in memory.

Signature
Function.map(iterable, *, order="index", return_exceptions=False,
             retries=None, input_timeout_seconds=None,
             priority=None, namespace=None, max_concurrency=None)

Function.starmap(iterable, *, order="index", return_exceptions=False,
                 retries=None, input_timeout_seconds=None,
                 priority=None, namespace=None, max_concurrency=None)

iterable Iterable

.map(): each element is passed as the sole positional arg. .starmap(): each element is a tuple splatted as positional args — (a, b) calls f(a, b).

order strDefault: "index"

"index" yields in input order (like list(map(f, xs))); "arrival" yields as results complete, for maximum throughput.

return_exceptions boolDefault: False

If True, failed inputs are yielded in-place as exception objects and the generator never stops early. If False, the first failure raises immediately.

retries dict | int | NoneDefault: None

Override the per-input retry policy for this batch — an int shorthand or a dict like {"max_retries": 3, "backoff": {"initial_seconds": 1, "max_seconds": 60, "factor": 2.0}}. Falls back to the function's retries=.

input_timeout_seconds int | NoneDefault: None

Per-input timeout, distinct from the run-global timeout=. A slow input surfaces INPUT_TIMEOUT.

priority int | NoneDefault: None

Scheduling priority 0-9 (9 = urgent, 0 = best-effort). Defaults to the function's priority, or 5 (FIFO).

namespace str | NoneDefault: None

Override the namespace used for GPU quota accounting.

max_concurrency int | NoneDefault: None

Cap on the number of concurrent worker runs for this batch.

map / starmap
# Fan out; results come back in input order.
for vec in embed.map(["a", "b", "c"]):
    print(vec)

# Tolerate failures, prioritize throughput.
for out in embed.map(dataset, order="arrival", return_exceptions=True):
    if isinstance(out, Exception):
        log(out)

# starmap unpacks each tuple into positional args: add(1, 2), add(3, 4).
@app.function(gpu="RTX-A4500", image="fabric/torch")
def add(a: int, b: int) -> int:
    return a + b

for total in add.starmap([(1, 2), (3, 4)]):
    print(total)

MapHandle

Handle for an in-flight or completed map invocation, identified by its map_id (a map_<ULID>). The results generator is lazy — no network calls until iteration begins — and resumable, so an interrupted stream can be restarted from a cursor.

Signature
MapHandle.results(*, order="index", return_exceptions=False,
                  cursor=None) -> Generator
MapHandle.cancel() -> None
MapHandle.status() -> dict

order strDefault: "index"

"index" (input order) or "arrival" (throughput-max order), same as .map().

return_exceptions boolDefault: False

If True, failed inputs are yielded in-place; if False, the first failure raises.

cursor str | NoneDefault: None

Opaque resume cursor from a previously interrupted iteration — pass it to resume from the last seen result instead of the start.

Function.from_name()

Returns a lightweight handle to a deployed app's web endpoint, so other code can invoke it without importing the original function. In the current contract, calling a deployed function goes over the web-endpoint HTTP ingress as JSON — there is no cloudpickle-over-RPC path — so from_name targets web_endpoint / web_server / asgi_app endpoints. The function_name selector matches an endpoint by name, by path (e.g. /predict), or by function qualname.

Signature
Function.from_name(app_name: str, function_name: str) -> handle

app_name str

Name of the deployed app. Raises APP_STOPPED if the app is stopped, DEPLOYMENT_NOT_FOUND if it has no deployed endpoints.

function_name str

Endpoint selector: an endpoint name, a path like /predict, or a function qualname. An ambiguous selector raises INVALID_ARGUMENT — pass a path to disambiguate.

Handle methods

The returned handle exposes several ways to call the endpoint — all resolve the endpoint on first use and return the decoded JSON response:

Signature
handle.remote(*args, **kwargs) -> Any
handle.spawn(*args, **kwargs) -> None
handle.request(*, method="POST", path=None, json=None,
               headers=None, params=None) -> Any
handle.remote_json(payload=..., *, method="POST", path=None,
                   headers=None, params=None, **json_fields) -> Any
handle.web(payload=..., *, method="POST", path=None,
           headers=None, params=None, **json_fields) -> Any

remote(*args, **kwargs) Any

Convenience call. A single positional arg is sent as the JSON body; keyword args are sent as a JSON dict; no args sends null. Mixing positional and keyword args raises INVALID_ARGUMENT.

method strDefault: "POST"

HTTP method for request() / remote_json() / web().

path str | NoneDefault: None

Endpoint path to hit; when omitted, the resolved endpoint's own path is used.

json / payload Any

JSON request body. remote_json()/web() accept either one payload positional or **json_fields keyword fields — not both.

headers, params Mapping | NoneDefault: None

Extra HTTP headers and query-string params.

Call a deployed endpoint
import bladekit

# Reference a deployed app's web endpoint from any process.
predict = bladekit.Function.from_name("classifier", "/predict")

# POST the arg as the JSON body; returns the decoded JSON response.
result = predict.remote({"image_url": "https://example.com/cat.jpg"})

# Or build the request explicitly.
result = predict.request(method="POST", json={"image_url": "..."})

Reference from the Blade console · Updated .

Contact the team

Loading the form…