Skip to content

Commit 7974866

Browse files
committed
python: Add async client, update pyo3
* Support for running maturin commands with uv * set `PSP_UV=1` in environment * use `uv venv` to create venv, then activate it * `uv pip install -r **/requirements.txt` to install requirements * Update pyo3 from 0.21 to 0.23 * this was to support use of the `pyo3-async-runtimes` crate * Build `abi3` .so when building with `maturin develop` * **Caveat**: after this change, old non-abi3 .so's still lingering in the rust/perspective-python directory may be loaded preferentially by Python when using an editable install. It is best to delete those old .so's. * Repurpose PyClient as AsyncClient and export bindings to Python * Add async client pytests for both cpython and pyodide * Uses `pytest-asyncio` plugin * Add python and pytest vscode settings * Supports running cpython pytest suite from vscode's Test Explorer Signed-off-by: Tom Jakubowski <[email protected]>
1 parent 550d5ed commit 7974866

28 files changed

+649
-255
lines changed

.devcontainer/postcreate.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,8 @@ sudo apt-get update
1313
sudo apt-get install -y kitware-archive-keyring
1414
sudo apt-get install -y cmake
1515

16+
# Install uv
17+
curl -LsSf https://astral.sh/uv/install.sh | sh
18+
1619
# Repo setup
1720
pnpm install

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,5 @@ rust/target*
5858
Vagrantfile
5959
vcpkg
6060
venv/
61-
rust/perspective-python/perspective_python-*.data
61+
rust/perspective-python/perspective_python-*.data
62+
.pytest-cache/

.vscode/settings.default.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
"PSP_ENABLE_WASM": "1"
77
},
88
"python.formatting.provider": "black",
9+
"python.testing.pytestEnabled": true,
10+
"python.testing.pytestArgs": [
11+
"rust/perspective-python/perspective/tests/"
12+
],
913
"rust-analyzer.server.extraEnv": {
1014
"PSP_ROOT_DIR": "../..",
1115
"PSP_DISABLE_CPP": "1",

Cargo.lock

Lines changed: 57 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-lock.yaml

Lines changed: 9 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/perspective-python/Cargo.toml

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ crate-type = ["cdylib"]
5656
[build-dependencies]
5757
cmake = "0.1.50"
5858
num_cpus = "^1.16.0"
59-
pyo3-build-config = "0.20.2"
59+
pyo3-build-config = "0.22.6"
6060
python-config-rs = "0.1.2"
6161

6262
[dependencies]
@@ -67,7 +67,22 @@ async-lock = "2.5.0"
6767
pollster = "0.3.0"
6868
extend = "1.1.2"
6969
futures = "0.3.28"
70-
pyo3 = { version = "0.21.2", features = ["extension-module", "serde"] }
71-
pythonize = "0.21.1"
70+
pyo3 = { version = "0.23.4", features = [
71+
"experimental-async",
72+
"extension-module",
73+
"serde",
74+
"py-clone",
75+
] }
76+
pythonize = "0.23.0"
7277
tracing = { version = ">=0.1.36" }
7378
tracing-subscriber = { version = "0.3.15", features = ["env-filter"] }
79+
80+
[target.'cfg(target_os="emscripten")'.dependencies]
81+
pyo3-async-runtimes = { version = "0.23", features = ["attributes"] }
82+
83+
[target.'cfg(not(target_os="emscripten"))'.dependencies]
84+
pyo3-async-runtimes = { version = "0.23", features = [
85+
"attributes",
86+
"tokio-runtime",
87+
] }
88+
tokio = { version = "1.43.0", features = ["full"] }

rust/perspective-python/build.mjs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import * as fs from "node:fs";
1414
import sh from "../../tools/perspective-scripts/sh.mjs";
1515
import * as url from "url";
16-
import * as TOML from "@iarna/toml";
16+
import * as toml from "smol-toml";
1717
import * as tar from "tar";
1818
import * as glob from "glob";
1919
import * as path from "path";
@@ -114,10 +114,10 @@ if (build_wheel) {
114114
if (build_sdist) {
115115
// `maturin sdist` has some issues with Cargo workspaces, so we assemble the sdist by hand here
116116
// Note that the resulting sdist is _not_ a Cargo workspace, it is rooted in this package.
117-
const cargo_toml = fs.readFileSync("./Cargo.toml");
118-
const pyproject_toml = fs.readFileSync("./pyproject.toml");
119-
const cargo = TOML.parse(cargo_toml);
120-
const pyproject = TOML.parse(pyproject_toml);
117+
const cargo_toml = fs.readFileSync("./Cargo.toml").toString('utf-8');
118+
const pyproject_toml = fs.readFileSync("./pyproject.toml").toString('utf-8');
119+
const cargo = toml.parse(cargo_toml);
120+
const pyproject = toml.parse(pyproject_toml);
121121

122122
const version = cargo["package"]["version"];
123123
const data_dir = `perspective_python-${version}.data`;
@@ -153,8 +153,16 @@ if (build_sdist) {
153153
);
154154
}
155155

156+
if (process.env['PSP_UV'] === '1') {
157+
flags += ' --uv'
158+
}
159+
156160
if (!build_wheel && !build_sdist) {
157-
cmd.sh(`maturin develop --features=external-docs ${flags} ${target}`);
161+
const dev_features = [
162+
"abi3",
163+
"external-docs",
164+
];
165+
cmd.sh(`maturin develop --features=${dev_features.join(',')} ${flags} ${target}`);
158166
}
159167

160168
if (!cmd.isEmpty()) {

rust/perspective-python/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
},
1717
"devDependencies": {
1818
"@finos/perspective-scripts": "workspace:*",
19-
"@iarna/toml": "^1.0.0-rc.1",
19+
"smol-toml": "^1.3.1",
2020
"glob": "^11",
2121
"cpy": "^9.0.1",
2222
"tar": "^7.4.3"

rust/perspective-python/perspective/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"Client",
1818
"PerspectiveError",
1919
"ProxySession",
20+
"AsyncClient",
2021
]
2122

2223
import functools
@@ -26,6 +27,7 @@
2627
PerspectiveError,
2728
ProxySession,
2829
PySyncServer as Server,
30+
AsyncClient,
2931
# NOTE: these are classes without constructors,
3032
# so we import them just for type hinting
3133
Table, # noqa: F401

0 commit comments

Comments
 (0)