Skip to content

feat: Add Python bindings #269

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
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/upload-release-assets@v2.0
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 <datatriny@gmail.com>"]
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