Metadata-Version: 2.4
Name: observable-code
Version: 0.2.0
Summary: Instant observability for developers shipping fast
Requires-Python: >=3.9
Requires-Dist: qrcode>=7.4
Requires-Dist: requests>=2.32
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=1.0; extra == 'dev'
Requires-Dist: pytest-cov>=6.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: responses>=0.25; extra == 'dev'
Description-Content-Type: text/markdown

# observable-code

**Did my thing run?** Add one decorator to a Python function and a real-time
`it ran ✓` / `it failed ✗` event appears on your phone — and on the web — within ~2 seconds.

Built for background jobs, webhooks, cron tasks, and AI-generated automation.
Deliberately *not* Datadog: instant, low-friction confidence, not deep telemetry.

```bash
pip install observable-code
```

## Quickstart

```python
import observable

@observable.track()
def nightly_job():
    ...  # your work

nightly_job()  # → "it ran ✓" on your phone
```

Pair your phone once with a QR scan:

```bash
observable setup        # renders a QR code; scan it in the mobile app
```

That's it. Every run of a tracked function now shows up live.

## The golden rule

**Tracking never blocks, delays, or crashes your function.** Dispatch is
fire-and-forget on a background thread with a short timeout; any error fails
silently to stderr. Your decorated function returns immediately (typically
<50 ms) even if the network is down or the server hangs.

## More

```python
@observable.track()
async def my_async_job(): ...        # works on async functions

with observable.track("data-import"): # works as a context manager
    ...

observable.trace("rows", 1240)        # attach metadata to the current event
observable.event("deploy-finished")   # standalone fire-and-forget event
```

## Production (env vars)

For deployed services, configure via environment instead of QR pairing:

```bash
export OBSERVABLE_CODE_API_KEY="obscode_sk_..."   # account-mode API key
# or OBSERVABLE_CODE_SESSION_ID="..."             # anonymous session id
export OBSERVABLE_CODE_API_URL="https://observable.codes"  # optional override
```

Credentials resolve in order: env var → config file (`~/.observable-code/config.json`).

CLI helpers: `observable show-key`, `observable status`, `observable pair`.

## Testing

Set `OBSERVABLE_TEST_MODE=1` to switch to synchronous posting for deterministic tests.

---

Requires Python ≥3.9. Canonical host: [observable.codes](https://observable.codes).
