Metadata-Version: 2.5
Name: stanterprise-protobuf
Version: 0.1.3
Summary: Generated Python code for the stanterprise test system protobuf schemas
Project-URL: Repository, https://github.com/stanterprise/proto-python
Author: Stanislav Fedii
License: MIT
License-File: LICENSE
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: betterproto==2.0.0b7
Requires-Dist: grpclib>=0.4.7
Description-Content-Type: text/markdown

# proto-python

Generated Python code for the [stanterprise test system protobuf schemas](https://github.com/stanterprise/protobuf).
This is the Python counterpart of [proto-ts](https://github.com/stanterprise/proto-ts).

Code is generated with [betterproto](https://github.com/danielgtaylor/python-betterproto): messages
are `dataclass`es, timestamps and durations map to `datetime`/`timedelta`, and gRPC services are
async (`grpclib`).

## Install

```bash
pip install stanterprise-protobuf
```

## Usage

Messages mirror the proto package structure:

```python
from datetime import datetime, timedelta, timezone

from testsystem.v1.common import TestStatus
from testsystem.v1.entities import SuiteType, TestCaseRun, TestSuiteRun
from testsystem.v1.events import SuiteBeginEventRequest

suite = TestSuiteRun(
    id="suite-1",
    name="Checkout",
    run_id="run-1",
    type=SuiteType.PROJECT,
    status=TestStatus.RUNNING,
    start_time=datetime.now(timezone.utc),
    duration=timedelta(seconds=42),
    test_cases=[TestCaseRun(id="case-1", name="adds item to cart", status=TestStatus.PASSED)],
)

payload = bytes(SuiteBeginEventRequest(suite=suite))
decoded = SuiteBeginEventRequest().parse(payload)
```

### gRPC client

```python
from grpclib.client import Channel

from testsystem.v1.events import HeartbeatEventRequest
from testsystem.v1.observer import TestEventCollectorStub

async with Channel("localhost", 50051) as channel:
    stub = TestEventCollectorStub(channel)
    ack = await stub.heartbeat(HeartbeatEventRequest(source_id="worker-0"))
```

### gRPC server

```python
from grpclib.server import Server

from testsystem.v1.observer import AckResponse, TestEventCollectorBase


class Collector(TestEventCollectorBase):
    async def heartbeat(self, message):
        return AckResponse(success=True)
    # ... implement the remaining RPCs

server = Server([Collector()])
await server.start("0.0.0.0", 50051)
```

## Available packages

| Import                   | Contents                                                          |
| ------------------------ | ----------------------------------------------------------------- |
| `testsystem.v1.common`   | `TestStatus`, `Attachment`                                        |
| `testsystem.v1.entities` | `TestCaseRun`, `StepRun`, `TestSuiteRun`, `SuiteType`             |
| `testsystem.v1.events`   | all `*EventRequest` messages                                      |
| `testsystem.v1.observer` | `AckResponse`, `TestEventCollectorStub`, `TestEventCollectorBase` |

## Development

The `.proto` files come from the `protobuf` git submodule, and the generated code under `src/testsystem`
is committed so consumers and CI never need `protoc`.

```bash
git submodule update --init --recursive
make venv        # uv sync
make generate    # regenerate src/testsystem from protobuf/
make lint typecheck test
make build       # sdist + wheel into dist/
make verify      # fails if committed generated code is stale
```

### Updating the schema

1. Bump the `protobuf` submodule to the desired tag and commit the new pointer.
2. Run `make generate` and commit the regenerated `src/testsystem`.
3. Bump `version` in `pyproject.toml`.

### Releasing

Push a `vX.Y.Z` tag matching `pyproject.toml`. The publish workflow verifies the match, regenerates,
tests, builds, and publishes to PyPI via trusted publishing (no API token required — add
`proto-python` / `publish.yml` as a trusted publisher on PyPI first). If you configure the publisher
with an environment name, create a matching GitHub environment and add `environment: <name>` to the
publish job.
