rio-tiler 8.0.4__py3-none-any.whl → 8.0.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
rio_tiler/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """rio-tiler."""
2
2
 
3
- __version__ = "8.0.4"
3
+ __version__ = "8.0.5"
4
4
 
5
5
  from . import ( # noqa
6
6
  colormap,
rio_tiler/colormap.py CHANGED
@@ -6,9 +6,9 @@ import os
6
6
  import pathlib
7
7
  import re
8
8
  import warnings
9
+ from collections.abc import Sequence
9
10
  from importlib.resources import as_file
10
11
  from importlib.resources import files as resources_files
11
- from typing import Dict, List, Sequence, Tuple, Union
12
12
 
13
13
  import attr
14
14
  import numpy
@@ -137,7 +137,7 @@ def apply_cmap(data: numpy.ndarray, colormap: ColorMapType) -> DataMaskType:
137
137
 
138
138
 
139
139
  def apply_discrete_cmap(
140
- data: numpy.ndarray, colormap: Union[GDALColorMapType, DiscreteColorMapType]
140
+ data: numpy.ndarray, colormap: GDALColorMapType | DiscreteColorMapType
141
141
  ) -> DataMaskType:
142
142
  """Apply discrete colormap.
143
143
 
@@ -217,7 +217,7 @@ def apply_intervals_cmap(
217
217
  return data[:-1], data[-1]
218
218
 
219
219
 
220
- def parse_color(rgba: Union[Sequence[int], str]) -> Tuple[int, int, int, int]:
220
+ def parse_color(rgba: Sequence[int] | str | None) -> tuple[int, int, int, int]:
221
221
  """Parse RGB/RGBA color and return valid rio-tiler compatible RGBA colormap entry.
222
222
 
223
223
  Args:
@@ -290,7 +290,7 @@ class ColorMaps:
290
290
 
291
291
  """
292
292
 
293
- data: Dict[str, Union[str, pathlib.Path, ColorMapType]] = attr.ib(
293
+ data: dict[str, str | pathlib.Path | ColorMapType | None] = attr.ib(
294
294
  default=attr.Factory(lambda: DEFAULT_CMAPS_FILES)
295
295
  )
296
296
 
@@ -344,7 +344,7 @@ class ColorMaps:
344
344
 
345
345
  return cmap
346
346
 
347
- def list(self) -> List[str]:
347
+ def list(self) -> list[str]:
348
348
  """List registered Colormaps.
349
349
 
350
350
  Returns
@@ -355,7 +355,7 @@ class ColorMaps:
355
355
 
356
356
  def register(
357
357
  self,
358
- custom_cmap: Dict[str, Union[str, pathlib.Path, ColorMapType]],
358
+ custom_cmap: dict[str, str | pathlib.Path | ColorMapType | None],
359
359
  overwrite: bool = False,
360
360
  ) -> "ColorMaps":
361
361
  """Register a custom colormap.
@@ -1,7 +1,5 @@
1
1
  """rio_tiler.io.Reader with VSIFILE/Obstore Opener."""
2
2
 
3
- from typing import Union
4
-
5
3
  import attr
6
4
  import rasterio
7
5
  from rasterio.io import DatasetReader, DatasetWriter, MemoryFile
@@ -21,7 +19,7 @@ except ImportError: # pragma: nocover
21
19
  class VSIReader(Reader):
22
20
  """Rasterio Reader with VSIFILE opener."""
23
21
 
24
- dataset: Union[DatasetReader, DatasetWriter, MemoryFile, WarpedVRT] = attr.ib(
22
+ dataset: DatasetReader | DatasetWriter | MemoryFile | WarpedVRT | None = attr.ib(
25
23
  default=None, init=False
26
24
  )
27
25
 
@@ -3,9 +3,10 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import contextlib
6
+ from collections.abc import Callable
6
7
  from functools import cache
7
8
  from pathlib import Path
8
- from typing import Any, Callable, Dict, List, Literal, Optional, Union
9
+ from typing import Any, Literal
9
10
  from urllib.parse import urlparse
10
11
 
11
12
  import attr
@@ -88,13 +89,13 @@ class ZarrReader(BaseReader):
88
89
 
89
90
  """
90
91
 
91
- input: str = attr.ib()
92
- dataset: xarray.Dataset = attr.ib(default=None)
92
+ input: str | None = attr.ib()
93
+ dataset: xarray.Dataset | None = attr.ib(default=None)
93
94
 
94
95
  tms: TileMatrixSet = attr.ib(default=WEB_MERCATOR_TMS)
95
96
 
96
97
  opener: Callable[..., xarray.Dataset] = attr.ib(default=open_dataset)
97
- opener_options: Dict = attr.ib(factory=dict)
98
+ opener_options: dict = attr.ib(factory=dict)
98
99
  _ctx_stack: contextlib.ExitStack = attr.ib(init=False, factory=contextlib.ExitStack)
99
100
 
100
101
  def __attrs_post_init__(self):
@@ -142,7 +143,7 @@ class ZarrReader(BaseReader):
142
143
  self.close()
143
144
 
144
145
  @property
145
- def variables(self) -> List[str]:
146
+ def variables(self) -> list[str]:
146
147
  """Return dataset variable names"""
147
148
  return list(self.dataset.data_vars) # type: ignore
148
149
 
@@ -191,16 +192,16 @@ class ZarrReader(BaseReader):
191
192
  def _get_variable(
192
193
  self,
193
194
  variable: str,
194
- sel: Optional[List[str]] = None,
195
- method: Optional[sel_methods] = None,
195
+ sel: list[str] | None = None,
196
+ method: sel_methods | None = None,
196
197
  ) -> xarray.DataArray:
197
198
  """Get DataArray from xarray Dataset."""
198
199
  da = self.dataset[variable]
199
200
 
200
201
  if sel:
201
- _idx: Dict[str, List] = {}
202
+ _idx: dict[str, list] = {}
202
203
  for s in sel:
203
- val: Union[str, slice]
204
+ val: str | slice
204
205
  dim, val = s.split("=")
205
206
 
206
207
  # cast string to dtype of the dimension
@@ -239,8 +240,8 @@ class ZarrReader(BaseReader):
239
240
  self,
240
241
  *,
241
242
  variable: str,
242
- sel: Optional[List[str]] = None,
243
- method: Optional[sel_methods] = None,
243
+ sel: list[str] | None = None,
244
+ method: sel_methods | None = None,
244
245
  ):
