Skip to content

Commit 68868e4

Browse files
feat(vortex-python): Add OpenDAL-backed CosStore to the Python object-store API
1 parent c5e075a commit 68868e4

51 files changed

Lines changed: 6688 additions & 10 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

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

Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ members = [
1111
"vortex-flatbuffers",
1212
"vortex-metrics",
1313
"vortex-io",
14+
"vortex-object-store-opendal",
1415
"vortex-proto",
1516
"vortex-array",
1617
"vortex-arrow",
@@ -429,3 +430,12 @@ incremental = false
429430
# This improved build times significantly for default common cases that we use locally
430431
[profile.dev.package.vortex-fastlanes]
431432
debug = false
433+
434+
# Vendored fork of `pyo3-object_store` that adds `From<Arc<dyn ObjectStore>> for
435+
# PyObjectStore`, allowing any pre-built `object_store::ObjectStore` (e.g. the OpenDAL-backed
436+
# COS/OSS store) to be passed to Vortex's `read_url(store=...)` / `write(store=...)` APIs.
437+
#
438+
# Once https://github.com/developmentseed/obstore (pyo3-object_store) ships this constructor
439+
# upstream, this patch can be removed.
440+
[patch.crates-io]
441+
pyo3-object_store = { path = "vendor/pyo3-object_store" }

docs/api/python/store.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Vortex arrays support reading and writing to many object storage systems:
1313
store/http
1414
store/local
1515
store/memory
16+
store/opendal
1617
store/config
1718

1819
.. autofunction:: vortex.store.from_url

docs/api/python/store/opendal.rst

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
========
2+
OpenDAL (COS)
3+
========
4+
5+
Vortex can read from and write to Tencent Cloud COS through
6+
`OpenDAL <https://opendal.apache.org/>`_, which provides native service support.
7+
8+
This store is available only when Vortex is built with the ``opendal`` feature
9+
(e.g. ``maturin develop --features opendal`` or ``cargo build -p vortex-jni --features opendal``).
10+
11+
.. autoclass:: vortex.store.CosStore
12+
:members:
13+
14+
Reading from COS
15+
================
16+
17+
Pass a ``cos://`` URL directly. Credentials and the endpoint are picked up from the environment
18+
variables OpenDAL's COS builder reads (``TENCENTCLOUD_SECRET_ID``, ``TENCENTCLOUD_SECRET_KEY`` and
19+
``COS_ENDPOINT``):
20+
21+
.. code-block:: python
22+
23+
import vortex as vx
24+
25+
a = vx.io.read_url("cos://my-bucket/path/to/dataset.vortex")
26+
27+
Or configure explicitly with :class:`~vortex.store.CosStore` before reading:
28+
29+
.. code-block:: python
30+
31+
from vortex.store import CosStore
32+
33+
CosStore(
34+
bucket="my-bucket",
35+
endpoint="https://cos.ap-guangzhou.myqcloud.com",
36+
secret_id="AKID...",
37+
secret_key="...",
38+
).apply()
39+
40+
a = vx.io.read_url("cos://my-bucket/path/to/dataset.vortex")
41+
42+
Passing a store object directly
43+
===============================
44+
45+
``CosStore`` is a concrete store object. You can build one once and pass it
46+
directly to :func:`vortex.io.read_url` / :func:`vortex.io.write` via the ``store=`` argument,
47+
exactly like the built-in S3/Azure/GCS stores:
48+
49+
.. code-block:: python
50+
51+
from vortex.io import read_url
52+
from vortex.store import CosStore
53+
54+
store = CosStore(
55+
bucket="my-bucket",
56+
endpoint="https://cos.ap-guangzhou.myqcloud.com",
57+
secret_id="AKID...",
58+
secret_key="...",
59+
)
60+
61+
a = read_url("cos://my-bucket/path/to/dataset.vortex", store=store)
62+
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
[package]
2+
name = "pyo3-object_store"
3+
version = "0.11.0"
4+
authors = ["Kyle Barron <kyle@developmentseed.org>"]
5+
edition = "2021"
6+
description = "object_store integration for pyo3."
7+
readme = "README.md"
8+
repository = "https://github.com/developmentseed/obstore"
9+
license = "MIT OR Apache-2.0"
10+
keywords = []
11+
categories = []
12+
rust-version = "1.75"
13+
# Include the Python type hints as part of the cargo distribution
14+
include = ["src", "type-hints", "README.md", "LICENSE"]
15+
16+
[features]
17+
default = ["external-store-warning"]
18+
external-store-warning = []
19+
20+
[dependencies]
21+
async-trait = "0.1.85"
22+
bytes = "1"
23+
chrono = "0.4"
24+
futures = "0.3"
25+
# This is already an object_store dependency
26+
humantime = "2.1"
27+
# This is already an object_store dependency
28+
http = "1"
29+
# This is already an object_store dependency
30+
itertools = "0.14.0"
31+
object_store = { version = "0.13.0", features = [
32+
"aws",
33+
"azure",
34+
"gcp",
35+
"http",
36+
] }
37+
# This is already an object_store dependency
38+
percent-encoding = "2.1"
39+
pyo3 = { version = "0.29", features = ["chrono", "indexmap"] }
40+
pyo3-async-runtimes = { version = "0.29", features = ["tokio-runtime"] }
41+
serde = "1"
42+
thiserror = "1"
43+
tokio = { version = "1.40", features = ["rt-multi-thread"] }
44+
url = "2"
45+
46+
[lib]
47+
crate-type = ["rlib"]

vendor/pyo3-object_store/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 Development Seed
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

0 commit comments

Comments
 (0)