Skip to content

Commit

Permalink
feat: Add Python bindings (#269)
Browse files Browse the repository at this point in the history
  • Loading branch information
DataTriny authored Jan 3, 2024
1 parent c8d1a56 commit 52560da
Show file tree
Hide file tree
Showing 21 changed files with 2,106 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ on:
release:
types:
- published
name: Publish bindings
name: Publish C bindings
jobs:
build-binaries:
if: startsWith(github.ref_name, 'accesskit_c-v')
Expand Down
13 changes: 13 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ jobs:
clang-format-version: 15
check-path: bindings/c

- name: ruff format
uses: chartboost/ruff-action@v1
with:
args: format --check

- name: ruff check
uses: chartboost/ruff-action@v1

test:
runs-on: ${{ matrix.os }}
strategy:
Expand All @@ -43,6 +51,11 @@ jobs:
toolchain: stable
components: clippy

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.9'

- name: restore cache
uses: Swatinem/rust-cache@v2

Expand Down
144 changes: 144 additions & 0 deletions .github/workflows/python-bindings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
on:
push:
tags:
- 'accesskit_python-v*'

name: Publish Python bindings

env:
MIN_PYTHON_VERSION: 3.9

jobs:
macos-wheels:
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
target: [x86_64, aarch64]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v5
with:
python-version: ${{ env.MIN_PYTHON_VERSION }}
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: --release --out dist
sccache: 'true'
- name: Test wheel installation
if: matrix.target == 'x86_64'
run: |
pip install accesskit --no-index --find-links dist --force-reinstall
python -c "import accesskit"
- name: Upload wheels
uses: actions/upload-artifact@v3
with:
name: wheels
path: dist

unix-wheels:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target: [x86_64, x86, aarch64]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v5
with:
python-version: ${{ env.MIN_PYTHON_VERSION }}
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: --release --out dist
sccache: 'true'
manylinux: auto
- name: Test wheel installation
if: matrix.target == 'x86_64'
run: |
pip install accesskit --no-index --find-links dist --force-reinstall
python -c "import accesskit"
- name: Upload wheels
uses: actions/upload-artifact@v3
with:
name: wheels
path: dist

windows-wheels:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
target: [x64, x86]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v5
with:
python-version: ${{ env.MIN_PYTHON_VERSION }}
architecture: ${{ matrix.target }}
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: --release --out dist
sccache: 'true'
- name: Test wheel installation
run: |
pip install accesskit --no-index --find-links dist --force-reinstall
python -c "import accesskit"
- name: Upload wheels
uses: actions/upload-artifact@v3
with:
name: wheels
path: dist

sdist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build sdist
uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out dist
- name: Upload sdist
uses: actions/upload-artifact@v3
with:
name: wheels
path: dist

pypi-release:
name: Publish to PyPI
environment: release
permissions:
id-token: write
if: "startsWith(github.ref, 'refs/tags/')"
needs: [macos-wheels, unix-wheels, windows-wheels, sdist]
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v3
with:
name: wheels
- uses: PyO3/maturin-action@v1
with:
command: upload
args: --non-interactive --skip-existing *

github-release:
name: Add to GitHub release
if: "startsWith(github.ref, 'refs/tags/')"
needs: [macos-wheels, unix-wheels, windows-wheels, sdist]
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v3
with:
name: wheels
path: dist

- uses: AButler/[email protected]
with:
files: "dist/*"
repo-token: ${{ secrets.GITHUB_TOKEN }}
release-tag: ${{ github.ref_name }}
18 changes: 18 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ members = [
"platforms/windows",
"platforms/winit",
"bindings/c",
"bindings/python",
]
default-members = [
"common",
"consumer",
"platforms/winit",
"bindings/c",
"bindings/python",
]

[profile.release]
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ While we expect GUI toolkit developers to eventually integrate AccessKit into th

### Language bindings

UI toolkit developers who merely want to use AccessKit should not be required to use Rust directly. In addition to a direct Rust API, AccessKit provides a C API covering both the core data structures and all platform adapters. This C API can be used from a variety of languages. The Rust source for the C bindings is in [the `bindings/c directory`](https://github.com/AccessKit/accesskit/tree/main/bindings/c). The AccessKit project also provides a pre-built package, including a header file, both dynamic and static libraries, and sample code, for the C API, so toolkit developers won't need to deal with Rust at all. The latest pre-built package can be found in [AccessKit's GitHub releases](https://github.com/AccessKit/accesskit/releases); search for the name "accesskit_c".
UI toolkit developers who merely want to use AccessKit should not be required to use Rust directly.

AccessKit provides a C API covering both the core data structures and all platform adapters. This C API can be used from a variety of languages. The Rust source for the C bindings is in [the `bindings/c directory`](https://github.com/AccessKit/accesskit/tree/main/bindings/c). The AccessKit project also provides a pre-built package, including a header file, both dynamic and static libraries, and sample code, for the C API, so toolkit developers won't need to deal with Rust at all. The latest pre-built package can be found in [AccessKit's GitHub releases](https://github.com/AccessKit/accesskit/releases); search for the name "accesskit_c".

Bindings for the Python programming language are also available. Rust source code is in [the `bindings/python directory`](https://github.com/AccessKit/accesskit/tree/main/bindings/python). Releases can be found on [PyPI](https://pypi.org/project/accesskit/) and can be included in your project using `pip`.

While many languages can use a C API, we also plan to provide libraries that make it easier to safely use AccessKit from languages other than Rust and C. In particular, we're planning to provide such a library for Java and other JVM-based languages.

Expand Down
11 changes: 11 additions & 0 deletions bindings/python/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[target.aarch64-apple-darwin]
rustflags = [
"-C", "link-arg=-undefined",
"-C", "link-arg=dynamic_lookup",
]

[target.x86_64-apple-darwin]
rustflags = [
"-C", "link-arg=-undefined",
"-C", "link-arg=dynamic_lookup",
]
30 changes: 30 additions & 0 deletions bindings/python/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[package]
name = "accesskit_python"
version = "0.1.0"
authors = ["Arnold Loubriat <[email protected]>"]
license = "MIT OR Apache-2.0"
description = "Python bindings to the AccessKit library"
readme = "README.md"
publish = false
edition = "2021"

[lib]
name = "accesskit"
crate-type = ["cdylib"]
doc = false

[features]
extension-module = ["pyo3/extension-module"]

[dependencies]
accesskit = { version = "0.12.1", path = "../../common", features = ["pyo3"] }
pyo3 = { version = "0.20", features = ["abi3-py39", "multiple-pymethods"] }

[target.'cfg(target_os = "windows")'.dependencies]
accesskit_windows = { version = "0.15.1", path = "../../platforms/windows" }

[target.'cfg(target_os = "macos")'.dependencies]
accesskit_macos = { version = "0.10.1", path = "../../platforms/macos" }

[target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd"))'.dependencies]
accesskit_unix = { version = "0.6.2", path = "../../platforms/unix" }
15 changes: 15 additions & 0 deletions bindings/python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# AccessKit

These are the bindings to use AccessKit from Python.

Documentation for the Rust packages can be found [here](https://docs.rs/accesskit/latest/accesskit/).

An example program showing how to integrate AccessKit in a pygame application is available [here](https://github.com/AccessKit/accesskit/tree/main/bindings/python/examples/pygame).

## Building from a Source Distribution

If there are no wheels available for your platform, you will have to build one yourself. You will need to have Rust installed on your system, so that the native libraries can be compiled. Please visit [rustup.rs](https://rustup.rs) for instructions on how to proceed.

## Building from within the repository

This project uses [maturin](https://github.com/PyO3/maturin) as its build tool. If you need to manually build wheels for development purposes, it is recommended to install it inside a virtual environment. All maturin commands must be issued from this repository's root directory.
Loading

0 comments on commit 52560da

Please sign in to comment.