Skip to main content

rekuest

codecov PyPI version PyPI pyversions

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.call raises AgentLost with what is known (started, last_progress, and the action's effects), 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() and task.record(fn) return their recorded values. Inside it, a lost step raises AgentLost, and task.retry, task.hold and task.guard cover 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 8.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rekuest 8.0.1
File Size Uploaded
rekuest-8.0.1.tar.gz 133.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for rekuest 8.0.1
File Interpreter ABI Platform
rekuest-8.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 277.0 kB

Release files / rekuest-8.0.1.tar.gz

Download URL rekuest-8.0.1.tar.gz
Size 133.6 kB
Tags Source
SHA-256 checksum
How to use checksums
687811d83c58f3c34cc71e73d35043649fa6d8472d1f4f6003f4813cc26f724c
BLAKE2b-256 checksum
How to use checksums
3f2f70871b92408eb61a2abf2585e702f78c2ea7ce6c41e2f57dd4a487433b3a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","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-8.0.1-py3-none-any.whl

Download URL rekuest-8.0.1-py3-none-any.whl
Size 143.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9366362bac94ce72c8e205e9cac918707f405a15f392fe7bf85f8fffef2f4de8
BLAKE2b-256 checksum
How to use checksums
60e56c6a3869167c91ed47d70195e46ea36793404732f8ee3cc33031fb2174e2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","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 history Release notifications | RSS feed

8.3.0

2 release files

8.2.0

2 release files

8.1.0

2 release files

This release

8.0.1 This release

2 release files

8.0.0

2 release files

7.1.0

2 release files

7.0.0

2 release files

6.1.0

2 release files

6.0.1

2 release files

6.0.0

2 release files

5.1.1

2 release files

5.1.0

2 release files

5.0.0

2 release files

4.0.0

2 release files

3.0.2

2 release files

3.0.1

2 release files

3.0.0

2 release files

0.2.27

2 release files

0.2.26

2 release files

0.2.25

2 release files

0.2.23

2 release files

0.2.22

2 release files

0.2.21

2 release files

0.2.20

2 release files

0.2.19

2 release files

0.2.18

2 release files

0.2.17

2 release files

0.2.16

2 release files

0.2.15

2 release files

0.2.14

2 release files

0.2.13

2 release files

0.2.12

2 release files

0.2.11

2 release files

0.2.10

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.5

2 release files

0.2.3

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.53

2 release files

0.1.52

2 release files

0.1.49

2 release files

0.1.45

2 release files

0.1.44

2 release files

0.1.43

2 release files

0.1.42

2 release files

0.1.41

2 release files

0.1.40

2 release files

0.1.39

2 release files

0.1.38

2 release files

0.1.37

2 release files

0.1.36

2 release files

0.1.35

2 release files

0.1.34

2 release files

0.1.30

2 release files

0.1.29

2 release files

0.1.22

2 release files

0.1.19

2 release files

0.1.18

2 release files

0.1.17

2 release files

0.1.16

2 release files

0.1.15

2 release files

0.1.14

2 release files

0.1.13

2 release files

0.1.12

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.0.22

2 release files

0.0.21

2 release files

0.0.20

2 release files

0.0.19

2 release files

0.0.18

2 release files

0.0.17

2 release files

0.0.14

2 release files

0.0.13

2 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.8

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page