rekuest
The distributed runtime for Arkitekt apps.
An Arkitekt app is a declaration: the actions, states and hooks it offers. The declaration itself is arkitekt-spec's, and executing it locally is arkitekt-runtime's. rekuest adds what running it distributed takes:
- an agent that registers the declaration with a rekuest server over a websocket, is assigned tasks, and reports their progress, logs and results back;
- the caller through which one app's actions call other apps' actions via the server;
Rekuest, the GraphQL client for the server: find actions and implementations, call them, and watch their tasks.
You rarely import rekuest yourself. run(app) in arkitekt
uses it, and the names an app is written with (App, Task, the Annotated markers,
the policies) come from arkitekt.
Install
pip install "arkitekt[rekuest]" # what an app needs to run(app)
pip install rekuest # just the runtime and client
The optional extras are units (physical-quantity ports, via kanne) and types
(annotated-types constraints). rekuest requires Python 3.11+.
Offering actions
Declare the app with arkitekt and run it. run connects it through rekuest's provider,
which builds the agent and keeps it offering the app's actions until you stop it:
from arkitekt import App, Task, run
app = App("measure", "0.1.0")
@app.action
def double(x: int, task: Task) -> int:
"""Double
Doubles a number.
"""
task.log(f"doubling {x}")
return x * 2
if __name__ == "__main__":
run(app)
An app can also name the provider explicitly: App(..., providers=[rekuest_provider])
with from rekuest.arkitekt import rekuest_provider.
Calling actions
From a script, name the rekuest service and call an action by its id (or pass an
Action/Implementation you looked up). The call is a root task:
from arkitekt import easy
from rekuest.arkitekt import rekuest_service
with easy("my-script", rekuest_service) as rekuest:
result = rekuest.call("<action-id>", x=21)
Only a workflow may call other actions. A call made inside one is a child of the
task it runs in, so it goes through the task: resolve the target with the client, then
call it on the task. A plain @app.action that calls raises NotAWorkflowError, and
rekuest.acall inside a task raises RootOnlyCallError:
from arkitekt import App, Task
from rekuest.arkitekt import rekuest_service
from rekuest.client.client import Rekuest
app = App("orchestrate", "0.1.0", services=[rekuest_service])
@app.workflow
async def double_twice(x: int, action_id: str, task: Task, rekuest: Rekuest) -> int:
"""Double Twice"""
action = await rekuest.aresolve(action_id)
once = await task.acall(action, x=x)
return await task.acall(action, x=once)
Usually a workflow names what it needs of another app as a protocol instead
(@app.declare, see Agent dependencies) and calls its
methods; a method annotated as a generator streams the other action's yields.
Actions, implementations, shortcuts, test cases, test results and task events travel
between actions by id (@rekuest/action, @rekuest/implementation, …), so an action
can take and return them directly.
When an agent dies
Nothing is re-run behind your back.
- A plain task whose agent dies mid-run ends LOST: not failed, its fate unknown.
rekuest.callraisesAgentLostwith what is known (started,last_progress, and the action'seffects), and whoever called decides. Work that was never picked up is simply delivered again. - A workflow is resumed: it runs again from the top, but the calls it already made
return their recorded results, and
task.now(),task.random(),task.sleep()andtask.record(fn)return their recorded values. Inside it, a lost step raisesAgentLost, andtask.retry,task.holdandtask.guardcover the usual answers.
effects= on an action (NONE, REPEATABLE, UNKNOWN, IRREVERSIBLE) says what running it
again would do. It is information for whoever decides, never a rule the server acts on.
See Workflows.
Package layout
| Module | What it is |
|---|---|
rekuest.arkitekt |
The service (rekuest_service), the agent provider (rekuest_provider) and the @rekuest/* structures |
rekuest.agents |
The agent, its websocket transport, control channel and caller |
rekuest.client |
Rekuest, the GraphQL client, and its postman |
rekuest.api.schema |
The generated GraphQL operations and types |
rekuest.protocol |
The wire protocol the agent speaks with the server |
Guides
- Workflows — calling other actions, and what happens when an agent dies
- Agent dependencies — declare the actions and states an app depends on
- Disconnect policy — what happens to in-flight work when the agent loses its connection
- The agent journal — the ordered, persisted record of everything an agent reports
Development
uv sync # install dependencies
pytest -m "not integration" # fast unit tests
pytest -m integration # full integration tests (require Docker)
Integration tests spin up the rekuest stack with Docker Compose and exercise real
calls against it; see tests/conftest.py.
Learn more
License
GPL-3.0-or-later
Metadata
Release files for rekuest 7.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rekuest-7.1.0.tar.gz | 130.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rekuest-7.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 271.4 kB
Release files / rekuest-7.1.0.tar.gz
| Download URL | rekuest-7.1.0.tar.gz |
|---|---|
| Size | 130.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
92929cafeb824cbadfa6889e744bb0b89ed71c71782b8174fbe82216b44f8274
|
|
BLAKE2b-256 checksum How to use checksums |
8ed9cdee7a69669be1127e93cf8c9a5410f57ef2914734a4b35df3812988cb6a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / rekuest-7.1.0-py3-none-any.whl
| Download URL | rekuest-7.1.0-py3-none-any.whl |
|---|---|
| Size | 140.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
df5616fdfe8e0d089d7433a6c0fe064573583a911b032c018a3618a9af588661
|
|
BLAKE2b-256 checksum How to use checksums |
98ebd1f7fbf532163df65fac1d27fafa58a709467370fbb73efa848c3a00c948
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.21 {"installer":{"name":"uv","version":"0.12.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|