sentinelhub 3.10.1__py3-none-any.whl → 3.10.2__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.
sentinelhub/_version.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """Version of the sentinelhub package."""
2
2
 
3
- __version__ = "3.10.1"
3
+ __version__ = "3.10.2"
@@ -134,11 +134,13 @@ class SentinelHubBaseApiRequest(DataRequest, metaclass=ABCMeta):
134
134
  settings from config object. In case different collections have different restrictions then
135
135
  `SHConfig.sh_base_url` breaks the tie in case it matches one of the data collection URLs.
136
136
  """
137
- data_collection_urls = tuple({
138
- input_data_dict.service_url.rstrip("/")
139
- for input_data_dict in self.payload["input"]["data"]
140
- if isinstance(input_data_dict, InputDataDict) and input_data_dict.service_url is not None
141
- })
137
+ data_collection_urls = tuple(
138
+ {
139
+ input_data_dict.service_url.rstrip("/")
140
+ for input_data_dict in self.payload["input"]["data"]
141
+ if isinstance(input_data_dict, InputDataDict) and input_data_dict.service_url is not None
142
+ }
143
+ )
142
144
  config_base_url = self.config.sh_base_url.rstrip("/")
143
145
 
144
146
  if not data_collection_urls:
@@ -150,17 +150,19 @@ class SentinelHubBatch(BaseBatchClient):
150
150
  :param kwargs: Any other arguments to be added to a dictionary of parameters
151
151
  :return: A dictionary of output parameters
152
152
  """
153
- return remove_undefined({
154
- "defaultTilePath": default_tile_path,
155
- "overwrite": overwrite,
156
- "skipExisting": skip_existing,
157
- "cogOutput": cog_output,
158
- "cogParameters": cog_parameters,
159
- "createCollection": create_collection,
160
- "collectionId": collection_id,
161
- "responses": responses,
162
- **kwargs,
163
- })
153
+ return remove_undefined(
154
+ {
155
+ "defaultTilePath": default_tile_path,
156
+ "overwrite": overwrite,
157
+ "skipExisting": skip_existing,
158
+ "cogOutput": cog_output,
159
+ "cogParameters": cog_parameters,
160
+ "createCollection": create_collection,
161
+ "collectionId": collection_id,
162
+ "responses": responses,
163
+ **kwargs,
164
+ }
165
+ )
164
166
 
165
167
  def iter_tiling_grids(self, **kwargs: Any) -> SentinelHubFeatureIterator:
