Skip to content

Migrate to uv, consolidate packaging in pyproject.toml, add MIT license - #50

Merged
rnovatorov merged 11 commits into
mainfrom
build/migrate-to-uv
Sep 23, 2026
Merged

rnovatorov merged 11 commits into
mainfrom
build/migrate-to-uv

Conversation

@rnovatorov

Copy link
Copy Markdown
Member

What

Replaces pipenv + setup.py + twine with uv and a single pyproject.toml, adds an MIT license, and rebuilds the Docker image with dependency-layer caching.

Commit-by-commit (each independently reviewable):

  1. chore: add MIT license
  2. build: replace setup.py with pyproject.toml
  3. build: replace pipenv with uv
  4. ci: run checks with uv
  5. build: build docker image with layered uv install
  6. chore: drop unused faker dev dependency
  7. fix: scope pyflakes to source directories
  8. style: apply black 26 formatting

Why

  • pipenv is slow, in maintenance mode, and CI bootstrapped it via the deprecated get-pipenv.py script. uv covers pipenv, twine, and the build step with one fast tool.
  • The package shipped without any license (all-rights-reserved by default) — now MIT, declared via PEP 639 metadata.
  • The dev environment is finally reproducible: uv.lock is committed (the Pipfile.lock never was).

Notable details

  • Runtime dependencies are byte-identical (aiomqtt==2.5.*, dnspython==2.8.*, json-log-formatter==1.1.*, httpx==0.28.*); Requires-Python: >=3.11 is newly declared (old setup.py never set python_requires).
  • .python-version pins local development to 3.11 (oldest supported); the CI matrix is unchanged and driven by UV_PYTHON.
  • Docker: deps install from the frozen lock into the system interpreter in their own layer — source-only edits rebuild in ~5s; the SDK layer installs exactly one package.
  • bump-version now runs uv lock so frozen Docker builds never see a stale manifest.
  • Coverage is scoped to enapter and pyflakes to src tests examples, since the .venv now lives inside the repo.
  • Releases now publish an sdist alongside the wheel.

Verification

  • make check: black/isort/pyflakes/mypy + 204 unit tests + 5 integration tests (live mosquitto) — all green on Python 3.11.
  • make dist: sdist + wheel inspected; Requires-Dist identical to the previous release, py.typed and LICENSE ship correctly.
  • Docker image: built, runtime imports verified (enapter 0.24.0 + all deps), layer-cache behavior proven with a source-file dirtying test.

Follow-ups (separate PRs)

  • Dependency updates + pin convention (major-pin for V>1, minor otherwise).
  • Bump the outdated actions in the Docker CI jobs.
  • Re-introduce repo-local opencode permissions once real agent needs emerge.

The repository was distributed without a license, leaving consumers
without permission to use the SDK.
Consolidate packaging and tool configuration (pytest, isort) into a
single PEP 621 manifest. Building goes through PEP 517 instead of
invoking setup.py directly. The version stays in
src/enapter/__init__.py, read dynamically; metadata is unchanged
apart from the now-declared MIT license.
pipenv is slow, in maintenance mode, and CI had to bootstrap it via
the deprecated get-pipenv.py script. uv is a single fast tool that
now covers everything pipenv and twine did.

uv.lock finally pins the dev environment (Pipfile.lock was never
committed) and .python-version pins the local interpreter to the
oldest supported Python. Coverage is scoped to the enapter package
because the environment now lives inside the repo as .venv. The
repo-local opencode.json permissions are dropped for now; they will
be reintroduced based on observed needs.
Replace the setup-python and pipenv bootstrap steps with
astral-sh/setup-uv; the UV_PYTHON matrix variable provisions each
interpreter. The publish job needs no interpreter at all since uv
builds and uploads the package standalone.

The Docker jobs are left untouched; their outdated actions will be
bumped separately.
Install dependencies and the SDK in separate layers so source-only
changes no longer reinstall every dependency. Dependencies are
rendered from the frozen uv.lock and installed into the system
interpreter, matching the previous pip install . behavior.

bump-version refreshes uv.lock so frozen builds never see a stale
manifest.
faker is not referenced anywhere in the repo; likely a leftover
from removed tests.
The uv-managed .venv lives inside the repository, so plain
"pyflakes ." now walks installed packages. Enumerate the actual
targets instead, mirroring how coverage was scoped to enapter.
The fresh lock upgraded black to 26.5.1, which enforces a magic
trailing comma in the mqtt client signature.
This entry is why Pipfile.lock was never tracked; the file itself
is gone with the pipenv migration.
Keep the token off the process command line; uv reads
UV_PUBLISH_TOKEN.
The files are plain local paths; COPY has no archive or URL
semantics to invoke.
@rnovatorov
rnovatorov merged commit 8e1c224 into main Sep 23, 2026
7 checks passed
@rnovatorov
rnovatorov deleted the build/migrate-to-uv branch September 23, 2026 11:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant