sentinelhub 3.10.1__tar.gz → 3.10.3__tar.gz
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-3.10.1 → sentinelhub-3.10.3}/PKG-INFO +4 -5
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/pyproject.toml +7 -8
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/_version.py +1 -1
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/base_request.py +7 -5
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/batch/process.py +13 -11
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/batch/utils.py +11 -1
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/byoc.py +7 -5
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/catalog.py +16 -14
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/config.py +3 -1
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/constants.py +4 -4
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/data_collections_bands.py +1 -1
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/download/handlers.py +1 -1
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/download/sentinelhub_client.py +6 -1
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/geometry.py +1 -1
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/.gitignore +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/LICENSE.md +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/README.md +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/.utmzones.geojson +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/__init__.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/__init__.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/base.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/batch/__init__.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/batch/base.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/batch/statistical.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/fis.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/ogc.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/opensearch.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/process.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/statistical.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/utils.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/api/wfs.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/areas.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/aws/__init__.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/aws/batch.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/aws/client.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/aws/commands.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/aws/constants.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/aws/data.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/aws/data_safe.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/aws/request.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/base.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/commands.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/data_collections.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/data_utils.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/decoding.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/download/__init__.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/download/client.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/download/models.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/download/rate_limit.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/download/sentinelhub_statistical_client.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/download/session.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/evalscript.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/exceptions.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/geo_utils.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/geopedia/__init__.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/geopedia/core.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/geopedia/request.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/io_utils.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/py.typed +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/testing_utils.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/time_utils.py +0 -0
- {sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: sentinelhub
|
|
3
|
-
Version: 3.10.
|
|
3
|
+
Version: 3.10.3
|
|
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
|
|
@@ -63,7 +63,7 @@ docs = [
|
|
|
63
63
|
"matplotlib",
|
|
64
64
|
"nbsphinx",
|
|
65
65
|
"sphinx==7.1.2",
|
|
66
|
-
"sphinx_mdinclude",
|
|
66
|
+
"sphinx_mdinclude==0.5.4", # version fixed because 0.6.0 didnt work at release time of 3.10.2
|
|
67
67
|
"sphinx_rtd_theme==1.3.0",
|
|
68
68
|
]
|
|
69
69
|
dev = [
|
|
@@ -73,14 +73,13 @@ dev = [
|
|
|
73
73
|
"click>=8.0.0",
|
|
74
74
|
"fs",
|
|
75
75
|
"mypy>=0.990",
|
|
76
|
-
"moto",
|
|
76
|
+
"moto[s3]>=5.0.0",
|
|
77
77
|
"pandas",
|
|
78
78
|
"pre-commit",
|
|
79
79
|
"pylint>=2.14.0",
|
|
80
80
|
"pytest>=4.0.0",
|
|
81
81
|
"pytest-cov",
|
|
82
82
|
"pytest-dependency",
|
|
83
|
-
"pytest-lazy-fixture",
|
|
84
83
|
"pytest-mock",
|
|
85
84
|
"ray[default]",
|
|
86
85
|
"requests-mock",
|
|
@@ -111,7 +110,7 @@ preview = true
|
|
|
111
110
|
[tool.ruff]
|
|
112
111
|
line-length = 120
|
|
113
112
|
target-version = "py38"
|
|
114
|
-
select = [
|
|
113
|
+
lint.select = [
|
|
115
114
|
"F", # pyflakes
|
|
116
115
|
"E", # pycodestyle
|
|
117
116
|
"W", # pycodestyle
|
|
@@ -144,7 +143,7 @@ select = [
|
|
|
144
143
|
"RUF", # ruff rules
|
|
145
144
|
]
|
|
146
145
|
fix = true
|
|
147
|
-
fixable = [
|
|
146
|
+
lint.fixable = [
|
|
148
147
|
"I", # sort imports
|
|
149
148
|
"F401", # remove redundant imports
|
|
150
149
|
"UP007", # use new-style union type annotations
|
|
@@ -152,7 +151,7 @@ fixable = [
|
|
|
152
151
|
"UP037", # remove quotes around types when not necessary
|
|
153
152
|
"FA100", # import future annotations where necessary (not autofixable ATM)
|
|
154
153
|
]
|
|
155
|
-
ignore = [
|
|
154
|
+
lint.ignore = [
|
|
156
155
|
"C408", # complains about `dict()` calls, we use them to avoid too many " in the code
|
|
157
156
|
"SIM108", # tries to aggresively inline `if`, not always readable
|
|
158
157
|
"COM812", # trailing comma missing, fights with black
|
|
@@ -163,11 +162,11 @@ ignore = [
|
|
|
163
162
|
"B028", # always demands a stacklevel argument when warning
|
|
164
163
|
"PT011", # complains for `pytest.raises(ValueError)` but we use it a lot
|
|
165
164
|
]
|
|
166
|
-
per-file-ignores = { "__init__.py" = ["F401"], "conf.py" = ["FA100"] }
|
|
165
|
+
lint.per-file-ignores = { "__init__.py" = ["F401"], "conf.py" = ["FA100"] }
|
|
167
166
|
exclude = [".git", "__pycache__", "build", "dist", "sentinelhub/aws/*"]
|
|
168
167
|
|
|
169
168
|
|
|
170
|
-
[tool.ruff.isort]
|
|
169
|
+
[tool.ruff.lint.isort]
|
|
171
170
|
section-order = [
|
|
172
171
|
"future",
|
|
173
172
|
"standard-library",
|
|
@@ -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
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
|
@@ -73,9 +73,12 @@ def monitor_batch_job(
|
|
|
73
73
|
|
|
74
74
|
progress_bar = tqdm(total=batch_request.tile_count, initial=finished_count, desc="Progress rate")
|
|
75
75
|
success_bar = tqdm(total=finished_count, initial=success_count, desc="Success rate")
|
|
76
|
+
|
|
77
|
+
monitoring_status = [BatchRequestStatus.ANALYSIS_DONE, BatchRequestStatus.PROCESSING]
|
|
76
78
|
with progress_bar, success_bar:
|
|
77
|
-
while finished_count < batch_request.tile_count:
|
|
79
|
+
while finished_count < batch_request.tile_count and batch_request.status in monitoring_status:
|
|
78
80
|
time.sleep(sleep_time)
|
|
81
|
+
batch_request = batch_client.get_request(batch_request)
|
|
79
82
|
|
|
80
83
|
tiles_per_status = _get_batch_tiles_per_status(batch_request, batch_client)
|
|
81
84
|
new_success_count = len(tiles_per_status[BatchTileStatus.PROCESSED])
|
|
@@ -93,6 +96,13 @@ def monitor_batch_job(
|
|
|
93
96
|
failed_tiles_num = finished_count - success_count
|
|
94
97
|
if failed_tiles_num:
|
|
95
98
|
LOGGER.info("Batch job failed for %d tiles", failed_tiles_num)
|
|
99
|
+
|
|
100
|
+
while batch_request.status is BatchRequestStatus.PROCESSING:
|
|
101
|
+
LOGGER.info("Waiting on batch job status update.")
|
|
102
|
+
time.sleep(sleep_time)
|
|
103
|
+
batch_request = batch_client.get_request(batch_request)
|
|
104
|
+
|
|
105
|
+
LOGGER.info("Batch job finished with status %s", batch_request.status.value)
|
|
96
106
|
return tiles_per_status
|
|
97
107
|
|
|
98
108
|
|
|
@@ -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
|
-
|
|
225
|
-
|
|
226
|
-
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
|
|
@@ -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
|
"""
|
|
@@ -81,7 +81,7 @@ class CRSMeta(EnumMeta):
|
|
|
81
81
|
|
|
82
82
|
return super().__new__(mcs, cls, bases, classdict)
|
|
83
83
|
|
|
84
|
-
def __call__(cls, crs_value, *args, **kwargs): # type: ignore[no-untyped-def]
|
|
84
|
+
def __call__(cls, crs_value, *args, **kwargs): # type: ignore[no-untyped-def]
|
|
85
85
|
"""This is executed whenever CRS('something') is called"""
|
|
86
86
|
# pylint: disable=signature-differs
|
|
87
87
|
crs_value = cls._parse_crs(crs_value)
|
|
@@ -201,7 +201,7 @@ class CRS(Enum, metaclass=CRSMeta):
|
|
|
201
201
|
"""
|
|
202
202
|
return self.name.startswith("UTM")
|
|
203
203
|
|
|
204
|
-
@functools.lru_cache(maxsize=128)
|
|
204
|
+
@functools.lru_cache(maxsize=128)
|
|
205
205
|
def projection(self) -> pyproj.Proj:
|
|
206
206
|
"""Returns a projection in form of pyproj class.
|
|
207
207
|
|
|
@@ -212,7 +212,7 @@ class CRS(Enum, metaclass=CRSMeta):
|
|
|
212
212
|
"""
|
|
213
213
|
return pyproj.Proj(self._get_pyproj_projection_def(), preserve_units=True)
|
|
214
214
|
|
|
215
|
-
@functools.lru_cache(maxsize=128)
|
|
215
|
+
@functools.lru_cache(maxsize=128)
|
|
216
216
|
def pyproj_crs(self) -> pyproj.CRS:
|
|
217
217
|
"""Returns a pyproj CRS class.
|
|
218
218
|
|
|
@@ -223,7 +223,7 @@ class CRS(Enum, metaclass=CRSMeta):
|
|
|
223
223
|
"""
|
|
224
224
|
return pyproj.CRS(self._get_pyproj_projection_def())
|
|
225
225
|
|
|
226
|
-
@functools.lru_cache(maxsize=512)
|
|
226
|
+
@functools.lru_cache(maxsize=512)
|
|
227
227
|
def get_transform_function(self, other: CRS, always_xy: bool = True) -> Callable[..., tuple]:
|
|
228
228
|
"""Returns a function for transforming geometrical objects from one CRS to another. The function will support
|
|
229
229
|
transformations between any objects that pyproj supports.
|
|
@@ -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
|
|
|
@@ -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
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sentinelhub-3.10.1 → sentinelhub-3.10.3}/sentinelhub/download/sentinelhub_statistical_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|