245
246
  """Return xarray.DataArray info."""
246
247
  with XarrayReader(
@@ -258,8 +259,8 @@ class ZarrReader(BaseReader):
258
259
  crs: CRS,
259
260
  *,
260
261
  variable: str,
261
- sel: Optional[List[str]] = None,
262
- method: Optional[sel_methods] = None,
262
+ sel: list[str] | None = None,
263
+ method: sel_methods | None = None,
263
264
  ) -> BBox:
264
265
  """Return Geographic Bounds for a Geographic CRS."""
265
266
  with XarrayReader(
@@ -271,8 +272,8 @@ class ZarrReader(BaseReader):
271
272
  self,
272
273
  *,
273
274
  variable: str,
274
- sel: Optional[List[str]] = None,
275
- method: Optional[sel_methods] = None,
275
+ sel: list[str] | None = None,
276
+ method: sel_methods | None = None,
276
277
  ) -> Info:
277
278
  """Return xarray.DataArray info."""
278
279
  with XarrayReader(
@@ -284,10 +285,10 @@ class ZarrReader(BaseReader):
284
285
  self,
285
286
  *args: Any,
286
287
  variable: str,
287
- sel: Optional[List[str]] = None,
288
- method: Optional[sel_methods] = None,
288
+ sel: list[str] | None = None,
289
+ method: sel_methods | None = None,
289
290
  **kwargs: Any,
290
- ) -> Dict[str, BandStatistics]:
291
+ ) -> dict[str, BandStatistics]:
291
292
  """Return statistics from a dataset."""
292
293
  with XarrayReader(
293
294
  self._get_variable(variable, sel=sel, method=method),
@@ -298,8 +299,8 @@ class ZarrReader(BaseReader):
298
299
  self,
299
300
  *args: Any,
300
301
  variable: str,
301
- sel: Optional[List[str]] = None,
302
- method: Optional[sel_methods] = None,
302
+ sel: list[str] | None = None,
303
+ method: sel_methods | None = None,
303
304
  **kwargs: Any,
304
305
  ) -> ImageData:
