Restructure coglet Python module to improve separation of structure and prepare for publishing (#2710)
* feat(coglet): add build.rs for PEP 440 version + build metadata
Add build script that:
- Converts semver pre-release tags to PEP 440 format
(e.g., 0.17.0-alpha.2 → 0.17.0a2)
- Captures git SHA, build timestamp, and rustc version
- Emits as compile-time environment variables
Add frozen BuildInfo pyclass for coglet.__build__ with version,
git_sha, build_time, and rustc_version fields.
* refactor(coglet): move CancelationException to Rust static, rewrite signal handler
Replace module setattr + Python string exec with:
- OnceLock<Py<PyAny>> static for the exception class
- Rust #[pyfunction] signal handler
Eliminates a setattr on the coglet module (needed for upcoming
module write protection) and removes Python-as-string.
* refactor(coglet): rewrite audit hook in Rust, add worker_local tracing target
audit.rs:
- Replace 60-line Python string with Rust #[pyfunction] audit hook
- Add AtomicBool re-entrancy guard (replaces threading.Timer hack)
- Add Mutex to serialize stream replacement across threads
- Demote helper functions from #[pyfunction] to pub(crate)
- Rename TeeWriter -> _TeeWriter (private pyclass)
worker_tracing_layer.rs:
- Add coglet::worker_local target filter (excluded from IPC,
always written to worker stderr fd 101)
- Used by audit.rs for poisoned-lock diagnostics that must not
traverse the log routing infrastructure
* refactor(coglet): rename SlotLogWriter -> _SlotLogWriter in Python API
Make the log writer class private in the Python namespace via
pyclass(name = "_SlotLogWriter"). Rust type name unchanged.
* refactor(coglet): use OnceLock statics for async Python helpers in predictor
Move _collect_async_gen and _ctx_wrapper Python async helper functions
into OnceLock statics so they are defined once and reused across calls.
Fix Py<PyAny>::call1() call sites to pass py token as first argument.
* refactor(coglet): rewrite module API with __getattr__/__dir__/__setattr__
- Remove standalone active() #[pyfunction], expose via __getattr__ as
property-like attribute (no parens needed)
- Add __getattr__ for 'active' and '__build__' attribute access
- Add __dir__ returning only public API: __version__, __build__, active, serve
- Add __setattr__ to block writes to module (registered LAST in init)
- Use PEP 440 version from COGLET_PEP440_VERSION env var
- Store BuildInfo as _build_info, exposed as __build__ via __getattr__
* refactor(coglet): restructure module into server object + _sdk submodule
- coglet.server: frozen Server pyclass with .active property, .serve(),
._run_worker(), ._is_cancelable()
- coglet._sdk: submodule for Python runtime integration classes
(_SlotLogWriter, _TeeWriter)
- Root module is plain: __version__, __build__, server, _sdk
- No PEP 562 machinery needed — static attrs in dict, dynamic .active
is a #[getter] on frozen pyclass
- Update all callsites: http.py, orchestrator.rs, tests, docs
* refactor(coglet): mixed layout with _impl .so and hand-managed __init__.py
- coglet/__init__.py: explicit re-exports with __all__ control
- coglet/py.typed: marker for type stub distribution
- pyproject.toml: module-name = coglet._impl for mixed layout
- lib.rs: #[pyo3(name = "_impl")] + __all__ for import control
- .gitignore: add *.so, *.pyd to prevent committing build artifacts
- Maturin now builds as mixed python/rust project, no auto-generated wrapper
* docs(coglet): add help text to _sdk submodule
* refactor(coglet): update stub generation pipeline + pyproject.toml
- Remove stale root coglet.pyi, replace with coglet/__init__.pyi (mypy
stubgen) and coglet/_sdk/__init__.pyi (pyo3-stub-gen)
- pyproject.toml: add python-source = '.' for pyo3-stub-gen mixed layout
- mise.toml: update generate:stubs to run pyo3-stub-gen then mypy stubgen
- mise.toml: rewrite stub:check to use git diff on all .pyi files
- mise.toml: update stub:typecheck path
* test(coglet): add module structure tests for new API
Tests for: PEP 440 version, BuildInfo fields/frozen/repr,
server.active property, server frozen protection, _sdk submodule
contents, __all__ excludes internals. 17 new tests, all passing.
* fix(coglet): sort imports and add re-export alias for ruff compliance