Metadata-Version: 2.5
Name: arkitekt
Version: 4.2.1
Summary: client for the arkitekt platform
Author-email: jhnnsrs <jhnnsrs@gmail.com>
License-Expression: MIT
License-File: LICENSE
Requires-Python: <4,>=3.11
Requires-Dist: aiohttp>=3.9
Requires-Dist: arkitekt-spec>=1.3.2
Requires-Dist: click>=8.2.0
Requires-Dist: fakts>=4
Requires-Dist: koil>=3.3.4
Requires-Dist: platformdirs>=4.5.0
Requires-Dist: py-machineid>=0.8.1
Requires-Dist: pyyaml>=6.0.2
Requires-Dist: rath>=4
Requires-Dist: semver>=3.0.4
Requires-Dist: turms>=2.1.0
Requires-Dist: typer>=0.15.0
Requires-Dist: watchfiles>=1.0.5
Provides-Extra: all
Requires-Dist: alpaka>=3; extra == 'all'
Requires-Dist: elektro>=4.1; extra == 'all'
Requires-Dist: fluss>=4; extra == 'all'
Requires-Dist: kabinet>=4; extra == 'all'
Requires-Dist: kraph>=4; extra == 'all'
Requires-Dist: lovekit>=3; extra == 'all'
Requires-Dist: mikro>=6.1; extra == 'all'
Requires-Dist: rekuest>=6; extra == 'all'
Requires-Dist: unlok>=4; extra == 'all'
Provides-Extra: alpaka
Requires-Dist: alpaka>=3; extra == 'alpaka'
Provides-Extra: elektro
Requires-Dist: elektro>=4.1; extra == 'elektro'
Provides-Extra: fluss
Requires-Dist: fluss>=4; extra == 'fluss'
Provides-Extra: kabinet
Requires-Dist: kabinet>=4; extra == 'kabinet'
Provides-Extra: kraph
Requires-Dist: kraph>=4; extra == 'kraph'
Provides-Extra: lovekit
Requires-Dist: lovekit>=3; extra == 'lovekit'
Provides-Extra: mikro
Requires-Dist: mikro>=6.1; extra == 'mikro'
Provides-Extra: qt
Requires-Dist: arkitekt-runtime[qt]>=3.0.1; extra == 'qt'
Requires-Dist: qtpy>=2.4.3; extra == 'qt'
Provides-Extra: rekuest
Requires-Dist: rekuest>=6; extra == 'rekuest'
Provides-Extra: serve
Requires-Dist: arkitekt-fastapi>=1.0; extra == 'serve'
Provides-Extra: tqdm
Requires-Dist: tqdm>=4.66; extra == 'tqdm'
Provides-Extra: unlok
Requires-Dist: unlok>=4; extra == 'unlok'
Description-Content-Type: text/markdown

<p align="center">
  <h1 align="center">arkitekt</h1>
</p>

<p align="center">
  <em>Turn your Python functions into apps you can orchestrate, share, and scale.</em>
</p>

<p align="center">
  <a href="https://codecov.io/gh/jhnnsrs/arkitekt"><img src="https://codecov.io/gh/jhnnsrs/arkitekt/branch/master/graph/badge.svg?token=UGXEA2THBV" alt="codecov"></a>
  <a href="https://pypi.org/project/arkitekt/"><img src="https://badge.fury.io/py/arkitekt.svg" alt="PyPI version"></a>
  <a href="https://pypi.python.org/pypi/arkitekt/"><img src="https://img.shields.io/pypi/pyversions/arkitekt.svg" alt="PyPI pyversions"></a>
  <a href="https://arkitekt.live"><img src="https://img.shields.io/badge/docs-arkitekt.live-blue" alt="Documentation"></a>
</p>

---

## What is Arkitekt?