305
306
  """Read a Web Map tile from a dataset."""
@@ -313,8 +314,8 @@ class ZarrReader(BaseReader):
313
314
  self,
314
315
  *args: Any,
315
316
  variable: str,
316
- sel: Optional[List[str]] = None,
317
- method: Optional[sel_methods] = None,
317
+ sel: list[str] | None = None,
318
+ method: sel_methods | None = None,
318
319
  **kwargs: Any,
319
320
  ) -> ImageData:
320
321
  """Read part of a dataset."""
@@ -327,8 +328,8 @@ class ZarrReader(BaseReader):
327
328
  self,
328
329
  *args: Any,
329
330
  variable: str,
330
- sel: Optional[List[str]] = None,
331
- method: Optional[sel_methods] = None,
331
+ sel: list[str] | None = None,
332
+ method: sel_methods | None = None,
332
333
  **kwargs: Any,
333
334
  ) -> ImageData:
334
335
  """Return a preview of a dataset."""
@@ -341,8 +342,8 @@ class ZarrReader(BaseReader):
341
342
  self,
342
343
  *args: Any,
343
344
  variable: str,
344
- sel: Optional[List[str]] = None,
345
- method: Optional[sel_methods] = None,
345
+ sel: list[str] | None = None,
346
+ method: sel_methods | None = None,
346
347
  **kwargs: Any,
347
348
  ) -> PointData:
348
349
  """Read a pixel value from a dataset."""
@@ -355,8 +356,8 @@ class ZarrReader(BaseReader):
355
356
  self,
356
357
  *args: Any,
357
358
  variable: str,
358
- sel: Optional[List[str]] = None,
359
- method: Optional[sel_methods] = None,
359
+ sel: list[str] | None = None,
360
+ method: sel_methods | None = None,
360
361
  **kwargs: Any,
361
362
  ) -> ImageData:
362
363
  """Read part of a dataset defined by a geojson feature."""
rio_tiler/expression.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """rio-tiler.expression: Parse and Apply expression."""
2
2
 
3
3
  import re
4
- from typing import List, Sequence, Tuple
4
+ from collections.abc import Sequence
5
5
 
6
6
  import numexpr
7
7
  import numpy
@@ -9,7 +9,7 @@ import numpy
9
9
  from rio_tiler.errors import InvalidExpression
10
10
 
11
11
 
12
- def parse_expression(expression: str, cast: bool = True) -> Tuple:
12
+ def parse_expression(expression: str, cast: bool = True) -> tuple:
13
13
  """Parse rio-tiler band math expression and extract bands.
14
14
 
15
15
  Args:
@@ -37,7 +37,7 @@ def parse_expression(expression: str, cast: bool = True) -> Tuple:
37
37
  return output_bands
38
38
 
39
39
 
40
- def get_expression_blocks(expression: str) -> List[str]:
40
+ def get_expression_blocks(expression: str) -> list[str]:
41
41
  """Split expression in blocks.
42
42
 
43
43
  Args:
rio_tiler/io/base.py CHANGED
@@ -4,8 +4,9 @@ import abc
4
4
  import contextlib
5
5
  import re
6
6
  import warnings
7
+ from collections.abc import Sequence
7
8
  from functools import cached_property
8
- from typing import Any, Dict, List, Optional, Sequence, Tuple, Type, Union, cast
9
+ from typing import Any, cast
9
10
 
10
11
  import attr
11
12
  import numpy
@@ -44,9 +45,9 @@ class SpatialMixin:
44
45
  bounds: BBox = attr.ib(init=False)
45
46
  crs: CRS = attr.ib(init=False)
46
47
 
47
- transform: Optional[Affine] = attr.ib(default=None, init=False)
48
- height: Optional[int] = attr.ib(default=None, init=False)
49
- width: Optional[int] = attr.ib(default=None, init=False)
48
+ transform: Affine | None = attr.ib(default=None, init=False)
49
+ height: int | None = attr.ib(default=None, init=False)
50
+ width: int | None = attr.ib(default=None, init=False)
50
51
 
51
52
  def get_geographic_bounds(self, crs: CRS) -> BBox:
52
53
  """Return Geographic Bounds for a Geographic CRS."""