166
168
  """An iterator over tiling grids
sentinelhub/api/byoc.py CHANGED
@@ -220,11 +220,13 @@ class SentinelHubBYOC(SentinelHubService):
220
220
  headers = {"Content-Type": MimeType.JSON.get_string()}
221
221
 
222
222
  _tile = self._to_dict(tile)
223
- updates = remove_undefined({
224
- "path": _tile["path"],
225
- "coverGeometry": _tile.get("coverGeometry"),
226
- "sensingTime": _tile.get("sensingTime"),
227
- })
223
+ updates = remove_undefined(
224
+ {
225
+ "path": _tile["path"],
226
+ "coverGeometry": _tile.get("coverGeometry"),
227
+ "sensingTime": _tile.get("sensingTime"),
228
+ }
229
+ )
228
230
 
229
231
  return self.client.get_json(
230
232
  url=url, request_type=RequestType.PUT, post_values=updates, headers=headers, use_session=True
@@ -140,20 +140,22 @@ class SentinelHubCatalog(SentinelHubService):
140
140
  if geometry and geometry.crs is not CRS.WGS84:
141
141
  geometry = geometry.transform(CRS.WGS84)
142
142
 
143
- payload = remove_undefined({
144
- "collections": [collection_id],
145
- "datetime": f"{start_time}/{end_time}" if time else None,
146
- "bbox": list(bbox) if bbox else None,
147
- "intersects": geometry.get_geojson(with_crs=False) if geometry else None,
148
- "ids": ids,
149
- "filter": self._prepare_filters(filter, collection, filter_lang),
150
- "filter-lang": filter_lang,
151
- "filter-crs": filter_crs,
152
- "fields": fields,
153
- "distinct": distinct,
154
- "limit": limit,
155
- **kwargs,
156
- })
143
+ payload = remove_undefined(
144
+ {
145
+ "collections": [collection_id],
146
+ "datetime": f"{start_time}/{end_time}" if time else None,
147
+ "bbox": list(bbox) if bbox else None,
148
+ "intersects": geometry.get_geojson(with_crs=False) if geometry else None,
149
+ "ids": ids,
150
+ "filter": self._prepare_filters(filter, collection, filter_lang),
151
+ "filter-lang": filter_lang,
152
+ "filter-crs": filter_crs,
153
+ "fields": fields,
154
+ "distinct": distinct,
155
+ "limit": limit,
156
+ **kwargs,
157
+ }
158
+ )
157
159
 
158
160
  return CatalogSearchIterator(self.client, url, payload)
159
161
 
sentinelhub/config.py CHANGED
@@ -24,7 +24,7 @@ SH_CLIENT_SECRET_ENV_VAR = "SH_CLIENT_SECRET"
24
24
 
25
25
 
26
26
  @dataclass(repr=False)
27
- class _SHConfig:
27
+ class _SHConfig: # pylint: disable=too-many-instance-attributes
28
28
  instance_id: str = ""
29
29
  sh_client_id: str = ""
30
30
  sh_client_secret: str = ""
@@ -46,6 +46,7 @@ class _SHConfig:
46
46
  download_sleep_time: float = 5.0
47
47
  download_timeout_seconds: float = 120.0
48
48
  number_of_download_processes: int = 1
49
+ max_retries: int | None = None
49
50
 
50
51
  def __post_init__(self) -> None:
51
52
  if self.sh_auth_base_url is not None:
@@ -94,6 +95,7 @@ class SHConfig(_SHConfig):
94
95
  attempt this number exponentially increases with factor `3`.
95
96
  - `download_timeout_seconds`: Maximum number of seconds before download attempt is canceled.
96
97
  - `number_of_download_processes`: Number of download processes, used to calculate rate-limit sleep time.
98
+ - `max_retries`: Maximum number of retries until an exception is raised.
97
99
 
98
100
  The location of `config.toml` for manual modification can be found with `SHConfig.get_config_location()`.
99
101
  """
@@ -1,4 +1,4 @@
1
- """ Contains information about data collections used by SH """
1
+ """Contains information about data collections used by SH"""
2
2
 
3
3
  from __future__ import annotations
4
4
 
@@ -52,7 +52,7 @@ def fail_user_errors(download_func: Callable[[Self, DownloadRequest], T]) -> Cal
52
52
 
53
53
 
54
54
  def retry_temporary_errors(
55
- download_func: Callable[[SelfWithConfig, DownloadRequest], T]
55
+ download_func: Callable[[SelfWithConfig, DownloadRequest], T],
56
56
  ) -> Callable[[SelfWithConfig, DownloadRequest], T]:
57
57
  """Decorator function for handling server and connection errors"""
58
58
  backoff_coefficient = 3
@@ -15,7 +15,7 @@ from requests import Response
15
15
 
16
16
  from ..config import SHConfig
17
17
  from ..constants import SHConstants
18
- from ..exceptions import SHRateLimitWarning, SHRuntimeWarning
18
+ from ..exceptions import OutOfRequestsException, SHRateLimitWarning, SHRuntimeWarning
19
19
  from ..types import JsonDict
20
20
  from .client import DownloadClient
21
21
  from .handlers import fail_user_errors, retry_temporary_errors
@@ -75,10 +75,12 @@ class SentinelHubDownloadClient(DownloadClient):
75
75
  """
76
76
  Executes the download with a single thread and uses a rate limit object, which is shared between all threads
77
77
  """
