This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git


The following commit(s) were added to refs/heads/main by this push:
     new 76f06670e feat(bindings/python)!: Add stubs for remaining types (#6720)
76f06670e is described below

commit 76f06670efe95462cf4f1f474fae5b94301623fd
Author: Chitral Verma <[email protected]>
AuthorDate: Wed Oct 22 12:52:58 2025 +0530

    feat(bindings/python)!: Add stubs for remaining types (#6720)
    
    * Stubs for Layers
    
    * Stubs for Metadata, Entry, and EntryMode
    
    * Add to API Reference
    
    * Add stubs for operator and file
    
    * update stub-gen and add AsyncFile
    
    * fix docs
    
    * Stubs for operator
    
    * Stubs for AsyncOpertor
    
    * Remove operator module and fix tests
    
    * fix tests
---
 bindings/python/Cargo.toml                  |    2 +-
 bindings/python/docs/api/async_file.md      |    4 +-
 bindings/python/docs/api/capability.md      |    4 +-
 bindings/python/docs/api/file.md            |    4 +-
 bindings/python/docs/api/types.md           |   16 +-
 bindings/python/pyrightconfig.json          |    3 +-
 bindings/python/python/opendal/__init__.pyi | 1337 +++++++++++++++------------
 bindings/python/python/opendal/file.pyi     |  317 +++++++
 bindings/python/python/opendal/layers.pyi   |   17 +-
 bindings/python/python/opendal/types.pyi    |   26 +
 bindings/python/ruff.toml                   |    2 +-
 bindings/python/src/file.rs                 |  323 ++++++-
 bindings/python/src/layers.rs               |   13 +-
 bindings/python/src/lib.rs                  |   22 +-
 bindings/python/src/operator.rs             | 1162 ++++++++++++++++++++---
 bindings/python/tests/conftest.py           |    4 +-
 bindings/python/tests/test_capability.py    |    4 +-
 17 files changed, 2436 insertions(+), 824 deletions(-)

diff --git a/bindings/python/Cargo.toml b/bindings/python/Cargo.toml
index 3ac16216a..9b4ad00b9 100644
--- a/bindings/python/Cargo.toml
+++ b/bindings/python/Cargo.toml
@@ -173,7 +173,7 @@ opendal = { version = ">=0", path = "../../core", features 
= [
 ] }
 pyo3 = { version = "0.26.0", features = ["generate-import-lib", "jiff-02"] }
 pyo3-async-runtimes = { version = "0.26.0", features = ["tokio-runtime"] }
-pyo3-stub-gen = { version = "0.15" }
+pyo3-stub-gen = { version = "0.16" }
 tokio = "1"
 
 [target.'cfg(unix)'.dependencies.opendal]
diff --git a/bindings/python/docs/api/async_file.md 
b/bindings/python/docs/api/async_file.md
index b06891f2f..6a2b9f421 100644
--- a/bindings/python/docs/api/async_file.md
+++ b/bindings/python/docs/api/async_file.md
@@ -1,6 +1,6 @@
-::: opendal.AsyncFile
+::: opendal.file.AsyncFile
     options:
-      heading: "opendal.AsyncFile"
+      heading: "opendal.file.AsyncFile"
       heading_level: 2
       show_source: false
       show_bases: false
diff --git a/bindings/python/docs/api/capability.md 
b/bindings/python/docs/api/capability.md
index 14bac70df..68174b5f5 100644
--- a/bindings/python/docs/api/capability.md
+++ b/bindings/python/docs/api/capability.md
@@ -1,6 +1,6 @@
-::: opendal.Capability
+::: opendal.capability.Capability
     options:
-      heading: "opendal.Capability"
+      heading: "opendal.capability.Capability"
       heading_level: 2
       show_source: false
       show_bases: false
diff --git a/bindings/python/docs/api/file.md b/bindings/python/docs/api/file.md
index 437c77062..b47290759 100644
--- a/bindings/python/docs/api/file.md
+++ b/bindings/python/docs/api/file.md
@@ -1,6 +1,6 @@
-::: opendal.File
+::: opendal.file.File
     options:
-      heading: "opendal.File"
+      heading: "opendal.file.File"
       heading_level: 2
       show_source: false
       show_bases: false
diff --git a/bindings/python/docs/api/types.md 
b/bindings/python/docs/api/types.md
index 396d9bee4..736a088c4 100644
--- a/bindings/python/docs/api/types.md
+++ b/bindings/python/docs/api/types.md
@@ -3,9 +3,9 @@
 This page documents all types in OpenDAL.
 
 ## Entry
-::: opendal.Entry
+::: opendal.types.Entry
     options:
-      heading: "opendal.Entry"
+      heading: "opendal.types.Entry"
       heading_level: 2
       show_source: false
       show_bases: false
@@ -13,13 +13,21 @@ This page documents all types in OpenDAL.
 ## EntryMode   
 ::: opendal.types.EntryMode
     options:
-      heading: "opendal.EntryMode"
+      heading: "opendal.types.EntryMode"
       heading_level: 2
 
 ## Metadata   
 ::: opendal.types.Metadata
     options:
-      heading: "opendal.Metadata"
+      heading: "opendal.types.Metadata"
+      heading_level: 2
+      show_source: false
+      show_bases: false
+
+## PresignedRequest   
+::: opendal.types.PresignedRequest
+    options:
+      heading: "opendal.types.PresignedRequest"
       heading_level: 2
       show_source: false
       show_bases: false
diff --git a/bindings/python/pyrightconfig.json 
b/bindings/python/pyrightconfig.json
index a76866465..c792ffe00 100644
--- a/bindings/python/pyrightconfig.json
+++ b/bindings/python/pyrightconfig.json
@@ -2,5 +2,6 @@
   "include": ["python/opendal/"],
   "ignore": [
     "python/opendal/*.pyi"
-  ]
+  ],
+  "reportIgnoreCommentWithoutRule": false
 }
diff --git a/bindings/python/python/opendal/__init__.pyi 
b/bindings/python/python/opendal/__init__.pyi
index 91ec09466..7e3ca6759 100644
--- a/bindings/python/python/opendal/__init__.pyi
+++ b/bindings/python/python/opendal/__init__.pyi
@@ -15,699 +15,898 @@
 # specific language governing permissions and limitations
 # under the License.
 
+# This file is automatically generated by pyo3_stub_gen
+# ruff: noqa: E501, F401
+
+import builtins
+import collections.abc
+import datetime
 import os
-from collections.abc import AsyncIterable, Iterable
-from types import TracebackType
-from typing import TypeAlias, final
-
-try:
-    from warnings import deprecated
-except ImportError:
-    from typing_extensions import deprecated
-from opendal import exceptions as exceptions
-from opendal import layers as layers
-from opendal.__base import _Base
-from opendal.capability import Capability
-from opendal.layers import Layer
-from opendal.types import Entry, Metadata
+import pathlib
+import typing
 
-PathBuf: TypeAlias = str | os.PathLike
+from opendal import capability, exceptions, file, layers, types
+from opendal.layers import Layer
 
-@final
-class Operator(_Base):
-    """The entry class for all public blocking APIs.
+__version__: builtins.str = "0.46.1"
 
-    Args:
-        scheme (str): The service name that OpenDAL supports.
-        **options (any): The options for the service.
-            See the documentation of each service for more details.
[email protected]
+class AsyncOperator:
+    r"""
+    The async equivalent of `Operator`.
 
-    Example:
-        ```python
-        import opendal
+    `AsyncOperator` is the entry point for all async APIs.
 
-        op = opendal.Operator(
-            "s3", bucket="bucket", region="us-east-1"
-        )
-        op.write("hello.txt", b"hello world")
-        ```
+    See Also
+    --------
+    Operator
     """
 
-    def __init__(self, scheme: str, **options) -> None: ...
-    def layer(self, layer: Layer) -> Operator:
-        """Add new layers upon the current operator.
+    def __new__(cls, scheme: builtins.str, **kwargs: typing.Any) -> 
AsyncOperator:
+        r"""
+        Create a new `AsyncOperator`.
 
-        Args:
-            layer (Layer): The layer to be added.
+        Parameters
+        ----------
+        scheme : str
+            The scheme of the service.
+        **kwargs : dict
+            The options for the service.
 
         Returns
         -------
-            The new operator with the layer added.
-        """
-    def open(self, path: PathBuf, mode: str, **options) -> File:
-        """Open a file at the given path for reading or writing.
-
-        Args:
-            path (str | Path): The path to the file.
-            mode (str): The mode to open the file. Must be either `"rb"` for 
reading or
-                `"wb"` for writing.
-            **options (Any): Additional options passed to the underlying 
OpenDAL reader
-                or writer.
-                - If `mode == "rb"`: options match the
-                  [OpenDAL 
`ReaderOptions`](https://opendal.apache.org/docs/rust/opendal/options/struct.ReaderOptions.html).
-                - If `mode == "wb"`: options match the
-                  [OpenDAL 
`WriteOptions`](https://opendal.apache.org/docs/rust/opendal/options/struct.WriteOptions.html).
+        AsyncOperator
+            The new async operator.
+        """
+    def layer(self, layer: Layer) -> AsyncOperator:
+        r"""
+        Add a new layer to the operator.
 
-        Returns
-        -------
-            File: A file-like object that can be used to read or write the 
file.
-
-        Example:
-            ```python
-            import opendal
-
-            op = opendal.Operator(
-                "s3", bucket="bucket", region="us-east-1"
-            )
-            with op.open("hello.txt", "wb") as f:
-                f.write(b"hello world")
-            ```
-        """
-    def read(self, path: PathBuf, **options) -> bytes:
-        """Read the content of the object at the given path.
-
-        Args:
-            path (str | Path): The path to the object.
-            **options (Any): Optional read parameters matching the
-                [OpenDAL 
`ReadOptions`](https://opendal.apache.org/docs/rust/opendal/options/struct.ReadOptions.html):
-
-                - offset (int): Byte offset to start reading from. Defaults to 0
-                    if not specified.
-                - size (int): Number of bytes to read. If not specified, reads 
until
-                    the end of the object.
-                  Together, `offset` and `size` define the byte range for 
reading.
-                - version (str): Specify the version of the object to read, if
-                    supported by the backend.
-                - concurrent (int): Level of concurrency for reading. Defaults 
to
-                    backend-specific value.
-                - chunk (int): Read chunk size in bytes.
-                - gap (int): Minimum gap (in bytes) between chunks to consider
-                    them separate.
-                - if_match (str): Read only if the ETag matches the given 
value.
-                - if_none_match (str): Read-only if the ETag does not match the
-                    given value.
-                - if_modified_since (datetime): Only read if the object was 
modified
-                    since this timestamp. This timestamp must be in UTC.
-                - if_unmodified_since (datetime): Only read if the object was 
not
-                    modified since this timestamp. This timestamp must be in 
UTC.
+        Parameters
+        ----------
+        layer : Layer
+            The layer to add.
 
         Returns
         -------
-            bytes: The content of the object as bytes.
-        """
-    def write(self, path: PathBuf, bs: bytes, **options) -> None:
-        """Write the content to the object at the given path.
-
-        Args:
-            path (str | Path): The path to the object.
-            bs (bytes): The content to write.
-            **options (Any): Optional write parameters matching the
-                [OpenDAL 
`WriteOptions`](https://opendal.apache.org/docs/rust/opendal/options/struct.WriteOptions.html):
-
-                - append (bool): If True, append to the object instead of 
overwriting.
-                - chunk (int): Specify the chunk size in bytes for multipart 
uploads.
-                - concurrent (int): Number of concurrent upload parts. Larger 
values can
-                    improve performance.
-                - cache_control (str): Override the cache-control header for 
the object.
-                - content_type (str): Explicitly set the Content-Type header 
for
-                    the object.
-                - content_disposition (str): Sets how the object should be 
presented
-                    (e.g., as an attachment).
-                - content_encoding (str): Override the Content-Encoding header.
-                - if_match (str): Perform the write only if the object's 
current
-                    ETag matches the given one.
-                - if_none_match (str): Perform the write only if the object's
-                    current ETag does NOT match the given one.
-                - if_not_exists (bool): Only write the object if it doesn't
-                    already exist.
-                - user_metadata (dict[str, str]): Custom user metadata to 
associate
-                    with the object.
+        AsyncOperator
+            A new operator with the layer added.
+        """
+    def open(
+        self,
+        path: builtins.str | os.PathLike | pathlib.Path,
+        mode: builtins.str,
+        **kwargs: typing.Any,
+    ) -> collections.abc.Awaitable[file.AsyncFile]:
+        r"""
+        Open an async file-like object for the given path.
+
+        The returning async file-like object is a context manager.
+
+        Parameters
+        ----------
+        path : str
+            The path to the file.
+        mode : str
+            The mode to open the file in. Only "rb" and "wb" are supported.
+        **kwargs : dict
+            Additional options for the underlying reader or writer.
 
         Returns
         -------
-            None
-        """
-    def stat(self, path: PathBuf, **kwargs) -> Metadata:
-        """Get the metadata of the object at the given path.
-
-        Args:
-            path (str | Path): The path to the object.
-            **kwargs (Any): Optional stat parameters matching the
-                [OpenDAL 
`StatOptions`](https://opendal.apache.org/docs/rust/opendal/options/struct.StatOptions.html):
-
-                - version (str): Specify the version of the object to read, if
-                    supported by the backend.
-                - if_match (str): Read only if the ETag matches the given 
value.
-                - if_none_match (str): Read-only if the ETag does not match the
-                    given value.
-                - if_modified_since (datetime): Only read if the object was 
modified
-                    since this timestamp. This timestamp must be in UTC.
-                - if_unmodified_since (datetime): Only read if the object was 
not
-                    modified since this timestamp. This timestamp must be in 
UTC.
-                - cache_control (str): Override the cache-control header for 
the object.
-                - content_type (str): Explicitly set the Content-Type header 
for
-                    the object.
-                - content_disposition (str): Sets how the object should be 
presented
-                    (e.g., as an attachment).
+        coroutine
+            An awaitable that returns a file-like object.
+        """
+    def read(
+        self,
+        path: builtins.str | os.PathLike | pathlib.Path,
+        *,
+        version: builtins.str | None = None,
+        concurrent: builtins.int | None = None,
+        chunk: builtins.int | None = None,
+        gap: builtins.int | None = None,
+        offset: builtins.int | None = None,
+        prefetch: builtins.int | None = None,
+        size: builtins.int | None = None,
+        if_match: builtins.str | None = None,
+        if_none_match: builtins.str | None = None,
+        if_modified_since: datetime.datetime = None,
+        if_unmodified_since: datetime.datetime = None,
+        content_type: builtins.str | None = None,
+        cache_control: builtins.str | None = None,
+        content_disposition: builtins.str | None = None,
+    ) -> collections.abc.Awaitable[builtins.bytes]:
+        r"""
+        Read the entire contents of a file at the given path.
+
+        Parameters
+        ----------
+        path : str
+            The path to the file.
+        version : str, optional
+            The version of the file.
+        concurrent : int, optional
+            The number of concurrent readers.
+        chunk : int, optional
+            The size of each chunk.
+        gap : int, optional
+            The gap between each chunk.
+        offset : int, optional
+            The offset of the file.
+        prefetch : int, optional
+            The number of bytes to prefetch.
+        size : int, optional
+            The size of the file.
+        if_match : str, optional
+            The ETag of the file.
+        if_none_match : str, optional
+            The ETag of the file.
+        if_modified_since : str, optional
+            The last modified time of the file.
+        if_unmodified_since : str, optional
+            The last modified time of the file.
+        content_type : str, optional
+            The content type of the file.
+        cache_control : str, optional
+            The cache control of the file.
+        content_disposition : str, optional
+            The content disposition of the file.
 
         Returns
         -------
-            Metadata: The metadata of the object.
+        coroutine
+            An awaitable that returns the contents of the file as bytes.
         """