[**Arkitekt**](https://arkitekt.live) is an open platform for building, connecting, and orchestrating
computational apps. `arkitekt` is its Python client: it takes your ordinary Python functions and
exposes them as **remotely callable, orchestratable building blocks** — without you having to write
servers, APIs, message queues, or UIs.

Declare an app, run it, and its actions become available on an Arkitekt server where they can be:

- **Called** from anywhere — other apps, notebooks, scripts, or the web UI.
- **Composed** into real-time workflows that wire your functions together.
- **Given a GUI automatically**, generated from your Python type hints.
- **Shared** with your team behind central authentication and permissions.
- **Packaged and deployed** as a Docker container with a single command.

Arkitekt grew out of the needs of data-intensive science (it has first-class clients for microscopy,
electrophysiology and graph data), but the core is **domain-agnostic** — any Python workload fits.

> 📚 The best place to understand the platform and its concepts is the documentation at **[arkitekt.live](https://arkitekt.live)**.

## Installation

```bash
pip install "arkitekt[all]"
```

This installs the `arkitekt` command line interface, the runtime and every service client. Prefer a
lean install? The CLI and packaging tooling are always included — pick only the extras you need:

| Extra | Brings in |
| --- | --- |
| `rekuest` | the distributed runtime `run(app)` needs to offer actions |
| `mikro` | microscopy and imaging data |
| `elektro` | electrophysiology data and simulations |
| `kraph` | knowledge graphs and measurements |
| `fluss` | workflows, and the engine that runs them |
| `kabinet` | managing deployments of apps |
| `unlok` | users, clients, hubs and redeem tokens (lok) |
| `alpaka` | LLMs and chat |
| `lovekit` | WebRTC streams and rooms |
| `serve` | serving an app from a FastAPI application (arkitekt-fastapi) |
| `qt` | Qt integration (`arkitekt.qt`) |
| `tqdm` | a `tqdm` that reports progress to the running task |

```bash
pip install "arkitekt[rekuest,mikro]"
```

Declaring, inspecting and packaging an app, and calling services with `easy`, need no runtime; offering
actions with `run(app)` needs the `rekuest` extra. `arkitekt` requires **Python 3.11+**.

## Offering actions

An `App` is a declaration: its identifier, its version, and the actions it offers. Any function
decorated with `@app.action` becomes a callable building block on the platform. Its arguments and
return value are inferred from the type hints, which also drive validation, documentation and the
generated GUI. The first line of the docstring becomes the action's title, the rest its description.

```python
from typing import Annotated

from arkitekt import App, Description, run

app = App("hello", "0.1.0")


@app.action
def greet(
    name: Annotated[str, Description("Who to greet")] = "world",
    times: Annotated[int, Description("How often to say it")] = 1,
) -> str:
    """Greet

    Says hello.
    """
    return " ".join([f"Hello {name}!"] * times)


if __name__ == "__main__":
    run(app)
```

Nothing connects when the `App` is declared. `run(app)` authenticates (opening your browser the first
time), registers the actions and blocks until you stop it. The server is taken from `$FAKTS_URL`, or
passed explicitly with `run(app, url="localhost")`; `headless=True` prints a device code instead of
opening a browser.

### Using a service inside an action

Actions that need a service client name it in `services=` and take it by annotation — arkitekt injects
the client, just like the running `Task`:

```python
from arkitekt import App, Task, run
from mikro import Mikro, mikro_service
from mikro.arkitekt.specs import Volume

app = App("inspect-volume", "0.1.0", services=[mikro_service])


@app.action
def describe(volume: Volume, mikro: Mikro, task: Task) -> str:
    """Describe Volume"""
    task.progress(50, "Reading")
    return f"{volume.data.shape}"


if __name__ == "__main__":
    run(app)
```

Beyond actions, an app can declare `@app.model` result types, `@app.state` that the platform publishes
live, `@app.startup`/`@app.shutdown` hooks and `@app.background` tasks, and a typed app context
(`App(..., app_context=Setup)` together with `run(app, context=Setup(...))`). The
[examples](examples/README.md) show one each.

## Calling services

Scripts and notebooks that only *call* the platform don't declare actions. `easy` declares an app for
you, connects it, and hands back the clients of the services you name:

```python
from arkitekt import easy
from mikro import mikro_service

with easy("my-script", mikro_service) as mikro:
    folder = mikro.create_folder(name="examples")
```

Name several services and you get a tuple back, in the same order:

```python
from arkitekt import aeasy, interactive
from fluss import fluss_service
from mikro import mikro_service

async with aeasy("my-script", mikro_service, fluss_service) as (mikro, fluss):
    ...

# In Jupyter: connects once and stays connected.
mikro = interactive("notebook", mikro_service)
```

Every service client exposes each operation as a method, in a blocking and an `a`-prefixed async
flavour (`mikro.create_folder(...)`, `await mikro.acreate_folder(...)`).

## The CLI

`arkitekt` is the command line for building, running and packaging apps. Standing up an Arkitekt
server is the job of [konstruktor](https://github.com/arkitektio/konstruktor).

| Command | What it does |
| --- | --- |
| `init` | Scaffold an app: an entrypoint file that declares it. There is no separate manifest. |
| `run dev` · `run prod` | Run the app — with hot reloading while you develop, or as it runs in a container. |
| `gen` | Generate typed clients. |
| `inspect` | Show what the app would register, without connecting. |
| `call` | Call an action of the app. |
| `plugin` | Containerize the app into flavours and publish it as a deployable plugin. |
| `mesh` | Join this machine to the deployment's private WireGuard mesh. |
| `self` | Manage your install — upgrade the SDK, print versions, dump diagnostics. |

```bash
mkdir my-app && cd my-app
arkitekt init          # scaffold an app
arkitekt run dev       # run it with hot reloading
```

See the full reference in **[docs/cli.md](docs/cli.md)**, and
[docs/app_types.md](docs/app_types.md) for choosing between a standalone and a plugin app.

## Working with data

Arkitekt serializes and documents standard Python types — `str`, `bool`, `int`, `float`, `Enum`,
`list`, `dict`, and pydantic models or dataclasses declared with `@app.model`. For heavier data
(images, arrays, large objects), the platform follows a **store-by-reference** model: data lives in a
central, scalable store and only a lightweight reference travels between apps. Service clients like
`mikro` and `elektro` provide ready-made structures for this; within one app,
`app.memory_structure(...)` lets arbitrary objects cross actions without leaving the agent.

## Examples

[`examples/`](examples/README.md) holds small, self-contained scripts — one per thing an app can do.
Each declares its dependencies in a PEP 723 header, so there is nothing to install:

```bash
uv run --script examples/hello.py
```

## Documentation & links

- 📚 **Documentation:** [arkitekt.live](https://arkitekt.live)
- 🧰 **CLI reference:** [docs/cli.md](docs/cli.md)
- 📦 **PyPI:** [pypi.org/project/arkitekt](https://pypi.org/project/arkitekt/)
- 🐙 **Source:** [github.com/jhnnsrs/arkitekt](https://github.com/jhnnsrs/arkitekt)

## License

`arkitekt` is released under the [MIT License](LICENSE).
