Metadata-Version: 2.4
Name: openlatch-tool-sdk
Version: 1.0.0
Summary: OpenLatch detection-tool SDK — Standard Webhooks v1 verify/sign + FastAPI decorator.
Project-URL: Homepage, https://openlatch.ai
Project-URL: Repository, https://github.com/OpenLatch/openlatch-provider
Author-email: OpenLatch <hello@openlatch.ai>
License: Apache-2.0
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.11
Requires-Dist: cryptography>=42
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.6
Provides-Extra: dev
Requires-Dist: fastapi>=0.115; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Provides-Extra: fastapi
Requires-Dist: fastapi>=0.115; extra == 'fastapi'
Description-Content-Type: text/markdown

# openlatch-tool-sdk

Standard Webhooks v1 verify/sign + FastAPI decorator for OpenLatch
detection tools (Python). Pairs with `openlatch-provider listen` (HMAC
verification happens there) or stands on its own when the tool server is
exposed publicly.

## Install

```bash
pip install 'openlatch-tool-sdk[fastapi]'
```

## FastAPI

```python
from openlatch_tool_sdk import CloudEvent, Verdict, tool
from fastapi import FastAPI

app = FastAPI()

@tool(app, path="/event", secret=None)  # secret=os.environ["OPENLATCH_WHSEC"] for standalone
async def detect(event: CloudEvent) -> Verdict:
    text = str((event.tool_call.input if event.tool_call else None) or {})
    if "AKIA" in text:
        return Verdict(
            risk_score=99,
            severity_hint="critical",
            verdict_hint="deny",
            rule_id="aws.access_key",
            rationale_summary="AWS access key detected",
        )
    return Verdict(risk_score=5, severity_hint="low", verdict_hint="allow")
```

## Direct API

```python
from openlatch_tool_sdk import compute_signature, sign_response, verify
```

## Verdict shape

Pydantic models are configured with `alias_generator=to_camel`, so wire
JSON uses camelCase (`riskScore`, `severityHint`, …) per
`provider-call.schema.json`, while Python code uses snake_case naturally.

## Cross-impl HMAC parity

Test fixtures and signed outputs are byte-identical between this SDK,
`@openlatch/tool-sdk` (npm), and `runtime/webhook.rs` in the
`openlatch-provider` Rust binary. The same `whsec_<base64>` secret +
`<id>.<timestamp>.<raw-body>` payload + base64(HMAC-SHA256) framing is
used by all three.

## Releases

`openlatch-tool-sdk` is released in lock-step with `openlatch-provider`
via release-please. Land conventional-commit PRs against `main`;
release-please opens a Release PR bumping all three packages
(`openlatch-provider` on crates.io + npm, `openlatch-tool-sdk` on PyPI,
`@openlatch/tool-sdk` on npm). Merging the Release PR creates a `v*`
tag and the unified `publish.yml` workflow publishes everything via
OIDC trusted publishing.