78
+ download_attempts = 0
78
79
  while True:
79
80
  sleep_time = self._execute_thread_safe(self.rate_limit.register_next)
80
81
 
81
82
  if sleep_time == 0:
83
+ download_attempts += 1
82
84
  LOGGER.debug(
83
85
  "Sending %s request to %s. Hash of sent request is %s",
84
86
  request.request_type.value,
@@ -89,6 +91,9 @@ class SentinelHubDownloadClient(DownloadClient):
89
91
 
90
92
  if response.status_code == requests.status_codes.codes.TOO_MANY_REQUESTS:
91
93
  warnings.warn("Download rate limit hit", category=SHRateLimitWarning)
94
+ if self.config.max_retries is not None and download_attempts >= self.config.max_retries:
95
+ raise OutOfRequestsException("Maximum number of download attempts reached")
96
+
92
97
  self._execute_thread_safe(self.rate_limit.update, response.headers, default=self.default_retry_time)
93
98
  continue
94
99
 
sentinelhub/geometry.py CHANGED
@@ -150,7 +150,7 @@ class BBox(_BaseGeometry):
150
150
 
151
151
  @staticmethod
152
152
  def _tuple_from_list_or_tuple(
153
- bbox: tuple[float, float, float, float] | tuple[tuple[float, float], tuple[float, float]]
153
+ bbox: tuple[float, float, float, float] | tuple[tuple[float, float], tuple[float, float]],
154
154
  ) -> tuple[float, float, float, float]:
155
155
  """Converts a list or tuple representation of a bbox into a flat tuple representation.
156
156
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: sentinelhub
3
- Version: 3.10.1
3
+ Version: 3.10.2
4
4
  Summary: Python API for Sentinel Hub
5
5
  Project-URL: Homepage, https://github.com/sentinel-hub/sentinelhub-py
6
6
  Project-URL: Documentation, https://sentinelhub-py.readthedocs.io
@@ -73,14 +73,13 @@ Requires-Dist: boto3-stubs>=1.20.0; extra == 'dev'
73
73
  Requires-Dist: build; extra == 'dev'
74
74
  Requires-Dist: click>=8.0.0; extra == 'dev'
75
75
  Requires-Dist: fs; extra == 'dev'
76
- Requires-Dist: moto; extra == 'dev'
76
+ Requires-Dist: moto[s3]>=5.0.0; extra == 'dev'
77
77
  Requires-Dist: mypy>=0.990; extra == 'dev'
78
78
  Requires-Dist: pandas; extra == 'dev'
79
79
  Requires-Dist: pre-commit; extra == 'dev'
80
80
  Requires-Dist: pylint>=2.14.0; extra == 'dev'
81
81
  Requires-Dist: pytest-cov; extra == 'dev'
82
82
  Requires-Dist: pytest-dependency; extra == 'dev'
83
- Requires-Dist: pytest-lazy-fixture; extra == 'dev'
84
83
  Requires-Dist: pytest-mock; extra == 'dev'
85
84
  Requires-Dist: pytest>=4.0.0; extra == 'dev'
86
85
  Requires-Dist: ray[default]; extra == 'dev'
@@ -94,7 +93,7 @@ Requires-Dist: docutils; extra == 'docs'
94
93
  Requires-Dist: ipython; extra == 'docs'
95
94
  Requires-Dist: matplotlib; extra == 'docs'
96
95
  Requires-Dist: nbsphinx; extra == 'docs'
97
- Requires-Dist: sphinx-mdinclude; extra == 'docs'
96
+ Requires-Dist: sphinx-mdinclude==0.5.4; extra == 'docs'
98
97
  Requires-Dist: sphinx-rtd-theme==1.3.0; extra == 'docs'
99
98
  Requires-Dist: sphinx==7.1.2; extra == 'docs'
100
99
  Description-Content-Type: text/markdown
@@ -1,19 +1,19 @@
1
1
  sentinelhub/.utmzones.geojson,sha256=2kBUChuQK-ffIAc-5c8zluUa1JGgkop1HTShmhwp80s,768447
2
2
  sentinelhub/__init__.py,sha256=sXLQjfrL_0hFpZkl4cIavVLpMgXYP6SGixBXLSVqh6c,2185
3
- sentinelhub/_version.py,sha256=TS1qSVtKnb0j1UJPbWjP3YLKj6HriHiHCPbXlqhXvzc,66
3
+ sentinelhub/_version.py,sha256=jGtSnzPFNOsNMe0Rk7gYsIWc4mOpshHocEnUsFfiQcM,66
4
4
  sentinelhub/areas.py,sha256=Wuu6WwOlGQkvK9P4C7FGxC42IEyfYqifobdMd0ty4Fw,31885
5
5
  sentinelhub/base.py,sha256=g3E2Nh6I0c3GrkTmJ2rVK_disN2spQUn-yCWc_4NqMk,12857
6
6
  sentinelhub/commands.py,sha256=KHDT0uJATP9vWxjNLpUpaboPfHoXC3nIlmFGqS8DL0E,3306
7
- sentinelhub/config.py,sha256=fxKgSbiei62ePXvIUg2sBYDPXKR_UA93tkS_pdvnrFg,10201
7
+ sentinelhub/config.py,sha256=8ZJ8f4LKRwO6dDLHBtP_-T8yf8zUbQ_K5GafRhDaAXc,10365
8
8
  sentinelhub/constants.py,sha256=t8ivRGwBtXdCbqF1A7Zh_q5Zw599g1BdjVvb_n-ubAA,13528
9
9
  sentinelhub/data_collections.py,sha256=MxlNztn487sb-yBwbi1-uiLGis__-lCDvPSew8td6js,24305
10
- sentinelhub/data_collections_bands.py,sha256=Q_rFCqkrW11oAQrxPL4IdeximMqiUPkTGv9ZqP15d-g,11310
10
+ sentinelhub/data_collections_bands.py,sha256=H-oQUyHjcROHfe063Rt0C9I-2csmPlAlmNmVyJfZ9iE,11308
11
11
  sentinelhub/data_utils.py,sha256=8RPF1mg79ZgavtrPVPbvBBCaIphqEWYezTezyRJZcEY,7572
12
12
  sentinelhub/decoding.py,sha256=qKG75pFFFRlafX_8-SvCs9nlKrvzx9KB1sHGE5eTFVQ,6692
13
13
  sentinelhub/evalscript.py,sha256=1e78isrLBncvRM1ZB2ZdqWCq7jw4GP4A9wBwDlRA9kw,4564
14
14
  sentinelhub/exceptions.py,sha256=OZJRA0-nWby7wfihxTLVV27_w06QywjXHOZ1xZAhbq4,3864
15
15
  sentinelhub/geo_utils.py,sha256=1z8M-GwPygzqH15qpnYOkVg-qFnz9dT8TUbKsBOI4HA,8485
16
- sentinelhub/geometry.py,sha256=jeHOYzdcTqP37gKMDu2-2TatrbjqTs_wTB4LASdoPtE,23000
16
+ sentinelhub/geometry.py,sha256=lklhZd0EyKDOm3u17BVwz-v0bwW_FxarHzxudWar7Ck,23001
17
17
  sentinelhub/io_utils.py,sha256=6J5cSkDItR6bShoI2ztAfW0GERSHrv6mXQrLo451IR8,5360
18
18
  sentinelhub/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  sentinelhub/testing_utils.py,sha256=e6ZeYvHF6rHaMrXOXuwVY30_QDFWd2YqWG3PD1RWscc,2346
@@ -21,9 +21,9 @@ sentinelhub/time_utils.py,sha256=AcI8iRWMe6Qn073H8sKQnxSeGqZjuZ7dlZvuFwM7AtU,802
21
21
  sentinelhub/types.py,sha256=m5bZPsdXNf10uh43QBzE3ajcE6P26QfQcXCY11ky_uw,393
22
22
  sentinelhub/api/__init__.py,sha256=WKpWQK4F9o9pvLxtFme7OJ0Lo6fgoiPw-UQ1EE5UXNU,813
23
23
  sentinelhub/api/base.py,sha256=EVgbL7trpTLj99Ei8nMSjmWq5MYJG1PPGyzQpK03JpY,4254
24
- sentinelhub/api/base_request.py,sha256=3sGBr8z52SOePAr3-vzSNkLMH3HE-Z46_F5pbKH8jbc,9526
25
- sentinelhub/api/byoc.py,sha256=0fGlxUns0sPgjJoLYn39_DDUfLzQoVLmP9aCDaHb0qk,12179
26
- sentinelhub/api/catalog.py,sha256=xuWZFm_354yAkQYHr0sj9rHf8uPBaWwRws8vU9Kl7xU,13966
24
+ sentinelhub/api/base_request.py,sha256=jpczEjLbs4X__-5_-WFwFsgvlktdNDRlfmcCKJWJhhQ,9564
25
+ sentinelhub/api/byoc.py,sha256=CXB8jamhGfRiuhO0JyZDnKrqPetXa9LdHtLcXQ6Bqcs,12217
26
+ sentinelhub/api/catalog.py,sha256=WuInAWYf36wn9aHbV2OKuyOL07u75DA93MpWj7ugwnY,14040
27
27
  sentinelhub/api/fis.py,sha256=pLGm9q351RuVUwGpQrhx778co7CMONd0FN81OVEC448,6451
28
28
  sentinelhub/api/ogc.py,sha256=cYYBCQRkVh0IEsuzX5sIxzNZ09O86k8p5yxF4nTkC7U,30244
29
29
  sentinelhub/api/opensearch.py,sha256=nNaykGfpfX1OurS1gFj4NLxUzCwi-r6oPR0WOVNUOwg,7706
@@ -33,7 +33,7 @@ sentinelhub/api/utils.py,sha256=kjhHT_czAKFY14kPBxqkjUaJ9P-6RMKRceNC5_SrGm4,3730
33
33
  sentinelhub/api/wfs.py,sha256=QFg1pTrTwYWhuAwvhFVAcjTTW5Kn_mEONpTBfL04asw,7604
34
34
  sentinelhub/api/batch/__init__.py,sha256=q2uKqxC7_aBoVf_mmKhzVUrdA5kPDVO_TnChdEa5eZo,454
35
35
  sentinelhub/api/batch/base.py,sha256=uALuJnGKyp2Zx0-T9ku_1pxS3E9wOcXrwyHgPXXxdyk,4348
36
- sentinelhub/api/batch/process.py,sha256=6ryuQE1z4K64tZd7NuFnVB9gDXxJpgmXUVz8NJtdUt4,24249
36
+ sentinelhub/api/batch/process.py,sha256=bNvRfS5sQ2Bf9H0T3DPjAKVlK8QqTRv_haoAvMnl6xI,24311
37
37
  sentinelhub/api/batch/statistical.py,sha256=7RqmKqfS56IlCEMnRWo_aG8gsivjN39J5lLx8BxrFtE,8156
38
38
  sentinelhub/api/batch/utils.py,sha256=_c6vjatxeS0Krhm2Rs5jclBZwqV3P-VoZmkjGlExP40,10767
39
39
  sentinelhub/aws/__init__.py,sha256=AreOfOvDp6Sy6jfMGMCI44fDBMqgtWk-lUFXQ-8ehK8,503
@@ -46,17 +46,17 @@ sentinelhub/aws/data_safe.py,sha256=U_vSySCG4KZYPjINVTsSoQD5GQejCpN2tqBaUbWkRqA,
46
46
  sentinelhub/aws/request.py,sha256=DO-xf05kqDcJvmw18iKYmjtKaandBiXoAsdgKZDCcIA,10989
47
47
  sentinelhub/download/__init__.py,sha256=KdyMDc79cVUwy2wCLK3URPFY2uRVs41-MuS4qlkMQrE,352
48
48
  sentinelhub/download/client.py,sha256=qwxoGjL8idUSPb55zRNRfJRxuBhhDf-bqZmLRBt0_kA,11587
49
- sentinelhub/download/handlers.py,sha256=-NBAuPZndafs0sOXK4hCOmGIpdlQrL8Ug1hvJu2P1KA,5499
49
+ sentinelhub/download/handlers.py,sha256=J1XcUHe5UbZYRGxC-aeQV9FCEBbr__vp3NxFpde2ekM,5500
50
50
  sentinelhub/download/models.py,sha256=sMyVrilTHQMAMRQ4TJK-fr3ltU9sCOWX4JtTdPvEfXg,10054
51
51
  sentinelhub/download/rate_limit.py,sha256=jN9EifCwF0ojL-NvYIyD34fFeK4U-DQTsYkntpxnCv8,5248
52
- sentinelhub/download/sentinelhub_client.py,sha256=1NVq1tOv5t4Jtb6LxHVDiGo2SBh2O0iUl9I0RUoeCh8,9131
52
+ sentinelhub/download/sentinelhub_client.py,sha256=62g3JxbDzHfFqXBXtoZYyO9ESXA1UvM2mO1qRvqd0t4,9434
53
53
  sentinelhub/download/sentinelhub_statistical_client.py,sha256=mzU3TCY2zqp6UlW_4466833WXSiWkDYNZkjv95cPnwU,4474
54
54
  sentinelhub/download/session.py,sha256=KMRUw6wVEb68g8FZknIMk3BkAQvmghiCpIQ1rhhIJ48,14615
55
55
  sentinelhub/geopedia/__init__.py,sha256=R1wvAx_41U_KkDQif3Dubngyv2nR1zOIedxCdvhP3MM,263
56
56
  sentinelhub/geopedia/core.py,sha256=gU7CWZe8q5ZlZX4j1Zub4kvg5Nd7YZvtLCHGcuQAkfY,16370
57
57
  sentinelhub/geopedia/request.py,sha256=nmrEHJzqG13npSF8co23d8gZGXqxT5pyAu2geZ_fnmY,6618
58
- sentinelhub-3.10.1.dist-info/METADATA,sha256=2OJWCkCBTU_p495MV03vQkU7ediCLXytqWM_mhMBU8k,10207
59
- sentinelhub-3.10.1.dist-info/WHEEL,sha256=mRYSEL3Ih6g5a_CVMIcwiF__0Ae4_gLYh01YFNwiq1k,87
60
- sentinelhub-3.10.1.dist-info/entry_points.txt,sha256=nQiaLJk-L-7XCwyDiMozwfnJ7WI2Rc9FqnJDBt6K51g,212
61
- sentinelhub-3.10.1.dist-info/licenses/LICENSE.md,sha256=Gczr65g8pY0N0OO_5g-zI3RTidQTMBVlL0JxM7n8tGM,1071
62
- sentinelhub-3.10.1.dist-info/RECORD,,
58
+ sentinelhub-3.10.2.dist-info/METADATA,sha256=mLXlyJSS0H2lDdr64BTwM7cjJiIj27QT9TgBj37pkhY,10174
59
+ sentinelhub-3.10.2.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
60
+ sentinelhub-3.10.2.dist-info/entry_points.txt,sha256=nQiaLJk-L-7XCwyDiMozwfnJ7WI2Rc9FqnJDBt6K51g,212
61
+ sentinelhub-3.10.2.dist-info/licenses/LICENSE.md,sha256=Gczr65g8pY0N0OO_5g-zI3RTidQTMBVlL0JxM7n8tGM,1071
62
+ sentinelhub-3.10.2.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.21.0
2
+ Generator: hatchling 1.24.2
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any