Metadata-Version: 2.4
Name: flyte
Version: 2.5.1
Summary: Add your description here
Author-email: Flyte Contributors <admin@flyte.org>
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: aiofiles>=24.1.0
Requires-Dist: click>=8.2.1
Requires-Dist: cloudpickle>=3.1.1
Requires-Dist: docstring_parser>=0.16
Requires-Dist: fsspec>=2025.3.0
Requires-Dist: connectrpc<1.0.0,>=0.9.0
Requires-Dist: obstore>=0.7.3
Requires-Dist: protobuf>=6.30.1
Requires-Dist: pydantic>=2.10.6
Requires-Dist: pyyaml>=6.0.2
Requires-Dist: rich-click==1.8.9
Requires-Dist: httpx<1.0.0,>=0.28.1
Requires-Dist: keyring>=25.6.0
Requires-Dist: msgpack>=1.1.0
Requires-Dist: toml>=0.10.2
Requires-Dist: async-lru>=2.0.5
Requires-Dist: mashumaro
Requires-Dist: aiolimiter>=1.2.1
Requires-Dist: flyteidl2==2.0.23
Requires-Dist: packaging
Requires-Dist: sentry-sdk>=2.0
Requires-Dist: pyOpenSSL>=24.0.0
Provides-Extra: aiosqlite
Requires-Dist: aiosqlite>=0.21.0; extra == "aiosqlite"
Provides-Extra: connector
Requires-Dist: grpcio>=1.71.0; extra == "connector"
Requires-Dist: grpcio-health-checking; extra == "connector"
Requires-Dist: httpx; extra == "connector"
Requires-Dist: prometheus-client; extra == "connector"
Provides-Extra: examples-test
Requires-Dist: polyglot-hello>=0.1.3; extra == "examples-test"
Requires-Dist: pandas; extra == "examples-test"
Requires-Dist: pyarrow; extra == "examples-test"
Requires-Dist: scikit-learn; extra == "examples-test"
Requires-Dist: joblib; extra == "examples-test"
Requires-Dist: nest-asyncio; extra == "examples-test"
Requires-Dist: deltalake; extra == "examples-test"
Requires-Dist: fastapi; extra == "examples-test"
Requires-Dist: uvicorn; extra == "examples-test"
Requires-Dist: lightning; extra == "examples-test"
Provides-Extra: sandbox
Requires-Dist: pydantic-monty==0.0.17; extra == "sandbox"
Provides-Extra: mcp
Requires-Dist: mcp>=1.26.0; extra == "mcp"
Requires-Dist: starlette; extra == "mcp"
Requires-Dist: uvicorn; extra == "mcp"
Provides-Extra: tui
Requires-Dist: textual>=0.80; extra == "tui"
Provides-Extra: rust-controller
Requires-Dist: flyte_controller_base==2.5.1; extra == "rust-controller"
Dynamic: license-file

