terrakio-core 0.4.97__py3-none-any.whl → 0.4.98.1b1__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.
Potentially problematic release.
This version of terrakio-core might be problematic. Click here for more details.
- terrakio_core/__init__.py +1 -1
- terrakio_core/async_client.py +26 -169
- terrakio_core/config.py +3 -44
- terrakio_core/convenience_functions/zonal_stats.py +86 -33
- terrakio_core/endpoints/auth.py +96 -47
- terrakio_core/endpoints/dataset_management.py +120 -54
- terrakio_core/endpoints/group_management.py +269 -76
- terrakio_core/endpoints/mass_stats.py +704 -581
- terrakio_core/endpoints/model_management.py +213 -109
- terrakio_core/endpoints/user_management.py +106 -21
- terrakio_core/exceptions.py +371 -1
- terrakio_core/sync_client.py +9 -124
- {terrakio_core-0.4.97.dist-info → terrakio_core-0.4.98.1b1.dist-info}/METADATA +2 -1
- terrakio_core-0.4.98.1b1.dist-info/RECORD +23 -0
- terrakio_core-0.4.97.dist-info/RECORD +0 -23
- {terrakio_core-0.4.97.dist-info → terrakio_core-0.4.98.1b1.dist-info}/WHEEL +0 -0
terrakio_core/endpoints/auth.py
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
|
-
import os
|
|
2
1
|
import json
|
|
3
|
-
|
|
4
|
-
from
|
|
5
|
-
|
|
2
|
+
import os
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
|
|
5
|
+
from ..exceptions import (
|
|
6
|
+
APIKeyError,
|
|
7
|
+
AuthenticationExpireError,
|
|
8
|
+
InvalidUsernamePasswordError,
|
|
9
|
+
LoginError,
|
|
10
|
+
QuotaError,
|
|
11
|
+
RefreshAPIKeyError,
|
|
12
|
+
ResetPasswordError,
|
|
13
|
+
SignupError,
|
|
14
|
+
UserInfoError,
|
|
15
|
+
InvalidEmailFormatError,
|
|
16
|
+
EmailAlreadyExistsError,
|
|
17
|
+
)
|
|
18
|
+
from ..helper.decorators import require_api_key, require_auth, require_token
|
|
6
19
|
|
|
7
20
|
class AuthClient:
|
|
8
21
|
def __init__(self, client):
|
|
@@ -20,22 +33,23 @@ class AuthClient:
|
|
|
20
33
|
Dict containing the authentication token
|
|
21
34
|
|
|
22
35
|
Raises:
|
|
23
|
-
|
|
36
|
+
SignupError: If the signup request fails
|
|
24
37
|
"""
|
|
25
38
|
payload = {
|
|
26
39
|
"email": email,
|
|
27
40
|
"password": password
|
|
28
41
|
}
|
|
42
|
+
response, status = await self._client._terrakio_request("POST", "/users/signup", json=payload)
|
|
43
|
+
if status != 200:
|
|
44
|
+
if status == 422:
|
|
45
|
+
raise InvalidEmailFormatError(f"Invalid email format: {response}", status_code=status)
|
|
46
|
+
elif status == 409:
|
|
47
|
+
raise EmailAlreadyExistsError(f"Email already exists: {response}", status_code=status)
|
|
48
|
+
raise SignupError(f"Signup request failed: {response}", status_code=status)
|
|
49
|
+
else:
|
|
50
|
+
return response
|
|
29
51
|
|
|
30
|
-
|
|
31
|
-
try:
|
|
32
|
-
result = await self._client._terrakio_request("POST", "/users/signup", json=payload)
|
|
33
|
-
except Exception as e:
|
|
34
|
-
self._client.logger.info(f"Signup failed: {str(e)}")
|
|
35
|
-
raise APIError(f"Signup request failed: {str(e)}")
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
async def login(self, email: str, password: str) -> Dict[str, str]:
|
|
52
|
+
async def login(self, email: str, password: str) -> None:
|
|
39
53
|
"""
|
|
40
54
|
Login a user with email and password.
|
|
41
55
|
|
|
@@ -44,7 +58,7 @@ class AuthClient:
|
|
|
44
58
|
password: User's password
|
|
45
59
|
|
|
46
60
|
Returns:
|
|
47
|
-
|
|
61
|
+
None
|
|
48
62
|
|
|
49
63
|
Raises:
|
|
50
64
|
APIError: If the login request fails
|
|
@@ -53,10 +67,14 @@ class AuthClient:
|
|
|
53
67
|
"email": email,
|
|
54
68
|
"password": password
|
|
55
69
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
response, status = await self._client._terrakio_request("POST", "/users/login", json=payload)
|
|
71
|
+
if status != 200:
|
|
72
|
+
if status == 401:
|
|
73
|
+
raise InvalidUsernamePasswordError(f"Invalid username or password: {response}", status_code=status)
|
|
74
|
+
else:
|
|
75
|
+
raise LoginError(f"Login request failed: {response}", status_code=status)
|
|
76
|
+
else:
|
|
77
|
+
token_response = response.get("token")
|
|
60
78
|
|
|
61
79
|
if token_response:
|
|
62
80
|
self._client.token = token_response
|
|
@@ -72,11 +90,6 @@ class AuthClient:
|
|
|
72
90
|
self._client.logger.info(f"Successfully authenticated as: {email}")
|
|
73
91
|
self._client.logger.info(f"Using Terrakio API at: {self._client.url}")
|
|
74
92
|
|
|
75
|
-
return {"token": token_response} if token_response else {"error": "Login failed"}
|
|
76
|
-
|
|
77
|
-
except Exception as e:
|
|
78
|
-
self._client.logger.info(f"Login failed: {str(e)}")
|
|
79
|
-
raise APIError(f"Login request failed: {str(e)}")
|
|
80
93
|
|
|
81
94
|
@require_token
|
|
82
95
|
async def view_api_key(self) -> str:
|
|
@@ -87,11 +100,18 @@ class AuthClient:
|
|
|
87
100
|
str: The API key
|
|
88
101
|
|
|
89
102
|
Raises:
|
|
90
|
-
|
|
103
|
+
AuthenticationExpireError: If authentication expired
|
|
104
|
+
APIKeyError: If the API key request fails
|
|
91
105
|
"""
|
|
92
|
-
|
|
93
|
-
api_key =
|
|
94
|
-
|
|
106
|
+
response, status = await self._client._terrakio_request("GET", "/users/key")
|
|
107
|
+
api_key = response.get("apiKey")
|
|
108
|
+
if status != 200:
|
|
109
|
+
if status == 400 and response.get("detail")["message"] == "Not authenticated":
|
|
110
|
+
raise AuthenticationExpireError(f"Authentication expired, please login again: {response}")
|
|
111
|
+
else:
|
|
112
|
+
raise APIKeyError(f"Error fetching API key: {response}", status_code=status)
|
|
113
|
+
else:
|
|
114
|
+
return api_key
|
|
95
115
|
|
|
96
116
|
@require_api_key
|
|
97
117
|
@require_token
|
|
@@ -103,17 +123,18 @@ class AuthClient:
|
|
|
103
123
|
str: The new API key
|
|
104
124
|
|
|
105
125
|
Raises:
|
|
106
|
-
|
|
126
|
+
RefreshAPIKeyError: If the API key refresh request fails
|
|
107
127
|
"""
|
|
108
|
-
|
|
109
|
-
self._client.key =
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
128
|
+
response, status = await self._client._terrakio_request("POST", "/users/refresh_key")
|
|
129
|
+
self._client.key = response.get("apiKey")
|
|
130
|
+
if status != 200:
|
|
131
|
+
raise RefreshAPIKeyError(f"Error refreshing API key: {response}", status_code=status)
|
|
132
|
+
else:
|
|
133
|
+
self._update_config_key()
|
|
134
|
+
return self._client.key
|
|
114
135
|
|
|
115
136
|
@require_api_key
|
|
116
|
-
def get_user_info(self) -> Dict[str, Any]:
|
|
137
|
+
async def get_user_info(self) -> Dict[str, Any]:
|
|
117
138
|
"""
|
|
118
139
|
Get information about the authenticated user.
|
|
119
140
|
|
|
@@ -121,9 +142,45 @@ class AuthClient:
|
|
|
121
142
|
Dict[str, Any]: User information
|
|
122
143
|
|
|
123
144
|
Raises:
|
|
124
|
-
|
|
145
|
+
AuthenticationExpireError: If authentication expired
|
|
146
|
+
UserInfoError: If the user info request fails
|
|
125
147
|
"""
|
|
126
|
-
|
|
148
|
+
response, status = await self._client._terrakio_request("GET", "/users/info")
|
|
149
|
+
if status != 200:
|
|
150
|
+
if status == 400 and response.get("detail")["message"] == "Not authenticated":
|
|
151
|
+
raise AuthenticationExpireError(f"Authentication expired, please login again: {response}", status_code=status)
|
|
152
|
+
else:
|
|
153
|
+
raise UserInfoError(f"Error fetching user info: {response}", status_code=status)
|
|
154
|
+
else:
|
|
155
|
+
return response
|
|
156
|
+
|
|
157
|
+
@require_api_key
|
|
158
|
+
async def reset_password(self, email : str) -> Dict[str, Any]:
|
|
159
|
+
"""
|
|
160
|
+
Reset the password for a user by email.
|
|
161
|
+
"""
|
|
162
|
+
response, status = await self._client._terrakio_request("GET", f"/users/reset-password?email={email}")
|
|
163
|
+
if status != 200:
|
|
164
|
+
raise ResetPasswordError(f"Error resetting password: {response}", status_code=status)
|
|
165
|
+
else:
|
|
166
|
+
return response['message']
|
|
167
|
+
|
|
168
|
+
@require_api_key
|
|
169
|
+
async def get_user_quota(self):
|
|
170
|
+
"""
|
|
171
|
+
Get the user's quota.
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
Dict: User's quota
|
|
175
|
+
|
|
176
|
+
Raises:
|
|
177
|
+
QuotaError: If the quota request fails
|
|
178
|
+
"""
|
|
179
|
+
response, status = await self._client._terrakio_request("GET", "/users/quota")
|
|
180
|
+
if status != 200:
|
|
181
|
+
raise QuotaError(f"Error fetching quota: {response}", status_code = status)
|
|
182
|
+
else:
|
|
183
|
+
return response
|
|
127
184
|
|
|
128
185
|
def _save_config(self, email: str, token: str):
|
|
129
186
|
"""
|
|
@@ -145,7 +202,6 @@ class AuthClient:
|
|
|
145
202
|
config["TERRAKIO_API_KEY"] = self._client.key
|
|
146
203
|
config["PERSONAL_TOKEN"] = token
|
|
147
204
|
os.makedirs(os.path.dirname(config_path), exist_ok=True)
|
|
148
|
-
|
|
149
205
|
with open(config_path, 'w') as f:
|
|
150
206
|
json.dump(config, f, indent=4)
|
|
151
207
|
|
|
@@ -177,11 +233,4 @@ class AuthClient:
|
|
|
177
233
|
self._client.logger.info(f"API key updated in {config_path}")
|
|
178
234
|
|
|
179
235
|
except Exception as e:
|
|
180
|
-
self._client.logger.info(f"Warning: Failed to update config file: {e}")
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
# we have four different circumstances:
|
|
184
|
-
# same expression, different region
|
|
185
|
-
# same expression, same region
|
|
186
|
-
# different expression, same region
|
|
187
|
-
# different expression, different region
|
|
236
|
+
self._client.logger.info(f"Warning: Failed to update config file: {e}")
|
|
@@ -1,51 +1,68 @@
|
|
|
1
|
-
from typing import
|
|
2
|
-
|
|
1
|
+
from typing import Any, Dict, List, Optional
|
|
2
|
+
|
|
3
|
+
from ..exceptions import (
|
|
4
|
+
CommandPermissionError,
|
|
5
|
+
DatasetNotFoundError,
|
|
6
|
+
DatasetPermissionError,
|
|
7
|
+
GetDatasetError,
|
|
8
|
+
ListDatasetsError,
|
|
9
|
+
CreateDatasetError,
|
|
10
|
+
DatasetAlreadyExistsError,
|
|
11
|
+
DeleteDatasetError,
|
|
12
|
+
OverwriteDatasetError,
|
|
13
|
+
)
|
|
14
|
+
from ..helper.decorators import require_api_key, require_auth, require_token
|
|
3
15
|
|
|
4
16
|
class DatasetManagement:
|
|
5
17
|
def __init__(self, client):
|
|
6
18
|
self._client = client
|
|
7
19
|
|
|
8
|
-
|
|
9
20
|
@require_api_key
|
|
10
|
-
def list_datasets(self, substring: Optional[str] = None
|
|
21
|
+
async def list_datasets(self, substring: Optional[str] = None) -> List[Dict[str, Any]]:
|
|
11
22
|
"""
|
|
12
23
|
List datasets, optionally filtering by a substring and collection.
|
|
13
24
|
|
|
14
25
|
Args:
|
|
15
26
|
substring: Substring to filter by (optional)
|
|
16
|
-
collection: Dataset collection (default: 'terrakio-datasets')
|
|
17
27
|
|
|
18
28
|
Returns:
|
|
19
29
|
List of datasets matching the criteria
|
|
20
30
|
"""
|
|
21
|
-
params = {"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
params = {"substring": substring} if substring else None
|
|
32
|
+
response, status = await self._client._terrakio_request("GET", "/datasets", params=params)
|
|
33
|
+
if status != 200:
|
|
34
|
+
raise ListDatasetsError(f"List datasets failed with status {status}", status_code=status)
|
|
35
|
+
return response
|
|
25
36
|
|
|
26
37
|
@require_api_key
|
|
27
|
-
def get_dataset(self, name: str
|
|
38
|
+
async def get_dataset(self, name: str) -> Dict[str, Any]:
|
|
28
39
|
"""
|
|
29
40
|
Retrieve dataset info by dataset name.
|
|
30
41
|
|
|
31
42
|
Args:
|
|
32
43
|
name: The name of the dataset (required)
|
|
33
|
-
collection: The dataset collection (default: 'terrakio-datasets')
|
|
34
44
|
|
|
35
45
|
Returns:
|
|
36
46
|
Dataset information as a dictionary
|
|
37
47
|
|
|
38
48
|
Raises:
|
|
39
|
-
|
|
49
|
+
GetDatasetError: If the API request fails
|
|
50
|
+
DatasetNotFoundError: If the dataset is not found
|
|
51
|
+
DatasetPermissionError: If the user does not have permission to get the dataset
|
|
40
52
|
"""
|
|
41
|
-
|
|
42
|
-
|
|
53
|
+
response, status = await self._client._terrakio_request("GET", f"/datasets/{name}")
|
|
54
|
+
if status != 200:
|
|
55
|
+
if status == 404:
|
|
56
|
+
raise DatasetNotFoundError(f"Dataset {name} not found", status_code = status)
|
|
57
|
+
if status == 403:
|
|
58
|
+
raise DatasetPermissionError(f"You do not have permission to get dataset {name}", status_code = status)
|
|
59
|
+
raise GetDatasetError(f"Get dataset failed with status {status}", status_code = status)
|
|
60
|
+
return response
|
|
43
61
|
|
|
44
62
|
@require_api_key
|
|
45
63
|
async def create_dataset(
|
|
46
64
|
self,
|
|
47
65
|
name: str,
|
|
48
|
-
collection: str = "terrakio-datasets",
|
|
49
66
|
products: Optional[List[str]] = None,
|
|
50
67
|
dates_iso8601: Optional[List[str]] = None,
|
|
51
68
|
bucket: Optional[str] = None,
|
|
@@ -67,7 +84,6 @@ class DatasetManagement:
|
|
|
67
84
|
|
|
68
85
|
Args:
|
|
69
86
|
name: Name of the dataset (required)
|
|
70
|
-
collection: Dataset collection (default: 'terrakio-datasets')
|
|
71
87
|
products: List of products
|
|
72
88
|
dates_iso8601: List of dates (will be automatically sorted chronologically)
|
|
73
89
|
bucket: Storage bucket
|
|
@@ -89,7 +105,6 @@ class DatasetManagement:
|
|
|
89
105
|
Raises:
|
|
90
106
|
APIError: If the API request fails
|
|
91
107
|
"""
|
|
92
|
-
params = {"collection": collection}
|
|
93
108
|
payload = {"name": name}
|
|
94
109
|
param_mapping = {
|
|
95
110
|
"products": products,
|
|
@@ -111,14 +126,42 @@ class DatasetManagement:
|
|
|
111
126
|
for param, value in param_mapping.items():
|
|
112
127
|
if value is not None:
|
|
113
128
|
payload[param] = value
|
|
114
|
-
|
|
115
|
-
|
|
129
|
+
response, status = await self._client._terrakio_request("POST", "/datasets", json = payload)
|
|
130
|
+
if status != 200:
|
|
131
|
+
if status ==403:
|
|
132
|
+
raise CommandPermissionError(f"You do not have permission to create dataset {name}", status_code = status)
|
|
133
|
+
elif status == 409:
|
|
134
|
+
raise DatasetAlreadyExistsError(f"Dataset {name} already exists", status_code = status)
|
|
135
|
+
raise CreateDatasetError(f"Create dataset failed with status {status}", status_code = status)
|
|
136
|
+
return response
|
|
137
|
+
|
|
138
|
+
@require_api_key
|
|
139
|
+
async def delete_dataset(self, name: str) -> Dict[str, Any]:
|
|
140
|
+
"""
|
|
141
|
+
Delete a dataset by name.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
name: The name of the dataset (required)
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
Deleted dataset information
|
|
148
|
+
|
|
149
|
+
Raises:
|
|
150
|
+
CommandPermissionError: If the user does not have permission to delete the dataset
|
|
151
|
+
DeleteDatasetError: If the API request fails
|
|
152
|
+
"""
|
|
153
|
+
response, status = await self._client._terrakio_request("DELETE", f"/datasets/{name}")
|
|
154
|
+
if status != 200:
|
|
155
|
+
if status == 403:
|
|
156
|
+
raise CommandPermissionError(f"You do not have permission to delete dataset {name}", status_code = status)
|
|
157
|
+
raise DeleteDatasetError(f"Delete dataset failed with status {status}", status_code = status)
|
|
158
|
+
return response
|
|
159
|
+
|
|
116
160
|
@require_api_key
|
|
117
161
|
def update_dataset(
|
|
118
162
|
self,
|
|
119
163
|
name: str,
|
|
120
164
|
append: bool = True,
|
|
121
|
-
collection: str = "terrakio-datasets",
|
|
122
165
|
products: Optional[List[str]] = None,
|
|
123
166
|
dates_iso8601: Optional[List[str]] = None,
|
|
124
167
|
bucket: Optional[str] = None,
|
|
@@ -140,7 +183,6 @@ class DatasetManagement:
|
|
|
140
183
|
Args:
|
|
141
184
|
name: Name of the dataset (required)
|
|
142
185
|
append: Whether to append data or replace (default: True)
|
|
143
|
-
collection: Dataset collection (default: 'terrakio-datasets')
|
|
144
186
|
products: List of products
|
|
145
187
|
dates_iso8601: List of dates (will be automatically sorted chronologically)
|
|
146
188
|
bucket: Storage bucket
|
|
@@ -162,11 +204,10 @@ class DatasetManagement:
|
|
|
162
204
|
Raises:
|
|
163
205
|
APIError: If the API request fails
|
|
164
206
|
"""
|
|
165
|
-
# Sort dates_iso8601 chronologically if provided
|
|
166
207
|
if dates_iso8601 is not None:
|
|
167
208
|
dates_iso8601 = sorted(dates_iso8601)
|
|
168
209
|
|
|
169
|
-
params = {"
|
|
210
|
+
params = {"append": str(append).lower()}
|
|
170
211
|
payload = {"name": name}
|
|
171
212
|
param_mapping = {
|
|
172
213
|
"products": products,
|
|
@@ -194,7 +235,6 @@ class DatasetManagement:
|
|
|
194
235
|
self,
|
|
195
236
|
name: str,
|
|
196
237
|
append: bool = True,
|
|
197
|
-
collection: str = "terrakio-datasets",
|
|
198
238
|
products: Optional[List[str]] = None,
|
|
199
239
|
dates_iso8601: Optional[List[str]] = None,
|
|
200
240
|
bucket: Optional[str] = None,
|
|
@@ -217,7 +257,6 @@ class DatasetManagement:
|
|
|
217
257
|
Args:
|
|
218
258
|
name: Name of the dataset (required)
|
|
219
259
|
append: Whether to append data or replace (default: True)
|
|
220
|
-
collection: Dataset collection (default: 'terrakio-datasets')
|
|
221
260
|
products: List of products
|
|
222
261
|
dates_iso8601: List of dates (will be automatically sorted chronologically)
|
|
223
262
|
bucket: Storage bucket
|
|
@@ -244,7 +283,7 @@ class DatasetManagement:
|
|
|
244
283
|
if dates_iso8601 is not None:
|
|
245
284
|
dates_iso8601 = sorted(dates_iso8601)
|
|
246
285
|
|
|
247
|
-
params = {"
|
|
286
|
+
params = {"append": str(append).lower()}
|
|
248
287
|
payload = {"name": name}
|
|
249
288
|
param_mapping = {
|
|
250
289
|
"products": products,
|
|
@@ -267,14 +306,55 @@ class DatasetManagement:
|
|
|
267
306
|
if value is not None:
|
|
268
307
|
payload[param] = value
|
|
269
308
|
return self._client._terrakio_request("PATCH", "/datasets", params = params, json = payload)
|
|
270
|
-
|
|
271
309
|
|
|
272
310
|
|
|
273
311
|
@require_api_key
|
|
274
|
-
def
|
|
312
|
+
async def _get_url_for_upload_inference_script(self, script_path: str) -> str:
|
|
313
|
+
"""
|
|
314
|
+
Get the url for the upload of the inference script
|
|
315
|
+
"""
|
|
316
|
+
# we have the path, and we just need to get the bucket name
|
|
317
|
+
payload = {
|
|
318
|
+
"script_path": script_path,
|
|
319
|
+
}
|
|
320
|
+
return await self._client._terrakio_request("POST", "models/update_inference_script", json = payload)
|
|
321
|
+
|
|
322
|
+
@require_api_key
|
|
323
|
+
async def update_virtual_dataset_inference(
|
|
324
|
+
self,
|
|
325
|
+
name: str,
|
|
326
|
+
inference_script_path: str,
|
|
327
|
+
append: bool = True,
|
|
328
|
+
):
|
|
329
|
+
"""
|
|
330
|
+
Update the inference script for a virtual dataset.
|
|
331
|
+
"""
|
|
332
|
+
params = {"append": str(append).lower()}
|
|
333
|
+
dataset_info = await self.get_dataset(name)
|
|
334
|
+
print("the current dataset info is: ", dataset_info)
|
|
335
|
+
script_path = dataset_info["path"]
|
|
336
|
+
product_name = dataset_info["products"][0]
|
|
337
|
+
script_path = script_path + f"/{product_name}.py"
|
|
338
|
+
upload_url_dict = await self._get_url_for_upload_inference_script(script_path)
|
|
339
|
+
upload_url = upload_url_dict["script_upload_url"]
|
|
340
|
+
try:
|
|
341
|
+
with open(inference_script_path, "r", encoding="utf-8") as f:
|
|
342
|
+
script_content = f.read()
|
|
343
|
+
script_bytes = script_content.encode('utf-8')
|
|
344
|
+
headers = {
|
|
345
|
+
"Content-Type": "text/x-python",
|
|
346
|
+
"Content-Length": str(len(script_bytes))
|
|
347
|
+
}
|
|
348
|
+
response = await self._client._regular_request("PUT", endpoint=upload_url, data=script_bytes, headers=headers)
|
|
349
|
+
except FileNotFoundError:
|
|
350
|
+
raise FileNotFoundError(f"Inference script file not found: {inference_script_path}")
|
|
351
|
+
except Exception as e:
|
|
352
|
+
raise Exception(f"Failed to upload inference script: {str(e)}")
|
|
353
|
+
|
|
354
|
+
@require_api_key
|
|
355
|
+
async def overwrite_dataset(
|
|
275
356
|
self,
|
|
276
357
|
name: str,
|
|
277
|
-
collection: str = "terrakio-datasets",
|
|
278
358
|
products: Optional[List[str]] = None,
|
|
279
359
|
dates_iso8601: Optional[List[str]] = None,
|
|
280
360
|
bucket: Optional[str] = None,
|
|
@@ -295,7 +375,6 @@ class DatasetManagement:
|
|
|
295
375
|
|
|
296
376
|
Args:
|
|
297
377
|
name: Name of the dataset (required)
|
|
298
|
-
collection: Dataset collection (default: 'terrakio-datasets')
|
|
299
378
|
products: List of products
|
|
300
379
|
dates_iso8601: List of dates (will be automatically sorted chronologically)
|
|
301
380
|
bucket: Storage bucket
|
|
@@ -315,9 +394,10 @@ class DatasetManagement:
|
|
|
315
394
|
Overwritten dataset information
|
|
316
395
|
|
|
317
396
|
Raises:
|
|
318
|
-
|
|
397
|
+
CommandPermissionError: If the user does not have permission to overwrite the dataset
|
|
398
|
+
DatasetNotFoundError: If the dataset is not found
|
|
399
|
+
OverwriteDatasetError: If the API request fails
|
|
319
400
|
"""
|
|
320
|
-
params = {"collection": collection}
|
|
321
401
|
payload = {"name": name}
|
|
322
402
|
param_mapping = {
|
|
323
403
|
"products": products,
|
|
@@ -338,25 +418,14 @@ class DatasetManagement:
|
|
|
338
418
|
for param, value in param_mapping.items():
|
|
339
419
|
if value is not None:
|
|
340
420
|
payload[param] = value
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
name: The name of the dataset (required)
|
|
350
|
-
collection: The dataset collection (default: 'terrakio-datasets')
|
|
351
|
-
|
|
352
|
-
Returns:
|
|
353
|
-
Deleted dataset information
|
|
354
|
-
|
|
355
|
-
Raises:
|
|
356
|
-
APIError: If the API request fails
|
|
357
|
-
"""
|
|
358
|
-
params = {"collection": collection}
|
|
359
|
-
return self._client._terrakio_request("DELETE", f"/datasets/{name}", params = params)
|
|
421
|
+
response, status = await self._client._terrakio_request("PUT", "/datasets", json = payload)
|
|
422
|
+
if status != 200:
|
|
423
|
+
if status == 403:
|
|
424
|
+
raise CommandPermissionError(f"You do not have permission to overwrite dataset {name}", status_code = status)
|
|
425
|
+
elif status == 404:
|
|
426
|
+
raise DatasetNotFoundError(f"Dataset {name} not found", status_code = status)
|
|
427
|
+
raise OverwriteDatasetError(f"Failed to overwrite dataset: {response}", status_code = status)
|
|
428
|
+
return response
|
|
360
429
|
|
|
361
430
|
@require_api_key
|
|
362
431
|
def download_file_to_path(self, job_name, stage, file_name, output_path):
|
|
@@ -370,9 +439,6 @@ class DatasetManagement:
|
|
|
370
439
|
verify=self.verify,
|
|
371
440
|
timeout=self.timeout
|
|
372
441
|
)
|
|
373
|
-
|
|
374
|
-
# fetch bucket info based on job name and stage
|
|
375
|
-
|
|
376
442
|
taskid = self.mass_stats.get_task_id(job_name, stage).get('task_id')
|
|
377
443
|
trackinfo = self.mass_stats.track_job([taskid])
|
|
378
444
|
bucket = trackinfo[taskid]['bucket']
|