|
2 | 2 |
|
3 | 3 | Integration between [`object_store`](https://docs.rs/object_store) and [`pyo3`](https://github.com/PyO3/pyo3).
|
4 | 4 |
|
5 |
| -This provides Python builder classes so that Python users can easily create `Arc<dyn ObjectStore>` instances, which can then be used in pure-Rust code. |
| 5 | +This provides Python builder classes so that Python users can easily create [`Arc<dyn ObjectStore>`][object_store::ObjectStore] instances, which can then be used in pure-Rust code. |
6 | 6 |
|
7 | 7 | ## Usage
|
8 | 8 |
|
9 | 9 | 1. Register the builders.
|
10 | 10 |
|
11 |
| - ```rs |
12 |
| - #[pymodule] |
13 |
| - fn python_module(py: Python, m: &Bound<PyModule>) -> PyResult<()> { |
14 |
| - pyo3_object_store::register_store_module(py, m, "python_module")?; |
15 |
| - pyo3_object_store::register_exceptions_module(py, m, "python_module")?; |
16 |
| - } |
17 |
| - ``` |
| 11 | + ```rs |
| 12 | + #[pymodule] |
| 13 | + fn python_module(py: Python, m: &Bound<PyModule>) -> PyResult<()> { |
| 14 | + pyo3_object_store::register_store_module(py, m, "python_module", "store")?; |
| 15 | + pyo3_object_store::register_exceptions_module(py, m, "python_module", "exceptions")?; |
| 16 | + } |
| 17 | + ``` |
18 | 18 |
|
19 |
| - This exports the underlying Python classes from your own Rust-Python library. |
| 19 | + This exports the underlying Python classes from your own Rust-Python library. |
20 | 20 |
|
21 |
| -2. Accept `PyObjectStore` as a parameter in your function exported to Python. Its `into_inner` method gives you an `Arc<dyn ObjectStore>`. |
| 21 | + Refer to [`register_store_module`] and [`register_exceptions_module`] for more information. |
22 | 22 |
|
23 |
| - ```rs |
24 |
| - #[pyfunction] |
25 |
| - pub fn use_object_store(store: PyObjectStore) { |
26 |
| - let store: Arc<dyn ObjectStore> = store.into_inner(); |
27 |
| - } |
28 |
| - ``` |
| 23 | +2. Accept [`PyObjectStore`] as a parameter in your function exported to Python. Its [`into_dyn`][PyObjectStore::into_dyn] method (or `Into` impl) gives you an [`Arc<dyn ObjectStore>`][object_store::ObjectStore]. |
| 24 | + |
| 25 | + ```rs |
| 26 | + #[pyfunction] |
| 27 | + pub fn use_object_store(store: PyObjectStore) { |
| 28 | + let store: Arc<dyn ObjectStore> = store.into_dyn(); |
| 29 | + } |
| 30 | + ``` |
| 31 | + |
| 32 | + You can also accept [`AnyObjectStore`] as a parameter, which wraps [`PyObjectStore`] and [`PyExternalObjectStore`]. This allows you to seamlessly recreate `ObjectStore` instances that users pass in from other Python libraries (like [`obstore`][obstore]) that themselves export `pyo3-object_store` builders. |
| 33 | + |
| 34 | + Note however that due to lack of [ABI stability](#abi-stability), `ObjectStore` instances will be **recreated**, and so there will be no connection pooling across the external store. |
29 | 35 |
|
30 | 36 | ## Example
|
31 | 37 |
|
32 |
| -The `obstore` Python library gives a full real-world example of using `pyo3-object_store`. It |
| 38 | +The [`obstore`][obstore] Python library gives a full real-world example of using `pyo3-object_store`, exporting a Python API that mimics the Rust [`ObjectStore`][object_store::ObjectStore] API. |
| 39 | + |
| 40 | +[obstore]: https://developmentseed.org/obstore/latest/ |
33 | 41 |
|
34 | 42 | ## ABI stability
|
35 | 43 |
|
| 44 | +It's [not currently possible](https://github.com/PyO3/pyo3/issues/1444) to share a `#[pyclass]` across multiple Python libraries, except in special cases where the underlying data has a stable ABI. |
| 45 | + |
| 46 | +As `object_store` does not currently have a stable ABI, we can't share `PyObjectStore` instances across multiple separately-compiled Python libraries. |
| 47 | + |
| 48 | +We have two ways to get around this: |
| 49 | + |
| 50 | +- Export your own Python classes so that users can construct `ObjectStore` instances that were compiled _with your library_. See [`register_store_module`]. |
| 51 | +- Accept [`AnyObjectStore`] or [`PyExternalObjectStore`] as a parameter, which allows for seamlessly **reconstructing** stores from an external Python library, like [`obstore`][obstore]. This has some overhead and removes any possibility of connection pooling across the two instances. |
| 52 | + |
36 | 53 | Note about not being able to use these across Python packages. It has to be used with the exported classes from your own library.
|
37 | 54 |
|
38 |
| -## Type hints |
| 55 | +## Python Type hints |
| 56 | + |
| 57 | +We don't yet have a _great_ solution here for reusing the store builder type hints in your own library. Type hints are shipped with the cargo dependency. Or, you can use a submodule on the `obstore` repo. See [`async-tiff` for an example](https://github.com/developmentseed/async-tiff/blob/35eaf116d9b1ab31232a1e23298b3102d2879e9c/python/python/async_tiff/store). |
| 58 | + |
| 59 | +## Version compatibility |
| 60 | + |
| 61 | +| pyo3-object_store | pyo3 | object_store | |
| 62 | +| ----------------- | ---- | ------------ | |
| 63 | +| 0.1.x | 0.23 | 0.12 | |
0 commit comments