sentinelhub 3.10.3__tar.gz → 3.11.0__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.3 → sentinelhub-3.11.0}/PKG-INFO +1 -1
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/pyproject.toml +2 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/__init__.py +4 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/_version.py +1 -1
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/__init__.py +4 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/batch/__init__.py +3 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/batch/base.py +8 -0
- sentinelhub-3.11.0/sentinelhub/api/batch/process_v2.py +325 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/batch/statistical.py +1 -1
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/batch/utils.py +76 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/process.py +1 -1
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/.gitignore +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/LICENSE.md +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/README.md +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/.utmzones.geojson +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/base.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/base_request.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/batch/process.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/byoc.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/catalog.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/fis.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/ogc.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/opensearch.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/statistical.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/utils.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/api/wfs.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/areas.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/aws/__init__.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/aws/batch.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/aws/client.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/aws/commands.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/aws/constants.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/aws/data.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/aws/data_safe.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/aws/request.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/base.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/commands.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/config.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/constants.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/data_collections.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/data_collections_bands.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/data_utils.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/decoding.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/download/__init__.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/download/client.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/download/handlers.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/download/models.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/download/rate_limit.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/download/sentinelhub_client.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/download/sentinelhub_statistical_client.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/download/session.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/evalscript.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/exceptions.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/geo_utils.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/geometry.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/geopedia/__init__.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/geopedia/core.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/geopedia/request.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/io_utils.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/py.typed +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/testing_utils.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/time_utils.py +0 -0
- {sentinelhub-3.10.3 → sentinelhub-3.11.0}/sentinelhub/types.py +0 -0
|
@@ -152,6 +152,7 @@ lint.fixable = [
|
|
|
152
152
|
"FA100", # import future annotations where necessary (not autofixable ATM)
|
|
153
153
|
]
|
|
154
154
|
lint.ignore = [
|
|
155
|
+
"G004", # f-strings in logging
|
|
155
156
|
"C408", # complains about `dict()` calls, we use them to avoid too many " in the code
|
|
156
157
|
"SIM108", # tries to aggresively inline `if`, not always readable
|
|
157
158
|
"COM812", # trailing comma missing, fights with black
|
|
@@ -191,6 +192,7 @@ disable = [
|
|
|
191
192
|
"unspecified-encoding",
|
|
192
193
|
"unnecessary-ellipsis",
|
|
193
194
|
"use-dict-literal",
|
|
195
|
+
"R0801",
|
|
194
196
|
]
|
|
195
197
|
|
|
196
198
|
[tool.pylint.design]
|
|
@@ -6,6 +6,8 @@ from ._version import __version__
|
|
|
6
6
|
from .api import (
|
|
7
7
|
AsyncProcessRequest,
|
|
8
8
|
BatchCollection,
|
|
9
|
+
BatchProcessClient,
|
|
10
|
+
BatchProcessRequest,
|
|
9
11
|
BatchRequest,
|
|
10
12
|
BatchRequestStatus,
|
|
11
13
|
BatchStatisticalRequest,
|
|
@@ -28,6 +30,8 @@ from .api import (
|
|
|
28
30
|
get_async_running_status,
|
|
29
31
|
monitor_batch_analysis,
|
|
30
32
|
monitor_batch_job,
|
|
33
|
+
monitor_batch_process_analysis,
|
|
34
|
+
monitor_batch_process_job,
|
|
31
35
|
monitor_batch_statistical_analysis,
|
|
32
36
|
monitor_batch_statistical_job,
|
|
33
37
|
opensearch,
|
|
@@ -4,6 +4,8 @@ The part of the package that implements interface with Sentinel Hub services.
|
|
|
4
4
|
|
|
5
5
|
from .batch import (
|
|
6
6
|
BatchCollection,
|
|
7
|
+
BatchProcessClient,
|
|
8
|
+
BatchProcessRequest,
|
|
7
9
|
BatchRequest,
|
|
8
10
|
BatchRequestStatus,
|
|
9
11
|
BatchStatisticalRequest,
|
|
@@ -13,6 +15,8 @@ from .batch import (
|
|
|
13
15
|
SentinelHubBatchStatistical,
|
|
14
16
|
monitor_batch_analysis,
|
|
15
17
|
monitor_batch_job,
|
|
18
|
+
monitor_batch_process_analysis,
|
|
19
|
+
monitor_batch_process_job,
|
|
16
20
|
monitor_batch_statistical_analysis,
|
|
17
21
|
monitor_batch_statistical_job,
|
|
18
22
|
)
|
|
@@ -4,10 +4,13 @@ The part of the package that implements interface with Sentinel Hub services.
|
|
|
4
4
|
|
|
5
5
|
from .base import BatchRequestStatus, BatchUserAction
|
|
6
6
|
from .process import BatchCollection, BatchRequest, BatchTileStatus, SentinelHubBatch
|
|
7
|
+
from .process_v2 import BatchProcessClient, BatchProcessRequest
|
|
7
8
|
from .statistical import BatchStatisticalRequest, SentinelHubBatchStatistical
|
|
8
9
|
from .utils import (
|
|
9
10
|
monitor_batch_analysis,
|
|
10
11
|
monitor_batch_job,
|
|
12
|
+
monitor_batch_process_analysis,
|
|
13
|
+
monitor_batch_process_job,
|
|
11
14
|
monitor_batch_statistical_analysis,
|
|
12
15
|
monitor_batch_statistical_job,
|
|
13
16
|
)
|
|
@@ -41,6 +41,14 @@ class BatchUserAction(Enum):
|
|
|
41
41
|
STOP = "STOP"
|
|
42
42
|
|
|
43
43
|
|
|
44
|
+
class StoppedStatusReason(Enum):
|
|
45
|
+
"""Description of why job status is STOPPED"""
|
|
46
|
+
|
|
47
|
+
OUT_OF_PU = "OUT_OF_PU"
|
|
48
|
+
USER_ACTION = "USER_ACTION"
|
|
49
|
+
UNHEALTHY = "UNHEALTHY"
|
|
50
|
+
|
|
51
|
+
|
|
44
52
|
class BaseBatchClient(SentinelHubService, Generic[BatchRequestType], metaclass=ABCMeta):
|
|
45
53
|
"""Class containing common methods and helper functions for Batch Client classes"""
|
|
46
54
|
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module implementing an interface with
|
|
3
|
+
`Batch Process V2 <https://docs.sentinel-hub.com/api/latest/api/batchv2/>`__.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
# ruff: noqa: FA100
|
|
7
|
+
# do not use `from __future__ import annotations`, it clashes with `dataclass_json`
|
|
8
|
+
import datetime as dt
|
|
9
|
+
import logging
|
|
10
|
+
from dataclasses import dataclass, field
|
|
11
|
+
from typing import Any, Dict, Iterator, Optional, Union
|
|
12
|
+
|
|
13
|
+
from dataclasses_json import CatchAll, LetterCase, Undefined, dataclass_json
|
|
14
|
+
from dataclasses_json import config as dataclass_config
|
|
15
|
+
from typing_extensions import Literal
|
|
16
|
+
|
|
17
|
+
from ...constants import RequestType
|
|
18
|
+
from ...types import Json, JsonDict
|
|
19
|
+
from ..base import SentinelHubFeatureIterator
|
|
20
|
+
from ..process import SentinelHubRequest
|
|
21
|
+
from ..utils import AccessSpecification, datetime_config, enum_config, remove_undefined, s3_specification
|
|
22
|
+
from .base import BaseBatchClient, BaseBatchRequest, BatchRequestStatus, BatchUserAction, StoppedStatusReason
|
|
23
|
+
|
|
24
|
+
LOGGER = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
BatchRequestType = Union[str, dict, "BatchProcessRequest"]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class BatchProcessClient(BaseBatchClient):
|
|
30
|
+
"""An interface class for Sentinel Hub Batch API version 2.
|
|
31
|
+
|
|
32
|
+
`Batch Process API <https://docs.sentinel-hub.com/api/latest/api/batchv2/>`__
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
s3_specification = staticmethod(s3_specification)
|
|
36
|
+
|
|
37
|
+
# pylint: disable=too-many-public-methods
|
|
38
|
+
@staticmethod
|
|
39
|
+
def _get_service_url(base_url: str) -> str:
|
|
40
|
+
"""Provides URL to Catalog API"""
|
|
41
|
+
return f"{base_url}/api/v2/batch"
|
|
42
|
+
|
|
43
|
+
def _get_processing_url(self, request_id: Optional[str] = None) -> str:
|
|
44
|
+
"""Creates a URL for process endpoint"""
|
|
45
|
+
url = f"{self.service_url}/process"
|
|
46
|
+
if request_id is None:
|
|
47
|
+
return url
|
|
48
|
+
return f"{url}/{request_id}"
|
|
49
|
+
|
|
50
|
+
def create(
|
|
51
|
+
self,
|
|
52
|
+
process_request: Union[SentinelHubRequest, JsonDict],
|
|
53
|
+
input: Dict[str, Any], # noqa: A002 #pylint: disable=redefined-builtin
|
|
54
|
+
output: Dict[str, Any],
|
|
55
|
+
instance_type: Literal["normal", "large"] = "normal",
|
|
56
|
+
description: Optional[str] = None,
|
|
57
|
+
**kwargs: Any,
|
|
58
|
+
) -> "BatchProcessRequest":
|
|
59
|
+
"""Create a new batch request
|
|
60
|
+
|
|
61
|
+
`Batch Process V2 <https://docs.sentinel-hub.com/api/latest/api/batchv2/>`__
|
|
62
|
+
|
|
63
|
+
:param process_request: An instance of SentinelHubRequest class containing all request parameters.
|
|
64
|
+
Alternatively, it can also be just a payload dictionary for Process API request
|
|
65
|
+
:param input: A dictionary with input parameters. It can be built with `tiling_grid_input` or `geopackage_input`
|
|
66
|
+
methods.
|
|
67
|
+
:param output: A dictionary with output parameters. It can be built with `raster_output` or `zarr_output`
|
|
68
|
+
methods.
|
|
69
|
+
:param instance_type": Specifies which size of instances to use for the request.
|
|
70
|
+
:param description: A description of a batch request
|
|
71
|
+
:param kwargs: Any other arguments to be added to a dictionary of parameters.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
if isinstance(process_request, SentinelHubRequest):
|
|
75
|
+
request_dict = process_request.download_list[0].post_values
|
|
76
|
+
else:
|
|
77
|
+
request_dict = process_request
|
|
78
|
+
|
|
79
|
+
if not isinstance(request_dict, dict):
|
|
80
|
+
raise ValueError(
|
|
81
|
+
"Parameter sentinelhub_request should be an instance of SentinelHubRequest or a "
|
|
82
|
+
"dictionary with a request payload"
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
payload = remove_undefined(
|
|
86
|
+
{
|
|
87
|
+
"processRequest": request_dict,
|
|
88
|
+
"input": input,
|
|
89
|
+
"output": output,
|
|
90
|
+
"instance_type": instance_type,
|
|
91
|
+
"description": description,
|
|
92
|
+
**kwargs,
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
request_info = self.client.get_json_dict(self._get_processing_url(), post_values=payload, use_session=True)
|
|
97
|
+
|
|
98
|
+
return BatchProcessRequest.from_dict(request_info)
|
|
99
|
+
|
|
100
|
+
@staticmethod
|
|
101
|
+
def geopackage_input(geopackage_specification: AccessSpecification) -> JsonDict:
|
|
102
|
+
"""A helper method to build a suitable dictionary for the `input` field.
|
|
103
|
+
|
|
104
|
+
:param geopackage_specification: A specification of the S3 path for the Geopackage. Can be built using the
|
|
105
|
+
`s3_specification` helper method.
|
|
106
|
+
"""
|
|
107
|
+
return {"type": "geopackage", "features": geopackage_specification}
|
|
108
|
+
|
|
109
|
+
@staticmethod
|
|
110
|
+
def tiling_grid_input(
|
|
111
|
+
grid_id: int, resolution: float, buffer_x: Optional[int] = None, buffer_y: Optional[int] = None, **kwargs: Any
|
|
112
|
+
) -> JsonDict:
|
|
113
|
+
"""A helper method to build a dictionary with tiling grid parameters for the `input` field.
|
|
114
|
+
|
|
115
|
+
:param grid_id: An ID of a tiling grid
|
|
116
|
+
:param resolution: A grid resolution
|
|
117
|
+
:param buffer_x: Will expand each output tile horizontally (left and right) by specified number of pixels.
|
|
118
|
+
:param buffer_y: Will expand each output tile vertically (up and down) by specified number of pixels.
|
|
119
|
+
:param kwargs: Any other arguments to be added to a dictionary of parameters
|
|
120
|
+
"""
|
|
121
|
+
return remove_undefined(
|
|
122
|
+
{
|
|
123
|
+
"type": "tiling-grid",
|
|
124
|
+
"id": grid_id,
|
|
125
|
+
"resolution": resolution,
|
|
126
|
+
"bufferX": buffer_x,
|
|
127
|
+
"bufferY": buffer_y,
|
|
128
|
+
**kwargs,
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
@staticmethod
|
|
133
|
+
def raster_output(
|
|
134
|
+
delivery: AccessSpecification,
|
|
135
|
+
*,
|
|
136
|
+
overwrite: Optional[bool] = None,
|
|
137
|
+
skip_existing: Optional[bool] = None,
|
|
138
|
+
cog_output: Optional[bool] = None,
|
|
139
|
+
cog_parameters: Optional[Dict[str, Any]] = None,
|
|
140
|
+
create_collection: Optional[bool] = None,
|
|
141
|
+
collection_id: Optional[str] = None,
|
|
142
|
+
**kwargs: Any,
|
|
143
|
+
) -> Dict[str, Any]:
|
|
144
|
+
"""A helper method to build a dictionary specifying raster output
|
|
145
|
+
|
|
146
|
+
:param delivery: An S3 access specification containing a path or a template on an s3 bucket where to store
|
|
147
|
+
results. You can use the `s3_specification` method for construction. For more information on templates see
|
|
148
|
+
documentation.
|
|
149
|
+
:param overwrite: A flag specifying if a request should overwrite existing outputs without failing
|
|
150
|
+
:param skip_existing: A flag specifying if existing outputs should be overwritten
|
|
151
|
+
:param cog_output: A flag specifying if outputs should be written in COGs (cloud-optimized GeoTIFFs) or
|
|
152
|
+
normal GeoTIFFs
|
|
153
|
+
:param cog_parameters: A dictionary specifying COG creation parameters. See documentation for more info.
|
|
154
|
+
:param create_collection: If True the results will be written in COGs and a batch collection will be created
|
|
155
|
+
:param collection_id: If True results will be added to an existing collection
|
|
156
|
+
:param kwargs: Any other arguments to be added to a dictionary of parameters
|
|
157
|
+
"""
|
|
158
|
+
return remove_undefined(
|
|
159
|
+
{
|
|
160
|
+
"type": "raster",
|
|
161
|
+
"delivery": delivery,
|
|
162
|
+
"overwrite": overwrite,
|
|
163
|
+
"skipExisting": skip_existing,
|
|
164
|
+
"cogOutput": cog_output,
|
|
165
|
+
"cogParameters": cog_parameters,
|
|
166
|
+
"createCollection": create_collection,
|
|
167
|
+
"collectionId": collection_id,
|
|
168
|
+
**kwargs,
|
|
169
|
+
}
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
@staticmethod
|
|
173
|
+
def zarr_output(
|
|
174
|
+
delivery: AccessSpecification,
|
|
175
|
+
*,
|
|
176
|
+
group: Optional[Dict[str, Any]] = None,
|
|
177
|
+
array_parameters: Optional[Dict[str, Any]] = None,
|
|
178
|
+
array_overrides: Optional[Dict[str, Any]] = None,
|
|
179
|
+
**kwargs: Any,
|
|
180
|
+
) -> JsonDict:
|
|
181
|
+
"""A helper method to build a dictionary specifying Zarr output. See documentation for more information on
|
|
182
|
+
each parameter.
|
|
183
|
+
|
|
184
|
+
`Batch Process V2 <https://docs.sentinel-hub.com/api/latest/api/batchv2/>`__
|
|
185
|
+
|
|
186
|
+
:param delivery: An S3 access specification containing a path or a template on an s3 bucket where to store
|
|
187
|
+
results. You can use the `s3_specification` method for construction. For more information on templates see
|
|
188
|
+
documentation.
|
|
189
|
+
:param group: Zarr group level parameters
|
|
190
|
+
:param array_parameters: Parameters that will be used for all output arrays, except where overriden with
|
|
191
|
+
`array_overrides`. Required unless `array_overrides` includes all required fields for all output arrays.
|
|
192
|
+
:param array_overrides: Overrides the values of `array_arameters` for individual arrays.
|
|
193
|
+
:param kwargs: Any other arguments to be added to a dictionary of parameters
|
|
194
|
+
"""
|
|
195
|
+
return remove_undefined(
|
|
196
|
+
{
|
|
197
|
+
"type": "zarr",
|
|
198
|
+
"delivery": delivery,
|
|
199
|
+
"group": group,
|
|
200
|
+
"arrayParameter": array_parameters,
|
|
201
|
+
"arrayOverrides": array_overrides,
|
|
202
|
+
**kwargs,
|
|
203
|
+
}
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
def iter_requests(
|
|
207
|
+
self, user_id: Optional[str] = None, search: Optional[str] = None, sort: Optional[str] = None, **kwargs: Any
|
|
208
|
+
) -> Iterator["BatchProcessRequest"]:
|
|
209
|
+
"""Iterate existing batch requests
|
|
210
|
+
|
|
211
|
+
`Batch Process V2 <https://docs.sentinel-hub.com/api/latest/api/batchv2/>`__
|
|
212
|
+
|
|
213
|
+
:param user_id: Filter requests by a user id who defined a request
|
|
214
|
+
:param search: A search query to filter requests
|
|
215
|
+
:param sort: A sort query
|
|
216
|
+
:param kwargs: Any additional parameters to include in a request query
|
|
217
|
+
:return: An iterator over existing batch requests
|
|
218
|
+
"""
|
|
219
|
+
params = remove_undefined({"userid": user_id, "search": search, "sort": sort, **kwargs})
|
|
220
|
+
feature_iterator = SentinelHubFeatureIterator(
|
|
221
|
+
client=self.client, url=self._get_processing_url(), params=params, exception_message="No requests found"
|
|
222
|
+
)
|
|
223
|
+
for request_info in feature_iterator:
|
|
224
|
+
yield BatchProcessRequest.from_dict(request_info)
|
|
225
|
+
|
|
226
|
+
def get_request(self, batch_request: BatchRequestType) -> "BatchProcessRequest":
|
|
227
|
+
"""Collects information about a single batch request.
|
|
228
|
+
|
|
229
|
+
`Batch Process V2 <https://docs.sentinel-hub.com/api/latest/api/batchv2/>`__
|
|
230
|
+
"""
|
|
231
|
+
request_id = self._parse_request_id(batch_request)
|
|
232
|
+
request_info = self.client.get_json_dict(url=self._get_processing_url(request_id), use_session=True)
|
|
233
|
+
return BatchProcessRequest.from_dict(request_info)
|
|
234
|
+
|
|
235
|
+
def update_request(self, batch_request: BatchRequestType, description: str) -> Json:
|
|
236
|
+
"""Update certain batch job request parameters. Can only update requests that are not currently being processed.
|
|
237
|
+
|
|
238
|
+
`Batch Process V2 <https://docs.sentinel-hub.com/api/latest/api/batchv2/>`__
|
|
239
|
+
|
|
240
|
+
:param batch_request: Batch request ID, a dictionary containing an "ID" field, or a BatchProcessRequest.
|
|
241
|
+
:param description: A description of a batch request to be updated.
|
|
242
|
+
"""
|
|
243
|
+
request_id = self._parse_request_id(batch_request)
|
|
244
|
+
|
|
245
|
+
return self.client.get_json(
|
|
246
|
+
url=self._get_processing_url(request_id),
|
|
247
|
+
post_values={"description": description},
|
|
248
|
+
request_type=RequestType.PUT,
|
|
249
|
+
use_session=True,
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
def start_analysis(self, batch_request: BatchRequestType) -> Json:
|
|
253
|
+
"""Starts analysis of a batch job request
|
|
254
|
+
|
|
255
|
+
:param batch_request: Batch request ID, a dictionary containing an "ID" field, or a BatchProcessRequest.
|
|
256
|
+
"""
|
|
257
|
+
return self._call_job(batch_request, "analyse")
|
|
258
|
+
|
|
259
|
+
def start_job(self, batch_request: BatchRequestType) -> Json:
|
|
260
|
+
"""Starts running a batch job
|
|
261
|
+
|
|
262
|
+
:param batch_request: Batch request ID, a dictionary containing an "ID" field, or a BatchProcessRequest.
|
|
263
|
+
"""
|
|
264
|
+
return self._call_job(batch_request, "start")
|
|
265
|
+
|
|
266
|
+
def stop_job(self, batch_request: BatchRequestType) -> Json:
|
|
267
|
+
"""Stops a batch job
|
|
268
|
+
|
|
269
|
+
:param batch_request: Batch request ID, a dictionary containing an "ID" field, or a BatchProcessRequest.
|
|
270
|
+
"""
|
|
271
|
+
return self._call_job(batch_request, "stop")
|
|
272
|
+
|
|
273
|
+
def iter_tiling_grids(self, **kwargs: Any) -> SentinelHubFeatureIterator:
|
|
274
|
+
"""An iterator over tiling grids
|
|
275
|
+
|
|
276
|
+
`Batch Process V2 <https://docs.sentinel-hub.com/api/latest/api/batchv2/>`__
|
|
277
|
+
|
|
278
|
+
:param kwargs: Any other request query parameters
|
|
279
|
+
:return: An iterator over tiling grid definitions
|
|
280
|
+
"""
|
|
281
|
+
return SentinelHubFeatureIterator(
|
|
282
|
+
client=self.client,
|
|
283
|
+
url=f"{self.service_url}/tilinggrids",
|
|
284
|
+
params=remove_undefined(kwargs),
|
|
285
|
+
exception_message="Failed to obtain information about available tiling grids",
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
def get_tiling_grid(self, grid_id: int) -> JsonDict:
|
|
289
|
+
"""Provides a single tiling grid
|
|
290
|
+
|
|
291
|
+
`Batch Process V2 <https://docs.sentinel-hub.com/api/latest/api/batchv2/>`__
|
|
292
|
+
|
|
293
|
+
:param grid_id: An ID of a requested tiling grid
|
|
294
|
+
:return: A tiling grid definition
|
|
295
|
+
"""
|
|
296
|
+
url = f"{self.service_url}/tilinggrids/{grid_id}"
|
|
297
|
+
return self.client.get_json_dict(url=url, use_session=True)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.INCLUDE)
|
|
301
|
+
@dataclass(repr=False)
|
|
302
|
+
class BatchProcessRequest(BaseBatchRequest): # pylint: disable=abstract-method
|
|
303
|
+
"""A dataclass object that holds information about a batch request"""
|
|
304
|
+
|
|
305
|
+
# dataclass_json doesn't handle parameter inheritance correctly
|
|
306
|
+
# pylint: disable=invalid-name
|
|
307
|
+
|
|
308
|
+
request_id: str = field(metadata=dataclass_config(field_name="id"))
|
|
309
|
+
request: dict
|
|
310
|
+
domain_account_id: str
|
|
311
|
+
status: BatchRequestStatus = field(metadata=enum_config(BatchRequestStatus))
|
|
312
|
+
error: Optional[str] = None
|
|
313
|
+
user_action: Optional[BatchUserAction] = field(metadata=enum_config(BatchUserAction), default=None)
|
|
314
|
+
user_action_updated: Optional[dt.datetime] = field(metadata=datetime_config, default=None)
|
|
315
|
+
created: Optional[dt.datetime] = field(metadata=datetime_config, default=None)
|
|
316
|
+
completion_percentage: float = 0
|
|
317
|
+
last_updated: Optional[dt.datetime] = field(metadata=datetime_config, default=None)
|
|
318
|
+
cost_PU: Optional[float] = field(metadata=dataclass_config(field_name="costPU"), default=None) # noqa: N815
|
|
319
|
+
stopped_status_reason: Optional[StoppedStatusReason] = field(
|
|
320
|
+
metadata=enum_config(StoppedStatusReason), default=None
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
other_data: CatchAll = field(default_factory=dict)
|
|
324
|
+
|
|
325
|
+
_REPR_PARAM_NAMES = ("request_id", "created", "status", "completion_percentage", "user_action", "cost_PU")
|
|
@@ -33,7 +33,7 @@ class SentinelHubBatchStatistical(BaseBatchClient["BatchStatisticalRequest"]):
|
|
|
33
33
|
information.
|
|
34
34
|
"""
|
|
35
35
|
|
|
36
|
-
s3_specification = s3_specification
|
|
36
|
+
s3_specification = staticmethod(s3_specification)
|
|
37
37
|
|
|
38
38
|
@staticmethod
|
|
39
39
|
def _get_service_url(base_url: str) -> str:
|
|
@@ -15,6 +15,7 @@ from ...config import SHConfig
|
|
|
15
15
|
from ...types import JsonDict
|
|
16
16
|
from .base import BatchRequestStatus
|
|
17
17
|
from .process import BatchRequest, BatchTileStatus, SentinelHubBatch
|
|
18
|
+
from .process_v2 import BatchProcessClient, BatchProcessRequest
|
|
18
19
|
from .statistical import BatchStatisticalRequest, SentinelHubBatchStatistical
|
|
19
20
|
|
|
20
21
|
LOGGER = logging.getLogger(__name__)
|
|
@@ -106,6 +107,54 @@ def monitor_batch_job(
|
|
|
106
107
|
return tiles_per_status
|
|
107
108
|
|
|
108
109
|
|
|
110
|
+
def monitor_batch_process_job(
|
|
111
|
+
request: BatchProcessRequest,
|
|
112
|
+
client: BatchProcessClient,
|
|
113
|
+
sleep_time: int = _DEFAULT_SLEEP_TIME,
|
|
114
|
+
analysis_sleep_time: int = _DEFAULT_ANALYSIS_SLEEP_TIME,
|
|
115
|
+
) -> BatchProcessRequest:
|
|
116
|
+
"""A utility function that keeps checking the progress of the batch processing job. Returns an updated version of
|
|
117
|
+
the request
|
|
118
|
+
|
|
119
|
+
Notes:
|
|
120
|
+
|
|
121
|
+
- Before calling this function make sure to start a batch job by calling `BatchProcessingClient.start_job` method.
|
|
122
|
+
In case a batch job is still being analysed this function will wait until the analysis ends.
|
|
123
|
+
- This function will be continuously collecting information from Sentinel Hub service. To avoid making too many
|
|
124
|
+
requests please make sure to adjust `sleep_time` parameter.
|
|
125
|
+
|
|
126
|
+
:param request: The request to monitor.
|
|
127
|
+
:param client: A batch processing client with appropriate configuration that is used to monitor the batch job.
|
|
128
|
+
:param sleep_time: Number of seconds to sleep between consecutive progress bar updates.
|
|
129
|
+
:param analysis_sleep_time: Number of seconds between consecutive status updates during analysis phase.
|
|
130
|
+
"""
|
|
131
|
+
if sleep_time < _MIN_SLEEP_TIME:
|
|
132
|
+
raise ValueError(f"To avoid making too many service requests please set sleep_time>={_MIN_SLEEP_TIME}")
|
|
133
|
+
|
|
134
|
+
batch_request: BatchProcessRequest = monitor_batch_process_analysis(request, client, sleep_time=analysis_sleep_time)
|
|
135
|
+
if batch_request.status is BatchRequestStatus.PROCESSING:
|
|
136
|
+
LOGGER.info("Batch job is running")
|
|
137
|
+
|
|
138
|
+
completion = batch_request.completion_percentage
|
|
139
|
+
progress_bar = tqdm(total=100, initial=completion, desc="Completion percentage")
|
|
140
|
+
|
|
141
|
+
monitoring_status = [BatchRequestStatus.ANALYSIS_DONE, BatchRequestStatus.PROCESSING]
|
|
142
|
+
with progress_bar:
|
|
143
|
+
while completion < 100 and batch_request.status in monitoring_status:
|
|
144
|
+
time.sleep(sleep_time)
|
|
145
|
+
batch_request = client.get_request(batch_request)
|
|
146
|
+
progress_bar.update(batch_request.completion_percentage - completion)
|
|
147
|
+
completion = batch_request.completion_percentage
|
|
148
|
+
|
|
149
|
+
while batch_request.status in monitoring_status:
|
|
150
|
+
LOGGER.info("Waiting on batch job status update, currently %s", batch_request.status)
|
|
151
|
+
time.sleep(sleep_time)
|
|
152
|
+
batch_request = client.get_request(batch_request)
|
|
153
|
+
|
|
154
|
+
LOGGER.info("Batch job finished with status %s", batch_request.status.value)
|
|
155
|
+
return batch_request
|
|
156
|
+
|
|
157
|
+
|
|
109
158
|
def _get_batch_tiles_per_status(
|
|
110
159
|
batch_request: BatchRequest, batch_client: SentinelHubBatch
|
|
111
160
|
) -> defaultdict[BatchTileStatus, list[dict]]:
|
|
@@ -200,6 +249,33 @@ def monitor_batch_analysis(
|
|
|
200
249
|
return batch_request
|
|
201
250
|
|
|
202
251
|
|
|
252
|
+
def monitor_batch_process_analysis(
|
|
253
|
+
request: BatchProcessRequest,
|
|
254
|
+
client: BatchProcessClient,
|
|
255
|
+
sleep_time: int = _DEFAULT_ANALYSIS_SLEEP_TIME,
|
|
256
|
+
) -> BatchProcessRequest:
|
|
257
|
+
"""A utility function that is waiting until analysis phase of a batch job finishes and regularly checks its status.
|
|
258
|
+
In case analysis phase failed it raises an error at the end.
|
|
259
|
+
|
|
260
|
+
:param request: The request to monitor.
|
|
261
|
+
:param client: A batch processing client with appropriate configuration that is used to monitor the batch job.
|
|
262
|
+
:param sleep_time: Number of seconds between consecutive status updates during analysis phase.
|
|
263
|
+
"""
|
|
264
|
+
if sleep_time < _MIN_ANALYSIS_SLEEP_TIME:
|
|
265
|
+
raise ValueError(
|
|
266
|
+
f"To avoid making too many service requests please set analysis sleep time >={_MIN_ANALYSIS_SLEEP_TIME}"
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
batch_request = client.get_request(request)
|
|
270
|
+
while batch_request.status in [BatchRequestStatus.CREATED, BatchRequestStatus.ANALYSING]:
|
|
271
|
+
LOGGER.info("Batch job has a status %s, sleeping for %d seconds", batch_request.status.value, sleep_time)
|
|
272
|
+
time.sleep(sleep_time)
|
|
273
|
+
batch_request = client.get_request(batch_request)
|
|
274
|
+
|
|
275
|
+
batch_request.raise_for_status(status=[BatchRequestStatus.FAILED, BatchRequestStatus.CANCELED])
|
|
276
|
+
return batch_request
|
|
277
|
+
|
|
278
|
+
|
|
203
279
|
def monitor_batch_statistical_analysis(
|
|
204
280
|
batch_request: BatchStatisticalRequestSpec,
|
|
205
281
|
config: SHConfig | None = None,
|
|
@@ -205,7 +205,7 @@ class AsyncProcessRequest(SentinelHubBaseApiRequest):
|
|
|
205
205
|
|
|
206
206
|
super().__init__(SentinelHubDownloadClient, **kwargs)
|
|
207
207
|
|
|
208
|
-
s3_specification = s3_specification
|
|
208
|
+
s3_specification = staticmethod(s3_specification)
|
|
209
209
|
|
|
210
210
|
@property
|
|
211
211
|
def mime_type(self) -> MimeType:
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sentinelhub-3.10.3 → sentinelhub-3.11.0}/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
|
|
File without changes
|