@@ -238,11 +239,11 @@ class BaseReader(SpatialMixin, metaclass=abc.ABCMeta):
238
239
  ...
239
240
 
240
241
  @abc.abstractmethod
241
- def statistics(self) -> Dict[str, BandStatistics]:
242
+ def statistics(self) -> dict[str, BandStatistics]:
242
243
  """Return bands statistics from a dataset.
243
244
 
244
245
  Returns:
245
- Dict[str, rio_tiler.models.BandStatistics]: bands statistics.
246
+ dict[str, rio_tiler.models.BandStatistics]: bands statistics.
246
247
 
247
248
  """
248
249
  ...
@@ -300,7 +301,7 @@ class BaseReader(SpatialMixin, metaclass=abc.ABCMeta):
300
301
  ...
301
302
 
302
303
  @abc.abstractmethod
303
- def feature(self, shape: Dict) -> ImageData:
304
+ def feature(self, shape: dict) -> ImageData:
304
305
  """Read a Dataset for a GeoJSON feature.
305
306
 
306
307
  Args:
@@ -331,16 +332,16 @@ class MultiBaseReader(SpatialMixin, metaclass=abc.ABCMeta):
331
332
  input: Any = attr.ib()
332
333
  tms: TileMatrixSet = attr.ib(default=WEB_MERCATOR_TMS)
333
334
 
334
- minzoom: int = attr.ib(default=None)
335
- maxzoom: int = attr.ib(default=None)
335
+ minzoom: int | None = attr.ib(default=None)
336
+ maxzoom: int | None = attr.ib(default=None)
336
337
 
337
- reader: Type[BaseReader] = attr.ib(init=False)
338
- reader_options: Dict = attr.ib(factory=dict)
338
+ reader: type[BaseReader] = attr.ib(init=False)
339
+ reader_options: dict = attr.ib(factory=dict)
339
340
 
340
341
  assets: Sequence[str] = attr.ib(init=False)
341
- default_assets: Optional[Sequence[str]] = attr.ib(init=False, default=None)
342
+ default_assets: Sequence[str] | None = attr.ib(init=False, default=None)
342
343
 
343
- ctx: Type[contextlib.AbstractContextManager] = attr.ib(
344
+ ctx: type[contextlib.AbstractContextManager] = attr.ib(
344
345
  init=False, default=contextlib.nullcontext
345
346
  )
346
347
 
@@ -357,11 +358,11 @@ class MultiBaseReader(SpatialMixin, metaclass=abc.ABCMeta):
357
358
  """Validate asset name and construct url."""
358
359
  ...
359
360
 
360
- def _get_reader(self, asset_info: AssetInfo) -> Tuple[Type[BaseReader], Dict]:
361
+ def _get_reader(self, asset_info: AssetInfo) -> tuple[type[BaseReader], dict]:
361
362
  """Get Asset Reader and options."""
362
363
  return self.reader, {}
363
364
 
364
- def parse_expression(self, expression: str, asset_as_band: bool = False) -> Tuple:
365
+ def parse_expression(self, expression: str, asset_as_band: bool = False) -> tuple:
365
366
  """Parse rio-tiler band math expression."""
366
367
  input_assets = "|".join(self.assets)
367
368
 
@@ -383,8 +384,8 @@ class MultiBaseReader(SpatialMixin, metaclass=abc.ABCMeta):
383
384
  def _update_statistics(
384
385
  self,
385
386
  img: ImageData,
386
- indexes: Optional[Indexes] = None,
387
- statistics: Optional[Sequence[Tuple[float, float]]] = None,
387
+ indexes: Indexes | None = None,
388
+ statistics: Sequence[tuple[float, float]] | None = None,
388
389
  ):
389
390
  """Update ImageData Statistics from AssetInfo."""
390
391
  indexes = cast_to_sequence(indexes)
@@ -400,9 +401,9 @@ class MultiBaseReader(SpatialMixin, metaclass=abc.ABCMeta):
400
401
 
401
402
  def info(
402
403
  self,
403
- assets: Optional[Union[Sequence[str], str]] = None,
404
+ assets: Sequence[str] | str | None = None,
404
405
  **kwargs: Any,
405
- ) -> Dict[str, Info]:
406
+ ) -> dict[str, Info]:
406
407
  """Return metadata from multiple assets.
