Update dlclive requirement & add deploy workflow#48
Update dlclive requirement & add deploy workflow#48C-Achard wants to merge 17 commits intocy/pre-release-fixes-2.0from
Conversation
Replace flexible >=2 specifiers with an exact deeplabcut-live==1.1.0 for the main dependency and its [pytorch] and [tf] extras in pyproject.toml. This pins the package (and its included extras like timm and scipy) to a known compatible release to avoid missing-dependency or compatibility issues.
Add a new GitHub Actions workflow (python-package.yml) to build and publish packages to PyPI. The workflow triggers on tag pushes (v*.*.*) and on PR events, sets up Python, caches pip, installs build tooling (build, twine, packaging), builds the package, and uploads artifacts to PyPI using TWINE_API_KEY. Also rename .github/workflows/ci.yml to .github/workflows/testing-ci.yml to clarify CI purpose.
2c4653c to
05497e8
Compare
Rename workflow and split into a build/validate job and a gated publish job. Add a Python matrix (3.10–3.12), cache keyed by matrix python-version, and update checkout/setup/cache action usages. Build sdist/wheel, run twine check, inspect dist contents, and perform a smoke install from the built wheel (with a best-effort CLI check). Publish step now runs only for tag pushes like vX.Y.Z and uploads with twine using the TWINE_API_KEY secret.
Replace dynamic = ["version"] with an explicit version = "2.0.0rc0" placeholder in pyproject.toml. This makes the package version static (release candidate) for packaging/CI needs; update the placeholder as appropriate for final releases.
Clarify package description to mention pose estimation experiments with DeepLabCut; fix authors by splitting the previous entry into two distinct authors (M-Lab of Adaptive Intelligence and Mathis Group for Computational Neuroscience and AI) with their respective emails; add a FIXME comment to the Documentation URL to mark docs as a placeholder.
Add a comment in the Python CI workflow recommending inclusion of the lock file for caching and validation. Update the smoke-test step to install the built wheel along with its dependencies by removing `--no-deps`. Also include minor whitespace cleanup.
Introduce dlclivegui.assets.ascii_art: a cross-platform, CI-safe ASCII/ANSI art generator using OpenCV and numpy (alpha compositing, content cropping, resizing, color modes, and terminal detection). Integrate it into main: add argparse with a --no-art flag, print a startup banner (unless disabled), and use the art helper for help text. Fix QApplication SIGINT keepalive timer handling (avoid duplicate timers and stop existing one before replacing). Change default SHOW_SPLASH to False in theme.py and update tests to restore SHOW_SPLASH=True via an autouse fixture so existing splash-dependent tests continue to pass.
Fix a small header comment in dlclivegui/assets/ascii_art.py and add dlclivegui/assets/* to coverage omit. Expand tests/gui/test_app_entrypoint.py with extensive unit tests for dlclivegui.assets.ascii_art (terminal/ANSI behavior, image helpers, rendering, generate/print API, and help banner), including TTY/NOTTY fixtures, image fixtures (using OpenCV, skipping if missing), and helpers for deterministic terminal sizing. Also adjust imports in the test to reference dlclivegui.assets.ascii_art.
There was a problem hiding this comment.
Pull request overview
This pull request prepares the DeepLabCut-Live GUI package for release by updating dependencies, adding CI/CD workflows, and enhancing the CLI with ASCII art branding. The changes pin the deeplabcut-live dependency to version 1.1.0 (which includes both PyTorch and TensorFlow pipelines), introduce automated testing and deployment workflows, and add a terminal-based ASCII art banner for improved user experience.
Changes:
- Pins
deeplabcut-livedependency to version 1.1.0 with exact version matching (==1.1) across all optional dependencies - Adds GitHub Actions workflows for continuous integration (testing-ci.yml) and package deployment to PyPI (python-package.yml)
- Introduces ASCII art rendering functionality for terminal branding with cross-platform support and ANSI color handling
- Updates project metadata (version, description, authors) and disables splash screen by default
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 15 comments.
Show a summary per file
| File | Description |
|---|---|
| pyproject.toml | Updates deeplabcut-live dependency to ==1.1, sets version to 2.0.0rc0, updates author information, and adds assets directory to coverage exclusions |
| .github/workflows/testing-ci.yml | New CI workflow for running unit and smoke tests across Python 3.10-3.12 on multiple OS platforms with coverage reporting |
| .github/workflows/python-package.yml | New deployment workflow for building, validating, and publishing packages to PyPI on version tags, with smoke testing on PRs |
| tox.ini | Changes from wheel-based package install to editable install (use_develop=true) for faster development iteration |
| dlclivegui/main.py | Adds argparse integration with ASCII art help description, startup print messages, and refactors signal timer handling |
| dlclivegui/gui/theme.py | Disables splash screen by default (SHOW_SPLASH = False) |
| dlclivegui/assets/ascii_art.py | New module providing terminal ASCII art rendering with OpenCV, supporting ANSI colors, transparency, and cross-platform terminal detection |
| tests/gui/test_app_entrypoint.py | Adds comprehensive tests for ASCII art functionality covering terminal detection, image processing, rendering, and help text generation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This reverts commit 3611774.
Update GitHub Actions usages to actions/checkout@v6 and actions/setup-python@v6 in format and python-package workflows for consistency and newer runner support. Improve the python-package workflow's CLI smoke test to explicitly check for the 'dlclivegui' entry point, run its --help when present, and fail the job if the help command returns non-zero—providing clearer diagnostics instead of silently continuing.
Add a __version__ = "2.0.0rc0" placeholder in dlclivegui/__init__.py and update pyproject.toml to use dynamic = ["version"] instead of a hardcoded version field. This makes the project metadata pull the version from the package source rather than storing it twice.
Wrap ASCII-art generation in a try/except to avoid crashing when the asset or terminal ops fail (catch FileNotFoundError, RuntimeError, OSError and fall back to no banner). Add a clarifying comment for the Windows ANSI os.system("") workaround. In argument parsing, allow parse_args to accept argv, detect --no-art early, safely build the help description with a fallback default and log a warning on failure. Replace startup prints with logging.info and use the computed description for argparse. These changes make startup more robust and avoid surprising exceptions when ASCII art cannot be produced.
Replace the autouse fixture with explicit fixtures to toggle dlclivegui.gui.theme.SHOW_SPLASH per-test. Adds set_use_splash_true and set_use_splash_false fixtures, updates tests to accept them, and removes the manual SHOW_SPLASH override in test_main_without_splash. Also fixes a comment typo (thems.py -> theme.py) to make splash behavior explicit and avoid cross-test side effects.
Improve ASCII art rendering performance by replacing per-pixel Python loops with vectorized operations and a byte-level cache. _map_luminance_to_chars now uses a numpy char LUT and joins rows from a (H,W) array of 1-char strings. _color_ascii_lines avoids cv.split and per-pixel f-strings: it computes luminance in float, uses a uint16 index map, packs RGB into a uint32 color key, and caches formatted ANSI-colored byte sequences keyed by (color<<8)|idx. Lines are built as bytearrays and decoded once. Functionality/formatting is preserved while reducing Python-level overhead.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 9 changed files in this pull request and generated 6 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "CameraConfigDialog", | ||
| "main", | ||
| ] | ||
| __version__ = "2.0.0rc0" # PLACEHOLDER |
There was a problem hiding this comment.
__version__ is marked as # PLACEHOLDER. If release automation (or importlib.metadata.version) is expected to reflect the published version, this placeholder should be replaced with the real versioning strategy (or removed in favor of a single authoritative source).
| __version__ = "2.0.0rc0" # PLACEHOLDER | |
| __version__ = "2.0.0rc0" |
Add a setuptools dynamic version entry in pyproject.toml so package version is taken from dlclivegui.__version__. Also include package-data for dlclivegui.assets. Refactor tests/gui/test_app_entrypoint.py to import cv2 at module level and skip the test module early when OpenCV is not available (removed a duplicated try/except). Tighten the assertion in test_generate_ascii_lines_crop_alpha to compare the actual generated ASCII content (lines) rather than only lengths, and clean up related comments.
Fix the OpenCV error message to reference dlclivegui.assets.ascii_art and refactor _color_ascii_lines for performance and clarity. Changes include: encode ASCII ramp once, clarify luminance comment, pack colors into 0xRRGGBB, use a prefix_cache for ANSI SGR color prefixes, emit a color sequence only when the color changes (using prev_ck), use memoryview for row access, append a single reset per line, and simplify character emission. Functionality and ANSI formatting are preserved while reducing per-character allocations and cache complexity.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 9 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| try: | ||
| import cv2 as cv | ||
| except Exception: | ||
| pytest.skip("OpenCV (opencv-python) is required for these tests.", allow_module_level=True) | ||
|
|
||
| import dlclivegui.assets.ascii_art as ascii_mod | ||
|
|
There was a problem hiding this comment.
The module-level OpenCV import/skip skips the entire file (including the main entrypoint tests) when cv2 is unavailable. Since opencv-python is declared as a required runtime dependency and dlclivegui.assets.ascii_art raises if OpenCV is missing, this should fail rather than silently skip (or scope the skip to only the ASCII-art-specific tests).
| try: | |
| import cv2 as cv | |
| except Exception: | |
| pytest.skip("OpenCV (opencv-python) is required for these tests.", allow_module_level=True) | |
| import dlclivegui.assets.ascii_art as ascii_mod | |
| import cv2 as cv | |
| import dlclivegui.assets.ascii_art as ascii_mod |
| ASCII_IMAGE_PATH = resources.files("dlclivegui.assets") / "logo_transparent.png" | ||
|
|
There was a problem hiding this comment.
ASCII_IMAGE_PATH is defined via importlib.resources.files(...), which may not always be a real filesystem path. Since generate_ascii_lines() uses os.path.isfile() + OpenCV file loading, consider resolving this via resources.as_file(...) (or reusing the existing asset_path() helper) to ensure it works with all packaging/resource loaders.
| logging.info("Starting DeepLabCut-Live GUI...") | ||
| if not args.no_art: | ||
| logging.info(art.build_help_description(desc="Welcome to DeepLabCut-Live GUI!")) |
There was a problem hiding this comment.
Logging the result of build_help_description() will write a potentially large, multi-line ANSI-colored banner into logs, and it rebuilds the banner a second time (after already building it in parse_args). Consider avoiding logging the banner entirely (or only printing it to stdout when in a TTY), and/or caching the computed description/banner so the OpenCV work happens at most once per process.
| # ------------------------- | ||
| # Fixtures & small helpers | ||
| # ------------------------- | ||
|
|
There was a problem hiding this comment.
This file now mixes GUI entrypoint tests with a large suite of ASCII-art unit tests, which makes the test layout harder to navigate and maintain. Consider moving the ASCII-art tests/fixtures into a dedicated module (e.g. tests/assets/test_ascii_art.py) so GUI-focused tests stay lightweight and failures are easier to triage.
| ] | ||
| omit = [ | ||
| "tests/*", | ||
| "dlclivegui/assets/*", |
There was a problem hiding this comment.
The coverage omit pattern dlclivegui/assets/* will also exclude the new dlclivegui/assets/ascii_art.py module from coverage reporting, which makes the coverage output misleading (especially since tests were added for it). Consider narrowing/removing this omit pattern so Python code under dlclivegui/assets/ is still measured (non-Python assets don’t affect coverage anyway).
| "dlclivegui/assets/*", |
| if static_banner is None: | ||
| try: | ||
| banner = "\n".join( | ||
| generate_ascii_lines( | ||
| str(ASCII_IMAGE_PATH), |
There was a problem hiding this comment.
build_help_description() generates the banner (OpenCV load/resize/render) before checking whether it will actually be shown. This means even non-TTY output (e.g. CI logs or redirected --help) pays the full cost and can fail due to banner generation. Consider checking terminal_is_wide_enough() / sys.stdout.isatty() first and only generating the banner when it will be used.
| - name: Publish to PyPI | ||
| env: | ||
| TWINE_USERNAME: __token__ | ||
| TWINE_PASSWORD: ${{ secrets.TWINE_API_KEY }} | ||
| run: python -m twine upload --verbose dist/* |
There was a problem hiding this comment.
Publishing with a long-lived TWINE_API_KEY secret works, but it increases the blast radius if the token leaks. Consider switching to PyPI Trusted Publishing (OIDC) via pypa/gh-action-pypi-publish, which removes the need for storing PyPI API tokens in GitHub secrets and is the recommended approach for new release workflows.
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Setup Python | ||
| uses: actions/setup-python@v5 |
There was a problem hiding this comment.
Within this workflow, build_check uses actions/checkout@v6/setup-python@v6 but publish uses older majors. Aligning action major versions across jobs improves reproducibility and reduces maintenance overhead (or add a comment explaining why publish must remain on older majors).
| uses: actions/checkout@v4 | |
| - name: Setup Python | |
| uses: actions/setup-python@v5 | |
| uses: actions/checkout@v6 | |
| - name: Setup Python | |
| uses: actions/setup-python@v6 |
Release preparation
This pull request introduces a new GitHub Actions workflow for publishing to PyPI and updates the
deeplabcut-livedependency throughout the project to version 1.1, replacing the previous requirement for version 2 or higher.CI/CD Improvements:
.github/workflows/python-package.ymlto automate building and publishing the package to PyPI on tag pushes, with dependency caching and environment setup.Dependency Management:
deeplabcut-liveinpyproject.tomlto==1.1to ensure compatbile packages (esp. torch) are available