# EnterSense Python SDK

A typed, synchronous v1 intent client with zero runtime dependencies for Python 3.11+. Install the versioned SDK archive from the website. Source-archive installation builds the package with setuptools; registry publication is separate.

```sh
python -m pip install ./entersense_sdk-0.1.1.tar.gz
```

```python
from entersense import EnterSenseClient

client = EnterSenseClient(base_url="https://YOUR-API-HOST", timeout=5)
client.register_handler(
    "navigation.open", lambda action, intent: print(action["target"])
)
request = {
    "input": {"sense": "voice", "transcript": "open home"},
    "rules": [
        {
            "id": "home",
            "match": "open home",
            "action": {"type": "navigation.open", "target": "/"},
        }
    ],
}
resolution = client.resolve(request)  # Returns intents and performs no action.
executed = client.resolve_and_dispatch(request)  # Explicit application handlers.
```

Methods are `capabilities()`, `actions()`, `templates()`, `validate(request)`, and `resolve(request)`. `templates()` supplies editable requests. `register_handler(type, fn)` and `unregister_handler(type)` configure application-owned action behavior. `dispatch(resolution)` is explicit. Handlers are synchronous and receive the action and intent. Missing handlers are checked before any dispatch; handler failure stops later handlers without retry or rollback of completed effects.

## Transport and cancellation

`base_url` is required; an HTTP(S) proxy prefix is supported. Embedded credentials, queries and fragments are rejected. Default timeout is 10 seconds. Requests identify the SDK with its installed package version; uninstalled source uses an unversioned EnterSense SDK identifier. A transport can be injected with the signature `(method, url, JSON_body_or_None, timeout_seconds) -> (HTTP_status, decoded_JSON)`.

Optional method argument `cancel_event` accepts a `threading.Event`. The client checks it before sending and while waiting, then prevents handler dispatch after cancellation. The default urllib adapter performs bounded I/O in a daemon worker. A deadline or cancellation stops client waiting; an already-started HTTP request may finish in that worker. It cannot be unsent, and no handler executes from an abandoned response. Injected transports must likewise bound their own I/O. No automatic retry or redirect is performed.

Typed exceptions distinguish API rejection (`status`, server `code`), timeout, cancellation, transport/invalid response, missing handler and handler failure. The client does not print request bodies, secrets or credential-bearing URLs.

## Response validation

Catalog entries and template requests are validated before being returned. Invalid action payloads are rejected before registered handlers execute, including external navigation, invalid identifiers, unknown action fields and oversized UTF-8 payloads. Optional `confidence` and `minConfidence` accept both omission and JSON `null` (`None`), matching the generated API and templates. Applications still own authorization and the safety of handler side effects.

## Declarative actions

Supported types are `navigation.open`, `text.insert`, `media.play`, `media.pause`, `scene.focus`, and `workflow.trigger`. Workflow parameters are bounded string maps. Configure optional `enabled`/`minConfidence` on rules and adapter-supplied `confidence` on inputs. Replace voice input with `{"sense":"motion","gesture":"swipe_left"}` for normalized motion rules. No microphone/camera acquisition, recognition, shell execution or server HTTP relay is built in.

Voice production and motion beta describe founder-reported product stages, not certified hardware or recognition performance. Remaining senses explicitly return HTTP 422 `sense_unavailable`. Tests of this client do not validate a physical sensor or commercial integration.

## Development

```sh
PYTHONPATH=sdk/python/src python3 -m unittest discover -s sdk/python/tests
python3 -m compileall -q sdk/python/src
cd sdk/python
python3 -m venv .venv
.venv/bin/pip install -e '.[dev]'
.venv/bin/ruff check .
.venv/bin/ruff format --check .
.venv/bin/python -m build --no-isolation
```

The project is `entersense-sdk` version `0.1.1`; import package `entersense` includes `py.typed`. Framework-independent typed contracts/handler dispatch use an injected transport; urllib is the default adapter. The shared Rust API generates authoritative OpenAPI and catalogs. [SOURCES.md](SOURCES.md) records versions, official references and evidence boundaries.

## License

License terms have not yet been published. Public downloads do not grant an open-source license; the source repository remains private.
