Skip to main content

binary-wheel-builder

PyPI version PyPI - Downloads LICENSE CircleCI codecov Quality Gate Status Code Smells Maintainability Rating Security Rating Renovate


Build deterministic python wheels to distribute CLI tools (third party or your own with python and make them easily usable using python code.

Features

  • deterministic wheel file output
  • Use with Python Code or as CLI
  • Prebuilt data sources for your binaries
  • Ready to release and ship your binaries
  • Wrapper for cli calls inside Python
  • Exposes wheel as module entrypoint (python -m your_cli) and adds to path (your-cli)

Requirements

  • Python 3.8+ for host running wheel build
  • For target host every 3.x should work

Installation

... with pip

# with CLI dependencies
pip install binary_wheel_builder[cli]

# as SDK
pip install binary_wheel_builder

... with pipx

pipx install binary_wheel_builder[cli]

Usage

Build with CLI

  1. Create your config file e. g. my-cli-wheel.yaml:
    package: my_cli
    executable: my-cli-bin
    name: my-cli
    version: 0.0.1
    summary: My CLI provides nice and clean functionality on the terminal
    description: !FileContent README.md
    license: MIT
    requires_python: ">=3.8"
    classifier:
       - "License :: OSI Approved :: MIT License"
       # Check https://pypi.org/classifiers/ for all available
    project_urls:
       # Set project urls as you like
       "Homepage": "https://github.com/my-org/my-cli"
       "Source Code": "https://github.com/my-org/my-cli,git"
       "Bug Tracker": "https://github.com/my-org/my-cli/issues"
    source: !WheelSource
      # Fetch binary from GitHub releases
      implementation: binary_wheel_builder.api.wheel_sources.GithubReleaseBinarySource
      project_slug: my-org/my-cli
      version: "0.0.1"
      tag_prefix: "" # e.g. set to v when your tag is vX.Y.Z
     # Path of the binary relative to your package root
      binary_path: my_cli/my-cli-bin
      # Download file name based on platform the wheel is built for
      asset_name_mapping:
        !WellknownPlatform MAC_SILICON: "mycli-darwin-arm64"
        !WellknownPlatform MAC_INTEL: "mycli-darwin-amd64"
        !WellknownPlatform LINUX_GENERIC_x86_64: "my-cli-linux-amd64"
        !WellKnownPlatform LINUX_GENERIC_aarch64: "my-cli-linux-arm"
      # Supported platforms by the wheel
      platforms:
        - !WellknownPlatform MAC_INTEL
        - !WellknownPlatform MAC_SILICON
        - !WellknownPlatform LINUX_GENERIC_x86_64
        - !WellKnownPlatform LINUX_GENERIC_aarch64
    
  2. Build your wheel for all platforms
    binary-wheel-builder --wheel-spec my-cli-wheel.yaml
    
  3. Upload your wheel files using twine:
    twine upload -r pypi dist/*
    
  4. Enjoy and consume your CLI as a package

If you want to have auto complete and validation right in the IDE, you can use the JSON Schema.

Build with Python code

If you prefer to write Python Code you use almost the same structure:

from pathlib import Path

from binary_wheel_builder.api import build_wheel, Wheel, well_known_platforms
from binary_wheel_builder.api.wheel_sources import GithubReleaseBinarySource


# Add a custom github release source
class MyCliGithubReleaseSource(GithubReleaseBinarySource):
    def __init__(self, version: str):
        super().__init__(
            "my-org/my-repo",
            version,
            {
                well_known_platforms.MAC_SILICON: "mycli-darwin-arm64",
                well_known_platforms.MAC_INTEL: "mycli-darwin-amd64",
                well_known_platforms.LINUX_GENERIC_x86_64: "my-cli-linux-amd64",
                well_known_platforms.LINUX_GENERIC_aarch64: "my-cli-linux-arm",
            },
            "my_cli/my-cli-bin"
        )


dist_folder = Path("dist")

print("Built wheels:")
for result in build_wheel(
        Wheel(
            package="my_cli",
            executable="my-cli-bin",
            name="my-cli",
            version="0.0.1",
            summary='My CLI provides nice and clean functionality on the terminal',
            license='MIT',
            requires_python=">=3.9",
            classifier=[
                'License :: OSI Approved :: MIT License',
                # Check https://pypi.org/classifiers/ for all available
            ],
            project_urls={
                'Homepage': 'https://github.com/my-org/my-cli',
                'Source Code': 'https://github.com/my-org/my-cli,git',
                'Bug Tracker': 'https://github.com/my-org/my-cli/issues',
            },
            source=MyCliGithubReleaseSource("0.0.1"),
            platforms=[
                well_known_platforms.MAC_INTEL,
                well_known_platforms.MAC_SILICON,
                well_known_platforms.LINUX_GENERIC_x86_64,
                well_known_platforms.LINUX_GENERIC_aarch64
            ]
        ),
        dist_folder
):
    print(f" > {result.file_path} [{result.checksum}]")

Afterwards upload with twine: Upload your wheel files using twine:

twine upload -r pypi dist/*

Using the generated wheel

With python module call

python -m my_cli

Using wrapper in path

my-cli

Using in Python code using exec utils

import subprocess

from my_cli import exec

# Run process and prefix stdout and stderr
exec.exec_with_templated_output(["--help"])

# Create a subprocess, specifying how to handle stdout, stderr
exec.create_subprocess(["--help"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

# Perform command with suppressed output and return finished proces instance,
# on that one can also check if the call was successfully
exec.exec_silently(["--version"])

Motivation

Sometimes managing CLI dependencies for tooling etc. can become quite a pain.

Also sometimes there are just so many options to distribute binaries, but Python is preinstalled on almost any nix machine. This opens great possibilities with using pip(x) to install dependencies or even reuse standalone CLI applications as regular dependency in your code.

Documentation

Contributing

I love your input! I want to make contributing to this project as easy and transparent as possible, whether it's:

  • Reporting a bug
  • Discussing the current state of the configuration
  • Submitting a fix
  • Proposing new features
  • Becoming a maintainer

To get started please read the Contribution Guidelines.

Development

Requirements

  • Python 3.8+
  • Poetry

Test

Integration Tests

poetry run pytest integration_tests/

Unit Tests

poetry run pytest binary_wheel_builder/

Build

poetry install

Alternatives

  • Using platform native package management
  • curl'ing dependencies

Metadata

Release files for binary_wheel_builder 3.15.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for binary_wheel_builder 3.15.1
File Size Uploaded
binary_wheel_builder-3.15.1.tar.gz 23.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for binary_wheel_builder 3.15.1
File Interpreter ABI Platform
binary_wheel_builder-3.15.1-py3-none-any.whl Python 3 none any Details

Total release size: 53.2 kB

Release files / binary_wheel_builder-3.15.1.tar.gz

Download URL binary_wheel_builder-3.15.1.tar.gz
Size 23.8 kB
Tags Source
SHA-256 checksum
How to use checksums
c810c22ffe0efac5ba41e410acd863832914e6f7e828fc56167fc52ad579d097
BLAKE2b-256 checksum
How to use checksums
52e630bfe07d9263f05bb7c66e386ab4123e4ec27d72dd1d5a1a6cf04d5eea31
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.5.1 CPython/3.12.15 Linux/7.0.0-1013-aws

Release files / binary_wheel_builder-3.15.1-py3-none-any.whl

Download URL binary_wheel_builder-3.15.1-py3-none-any.whl
Size 29.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c2325b17d24052ff6d5cd53d1d1991090ea87ec43f374ffffd9b66de62e17df8
BLAKE2b-256 checksum
How to use checksums
f87fb1089c4a7ce8e3330a2c89957e264ee6e7f63d9436cfa9ee21b518e97cae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.5.1 CPython/3.12.15 Linux/7.0.0-1013-aws

Release history Release notifications | RSS feed

This release

3.15.1 This release

2 release files

3.14.2

2 release files

3.14.1

2 release files

3.14.0

2 release files

3.13.0

2 release files

3.12.3

2 release files

3.12.2

2 release files

3.12.1

2 release files

3.12.0

2 release files

3.11.2

2 release files

3.11.1

2 release files

3.11.0

2 release files

3.10.9

2 release files

3.10.8

2 release files

3.10.4

2 release files

3.10.3

2 release files

3.10.1

2 release files

3.10.0

2 release files

3.9.0

2 release files

3.8.0

2 release files

3.7.5

2 release files

3.7.4

2 release files

3.7.3

2 release files

3.7.2

2 release files

3.7.1

2 release files

3.7.0

2 release files

3.6.1

2 release files

3.6.0

2 release files

3.5.4

2 release files

3.5.3

2 release files

3.5.2

2 release files

3.5.1

2 release files

3.5.0

2 release files

3.4.0

2 release files

3.3.0

2 release files

3.2.0

2 release files

3.1.1

2 release files

3.1.0

2 release files

3.0.0

2 release files

2.1.1

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.3.2

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page