Skip to main content

Tools for packaging and publishing to pypi for those who just do not want to deal with it

Project description

wads

Modern Python project packaging and CI/CD tools for developers who want to focus on code, not configuration.

PyPI version Python versions

What is Wads?

Wads helps you:

  • Create new Python projects with modern tooling (pyproject.toml, GitHub Actions)
  • Manage CI/CD workflows with configuration-driven GitHub Actions
  • Handle system dependencies declaratively in pyproject.toml
  • Migrate legacy projects from setup.cfg to modern formats
  • Debug CI failures with automated diagnostics

Installation

pip install wads          # light core: config reading + templating engine
pip install wads[create]  # full project-creation / publishing toolchain
pip install wads[all]     # create + docs

wads ships a light core (just enough to read [tool.wads.ci] / package.json config and run the templating engine — handy in CI) plus a heavier create extra (requests, build, wheel, ruamel.yaml) for scaffolding and publishing. Use wads[create] (or wads[all]) when running populate/pack to create or publish projects.

Quick Start

Create a New Project

populate my-project --root-url https://github.com/user/my-project
cd my-project

This creates a complete project structure with:

  • pyproject.toml (modern build configuration)
  • README.md, LICENSE, .gitignore
  • Package directory with __init__.py
  • GitHub Actions CI/CD workflow (optional)

Add NPM publishing for JS/TS components (optional)

Python projects often ship a small JS/TS component (a widget, a browser UI). populate --with-npm adds a parametrized NPM CI alongside the Python one, following the same "config-file-driven, fixed-workflow" model:

populate my-project --root-url https://github.com/user/my-project --with-npm

This adds:

  • js/package.json — standard npm manifest with a namespaced "wads" config block (wads.ci.*) controlling node versions, lint/test/build commands, and publishing — analogous to [tool.wads.ci] in pyproject.toml.
  • .github/workflows/npm-ci.yml — a stub calling wads's reusable NPM workflow.

Validation runs on every push/PR; publishing is opt-in. It publishes only when wads.ci.publish.enabled is true and the commit message contains the marker [publish-npm] (deliberately distinct from the Python side). Publishing uses npm OIDC trusted publishing + provenance by default (no long-lived token). Customize the subdirectory and package name with --npm-subdir / --npm-package-name; bring your own templates by pointing the generator at a different template source.