407
408
 
408
409
  Args:
@@ -419,7 +420,7 @@ class MultiBaseReader(SpatialMixin, metaclass=abc.ABCMeta):
419
420
  )
420
421
  assets = cast_to_sequence(assets or self.assets)
421
422
 
422
- def _reader(asset: str, **kwargs: Any) -> Dict:
423
+ def _reader(asset: str, **kwargs: Any) -> dict:
423
424
  asset_info = self._get_asset_info(asset)
424
425
  reader, options = self._get_reader(asset_info)
425
426
 
@@ -435,11 +436,11 @@ class MultiBaseReader(SpatialMixin, metaclass=abc.ABCMeta):
435
436
 
436
437
  def statistics(
437
438
  self,
438
- assets: Optional[Union[Sequence[str], str]] = None,
439
- asset_indexes: Optional[Dict[str, Indexes]] = None,
440
- asset_expression: Optional[Dict[str, str]] = None,
439
+ assets: Sequence[str] | str | None = None,
440
+ asset_indexes: dict[str, Indexes] | None = None,
441
+ asset_expression: dict[str, str] | None = None,
441
442
  **kwargs: Any,
442
- ) -> Dict[str, Dict[str, BandStatistics]]:
443
+ ) -> dict[str, dict[str, BandStatistics]]:
443
444
  """Return array statistics for multiple assets.
444
445
 
445
446
  Args:
@@ -462,7 +463,7 @@ class MultiBaseReader(SpatialMixin, metaclass=abc.ABCMeta):
462
463
  asset_indexes = asset_indexes or {}
463
464
  asset_expression = asset_expression or {}
464
465
 
465
- def _reader(asset: str, *args: Any, **kwargs: Any) -> Dict:
466
+ def _reader(asset: str, *args: Any, **kwargs: Any) -> dict:
466
467
  asset_info = self._get_asset_info(asset)
467
468
  reader, options = self._get_reader(asset_info)
468
469
 
@@ -483,16 +484,16 @@ class MultiBaseReader(SpatialMixin, metaclass=abc.ABCMeta):
483
484
 
484
485
  def merged_statistics(
485
486
  self,
486
- assets: Optional[Union[Sequence[str], str]] = None,
487
- expression: Optional[str] = None,
488
- asset_indexes: Optional[Dict[str, Indexes]] = None,
487
+ assets: Sequence[str] | str | None = None,
488
+ expression: str | None = None,
489
+ asset_indexes: dict[str, Indexes] | None = None,
489
490
  categorical: bool = False,
490
- categories: Optional[List[float]] = None,
491
- percentiles: Optional[List[int]] = None,
492
- hist_options: Optional[Dict] = None,
491
+ categories: list[float] | None = None,
492
+ percentiles: list[int] | None = None,
493
+ hist_options: dict | None = None,
493
494
  max_size: int = 1024,
494
495
  **kwargs: Any,
495
- ) -> Dict[str, BandStatistics]:
496
+ ) -> dict[str, BandStatistics]:
496
497
  """Return array statistics for multiple assets.
497
498
 
498
499
  Args:
@@ -538,9 +539,9 @@ class MultiBaseReader(SpatialMixin, metaclass=abc.ABCMeta):
538
539
  tile_x: int,
539
540
  tile_y: int,
540
541
  tile_z: int,
541
- assets: Optional[Union[Sequence[str], str]] = None,
542
- expression: Optional[str] = None,
543
- asset_indexes: Optional[Dict[str, Indexes]] = None,
542
+ assets: Sequence[str] | str | None = None,
543
+ expression: str | None = None,
544
+ asset_indexes: dict[str, Indexes] | None = None,
544
545
  asset_as_band: bool = False,
545
546
  **kwargs: Any,
546
547
  ) -> ImageData:
@@ -640,9 +641,9 @@ class MultiBaseReader(SpatialMixin, metaclass=abc.ABCMeta):
640
641
  def part(
641
642
  self,
642
643
  bbox: BBox,
643
- assets: Optional[Union[Sequence[str], str]] = None,
644
- expression: Optional[str] = None,
645
- asset_indexes: Optional[Dict[str, Indexes]] = None,
644
+ assets: Sequence[str] | str | None = None,
645
+ expression: str | None = None,
646
+ asset_indexes: dict[str, Indexes] | None = None,
646
647
  asset_as_band: bool = False,
647
648
  **kwargs: Any,
648
649
  ) -> ImageData:
