Skip to content

Prepare 0.2.0 for PyPI: self-contained sdist, settled public API, Trusted Publishing release workflow - #3

Merged
Bogzx merged 2 commits into
mainfrom
improve/2026-10-01-pypi-release-prep
Oct 1, 2026
Merged

Bogzx merged 2 commits into
mainfrom
improve/2026-10-01-pypi-release-prep

Conversation

@Bogzx

@Bogzx Bogzx commented Oct 1, 2026

Copy link
Copy Markdown
Owner

Prepares 0.2.0 for a first PyPI release: fixes the sdist, settles two public names that become breaking changes once published, and adds a release workflow that publishes through PyPI Trusted Publishing. Nothing is published by this PR.

Why

  • The sdist's own tests could not run. setuptools auto-includes only tests/test*.py. With no conftest.py and no tests/fixtures/*.json, pytest in an unpacked sdist stopped with 7 collection errors, which breaks downstream packagers.
  • from dxtrade_wrapper import * replaced the builtin ConnectionError. After a star import, except ConnectionError no longer caught socket errors such as ConnectionRefusedError; I checked this directly. Renames like this cost a deprecation cycle once a release is public.
  • The primary class was DXTradeDashboardWrapper, with DXTradeClient only an alias.
  • logout() dropped its requests.Session without closing it, leaking one connection pool per re-login in long-running bots.
  • Not ready for PyPI:
    • no Python-version classifiers;
    • no Source/Issues/Changelog URLs;
    • a relative CHANGELOG link that breaks on PyPI;
    • no install instructions;
    • no release process;
    • and the README said AuthenticationError covers "401/403", which is true only at login.

What changed

  • API:

    • DXTradeClient is the class, and DXTradeDashboardWrapper remains as an alias.
    • DXTradeConnectionError is the network-error class. ConnectionError still imports, as the same class, but is no longer in __all__.
    • logout() closes the Session before replacing it.
    • The examples, tests and README use the new names.
  • Packaging:

    • MANIFEST.in adds the tests and fixtures, CHANGELOG, examples and scripts.
    • pyproject.toml gains classifiers for Python 3.9–3.14 and the OS, and the extra URLs.
    • The mypy target stays 3.10, with a comment: current mypy rejects 3.9, and 3.9 is covered by the test matrix.
  • README:

    • an Install section;
    • absolute links;
    • the 401/403 wording now reads "401, and a 403 at login"; other 403s are plain DXTradeAPIError;
    • a "Packaging and releases" section.
  • scripts/check_release.py: the version has a CHANGELOG entry. Given a tag, it also checks that the tag equals __version__ and that the entry is dated. CHANGELOG now reads 0.2.0 (2026-10-01) and records the API changes above.

  • CI package job: check_release.py, twine check --strict, running the unpacked sdist's own tests, and installing the wheel in a clean venv with a py.typed check.

  • .github/workflows/release.yml, triggered when a GitHub release is published:

    1. build and check: tag vs version, dated changelog, twine, sdist tests;
    2. attach the sdist and wheel to the release;
    3. publish to TestPyPI (skip-existing), then PyPI, through pypa/gh-action-pypi-publish with OIDC, in environments testpypi and pypi.

    Step 3 runs only when the repository variable PYPI_PUBLISH is true, so publishing a GitHub release before PyPI is set up does not produce failing jobs.

Verification

  • python -m pytest -q: 127 passed, 13 skipped; it was 121 + 13, and the 6 new tests are in test_public_api.py. 5 of the 6 fail on main.
  • DXTRADE_SPEC_TESTS=1 python -m pytest tests/test_spec_conformance.py: 13 passed, against the live OpenAPI document. ruff: clean. mypy dxtrade_wrapper: no issues.
  • Packaging:
    • python -m build, then twine check --strict dist/*: both PASSED.
    • Unpacked sdist: pip install ".[test]" && pytest gives 127 passed, 13 skipped; on main it was 7 collection errors.
    • Wheel in a clean Python 3.9.23 venv: imports, py.typed is present, DXTradeClient is exported.
  • python scripts/check_release.py v0.2.0 reports ok. … v0.2.1 reports error: tag v0.2.1 does not match __version__ 0.2.0 and exits 1.
  • actionlint 1.7.7 is clean on both workflows. release.yml cannot run before it is on main and a release is published. Its build steps are the same commands as the CI package job, which runs on this PR.
  • examples/offline_demo.py still runs end to end.

Needs a human

  • The distribution name stays dxtrade-python-wrapper; it and dxtrade-wrapper were both free on PyPI on 2026-10-01. Change [project] name before the first upload if you prefer the shorter one, which matches the import name.
  • To publish:
    1. On pypi.org and test.pypi.org, add a pending Trusted Publisher: owner Bogzx, repository DXtrade-python-wrapper, workflow release.yml, environment pypi / testpypi.
    2. In the repo settings, create the environments testpypi and pypi, with yourself as required reviewer on pypi.
    3. Set the repository variable PYPI_PUBLISH=true.
    4. Publish the release: gh release create v0.2.0 --title v0.2.0 --notes-file <0.2.0 section of CHANGELOG> from main.
  • The client is still not verified against a live broker; the README says so. Publishing it as Development Status :: 3 - Alpha with that warning is honest, but whether to wait for a demo-account run is your call.

The client-module split (P6) follows in a separate PR stacked on this one.

🤖 Generated with Claude Code

Bogdan Truta and others added 2 commits October 1, 2026 12:56
- DXTradeClient is the class; DXTradeDashboardWrapper stays as an alias.
- DXTradeConnectionError is the network-error class. The 0.1 name
  ConnectionError still imports but is no longer in __all__: after
  `from dxtrade_wrapper import *`, `except ConnectionError` stopped catching
  socket errors such as ConnectionRefusedError (verified).
- logout() closes the requests Session before replacing it, so a bot that
  re-logs in for days does not leak one connection pool per session.
- tests/test_public_api.py pins these; 5 of its 6 tests fail on the old code.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…kflow

- MANIFEST.in: the sdist shipped tests/test_*.py without conftest.py or the
  JSON fixtures, so `pytest` in an unpacked sdist failed with 7 collection
  errors. It now also includes CHANGELOG, examples and scripts.
- pyproject: Python 3.9-3.14 and OS classifiers; Source, Issues and
  Changelog URLs.
- README: an Install section, absolute links (relative ones break on PyPI),
  accurate 401/403 wording, packaging and release notes.
- scripts/check_release.py: the version has a CHANGELOG entry; with a tag,
  the tag matches __version__ and the entry is dated. CHANGELOG dates 0.2.0.
- CI package job: check_release, twine check --strict, test the unpacked
  sdist, install the wheel in a clean venv and check py.typed.
- release.yml (on a published GitHub release): build and check, attach the
  sdist and wheel to the release, then publish to TestPyPI and PyPI via
  Trusted Publishing, only when the repository variable PYPI_PUBLISH=true.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Bogzx
Bogzx merged commit a0b2d3c into main Oct 1, 2026
6 checks passed
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