# Python Style Guide This guide defines Python conventions for the MXAccess Gateway Python package, CLI, and tests. ## Baseline - Target modern supported Python versions defined by `pyproject.toml`. - Use `pyproject.toml` for package metadata and tool configuration. - Use type hints for public APIs and non-trivial internal functions. - Run the configured formatter and linter when the package is available. - Keep generated protobuf code separate from handwritten modules. ## Source Documentation - Maintain the existing documentation style in the file, package, and surrounding component. - Write comments that include business-specific or domain-specific context when that context is available from the code, surrounding docs, or naming. - Use docstrings for public classes, functions, and modules when behavior, parity constraints, or security requirements are not obvious from the name and type hints. - Avoid comments that restate syntax or control flow. ## Package Structure - Put library code under `src/zb_mom_ww_mxgateway/`. - Put CLI entry points under `src/zb_mom_ww_mxgateway_cli/`. - Keep generated protobuf modules under a clearly named `generated` package. - Avoid import side effects that open channels, read environment variables, or start background tasks. ## Naming - Use `snake_case` for functions, variables, modules, and methods. - Use `PascalCase` for classes and exceptions. - Use `UPPER_SNAKE_CASE` for constants. - Keep MXAccess names recognizable in public APIs, even when Python wrappers use idiomatic method names. ## Async - Make the client async-first. - Use async context managers for clients and sessions when practical. - Cancel gRPC streams when async iteration is canceled. - Document that canceling a Python task does not abort an in-flight MXAccess COM call inside the worker. ## Errors - Use typed exceptions for transport, authentication, authorization, session, worker, command, and MXAccess failures. - Attach raw protobuf replies to command exceptions when available. - Redact API keys, passwords, and secured write values in exception messages and CLI output. ## CLI - Keep CLI output deterministic for tests. - Support JSON output for automation. - Load API keys from explicit flags or named environment variables. Do not read secrets implicitly during module import. ## Tests - Use `pytest` and `pytest-asyncio`. - Use fake generated stubs or an in-process test gRPC server for unit tests. - Keep live integration tests behind an explicit opt-in environment variable and a `pytest` skip guard, matching the existing tests (for example the loopback TLS tests gate on `MXGATEWAY_RUN_TLS_TESTS=1`).