-    def create_dir(self, path: PathBuf) -> None:
-        """Create a directory at the given path.
-
-        Args:
-            path (str|Path): The path to the directory.
-        """
-    def delete(self, path: PathBuf) -> None:
-        """Delete the object at the given path.
-
-        Args:
-            path (str|Path): The path to the object.
-        """
-    def exists(self, path: PathBuf) -> bool:
-        """Check if the object at the given path exists.
-
-        Args:
-            path (str|Path): The path to the object.
+    def write(
+        self,
+        path: builtins.str | os.PathLike | pathlib.Path,
+        bs: builtins.bytes,
+        *,
+        append: builtins.bool | None = None,
+        chunk: builtins.int | None = None,
+        concurrent: builtins.int | None = None,
+        cache_control: builtins.str | None = None,
+        content_type: builtins.str | None = None,
+        content_disposition: builtins.str | None = None,
+        content_encoding: builtins.str | None = None,
+        if_match: builtins.str | None = None,
+        if_none_match: builtins.str | None = None,
+        if_not_exists: builtins.bool | None = None,
+        user_metadata: typing.Mapping[builtins.str, builtins.str] | None = 
None,
+    ) -> collections.abc.Awaitable[None]:
+        r"""
+        Write bytes to a file at the given path.
+
+        This function will create a file if it does not exist, and will
+        overwrite its contents if it does.
+
+        Parameters
+        ----------
+        path : str
+            The path to the file.
+        bs : bytes
+            The contents to write to the file.
+        append : bool, optional
+            Whether to append to the file instead of overwriting it.
+        chunk : int, optional
+            The chunk size to use when writing the file.
+        concurrent : int, optional
+            The number of concurrent requests to make when writing the file.
+        cache_control : str, optional
+            The cache control header to set on the file.
+        content_type : str, optional
+            The content type header to set on the file.
+        content_disposition : str, optional
+            The content disposition header to set on the file.
+        content_encoding : str, optional
+            The content encoding header to set on the file.
+        if_match : str, optional
+            The ETag to match when writing the file.
+        if_none_match : str, optional
+            The ETag to not match when writing the file.
+        if_not_exists : bool, optional
+            Whether to fail if the file already exists.
+        user_metadata : dict, optional
+            The user metadata to set on the file.
 
         Returns
         -------
