Metadata-Version: 2.4
Name: runbound-application-context
Version: 0.1.0a1
Summary: Runbound application context for Python: operation-scoped application user and release attribution, shared by the Runbound Runtime and Telemetry packages.
Author: Runbound
License-Expression: LicenseRef-Runbound-Runtime-SDK
Project-URL: Homepage, https://github.com/runbound-io/runtime/tree/main/shared/application-context/python#readme
Project-URL: Repository, https://github.com/runbound-io/runtime
Project-URL: Issues, https://github.com/runbound-io/runtime/issues
Project-URL: Changelog, https://github.com/runbound-io/runtime/blob/main/shared/application-context/python/CHANGELOG.md
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Typing :: Typed
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# runbound-application-context

Attribute each operation in a Python process to your application's user and
release. A scope follows threads and asyncio tasks, and restores its parent
when it exits.

## About Runbound

Runbound runs workloads under policy and records what happened as evidence.
This package holds the application attribution Runbound's Python packages
share, so a scope opened through one is seen by all of them.

## Install

```sh
python -m pip install --pre runbound-application-context
```

`--pre` selects the alpha. `runbound-runtime` and `runbound-telemetry` install
it for you, at the exact version they need.

## Alpha limits

`0.1.0a1` is an early, unsupported alpha. APIs may change between alpha
releases.

- **Python 3.11 or later.** It is tested on CPython 3.11 to 3.14.
- **Pure Python, standard library only.** It installs on any platform.
- **Cloud mode is not yet available.** Captured observations withhold the
  application user locally; only an authenticated Runbound Cloud delivery may
  record one.

## Quickstart

This runs entirely in your process. Save it as `scopes.py`:

```python
import asyncio

from runbound_application_context import application_scope, current, initialize_release

initialize_release("1.4.2")


async def handle(user_id):
    with application_scope(application_user_id=user_id):
        await asyncio.sleep(0)
        snapshot = current()
        print(f"{snapshot.application_user_id} on {snapshot.release_id}")


async def main():
    await asyncio.gather(handle("alice"), handle("bob"))
    print(f"outside: {current().application_user_id} on {current().release_id}")


asyncio.run(main())
```

```sh
python scopes.py
```

Expected output:

```text
alice on 1.4.2
bob on 1.4.2
outside: None on 1.4.2
```

Each task sees only its own scope, and leaving the scope restores the one
outside it, even when the work inside raises or is cancelled.

## API

| API | Purpose |
| --- | --- |
| `initialize_release(release_id)` | Set the release every operation defaults to; a conflicting second release raises `ValueError`. |
| `application_scope(application_user_id=..., release_id=...)` | A context manager that attributes the operations inside it; `None` clears a field. |
| `current()` | The `Snapshot` in effect: `application_user_id` and `release_id`. |
| `capture()` | The snapshot a recorded observation may carry; without authenticated Cloud delivery it withholds the user. |
| `handoff(snapshot)` | A context manager that makes a snapshot current, for a task you detach deliberately. |

A user ID is attribution only. It is never authentication, tenancy or
authorization, and trace headers, baggage and environment variables never set
one. Call `application_scope` after your application has resolved its own
user. A task started in an empty `contextvars.Context` begins with no scope;
pass it a snapshot through `handoff` only when you mean to.

## Network access

This package makes no network connections and no disk reads or writes.
Scopes and snapshots live in memory in your process.

## What it does not do

It records nothing by itself and sends nothing anywhere: it holds the
attribution that other Runbound packages read when they record an
observation.

## Upgrade and uninstall

Keep it at the version your Runbound packages require; they pin it exactly,
and pip upgrades it with them. To uninstall, remove the packages that depend
on it, then run `python -m pip uninstall runbound-application-context`.

Source: [runbound-io/runtime](https://github.com/runbound-io/runtime/tree/main/shared/application-context/python).
Runbound software is proprietary under the Runbound Runtime and SDK Licence in this package's `LICENSE` file. The licence permits use in your own commercial and internal applications and distribution as an application dependency; it does not permit standalone redistribution. Cloud-required features need the appropriate Runbound service entitlement. Source is intended to be public for inspection and contributions through GitHub issues and pull requests; follow the repository contribution terms. The package bundles no third-party software; changes are in
[CHANGELOG.md](https://github.com/runbound-io/runtime/blob/main/shared/application-context/python/CHANGELOG.md).
