Skip to content

Commit

Permalink
refactor(bindings/python): return bytes directly and add type stub fi…
Browse files Browse the repository at this point in the history
…le (#1514)

* refactor(bindings/python): raise RuntimeError instead of BaseException

* refactor(bindings/python): return bytes from `read`

* feat(bindings/python): add type stub file
  • Loading branch information
messense authored Mar 8, 2023
1 parent 7bb7bef commit 5d1b952
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 10 deletions.
14 changes: 14 additions & 0 deletions bindings/python/opendal.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class Operator:
def __init__(scheme: str, **kwargs): ...
def read(self, path: str) -> bytes: ...
def write(self, path: str, bs: bytes): ...
def stat(self, path: str) -> Metadata: ...

class AsyncOperator:
def __init__(scheme: str, **kwargs): ...
async def read(self, path: str) -> bytes: ...
async def write(self, path: str, bs: bytes): ...
async def stat(self, path: str) -> Metadata: ...

class Metadata:
def content_length(self) -> int: ...
18 changes: 10 additions & 8 deletions bindings/python/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ use std::collections::HashMap;
use std::str::FromStr;

use ::opendal as od;
use pyo3::exceptions::PyBaseException;
use pyo3::exceptions::PyFileNotFoundError;
use pyo3::exceptions::{PyFileNotFoundError, PyRuntimeError};
use pyo3::prelude::*;
use pyo3::types::PyDict;
use pyo3::types::{PyBytes, PyDict};
use pyo3_asyncio::tokio::future_into_py;

fn build_operator(scheme: od::Scheme, map: HashMap<String, String>) -> PyResult<od::Operator> {
Expand Down Expand Up @@ -65,8 +64,9 @@ impl AsyncOperator {
let this = self.0.clone();
let path = path.to_string();
future_into_py(py, async move {
let res: Vec<u8> = this.read(&path).await.map_err(format_pyerr)?;
Ok(res)
let res = this.read(&path).await.map_err(format_pyerr)?;
let bytes = Python::with_gil(|py| PyBytes::new(py, &res).to_object(py));
Ok(bytes)
})
}

Expand Down Expand Up @@ -112,8 +112,10 @@ impl Operator {
Ok(Operator(build_operator(scheme, map)?.blocking()))
}

pub fn read(&self, path: &str) -> PyResult<Vec<u8>> {
self.0.read(path).map_err(format_pyerr)
pub fn read<'p>(&'p self, py: Python<'p>, path: &str) -> PyResult<&'p PyBytes> {
let res = self.0.read(path).map_err(format_pyerr)?;
let bytes = PyBytes::new(py, &res);
Ok(bytes)
}

pub fn write(&self, path: &str, bs: Vec<u8>) -> PyResult<()> {
Expand All @@ -139,7 +141,7 @@ fn format_pyerr(err: od::Error) -> PyErr {
use od::ErrorKind::*;
match err.kind() {
NotFound => PyFileNotFoundError::new_err(err.to_string()),
_ => PyBaseException::new_err(err.to_string()),
_ => PyRuntimeError::new_err(err.to_string()),
}
}

Expand Down
4 changes: 2 additions & 2 deletions bindings/python/tests/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def test_blocking():
op = opendal.Operator("memory")
op.write("test", b"Hello, World!")
bs = op.read("test")
print(bytes(bs).decode("utf-8"))
print(bs.decode("utf-8"))
meta = op.stat("test")
print(f"content_length: {meta.content_length()}")

Expand All @@ -31,7 +31,7 @@ async def test_async():
op = opendal.AsyncOperator("memory")
await op.write("test", b"Hello, World!")
bs = await op.read("test")
print(bytes(bs).decode("utf-8"))
print(bs.decode("utf-8"))
meta = await op.stat("test")
print(f"content_length: {meta.content_length()}")

Expand Down

2 comments on commit 5d1b952

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for opendal ready!

✅ Preview
https://opendal-oqwnkzvry-databend.vercel.app

Built with commit 5d1b952.
This pull request is being automatically deployed with vercel-action

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Rust Benchmark'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 2.

Benchmark suite Current: 5d1b952 Previous: 7bb7bef Ratio
service_memory_read_full/256 KiB 34963 ns/iter (± 1646) 13821 ns/iter (± 15) 2.53
service_memory_write_once/256 KiB 47263 ns/iter (± 2636) 19126 ns/iter (± 145) 2.47

This comment was automatically generated by workflow using github-action-benchmark.

CC: @Xuanwo

Please sign in to comment.