Skip to content

Commit 71d43f8

Browse files
dcjclaude
andcommitted
Add CONTRIBUTING.md and README contributing section
Adapted from python-oa3's CONTRIBUTING with scope rewritten for the framework layer (lifecycle, VEN/BL clients, notification channels, mDNS discovery, auth flows). Calls out which classes of bug belong upstream in python-oa3 instead. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 342c8b6 commit 71d43f8

2 files changed

Lines changed: 92 additions & 0 deletions

File tree

CONTRIBUTING.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Contributing to python-oa3-client
2+
3+
Thanks for your interest in contributing! This repo is a Python companion client framework on top of [openadr3](https://github.com/grid-coordination/python-oa3) — it adds a `BaseClient` lifecycle, `VenClient` / `BlClient` wrappers, notification channels (MQTT, webhook), and optional mDNS/DNS-SD VTN discovery. The underlying spec, raw HTTP, and Pydantic models live in `python-oa3`; this repo is the framework layer that consumes them.
4+
5+
## How to contribute
6+
7+
### Discussions
8+
9+
Use [Discussions](https://github.com/grid-coordination/python-oa3-client/discussions) for:
10+
11+
- Questions about how to use the client framework — VEN registration, lifecycle, channel selection, `__getattr__` delegation to `OpenADRClient`, mDNS modes
12+
- API and design judgment calls — "should `python-oa3-client` model X?" / "which layer does Y belong in — `python-oa3` or `python-oa3-client`?"
13+
- VTN behavior gaps that affect the framework — e.g. odd `/notifiers` responses, MQTT URI scheme variants, webhook callback reachability across NAT
14+
- Coordination with the upstream [OpenADR 3.1.0 specification](https://github.com/grid-coordination/python-oa3/blob/main/resources/openadr3.yaml) and the [VTN Reference Implementation](https://github.com/oadr3-org/openadr3-vtn-reference-implementation)
15+
- Sharing what you're building on top of `python-oa3-client` (VENs, business-logic clients, integrations)
16+
17+
Discussions are open-ended — a good place to think out loud or scope something before it becomes a concrete change. Aligned outcomes from a Discussion often turn into one or more Issues.
18+
19+
### Issues
20+
21+
Use [Issues](https://github.com/grid-coordination/python-oa3-client/issues) for actionable changes:
22+
23+
- Bugs in client construction, auth (Bearer or OAuth2 client-credentials), VEN registration idempotency, or program lookup
24+
- Channel bugs — MQTT connection lifecycle, webhook receiver routing, message coercion, `await_messages` timing
25+
- mDNS/DNS-SD discovery issues — TXT-record parsing, fallback behavior across the four `DiscoveryMode` values, `advertise_vtn` interop
26+
- VTN behavior gaps that should be absorbed at the framework layer (Postel's Law: be liberal in what you accept) rather than in `python-oa3` itself
27+
- Test failures or unexpected behavior with concrete repro steps
28+
- Documentation errors, unclear explanations, or stale prose in `README.md` or `doc/`
29+
- Discussion outcomes that have alignment and a clear scope
30+
31+
If a bug is in raw HTTP, request building, or coerced entity shape, it likely belongs in [`python-oa3`](https://github.com/grid-coordination/python-oa3) instead — file there. If you're not sure which repo, file here and we'll move it.
32+
33+
If you're not sure whether something is an Issue or a Discussion, start with a Discussion — we can convert it later.
34+
35+
### Pull requests
36+
37+
Pull requests are welcome.
38+
39+
- For small fixes (typos, broken links, single-test corrections, single-channel bug fixes, mDNS edge cases), open a PR directly.
40+
- For substantive changes (new notification channel types, new lifecycle hooks, new discovery modes, new auth modes), open a Discussion or Issue first so we can align on scope before you invest the effort.
41+
- All changes pass `pytest tests/` and `ruff check src tests` / `ruff format --check src tests` cleanly. CI runs lint on every push and PR.
42+
- Match the existing tone and structure. The framework keeps `BaseClient` (auth + lifecycle), `VenClient` / `BlClient` (entity-aware wrappers), and notification channels (`NotificationChannel` protocol implementations) as roughly orthogonal layers; patches that fit cleanly into one layer without leaking concerns across them are the easiest to land. In particular, raw HTTP and coercion concerns belong in `python-oa3`, not here.
43+
- One commit per logical change is fine; we don't require squash or any particular branch naming.
44+
45+
## Development
46+
47+
```bash
48+
pip install -e ".[dev]" # install with dev dependencies (includes mqtt/webhooks/mdns extras)
49+
pytest tests/ -v # run the unit test suite (offline)
50+
ruff check src tests # lint
51+
ruff format --check src tests # format check (drop --check to apply)
52+
```
53+
54+
Optional integration tests under `examples/` (e.g. `smoke_test.py`, `smoke_test_mdns.py`) exercise live VTN-RI, Mosquitto, or zeroconf and are not run by `pytest tests/`. Run them manually when changes touch the relevant integration surface.
55+
56+
### Pre-commit hooks
57+
58+
This project uses [pre-commit](https://pre-commit.com/) to run Ruff lint and format checks automatically:
59+
60+
```bash
61+
pip install pre-commit
62+
pre-commit install
63+
```
64+
65+
Ruff lint + format are also enforced in CI via `.github/workflows/lint.yml`.
66+
67+
### Relationship to python-oa3
68+
69+
`python-oa3-client` depends on `openadr3>=0.3.0` and exposes its `OpenADRClient` methods directly via `__getattr__` delegation on `BaseClient`. When deciding where a change belongs:
70+
71+
- **In `python-oa3`**: spec types, raw HTTP request/response, Pydantic models, coercion to entities, time handling.
72+
- **In `python-oa3-client`** (this repo): client lifecycle, auth flows beyond bare Bearer (OAuth2 token fetch, User-Agent composition), VEN registration semantics, program-name caching, notification channel implementations, mDNS discovery, VEN-scoped convenience methods.
73+
74+
If a patch needs to span both repos, file the design discussion in whichever feels more central and link the two PRs.
75+
76+
## Code of conduct
77+
78+
Be respectful and constructive. We're a small project and appreciate everyone who takes the time to file an issue or send a PR.
79+
80+
## Important notice
81+
82+
This library is provided on an "as-is" basis. Updates and maintenance, including responses to issues filed on GitHub, will take place on an "as time and resources permit" basis. Library output (notification messages, coerced payloads, discovered VTN records) is best-effort against the [OpenADR 3.1.0 specification](https://github.com/grid-coordination/python-oa3/blob/main/resources/openadr3.yaml) and the behavior of real-world VTN implementations (including the [VTN Reference Implementation](https://github.com/oadr3-org/openadr3-vtn-reference-implementation)). This library is not authoritative for billing, dispatch, or grid operations — independent verification against the source spec and your VTN's actual responses is recommended for any consumer relying on these results for operational correctness.

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,16 @@ pip install -e ".[dev]"
368368
pytest tests/ -v
369369
```
370370

371+
## Contributing
372+
373+
Issues, Discussions, and pull requests are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow (and the dev commands: tests, lint, format, pre-commit). In short:
374+
375+
- **Questions, API/design discussion, VTN behavior gaps**[Discussions](https://github.com/grid-coordination/python-oa3-client/discussions)
376+
- **Confirmed bugs, channel/discovery fixes, doc errors**[Issues](https://github.com/grid-coordination/python-oa3-client/issues)
377+
- **Patches** → pull requests; please open a Discussion or Issue first for non-trivial changes (new channel types, new discovery modes, new auth modes, new lifecycle hooks)
378+
379+
Bugs in raw HTTP, coerced entities, or spec-level shapes likely belong in [python-oa3](https://github.com/grid-coordination/python-oa3) rather than here.
380+
371381
## License
372382

373383
[MIT License](LICENSE) — Copyright (c) 2026 Clark Communications Corporation

0 commit comments

Comments
 (0)