> [!IMPORTANT]
> ## Flyte 2 Devbox is now available!
>
> Check out the guide [here](https://www.union.ai/docs/v2/flyte/user-guide/run-modes/running-devbox/) to get started.

---

# Flyte 2 SDK

**Reliably orchestrate ML pipelines, models, and agents at scale — in pure Python.**

[![Version](https://img.shields.io/pypi/v/flyte?label=version&color=blue)](https://pypi.org/project/flyte/)
[![Python](https://img.shields.io/pypi/pyversions/flyte?color=brightgreen)](https://pypi.org/project/flyte/)
[![License](https://img.shields.io/badge/license-Apache%202.0-orange)](LICENSE)
[![Try in Browser](https://img.shields.io/badge/Try%20in%20Browser-Live%20Demo-7652a2)](https://flyte2intro.apps.demo.hosted.unionai.cloud/)
[![Docs](https://img.shields.io/badge/Docs-flyte-blue)](https://www.union.ai/docs/v2/flyte/user-guide/running-locally/)
[![SDK Reference](https://img.shields.io/badge/SDK%20Reference-API-brightgreen)](https://www.union.ai/docs/v2/union/api-reference/flyte-sdk/)
[![CLI Reference](https://img.shields.io/badge/CLI%20Reference-API-brightgreen)](https://www.union.ai/docs/v2/union/api-reference/flyte-cli/)

## Install

```bash
pip install flyte
```

## Example

Create a file called `flyte_intro.py` with the following content:

```python
import asyncio
import flyte

env = flyte.TaskEnvironment(
    name="hello_world",
    image=flyte.Image.from_debian_base(python_version=(3, 12)),
)

@env.task(retries=3, cache="auto")  # 👈 add retries and caching
async def predict(x: int) -> int:
    return 2 * x + 5

@env.task
async def main(data: list[int]) -> float:
    xs = await asyncio.gather(*(predict(x) for x in data))
    return sum(xs) / len(xs)
```

<table>
<tr><td><b>Python</b></td><td><b>Flyte CLI</b></td></tr>
<tr>
<td>

```bash
python flyte_intro.py
```

</td>
<td>

```bash
flyte run flyte_intro.py main --data '[1,2,3]'
```

</td>
</tr>
</table>

<details>

<summary>ℹ️ Synchronous Python</summary>

<br>

Flyte 2 also supports synchronous python, although async is recommended for
more control over concurrency and parallelism.

```python
@env.task
def predict(x: int) -> int:
    return 2 * x + 5

@env.task
def main(data: list[int]) -> float:
    xs = list(flyte.map(predict, data))
    return sum(xs) / len(xs)
```

</details>

## Serve a Model

```python
# serving.py
from fastapi import FastAPI
import flyte
from flyte.app.extras import FastAPIAppEnvironment

app = FastAPI()
env = FastAPIAppEnvironment(
    name="my-model",
    app=app,
    image=flyte.Image.from_debian_base(python_version=(3, 12)).with_pip_packages(
        "fastapi", "uvicorn"
    ),
)

@app.get("/predict")
async def predict(x: float) -> dict:
    return {"result": x * 2 + 5}

if __name__ == "__main__":
    flyte.init_from_config()
    flyte.serve(env)
```

<table>
<tr><td><b>Python</b></td><td><b>Flyte CLI</b></td></tr>
<tr>
<td>

```bash
python serving.py
```

</td>
<td>

```bash
flyte serve serving.py env
```

</td>
</tr>
</table>

### Local Development Experience

Install the TUI for a rich local development experience:

```bash
pip install flyte[tui]
```

Run `flyte_intro.py` on the TUI:

```bash
flyte run --tui --local flyte_intro.py main --data '[1,2,3]'
```

<img src="static/flyte-tui.gif" alt="Flyte TUI">

### Flyte Devbox

Flyte Devbox is a docker- and k3s-based local development environment for Flyte.
It allows you to run Flyte workflows and services locally.

```bash
flyte start devbox
```

Create the configuration file for the devbox:

```bash
flyte create config \
    --endpoint localhost:30080 \
    --project flytesnacks \
    --domain development \
    --builder local \
    --insecure
```

Run on the devbox:

```bash
flyte run flyte_intro.py main --data '[1,2,3]'
```

<img src="static/flyte-start-devbox.png" alt="Flyte Start Devbox">

<img src="static/flyte-hello-world.gif" alt="Flyte Hello World">

## Rust Controller (experimental)

<details>

<summary>Developer Guide</summary>

<br>

The Rust controller is an alternative implementation of the remote controller written in Rust and exposed
to Python via maturin / pyo3. Distributed as a separate `flyte_controller_base` wheel so the main SDK does
not need to switch its build toolchain to rust/maturin. Keep important dependencies (notably `flyteidl2`)
in lockstep between `pyproject.toml`, `rs_controller/pyproject.toml`, and `rs_controller/Cargo.toml`.

### Installing the Rust controller


`flyte_controller_base` is an **optional** dependency — `pip install flyte` does not pull it in
automatically. The default Flyte task image (as of #1083) bundles the Rust controller, so tasks
running on the default image work out of the box. You only need the extra when:

- running locally (e.g. `flyte run --local examples/basics/hello_v2.py`), or
- bringing your own task image.

```bash
pip install flyte[rust-controller]
```


### Running with the Rust controller

The Rust controller is gated behind an env var. Set it to `1` (also accepts `true` / `yes`):

```bash
_F_USE_RUST_CONTROLLER=1 python examples/basics/hello_v2.py
```

The driver propagates this env var to all sub-task pods, so both the driver and child actions use the
Rust controller for that run.

> The Rust controller is currently under rapid development and contains gaps: abort RPC on cancel,
> `Code.ABORTED` fast-fail, tunable retries / QPS, graceful `stop()`. See PR #675.

> Dev iteration requires the local image builder. The `flyte_controller_base` wheel is not
> on PyPI until release, and the remote image builder installs all wheels in a layer at once,
> so it cannot resolve `flyte_controller_base` from a sibling layer. Use the local image
> builder while developing the Rust controller:
>
> ```yaml
> # .flyte/config.yaml
> image:
>   builder: local
> ```

### Developing the Rust controller

#### One-time setup

Build the manylinux builder images. They are cached, so you only need to rebuild them when the
build tooling itself changes:

```bash
cd rs_controller
make build-builders
cd ..
```

#### Iteration loop

After every Rust change, run the all-in-one dev target from the repo root:

```bash
REGISTRY=<your-registry> make dev-rs-dist
```

`dev-rs-dist` does four things:

1. `cd rs_controller && make build-wheels` — build manylinux x86_64 + aarch64 wheels (use
   `make build-wheel-local` if you only need a macOS wheel for the driver).
2. `make dist` — build the main `flyte` SDK wheel.
3. `uv run python maint_tools/build_default_image.py --registry $(REGISTRY)` — build the default
   image with both wheels baked in and push it to your registry.
4. `uv pip install --find-links ./rs_controller/dist --no-index --force-reinstall --no-deps flyte_controller_base` —
   refresh the wheel in your local venv so the driver picks up the new build.

After this, any `flyte.TaskEnvironment` that does not pass an explicit `image=` will resolve to the default
debian image and automatically have the Rust wheel layered in. If you do pass an explicit `image=`, the
auto-bake is skipped; in that case, chain `.with_local_rs_controller()` onto the image to bake the Rust wheel
manually.

If you only changed Python (not Rust), you can skip the wheel rebuild and just run `make dist` plus
the rebuild image step. The Rust wheel is reused.

### Build configuration summary

The Rust crate ships with two cargo features so the same project can produce a Rust rlib and a
Python extension wheel:

```toml
[features]
default = ["pyo3/auto-initialize"]            # Rust crate users; links libpython
extension-module = ["pyo3/extension-module"]  # Python wheels; no libpython linking

[lib]
crate-type = ["rlib", "cdylib"]               # Both Rust and Python usage
```

- `pyo3/auto-initialize` embeds Python into Rust (works locally on macOS, fails inside the manylinux
  builder because libpython is unavailable there).
- `pyo3/extension-module` extends Python with Rust (must not link libpython for portable wheels).

So local `cargo run --bin <name>` uses `default` features, and the manylinux builder explicitly
disables defaults and turns on `extension-module`:

```toml
# rs_controller/pyproject.toml
[tool.maturin]
no-default-features = true
features = ["extension-module"]
```

</details>

## Learn More

- **[Live Demo](https://flyte2intro.apps.demo.hosted.unionai.cloud/)** — Try Flyte 2 in your browser
- **[Documentation](https://www.union.ai/docs/v2/flyte/user-guide/running-locally/)** — Get started running locally
- **[SDK Reference](https://www.union.ai/docs/v2/union/api-reference/flyte-sdk/)** — API reference docs
- **[CLI Reference](https://www.union.ai/docs/v2/union/api-reference/flyte-cli/)** — CLI docs
- **[Join the Flyte 2 Production Preview](https://www.union.ai/try-flyte-2)** — Get early access
- **[Features](FEATURES.md)** — Async parallelism, app serving, tracing, and more
- **[Examples](examples/)** — Ready-to-run examples for every feature
- **[Contributing](CONTRIBUTING.md)** — Set up a dev environment and contribute
- **[Slack](https://slack.flyte.org/)** | **[GitHub Discussions](https://github.com/flyteorg/flyte/discussions)** | **[Issues](https://github.com/flyteorg/flyte/issues)**

## License

Flyte 2 is licensed under the [Apache 2.0 License](LICENSE).
