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: 1 addition & 1 deletion python/_obstore
Submodule _obstore updated 112 files
4 changes: 4 additions & 0 deletions python/docs/api/decoder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Decoder

::: async_tiff.Decoder
::: async_tiff.DecoderRegistry
5 changes: 5 additions & 0 deletions python/docs/api/geo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Geospatial tags

::: async_tiff.GeoKeyDirectory
options:
show_if_no_docstring: true
5 changes: 5 additions & 0 deletions python/docs/api/ifd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# IFD

::: async_tiff.ImageFileDirectory
options:
show_if_no_docstring: true
3 changes: 0 additions & 3 deletions python/docs/api/store/aws.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# AWS S3

::: async_tiff.store.S3Store
::: async_tiff.store.S3ConfigInput
options:
show_if_no_docstring: true
::: async_tiff.store.S3Config
options:
show_if_no_docstring: true
Expand Down
3 changes: 0 additions & 3 deletions python/docs/api/store/azure.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

::: async_tiff.store.AzureStore
::: async_tiff.store.AzureAccessKey
::: async_tiff.store.AzureConfigInput
options:
show_if_no_docstring: true
::: async_tiff.store.AzureConfig
options:
show_if_no_docstring: true
Expand Down
3 changes: 0 additions & 3 deletions python/docs/api/store/gcs.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# Google Cloud Storage

::: async_tiff.store.GCSStore
::: async_tiff.store.GCSConfigInput
options:
show_if_no_docstring: true
::: async_tiff.store.GCSConfig
options:
show_if_no_docstring: true
Expand Down
3 changes: 3 additions & 0 deletions python/docs/api/thread-pool.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Thread Pool

::: async_tiff.ThreadPool
5 changes: 5 additions & 0 deletions python/docs/api/tiff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# TIFF

::: async_tiff.TIFF
options:
show_if_no_docstring: true
5 changes: 5 additions & 0 deletions python/docs/api/tile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Tile

::: async_tiff.Tile
options:
show_if_no_docstring: true
6 changes: 6 additions & 0 deletions python/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ extra:
nav:
- "index.md"
- API Reference:
- api/tiff.md
- api/ifd.md
- api/tile.md
- api/geo.md
- api/decoder.md
- api/thread-pool.md
- async-tiff.store:
- api/store/index.md
- api/store/aws.md
Expand Down
20 changes: 17 additions & 3 deletions python/python/async_tiff/_decoder.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,26 @@ from collections.abc import Buffer
from .enums import CompressionMethod

class Decoder(Protocol):
"""A custom Python-provided decompression algorithm."""
# In the future, we could pass in photometric interpretation and jpeg tables as
# well.
@staticmethod
def __call__(buffer: Buffer) -> Buffer: ...
def __call__(buffer: Buffer) -> Buffer:
"""A callback to decode compressed data."""

class DecoderRegistry:
"""A registry holding multiple decoder methods."""
def __init__(
self, decoders: dict[CompressionMethod | int, Decoder] | None = None
) -> None: ...
self, custom_decoders: dict[CompressionMethod | int, Decoder] | None = None
) -> None:
"""Construct a new decoder registry.

By default, pure-Rust decoders will be used for any recognized and supported
compression types. Only the supplied decoders will override Rust-native
decoders.

Args:
custom_decoders: any custom decoder methods to use. This will be applied
_after_ (and override) any default provided Rust decoders. Defaults to
None.
"""
4 changes: 3 additions & 1 deletion python/python/async_tiff/_thread_pool.pyi
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
class ThreadPool:
def __init__(self, num_threads: int) -> None: ...
"""A Rust-managed thread pool."""
def __init__(self, num_threads: int) -> None:
"""Construct a new ThreadPool with the given number of threads."""
43 changes: 39 additions & 4 deletions python/python/async_tiff/_tiff.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,43 @@ class TIFF:
*,
store: obstore.store.ObjectStore | ObjectStore,
prefetch: int | None = 16384,
) -> TIFF: ...
) -> TIFF:
"""Open a new TIFF.

Args:
path: The path within the store to read from.
store: The backend to use for data fetching.
prefetch: The number of initial bytes to read up front. Defaults to 16384.

Returns:
A TIFF instance.
"""
@property
def ifds(self) -> list[ImageFileDirectory]: ...
async def fetch_tile(self, x: int, y: int, z: int) -> Tile: ...
async def fetch_tiles(self, x: list[int], y: list[int], z: int) -> list[Tile]: ...
def ifds(self) -> list[ImageFileDirectory]:
"""Access the underlying IFDs of this TIFF.

Each ImageFileDirectory (IFD) represents one of the internal "sub images" of
this file.
"""
async def fetch_tile(self, x: int, y: int, z: int) -> Tile:
"""Fetch a single tile.

Args:
x: The column index within the ifd to read from.
y: The row index within the ifd to read from.
z: The IFD index to read from.

Returns:
Tile response.
"""
async def fetch_tiles(self, x: list[int], y: list[int], z: int) -> list[Tile]:
"""Fetch multiple tiles concurrently.

Args:
x: The column indexes within the ifd to read from.
y: The row indexes within the ifd to read from.
z: The IFD index to read from.

Returns:
Tile responses.
"""
24 changes: 19 additions & 5 deletions python/python/async_tiff/_tile.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,31 @@ from ._decoder import DecoderRegistry
from ._thread_pool import ThreadPool

class Tile:
"""A representation of a TIFF image tile."""
@property
def x(self) -> int: ...
def x(self) -> int:
"""The column index this tile represents."""
@property
def y(self) -> int: ...
def y(self) -> int:
"""The row index this tile represents."""
@property
def compressed_bytes(self) -> Buffer: ...
def compressed_bytes(self) -> Buffer:
"""The compressed bytes underlying this tile."""
@property
def compression_method(self) -> CompressionMethod: ...
def compression_method(self) -> CompressionMethod | int:
"""The compression method used by this tile."""
async def decode(
self,
*,
decoder_registry: DecoderRegistry | None = None,
pool: ThreadPool | None = None,
) -> Buffer: ...
) -> Buffer:
"""Decode this tile's data.

Keyword Args:
decoder_registry: the decoders to use for decompression. Defaults to None.
pool: the thread pool on which to run decompression. Defaults to None.

Returns:
Decoded tile data as a buffer.
"""
2 changes: 1 addition & 1 deletion python/python/async_tiff/store
8 changes: 4 additions & 4 deletions python/src/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ pub(crate) struct PyDecoderRegistry(Arc<DecoderRegistry>);
#[pymethods]
impl PyDecoderRegistry {
#[new]
#[pyo3(signature = (decoders = None))]
pub(crate) fn new(decoders: Option<HashMap<PyCompressionMethod, PyDecoder>>) -> Self {
#[pyo3(signature = (custom_decoders = None))]
pub(crate) fn new(custom_decoders: Option<HashMap<PyCompressionMethod, PyDecoder>>) -> Self {
let mut decoder_registry = DecoderRegistry::default();
if let Some(decoders) = decoders {
for (compression, decoder) in decoders.into_iter() {
if let Some(custom_decoders) = custom_decoders {
for (compression, decoder) in custom_decoders.into_iter() {
decoder_registry
.as_mut()
.insert(compression.into(), Box::new(decoder));
Expand Down