Package manager: npm or pnpm. The reusable workflow drives npm by default and pnpm when selected — either explicitly via wads.ci.packageManager (or populate --npm-package-manager pnpm) or auto-detected from a pnpm-lock.yaml in the package directory. pnpm consumers should declare a "packageManager": "pnpm@x.y.z" field in their package.json (pnpm's own convention); the CI reads the pnpm version from there. Existing npm consumers are unaffected (no pnpm-lock.yaml → npm).

Configure CI in pyproject.toml

Edit your pyproject.toml to configure CI behavior:

[tool.wads.ci.testing]
python_versions = ["3.10", "3.12"]
pytest_args = ["-v", "--tb=short"]
coverage_enabled = true
test_on_windows = true

[tool.wads.ci.quality.ruff]
enabled = true

[tool.wads.ci.build]
sdist = true
wheel = true

Declare System Dependencies

Need ffmpeg, ODBC drivers, or other system packages in CI? Declare them in pyproject.toml:

[tool.wads.ops.ffmpeg]
description = "Multimedia framework for video/audio processing"
url = "https://ffmpeg.org/"

check.linux = "which ffmpeg"
check.macos = "which ffmpeg"

install.linux = "sudo apt-get install -y ffmpeg"
install.macos = "brew install ffmpeg"
install.windows = "choco install ffmpeg -y"

note = "Required for audio processing features"

The install-system-deps action in your CI workflow will automatically install these.

Core Features

1. Project Setup (populate)

Create new Python projects with modern best practices:

# Basic usage
populate my-project

# With custom settings
populate my-project \
  --root-url https://github.com/myorg/my-project \
  --description "My awesome project" \
  --author "Your Name" \
  --license apache

Options:

  • --root-url: GitHub repository URL
  • --description: Project description
  • --author: Author name
  • --license: License type (mit, apache, bsd, etc.)
  • --keywords: Comma-separated keywords
  • --overwrite: Files to overwrite if they exist

Tip: Configure defaults in wads_configs.json or use WADS_CONFIGS_FILE environment variable to point to your custom config.

2. Package and Publish (pack)

Build and publish packages to PyPI:

# See current configuration
pack current-configs

# Increment version and publish
pack go .

# Or step-by-step
pack increment-configs-version
pack run-setup
pack twine-upload-dist

3. Migration Tools (wads-migrate)

Migrate legacy projects to modern format:

# Migrate setup.cfg to pyproject.toml
wads-migrate setup-to-pyproject setup.cfg -o pyproject.toml

# Migrate old CI workflow to new format
wads-migrate ci-old-to-new .github/workflows/old-ci.yml -o .github/workflows/ci.yml

Python API:

from wads.migration import migrate_setuptools_to_hatching, migrate_github_ci_old_to_new

# From setup.cfg file
pyproject_content = migrate_setuptools_to_hatching('setup.cfg')

# From setup.cfg dict
config = {'metadata': {'name': 'myproject', 'version': '1.0.0'}}
pyproject_content = migrate_setuptools_to_hatching(config)

# Migrate CI workflow
new_ci = migrate_github_ci_old_to_new('.github/workflows/ci.yml')

4. CI Debugging (wads-ci-debug)

Diagnose and fix GitHub Actions CI failures:

# Analyze latest failure
wads-ci-debug myorg/myrepo

# Analyze specific run
wads-ci-debug myorg/myrepo --run-id 1234567890

# Generate fix instructions
wads-ci-debug myorg/myrepo --fix --local-repo .

The tool will:

  • Fetch CI logs from GitHub
  • Parse test failures and errors
  • Identify root causes
  • Generate fix instructions with file locations and suggested changes

CI Configuration Reference

Wads uses pyproject.toml as a single source of truth for CI configuration. Here's what you can configure:

Install Extras

By default CI installs only your package's core dependencies. If your test suite needs an extra (e.g. a heavier create/dev group), declare it so CI installs .[extras]:

[tool.wads.ci.install]
extras = "dev"          # or a list, e.g. ["dev", "test"]

Python Versions and Testing

[tool.wads.ci.testing]
python_versions = ["3.10", "3.11", "3.12"]  # Test matrix
pytest_args = ["-v", "--tb=short"]           # Pytest arguments
coverage_enabled = true                      # Enable coverage
coverage_threshold = 80                      # Minimum coverage %
exclude_paths = ["examples", "scrap"]        # Paths to exclude
test_on_windows = true                       # Run Windows tests

Code Quality Tools

[tool.wads.ci.quality.ruff]
enabled = true
# line_length = 88

[tool.wads.ci.quality.mypy]
enabled = false
# strict = true

Custom Commands

[tool.wads.ci.commands]
pre_test = [
    "python scripts/setup_test_data.py",
]
post_test = [
    "python scripts/cleanup.py",
]

Build and Publish

[tool.wads.ci.build]
sdist = true
wheel = true

[tool.wads.ci.publish]
enabled = true  # Publish to PyPI on main/master

System Dependencies

System dependencies are declared using the [tool.wads.ops.*] format and automatically installed in CI via the install-system-deps action.

Format:

[tool.wads.ops.{package-name}]
description = "Description of the package"
url = "https://package-homepage.com"

# Check if already installed (exit code 0 = present)
check.linux = "which package-name"
check.macos = "brew list package-name"
check.windows = "where package-name"

# Install commands (string or list of strings)
install.linux = "sudo apt-get install -y package-name"
install.macos = "brew install package-name"
install.windows = "choco install package-name -y"

# Optional metadata
note = "Additional installation notes"
alternatives = ["alternative-package"]

Real-world example (ODBC drivers):

[tool.wads.ops.unixodbc]
description = "ODBC driver interface for database connectivity"
url = "https://www.unixodbc.org/"

check.linux = "dpkg -s unixodbc || rpm -q unixODBC"
check.macos = "brew list unixodbc"

install.linux = [
    "sudo apt-get update",
    "sudo apt-get install -y unixodbc unixodbc-dev"
]
install.macos = "brew install unixodbc"

note = "On Alpine: apk add unixodbc unixodbc-dev"
alternatives = ["iodbc"]

See docs/SYSTEM_DEPENDENCIES.md for comprehensive examples.

Claude Code Skills

Wads ships with Claude Code skills for AI-assisted workflows. Install them globally so they're available in every project:

wads-install-skills

This symlinks skills to ~/.claude/skills/, so they stay in sync when wads is updated:

Command Description
/setup-py-project AI-guided Python project creation: name suggestions, PyPI/GitHub availability checking, repo creation, file population
/wads-migrate Migrate projects to modern wads setup (pyproject.toml + uv CI)

Example:

/setup-py-project "a tool for audio signal processing"

To list available skills without installing: wads-install-skills --list To update existing skills: wads-install-skills --force

Documentation

Troubleshooting

Version Tag Misalignment

If PyPI publishing fails with "appears to already exist":

WARNING  Skipping mypackage-0.1.4-py3-none-any.whl because it appears to already exist

This means your git tags are misaligned with the version in pyproject.toml.

Fix:

  1. Check the current PyPI version: https://pypi.org/project/your-package/
  2. Update version in pyproject.toml to a higher number
  3. Create and push git tag:
    git tag 0.1.5
    git push origin 0.1.5
    

CI Failures

Use wads-ci-debug to analyze failures:

wads-ci-debug myorg/myrepo --fix

Common issues:

  • Missing system dependencies → Add to [tool.wads.ops.*]
  • Python version incompatibilities → Check python_versions in [tool.wads.ci.testing]
  • Test failures → Review generated fix instructions

Development

Running Tests

pytest wads/tests/

Building Documentation

pip install -e ".[docs]"
epythet build

License

Apache Software License 2.0

Links

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wads-0.1.96.tar.gz (317.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wads-0.1.96-py3-none-any.whl (266.2 kB view details)

Uploaded Python 3

File details

Details for the file wads-0.1.96.tar.gz.

File metadata

  • Download URL: wads-0.1.96.tar.gz
  • Upload date:
  • Size: 317.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for wads-0.1.96.tar.gz
Algorithm Hash digest
SHA256 4ac6f69dd83897ffd9ed135f4516c35d7e969c40759b0b3dfccc7854de80e229
MD5 e83ae7090f4b68851d4343e1aaebd9c0
BLAKE2b-256 bb343325156fa27f0201f301c6e25e72650efdf93cfcaca9b14a4552d68ff105

See more details on using hashes here.

File details

Details for the file wads-0.1.96-py3-none-any.whl.

File metadata

  • Download URL: wads-0.1.96-py3-none-any.whl
  • Upload date:
  • Size: 266.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for wads-0.1.96-py3-none-any.whl
Algorithm Hash digest
SHA256 dec0422483824e15e41c77263e1d3d6040cf83b97f59b7759386278542b59c82
MD5 ce97bd9928f2b48742876311deb349ce
BLAKE2b-256 51e0b3b7a07f22f82543a31b5f7140361ea4cc3e3860107508ae1d609ca523fe

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page