-            True if the object exists, False otherwise.
-        """
-    def list(self, path: PathBuf, **kwargs) -> Iterable[Entry]:
-        """List objects at the given path.
-
-        Args:
-            path (str | Path): The path to the directory/ prefix.
-            **kwargs (Any): Optional listing parameters matching the
-                [OpenDAL 
`ListOptions`](https://opendal.apache.org/docs/rust/opendal/options/struct.ListOptions.html):
-
-                - limit (int): The limit passed to the underlying service to 
specify the
-                    max results that could return per-request. Users could use 
this to
-                    control the memory usage of list operation. If not set, 
all matching
-                    entries will be listed.
-                - start_after (str): Start listing after this key. Useful for 
pagination
-                    or resuming interrupted listings.
-                - recursive (bool): Whether to list entries recursively 
through all
-                    subdirectories. If False, lists only top-level entries 
(entries
-                    under the given path).
-                - versions (bool): Whether to include all versions of objects, 
if the
-                    underlying service supports versioning.
-                - deleted (bool): Whether to include deleted objects, if the 
underlying
-                    service supports soft-deletes or versioning.
+        coroutine
+            An awaitable that completes when the write is finished.
+        """
+    def stat(
+        self,
+        path: builtins.str | os.PathLike | pathlib.Path,
+        *,
+        version: builtins.str | None = None,
+        if_match: builtins.str | None = None,
+        if_none_match: builtins.str | None = None,
+        if_modified_since: datetime.datetime = None,
+        if_unmodified_since: datetime.datetime = None,
+        content_type: builtins.str | None = None,
+        cache_control: builtins.str | None = None,
+        content_disposition: builtins.str | None = None,
+    ) -> collections.abc.Awaitable[types.Metadata]:
+        r"""
+        Get the metadata of a file at the given path.
+
+        Parameters
+        ----------
+        path : str
+            The path to the file.
+        version : str, optional
+            The version of the file.
+        if_match : str, optional
+            The ETag of the file.
+        if_none_match : str, optional
+            The ETag of the file.
+        if_modified_since : datetime, optional
+            The last modified time of the file.
+        if_unmodified_since : datetime, optional
+            The last modified time of the file.
+        content_type : str, optional
+            The content type of the file.
+        cache_control : str, optional
+            The cache control of the file.
+        content_disposition : str, optional
+            The content disposition of the file.
 
         Returns
         -------
-            Iterable[Entry]: An iterable of entries representing the objects 
in the
-                directory or prefix.
+        coroutine
+            An awaitable that returns the metadata of the file.
         """
-    @deprecated("Use `list()` instead.")
-    def scan(self, path: PathBuf, **kwargs) -> Iterable[Entry]:
-        """Scan the objects at the given path recursively.
-
-        Args:
-            path (str | Path): The path to the directory/ prefix.
-            **kwargs (Any): Optional listing parameters matching the
-                [OpenDAL 
`ListOptions`](https://opendal.apache.org/docs/rust/opendal/options/struct.ListOptions.html),
-                excluding `recursive` which is always enforced as `True`
+    def copy(
+        self,
+        source: builtins.str | os.PathLike | pathlib.Path,
+        target: builtins.str | os.PathLike | pathlib.Path,
+    ) -> collections.abc.Awaitable[None]:
+        r"""
+        Copy a file from one path to another.
+
+        Parameters
+        ----------
+        source : str
+            The path to the source file.
+        target : str
+            The path to the target file.
 
         Returns
         -------
-            Iterable[Entry]: An iterable of all entries under the given path,
-                recursively traversing all subdirectories. Each entry 
represents
-                an object (e.g., file or directory) discovered within the full
-                descendant hierarchy of the specified path.
+        coroutine
+            An awaitable that completes when the copy is finished.
         """
-    def capability(self) -> Capability:
-        """Get the capability of the operator.
+    def rename(
+        self,
+        source: builtins.str | os.PathLike | pathlib.Path,
+        target: builtins.str | os.PathLike | pathlib.Path,
+    ) -> collections.abc.Awaitable[None]:
+        r"""
+        Rename (move) a file from one path to another.
+
+        Parameters
+        ----------
+        source : str
+            The path to the source file.
+        target : str
+            The path to the target file.
 
         Returns
         -------
-            The capability of the operator.
-        """
-    def copy(self, source: PathBuf, target: PathBuf) -> None:
-        """Copy the object from source to target.
-
-        Args:
-            source (str|Path): The source path.
-            target (str|Path): The target path.
+        coroutine
+            An awaitable that completes when the rename is finished.
         """
-    def rename(self, source: PathBuf, target: PathBuf) -> None:
-        """Rename the object from source to target.
-
-        Args:
-            source (str|Path): The source path.
-            target (str|Path): The target path.
-        """
-    def remove_all(self, path: PathBuf) -> None:
-        """Convert into an async operator."""
-    def to_async_operator(self) -> AsyncOperator: ...
-
-@final
-class AsyncOperator(_Base):
-    """The entry class for all public async APIs.
-
-    Args:
-        scheme (str): The service name that OpenDAL supports.
-        **options (any): The options for the service.
-            See the documentation of each service for more details.
-
-    Example:
-        ```python
-        import opendal
-
-        op = opendal.AsyncOperator(
-            "s3", bucket="bucket", region="us-east-1"
-        )
-        await op.write("hello.txt", b"hello world")
-        ```
-    """
-
-    def __init__(self, scheme: str, **options) -> None: ...
-    def layer(self, layer: Layer) -> AsyncOperator: ...
-    async def open(self, path: PathBuf, mode: str, **options) -> AsyncFile:
-        """Open a file at the given path for reading or writing.
-
-        Args:
-            path (str | Path): The path to the file.
-            mode (str): The mode to open the file. Must be either `"rb"` for 
reading or
-                `"wb"` for writing.
-            **options (Any): Additional options passed to the underlying 
OpenDAL reader
-                or writer.
-                - If `mode == "rb"`: options match the
-                  [OpenDAL 
`ReaderOptions`](https://opendal.apache.org/docs/rust/opendal/options/struct.ReaderOptions.html).
-                - If `mode == "wb"`: options match the
-                  [OpenDAL 
`WriteOptions`](https://opendal.apache.org/docs/rust/opendal/options/struct.WriteOptions.html).
+    def remove_all(
+        self, path: builtins.str | os.PathLike | pathlib.Path
+    ) -> collections.abc.Awaitable[None]:
+        r"""
+        Recursively remove all files and directories at the given path.
 
-        Returns
-        -------
-            AsyncFile: A file-like object that can be used to read or write 
the file.
-
-        Example:
-            ```python
-            import opendal
-
-            op = opendal.AsyncOperator(
-                "s3", bucket="bucket", region="us-east-1"
-            )
-            async with await op.open("hello.txt", "wb") as f:
-                await f.write(b"hello world")
-            ```
-        """
-    async def read(self, path: PathBuf, **options) -> bytes:
-        """Read the content of the object at the given path.
-
-        Args:
-            path (str | Path): The path to the object.
-            **options (Any): Optional read parameters matching the
-                [OpenDAL 
`ReadOptions`](https://opendal.apache.org/docs/rust/opendal/options/struct.ReadOptions.html):
-
-                - offset (int): Byte offset to start reading from. Defaults to 0
-                    if not specified.
-                - size (int): Number of bytes to read. If not specified, reads 
until
-                    the end of the object.
-                  Together, `offset` and `size` define the byte range for 
reading.
-                - version (str): Specify the version of the object to read, if
-                    supported by the backend.
-                - concurrent (int): Level of concurrency for reading. Defaults 
to
-                    backend-specific value.
-                - chunk (int): Read chunk size in bytes.
-                - gap (int): Minimum gap (in bytes) between chunks to consider
-                    them separate.
-                - override_content_type (str): Override the returned content 
type.
-                - if_match (str): Read only if the ETag matches the given 
value.
-                - if_none_match (str): Read-only if the ETag does not match the
-                    given value.
-                - if_modified_since (datetime): Only read if the object was 
modified
-                    since this timestamp. This timestamp must be in UTC.
-                - if_unmodified_since (datetime): Only read if the object was 
not
-                    modified since this timestamp. This timestamp must be in 
UTC.
+        Parameters
+        ----------
+        path : str
+            The path to remove.
 
         Returns
         -------
-            The content of the object as bytes.
-        """
-    async def write(self, path: PathBuf, bs: bytes, **options) -> None:
-        """Write the content to the object at the given path.
-
-        Args:
-            path (str | Path): The path to the object.
-            bs (bytes): The content to write.
-            **options (Any): Optional write parameters matching the
-                [OpenDAL 
`WriteOptions`](https://opendal.apache.org/docs/rust/opendal/options/struct.WriteOptions.html):
-
-                - append (bool): If True, append to the object instead of 
overwriting.
-                - chunk (int): Specify the chunk size in bytes for multipart 
uploads.
-                - concurrent (int): Number of concurrent upload parts. Larger 
values can
-                    improve performance.
-                - cache_control (str): Override the cache-control header for 
the object.
-                - content_type (str): Explicitly set the Content-Type header 
for
-                    the object.
-                - content_disposition (str): Sets how the object should be 
presented
-                    (e.g., as an attachment).
-                - content_encoding (str): Override the Content-Encoding header.
-                - if_match (str): Perform the write only if the object's 
current
-                    ETag matches the given one.
-                - if_none_match (str): Perform the write only if the object's
-                    current ETag does NOT match the given one.
-                - if_not_exists (bool): Only write the object if it doesn't
-                    already exist.
-                - user_metadata (dict[str, str]): Custom user metadata to 
associate
-                    with the object.
+        coroutine
+            An awaitable that completes when the removal is finished.
+        """
+    def check(self) -> collections.abc.Awaitable[None]:
+        r"""
+        Check if the operator is able to work correctly.
 
         Returns
         -------
-            None
-        """
-    async def stat(self, path: PathBuf, **kwargs) -> Metadata:
-        """Get the metadata of the object at the given path.
-
-        Args:
-            path (str | Path): The path to the object.
-            **kwargs (Any): Optional stat parameters matching the
-                [OpenDAL 
`StatOptions`](https://opendal.apache.org/docs/rust/opendal/options/struct.StatOptions.html):
-
-                - version (str): Specify the version of the object to read, if
-                    supported by the backend.
-                - if_match (str): Read only if the ETag matches the given 
value.
-                - if_none_match (str): Read-only if the ETag does not match the
-                    given value.
-                - if_modified_since (datetime): Only read if the object was 
modified
-                    since this timestamp. This timestamp must be in UTC.
-                - if_unmodified_since (datetime): Only read if the object was 
not
-                    modified since this timestamp. This timestamp must be in 
UTC.
-                - cache_control (str): Override the cache-control header for 
the object.
-                - content_type (str): Explicitly set the Content-Type header 
for
-                    the object.
-                - content_disposition (str): Sets how the object should be 
presented
-                    (e.g., as an attachment).
+        coroutine
+            An awaitable that completes when the check is finished.
+
+        Raises
+        ------
+        Exception
+            If the operator is not able to work correctly.
+        """
+    def create_dir(
+        self, path: builtins.str | os.PathLike | pathlib.Path
+    ) -> collections.abc.Awaitable[None]:
+        r"""
+        Create a directory at the given path.
+
+        Notes
+        -----
+        To indicate that a path is a directory, it must end with a `/`.
+        This operation is always recursive, like `mkdir -p`.
+
+        Parameters
+        ----------
+        path : str
+            The path to the directory.
 
         Returns
         -------
-            Metadata: The metadata of the object.
+        coroutine
+            An awaitable that completes when the directory is created.
         """
-    async def create_dir(self, path: PathBuf) -> None:
-        """Create a directory at the given path.
+    def delete(
+        self, path: builtins.str | os.PathLike | pathlib.Path
+    ) -> collections.abc.Awaitable[None]:
+        r"""
+        Delete a file at the given path.
 
-        Args:
-            path (str|Path): The path to the directory.
-        """
-    async def delete(self, path: PathBuf) -> None:
-        """Delete the object at the given path.
-
-        Args:
-            path (str|Path): The path to the object.
-        """
-    async def exists(self, path: PathBuf) -> bool:
-        """Check if the object at the given path exists.
+        Notes
+        -----
+        This operation will not return an error if the path does not exist.
 
-        Args:
-            path (str|Path): The path to the object.
+        Parameters
+        ----------
+        path : str
+            The path to the file.
 
         Returns
         -------
-            True if the object exists, False otherwise.
-        """
-    async def list(self, path: PathBuf, **kwargs) -> AsyncIterable[Entry]:
-        """List objects at the given path.
-
-        Args:
-            path (str | Path): The path to the directory/ prefix.
-            **kwargs (Any): Optional listing parameters matching the
-                [OpenDAL 
`ListOptions`](https://opendal.apache.org/docs/rust/opendal/options/struct.ListOptions.html):
-
-                - limit (int): The limit passed to the underlying service to 
specify the
-                    max results that could return per-request. Users could use 
this to
-                    control the memory usage of list operation. If not set, 
all matching
-                    entries will be listed.
-                - start_after (str): Start listing after this key. Useful for 
pagination
-                    or resuming interrupted listings.
-                - recursive (bool): Whether to list entries recursively 
through all
-                    subdirectories. If False, lists only top-level entries 
(entries
-                    under the given path).
-                - versions (bool): Whether to include all versions of objects, 
if the
-                    underlying service supports versioning.
-                - deleted (bool): Whether to include deleted objects, if the 
underlying
-                    service supports soft-deletes or versioning.
+        coroutine
+            An awaitable that completes when the file is deleted.
+        """
+    def exists(
+        self, path: builtins.str | os.PathLike | pathlib.Path
+    ) -> collections.abc.Awaitable[builtins.bool]:
+        r"""
+        Check if a path exists.
+
+        Parameters
+        ----------
+        path : str
+            The path to check.
 
         Returns
         -------
-            Iterable[Entry]: An iterable of entries representing the objects 
in the
-                directory or prefix.
+        coroutine
+            An awaitable that returns True if the path exists, False otherwise.
         """
-    @deprecated("Use `list()` instead.")
-    async def scan(self, path: PathBuf, **kwargs) -> AsyncIterable[Entry]:
-        """Scan the objects at the given path recursively.
-
-        Args:
-            path (str | Path): The path to the directory/ prefix.
-            **kwargs (Any): Optional listing parameters matching the
-                [OpenDAL 
`ListOptions`](https://opendal.apache.org/docs/rust/opendal/options/struct.ListOptions.html),
-                excluding `recursive` which is always enforced as `True`
+    def list(
+        self,
+        path: builtins.str | os.PathLike | pathlib.Path,
+        *,
+        limit: builtins.int | None = None,
+        start_after: builtins.str | None = None,
+        recursive: builtins.bool | None = None,
+        versions: builtins.bool | None = None,
+        deleted: builtins.bool | None = None,
+    ) -> collections.abc.AsyncIterable[types.Entry]:
+        r"""
+        List entries in the given directory.
+
+        Parameters
+        ----------
+        path : str
+            The path to the directory.
+        limit : int, optional
+            The maximum number of entries to return.
+        start_after : str, optional
+            The entry to start after.
+        recursive : bool, optional
+            Whether to list recursively.
+        versions : bool, optional
+            Whether to list versions.
+        deleted : bool, optional
+            Whether to list deleted entries.
 
         Returns
         -------
-            Iterable[Entry]: An iterable of all entries under the given path,
-                recursively traversing all subdirectories. Each entry 
represents
-                an object (e.g., file or directory) discovered within the full
-                descendant hierarchy of the specified path.
+        coroutine
+            An awaitable that returns an async iterator over the entries.
         """
-    async def presign_stat(self, path: PathBuf, expire_second: int) -> 
PresignedRequest:
-        """Generate a presigned URL for stat operation.
-
-        Args:
-            path (str|Path): The path to the object.
-            expire_second (int): The expiration time in seconds.
+    def presign_stat(
+        self,
+        path: builtins.str | os.PathLike | pathlib.Path,
+        expire_second: builtins.int,
+    ) -> types.PresignedRequest:
+        r"""
+        Create a presigned request for a stat operation.
+
+        Parameters
+        ----------
+        path : str
+            The path of the object to stat.
+        expire_second : int
+            The number of seconds until the presigned URL expires.
 
         Returns
         -------
-            A presigned request object.
+        coroutine
+            An awaitable that returns a presigned request object.
         """
-    async def presign_read(self, path: PathBuf, expire_second: int) -> 
PresignedRequest:
-        """Generate a presigned URL for read operation.
-
-        Args:
-            path (str|Path): The path to the object.
-            expire_second (int): The expiration time in seconds.
+    def presign_read(
+        self,
+        path: builtins.str | os.PathLike | pathlib.Path,
+        expire_second: builtins.int,
+    ) -> types.PresignedRequest:
+        r"""
+        Create a presigned request for a read operation.
+
+        Parameters
+        ----------
+        path : str
+            The path of the object to read.
+        expire_second : int
+            The number of seconds until the presigned URL expires.
 
         Returns
         -------
-            A presigned request object.
+        coroutine
+            An awaitable that returns a presigned request object.
         """
-    async def presign_write(
-        self, path: PathBuf, expire_second: int
-    ) -> PresignedRequest:
-        """Generate a presigned URL for write operation.
-
-        Args:
-            path (str|Path): The path to the object.
-            expire_second (int): The expiration time in seconds.
+    def presign_write(
+        self,
+        path: builtins.str | os.PathLike | pathlib.Path,
+        expire_second: builtins.int,
+    ) -> types.PresignedRequest:
+        r"""
+        Create a presigned request for a write operation.
+
+        Parameters
+        ----------
+        path : str
+            The path of the object to write to.
+        expire_second : int
+            The number of seconds until the presigned URL expires.
 
         Returns
         -------
-            A presigned request object.
+        coroutine
+            An awaitable that returns a presigned request object.
         """
-    async def presign_delete(
-        self, path: PathBuf, expire_second: int
-    ) -> PresignedRequest:
-        """Generate a presigned URL for delete operation.
-
-        Args:
-            path (str|Path): The path to the object.
-            expire_second (int): The expiration time in seconds.
+    def presign_delete(
+        self,
+        path: builtins.str | os.PathLike | pathlib.Path,
+        expire_second: builtins.int,
+    ) -> types.PresignedRequest:
+        r"""
+        Create a presigned request for a delete operation.
+
+        Parameters
+        ----------
+        path : str
+            The path of the object to delete.
+        expire_second : int
+            The number of seconds until the presigned URL expires.
 
         Returns
         -------
-            A presigned request object.
+        coroutine
+            An awaitable that returns a presigned request object.
         """
-    def capability(self) -> Capability: ...
-    async def copy(self, source: PathBuf, target: PathBuf) -> None:
-        """Copy the object from source to target.
+    def full_capability(self) -> capability.Capability:
+        r"""
+        Get all capabilities of this operator.
 
-        Args:
-            source (str|Path): The source path.
-            target (str|Path): The target path.
+        Returns
+        -------
+        Capability
+            The capability of the operator.
         """
-    async def rename(self, source: PathBuf, target: PathBuf) -> None:
-        """Rename the object from source to target.
+    def to_operator(self) -> Operator:
+        r"""
+        Create a new blocking `Operator` from this async operator.
 
-        Args:
-            source (str|Path): The source path.
-            target (str|Path): The target path.
+        Returns
+        -------
+        Operator
+            The blocking operator.
         """
-    async def remove_all(self, path: PathBuf) -> None:
-        """Remove all objects at the given path.
 
-        Args:
-            path (str|Path): The path to the directory.
-        """
-    def to_operator(self) -> Operator: ...
[email protected]
+class Operator:
+    r"""
+    The blocking equivalent of `AsyncOperator`.
 
-@final
-class File:
-    """
-    A file-like object for reading and writing data.
+    `Operator` is the entry point for all blocking APIs.
 
-    Created by the `open` method of the `Operator` class.
+    See Also
+    --------
+    AsyncOperator
     """
 
-    def read(self, size: int | None = None) -> bytes:
-        """Read the content of the file.
+    def __new__(cls, scheme: builtins.str, **kwargs: typing.Any) -> Operator:
+        r"""
+        Create a new blocking `Operator`.
 
-        Args:
-            size (int): The number of bytes to read. If None, read all.
+        Parameters
+        ----------
+        scheme : str
+            The scheme of the service.
+        **kwargs : dict
+            The options for the service.
 
         Returns
         -------
-            The content of the file as bytes.
+        Operator
+            The new operator.
         """
-    def readline(self, size: int | None = None) -> bytes:
-        """Read a single line from the file.
+    def layer(self, layer: Layer) -> Operator:
+        r"""
+        Add a new layer to this operator.
 
-        Args:
-            size (int): The number of bytes to read. If None, read until 
newline.
+        Parameters
+        ----------
+        layer : Layer
+            The layer to add.
 
         Returns
         -------
-            The line read from the file as bytes.
-        """
-    def write(self, bs: bytes) -> None:
-        """Write the content to the file.
-
-        Args:
-            bs (bytes): The content to write.
+        Operator
+            A new operator with the layer added.
         """
-    def seek(self, pos: int, whence: int = 0) -> int:
-        """Set the file's current position.
-
-        Args:
-            pos (int): The position to set.
-            whence (int): The reference point for the position. Can be 0, 1, 
or 2.
+    def open(
+        self,
+        path: builtins.str | os.PathLike | pathlib.Path,
+        mode: builtins.str,
+        **kwargs: typing.Any,
+    ) -> file.File:
+        r"""
+        Open a file-like object for the given path.
+
+        The returning file-like object is a context manager.
+
+        Parameters
+        ----------
+        path : str
+            The path to the file.
+        mode : str
+            The mode to open the file in. Only "rb" and "wb" are supported.
+        **kwargs
+            Additional options for the underlying reader or writer.
 
         Returns
         -------
-            The new position in the file.
+        File
+            A file-like object.
         """
-    def tell(self) -> int:
-        """Get the current position in the file.
+    def read(
+        self,
+        path: builtins.str | os.PathLike | pathlib.Path,
+        *,
+        version: builtins.str | None = None,
+        concurrent: builtins.int | None = None,
+        chunk: builtins.int | None = None,
+        gap: builtins.int | None = None,
+        offset: builtins.int | None = None,
+        prefetch: builtins.int | None = None,
+        size: builtins.int | None = None,
+        if_match: builtins.str | None = None,
+        if_none_match: builtins.str | None = None,
+        if_modified_since: datetime.datetime = None,
+        if_unmodified_since: datetime.datetime = None,
+        content_type: builtins.str | None = None,
+        cache_control: builtins.str | None = None,
+        content_disposition: builtins.str | None = None,
+    ) -> builtins.bytes:
+        r"""
+        Read the entire contents of a file at the given path.
+
+        Parameters
+        ----------
+        path : str
+            The path to the file.
+        version : str, optional
+            The version of the file.
+        concurrent : int, optional
+            The number of concurrent readers.
+        chunk : int, optional
+            The size of each chunk.
+        gap : int, optional
+            The gap between each chunk.
+        offset : int, optional
+            The offset of the file.
+        prefetch : int, optional
+            The number of bytes to prefetch.
+        size : int, optional
+            The size of the file.
+        if_match : str, optional
+            The ETag of the file.
+        if_none_match : str, optional
+            The ETag of the file.
+        if_modified_since : str, optional
+            The last modified time of the file.
+        if_unmodified_since : str, optional
+            The last modified time of the file.
+        content_type : str, optional
+            The content type of the file.
+        cache_control : str, optional
+            The cache control of the file.
+        content_disposition : str, optional
+            The content disposition of the file.
 
         Returns
         -------
-            The current position in the file.
+        bytes
+            The contents of the file as bytes.
         """
-    def close(self) -> None:
-        """Close the file."""
-    def __enter__(self) -> File:
-        """Enter the runtime context related to this object."""
-    def __exit__(
+    def write(
         self,
-        exc_type: type[BaseException] | None,
-        exc_value: BaseException | None,
-        traceback: TracebackType | None,
+        path: builtins.str | os.PathLike | pathlib.Path,
+        bs: builtins.bytes,
+        *,
+        append: builtins.bool | None = None,
+        chunk: builtins.int | None = None,
+        concurrent: builtins.int | None = None,
+        cache_control: builtins.str | None = None,
+        content_type: builtins.str | None = None,
+        content_disposition: builtins.str | None = None,
+        content_encoding: builtins.str | None = None,
+        if_match: builtins.str | None = None,
+        if_none_match: builtins.str | None = None,
+        if_not_exists: builtins.bool | None = None,
+        user_metadata: typing.Mapping[builtins.str, builtins.str] | None = 
None,
     ) -> None:
-        """Exit the runtime context related to this object."""
-    @property
-    def closed(self) -> bool:
-        """Check if the file is closed."""
-    def flush(self) -> None:
-        """Flush the internal buffer."""
-    def readable(self) -> bool:
-        """Check if the file is readable."""
-    def readinto(self, buffer: bytes | bytearray) -> int:
-        """Read bytes into a buffer.
-
-        Args:
-            buffer (bytes|bytearray): The buffer to read into.
+        r"""
+        Write bytes to a file at the given path.
+
+        This function will create a file if it does not exist, and will
+        overwrite its contents if it does.
+
+        Parameters
+        ----------
+        path : str
+            The path to the file.
+        bs : bytes
+            The contents to write to the file.
+        append : bool, optional
+            Whether to append to the file instead of overwriting it.
+        chunk : int, optional
+            The chunk size to use when writing the file.
+        concurrent : int, optional
+            The number of concurrent requests to make when writing the file.
+        cache_control : str, optional
+            The cache control header to set on the file.
+        content_type : str, optional
+            The content type header to set on the file.
+        content_disposition : str, optional
+            The content disposition header to set on the file.
+        content_encoding : str, optional
+            The content encoding header to set on the file.
+        if_match : str, optional
+            The ETag to match when writing the file.
+        if_none_match : str, optional
+            The ETag to not match when writing the file.
+        if_not_exists : bool, optional
+            Whether to fail if the file already exists.
+        user_metadata : dict, optional
+            The user metadata to set on the file.
+        """
+    def stat(
+        self,
+        path: builtins.str | os.PathLike | pathlib.Path,
+        *,
+        version: builtins.str | None = None,
+        if_match: builtins.str | None = None,
+        if_none_match: builtins.str | None = None,
+        if_modified_since: datetime.datetime = None,
+        if_unmodified_since: datetime.datetime = None,
+        content_type: builtins.str | None = None,
+        cache_control: builtins.str | None = None,
+        content_disposition: builtins.str | None = None,
+    ) -> types.Metadata:
+        r"""
+        Get the metadata of a file at the given path.
+
+        Parameters
+        ----------
+        path : str
+            The path to the file.
+        version : str, optional
+            The version of the file.
+        if_match : str, optional
+            The ETag of the file.
+        if_none_match : str, optional
+            The ETag of the file.
+        if_modified_since : datetime, optional
+            The last modified time of the file.
+        if_unmodified_since : datetime, optional
+            The last modified time of the file.
+        content_type : str, optional
+            The content type of the file.
+        cache_control : str, optional
+            The cache control of the file.
+        content_disposition : str, optional
+            The content disposition of the file.
 
         Returns
         -------
-            The number of bytes read.
+        Metadata
+            The metadata of the file.
         """
-    def seekable(self) -> bool:
-        """Check if the file supports seeking."""
-    def writable(self) -> bool:
-        """Check if the file is writable."""
-
-@final
-class AsyncFile:
-    """
-    A file-like object for reading and writing data.
-
-    Created by the `open` method of the `AsyncOperator` class.
-    """
-
-    async def read(self, size: int | None = None) -> bytes:
-        """Read the content of the file.
+    def copy(
+        self,
+        source: builtins.str | os.PathLike | pathlib.Path,
+        target: builtins.str | os.PathLike | pathlib.Path,
+    ) -> None:
+        r"""
+        Copy a file from one path to another.
 
-        Args:
-            size (int): The number of bytes to read. If None, read all.
+        Parameters
+        ----------
+        source : str
+            The path to the source file.
+        target : str
+            The path to the target file.
+        """
+    def rename(
+        self,
+        source: builtins.str | os.PathLike | pathlib.Path,
+        target: builtins.str | os.PathLike | pathlib.Path,
+    ) -> None:
+        r"""
+        Rename (move) a file from one path to another.
+
+        Parameters
+        ----------
+        source : str
+            The path to the source file.
+        target : str
+            The path to the target file.
+        """
+    def remove_all(self, path: builtins.str | os.PathLike | pathlib.Path) -> 
None:
+        r"""
+        Recursively remove all files and directories at the given path.
+
+        Parameters
+        ----------
+        path : str
+            The path to remove.
+        """
+    def create_dir(self, path: builtins.str | os.PathLike | pathlib.Path) -> 
None:
+        r"""
+        Create a directory at the given path.
+
+        Notes
+        -----
+        To indicate that a path is a directory, it must end with a `/`.
+        This operation is always recursive, like `mkdir -p`.
+
+        Parameters
+        ----------
+        path : str
+            The path to the directory.
+        """
+    def delete(self, path: builtins.str | os.PathLike | pathlib.Path) -> None:
+        r"""
+        Delete a file at the given path.
+
+        Notes
+        -----
+        This operation will not return an error if the path does not exist.
+
+        Parameters
+        ----------
+        path : str
+            The path to the file.
+        """
+    def exists(self, path: builtins.str | os.PathLike | pathlib.Path) -> 
builtins.bool:
+        r"""
+        Check if a path exists.
+
+        Parameters
+        ----------
+        path : str
+            The path to check.
 
         Returns
         -------
-            The content of the file as bytes.
+        bool
+            True if the path exists, False otherwise.
         """
-    async def write(self, bs: bytes) -> None:
-        """Write the content to the file.
+    def list(
+        self,
+        path: builtins.str | os.PathLike | pathlib.Path,
+        *,
+        limit: builtins.int | None = None,
+        start_after: builtins.str | None = None,
+        recursive: builtins.bool | None = None,
+        versions: builtins.bool | None = None,
+        deleted: builtins.bool | None = None,
+    ) -> collections.abc.Iterable[types.Entry]:
+        r"""
+        List entries in the given directory.
+
+        Parameters
+        ----------
+        path : str
+            The path to the directory.
+        limit : int, optional
+            The maximum number of entries to return.
+        start_after : str, optional
+            The entry to start after.
+        recursive : bool, optional
+            Whether to list recursively.
+        versions : bool, optional
+            Whether to list versions.
+        deleted : bool, optional
+            Whether to list deleted entries.
 
-        Args:
-            bs (bytes): The content to write.
+        Returns
+        -------
+        BlockingLister
+            An iterator over the entries in the directory.
         """
-    async def seek(self, pos: int, whence: int = 0) -> int:
-        """Set the file's current position.
+    def scan(
+        self,
+        path: builtins.str | os.PathLike | pathlib.Path,
+        *,
+        limit: builtins.int | None = None,
+        start_after: builtins.str | None = None,
+        versions: builtins.bool | None = None,
+        deleted: builtins.bool | None = None,
+    ) -> collections.abc.Iterable[types.Entry]:
+        r"""
+        Recursively list entries in the given directory.
+
+        Deprecated
+        ----------
+            Use `list()` with `recursive=True` instead.
+
+        Parameters
+        ----------
+        path : str
+            The path to the directory.
+        limit : int, optional
+            The maximum number of entries to return.
+        start_after : str, optional
+            The entry to start after.
+        versions : bool, optional
+            Whether to list versions.
+        deleted : bool, optional
+            Whether to list deleted entries.
 
-        Args:
-            pos (int): The position to set.
-            whence (int): The reference point for the position. Can be 0, 1, 
or 2.
+        Returns
+        -------
+        BlockingLister
+            An iterator over the entries in the directory.
+        """
+    def full_capability(self) -> capability.Capability:
+        r"""
+        Get all capabilities of this operator.
 
         Returns
         -------
-            The new position in the file.
+        Capability
+            The capability of the operator.
+        """
+    def check(self) -> None:
+        r"""
+        Check if the operator is able to work correctly.
+
+        Raises
+        ------
+        Exception
+            If the operator is not able to work correctly.
         """
-    async def tell(self) -> int:
-        """Get the current position in the file.
+    def to_async_operator(self) -> AsyncOperator:
+        r"""
+        Create a new `AsyncOperator` from this blocking operator.
 
         Returns
         -------
-            The current position in the file.
+        AsyncOperator
+            The async operator.
         """
-    async def close(self) -> None:
-        """Close the file."""
-    def __aenter__(self) -> AsyncFile:
-        """Enter the runtime context related to this object."""
-    def __aexit__(
-        self,
-        exc_type: type[BaseException] | None,
-        exc_value: BaseException | None,
-        traceback: TracebackType | None,
-    ) -> None:
-        """Exit the runtime context related to this object."""
-    @property
-    async def closed(self) -> bool:
-        """Check if the file is closed."""
-    async def readable(self) -> bool:
-        """Check if the file is readable."""
-    async def seekable(self) -> bool:
-        """Check if the file supports seeking."""
-    async def writable(self) -> bool:
-        """Check if the file is writable."""
-
-@final
-class PresignedRequest:
-    @property
-    def url(self) -> str: ...
-    @property
-    def method(self) -> str: ...
-    @property
-    def headers(self) -> dict[str, str]: ...
diff --git a/bindings/python/python/opendal/file.pyi 
b/bindings/python/python/opendal/file.pyi
new file mode 100644
index 000000000..b6d59207c
--- /dev/null
+++ b/bindings/python/python/opendal/file.pyi
@@ -0,0 +1,317 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# This file is automatically generated by pyo3_stub_gen
+# ruff: noqa: E501, F401
+
+import builtins
+import collections.abc
+import types
+import typing
+
[email protected]
+class AsyncFile:
+    r"""
+    An async file-like object for reading and writing data.
+
+    Created by the `open` method of the `AsyncOperator` class.
+    """
+
+    @property
+    def closed(self) -> collections.abc.Awaitable[builtins.bool]:
+        r"""
+        Whether this file is closed.
+
+        Returns
+        -------
+        coroutine
+            An awaitable that returns True if this file is closed.
+        """
+    def read(
+        self, size: builtins.int | None = None
+    ) -> collections.abc.Awaitable[builtins.bytes]:
+        r"""
+        Read at most `size` bytes from this file asynchronously.
+
+        If `size` is not specified, read until EOF.
+
+        Parameters
+        ----------
+        size : int, optional
+            The maximum number of bytes to read.
+
+        Returns
+        -------
+        coroutine
+            An awaitable that returns the bytes read from the stream.
+        """
+    def write(self, bs: builtins.bytes) -> 
collections.abc.Awaitable[builtins.int]:
+        r"""
+        Write bytes to this file asynchronously.
+
+        Parameters
+        ----------
+        bs : bytes
+            The bytes to write to the file.
+
+        Returns
+        -------
+        coroutine
+            An awaitable that returns the number of bytes written.
+        """
+    def seek(
+        self, pos: builtins.int, whence: builtins.int = 0
+    ) -> collections.abc.Awaitable[builtins.int]:
+        r"""
+        Change the position of this file to the given byte offset.
+
+        Parameters
+        ----------
+        pos : int
+            The byte offset (position) to set.
+        whence : int, optional
+            The reference point for the offset.
+            0: start of file (default); 1: current position; 2: end of file.
+
+        Returns
+        -------
+        coroutine
+            An awaitable that returns the current absolute position.
+        """
+    def tell(self) -> collections.abc.Awaitable[builtins.int]:
+        r"""
+        Return the current position of this file.
+
+        Returns
+        -------
+        coroutine
+            An awaitable that returns the current absolute position.
+        """
+    def close(self) -> collections.abc.Awaitable[None]:
+        r"""
+        Close this file.
+
+        This also flushes write buffers, if applicable.
+
+        Notes
+        -----
+        A closed file cannot be used for further I/O operations.
+        """
+    def __aenter__(self) -> typing.Self: ...
+    def __aexit__(
+        self,
+        exc_type: type[builtins.BaseException] | None,
+        exc_value: builtins.BaseException | None,
+        traceback: types.TracebackType | None,
+    ) -> None: ...
+    def readable(self) -> collections.abc.Awaitable[builtins.bool]:
+        r"""
+        Whether this file can be read from.
+
+        Returns
+        -------
+        coroutine
+            An awaitable that returns True if this file can be read from.
+        """
+    def writable(self) -> collections.abc.Awaitable[builtins.bool]:
+        r"""
+        Whether this file can be written to.
+
+        Returns
+        -------
+        coroutine
+            An awaitable that returns True if this file can be written to.
+        """
+    def seekable(self) -> collections.abc.Awaitable[builtins.bool]:
+        r"""
+        Whether this file can be repositioned.
+
+        Notes
+        -----
+        This is only applicable to *readable* files.
+
+        Returns
+        -------
+        coroutine
+            An awaitable that returns True if this file can be repositioned.
+        """
+
[email protected]
+class File:
+    r"""
+    A file-like object for reading and writing data.
+
+    Created by the `open` method of the `Operator` class.
+    """
+
+    @property
+    def closed(self) -> builtins.bool:
+        r"""
+        Whether this file is closed.
+
+        Returns
+        -------
+        bool
+            True if this file is closed.
+        """
+    def read(self, size: builtins.int | None = None) -> builtins.bytes:
+        r"""
+        Read at most `size` bytes from this file.
+
+        If `size` is not specified, read until EOF.
+
+        Parameters
+        ----------
+        size : int, optional
+            The maximum number of bytes to read.
+
+        Returns
+        -------
+        bytes
+            The bytes read from this file.
+        """
+    def readline(self, size: builtins.int | None = None) -> builtins.bytes:
+        r"""
+        Read one line from this file.
+
+        If `size` is not specified, read until newline.
+
+        Parameters
+        ----------
+        size : int, optional
+            The maximum number of bytes to read.
+
+        Notes
+        -----
+        Retains newline characters after each line, unless
+        the file’s last line has no terminating newline.
+
+        Returns
+        -------
+        bytes
+            The bytes read from this file.
+        """
+    def readinto(self, buffer: builtins.bytes | builtins.bytearray) -> 
builtins.int:
+        r"""
+        Read bytes into a pre-allocated buffer.
+
+        Parameters
+        ----------
+        buffer : bytes | bytearray
+            A writable, pre-allocated buffer to read into.
+
+        Returns
+        -------
+        int
+            The number of bytes read.
+        """
+    def write(self, bs: builtins.bytes) -> builtins.int:
+        r"""
+        Write bytes to this file.
+
+        Parameters
+        ----------
+        bs : bytes
+            The bytes to write to the file.
+
+        Returns
+        -------
+        int
+            The number of bytes written.
+        """
+    def seek(self, pos: builtins.int, whence: builtins.int = 0) -> 
builtins.int:
+        r"""
+        Change the position of this file to the given byte offset.
+
+        Parameters
+        ----------
+        pos : int
+            The byte offset (position) to set.
+        whence : int, optional
+            The reference point for the offset.
+            0: start of file (default); 1: current position; 2: end of file.
+
+        Returns
+        -------
+        int
+            The new absolute position.
+        """
+    def tell(self) -> builtins.int:
+        r"""
+        Return the current position of this file.
+
+        Returns
+        -------
+        int
+            The current absolute position.
+        """
+    def close(self) -> None:
+        r"""
+        Close this file.
+
+        This also flushes write buffers, if applicable.
+
+        Notes
+        -----
+        A closed file cannot be used for further I/O operations.
+        """
+    def __enter__(self, slf: File) -> File: ...
+    def __exit__(
+        self,
+        exc_type: type[builtins.BaseException] | None,
+        exc_value: builtins.BaseException | None,
+        traceback: types.TracebackType | None,
+    ) -> None: ...
+    def flush(self) -> None:
+        r"""
+        Flush the underlying writer.
+
+        Notes
+        -----
+        Is a no-op if the file is not `writable`.
+        """
+    def readable(self) -> builtins.bool:
+        r"""
+        Whether this file can be read from.
+
+        Returns
+        -------
+        bool
+            True if this file can be read from.
+        """
+    def writable(self) -> builtins.bool:
+        r"""
+        Whether this file can be written to.
+
+        Returns
+        -------
+        bool
+            True if this file can be written to.
+        """
+    def seekable(self) -> builtins.bool:
+        r"""
+        Whether this file can be repositioned.
+
+        Notes
+        -----
+        This is only applicable to *readable* files.
+
+        Returns
+        -------
+        bool
+            True if this file can be repositioned.
+        """
diff --git a/bindings/python/python/opendal/layers.pyi 
b/bindings/python/python/opendal/layers.pyi
index 8dbd071c9..d46e6f5e1 100644
--- a/bindings/python/python/opendal/layers.pyi
+++ b/bindings/python/python/opendal/layers.pyi
@@ -24,9 +24,7 @@ import typing
 @typing.final
 class ConcurrentLimitLayer(Layer):
     r"""
-    ConcurrentLimitLayer.
-
-    Create a layer that limits the number of concurrent operations.
+    A layer that limits the number of concurrent operations.
 
     Notes
     -----
@@ -51,19 +49,12 @@ class ConcurrentLimitLayer(Layer):
         """
 
 class Layer:
-    r"""
-    Layer.
-
-    Layers are used to intercept the operations on the underlying storage.
-    """
+    r"""Layers are used to intercept the operations on the underlying 
storage."""
 
 @typing.final
 class MimeGuessLayer(Layer):
     r"""
-    MimeGuessLayer.
-
-    Create a layer that guesses MIME types for objects based on their
-    paths or content.
+    A layer that guesses MIME types for objects based on their paths or 
content.
 
     This layer uses the `mime_guess` crate
     (see https://crates.io/crates/mime_guess) to infer the
@@ -91,8 +82,6 @@ class MimeGuessLayer(Layer):
 @typing.final
 class RetryLayer(Layer):
     r"""
-    RetryLayer.
-
     A layer that retries operations that fail with temporary errors.
 
     Operations are retried if they fail with an error for which
diff --git a/bindings/python/python/opendal/types.pyi 
b/bindings/python/python/opendal/types.pyi
index 48377f206..189c66d08 100644
--- a/bindings/python/python/opendal/types.pyi
+++ b/bindings/python/python/opendal/types.pyi
@@ -99,6 +99,32 @@ class Metadata:
     def user_metadata(self) -> builtins.dict[builtins.str, builtins.str] | 
None:
         r"""The user-defined metadata of this entry."""
 
[email protected]
+class PresignedRequest:
+    r"""
+    A presigned request.
+
+    This contains the information required to make a request to the
+    underlying service, including the URL, method, and headers.
+    """
+
+    @property
+    def url(self) -> builtins.str:
+        r"""The URL of this request."""
+    @property
+    def method(self) -> builtins.str:
+        r"""The HTTP method of this request."""
+    @property
+    def headers(self) -> builtins.dict[builtins.str, builtins.str]:
+        r"""
+        The HTTP headers of this request.
+
+        Returns
+        -------
+        dict
+            The HTTP headers of this request.
+        """
+
 @typing.final
 class EntryMode(enum.Enum):
     r"""
diff --git a/bindings/python/ruff.toml b/bindings/python/ruff.toml
index 6d47e327b..82ab34682 100644
--- a/bindings/python/ruff.toml
+++ b/bindings/python/ruff.toml
@@ -73,6 +73,6 @@ strict = true
 known-first-party = ["opendal"]
 
 [lint.per-file-ignores]
-"*.pyi" = ["PYI021", "ANN003", "RUF100"]
+"*.pyi" = ["PYI021", "ANN003", "RUF100", "ANN401"]
 "benchmark/*" = ["D100", "D101", "D103", "ANN201"]
 "tests/*" = ["D101", "D100", "D103", "ANN201", "ANN001"]
diff --git a/bindings/python/src/file.rs b/bindings/python/src/file.rs
index 4037a6c97..3a5547351 100644
--- a/bindings/python/src/file.rs
+++ b/bindings/python/src/file.rs
@@ -36,9 +36,11 @@ use tokio::sync::Mutex;
 
 use crate::*;
 
-/// A file-like object.
-/// Can be used as a context manager.
-#[pyclass(module = "opendal")]
+/// A file-like object for reading and writing data.
+///
+/// Created by the `open` method of the `Operator` class.
+#[gen_stub_pyclass]
+#[pyclass(module = "opendal.file")]
 pub struct File(FileState);
 
 enum FileState {
@@ -57,10 +59,24 @@ impl File {
     }
 }
 
+#[gen_stub_pymethods]
 #[pymethods]
 impl File {
-    /// Read and return at most size bytes, or if size is not given, until EOF.
-    #[pyo3(signature = (size=None,))]
+    /// Read at most `size` bytes from this file.
+    ///
+    /// If `size` is not specified, read until EOF.
+    ///
+    /// Parameters
+    /// ----------
+    /// size : int, optional
+    ///     The maximum number of bytes to read.
+    ///
+    /// Returns
+    /// -------
+    /// bytes
+    ///     The bytes read from this file.
+    #[gen_stub(override_return_type(type_repr = "builtins.bytes", 
imports=("builtins")))]
+    #[pyo3(signature = (size=None))]
     pub fn read<'p>(
         &'p mut self,
         py: Python<'p>,
@@ -101,10 +117,26 @@ impl File {
         Buffer::new(buffer).into_bytes_ref(py)
     }
 
-    /// Read a single line from the file.
-    /// A newline character (`\n`) is left at the end of the string, and is 
only omitted on the last line of the file if the file doesn’t end in a newline.
-    /// If size is specified, at most size bytes will be read.
-    #[pyo3(signature = (size=None,))]
+    /// Read one line from this file.
+    ///
+    /// If `size` is not specified, read until newline.
+    ///
+    /// Parameters
+    /// ----------
+    /// size : int, optional
+    ///     The maximum number of bytes to read.
+    ///
+    /// Notes
+    /// -----
+    /// Retains newline characters after each line, unless
+    /// the file’s last line has no terminating newline.
+    ///
+    /// Returns
+    /// -------
+    /// bytes
+    ///     The bytes read from this file.
+    #[gen_stub(override_return_type(type_repr = "builtins.bytes", 
imports=("builtins")))]
+    #[pyo3(signature = (size=None))]
     pub fn readline<'p>(
         &'p mut self,
         py: Python<'p>,
@@ -146,8 +178,22 @@ impl File {
         Buffer::new(buffer).into_bytes_ref(py)
     }
 
-    /// Read bytes into a pre-allocated, writable buffer
-    pub fn readinto(&mut self, buffer: PyBuffer<u8>) -> PyResult<usize> {
+    /// Read bytes into a pre-allocated buffer.
+    ///
+    /// Parameters
+    /// ----------
+    /// buffer : bytes | bytearray
+    ///     A writable, pre-allocated buffer to read into.
+    ///
+    /// Returns
+    /// -------
+    /// int
+    ///     The number of bytes read.
+    pub fn readinto(
+        &mut self,
+        #[gen_stub(override_type(type_repr = "builtins.bytes | 
builtins.bytearray", imports=("builtins")))]
+        buffer: PyBuffer<u8>,
+    ) -> PyResult<usize> {
         let reader = match &mut self.0 {
             FileState::Reader(r) => r,
             FileState::Writer(_) => {
@@ -181,8 +227,21 @@ impl File {
         })
     }
 
-    /// Write bytes into the file.
-    pub fn write(&mut self, bs: &[u8]) -> PyResult<usize> {
+    /// Write bytes to this file.
+    ///
+    /// Parameters
+    /// ----------
+    /// bs : bytes
+    ///     The bytes to write to the file.
+    ///
+    /// Returns
+    /// -------
+    /// int
+    ///     The number of bytes written.
+    pub fn write(
+        &mut self,
+        #[gen_stub(override_type(type_repr = "builtins.bytes", 
imports=("builtins")))] bs: &[u8],
+    ) -> PyResult<usize> {
         let writer = match &mut self.0 {
             FileState::Reader(_) => {
                 return Err(PyIOError::new_err(
@@ -203,15 +262,20 @@ impl File {
             .map_err(|err| PyIOError::new_err(err.to_string()))
     }
 
-    /// Change the stream position to the given byte offset.
-    /// Offset is interpreted relative to the position indicated by `whence`.
-    /// The default value for whence is `SEEK_SET`. Values for `whence` are:
+    /// Change the position of this file to the given byte offset.
     ///
-    /// * `SEEK_SET` or `0` – start of the stream (the default); offset should 
be zero or positive
-    /// * `SEEK_CUR` or `1` – current stream position; offset may be negative
-    /// * `SEEK_END` or `2` – end of the stream; offset is usually negative
+    /// Parameters
+    /// ----------
+    /// pos : int
+    ///     The byte offset (position) to set.
+    /// whence : int, optional
+    ///     The reference point for the offset.
+    ///     0: start of file (default); 1: current position; 2: end of file.
     ///
-    /// Return the new absolute position.
+    /// Returns
+    /// -------
+    /// int
+    ///     The new absolute position.
     #[pyo3(signature = (pos, whence = 0))]
     pub fn seek(&mut self, pos: i64, whence: u8) -> PyResult<u64> {
         if !self.seekable()? {
@@ -245,7 +309,12 @@ impl File {
             .map_err(|err| PyIOError::new_err(err.to_string()))
     }
 
-    /// Return the current stream position.
+    /// Return the current position of this file.
+    ///
+    /// Returns
+    /// -------
+    /// int
+    ///     The current absolute position.
     pub fn tell(&mut self) -> PyResult<u64> {
         let reader = match &mut self.0 {
             FileState::Reader(r) => r,
@@ -266,6 +335,13 @@ impl File {
             .map_err(|err| PyIOError::new_err(err.to_string()))
     }
 
+    /// Close this file.
+    ///
+    /// This also flushes write buffers, if applicable.
+    ///
+    /// Notes
+    /// -----
+    /// A closed file cannot be used for further I/O operations.
     fn close(&mut self) -> PyResult<()> {
         if let FileState::Writer(w) = &mut self.0 {
             w.close().map_err(format_pyerr_from_io_error)?;
@@ -278,16 +354,25 @@ impl File {
         slf
     }
 
+    #[allow(unused_variables)]
+    #[pyo3(signature = (exc_type, exc_value, traceback))]
     pub fn __exit__(
         &mut self,
-        _exc_type: Py<PyAny>,
-        _exc_value: Py<PyAny>,
-        _traceback: Py<PyAny>,
+        #[gen_stub(override_type(type_repr = "type[builtins.BaseException] | 
None", imports=("builtins")))]
+        exc_type: Py<PyAny>,
+        #[gen_stub(override_type(type_repr = "builtins.BaseException | None", 
imports=("builtins")))]
+        exc_value: Py<PyAny>,
+        #[gen_stub(override_type(type_repr = "types.TracebackType | None", 
imports=("types")))]
+        traceback: Py<PyAny>,
     ) -> PyResult<()> {
         self.close()
     }
 
-    /// Flush the underlying writer. Is a no-op if the file is opened in 
reading mode.
+    /// Flush the underlying writer.
+    ///
+    /// Notes
+    /// -----
+    /// Is a no-op if the file is not `writable`.
     pub fn flush(&mut self) -> PyResult<()> {
         if matches!(self.0, FileState::Reader(_)) {
             Ok(())
@@ -301,19 +386,36 @@ impl File {
         }
     }
 
-    /// Return True if the stream can be read from.
+    /// Whether this file can be read from.
+    ///
+    /// Returns
+    /// -------
+    /// bool
+    ///     True if this file can be read from.
     pub fn readable(&self) -> PyResult<bool> {
         Ok(matches!(self.0, FileState::Reader(_)))
     }
 
-    /// Return True if the stream can be written to.
+    /// Whether this file can be written to.
+    ///
+    /// Returns
+    /// -------
+    /// bool
+    ///     True if this file can be written to.
     pub fn writable(&self) -> PyResult<bool> {
         Ok(matches!(self.0, FileState::Writer(_)))
     }
 
-    /// Return True if the stream can be repositioned.
+    /// Whether this file can be repositioned.
+    ///
+    /// Notes
+    /// -----
+    /// This is only applicable to *readable* files.
     ///
-    /// In OpenDAL this is limited to only *readable* streams.
+    /// Returns
+    /// -------
+    /// bool
+    ///     True if this file can be repositioned.
     pub fn seekable(&self) -> PyResult<bool> {
         match &self.0 {
             FileState::Reader(_) => Ok(true),
@@ -321,16 +423,23 @@ impl File {
         }
     }
 
-    /// Return True if the stream is closed.
+    /// Whether this file is closed.
+    ///
+    /// Returns
+    /// -------
+    /// bool
+    ///     True if this file is closed.
     #[getter]
     pub fn closed(&self) -> PyResult<bool> {
         Ok(matches!(self.0, FileState::Closed))
     }
 }
 
-/// A file-like async reader.
-/// Can be used as an async context manager.
-#[pyclass(module = "opendal")]
+/// An async file-like object for reading and writing data.
+///
+/// Created by the `open` method of the `AsyncOperator` class.
+#[gen_stub_pyclass]
+#[pyclass(module = "opendal.file")]
 pub struct AsyncFile(Arc<Mutex<AsyncFileState>>);
 
 enum AsyncFileState {
@@ -349,9 +458,26 @@ impl AsyncFile {
     }
 }
 
+#[gen_stub_pymethods]
 #[pymethods]
 impl AsyncFile {
-    /// Read and return at most size bytes, or if size is not given, until EOF.
+    /// Read at most `size` bytes from this file asynchronously.
+    ///
+    /// If `size` is not specified, read until EOF.
+    ///
+    /// Parameters
+    /// ----------
+    /// size : int, optional
+    ///     The maximum number of bytes to read.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns the bytes read from the stream.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[builtins.bytes]",
+        imports=("collections.abc", "builtins")
+    ))]
     #[pyo3(signature = (size=None))]
     pub fn read<'p>(&'p self, py: Python<'p>, size: Option<usize>) -> 
PyResult<Bound<'p, PyAny>> {
         let state = self.0.clone();
@@ -397,8 +523,27 @@ impl AsyncFile {
         })
     }
 
-    /// Write bytes into the file.
-    pub fn write<'p>(&'p mut self, py: Python<'p>, bs: &'p [u8]) -> 
PyResult<Bound<'p, PyAny>> {
+    /// Write bytes to this file asynchronously.
+    ///
+    /// Parameters
+    /// ----------
+    /// bs : bytes
+    ///     The bytes to write to the file.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns the number of bytes written.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[builtins.int]",
+        imports=("collections.abc", "builtins")
+    ))]
+    pub fn write<'p>(
+        &'p mut self,
+        py: Python<'p>,
+        #[gen_stub(override_type(type_repr = "builtins.bytes", 
imports=("builtins")))]
+        bs: &'p [u8],
+    ) -> PyResult<Bound<'p, PyAny>> {
         let state = self.0.clone();
 
         // FIXME: can we avoid this clone?
@@ -429,15 +574,24 @@ impl AsyncFile {
         })
     }
 
-    /// Change the stream position to the given byte offset.
-    /// offset is interpreted relative to the position indicated by `whence`.
-    /// The default value for whence is `SEEK_SET`. Values for `whence` are:
+    /// Change the position of this file to the given byte offset.
     ///
-    /// * `SEEK_SET` or `0` – start of the stream (the default); offset should 
be zero or positive
-    /// * `SEEK_CUR` or `1` – current stream position; offset may be negative
-    /// * `SEEK_END` or `2` – end of the stream; offset is usually negative
+    /// Parameters
+    /// ----------
+    /// pos : int
+    ///     The byte offset (position) to set.
+    /// whence : int, optional
+    ///     The reference point for the offset.
+    ///     0: start of file (default); 1: current position; 2: end of file.
     ///
-    /// Return the new absolute position.
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns the current absolute position.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[builtins.int]",
+        imports=("collections.abc", "builtins")
+    ))]
     #[pyo3(signature = (pos, whence = 0))]
     pub fn seek<'p>(
         &'p mut self,
@@ -479,7 +633,16 @@ impl AsyncFile {
         .and_then(|pos| pos.into_bound_py_any(py))
     }
 
-    /// Return the current stream position.
+    /// Return the current position of this file.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns the current absolute position.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[builtins.int]",
+        imports=("collections.abc", "builtins")
+    ))]
     pub fn tell<'p>(&'p mut self, py: Python<'p>) -> PyResult<Bound<'p, 
PyAny>> {
         let state = self.0.clone();
 
@@ -508,6 +671,17 @@ impl AsyncFile {
         .and_then(|pos| pos.into_bound_py_any(py))
     }
 
+    /// Close this file.
+    ///
+    /// This also flushes write buffers, if applicable.
+    ///
+    /// Notes
+    /// -----
+    /// A closed file cannot be used for further I/O operations.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[None]",
+        imports=("collections.abc")
+    ))]
     fn close<'p>(&'p mut self, py: Python<'p>) -> PyResult<Bound<'p, PyAny>> {
         let state = self.0.clone();
         future_into_py(py, async move {
@@ -520,22 +694,38 @@ impl AsyncFile {
         })
     }
 
+    #[gen_stub(override_return_type(type_repr="typing.Self", 
imports=("typing")))]
     fn __aenter__<'a>(slf: PyRef<'a, Self>, py: Python<'a>) -> 
PyResult<Bound<'a, PyAny>> {
         let slf = slf.into_py_any(py)?;
         future_into_py(py, async move { Ok(slf) })
     }
 
+    #[allow(unused_variables)]
+    #[gen_stub(override_return_type(type_repr = "None"))]
+    #[pyo3(signature = (exc_type, exc_value, traceback))]
     fn __aexit__<'a>(
         &'a mut self,
         py: Python<'a>,
-        _exc_type: &Bound<'a, PyAny>,
-        _exc_value: &Bound<'a, PyAny>,
-        _traceback: &Bound<'a, PyAny>,
+        #[gen_stub(override_type(type_repr = "type[builtins.BaseException] | 
None", imports=("builtins")))]
+        exc_type: &Bound<'a, PyAny>,
+        #[gen_stub(override_type(type_repr = "builtins.BaseException | None", 
imports=("builtins")))]
+        exc_value: &Bound<'a, PyAny>,
+        #[gen_stub(override_type(type_repr = "types.TracebackType | None", 
imports=("types")))]
+        traceback: &Bound<'a, PyAny>,
     ) -> PyResult<Bound<'a, PyAny>> {
         self.close(py)
     }
 
-    /// Check if the stream may be read from.
+    /// Whether this file can be read from.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns True if this file can be read from.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[builtins.bool]",
+        imports=("collections.abc", "builtins")
+    ))]
     pub fn readable<'p>(&'p self, py: Python<'p>) -> PyResult<Bound<'p, 
PyAny>> {
         let state = self.0.clone();
         future_into_py(py, async move {
@@ -544,7 +734,16 @@ impl AsyncFile {
         })
     }
 
-    /// Check if the stream may be written to.
+    /// Whether this file can be written to.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns True if this file can be written to.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[builtins.bool]",
+        imports=("collections.abc", "builtins")
+    ))]
     pub fn writable<'p>(&'p self, py: Python<'p>) -> PyResult<Bound<'p, 
PyAny>> {
         let state = self.0.clone();
         future_into_py(py, async move {
@@ -553,7 +752,20 @@ impl AsyncFile {
         })
     }
 
-    /// Check if the stream reader may be re-located.
+    /// Whether this file can be repositioned.
+    ///
+    /// Notes
+    /// -----
+    /// This is only applicable to *readable* files.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns True if this file can be repositioned.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[builtins.bool]",
+        imports=("collections.abc", "builtins")
+    ))]
     pub fn seekable<'p>(&'p self, py: Python<'p>) -> PyResult<Bound<'p, 
PyAny>> {
         if true {
             self.readable(py)
@@ -562,7 +774,16 @@ impl AsyncFile {
         }
     }
 
-    /// Check if the stream is closed.
+    /// Whether this file is closed.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns True if this file is closed.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[builtins.bool]",
+        imports=("collections.abc", "builtins")
+    ))]
     #[getter]
     pub fn closed<'p>(&'p self, py: Python<'p>) -> PyResult<Bound<'p, PyAny>> {
         let state = self.0.clone();
diff --git a/bindings/python/src/layers.rs b/bindings/python/src/layers.rs
index 3948f30d6..84365f88e 100644
--- a/bindings/python/src/layers.rs
+++ b/bindings/python/src/layers.rs
@@ -24,15 +24,11 @@ pub trait PythonLayer: Send + Sync {
     fn layer(&self, op: Operator) -> Operator;
 }
 
-/// Layer
-///
 /// Layers are used to intercept the operations on the underlying storage.
 #[gen_stub_pyclass]
 #[pyclass(module = "opendal.layers", subclass)]
 pub struct Layer(pub Box<dyn PythonLayer>);
 
-/// RetryLayer
-///
 /// A layer that retries operations that fail with temporary errors.
 ///
 /// Operations are retried if they fail with an error for which
@@ -117,9 +113,7 @@ impl RetryLayer {
     }
 }
 
-/// ConcurrentLimitLayer
-///
-/// Create a layer that limits the number of concurrent operations.
+/// A layer that limits the number of concurrent operations.
 ///
 /// Notes
 /// -----
@@ -163,10 +157,7 @@ impl ConcurrentLimitLayer {
     }
 }
 
-/// MimeGuessLayer
-///
-/// Create a layer that guesses MIME types for objects based on their
-/// paths or content.
+/// A layer that guesses MIME types for objects based on their paths or 
content.
 ///
 /// This layer uses the `mime_guess` crate
 /// (see https://crates.io/crates/mime_guess) to infer the
diff --git a/bindings/python/src/lib.rs b/bindings/python/src/lib.rs
index f86b5fa22..c4133ecc9 100644
--- a/bindings/python/src/lib.rs
+++ b/bindings/python/src/lib.rs
@@ -38,15 +38,15 @@ mod errors;
 pub use errors::*;
 mod options;
 pub use options::*;
-use pyo3_stub_gen::{define_stub_info_gatherer, derive::*};
+use pyo3_stub_gen::{define_stub_info_gatherer, derive::*, module_variable};
+
+// Add version
+module_variable!("opendal", "__version__", &str, env!("CARGO_PKG_VERSION"));
 
 #[pymodule(gil_used = false)]
 fn _opendal(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
-    m.add_class::<Operator>()?;
-    m.add_class::<AsyncOperator>()?;
-
-    m.add_class::<File>()?;
-    m.add_class::<AsyncFile>()?;
+    // File module
+    add_pymodule!(py, m, "file", [File, AsyncFile])?;
 
     // Capability module
     add_pymodule!(py, m, "capability", [Capability])?;
@@ -60,9 +60,15 @@ fn _opendal(py: Python, m: &Bound<'_, PyModule>) -> 
PyResult<()> {
     )?;
 
     // Types module
-    add_pymodule!(py, m, "types", [Entry, EntryMode, Metadata])?;
+    add_pymodule!(
+        py,
+        m,
+        "types",
+        [Entry, EntryMode, Metadata, PresignedRequest]
+    )?;
 
-    m.add_class::<PresignedRequest>()?;
+    m.add_class::<Operator>()?;
+    m.add_class::<AsyncOperator>()?;
 
     m.add_class::<WriteOptions>()?;
     m.add_class::<ReadOptions>()?;
diff --git a/bindings/python/src/operator.rs b/bindings/python/src/operator.rs
index 5300256fa..993cda599 100644
--- a/bindings/python/src/operator.rs
+++ b/bindings/python/src/operator.rs
@@ -49,9 +49,14 @@ fn build_blocking_operator(
     Ok(op)
 }
 
-/// `Operator` is the entry for all public blocking APIs
+/// The blocking equivalent of `AsyncOperator`.
 ///
-/// Create a new blocking `Operator` with the given `scheme` and 
options(`**kwargs`).
+/// `Operator` is the entry point for all blocking APIs.
+///
+/// See also
+/// --------
+/// AsyncOperator
+#[gen_stub_pyclass]
 #[pyclass(module = "opendal")]
 pub struct Operator {
     core: ocore::blocking::Operator,
@@ -59,18 +64,32 @@ pub struct Operator {
     __map: HashMap<String, String>,
 }
 
+#[gen_stub_pymethods]
 #[pymethods]
 impl Operator {
+    /// Create a new blocking `Operator`.
+    ///
+    /// Parameters
+    /// ----------
+    /// scheme : str
+    ///     The scheme of the service.
+    /// **kwargs : dict
+    ///     The options for the service.
+    ///
+    /// Returns
+    /// -------
+    /// Operator
+    ///     The new operator.
     #[new]
-    #[pyo3(signature = (scheme, *, **map))]
-    pub fn new(scheme: &str, map: Option<&Bound<PyDict>>) -> PyResult<Self> {
+    #[pyo3(signature = (scheme, *, **kwargs))]
+    pub fn new(scheme: &str, kwargs: Option<&Bound<PyDict>>) -> PyResult<Self> 
{
         let scheme = ocore::Scheme::from_str(scheme)
             .map_err(|err| {
                 ocore::Error::new(ocore::ErrorKind::Unexpected, "unsupported 
scheme")
                     .set_source(err)
             })
             .map_err(format_pyerr)?;
-        let map = map
+        let map = kwargs
             .map(|v| {
                 v.extract::<HashMap<String, String>>()
                     .expect("must be valid hashmap")
@@ -84,7 +103,17 @@ impl Operator {
         })
     }
 
-    /// Add new layers upon the existing operator
+    /// Add a new layer to this operator.
+    ///
+    /// Parameters
+    /// ----------
+    /// layer : Layer
+    ///     The layer to add.
+    ///
+    /// Returns
+    /// -------
+    /// Operator
+    ///     A new operator with the layer added.
     pub fn layer(&self, layer: &layers::Layer) -> PyResult<Self> {
         let op = layer.0.layer(self.core.clone().into());
 
@@ -98,7 +127,24 @@ impl Operator {
         })
     }
 
-    /// Open a file-like reader for the given path.
+    /// Open a file-like object for the given path.
+    ///
+    /// The returning file-like object is a context manager.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the file.
+    /// mode : str
+    ///     The mode to open the file in. Only "rb" and "wb" are supported.
+    /// **kwargs
+    ///     Additional options for the underlying reader or writer.
+    ///
+    /// Returns
+    /// -------
+    /// File
+    ///     A file-like object.
+    #[gen_stub(override_return_type(type_repr = "file.File"))]
     #[pyo3(signature = (path, mode, *, **kwargs))]
     pub fn open(
         &self,
@@ -141,150 +187,476 @@ impl Operator {
         }
     }
 
-    /// Read the whole path into bytes.
-    #[pyo3(signature = (path, **kwargs))]
+    /// Read the entire contents of a file at the given path.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the file.
+    /// version : str, optional
+    ///     The version of the file.
+    /// concurrent : int, optional
+    ///     The number of concurrent readers.
+    /// chunk : int, optional
+    ///     The size of each chunk.
+    /// gap : int, optional
+    ///     The gap between each chunk.
+    /// offset : int, optional
+    ///     The offset of the file.
+    /// prefetch : int, optional
+    ///     The number of bytes to prefetch.
+    /// size : int, optional
+    ///     The size of the file.
+    /// if_match : str, optional
+    ///     The ETag of the file.
+    /// if_none_match : str, optional
+    ///     The ETag of the file.
+    /// if_modified_since : str, optional
+    ///     The last modified time of the file.
+    /// if_unmodified_since : str, optional
+    ///     The last modified time of the file.
+    /// content_type : str, optional
+    ///     The content type of the file.
+    /// cache_control : str, optional
+    ///     The cache control of the file.
+    /// content_disposition : str, optional
+    ///     The content disposition of the file.
+    ///
+    /// Returns
+    /// -------
+    /// bytes
+    ///     The contents of the file as bytes.
+    #[allow(clippy::too_many_arguments)]
+    #[gen_stub(override_return_type(type_repr = "builtins.bytes", 
imports=("builtins")))]
+    #[pyo3(signature = (path, *,
+        version=None,
+        concurrent=None,
+        chunk=None,
+        gap=None,
+        offset=None,
+        prefetch=None,
+        size=None,
+        if_match=None,
+        if_none_match=None,
+        if_modified_since=None,
+        if_unmodified_since=None,
+        content_type=None,
+        cache_control=None,
+        content_disposition=None))]
     pub fn read<'p>(
         &'p self,
         py: Python<'p>,
         path: PathBuf,
-        kwargs: Option<ReadOptions>,
+        version: Option<String>,
+        concurrent: Option<usize>,
+        chunk: Option<usize>,
+        gap: Option<usize>,
+        offset: Option<usize>,
+        prefetch: Option<usize>,
+        size: Option<usize>,
+        if_match: Option<String>,
+        if_none_match: Option<String>,
+        #[gen_stub(override_type(type_repr = "datetime.datetime", 
imports=("datetime")))]
+        if_modified_since: Option<jiff::Timestamp>,
+        #[gen_stub(override_type(type_repr = "datetime.datetime", 
imports=("datetime")))]
+        if_unmodified_since: Option<jiff::Timestamp>,
+        content_type: Option<String>,
+        cache_control: Option<String>,
+        content_disposition: Option<String>,
     ) -> PyResult<Bound<'p, PyAny>> {
         let path = path.to_string_lossy().to_string();
-        let kwargs = kwargs.unwrap_or_default();
+        let opts = ReadOptions {
+            version,
+            concurrent,
+            chunk,
+            gap,
+            offset,
+            prefetch,
+            size,
+            if_match,
+            if_none_match,
+            if_modified_since,
+            if_unmodified_since,
+            content_type,
+            cache_control,
+            content_disposition,
+        };
         let buffer = self
             .core
-            .read_options(&path, kwargs.into())
+            .read_options(&path, opts.into())
             .map_err(format_pyerr)?
             .to_vec();
 
         Buffer::new(buffer).into_bytes_ref(py)
     }
 
-    /// Write bytes into a given path.
-    #[pyo3(signature = (path, bs, **kwargs))]
-    pub fn write(&self, path: PathBuf, bs: Vec<u8>, kwargs: 
Option<WriteOptions>) -> PyResult<()> {
+    /// Write bytes to a file at the given path.
+    ///
+    /// This function will create a file if it does not exist, and will
+    /// overwrite its contents if it does.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the file.
+    /// bs : bytes
+    ///     The contents to write to the file.
+    /// append : bool, optional
+    ///     Whether to append to the file instead of overwriting it.
+    /// chunk : int, optional
+    ///     The chunk size to use when writing the file.
+    /// concurrent : int, optional
+    ///     The number of concurrent requests to make when writing the file.
+    /// cache_control : str, optional
+    ///     The cache control header to set on the file.
+    /// content_type : str, optional
+    ///     The content type header to set on the file.
+    /// content_disposition : str, optional
+    ///     The content disposition header to set on the file.
+    /// content_encoding : str, optional
+    ///     The content encoding header to set on the file.
+    /// if_match : str, optional
+    ///     The ETag to match when writing the file.
+    /// if_none_match : str, optional
+    ///     The ETag to not match when writing the file.
+    /// if_not_exists : bool, optional
+    ///     Whether to fail if the file already exists.
+    /// user_metadata : dict, optional
+    ///     The user metadata to set on the file.
+    #[allow(clippy::too_many_arguments)]
+    #[pyo3(signature = (path, bs, *,
+        append= None,
+        chunk = None,
+        concurrent = None,
+        cache_control = None,
+        content_type = None,
+        content_disposition = None,
+        content_encoding = None,
+        if_match = None,
+        if_none_match = None,
+        if_not_exists = None,
+        user_metadata = None))]
+    pub fn write(
+        &self,
+        path: PathBuf,
+        #[gen_stub(override_type(type_repr = "builtins.bytes", 
imports=("builtins")))] bs: Vec<u8>,
+        append: Option<bool>,
+        chunk: Option<usize>,
+        concurrent: Option<usize>,
+        cache_control: Option<String>,
+        content_type: Option<String>,
+        content_disposition: Option<String>,
+        content_encoding: Option<String>,
+        if_match: Option<String>,
+        if_none_match: Option<String>,
+        if_not_exists: Option<bool>,
+        user_metadata: Option<HashMap<String, String>>,
+    ) -> PyResult<()> {
         let path = path.to_string_lossy().to_string();
-        let kwargs = kwargs.unwrap_or_default();
+        let opts = WriteOptions {
+            append,
+            chunk,
+            concurrent,
+            cache_control,
+            content_type,
+            content_disposition,
+            content_encoding,
+            if_match,
+            if_none_match,
+            if_not_exists,
+            user_metadata,
+        };
+
         self.core
-            .write_options(&path, bs, kwargs.into())
+            .write_options(&path, bs, opts.into())
             .map(|_| ())
             .map_err(format_pyerr)
     }
 
-    /// Get metadata for the current path **without cache** directly.
-    #[pyo3(signature = (path, **kwargs))]
-    pub fn stat(&self, path: PathBuf, kwargs: Option<&Bound<PyDict>>) -> 
PyResult<Metadata> {
+    /// Get the metadata of a file at the given path.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the file.
+    /// version : str, optional
+    ///     The version of the file.
+    /// if_match : str, optional
+    ///     The ETag of the file.
+    /// if_none_match : str, optional
+    ///     The ETag of the file.
+    /// if_modified_since : datetime, optional
+    ///     The last modified time of the file.
+    /// if_unmodified_since : datetime, optional
+    ///     The last modified time of the file.
+    /// content_type : str, optional
+    ///     The content type of the file.
+    /// cache_control : str, optional
+    ///     The cache control of the file.
+    /// content_disposition : str, optional
+    ///     The content disposition of the file.
+    ///
+    /// Returns
+    /// -------
+    /// Metadata
+    ///     The metadata of the file.
+    #[gen_stub(override_return_type(type_repr = "types.Metadata"))]
+    #[allow(clippy::too_many_arguments)]
+    #[pyo3(signature = (path, *,
+        version=None,
+        if_match=None,
+        if_none_match=None,
+        if_modified_since=None,
+        if_unmodified_since=None,
+        content_type=None,
+        cache_control=None,
+        content_disposition=None))]
+    pub fn stat(
+        &self,
+        path: PathBuf,
+        version: Option<String>,
+        if_match: Option<String>,
+        if_none_match: Option<String>,
+        #[gen_stub(override_type(type_repr = "datetime.datetime", 
imports=("datetime")))]
+        if_modified_since: Option<jiff::Timestamp>,
+        #[gen_stub(override_type(type_repr = "datetime.datetime", 
imports=("datetime")))]
+        if_unmodified_since: Option<jiff::Timestamp>,
+        content_type: Option<String>,
+        cache_control: Option<String>,
+        content_disposition: Option<String>,
+    ) -> PyResult<Metadata> {
         let path = path.to_string_lossy().to_string();
-        let kwargs = kwargs
-            .map(|v| v.extract::<StatOptions>())
-            .transpose()?
-            .unwrap_or_default();
+        let opts = StatOptions {
+            version,
+            if_match,
+            if_none_match,
+            if_modified_since,
+            if_unmodified_since,
+            content_type,
+            cache_control,
+            content_disposition,
+        };
         self.core
-            .stat_options(&path, kwargs.into())
+            .stat_options(&path, opts.into())
             .map_err(format_pyerr)
             .map(Metadata::new)
     }
 
-    /// Copy the source to the target.
+    /// Copy a file from one path to another.
+    ///
+    /// Parameters
+    /// ----------
+    /// source : str
+    ///     The path to the source file.
+    /// target : str
+    ///     The path to the target file.
     pub fn copy(&self, source: PathBuf, target: PathBuf) -> PyResult<()> {
         let source = source.to_string_lossy().to_string();
         let target = target.to_string_lossy().to_string();
         self.core.copy(&source, &target).map_err(format_pyerr)
     }
 
-    /// Rename filename.
+    /// Rename (move) a file from one path to another.
+    ///
+    /// Parameters
+    /// ----------
+    /// source : str
+    ///     The path to the source file.
+    /// target : str
+    ///     The path to the target file.
     pub fn rename(&self, source: PathBuf, target: PathBuf) -> PyResult<()> {
         let source = source.to_string_lossy().to_string();
         let target = target.to_string_lossy().to_string();
         self.core.rename(&source, &target).map_err(format_pyerr)
     }
 
-    /// Remove all files
+    /// Recursively remove all files and directories at the given path.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to remove.
     pub fn remove_all(&self, path: PathBuf) -> PyResult<()> {
         let path = path.to_string_lossy().to_string();
         self.core.remove_all(&path).map_err(format_pyerr)
     }
 
-    /// Create a dir at the given path.
-    ///
-    /// # Notes
-    ///
-    /// To indicate that a path is a directory, it is compulsory to include
-    /// a trailing / in the path. Failure to do so may result in
-    ///  a ` NotADirectory ` error being returned by OpenDAL.
+    /// Create a directory at the given path.
     ///
-    /// # Behavior
+    /// Notes
+    /// -----
+    /// To indicate that a path is a directory, it must end with a `/`.
+    /// This operation is always recursive, like `mkdir -p`.
     ///
-    /// - Create on existing dir will succeed.
-    /// - Create dir is always recursive, works like `mkdir -p`
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the directory.
     pub fn create_dir(&self, path: PathBuf) -> PyResult<()> {
         let path = path.to_string_lossy().to_string();
         self.core.create_dir(&path).map_err(format_pyerr)
     }
 
-    /// Delete given path.
+    /// Delete a file at the given path.
     ///
-    /// # Notes
+    /// Notes
+    /// -----
+    /// This operation will not return an error if the path does not exist.
     ///
-    /// - Delete not existing error won't return errors.
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the file.
     pub fn delete(&self, path: PathBuf) -> PyResult<()> {
         let path = path.to_string_lossy().to_string();
         self.core.delete(&path).map_err(format_pyerr)
     }
 
-    /// Checks if the given path exists.
+    /// Check if a path exists.
     ///
-    /// # Notes
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to check.
     ///
-    /// - Check not existing path won't return errors.
+    /// Returns
+    /// -------
+    /// bool
+    ///     True if the path exists, False otherwise.
     pub fn exists(&self, path: PathBuf) -> PyResult<bool> {
         let path = path.to_string_lossy().to_string();
         self.core.exists(&path).map_err(format_pyerr)
     }
 
-    /// List current dir path.
-    #[pyo3(signature = (path, **kwargs))]
-    pub fn list(&self, path: PathBuf, kwargs: Option<&Bound<PyDict>>) -> 
PyResult<BlockingLister> {
+    /// List entries in the given directory.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the directory.
+    /// limit : int, optional
+    ///     The maximum number of entries to return.
+    /// start_after : str, optional
+    ///     The entry to start after.
+    /// recursive : bool, optional
+    ///     Whether to list recursively.
+    /// versions : bool, optional
+    ///     Whether to list versions.
+    /// deleted : bool, optional
+    ///     Whether to list deleted entries.
+    ///
+    /// Returns
+    /// -------
+    /// BlockingLister
+    ///     An iterator over the entries in the directory.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Iterable[types.Entry]",
+        imports=("collections.abc")
+    ))]
+    #[pyo3(signature = (path, *,
+        limit=None,
+        start_after=None,
+        recursive=None,
+        versions=None,
+        deleted=None))]
+    pub fn list(
+        &self,
+        path: PathBuf,
+        limit: Option<usize>,
+        start_after: Option<String>,
+        recursive: Option<bool>,
+        versions: Option<bool>,
+        deleted: Option<bool>,
+    ) -> PyResult<BlockingLister> {
         let path = path.to_string_lossy().to_string();
 
-        let kwargs = kwargs
-            .map(|v| v.extract::<ListOptions>())
-            .transpose()?
-            .unwrap_or_default();
+        let opts = ListOptions {
+            limit,
+            start_after,
+            recursive,
+            versions,
+            deleted,
+        };
 
         let l = self
             .core
-            .lister_options(&path, kwargs.into())
+            .lister_options(&path, opts.into())
             .map_err(format_pyerr)?;
         Ok(BlockingLister::new(l))
     }
 
-    /// List dir in a flat way.
-    #[pyo3(signature = (path, **kwargs))]
-    pub fn scan<'p>(
+    /// Recursively list entries in the given directory.
+    ///
+    /// Deprecated
+    /// ----------
+    ///     Use `list()` with `recursive=True` instead.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the directory.
+    /// limit : int, optional
+    ///     The maximum number of entries to return.
+    /// start_after : str, optional
+    ///     The entry to start after.
+    /// versions : bool, optional
+    ///     Whether to list versions.
+    /// deleted : bool, optional
+    ///     Whether to list deleted entries.
+    ///
+    /// Returns
+    /// -------
+    /// BlockingLister
+    ///     An iterator over the entries in the directory.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Iterable[types.Entry]",
+        imports=("collections.abc")
+    ))]
+    #[pyo3(signature = (path, *,
+        limit=None,
+        start_after=None,
+        versions=None,
+        deleted=None))]
+    pub fn scan(
         &self,
-        py: Python<'p>,
         path: PathBuf,
-        kwargs: Option<&Bound<PyDict>>,
+        limit: Option<usize>,
+        start_after: Option<String>,
+        versions: Option<bool>,
+        deleted: Option<bool>,
     ) -> PyResult<BlockingLister> {
-        let d = PyDict::new(py);
-        let kwargs = kwargs.unwrap_or(&d);
-        kwargs.set_item("recursive", true)?;
-
-        self.list(path, Some(kwargs))
+        self.list(path, limit, start_after, Some(true), versions, deleted)
     }
 
-    pub fn capability(&self) -> PyResult<capability::Capability> {
+    /// Get all capabilities of this operator.
+    ///
+    /// Returns
+    /// -------
+    /// Capability
+    ///     The capability of the operator.
+    #[gen_stub(override_return_type(type_repr = "capability.Capability"))]
+    pub fn full_capability(&self) -> PyResult<capability::Capability> {
         Ok(capability::Capability::new(
             self.core.info().full_capability(),
         ))
     }
 
-    /// Check if this operator can work correctly.
+    /// Check if the operator is able to work correctly.
+    ///
+    /// Raises
+    /// ------
+    /// Exception
+    ///     If the operator is not able to work correctly.
     pub fn check(&self) -> PyResult<()> {
         self.core.check().map_err(format_pyerr)
     }
 
+    /// Create a new `AsyncOperator` from this blocking operator.
+    ///
+    /// Returns
+    /// -------
+    /// AsyncOperator
+    ///     The async operator.
     pub fn to_async_operator(&self) -> PyResult<AsyncOperator> {
         Ok(AsyncOperator {
             core: self.core.clone().into(),
@@ -307,6 +679,7 @@ impl Operator {
         }
     }
 
+    #[gen_stub(skip)]
     fn __getnewargs_ex__(&self, py: Python) -> PyResult<Py<PyAny>> {
         let args = vec![self.__scheme.to_string()];
         let args = PyTuple::new(py, args)?.into_py_any(py)?;
@@ -315,9 +688,14 @@ impl Operator {
     }
 }
 
-/// `AsyncOperator` is the entry for all public async APIs
+/// The async equivalent of `Operator`.
+///
+/// `AsyncOperator` is the entry point for all async APIs.
 ///
-/// Create a new `AsyncOperator` with the given `scheme` and 
options(`**kwargs`).
+/// See also
+/// --------
+/// Operator
+#[gen_stub_pyclass]
 #[pyclass(module = "opendal")]
 pub struct AsyncOperator {
     core: ocore::Operator,
@@ -325,18 +703,32 @@ pub struct AsyncOperator {
     __map: HashMap<String, String>,
 }
 
+#[gen_stub_pymethods]
 #[pymethods]
 impl AsyncOperator {
+    /// Create a new `AsyncOperator`.
+    ///
+    /// Parameters
+    /// ----------
+    /// scheme : str
+    ///     The scheme of the service.
+    /// **kwargs : dict
+    ///     The options for the service.
+    ///
+    /// Returns
+    /// -------
+    /// AsyncOperator
+    ///     The new async operator.
     #[new]
-    #[pyo3(signature = (scheme, *,  **map))]
-    pub fn new(scheme: &str, map: Option<&Bound<PyDict>>) -> PyResult<Self> {
+    #[pyo3(signature = (scheme, * ,**kwargs))]
+    pub fn new(scheme: &str, kwargs: Option<&Bound<PyDict>>) -> PyResult<Self> 
{
         let scheme = ocore::Scheme::from_str(scheme)
             .map_err(|err| {
                 ocore::Error::new(ocore::ErrorKind::Unexpected, "unsupported 
scheme")
                     .set_source(err)
             })
             .map_err(format_pyerr)?;
-        let map = map
+        let map = kwargs
             .map(|v| {
                 v.extract::<HashMap<String, String>>()
                     .expect("must be valid hashmap")
@@ -350,7 +742,17 @@ impl AsyncOperator {
         })
     }
 
-    /// Add new layers upon the existing operator
+    /// Add a new layer to the operator.
+    ///
+    /// Parameters
+    /// ----------
+    /// layer : Layer
+    ///     The layer to add.
+    ///
+    /// Returns
+    /// -------
+    /// AsyncOperator
+    ///     A new operator with the layer added.
     pub fn layer(&self, layer: &layers::Layer) -> PyResult<Self> {
         let op = layer.0.layer(self.core.clone());
         Ok(Self {
@@ -360,7 +762,27 @@ impl AsyncOperator {
         })
     }
 
-    /// Open a file-like reader for the given path.
+    /// Open an async file-like object for the given path.
+    ///
+    /// The returning async file-like object is a context manager.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the file.
+    /// mode : str
+    ///     The mode to open the file in. Only "rb" and "wb" are supported.
+    /// **kwargs : dict
+    ///     Additional options for the underlying reader or writer.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns a file-like object.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[file.AsyncFile]",
+        imports=("collections.abc")
+    ))]
     #[pyo3(signature = (path, mode, *, **kwargs))]
     pub fn open<'p>(
         &'p self,
@@ -410,21 +832,108 @@ impl AsyncOperator {
         })
     }
 
-    /// Read the whole path into bytes.
-    #[pyo3(signature = (path, **kwargs))]
+    /// Read the entire contents of a file at the given path.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the file.
+    /// version : str, optional
+    ///     The version of the file.
+    /// concurrent : int, optional
+    ///     The number of concurrent readers.
+    /// chunk : int, optional
+    ///     The size of each chunk.
+    /// gap : int, optional
+    ///     The gap between each chunk.
+    /// offset : int, optional
+    ///     The offset of the file.
+    /// prefetch : int, optional
+    ///     The number of bytes to prefetch.
+    /// size : int, optional
+    ///     The size of the file.
+    /// if_match : str, optional
+    ///     The ETag of the file.
+    /// if_none_match : str, optional
+    ///     The ETag of the file.
+    /// if_modified_since : str, optional
+    ///     The last modified time of the file.
+    /// if_unmodified_since : str, optional
+    ///     The last modified time of the file.
+    /// content_type : str, optional
+    ///     The content type of the file.
+    /// cache_control : str, optional
+    ///     The cache control of the file.
+    /// content_disposition : str, optional
+    ///     The content disposition of the file.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns the contents of the file as bytes.
+    #[allow(clippy::too_many_arguments)]
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[builtins.bytes]",
+        imports=("collections.abc", "builtins")
+    ))]
+    #[pyo3(signature = (path, *,
+        version=None,
+        concurrent=None,
+        chunk=None,
+        gap=None,
+        offset=None,
+        prefetch=None,
+        size=None,
+        if_match=None,
+        if_none_match=None,
+        if_modified_since=None,
+        if_unmodified_since=None,
+        content_type=None,
+        cache_control=None,
+        content_disposition=None))]
     pub fn read<'p>(
         &'p self,
         py: Python<'p>,
         path: PathBuf,
-        kwargs: Option<ReadOptions>,
+        version: Option<String>,
+        concurrent: Option<usize>,
+        chunk: Option<usize>,
+        gap: Option<usize>,
+        offset: Option<usize>,
+        prefetch: Option<usize>,
+        size: Option<usize>,
+        if_match: Option<String>,
+        if_none_match: Option<String>,
+        #[gen_stub(override_type(type_repr = "datetime.datetime", 
imports=("datetime")))]
+        if_modified_since: Option<jiff::Timestamp>,
+        #[gen_stub(override_type(type_repr = "datetime.datetime", 
imports=("datetime")))]
+        if_unmodified_since: Option<jiff::Timestamp>,
+        content_type: Option<String>,
+        cache_control: Option<String>,
+        content_disposition: Option<String>,
     ) -> PyResult<Bound<'p, PyAny>> {
         let this = self.core.clone();
         let path = path.to_string_lossy().to_string();
-        let kwargs = kwargs.unwrap_or_default();
+        let opts = ReadOptions {
+            version,
+            concurrent,
+            chunk,
+            gap,
+            offset,
+            prefetch,
+            size,
+            if_match,
+            if_none_match,
+            if_modified_since,
+            if_unmodified_since,
+            content_type,
+            cache_control,
+            content_disposition,
+        };
         future_into_py(py, async move {
-            let range = kwargs.make_range();
+            let range = opts.make_range();
             let res = this
-                .reader_options(&path, kwargs.into())
+                .reader_options(&path, opts.into())
                 .await
                 .map_err(format_pyerr)?
                 .read(range.to_range())
@@ -435,61 +944,176 @@ impl AsyncOperator {
         })
     }
 
-    /// Write bytes into given path.
-    #[pyo3(signature = (path, bs, **kwargs))]
+    /// Write bytes to a file at the given path.
+    ///
+    /// This function will create a file if it does not exist, and will
+    /// overwrite its contents if it does.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the file.
+    /// bs : bytes
+    ///     The contents to write to the file.
+    /// append : bool, optional
+    ///     Whether to append to the file instead of overwriting it.
+    /// chunk : int, optional
+    ///     The chunk size to use when writing the file.
+    /// concurrent : int, optional
+    ///     The number of concurrent requests to make when writing the file.
+    /// cache_control : str, optional
+    ///     The cache control header to set on the file.
+    /// content_type : str, optional
+    ///     The content type header to set on the file.
+    /// content_disposition : str, optional
+    ///     The content disposition header to set on the file.
+    /// content_encoding : str, optional
+    ///     The content encoding header to set on the file.
+    /// if_match : str, optional
+    ///     The ETag to match when writing the file.
+    /// if_none_match : str, optional
+    ///     The ETag to not match when writing the file.
+    /// if_not_exists : bool, optional
+    ///     Whether to fail if the file already exists.
+    /// user_metadata : dict, optional
+    ///     The user metadata to set on the file.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that completes when the write is finished.
+    #[allow(clippy::too_many_arguments)]
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[None]",
+        imports=("collections.abc")
+    ))]
+    #[pyo3(signature = (path, bs, *,
+        append= None,
+        chunk = None,
+        concurrent = None,
+        cache_control = None,
+        content_type = None,
+        content_disposition = None,
+        content_encoding = None,
+        if_match = None,
+        if_none_match = None,
+        if_not_exists = None,
+        user_metadata = None))]
     pub fn write<'p>(
         &'p self,
         py: Python<'p>,
         path: PathBuf,
-        bs: &Bound<PyBytes>,
-        kwargs: Option<WriteOptions>,
+        #[gen_stub(override_type(type_repr = "builtins.bytes", 
imports=("builtins")))] bs: &Bound<
+            PyBytes,
+        >,
+        append: Option<bool>,
+        chunk: Option<usize>,
+        concurrent: Option<usize>,
+        cache_control: Option<String>,
+        content_type: Option<String>,
+        content_disposition: Option<String>,
+        content_encoding: Option<String>,
+        if_match: Option<String>,
+        if_none_match: Option<String>,
+        if_not_exists: Option<bool>,
+        user_metadata: Option<HashMap<String, String>>,
     ) -> PyResult<Bound<'p, PyAny>> {
-        let mut kwargs = kwargs.unwrap_or_default();
+        let opts = WriteOptions {
+            append,
+            chunk,
+            concurrent,
+            cache_control,
+            content_type,
+            content_disposition,
+            content_encoding,
+            if_match,
+            if_none_match,
+            if_not_exists,
+            user_metadata,
+        };
         let this = self.core.clone();
         let bs = bs.as_bytes().to_vec();
         let path = path.to_string_lossy().to_string();
         future_into_py(py, async move {
-            let mut write = this
-                .write_with(&path, bs)
-                .append(kwargs.append.unwrap_or(false));
-            if let Some(buffer) = kwargs.chunk {
-                write = write.chunk(buffer);
-            }
-            if let Some(content_type) = &kwargs.content_type {
-                write = write.content_type(content_type);
-            }
-            if let Some(content_disposition) = &kwargs.content_disposition {
-                write = write.content_disposition(content_disposition);
-            }
-            if let Some(cache_control) = &kwargs.cache_control {
-                write = write.cache_control(cache_control);
-            }
-            if let Some(user_metadata) = kwargs.user_metadata.take() {
-                write = write.user_metadata(user_metadata);
-            }
-
-            write.await.map(|_| ()).map_err(format_pyerr)
+            this.write_options(&path, bs, opts.into())
+                .await
+                .map(|_| ())
+                .map_err(format_pyerr)
         })
     }
 
-    /// Get metadata for the current path **without cache** directly.
-    #[pyo3(signature = (path, **kwargs))]
+    /// Get the metadata of a file at the given path.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the file.
+    /// version : str, optional
+    ///     The version of the file.
+    /// if_match : str, optional
+    ///     The ETag of the file.
+    /// if_none_match : str, optional
+    ///     The ETag of the file.
+    /// if_modified_since : datetime, optional
+    ///     The last modified time of the file.
+    /// if_unmodified_since : datetime, optional
+    ///     The last modified time of the file.
+    /// content_type : str, optional
+    ///     The content type of the file.
+    /// cache_control : str, optional
+    ///     The cache control of the file.
+    /// content_disposition : str, optional
+    ///     The content disposition of the file.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns the metadata of the file.
+    #[allow(clippy::too_many_arguments)]
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[types.Metadata]",
+        imports=("collections.abc")
+    ))]
+    #[pyo3(signature = (path, *,
+        version=None,
+        if_match=None,
+        if_none_match=None,
+        if_modified_since=None,
+        if_unmodified_since=None,
+        content_type=None,
+        cache_control=None,
+        content_disposition=None))]
     pub fn stat<'p>(
         &'p self,
         py: Python<'p>,
         path: PathBuf,
-        kwargs: Option<&Bound<PyDict>>,
+        version: Option<String>,
+        if_match: Option<String>,
+        if_none_match: Option<String>,
+        #[gen_stub(override_type(type_repr = "datetime.datetime", 
imports=("datetime")))]
+        if_modified_since: Option<jiff::Timestamp>,
+        #[gen_stub(override_type(type_repr = "datetime.datetime", 
imports=("datetime")))]
+        if_unmodified_since: Option<jiff::Timestamp>,
+        content_type: Option<String>,
+        cache_control: Option<String>,
+        content_disposition: Option<String>,
     ) -> PyResult<Bound<'p, PyAny>> {
         let this = self.core.clone();
         let path = path.to_string_lossy().to_string();
-        let kwargs = kwargs
-            .map(|v| v.extract::<StatOptions>())
-            .transpose()?
-            .unwrap_or_default();
+        let opts = StatOptions {
+            version,
+            if_match,
+            if_none_match,
+            if_modified_since,
+            if_unmodified_since,
+            content_type,
+            cache_control,
+            content_disposition,
+        };
 
         future_into_py(py, async move {
             let res: Metadata = this
-                .stat_options(&path, kwargs.into())
+                .stat_options(&path, opts.into())
                 .await
                 .map_err(format_pyerr)
                 .map(Metadata::new)?;
@@ -498,7 +1122,23 @@ impl AsyncOperator {
         })
     }
 
-    /// Copy source to target.``
+    /// Copy a file from one path to another.
+    ///
+    /// Parameters
+    /// ----------
+    /// source : str
+    ///     The path to the source file.
+    /// target : str
+    ///     The path to the target file.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that completes when the copy is finished.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[None]",
+        imports=("collections.abc")
+    ))]
     pub fn copy<'p>(
         &'p self,
         py: Python<'p>,
@@ -513,7 +1153,23 @@ impl AsyncOperator {
         })
     }
 
-    /// Rename filename
+    /// Rename (move) a file from one path to another.
+    ///
+    /// Parameters
+    /// ----------
+    /// source : str
+    ///     The path to the source file.
+    /// target : str
+    ///     The path to the target file.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that completes when the rename is finished.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[None]",
+        imports=("collections.abc")
+    ))]
     pub fn rename<'p>(
         &'p self,
         py: Python<'p>,
@@ -528,7 +1184,21 @@ impl AsyncOperator {
         })
     }
 
-    /// Remove all file
+    /// Recursively remove all files and directories at the given path.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to remove.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that completes when the removal is finished.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[None]",
+        imports=("collections.abc")
+    ))]
     pub fn remove_all<'p>(&'p self, py: Python<'p>, path: PathBuf) -> 
PyResult<Bound<'p, PyAny>> {
         let this = self.core.clone();
         let path = path.to_string_lossy().to_string();
@@ -537,24 +1207,46 @@ impl AsyncOperator {
         })
     }
 
-    /// Check if this operator can work correctly.
+    /// Check if the operator is able to work correctly.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that completes when the check is finished.
+    ///
+    /// Raises
+    /// ------
+    /// Exception
+    ///     If the operator is not able to work correctly.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[None]",
+        imports=("collections.abc")
+    ))]
     pub fn check<'p>(&'p self, py: Python<'p>) -> PyResult<Bound<'p, PyAny>> {
         let this = self.core.clone();
         future_into_py(py, async move { 
this.check().await.map_err(format_pyerr) })
     }
 
-    /// Create a dir at given path.
+    /// Create a directory at the given path.
     ///
-    /// # Notes
+    /// Notes
+    /// -----
+    /// To indicate that a path is a directory, it must end with a `/`.
+    /// This operation is always recursive, like `mkdir -p`.
     ///
-    /// To indicate that a path is a directory, it is compulsory to include
-    /// a trailing / in the path. Failure to do so may result in
-    /// `NotADirectory` error being returned by OpenDAL.
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the directory.
     ///
-    /// # Behavior
-    ///
-    /// - Create on existing dir will succeed.
-    /// - Create dir is always recursive, works like `mkdir -p`
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that completes when the directory is created.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[None]",
+        imports=("collections.abc")
+    ))]
     pub fn create_dir<'p>(&'p self, py: Python<'p>, path: PathBuf) -> 
PyResult<Bound<'p, PyAny>> {
         let this = self.core.clone();
         let path = path.to_string_lossy().to_string();
@@ -563,11 +1255,25 @@ impl AsyncOperator {
         })
     }
 
-    /// Delete given path.
+    /// Delete a file at the given path.
+    ///
+    /// Notes
+    /// -----
+    /// This operation will not return an error if the path does not exist.
     ///
-    /// # Notes
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the file.
     ///
-    /// - Delete not existing error won't return errors.
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that completes when the file is deleted.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[None]",
+        imports=("collections.abc")
+    ))]
     pub fn delete<'p>(&'p self, py: Python<'p>, path: PathBuf) -> 
PyResult<Bound<'p, PyAny>> {
         let this = self.core.clone();
         let path = path.to_string_lossy().to_string();
@@ -577,11 +1283,21 @@ impl AsyncOperator {
         )
     }
 
-    /// Check given path is exists.
+    /// Check if a path exists.
     ///
-    /// # Notes
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to check.
     ///
-    /// - Check not existing path won't return errors.
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns True if the path exists, False otherwise.
+    #[gen_stub(override_return_type(
+        type_repr="collections.abc.Awaitable[builtins.bool]",
+        imports=("collections.abc", "builtins")
+    ))]
     pub fn exists<'p>(&'p self, py: Python<'p>, path: PathBuf) -> 
PyResult<Bound<'p, PyAny>> {
         let this = self.core.clone();
         let path = path.to_string_lossy().to_string();
@@ -591,24 +1307,58 @@ impl AsyncOperator {
         )
     }
 
-    /// List current dir path.
-    #[pyo3(signature = (path, **kwargs))]
+    /// List entries in the given directory.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the directory.
+    /// limit : int, optional
+    ///     The maximum number of entries to return.
+    /// start_after : str, optional
+    ///     The entry to start after.
+    /// recursive : bool, optional
+    ///     Whether to list recursively.
+    /// versions : bool, optional
+    ///     Whether to list versions.
+    /// deleted : bool, optional
+    ///     Whether to list deleted entries.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns an async iterator over the entries.
+    #[allow(clippy::too_many_arguments)]
+    #[gen_stub(override_return_type(type_repr = 
"collections.abc.AsyncIterable[types.Entry]"))]
+    #[pyo3(signature = (path, *,
+        limit=None,
+        start_after=None,
+        recursive=None,
+        versions=None,
+        deleted=None))]
     pub fn list<'p>(
         &'p self,
         py: Python<'p>,
         path: PathBuf,
-        kwargs: Option<&Bound<PyDict>>,
+        limit: Option<usize>,
+        start_after: Option<String>,
+        recursive: Option<bool>,
+        versions: Option<bool>,
+        deleted: Option<bool>,
     ) -> PyResult<Bound<'p, PyAny>> {
         let this = self.core.clone();
         let path = path.to_string_lossy().to_string();
-        let kwargs = kwargs
-            .map(|v| v.extract::<ListOptions>())
-            .transpose()?
-            .unwrap_or_default();
+        let opts = ListOptions {
+            limit,
+            start_after,
+            recursive,
+            versions,
+            deleted,
+        };
 
         future_into_py(py, async move {
             let lister = this
-                .lister_options(&path, kwargs.into())
+                .lister_options(&path, opts.into())
                 .await
                 .map_err(format_pyerr)?;
             let pylister = Python::attach(|py| 
AsyncLister::new(lister).into_py_any(py))?;
@@ -617,22 +1367,62 @@ impl AsyncOperator {
         })
     }
 
-    /// List dir in a flat way.
-    #[pyo3(signature = (path, **kwargs))]
+    /// Recursively list entries in the given directory.
+    ///
+    /// Deprecated
+    /// ----------
+    ///     Use `list()` with `recursive=True` instead.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path to the directory.
+    /// limit : int, optional
+    ///     The maximum number of entries to return.
+    /// start_after : str, optional
+    ///     The entry to start after.
+    /// versions : bool, optional
+    ///     Whether to list versions.
+    /// deleted : bool, optional
+    ///     Whether to list deleted entries.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns an async iterator over the entries.
+    #[gen_stub(override_return_type(type_repr = 
"collections.abc.AsyncIterable[types.Entry]",))]
+    #[gen_stub(skip)]
+    #[pyo3(signature = (path, *,
+        limit=None,
+        start_after=None,
+        versions=None,
+        deleted=None))]
     pub fn scan<'p>(
         &'p self,
         py: Python<'p>,
         path: PathBuf,
-        kwargs: Option<&Bound<PyDict>>,
+        limit: Option<usize>,
+        start_after: Option<String>,
+        versions: Option<bool>,
+        deleted: Option<bool>,
     ) -> PyResult<Bound<'p, PyAny>> {
-        let d = PyDict::new(py);
-        let kwargs = kwargs.unwrap_or(&d);
-        kwargs.set_item("recursive", true)?;
-
-        self.list(py, path, Some(kwargs))
+        self.list(py, path, limit, start_after, Some(true), versions, deleted)
     }
 
-    /// Presign an operation for stat(head) which expires after 
`expire_second` seconds.
+    /// Create a presigned request for a stat operation.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path of the object to stat.
+    /// expire_second : int
+    ///     The number of seconds until the presigned URL expires.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns a presigned request object.
+    #[gen_stub(override_return_type(type_repr = "types.PresignedRequest"))]
     pub fn presign_stat<'p>(
         &'p self,
         py: Python<'p>,
@@ -652,7 +1442,20 @@ impl AsyncOperator {
         })
     }
 
-    /// Presign an operation for read which expires after `expire_second` 
seconds.
+    /// Create a presigned request for a read operation.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path of the object to read.
+    /// expire_second : int
+    ///     The number of seconds until the presigned URL expires.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns a presigned request object.
+    #[gen_stub(override_return_type(type_repr = "types.PresignedRequest"))]
     pub fn presign_read<'p>(
         &'p self,
         py: Python<'p>,
@@ -672,7 +1475,20 @@ impl AsyncOperator {
         })
     }
 
-    /// Presign an operation for write which expires after `expire_second` 
seconds.
+    /// Create a presigned request for a write operation.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path of the object to write to.
+    /// expire_second : int
+    ///     The number of seconds until the presigned URL expires.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns a presigned request object.
+    #[gen_stub(override_return_type(type_repr = "types.PresignedRequest"))]
     pub fn presign_write<'p>(
         &'p self,
         py: Python<'p>,
@@ -692,7 +1508,20 @@ impl AsyncOperator {
         })
     }
 
-    /// Presign an operation for delete which expires after `expire_second` 
seconds.
+    /// Create a presigned request for a delete operation.
+    ///
+    /// Parameters
+    /// ----------
+    /// path : str
+    ///     The path of the object to delete.
+    /// expire_second : int
+    ///     The number of seconds until the presigned URL expires.
+    ///
+    /// Returns
+    /// -------
+    /// coroutine
+    ///     An awaitable that returns a presigned request object.
+    #[gen_stub(override_return_type(type_repr = "types.PresignedRequest"))]
     pub fn presign_delete<'p>(
         &'p self,
         py: Python<'p>,
@@ -712,12 +1541,25 @@ impl AsyncOperator {
         })
     }
 
-    pub fn capability(&self) -> PyResult<capability::Capability> {
+    /// Get all capabilities of this operator.
+    ///
+    /// Returns
+    /// -------
+    /// Capability
+    ///     The capability of the operator.
+    #[gen_stub(override_return_type(type_repr = "capability.Capability"))]
+    pub fn full_capability(&self) -> PyResult<Capability> {
         Ok(capability::Capability::new(
             self.core.info().full_capability(),
         ))
     }
 
+    /// Create a new blocking `Operator` from this async operator.
+    ///
+    /// Returns
+    /// -------
+    /// Operator
+    ///     The blocking operator.
     pub fn to_operator(&self) -> PyResult<Operator> {
         let runtime = pyo3_async_runtimes::tokio::get_runtime();
         let _guard = runtime.enter();
@@ -748,6 +1590,7 @@ impl AsyncOperator {
         }
     }
 
+    #[gen_stub(skip)]
     fn __getnewargs_ex__(&self, py: Python) -> PyResult<Py<PyAny>> {
         let args = vec![self.__scheme.to_string()];
         let args = PyTuple::new(py, args)?.into_py_any(py)?;
@@ -756,24 +1599,35 @@ impl AsyncOperator {
     }
 }
 
-#[pyclass(module = "opendal")]
+/// A presigned request.
+///
+/// This contains the information required to make a request to the
+/// underlying service, including the URL, method, and headers.
+#[gen_stub_pyclass]
+#[pyclass(module = "opendal.types")]
 pub struct PresignedRequest(ocore::raw::PresignedRequest);
 
+#[gen_stub_pymethods]
 #[pymethods]
 impl PresignedRequest {
-    /// Return the URL of this request.
+    /// The URL of this request.
     #[getter]
     pub fn url(&self) -> String {
         self.0.uri().to_string()
     }
 
-    /// Return the HTTP method of this request.
+    /// The HTTP method of this request.
     #[getter]
     pub fn method(&self) -> &str {
         self.0.method().as_str()
     }
 
-    /// Return the HTTP headers of this request.
+    /// The HTTP headers of this request.
+    ///
+    /// Returns
+    /// -------
+    /// dict
+    ///     The HTTP headers of this request.
     #[getter]
     pub fn headers(&self) -> PyResult<HashMap<&str, &str>> {
         let mut headers = HashMap::new();
diff --git a/bindings/python/tests/conftest.py 
b/bindings/python/tests/conftest.py
index 5bf32d545..38a689628 100644
--- a/bindings/python/tests/conftest.py
+++ b/bindings/python/tests/conftest.py
@@ -79,8 +79,8 @@ def check_capability(request, operator, async_operator) -> 
None:
         marker
         and marker.args
         and not all(
-            [getattr(operator.capability(), x) for x in marker.args]
-            + [getattr(async_operator.capability(), x) for x in marker.args]
+            [getattr(operator.full_capability(), x) for x in marker.args]
+            + [getattr(async_operator.full_capability(), x) for x in 
marker.args]
         )
     ):
         pytest.skip(f"skip because {marker.args} not supported")
diff --git a/bindings/python/tests/test_capability.py 
b/bindings/python/tests/test_capability.py
index 240816418..b22decdb4 100644
--- a/bindings/python/tests/test_capability.py
+++ b/bindings/python/tests/test_capability.py
@@ -19,13 +19,13 @@ import pytest
 
 
 def test_capability(service_name, operator):
-    cap = operator.capability()
+    cap = operator.full_capability()
     assert cap is not None
     assert cap.read is not None
 
 
 def test_capability_exception(service_name, operator):
-    cap = operator.capability()
+    cap = operator.full_capability()
     assert cap is not None
     with pytest.raises(AttributeError):
         _ = cap.read_demo


Reply via email to