Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions docs/api/get.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,5 @@
::: obspec.GetOptions
::: obspec.GetResult
::: obspec.GetResultAsync
::: obspec.BufferIterator
::: obspec.BufferStream
::: obspec.OffsetRange
::: obspec.SuffixRange
2 changes: 0 additions & 2 deletions docs/api/list.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,4 @@
::: obspec.ListWithDelimiter
::: obspec.ListWithDelimiterAsync
::: obspec.ListResult
::: obspec.ListIterator
::: obspec.ListStream
::: obspec.ListChunkType_co
8 changes: 0 additions & 8 deletions src/obspec/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
from ._copy import Copy, CopyAsync
from ._delete import Delete, DeleteAsync
from ._get import (
BufferIterator,
BufferStream,
Get,
GetAsync,
GetOptions,
Expand All @@ -22,9 +20,7 @@
List,
ListAsync,
ListChunkType_co,
ListIterator,
ListResult,
ListStream,
ListWithDelimiter,
ListWithDelimiterAsync,
)
Expand All @@ -36,8 +32,6 @@
__all__ = [
"Attribute",
"Attributes",
"BufferIterator",
"BufferStream",
"Copy",
"CopyAsync",
"Delete",
Expand All @@ -56,9 +50,7 @@
"List",
"ListAsync",
"ListChunkType_co",
"ListIterator",
"ListResult",
"ListStream",
"ListWithDelimiter",
"ListWithDelimiterAsync",
"ObjectMeta",
Expand Down
57 changes: 9 additions & 48 deletions src/obspec/_get.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
from __future__ import annotations

import sys
from collections.abc import AsyncIterable, Iterable
from typing import TYPE_CHECKING, Protocol, TypedDict

if sys.version_info >= (3, 12):
from collections.abc import Buffer
else:
from typing_extensions import Buffer

if TYPE_CHECKING:
import sys
from collections.abc import Sequence
from datetime import datetime

from ._attributes import Attributes
from ._meta import ObjectMeta

if sys.version_info >= (3, 11):
from typing import Self
else:
from typing_extensions import Self

if sys.version_info >= (3, 12):
from collections.abc import Buffer
else:
from typing_extensions import Buffer


class OffsetRange(TypedDict):
"""Request all bytes starting from a given byte offset."""
Expand Down Expand Up @@ -127,7 +123,7 @@ class GetOptions(TypedDict, total=False):
"""


class GetResult(Protocol):
class GetResult(Iterable[Buffer], Protocol):
"""Result for a get request.

You can materialize the entire buffer by calling the `bytes` method or you can
Expand Down Expand Up @@ -171,12 +167,8 @@ def range(self) -> tuple[int, int]:
"""
...

def __iter__(self) -> BufferIterator:
"""Return a chunked stream over the result's bytes."""
...


class GetResultAsync(Protocol):
class GetResultAsync(AsyncIterable[Buffer], Protocol):
"""Result for an async get request.

You can materialize the entire buffer by calling the `bytes_async` method or you can
Expand Down Expand Up @@ -221,37 +213,6 @@ def range(self) -> tuple[int, int]:
"""
...

def __aiter__(self) -> BufferStream:
"""Return a chunked stream over the result's bytes.

Uses the default (10MB) chunk size.
"""
...


class BufferIterator(Protocol):
"""A synchronous iterator of bytes."""

def __iter__(self) -> Self:
"""Return `Self` as an async iterator."""
...

def __next__(self) -> Buffer:
"""Return the next Buffer chunk in the stream."""
...


class BufferStream(Protocol):
"""An asynchronous iterator of bytes."""

def __aiter__(self) -> Self:
"""Return `Self` as an async iterator."""
...

async def __anext__(self) -> Buffer:
"""Return the next Buffer chunk in the stream."""
...


class Get(Protocol):
def get(
Expand Down
36 changes: 3 additions & 33 deletions src/obspec/_list.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import sys
from collections.abc import Sequence
from typing import TYPE_CHECKING, Generic, Protocol, TypeVar

# Note: we need to use the typing-extensions typed dict because we also parametrize over
Expand All @@ -13,15 +12,10 @@
from typing_extensions import TypedDict

if TYPE_CHECKING:
from collections.abc import Sequence
from collections.abc import AsyncIterator, Iterator, Sequence

from ._meta import ObjectMeta

if sys.version_info >= (3, 11):
from typing import Self
else:
from typing_extensions import Self


ListChunkType_co = TypeVar("ListChunkType_co", covariant=True)
"""The data structure used for holding list results."""
Expand All @@ -42,37 +36,13 @@ class ListResult(TypedDict, Generic[ListChunkType_co]):
"""Object metadata for the listing"""


class ListIterator(Protocol[ListChunkType_co]):
"""An iterator of [ObjectMeta][obspec.ObjectMeta] that can be polled synchronously.""" # noqa: E501

def __iter__(self) -> Self:
"""Return `Self` as an iterator."""
...

def __next__(self) -> ListChunkType_co:
"""Return the next chunk of ObjectMeta in the iterator."""
...


class ListStream(Protocol[ListChunkType_co]):
"""A stream of [ObjectMeta][obspec.ObjectMeta] that can be polled asynchronously."""

def __aiter__(self) -> Self:
"""Return `Self` as an async iterator."""
...

async def __anext__(self) -> ListChunkType_co:
"""Return the next chunk of ObjectMeta in the stream."""
...


class List(Protocol):
def list(
self,
prefix: str | None = None,
*,
offset: str | None = None,
) -> ListIterator[Sequence[ObjectMeta]]:
) -> Iterator[Sequence[ObjectMeta]]:
"""List all the objects with the given prefix.

Prefixes are evaluated on a path segment basis, i.e. `foo/bar/` is a prefix of
Expand Down Expand Up @@ -122,7 +92,7 @@ def list_async(
prefix: str | None = None,
*,
offset: str | None = None,
) -> ListStream[Sequence[ObjectMeta]]:
) -> AsyncIterator[Sequence[ObjectMeta]]:
"""List all the objects with the given prefix.

Note that this method itself is **not async**. It's a synchronous method but
Expand Down
Loading