Metadata-Version: 2.4
Name: subpoena
Version: 0.1.0a1
Summary: Trace-native testing: OpenTelemetry spans as the test interface, enforcement proven by an independent witness.
License: Apache-2.0
Project-URL: Homepage, https://subpoena.dev
Project-URL: Source, https://github.com/sprigworks/subpoena
Project-URL: Documentation, https://github.com/sprigworks/subpoena/blob/main/python/README.md
Project-URL: Changelog, https://github.com/sprigworks/subpoena/blob/main/CHANGELOG.md
Keywords: opentelemetry,testing,tracing,traceql,observability
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: System :: Monitoring
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: opentelemetry-api<2,>=1.27
Requires-Dist: opentelemetry-sdk<2,>=1.27
Provides-Extra: test
Requires-Dist: pytest>=8; extra == "test"
Requires-Dist: pyyaml>=6; extra == "test"
Dynamic: license-file

# Subpoena for Python

The Python port of Subpoena's tier-1 harness. It meets the contract in
[docs/ports.md](https://github.com/sprigworks/subpoena/blob/main/docs/ports.md), checked the same way as the Go reference.

| Part | Module | Checked by |
| --- | --- | --- |
| Harness (H1–H6) | `subpoena.harness` | [`conformance/harness.yaml`](https://github.com/sprigworks/subpoena/blob/main/conformance/harness.yaml), all cases |
| TraceQL subset (Q1–Q3) | `subpoena.traceql`, native, no Go needed | the whole corpus in `tests/test_traceql.py`, and `subpoena-conform` over `python -m subpoena.traceql`: 139 cases, 0 mismatches |
| Witness file (W3) | `subpoena.witness` | the `witness.ReadLog` cases (`tests/test_witness.py`) |
| Generated names | generated by Weaver from your registry, like [the example](https://github.com/sprigworks/subpoena/blob/main/generated/python/semconv.py) | `pkg/production/languages_test.go` |
| Lint (L1), cross-examination (G1) | not yet | — |

```python
from subpoena.harness import Harness, require_absent, require_exists

def test_denied_session_never_execs():
    h = Harness()
    gateway = Gateway(tracer_provider=h.tracer_provider)  # inject; never install another provider
    gateway.handle(denied_request)
    tr = h.collect()                                        # before any assertion
    require_absent(tr, NO_EXEC_AFTER_DENY)                  # Inconclusive fails, too
```

`collect()` raises `IncompleteError` (carrying the snapshot) if a span was
dropped or never ended. Absence on an incomplete snapshot is Inconclusive, and
`require_absent` fails on it unless `allow_inconclusive=True` is passed.

```
pip install subpoena
```

Python 3.9+; depends on `opentelemetry-api` and `opentelemetry-sdk` only.
Alpha: APIs will change.

## Development

From a checkout of [github.com/sprigworks/subpoena](https://github.com/sprigworks/subpoena):

```
make python        # venv (uv), pytest, subpoena-conform
```

CI runs Python 3.9 and 3.12.

## Releasing

Bump `version` in `pyproject.toml`, merge, then push a tag `python/v<version>`
(for example `python/v0.1.0a1`) to GitHub and Buzz. The `publish-python`
workflow reruns the port checks, builds, and uploads to PyPI through Trusted
Publishing; no token is involved.