@@ -734,9 +735,9 @@ class MultiBaseReader(SpatialMixin, metaclass=abc.ABCMeta):
734
735
 
735
736
  def preview(
736
737
  self,
737
- assets: Optional[Union[Sequence[str], str]] = None,
738
- expression: Optional[str] = None,
739
- asset_indexes: Optional[Dict[str, Indexes]] = None,
738
+ assets: Sequence[str] | str | None = None,
739
+ expression: str | None = None,
740
+ asset_indexes: dict[str, Indexes] | None = None,
740
741
  asset_as_band: bool = False,
741
742
  **kwargs: Any,
742
743
  ) -> ImageData:
@@ -829,9 +830,9 @@ class MultiBaseReader(SpatialMixin, metaclass=abc.ABCMeta):
829
830
  self,
830
831
  lon: float,
831
832
  lat: float,
832
- assets: Optional[Union[Sequence[str], str]] = None,
833
- expression: Optional[str] = None,
834
- asset_indexes: Optional[Dict[str, Indexes]] = None,
833
+ assets: Sequence[str] | str | None = None,
834
+ expression: str | None = None,
835
+ asset_indexes: dict[str, Indexes] | None = None,
835
836
  asset_as_band: bool = False,
836
837
  **kwargs: Any,
837
838
  ) -> PointData:
@@ -918,10 +919,10 @@ class MultiBaseReader(SpatialMixin, metaclass=abc.ABCMeta):
918
919
 
919
920
  def feature(
920
921
  self,
921
- shape: Dict,
922
- assets: Optional[Union[Sequence[str], str]] = None,
923
- expression: Optional[str] = None,
924
- asset_indexes: Optional[Dict[str, Indexes]] = None,
922
+ shape: dict,
923
+ assets: Sequence[str] | str | None = None,
924
+ expression: str | None = None,
925
+ asset_indexes: dict[str, Indexes] | None = None,
925
926
  asset_as_band: bool = False,
926
927
  **kwargs: Any,
927
928
  ) -> ImageData:
@@ -1030,14 +1031,14 @@ class MultiBandReader(SpatialMixin, metaclass=abc.ABCMeta):
1030
1031
  input: Any = attr.ib()
1031
1032
  tms: TileMatrixSet = attr.ib(default=WEB_MERCATOR_TMS)
1032
1033
 
1033
- minzoom: int = attr.ib(default=None)
1034
- maxzoom: int = attr.ib(default=None)
1034
+ minzoom: int | None = attr.ib(default=None)
1035
+ maxzoom: int | None = attr.ib(default=None)
1035
1036
 
1036
- reader: Type[BaseReader] = attr.ib(init=False)
1037
- reader_options: Dict = attr.ib(factory=dict)
1037
+ reader: type[BaseReader] = attr.ib(init=False)
1038
+ reader_options: dict = attr.ib(factory=dict)
1038
1039
 
1039
1040
  bands: Sequence[str] = attr.ib(init=False)
1040
- default_bands: Optional[Sequence[str]] = attr.ib(init=False, default=None)
1041
+ default_bands: Sequence[str] | None = attr.ib(init=False, default=None)
1041
1042
 
1042
1043
  def __enter__(self):
1043
1044
  """Support using with Context Managers."""
@@ -1052,7 +1053,7 @@ class MultiBandReader(SpatialMixin, metaclass=abc.ABCMeta):
1052
1053
  """Validate band name and construct url."""
1053
1054
  ...
1054
1055
 
1055
- def parse_expression(self, expression: str) -> Tuple:
1056
+ def parse_expression(self, expression: str) -> tuple:
1056
1057
  """Parse rio-tiler band math expression."""
1057
1058
  input_bands = "|".join([rf"\b{band}\b" for band in self.bands])
1058
1059
  _re = re.compile(input_bands.replace("\\\\", "\\"))
@@ -1067,7 +1068,7 @@ class MultiBandReader(SpatialMixin, metaclass=abc.ABCMeta):
1067
1068
 
