diff --git a/python/_obstore b/python/_obstore index aaa8d6a..f636583 160000 --- a/python/_obstore +++ b/python/_obstore @@ -1 +1 @@ -Subproject commit aaa8d6a0de646b532dc74a81f4adbd8ecf9de026 +Subproject commit f63658339e5295cb6a0037ff7b802197be3ff264 diff --git a/python/docs/api/decoder.md b/python/docs/api/decoder.md new file mode 100644 index 0000000..9264b06 --- /dev/null +++ b/python/docs/api/decoder.md @@ -0,0 +1,4 @@ +# Decoder + +::: async_tiff.Decoder +::: async_tiff.DecoderRegistry diff --git a/python/docs/api/geo.md b/python/docs/api/geo.md new file mode 100644 index 0000000..78d7a04 --- /dev/null +++ b/python/docs/api/geo.md @@ -0,0 +1,5 @@ +# Geospatial tags + +::: async_tiff.GeoKeyDirectory + options: + show_if_no_docstring: true diff --git a/python/docs/api/ifd.md b/python/docs/api/ifd.md new file mode 100644 index 0000000..17eefa1 --- /dev/null +++ b/python/docs/api/ifd.md @@ -0,0 +1,5 @@ +# IFD + +::: async_tiff.ImageFileDirectory + options: + show_if_no_docstring: true diff --git a/python/docs/api/store/aws.md b/python/docs/api/store/aws.md index d72fbc4..848b5aa 100644 --- a/python/docs/api/store/aws.md +++ b/python/docs/api/store/aws.md @@ -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 diff --git a/python/docs/api/store/azure.md b/python/docs/api/store/azure.md index eec88e9..b766520 100644 --- a/python/docs/api/store/azure.md +++ b/python/docs/api/store/azure.md @@ -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 diff --git a/python/docs/api/store/gcs.md b/python/docs/api/store/gcs.md index d395e33..c658f95 100644 --- a/python/docs/api/store/gcs.md +++ b/python/docs/api/store/gcs.md @@ -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 diff --git a/python/docs/api/thread-pool.md b/python/docs/api/thread-pool.md new file mode 100644 index 0000000..f92fe27 --- /dev/null +++ b/python/docs/api/thread-pool.md @@ -0,0 +1,3 @@ +# Thread Pool + +::: async_tiff.ThreadPool diff --git a/python/docs/api/tiff.md b/python/docs/api/tiff.md new file mode 100644 index 0000000..1059366 --- /dev/null +++ b/python/docs/api/tiff.md @@ -0,0 +1,5 @@ +# TIFF + +::: async_tiff.TIFF + options: + show_if_no_docstring: true diff --git a/python/docs/api/tile.md b/python/docs/api/tile.md new file mode 100644 index 0000000..73b59e6 --- /dev/null +++ b/python/docs/api/tile.md @@ -0,0 +1,5 @@ +# Tile + +::: async_tiff.Tile + options: + show_if_no_docstring: true diff --git a/python/mkdocs.yml b/python/mkdocs.yml index 26d04d8..ff39752 100644 --- a/python/mkdocs.yml +++ b/python/mkdocs.yml @@ -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 diff --git a/python/python/async_tiff/_decoder.pyi b/python/python/async_tiff/_decoder.pyi index f46d0e8..d69b27e 100644 --- a/python/python/async_tiff/_decoder.pyi +++ b/python/python/async_tiff/_decoder.pyi @@ -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. + """ diff --git a/python/python/async_tiff/_thread_pool.pyi b/python/python/async_tiff/_thread_pool.pyi index 0363c7d..aa1165a 100644 --- a/python/python/async_tiff/_thread_pool.pyi +++ b/python/python/async_tiff/_thread_pool.pyi @@ -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.""" diff --git a/python/python/async_tiff/_tiff.pyi b/python/python/async_tiff/_tiff.pyi index 1c26f21..0bf35ba 100644 --- a/python/python/async_tiff/_tiff.pyi +++ b/python/python/async_tiff/_tiff.pyi @@ -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. + """ diff --git a/python/python/async_tiff/_tile.pyi b/python/python/async_tiff/_tile.pyi index 28f12bf..fd62cc6 100644 --- a/python/python/async_tiff/_tile.pyi +++ b/python/python/async_tiff/_tile.pyi @@ -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. + """ diff --git a/python/python/async_tiff/store b/python/python/async_tiff/store index e177177..9721d2d 120000 --- a/python/python/async_tiff/store +++ b/python/python/async_tiff/store @@ -1 +1 @@ -../../_obstore/obstore/python/obstore/store \ No newline at end of file +../../_obstore/obstore/python/obstore/_store \ No newline at end of file diff --git a/python/src/decoder.rs b/python/src/decoder.rs index 572fc7c..dbd5cba 100644 --- a/python/src/decoder.rs +++ b/python/src/decoder.rs @@ -29,11 +29,11 @@ pub(crate) struct PyDecoderRegistry(Arc); #[pymethods] impl PyDecoderRegistry { #[new] - #[pyo3(signature = (decoders = None))] - pub(crate) fn new(decoders: Option>) -> Self { + #[pyo3(signature = (custom_decoders = None))] + pub(crate) fn new(custom_decoders: Option>) -> 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));