Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ repos:
rev: v0.782
hooks:
- id: mypy
files: cibuildwheel/|test/
files: ^(cibuildwheel/|test/|bin/projects.py)
pass_filenames: false
165 changes: 119 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,52 +105,125 @@ For more information, including how to build on GitHub Actions, Appveyor, Azure
Options
-------

| | Option | Description |
|---|--------|-------------|
| **Build selection** | [`CIBW_PLATFORM`](https://cibuildwheel.readthedocs.io/en/stable/options/#platform) | Override the auto-detected target platform |
| | [`CIBW_BUILD`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-skip) <br> [`CIBW_SKIP`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-skip) | Choose the Python versions to build |
| **Build customization** | [`CIBW_ENVIRONMENT`](https://cibuildwheel.readthedocs.io/en/stable/options/#environment) | Set environment variables needed during the build |
| | [`CIBW_BEFORE_ALL`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-all) | Execute a shell command on the build system before any wheels are built. |
| | [`CIBW_BEFORE_BUILD`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-build) | Execute a shell command preparing each wheel's build |
| | [`CIBW_REPAIR_WHEEL_COMMAND`](https://cibuildwheel.readthedocs.io/en/stable/options/#repair-wheel-command) | Execute a shell command to repair each (non-pure Python) built wheel |
| | [`CIBW_MANYLINUX_X86_64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_I686_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_PYPY_X86_64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_AARCH64_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_PPC64LE_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) <br> [`CIBW_MANYLINUX_S390X_IMAGE`](https://cibuildwheel.readthedocs.io/en/stable/options/#manylinux-image) | Specify alternative manylinux docker images |
| | [`CIBW_DEPENDENCY_VERSIONS`](https://cibuildwheel.readthedocs.io/en/stable/options/#dependency-versions) | Specify how cibuildwheel controls the versions of the tools it uses |
| **Testing** | [`CIBW_TEST_COMMAND`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-command) | Execute a shell command to test each built wheel |
| | [`CIBW_BEFORE_TEST`](https://cibuildwheel.readthedocs.io/en/stable/options/#before-test) | Execute a shell command before testing each wheel |
| | [`CIBW_TEST_REQUIRES`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-requires) | Install Python dependencies before running the tests |
| | [`CIBW_TEST_EXTRAS`](https://cibuildwheel.readthedocs.io/en/stable/options/#test-extras) | Install your wheel for testing using extras_require |
| **Other** | [`CIBW_BUILD_VERBOSITY`](https://cibuildwheel.readthedocs.io/en/stable/options/#build-verbosity) | Increase/decrease the output of pip wheel |


Working examples
----------------

Here are some repos that use cibuildwheel.

- [Matplotlib](https://github.com/matplotlib/matplotlib) - The venerable Matplotlib, a Python library with C++ portions, built for Linux, Mac, and Windows on Github Actions.
- [pyinstrument_cext](https://github.com/joerick/pyinstrument_cext) - A simple C extension, without external dependencies, built on Travis CI/Appveyor.
- [websockets](https://github.com/aaugustin/websockets)
- [Parselmouth](https://github.com/YannickJadoul/Parselmouth) - A Python interface to the Praat software package, using pybind11, C++17 and CMake, with the core Praat static library built only once and shared between wheels; all platforms built on Github Actions.
- [python-admesh](https://github.com/admesh/python-admesh)
- [pybase64](https://github.com/mayeut/pybase64)
- [KDEpy](https://github.com/tommyod/KDEpy)
- [AutoPy](https://github.com/autopilot-rs/autopy)
- [apriltags2-ethz](https://github.com/safijari/apriltags2_ethz)
- [TgCrypto](https://github.com/pyrogram/tgcrypto)
- [twisted-iocpsupport](https://github.com/twisted/twisted-iocpsupport) - A submodule of Twisted that hooks into native C APIs using Cython. Built on Github CI for Windows.
- [gmic-py](https://github.com/dtschump/gmic-py)
- [creme](https://github.com/creme-ml/creme)
- [PyAV](https://github.com/PyAV-Org/PyAV)
- [aiortc](https://github.com/aiortc/aiortc)
- [aioquic](https://github.com/aiortc/aioquic)
- [pikepdf](https://github.com/pikepdf/pikepdf)
- [fathon](https://github.com/stfbnc/fathon)
- [etebase-py](https://github.com/etesync/etebase-py) - Python bindings to a Rust library using `setuptools-rust`, and `sccache` for improved speed, built on Travis CI.
- [xmlstarlet](https://github.com/dimitern/xmlstarlet) - Python 3.6+ CFFI bindings with true MSVC build and GitHub Actions.
- [bx-python](https://github.com/bxlab/bx-python) - A library that includes Cython extensions, built on Travis CI for Mac and Linux.
- [coverage.py](https://github.com/nedbat/coveragepy) - The coverage tool for Python.

> Add your repo here! Send a PR.
<!-- START bin/project.py -->

| Name | CI | OS | Notes |
|-----------------------------------|----|----|:------|
| [scikit-learn][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | :closed_book: scikit-learn: machine learning in Python |
| [Matplotlib][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The venerable Matplotlib, a Python library with C++ portions |
| [twisted-iocpsupport][] | ![github icon][] | ![windows icon][] | A submodule of Twisted that hooks into native C APIs using Cython. |
| [scikit-image][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | :closed_book: Image processing in Python |
| [websockets][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | :closed_book: Library for building WebSocket servers and clients in Python |
| [pyzmq][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | :closed_book: PyZMQ: Python bindings for zeromq |
| [aiortc][] | ![github icon][] | ![apple icon][] ![linux icon][] | WebRTC and ORTC implementation for Python using asyncio. |
| [h5py][] | ![azurepipelines icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | :closed_book: HDF5 for Python -- The h5py package is a Pythonic interface to the HDF5 binary data format. |
| [coverage.py][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | The coverage tool for Python |
| [River][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | :closed_book: 🌊 Online machine learning in Python |
| [PyAV][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Pythonic bindings for FFmpeg's libraries. |
| [google/neuroglancer][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | :closed_book: WebGL-based viewer for volumetric data |
| [aioquic][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | :closed_book: QUIC and HTTP/3 implementation in Python |
| [AutoPy][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. |
| [pikepdf][] | ![azurepipelines icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | :closed_book: A Python library for reading and writing PDF, powered by qpdf |
| [Parselmouth][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A Python interface to the Praat software package, using pybind11, C++17 and CMake, with the core Praat static library built only once and shared between wheels. |
| [python-rapidjson][] | ![travisci icon][] ![gitlab icon][] ![appveyor icon][] | ![windows icon][] ![linux icon][] | :closed_book: Python wrapper around rapidjson |
| [KDEpy][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | :closed_book: Kernel Density Estimation in Python |
| [pybind11:python_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | :closed_book: Example pybind11 module built with a Python-based build system |
| [pybind11:cmake_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | :closed_book: Example pybind11 module built with a CMake-based build system |
| [iminuit][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | :closed_book: Jupyter-friendly Python interface for C++ MINUIT2 |
| [jq.py][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | :closed_book: Python bindings for jq |
| [bx-python][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | A library that includes Cython extensions. |
| [boost-histogram][] | ![github icon][] ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Supports full range of wheels, including PyPy and alternate archs. |
| [pybase64][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | :closed_book: Fast Base64 encoding/decoding in Python |
| [TgCrypto][] | ![travisci icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Includes a Windows Travis build. |
| [etebase-py][] | ![travisci icon][] | ![linux icon][] | Python bindings to a Rust library using `setuptools-rust`, and `sccache` for improved speed. |
| [pyjet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | :closed_book: The interface between FastJet and NumPy |
| [numpythia][] | ![github icon][] | ![apple icon][] ![linux icon][] | :closed_book: The interface between PYTHIA and NumPy |
| [fathon][] | ![travisci icon][] | ![apple icon][] ![linux icon][] | :closed_book: python package for DFA (Detrended Fluctuation Analysis) and related algorithms |
| [pyinstrument_cext][] | ![travisci icon][] ![appveyor icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | A simple C extension, without external dependencies |
| [xmlstarlet][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | Python 3.6+ CFFI bindings with true MSVC build. |
| [pybind11:scikit_build_example][] | ![github icon][] | ![windows icon][] ![apple icon][] ![linux icon][] | :closed_book: An example combining scikit-build and pybind11 |

[scikit-learn]: https://github.com/scikit-learn/scikit-learn
[Matplotlib]: https://github.com/matplotlib/matplotlib
[twisted-iocpsupport]: https://github.com/twisted/twisted-iocpsupport
[scikit-image]: https://github.com/scikit-image/scikit-image
[websockets]: https://github.com/aaugustin/websockets
[pyzmq]: https://github.com/zeromq/pyzmq
[aiortc]: https://github.com/aiortc/aiortc
[h5py]: https://github.com/h5py/h5py
[coverage.py]: https://github.com/nedbat/coveragepy
[River]: https://github.com/online-ml/river
[PyAV]: https://github.com/PyAV-Org/PyAV
[google/neuroglancer]: https://github.com/google/neuroglancer
[aioquic]: https://github.com/aiortc/aioquic
[AutoPy]: https://github.com/autopilot-rs/autopy
[pikepdf]: https://github.com/pikepdf/pikepdf
[Parselmouth]: https://github.com/YannickJadoul/Parselmouth
[python-rapidjson]: https://github.com/python-rapidjson/python-rapidjson
[KDEpy]: https://github.com/tommyod/KDEpy
[pybind11:python_example]: https://github.com/pybind/python_example
[pybind11:cmake_example]: https://github.com/pybind/cmake_example
[iminuit]: https://github.com/scikit-hep/iminuit
[jq.py]: https://github.com/mwilliamson/jq.py
[bx-python]: https://github.com/bxlab/bx-python
[boost-histogram]: https://github.com/scikit-hep/boost-histogram
[pybase64]: https://github.com/mayeut/pybase64
[TgCrypto]: https://github.com/pyrogram/tgcrypto
[etebase-py]: https://github.com/etesync/etebase-py
[pyjet]: https://github.com/scikit-hep/pyjet
[numpythia]: https://github.com/scikit-hep/numpythia
[fathon]: https://github.com/stfbnc/fathon
[pyinstrument_cext]: https://github.com/joerick/pyinstrument_cext
[xmlstarlet]: https://github.com/dimitern/xmlstarlet
[pybind11:scikit_build_example]: https://github.com/pybind/scikit_build_example

[appveyor icon]: https://cdn.jsdelivr.net/npm/simple-icons@v4/icons/appveyor.svg
[github icon]: https://cdn.jsdelivr.net/npm/simple-icons@v4/icons/github.svg
[azurepipelines icon]: https://cdn.jsdelivr.net/npm/simple-icons@v4/icons/azurepipelines.svg
[circleci icon]: https://cdn.jsdelivr.net/npm/simple-icons@v4/icons/circleci.svg
[gitlab icon]: https://cdn.jsdelivr.net/npm/simple-icons@v4/icons/gitlab.svg
[travisci icon]: https://cdn.jsdelivr.net/npm/simple-icons@v4/icons/travisci.svg
[windows icon]: https://cdn.jsdelivr.net/npm/simple-icons@v4/icons/windows.svg
[apple icon]: https://cdn.jsdelivr.net/npm/simple-icons@v4/icons/apple.svg
[linux icon]: https://cdn.jsdelivr.net/npm/simple-icons@v4/icons/linux.svg

<!-- scikit-learn: 43307, last pushed 0 days ago -->
<!-- Matplotlib: 12725, last pushed 0 days ago -->
<!-- twisted-iocpsupport: 4100, last pushed 0 days ago -->
<!-- scikit-image: 4078, last pushed 0 days ago -->
<!-- websockets: 3058, last pushed 6 days ago -->
<!-- pyzmq: 2651, last pushed 4 days ago -->
<!-- aiortc: 2052, last pushed 5 days ago -->
<!-- h5py: 1450, last pushed 4 days ago -->
<!-- coverage.py: 1424, last pushed 0 days ago -->
<!-- River: 1162, last pushed 0 days ago -->
<!-- PyAV: 1106, last pushed 26 days ago -->
<!-- google/neuroglancer: 545, last pushed 0 days ago -->
<!-- aioquic: 538, last pushed 33 days ago -->
<!-- AutoPy: 501, last pushed 89 days ago -->
<!-- pikepdf: 471, last pushed 6 days ago -->
<!-- Parselmouth: 424, last pushed 10 days ago -->
<!-- python-rapidjson: 406, last pushed 1 days ago -->
<!-- KDEpy: 224, last pushed 7 days ago -->
<!-- pybind11:python_example: 218, last pushed 27 days ago -->
<!-- pybind11:cmake_example: 216, last pushed 11 days ago -->
<!-- iminuit: 164, last pushed 0 days ago -->
<!-- jq.py: 137, last pushed 57 days ago -->
<!-- bx-python: 95, last pushed 70 days ago -->
<!-- boost-histogram: 60, last pushed 3 days ago -->
<!-- pybase64: 51, last pushed 0 days ago -->
<!-- TgCrypto: 48, last pushed 19 days ago -->
<!-- etebase-py: 39, last pushed 6 days ago -->
<!-- pyjet: 27, last pushed 12 days ago -->
<!-- numpythia: 23, last pushed 11 days ago -->
<!-- fathon: 16, last pushed 44 days ago -->
<!-- pyinstrument_cext: 9, last pushed 12 days ago -->
<!-- xmlstarlet: 7, last pushed 0 days ago -->
<!-- pybind11:scikit_build_example: 1, last pushed 25 days ago -->

<!-- END bin/project.py -->

> Add your repo here! Send a PR, adding your information to `bin/projects.yml`.
>
> <sup>I'd like to include notes here to indicate why an example might be interesting to cibuildwheel users - the styles/technologies/techniques used in each. Please include that in future additions!</sup>

Expand Down
169 changes: 169 additions & 0 deletions bin/projects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
#!/usr/bin/env python3

"""
Convert a yaml project list into a nice table.

Suggested usage:

./bin/projects.py bin/projects.yml --online --auth $GITHUB_API_TOKEN --readme README.md
git diff
"""

import builtins
import functools
from datetime import datetime
from io import StringIO
from typing import Dict, Any, List, Optional, TextIO

import click
import yaml
from github import Github


ICONS = (
"appveyor",
"github",
"azurepipelines",
"circleci",
"gitlab",
"travisci",
"windows",
"apple",
"linux",
)


class Project:
NAME: int = 0

def __init__(self, config: Dict[str, Any], github: Optional[Github] = None):
try:
self.name: str = config["name"]
self.gh: str = config["gh"]
except KeyError:
print("Invalid config, needs at least gh and name!", config)
raise

self.stars_repo: str = config.get("stars", self.gh)
self.notes: str = config.get("notes", "")
self.ci: List[str] = config.get("ci", [])
self.os: List[str] = config.get("os", [])

self.online = github is not None
if github is not None:
repo = github.get_repo(self.stars_repo)
self.num_stars = repo.stargazers_count
self.pushed_at = repo.pushed_at
if not self.notes:
notes = repo.description
if notes:
self.notes = f":closed_book: {notes}"
else:
self.num_stars = 0
self.pushed_at = datetime.utcnow()

name_len = len(self.name) + 4
self.__class__.NAME = max(self.__class__.NAME, name_len)

def __lt__(self, other: "Project") -> bool:
if self.online:
return self.num_stars < other.num_stars
else:
return self.name < other.name

@classmethod
def header(cls) -> str:
return (
f"| {'Name':{cls.NAME}} | CI | OS | Notes |\n"
f"|{'':-^{cls.NAME+2 }}|----|----|:------|"
)

@property
def namelink(self) -> str:
return f"[{self.name}][]"

@property
def starslink(self) -> str:
return f"![{self.name} stars][]"

@property
def url(self) -> str:
return f"https://github.com/{self.gh}"

@property
def ci_icons(self) -> str:
return " ".join(f"![{icon} icon][]" for icon in self.ci)

@property
def os_icons(self) -> str:
return " ".join(f"![{icon} icon][]" for icon in self.os)

def table_row(self) -> str:
return f"| {self.namelink: <{self.NAME}} | {self.ci_icons} | {self.os_icons} | {self.notes} |"

def links(self) -> str:
return f"[{self.name}]: {self.url}"

def info(self) -> str:
days = (datetime.utcnow() - self.pushed_at).days
return f"<!-- {self.name}: {self.num_stars}, last pushed {days} days ago -->"


def str_projects(
config: List[Dict[str, Any]], *, online: bool = True, auth: Optional[str] = None
) -> str:
io = StringIO()
print = functools.partial(builtins.print, file=io)

github = Github(auth) if online else None

projects = sorted((Project(item, github) for item in config), reverse=online)

print(Project.header())
for project in projects:
print(project.table_row())

print()
for project in projects:
print(project.links())

print()
for icon in ICONS:
print(
f"[{icon} icon]: https://cdn.jsdelivr.net/npm/simple-icons@v4/icons/{icon}.svg"
)

print()
for project in projects:
print(project.info())

return io.getvalue()


@click.command()
@click.argument("input", type=click.File("r"))
@click.option("--online/--no-online", default=True, help="Get info from GitHub")
@click.option("--auth", help="GitHub authentication token")
@click.option("--readme", type=click.File("r+"), help="Modify a readme file if given")
def projects(
input: TextIO, online: bool, auth: Optional[str], readme: Optional[TextIO]
) -> None:
config = yaml.safe_load(input)
output = str_projects(config, online=online, auth=auth)

if readme is None:
print(output)
else:
text = readme.read()
start_str = "<!-- START bin/project.py -->\n"
start = text.find(start_str)
end = text.find("<!-- END bin/project.py -->\n")
new_text = f"{text[:start + len(start_str)]}\n{output}\n{text[end:]}"

readme.seek(0)
readme.write(new_text)
readme.truncate()


if __name__ == "__main__":
projects()
Loading