eotdl 2023.11.2.post5__py3-none-any.whl → 2023.11.3.post2__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.
- eotdl/__init__.py +1 -1
- eotdl/access/__init__.py +6 -3
- eotdl/access/airbus/__init__.py +5 -1
- eotdl/access/airbus/client.py +356 -338
- eotdl/access/airbus/parameters.py +19 -4
- eotdl/access/airbus/utils.py +26 -21
- eotdl/access/download.py +30 -14
- eotdl/access/search.py +17 -6
- eotdl/access/sentinelhub/__init__.py +5 -1
- eotdl/access/sentinelhub/client.py +57 -54
- eotdl/access/sentinelhub/evalscripts.py +38 -39
- eotdl/access/sentinelhub/parameters.py +43 -23
- eotdl/access/sentinelhub/utils.py +38 -28
- eotdl/auth/errors.py +2 -1
- eotdl/commands/auth.py +3 -3
- eotdl/curation/__init__.py +5 -1
- eotdl/curation/stac/__init__.py +5 -1
- eotdl/curation/stac/assets.py +55 -32
- eotdl/curation/stac/dataframe.py +20 -14
- eotdl/curation/stac/dataframe_bck.py +2 -2
- eotdl/curation/stac/dataframe_labeling.py +15 -12
- eotdl/curation/stac/extensions/__init__.py +6 -2
- eotdl/curation/stac/extensions/base.py +8 -4
- eotdl/curation/stac/extensions/dem.py +6 -3
- eotdl/curation/stac/extensions/eo.py +10 -6
- eotdl/curation/stac/extensions/label/__init__.py +5 -1
- eotdl/curation/stac/extensions/label/base.py +40 -26
- eotdl/curation/stac/extensions/label/image_name_labeler.py +64 -43
- eotdl/curation/stac/extensions/label/scaneo.py +59 -56
- eotdl/curation/stac/extensions/ml_dataset.py +154 -56
- eotdl/curation/stac/extensions/projection.py +11 -9
- eotdl/curation/stac/extensions/raster.py +22 -14
- eotdl/curation/stac/extensions/sar.py +12 -7
- eotdl/curation/stac/extent.py +67 -40
- eotdl/curation/stac/parsers.py +18 -10
- eotdl/curation/stac/stac.py +81 -62
- eotdl/datasets/__init__.py +1 -1
- eotdl/datasets/download.py +42 -55
- eotdl/datasets/ingest.py +68 -11
- eotdl/files/__init__.py +1 -1
- eotdl/files/ingest.py +3 -1
- eotdl/models/download.py +1 -1
- eotdl/repos/AuthAPIRepo.py +0 -1
- eotdl/repos/DatasetsAPIRepo.py +22 -146
- eotdl/repos/FilesAPIRepo.py +7 -92
- eotdl/repos/ModelsAPIRepo.py +0 -1
- eotdl/tools/__init__.py +5 -1
- eotdl/tools/geo_utils.py +78 -48
- eotdl/tools/metadata.py +13 -11
- eotdl/tools/paths.py +14 -14
- eotdl/tools/stac.py +36 -31
- eotdl/tools/time_utils.py +53 -26
- eotdl/tools/tools.py +84 -50
- {eotdl-2023.11.2.post5.dist-info → eotdl-2023.11.3.post2.dist-info}/METADATA +5 -3
- eotdl-2023.11.3.post2.dist-info/RECORD +84 -0
- eotdl-2023.11.2.post5.dist-info/RECORD +0 -84
- {eotdl-2023.11.2.post5.dist-info → eotdl-2023.11.3.post2.dist-info}/WHEEL +0 -0
- {eotdl-2023.11.2.post5.dist-info → eotdl-2023.11.3.post2.dist-info}/entry_points.txt +0 -0
eotdl/access/airbus/client.py
CHANGED
@@ -3,365 +3,383 @@ Module for managing the Airbus configuration and data access
|
|
3
3
|
"""
|
4
4
|
|
5
5
|
import json
|
6
|
-
import requests
|
7
|
-
from requests.exceptions import ConnectTimeout, ReadTimeout
|
8
|
-
from urllib3.exceptions import TimeoutError
|
9
6
|
import time
|
10
|
-
|
11
7
|
from typing import Optional, Iterable
|
12
8
|
from os.path import join, exists
|
13
|
-
|
14
|
-
from .
|
15
|
-
from ...tools.tools import expand_time_interval, bbox_to_coordinates
|
9
|
+
import requests
|
10
|
+
from requests.exceptions import ConnectTimeout, ReadTimeout
|
16
11
|
|
12
|
+
from .parameters import AirbusURL, AirbusProductType, AirbusImageFormat, AirbusRadiometricProcessing
|
13
|
+
from .utils import get_airbus_access_token
|
14
|
+
from ...tools import expand_time_interval, bbox_to_coordinates
|
17
15
|
|
18
|
-
class AirbusClient():
|
19
|
-
"""
|
20
|
-
Client class to manage the Sentinel Hub Python interface.
|
21
|
-
"""
|
22
16
|
|
23
|
-
|
24
|
-
access_token: str,
|
25
|
-
api_key: str,
|
26
|
-
) -> None:
|
17
|
+
class AirbusClient:
|
27
18
|
"""
|
28
|
-
|
29
|
-
|
30
|
-
Params
|
31
|
-
----------
|
32
|
-
access_token: str
|
33
|
-
Access token
|
34
|
-
api_key: str
|
35
|
-
API key
|
19
|
+
Client class to manage the Sentinel Hub Python interface.
|
36
20
|
"""
|
37
|
-
self.airbus_access_token = access_token
|
38
|
-
self._api_key = api_key
|
39
21
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
22
|
+
def __init__(
|
23
|
+
self,
|
24
|
+
access_token: str,
|
25
|
+
api_key: str,
|
26
|
+
) -> None:
|
27
|
+
"""
|
28
|
+
Constructor
|
29
|
+
|
30
|
+
Params
|
31
|
+
----------
|
32
|
+
access_token: str
|
33
|
+
Access token
|
34
|
+
api_key: str
|
35
|
+
API key
|
36
|
+
"""
|
37
|
+
self.airbus_access_token = access_token
|
38
|
+
self._api_key = api_key
|
39
|
+
|
40
|
+
def get_total_products_price(
|
41
|
+
self, payload: dict, all_info: Optional[bool] = False
|
42
|
+
) -> dict:
|
43
|
+
"""
|
44
|
+
Get total products price
|
45
|
+
"""
|
46
|
+
if all_info:
|
47
|
+
response = []
|
48
|
+
else:
|
49
|
+
response = 0
|
50
|
+
|
51
|
+
for _, location_data in payload.items():
|
52
|
+
product_id = location_data["image"]
|
53
|
+
if product_id:
|
54
|
+
price_response = self.get_product_price(
|
55
|
+
product_id, location_data["bounding_box"]
|
56
|
+
)
|
57
|
+
if all_info:
|
58
|
+
response.append(price_response)
|
59
|
+
else:
|
60
|
+
response += price_response["price"]["credits"]
|
61
|
+
|
62
|
+
return response
|
63
|
+
|
64
|
+
def get_product_price(
|
65
|
+
self,
|
66
|
+
product_id: str,
|
67
|
+
coordinates: Iterable,
|
68
|
+
product_type: Optional[AirbusProductType] = AirbusProductType.MULTISPECTRAL,
|
69
|
+
image_format: Optional[AirbusImageFormat] = AirbusImageFormat.GEOTIFF,
|
70
|
+
processing: Optional[
|
71
|
+
AirbusRadiometricProcessing
|
72
|
+
] = AirbusRadiometricProcessing.REFLECTANCE,
|
73
|
+
) -> dict:
|
74
|
+
"""
|
75
|
+
Get product price
|
76
|
+
|
77
|
+
Params
|
78
|
+
----------
|
79
|
+
product_id: str
|
80
|
+
Product ID
|
81
|
+
coordinates: tuple
|
82
|
+
Polygon coordinates
|
83
|
+
product_type: AirbusProductType
|
84
|
+
Product type
|
85
|
+
image_format: AirbusImageFormat
|
86
|
+
Image format
|
87
|
+
processing: AirbusRadiometricProcessing
|
88
|
+
Radiometric processing
|
89
|
+
Types are defined at parameters.py
|
90
|
+
|
91
|
+
Returns
|
92
|
+
----------
|
93
|
+
dict
|
94
|
+
Product price
|
95
|
+
"""
|
96
|
+
if isinstance(coordinates, (list, tuple)) and len(
|
97
|
+
coordinates
|
98
|
+
) == 4:
|
99
|
+
coordinates = bbox_to_coordinates(coordinates)
|
100
|
+
|
101
|
+
headers = {
|
102
|
+
"Authorization": f"Bearer {self.airbus_access_token}",
|
103
|
+
"Content-Type": "application/json",
|
104
|
+
"Cache-Control": "no-cache",
|
105
|
+
}
|
93
106
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
107
|
+
# TODO make productType, imageformat and processing configurable with paramters controlled by classes like
|
108
|
+
# TODO AirbusProductType.multiSpectral, AirbusImageFormat.geotiff, AirbusProcessing
|
109
|
+
payload = {
|
110
|
+
"kind": "order.data.product",
|
111
|
+
"products": [
|
112
|
+
{
|
113
|
+
"productType": product_type,
|
114
|
+
"radiometricProcessing": processing,
|
115
|
+
"imageFormat": image_format,
|
116
|
+
"crsCode": "urn:ogc:def:crs:EPSG::4326",
|
117
|
+
"id": product_id,
|
118
|
+
"aoi": {"type": "Polygon", "coordinates": [coordinates]},
|
119
|
+
}
|
120
|
+
],
|
98
121
|
}
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
122
|
+
response = requests.request(
|
123
|
+
"POST", AirbusURL.PRICES, json=payload, headers=headers, timeout=60000
|
124
|
+
)
|
125
|
+
|
126
|
+
return response.json()
|
127
|
+
|
128
|
+
def place_product_order(
|
129
|
+
self,
|
130
|
+
product_id: str,
|
131
|
+
coordinates: Iterable,
|
132
|
+
product_type: Optional[AirbusProductType] = AirbusProductType.MULTISPECTRAL,
|
133
|
+
image_format: Optional[AirbusImageFormat] = AirbusImageFormat.GEOTIFF,
|
134
|
+
processing: Optional[
|
135
|
+
AirbusRadiometricProcessing
|
136
|
+
] = AirbusRadiometricProcessing.REFLECTANCE,
|
137
|
+
) -> dict:
|
138
|
+
"""
|
139
|
+
Place product order
|
140
|
+
|
141
|
+
Params
|
142
|
+
----------
|
143
|
+
product_id: str
|
144
|
+
Product ID
|
145
|
+
bounding_box: tuple
|
146
|
+
Bounding box
|
147
|
+
product_type: AirbusProductType
|
148
|
+
Product type
|
149
|
+
image_format: AirbusImageFormat
|
150
|
+
Image format
|
151
|
+
processing: AirbusRadiometricProcessing
|
152
|
+
Radiometric processing
|
153
|
+
Types are defined at parameters.py
|
154
|
+
|
155
|
+
Returns
|
156
|
+
----------
|
157
|
+
dict
|
158
|
+
Order data
|
159
|
+
"""
|
160
|
+
if isinstance(coordinates, (list, tuple)) and len(
|
161
|
+
coordinates
|
162
|
+
) == 4:
|
163
|
+
coordinates = bbox_to_coordinates(coordinates)
|
164
|
+
|
165
|
+
payload = {
|
166
|
+
"kind": "order.data.product",
|
167
|
+
"products": [
|
168
|
+
{
|
169
|
+
"productType": product_type,
|
170
|
+
"radiometricProcessing": processing,
|
171
|
+
"imageFormat": image_format,
|
172
|
+
"crsCode": "urn:ogc:def:crs:EPSG::4326",
|
173
|
+
"id": product_id,
|
174
|
+
"aoi": {"type": "Polygon", "coordinates": [coordinates]},
|
175
|
+
}
|
176
|
+
],
|
117
177
|
}
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
return response.json()
|
123
|
-
|
124
|
-
def place_product_order(self,
|
125
|
-
product_id: str,
|
126
|
-
coordinates: Iterable,
|
127
|
-
product_type: Optional[AirbusProductType] = AirbusProductType.MULTISPECTRAL,
|
128
|
-
image_format: Optional[AirbusImageFormat] = AirbusImageFormat.GEOTIFF,
|
129
|
-
processing: Optional[AirbusRadiometricProcessing] = AirbusRadiometricProcessing.REFLECTANCE
|
130
|
-
) -> dict:
|
131
|
-
"""
|
132
|
-
Place product order
|
133
|
-
|
134
|
-
Params
|
135
|
-
----------
|
136
|
-
product_id: str
|
137
|
-
Product ID
|
138
|
-
bounding_box: tuple
|
139
|
-
Bounding box
|
140
|
-
product_type: AirbusProductType
|
141
|
-
Product type
|
142
|
-
image_format: AirbusImageFormat
|
143
|
-
Image format
|
144
|
-
processing: AirbusRadiometricProcessing
|
145
|
-
Radiometric processing
|
146
|
-
Types are defined at parameters.py
|
147
|
-
|
148
|
-
Returns
|
149
|
-
----------
|
150
|
-
dict
|
151
|
-
Order data
|
152
|
-
"""
|
153
|
-
if (isinstance(coordinates, tuple) or isinstance(coordinates, list)) and len(coordinates) == 4:
|
154
|
-
coordinates = bbox_to_coordinates(coordinates)
|
155
|
-
|
156
|
-
payload = {
|
157
|
-
"kind": "order.data.product",
|
158
|
-
"products": [
|
159
|
-
{
|
160
|
-
"productType": product_type,
|
161
|
-
"radiometricProcessing": processing,
|
162
|
-
"imageFormat": image_format,
|
163
|
-
"crsCode": "urn:ogc:def:crs:EPSG::4326",
|
164
|
-
"id": product_id,
|
165
|
-
"aoi": {
|
166
|
-
"type": "Polygon",
|
167
|
-
"coordinates": [
|
168
|
-
coordinates
|
169
|
-
]
|
170
|
-
}
|
178
|
+
|
179
|
+
headers = {
|
180
|
+
"Authorization": f"Bearer {self.airbus_access_token}",
|
171
181
|
}
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
headers = {
|
215
|
-
'authorization': f"Bearer {self.airbus_access_token}",
|
216
|
-
'cache-control': "no-cache",
|
182
|
+
|
183
|
+
response = requests.request(
|
184
|
+
"POST", AirbusURL.ORDERS, json=payload, headers=headers, timeout=60000
|
185
|
+
)
|
186
|
+
|
187
|
+
return response.json()
|
188
|
+
|
189
|
+
def search_image(
|
190
|
+
self,
|
191
|
+
bounding_box: Iterable,
|
192
|
+
acquisition_date: Iterable,
|
193
|
+
timeout: Optional[int] = 10,
|
194
|
+
) -> dict:
|
195
|
+
"""
|
196
|
+
Search image
|
197
|
+
|
198
|
+
Params
|
199
|
+
----------
|
200
|
+
bounding_box: tuple or list
|
201
|
+
Bounding box
|
202
|
+
acquisition_date: tuple or list
|
203
|
+
Acquisition date
|
204
|
+
timeout: int
|
205
|
+
Timeout
|
206
|
+
|
207
|
+
Returns
|
208
|
+
----------
|
209
|
+
dict
|
210
|
+
Image data
|
211
|
+
"""
|
212
|
+
if isinstance(acquisition_date, (tuple, list)):
|
213
|
+
acquisition_date = "[" + ",".join(acquisition_date) + "]"
|
214
|
+
if isinstance(bounding_box, (tuple, list)) and len(
|
215
|
+
bounding_box
|
216
|
+
) == 4:
|
217
|
+
bounding_box = ",".join(str(num) for num in bounding_box)
|
218
|
+
|
219
|
+
querystring = {"acquisitionDate": str(acquisition_date), "bbox": bounding_box}
|
220
|
+
|
221
|
+
headers = {
|
222
|
+
"authorization": f"Bearer {self.airbus_access_token}",
|
223
|
+
"cache-control": "no-cache",
|
217
224
|
}
|
218
225
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
226
|
+
try:
|
227
|
+
response = requests.request(
|
228
|
+
"GET",
|
229
|
+
AirbusURL.SEARCH,
|
230
|
+
headers=headers,
|
231
|
+
params=querystring,
|
232
|
+
verify=False,
|
233
|
+
timeout=timeout,
|
234
|
+
)
|
235
|
+
return response.json()
|
236
|
+
except json.decoder.JSONDecodeError:
|
237
|
+
print("JSONDecodeError")
|
238
|
+
print(response)
|
239
|
+
except ReadTimeout:
|
240
|
+
print("ReadTimeout")
|
241
|
+
print(response)
|
242
|
+
|
243
|
+
def search_images_close_in_time(
|
244
|
+
self,
|
245
|
+
payload_dict: dict,
|
246
|
+
path: Optional[str] = None,
|
247
|
+
max_days: Optional[int] = 30,
|
248
|
+
) -> dict:
|
249
|
+
"""
|
250
|
+
Search images close in time
|
251
|
+
|
252
|
+
Params
|
253
|
+
----------
|
254
|
+
payload_dict: dict
|
255
|
+
Payload dictionary
|
256
|
+
max_days: int
|
257
|
+
Maximum days to search
|
258
|
+
|
259
|
+
Returns
|
260
|
+
----------
|
261
|
+
dict
|
262
|
+
Dictionary with the image data, as {location_id: image_data}, to
|
263
|
+
maintain track of the location
|
264
|
+
"""
|
265
|
+
responses = {}
|
266
|
+
if path:
|
267
|
+
responses_path = join(path, "airbus_images_response.json")
|
268
|
+
if exists(responses_path):
|
269
|
+
with open(responses_path, "r", encoding="utf-8") as f:
|
270
|
+
responses = json.load(f)
|
271
|
+
|
272
|
+
for location_id, location_info in list(payload_dict.items()):
|
273
|
+
bounding_box, time_interval = (
|
274
|
+
location_info["bounding_box"],
|
275
|
+
location_info["time_interval"],
|
276
|
+
)
|
277
|
+
days = 1
|
278
|
+
|
279
|
+
if location_id in responses:
|
280
|
+
continue
|
281
|
+
|
282
|
+
while days <= max_days:
|
283
|
+
try:
|
284
|
+
response = self.search_image(bounding_box, time_interval)
|
285
|
+
except ConnectTimeout or TimeoutError:
|
286
|
+
# Wait 5 seconds and try again
|
287
|
+
time.sleep(5)
|
288
|
+
# Restart the connection
|
289
|
+
self.airbus_access_token = get_airbus_access_token(self._api_key)
|
290
|
+
# Continue with the search
|
291
|
+
response = self.search_image(bounding_box, time_interval)
|
292
|
+
|
293
|
+
total_results = response["totalResults"]
|
294
|
+
|
295
|
+
if total_results > 0:
|
296
|
+
# By default, the search results are sorted per acquisition date
|
297
|
+
# (newest data is displayed first) and per cloud coverage (less cloudy images are displayed first).
|
298
|
+
# So, we can stop the search when we find the first image
|
299
|
+
if total_results > 1:
|
300
|
+
response["features"] = [response["features"][0]]
|
301
|
+
responses[location_id] = response["features"][0]
|
302
|
+
if path:
|
303
|
+
with open(responses_path, "w", encoding="utf-8") as f:
|
304
|
+
json.dump(responses, f)
|
305
|
+
break
|
306
|
+
|
307
|
+
time_interval = expand_time_interval(time_interval)
|
308
|
+
days += 1
|
309
|
+
|
310
|
+
# If no image is found, we add a None value to the dictionary
|
311
|
+
if total_results == 0:
|
312
|
+
responses[location_id] = None
|
284
313
|
if path:
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
return product_payload_with_image, product_payload_without_image
|
331
|
-
|
332
|
-
def get_all_order_status(self):
|
333
|
-
"""
|
334
|
-
"""
|
335
|
-
headers = {
|
336
|
-
'Authorization': f"Bearer {self.airbus_access_token}",
|
337
|
-
'Content-Type': "application/json",
|
338
|
-
'Cache-Control': "no-cache",
|
339
|
-
}
|
314
|
+
with open(responses_path, "w", encoding="utf-8") as f:
|
315
|
+
json.dump(responses, f)
|
316
|
+
|
317
|
+
return responses
|
318
|
+
|
319
|
+
def format_product_payload(
|
320
|
+
self, location_payload: dict, images_response: dict
|
321
|
+
) -> dict:
|
322
|
+
"""
|
323
|
+
Format product payload
|
324
|
+
"""
|
325
|
+
for product_id, _ in location_payload.items():
|
326
|
+
# Add new key to the dictionary
|
327
|
+
location_payload[product_id]["image_response"] = (
|
328
|
+
images_response[product_id] if product_id in images_response else None
|
329
|
+
)
|
330
|
+
|
331
|
+
return location_payload
|
332
|
+
|
333
|
+
def split_product_payload(self, product_payload: dict) -> dict:
|
334
|
+
"""
|
335
|
+
Split product payload
|
336
|
+
"""
|
337
|
+
# split the product payload depending on if 'image' is None or not
|
338
|
+
product_payload_with_image = {}
|
339
|
+
product_payload_without_image = {}
|
340
|
+
|
341
|
+
for product_id, info in product_payload.items():
|
342
|
+
if info["image"]:
|
343
|
+
product_payload_with_image[product_id] = info
|
344
|
+
else:
|
345
|
+
product_payload_without_image[product_id] = info
|
346
|
+
|
347
|
+
return product_payload_with_image, product_payload_without_image
|
348
|
+
|
349
|
+
def get_all_order_status(self):
|
350
|
+
"""
|
351
|
+
Get all order status
|
352
|
+
"""
|
353
|
+
headers = {
|
354
|
+
"Authorization": f"Bearer {self.airbus_access_token}",
|
355
|
+
"Content-Type": "application/json",
|
356
|
+
"Cache-Control": "no-cache",
|
357
|
+
}
|
340
358
|
|
341
|
-
|
359
|
+
response = requests.request("GET", AirbusURL.ALL_ORDERS_STATUS, headers=headers, timeout=60000)
|
342
360
|
|
343
|
-
|
361
|
+
return response.text
|
344
362
|
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
363
|
+
def get_account_information(self):
|
364
|
+
"""
|
365
|
+
Get account information
|
366
|
+
"""
|
367
|
+
headers = {
|
368
|
+
"Authorization": f"Bearer {self.airbus_access_token}",
|
369
|
+
"Content-Type": "application/json",
|
370
|
+
"Cache-Control": "no-cache",
|
371
|
+
}
|
353
372
|
|
354
|
-
|
373
|
+
response = requests.request("GET", AirbusURL.ACCOUNT, headers=headers, timeout=60000)
|
355
374
|
|
356
|
-
|
375
|
+
return response.json()
|
357
376
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
}
|
377
|
+
def get_user_roles(self):
|
378
|
+
"""
|
379
|
+
Get user roles
|
380
|
+
"""
|
381
|
+
headers = {"Authorization": f"Bearer {self.airbus_access_token}"}
|
364
382
|
|
365
|
-
|
383
|
+
response = requests.request("GET", AirbusURL.ROLES, headers=headers, timeout=60000)
|
366
384
|
|
367
|
-
|
385
|
+
return response.json()
|