1068
1069
  def info(
1069
1070
  self,
1070
- bands: Optional[Union[Sequence[str], str]] = None,
1071
+ bands: Sequence[str] | str | None = None,
1071
1072
  **kwargs: Any,
1072
1073
  ) -> Info:
1073
1074
  """Return metadata from multiple bands.
@@ -1121,15 +1122,15 @@ class MultiBandReader(SpatialMixin, metaclass=abc.ABCMeta):
1121
1122
 
1122
1123
  def statistics(
1123
1124
  self,
1124
- bands: Optional[Union[Sequence[str], str]] = None,
1125
- expression: Optional[str] = None,
1125
+ bands: Sequence[str] | str | None = None,
1126
+ expression: str | None = None,
1126
1127
  categorical: bool = False,
1127
- categories: Optional[List[float]] = None,
1128
- percentiles: Optional[List[int]] = None,
1129
- hist_options: Optional[Dict] = None,
1128
+ categories: list[float] | None = None,
1129
+ percentiles: list[int] | None = None,
1130
+ hist_options: dict | None = None,
1130
1131
  max_size: int = 1024,
1131
1132
  **kwargs: Any,
1132
- ) -> Dict[str, BandStatistics]:
1133
+ ) -> dict[str, BandStatistics]:
1133
1134
  """Return array statistics for multiple assets.
1134
1135
 
1135
1136
  Args:
@@ -1172,8 +1173,8 @@ class MultiBandReader(SpatialMixin, metaclass=abc.ABCMeta):
1172
1173
  tile_x: int,
1173
1174
  tile_y: int,
1174
1175
  tile_z: int,
1175
- bands: Optional[Union[Sequence[str], str]] = None,
1176
- expression: Optional[str] = None,
1176
+ bands: Sequence[str] | str | None = None,
1177
+ expression: str | None = None,
1177
1178
  **kwargs: Any,
1178
1179
  ) -> ImageData:
1179
1180
  """Read and merge Web Map tiles multiple bands.
@@ -1244,8 +1245,8 @@ class MultiBandReader(SpatialMixin, metaclass=abc.ABCMeta):
1244
1245
  def part(
1245
1246
  self,
1246
1247
  bbox: BBox,
1247
- bands: Optional[Union[Sequence[str], str]] = None,
1248
- expression: Optional[str] = None,
1248
+ bands: Sequence[str] | str | None = None,
1249
+ expression: str | None = None,
1249
1250
  **kwargs: Any,
1250
1251
  ) -> ImageData:
1251
1252
  """Read and merge parts from multiple bands.
@@ -1308,8 +1309,8 @@ class MultiBandReader(SpatialMixin, metaclass=abc.ABCMeta):
1308
1309
 
1309
1310
  def preview(
1310
1311
  self,
1311
- bands: Optional[Union[Sequence[str], str]] = None,
1312
- expression: Optional[str] = None,
1312
+ bands: Sequence[str] | str | None = None,
1313
+ expression: str | None = None,
1313
1314
  **kwargs: Any,
1314
1315
  ) -> ImageData:
1315
1316
  """Read and merge previews from multiple bands.
@@ -1373,8 +1374,8 @@ class MultiBandReader(SpatialMixin, metaclass=abc.ABCMeta):
1373
1374
  self,
1374
1375
  lon: float,
1375
1376
  lat: float,
1376
- bands: Optional[Union[Sequence[str], str]] = None,
1377
- expression: Optional[str] = None,
1377
+ bands: Sequence[str] | str | None = None,
1378
+ expression: str | None = None,
1378
1379
  **kwargs: Any,
1379
1380
  ) -> PointData:
1380
1381
  """Read a pixel values from multiple bands.
@@ -1437,9 +1438,9 @@ class MultiBandReader(SpatialMixin, metaclass=abc.ABCMeta):
1437
1438
 
1438
1439
  def feature(
1439
1440
  self,
1440
- shape: Dict,
1441
- bands: Optional[Union[Sequence[str], str]] = None,
1442
- expression: Optional[str] = None,
1441
+ shape: dict,
1442
+ bands: Sequence[str] | str | None = None,
1443
+ expression: str | None = None,
1443
1444
  **kwargs: Any,
1444
1445
  ) -> ImageData:
1445
1446
  """Read and merge parts defined by geojson feature from multiple bands.