Skip to content

Commit cacddce

Browse files
Merge pull request #700 from robbinjanssen/docs/agents-md
Add AGENTS.md and move the development setup to CONTRIBUTING
2 parents 836affd + 0983475 commit cacddce

3 files changed

Lines changed: 134 additions & 43 deletions

File tree

‎AGENTS.md‎

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# AGENTS.md
2+
3+
Guidance for AI coding agents working on this repository. Human contributors:
4+
see [CONTRIBUTING](CONTRIBUTING.md).
5+
6+
## Project
7+
8+
`ojmicroline-thermostat`: an asynchronous Python client for OJ Microline cloud
9+
thermostats, published on PyPI. Its main consumer is the
10+
[Home Assistant integration](https://github.com/robbinjanssen/home-assistant-ojmicroline-thermostat)
11+
(same owner), which pins a released version; keep that integration in mind when
12+
changing the public API.
13+
14+
```text
15+
ojmicroline_thermostat/
16+
ojmicroline.py OJMicroline client: HTTP requests, session retry, push
17+
subscriptions; the OJMicrolineAPI protocol and
18+
SessionOJMicrolineAPI base class
19+
wd5.py WD5API: WD5 series (OWD5, MWD5), session API
20+
wg4.py WG4API: WG4 series (UWG4, AWG4), session API, push long-poll
21+
wg5.py WG5API: WG5 series (UWG5), OAuth2 API
22+
models/ Thermostat and Schedule dataclasses, parsed per series
23+
exceptions.py public exceptions
24+
const.py regulation modes and other constants
25+
tests/ pytest tests with aresponses and JSON fixtures
26+
```
27+
28+
## Commands
29+
30+
The project uses [uv](https://docs.astral.sh/uv/) and
31+
[prek](https://github.com/j178/prek).
32+
33+
```sh
34+
uv sync # create .venv with the dev tools
35+
uv run prek install # git hook running all checks on commit
36+
uv run prek run --all-files # Ruff, mypy, pylint, pytest, codespell, ...
37+
uv run pytest # tests with coverage
38+
uv build --no-sources # build the wheel and sdist (uv_build)
39+
```
40+
41+
Run all hooks and tests before committing. The hooks refuse commits to `main`;
42+
work on a branch.
43+
44+
## Requirements
45+
46+
- Python 3.11 to 3.14; CI tests every version. Write code that runs on 3.11:
47+
no PEP 695 generics (`def f[T]`), use `TypeVar`. mypy and Ruff target 3.11.
48+
- Runtime dependencies are only `aiohttp` and `yarl`. Do not import packages
49+
that are only development dependencies; `async_timeout` once broke clean
50+
installs that way, use `asyncio.timeout`.
51+
52+
## Conventions
53+
54+
- **Public API**: everything users need is exported from
55+
`ojmicroline_thermostat/__init__.py` and listed in `__all__`. Constructor
56+
arguments of the model APIs are public; `WD5API` keeps its positional
57+
arguments (`noqa: PLR0917`).
58+
- **Model APIs** implement the `OJMicrolineAPI` protocol: `login()`,
59+
`invalidate_session()`, `get_thermostats()`, `get_energy_usage()`,
60+
`set_regulation_mode()`, `get_notifications()` and `supports_notifications`.
61+
Session-based APIs (WD5, WG4) derive from `SessionOJMicrolineAPI`.
62+
- **HTTP**: all requests go through `OJMicroline._request` (the `request`
63+
attribute of an API), so the session passed to `OJMicroline` is used. It
64+
supports JSON bodies, form fields (`form=`) and another host (`host=`).
65+
- **Errors**: HTTP 401 raises `OJMicrolineUnauthorizedError`; `OJMicroline`
66+
then invalidates the session, logs in again and retries once. Other HTTP
67+
errors raise `OJMicrolineConnectionError`, timeouts `OJMicrolineTimeoutError`,
68+
and wrong credentials `OJMicrolineAuthError`.
69+
- **Temperatures** are integers in 1/100 °C.
70+
- **Typing**: mypy runs in strict mode from `pyproject.toml`; there is no
71+
`mypy.ini`.
72+
73+
## Tests
74+
75+
- Tests mock the API with `aresponses` and the JSON responses in
76+
`tests/fixtures/`. The Home Assistant integration copies these fixtures, so
77+
keep them realistic.
78+
- Coverage is 100%; CI requires at least 90%. Add a test for every bug fix that
79+
fails without the fix.
80+
- `config.py` (gitignored) holds real credentials for `test_output.py`, a
81+
manual script. Never commit it, and never print credentials or tokens.
82+
`test_output.py`'s import order depends on whether `config.py` exists, which
83+
is why `I001` is ignored for it in `pyproject.toml`.
84+
85+
## Pull requests and releases
86+
87+
- Every pull request needs one of these labels: `breaking-change`, `bugfix`,
88+
`hotfix`, `documentation`, `enhancement`, `refactor`, `performance`,
89+
`new-feature`, `maintenance`, `ci`, `dependencies`, `skip-changelog`.
90+
- Release Drafter derives the next version from the labels. Publishing a GitHub
91+
release runs `release.yaml`, which sets the version from the tag
92+
(`uv version`), builds the package and publishes it to PyPI. The version in
93+
`pyproject.toml` stays `0.0.0`.
94+
- Renovate keeps dependencies up to date and automerges minor and patch
95+
updates.

‎CONTRIBUTING.md‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,45 @@ the archive, maybe your question was already answered.
1616

1717
Even better: You could submit a pull request with a fix / new feature!
1818

19+
## Development environment
20+
21+
This Python project is fully managed using the [uv](https://docs.astral.sh/uv/) package manager.
22+
23+
You need at least:
24+
25+
- Python 3.11+
26+
- [uv](https://docs.astral.sh/uv/getting-started/installation/)
27+
28+
Install all packages, including all development requirements:
29+
30+
```bash
31+
uv sync
32+
```
33+
34+
uv creates a virtual environment in `.venv` and installs all necessary
35+
packages in it. Run commands in it with `uv run`.
36+
37+
Set up the pre-commit checks with [prek](https://prek.j178.dev):
38+
39+
```bash
40+
uv run prek install
41+
```
42+
43+
*Now you're all set to get started!*
44+
45+
All changes are linted and tested with each commit. You can run all checks
46+
and tests manually, using the following command:
47+
48+
```bash
49+
uv run prek run --all-files
50+
```
51+
52+
To run just the Python tests:
53+
54+
```bash
55+
uv run pytest
56+
```
57+
1958
## Pull request process
2059

2160
1. Search our repository for open or closed [pull requests][prs] that relates

‎README.md‎

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -284,45 +284,6 @@ We've set up a separate document for our
284284

285285
Thank you for being involved! :heart_eyes:
286286

287-
## Setting up development environment
288-
289-
This Python project is fully managed using the [uv][uv] package manager.
290-
291-
You need at least:
292-
293-
- Python 3.11+
294-
- [uv][uv-install]
295-
296-
Install all packages, including all development requirements:
297-
298-
```bash
299-
uv sync
300-
```
301-
302-
uv creates a virtual environment in `.venv` and installs all necessary
303-
packages in it. Run commands in it with `uv run`.
304-
305-
Set up the pre-commit checks with [prek][prek]:
306-
307-
```bash
308-
uv run prek install
309-
```
310-
311-
*Now you're all set to get started!*
312-
313-
All changes are linted and tested with each commit. You can run all checks
314-
and tests manually, using the following command:
315-
316-
```bash
317-
uv run prek run --all-files
318-
```
319-
320-
To run just the Python tests:
321-
322-
```bash
323-
uv run pytest
324-
```
325-
326287
## License
327288

328289
MIT License
@@ -372,7 +333,3 @@ SOFTWARE.
372333
[releases]: https://github.com/robbinjanssen/python-ojmicroline-thermostat/releases
373334
[stars-shield]: https://img.shields.io/github/stars/robbinjanssen/python-ojmicroline-thermostat.svg
374335
[stars-url]: https://github.com/robbinjanssen/python-ojmicroline-thermostat/stargazers
375-
376-
[prek]: https://prek.j178.dev
377-
[uv]: https://docs.astral.sh/uv/
378-
[uv-install]: https://docs.astral.sh/uv/getting-started/installation/

0 commit comments

Comments
 (0)