terrakio-core 0.2.3__py3-none-any.whl → 0.2.4__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 +0 -0
- terrakio_core/auth.py +238 -0
- terrakio_core/client.py +1005 -0
- terrakio_core/config.py +81 -0
- terrakio_core/dataset_management.py +235 -0
- terrakio_core/exceptions.py +18 -0
- terrakio_core/group_access_management.py +232 -0
- terrakio_core/mass_stats.py +262 -0
- terrakio_core/space_management.py +101 -0
- terrakio_core/user_management.py +227 -0
- {terrakio_core-0.2.3.dist-info → terrakio_core-0.2.4.dist-info}/METADATA +1 -1
- terrakio_core-0.2.4.dist-info/RECORD +14 -0
- terrakio_core-0.2.4.dist-info/top_level.txt +1 -0
- terrakio_core-0.2.3.dist-info/RECORD +0 -4
- terrakio_core-0.2.3.dist-info/top_level.txt +0 -1
- {terrakio_core-0.2.3.dist-info → terrakio_core-0.2.4.dist-info}/WHEEL +0 -0
terrakio_core/config.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import json
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Dict, Any, Optional
|
|
5
|
+
|
|
6
|
+
from .exceptions import ConfigurationError
|
|
7
|
+
|
|
8
|
+
# Default configuration file locations
|
|
9
|
+
DEFAULT_CONFIG_FILE = os.path.join(os.environ.get("HOME", ""), ".tkio_config.json")
|
|
10
|
+
DEFAULT_API_URL = "https://api.terrak.io"
|
|
11
|
+
|
|
12
|
+
def read_config_file(config_file: str = DEFAULT_CONFIG_FILE) -> Dict[str, Any]:
|
|
13
|
+
"""
|
|
14
|
+
Read and parse the configuration file.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
config_file: Path to the configuration file
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
Dict[str, Any]: Configuration parameters
|
|
21
|
+
|
|
22
|
+
Raises:
|
|
23
|
+
ConfigurationError: If the configuration file can't be read or parsed
|
|
24
|
+
"""
|
|
25
|
+
config_path = Path(os.path.expanduser(config_file))
|
|
26
|
+
|
|
27
|
+
if not config_path.exists():
|
|
28
|
+
raise ConfigurationError(
|
|
29
|
+
f"Configuration file not found: {config_file}\n"
|
|
30
|
+
f"Please create a file at {config_file} with the following format:\n"
|
|
31
|
+
'{\n "EMAIL": "your-email@example.com",\n "TERRAKIO_API_KEY": "your-api-key-here"\n}'
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
with open(config_path, 'r') as f:
|
|
36
|
+
config_data = json.load(f)
|
|
37
|
+
|
|
38
|
+
# Convert the JSON config to our expected format
|
|
39
|
+
config = {
|
|
40
|
+
# Allow config to override default URL if provided
|
|
41
|
+
'url': config_data.get('TERRAKIO_API_URL', DEFAULT_API_URL),
|
|
42
|
+
'key': config_data.get('TERRAKIO_API_KEY')
|
|
43
|
+
}
|
|
44
|
+
return config
|
|
45
|
+
|
|
46
|
+
except Exception as e:
|
|
47
|
+
raise ConfigurationError(f"Failed to parse configuration file: {e}")
|
|
48
|
+
|
|
49
|
+
def create_default_config(email: str, api_key: str, api_url: Optional[str] = None, config_file: str = DEFAULT_CONFIG_FILE) -> None:
|
|
50
|
+
"""
|
|
51
|
+
Create a default configuration file in JSON format.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
email: User email
|
|
55
|
+
api_key: Terrakio API key
|
|
56
|
+
api_url: Optional API URL (if different from default)
|
|
57
|
+
config_file: Path to configuration file
|
|
58
|
+
|
|
59
|
+
Raises:
|
|
60
|
+
ConfigurationError: If the configuration file can't be created
|
|
61
|
+
"""
|
|
62
|
+
config_path = Path(os.path.expanduser(config_file))
|
|
63
|
+
|
|
64
|
+
# Ensure directory exists
|
|
65
|
+
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
66
|
+
|
|
67
|
+
try:
|
|
68
|
+
config_data = {
|
|
69
|
+
"EMAIL": email,
|
|
70
|
+
"TERRAKIO_API_KEY": api_key
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
# Add API URL if provided
|
|
74
|
+
if api_url:
|
|
75
|
+
config_data["TERRAKIO_API_URL"] = api_url
|
|
76
|
+
|
|
77
|
+
with open(config_path, 'w') as f:
|
|
78
|
+
json.dump(config_data, f, indent=2)
|
|
79
|
+
|
|
80
|
+
except Exception as e:
|
|
81
|
+
raise ConfigurationError(f"Failed to create configuration file: {e}")
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from typing import Dict, Any, List, Optional
|
|
3
|
+
from .exceptions import APIError
|
|
4
|
+
|
|
5
|
+
class DatasetManagement:
|
|
6
|
+
def __init__(self, api_url: str, api_key: str, verify: bool = True, timeout: int = 60):
|
|
7
|
+
"""
|
|
8
|
+
Initialize the Dataset Management client.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
api_url: API base URL
|
|
12
|
+
api_key: API key for authentication
|
|
13
|
+
verify: Verify SSL certificates
|
|
14
|
+
timeout: Request timeout in seconds
|
|
15
|
+
"""
|
|
16
|
+
self.api_url = api_url.rstrip('/')
|
|
17
|
+
self.api_key = api_key
|
|
18
|
+
self.verify = verify
|
|
19
|
+
self.timeout = timeout
|
|
20
|
+
self.session = requests.Session()
|
|
21
|
+
self.session.headers.update({
|
|
22
|
+
'x-api-key': self.api_key,
|
|
23
|
+
'Content-Type': 'application/json'
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
def get_dataset(self, name: str, collection: str = "terrakio-datasets") -> Dict[str, Any]:
|
|
27
|
+
"""
|
|
28
|
+
Retrieve dataset info by dataset name.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
name: The name of the dataset (required)
|
|
32
|
+
collection: The dataset collection (default: 'terrakio-datasets')
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
Dataset information as a dictionary
|
|
36
|
+
|
|
37
|
+
Raises:
|
|
38
|
+
APIError: If the API request fails
|
|
39
|
+
"""
|
|
40
|
+
endpoint = f"{self.api_url}/datasets/{name}"
|
|
41
|
+
params = {"collection": collection} if collection else {}
|
|
42
|
+
try:
|
|
43
|
+
response = self.session.get(
|
|
44
|
+
endpoint,
|
|
45
|
+
params=params,
|
|
46
|
+
timeout=self.timeout,
|
|
47
|
+
verify=self.verify
|
|
48
|
+
)
|
|
49
|
+
if not response.ok:
|
|
50
|
+
raise APIError(f"API request failed: {response.status_code} {response.reason}")
|
|
51
|
+
return response.json()
|
|
52
|
+
except requests.RequestException as e:
|
|
53
|
+
raise APIError(f"Request failed: {str(e)}")
|
|
54
|
+
|
|
55
|
+
def list_datasets(self, substring: Optional[str] = None, collection: str = "terrakio-datasets") -> List[Dict[str, Any]]:
|
|
56
|
+
"""
|
|
57
|
+
List datasets, optionally filtering by a substring and collection.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
substring: Substring to filter by (optional)
|
|
61
|
+
collection: Dataset collection (default: 'terrakio-datasets')
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
List of datasets matching the criteria
|
|
65
|
+
|
|
66
|
+
Raises:
|
|
67
|
+
APIError: If the API request fails
|
|
68
|
+
"""
|
|
69
|
+
endpoint = f"{self.api_url}/datasets"
|
|
70
|
+
params = {"collection": collection}
|
|
71
|
+
if substring:
|
|
72
|
+
params["substring"] = substring
|
|
73
|
+
try:
|
|
74
|
+
response = self.session.get(
|
|
75
|
+
endpoint,
|
|
76
|
+
params=params,
|
|
77
|
+
timeout=self.timeout,
|
|
78
|
+
verify=self.verify
|
|
79
|
+
)
|
|
80
|
+
if not response.ok:
|
|
81
|
+
raise APIError(f"API request failed: {response.status_code} {response.reason}")
|
|
82
|
+
return response.json()
|
|
83
|
+
except requests.RequestException as e:
|
|
84
|
+
raise APIError(f"Request failed: {str(e)}")
|
|
85
|
+
|
|
86
|
+
def create_dataset(self, name: str, collection: str = "terrakio-datasets", **kwargs) -> Dict[str, Any]:
|
|
87
|
+
"""
|
|
88
|
+
Create a new dataset.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
name: Name of the dataset (required)
|
|
92
|
+
collection: Dataset collection (default: 'terrakio-datasets')
|
|
93
|
+
**kwargs: Additional dataset parameters including:
|
|
94
|
+
- products: List of products
|
|
95
|
+
- dates_iso8601: List of dates
|
|
96
|
+
- bucket: Storage bucket
|
|
97
|
+
- path: Storage path
|
|
98
|
+
- data_type: Data type
|
|
99
|
+
- no_data: No data value
|
|
100
|
+
- l_max: Maximum level
|
|
101
|
+
- y_size: Y size
|
|
102
|
+
- x_size: X size
|
|
103
|
+
- proj4: Projection string
|
|
104
|
+
- abstract: Dataset abstract
|
|
105
|
+
- geotransform: Geotransform parameters
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
Created dataset information
|
|
109
|
+
|
|
110
|
+
Raises:
|
|
111
|
+
APIError: If the API request fails
|
|
112
|
+
"""
|
|
113
|
+
endpoint = f"{self.api_url}/datasets"
|
|
114
|
+
params = {"collection": collection}
|
|
115
|
+
# Create payload with required name parameter
|
|
116
|
+
payload = {"name": name}
|
|
117
|
+
|
|
118
|
+
# Add optional parameters if provided
|
|
119
|
+
for param in ["products", "dates_iso8601", "bucket", "path", "data_type",
|
|
120
|
+
"no_data", "l_max", "y_size", "x_size", "proj4", "abstract", "geotransform"]:
|
|
121
|
+
if param in kwargs:
|
|
122
|
+
payload[param] = kwargs[param]
|
|
123
|
+
|
|
124
|
+
try:
|
|
125
|
+
response = self.session.post(
|
|
126
|
+
endpoint,
|
|
127
|
+
params=params,
|
|
128
|
+
json=payload,
|
|
129
|
+
timeout=self.timeout,
|
|
130
|
+
verify=self.verify
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
if not response.ok:
|
|
134
|
+
raise APIError(f"API request failed: {response.status_code} {response.reason}")
|
|
135
|
+
return response.json()
|
|
136
|
+
except requests.RequestException as e:
|
|
137
|
+
raise APIError(f"Request failed: {str(e)}")
|
|
138
|
+
|
|
139
|
+
def update_dataset(self, name: str, append: bool = True, collection: str = "terrakio-datasets", **kwargs) -> Dict[str, Any]:
|
|
140
|
+
"""
|
|
141
|
+
Update a dataset. By default, values are appended unless append is set to False.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
name: Name of the dataset (required)
|
|
145
|
+
append: Whether to append values (default: True)
|
|
146
|
+
collection: Dataset collection (default: 'terrakio-datasets')
|
|
147
|
+
**kwargs: Additional dataset parameters to update
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
Updated dataset information
|
|
151
|
+
|
|
152
|
+
Raises:
|
|
153
|
+
APIError: If the API request fails
|
|
154
|
+
"""
|
|
155
|
+
endpoint = f"{self.api_url}/datasets"
|
|
156
|
+
params = {"append": str(append).lower(), "collection": collection}
|
|
157
|
+
payload = {"name": name}
|
|
158
|
+
payload.update(kwargs)
|
|
159
|
+
try:
|
|
160
|
+
response = self.session.patch(
|
|
161
|
+
endpoint,
|
|
162
|
+
params=params,
|
|
163
|
+
json=payload,
|
|
164
|
+
timeout=self.timeout,
|
|
165
|
+
verify=self.verify
|
|
166
|
+
)
|
|
167
|
+
if not response.ok:
|
|
168
|
+
raise APIError(f"API request failed: {response.status_code} {response.reason}")
|
|
169
|
+
return response.json()
|
|
170
|
+
except requests.RequestException as e:
|
|
171
|
+
raise APIError(f"Request failed: {str(e)}")
|
|
172
|
+
|
|
173
|
+
def overwrite_dataset(self, name: str, collection: str = "terrakio-datasets", **kwargs) -> Dict[str, Any]:
|
|
174
|
+
"""
|
|
175
|
+
Overwrite a dataset (replace all values).
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
name: Name of the dataset (required)
|
|
179
|
+
collection: Dataset collection (default: 'terrakio-datasets')
|
|
180
|
+
**kwargs: New dataset parameters
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
Updated dataset information
|
|
184
|
+
|
|
185
|
+
Raises:
|
|
186
|
+
APIError: If the API request fails
|
|
187
|
+
"""
|
|
188
|
+
endpoint = f"{self.api_url}/datasets"
|
|
189
|
+
params = {"collection": collection}
|
|
190
|
+
payload = {"name": name}
|
|
191
|
+
payload.update(kwargs)
|
|
192
|
+
try:
|
|
193
|
+
response = self.session.put(
|
|
194
|
+
endpoint,
|
|
195
|
+
params=params,
|
|
196
|
+
json=payload,
|
|
197
|
+
timeout=self.timeout,
|
|
198
|
+
verify=self.verify
|
|
199
|
+
)
|
|
200
|
+
if not response.ok:
|
|
201
|
+
raise APIError(f"API request failed: {response.status_code} {response.reason}")
|
|
202
|
+
return response.json()
|
|
203
|
+
except requests.RequestException as e:
|
|
204
|
+
raise APIError(f"Request failed: {str(e)}")
|
|
205
|
+
|
|
206
|
+
def delete_dataset(self, name: str, collection: str = "terrakio-datasets") -> Dict[str, Any]:
|
|
207
|
+
"""
|
|
208
|
+
Delete a dataset by name.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
name: The name of the dataset (required)
|
|
212
|
+
collection: Dataset collection (default: 'terrakio-datasets')
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
API response as a dictionary
|
|
216
|
+
|
|
217
|
+
Raises:
|
|
218
|
+
APIError: If the API request fails
|
|
219
|
+
"""
|
|
220
|
+
endpoint = f"{self.api_url}/datasets/{name}"
|
|
221
|
+
params = {"collection": collection}
|
|
222
|
+
try:
|
|
223
|
+
response = self.session.delete(
|
|
224
|
+
endpoint,
|
|
225
|
+
params=params,
|
|
226
|
+
timeout=self.timeout,
|
|
227
|
+
verify=self.verify
|
|
228
|
+
)
|
|
229
|
+
if response.status_code == 404:
|
|
230
|
+
return {"status": "error", "message": f"Dataset '{name}' does not exist in collection '{collection}'"}
|
|
231
|
+
if not response.ok:
|
|
232
|
+
raise APIError(f"API request failed: {response.status_code} {response.reason}")
|
|
233
|
+
return response.json()
|
|
234
|
+
except requests.RequestException as e:
|
|
235
|
+
raise APIError(f"Request failed: {str(e)}")
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class APIError(Exception):
|
|
2
|
+
"""Exception raised for errors in the API responses."""
|
|
3
|
+
pass
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ConfigurationError(Exception):
|
|
7
|
+
"""Exception raised for errors in the configuration."""
|
|
8
|
+
pass
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DownloadError(Exception):
|
|
12
|
+
"""Exception raised for errors during data download."""
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ValidationError(Exception):
|
|
17
|
+
"""Exception raised for invalid request parameters."""
|
|
18
|
+
pass
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from typing import Dict, Any, List
|
|
3
|
+
from .exceptions import APIError
|
|
4
|
+
|
|
5
|
+
class GroupAccessManagement:
|
|
6
|
+
def __init__(self, api_url: str, api_key: str, verify: bool = True, timeout: int = 60):
|
|
7
|
+
"""
|
|
8
|
+
Initialize the Group Access Management client.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
api_url: API base URL
|
|
12
|
+
api_key: API key for authentication
|
|
13
|
+
verify: Verify SSL certificates
|
|
14
|
+
timeout: Request timeout in seconds
|
|
15
|
+
"""
|
|
16
|
+
self.api_url = api_url.rstrip('/')
|
|
17
|
+
self.api_key = api_key
|
|
18
|
+
self.verify = verify
|
|
19
|
+
self.timeout = timeout
|
|
20
|
+
self.session = requests.Session()
|
|
21
|
+
self.session.headers.update({
|
|
22
|
+
'x-api-key': self.api_key,
|
|
23
|
+
'Content-Type': 'application/json'
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
def get_group_users_and_datasets(self, group_name: str) -> Dict[str, Any]:
|
|
27
|
+
"""
|
|
28
|
+
Get users and datasets of a group.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
group_name: Name of the group
|
|
32
|
+
|
|
33
|
+
Returns:
|
|
34
|
+
Dictionary containing lists of users and datasets associated with the group
|
|
35
|
+
{
|
|
36
|
+
"users": [UID, ...],
|
|
37
|
+
"datasets": [DATASET_NAME, ...]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
Raises:
|
|
41
|
+
APIError: If the API request fails
|
|
42
|
+
"""
|
|
43
|
+
endpoint = f"https://dev-au.terrak.io/groups/{group_name}"
|
|
44
|
+
print("the endpoint is ", endpoint)
|
|
45
|
+
print
|
|
46
|
+
try:
|
|
47
|
+
response = self.session.get(
|
|
48
|
+
endpoint,
|
|
49
|
+
timeout=self.timeout,
|
|
50
|
+
verify=self.verify
|
|
51
|
+
)
|
|
52
|
+
print("the response is ", response.text)
|
|
53
|
+
if not response.ok:
|
|
54
|
+
error_msg = f"API request failed: {response.status_code} {response.reason}"
|
|
55
|
+
try:
|
|
56
|
+
error_data = response.json()
|
|
57
|
+
if "detail" in error_data:
|
|
58
|
+
error_msg += f" - {error_data['detail']}"
|
|
59
|
+
except:
|
|
60
|
+
pass
|
|
61
|
+
raise APIError(error_msg)
|
|
62
|
+
|
|
63
|
+
return response.json()
|
|
64
|
+
|
|
65
|
+
except requests.RequestException as e:
|
|
66
|
+
raise APIError(f"Request failed: {str(e)}")
|
|
67
|
+
|
|
68
|
+
def add_group_to_dataset(self, dataset: str, group: str) -> Dict[str, Any]:
|
|
69
|
+
"""
|
|
70
|
+
Add a group to a dataset.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
dataset: Name of the dataset
|
|
74
|
+
group: Name of the group to add to the dataset
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
API response data
|
|
78
|
+
|
|
79
|
+
Raises:
|
|
80
|
+
APIError: If the API request fails
|
|
81
|
+
"""
|
|
82
|
+
endpoint = f"{self.api_url}/groups/dataset/{dataset}"
|
|
83
|
+
print("hello")
|
|
84
|
+
print("the endpoint is ", endpoint)
|
|
85
|
+
params = {"group": group}
|
|
86
|
+
print("the endpoint is ", endpoint)
|
|
87
|
+
print("!!!!!!!!!!!")
|
|
88
|
+
print("the params are ", params)
|
|
89
|
+
try:
|
|
90
|
+
response = self.session.post(
|
|
91
|
+
endpoint,
|
|
92
|
+
params=params,
|
|
93
|
+
timeout=self.timeout,
|
|
94
|
+
verify=self.verify
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
if not response.ok:
|
|
98
|
+
error_msg = f"API request failed: {response.status_code} {response.reason}"
|
|
99
|
+
try:
|
|
100
|
+
error_data = response.json()
|
|
101
|
+
if "detail" in error_data:
|
|
102
|
+
error_msg += f" - {error_data['detail']}"
|
|
103
|
+
except:
|
|
104
|
+
pass
|
|
105
|
+
raise APIError(error_msg)
|
|
106
|
+
|
|
107
|
+
return response.json()
|
|
108
|
+
|
|
109
|
+
except requests.RequestException as e:
|
|
110
|
+
raise APIError(f"Request failed: {str(e)}")
|
|
111
|
+
|
|
112
|
+
def add_group_to_user(self, uid: str, group: str) -> Dict[str, Any]:
|
|
113
|
+
"""
|
|
114
|
+
Add a group to a user.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
uid: User UID
|
|
118
|
+
group: Name of the group to add to the user
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
API response data
|
|
122
|
+
|
|
123
|
+
Raises:
|
|
124
|
+
APIError: If the API request fails
|
|
125
|
+
"""
|
|
126
|
+
endpoint = f"{self.api_url}/groups/users/{uid}"
|
|
127
|
+
params = {"group": group}
|
|
128
|
+
print("the endpoint is ", endpoint)
|
|
129
|
+
print("the params are ", params)
|
|
130
|
+
try:
|
|
131
|
+
response = self.session.post(
|
|
132
|
+
endpoint,
|
|
133
|
+
params=params,
|
|
134
|
+
timeout=self.timeout,
|
|
135
|
+
verify=self.verify
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
if not response.ok:
|
|
139
|
+
error_msg = f"API request failed: {response.status_code} {response.reason}"
|
|
140
|
+
try:
|
|
141
|
+
error_data = response.json()
|
|
142
|
+
if "detail" in error_data:
|
|
143
|
+
error_msg += f" - {error_data['detail']}"
|
|
144
|
+
except:
|
|
145
|
+
pass
|
|
146
|
+
raise APIError(error_msg)
|
|
147
|
+
|
|
148
|
+
return response.json()
|
|
149
|
+
|
|
150
|
+
except requests.RequestException as e:
|
|
151
|
+
raise APIError(f"Request failed: {str(e)}")
|
|
152
|
+
|
|
153
|
+
def delete_group_from_user(self, uid: str, group: str) -> Dict[str, Any]:
|
|
154
|
+
"""
|
|
155
|
+
Delete a group from a user.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
uid: User UID
|
|
159
|
+
group: Name of the group to remove from the user
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
API response data
|
|
163
|
+
|
|
164
|
+
Raises:
|
|
165
|
+
APIError: If the API request fails
|
|
166
|
+
"""
|
|
167
|
+
endpoint = f"{self.api_url}/groups/users/{uid}"
|
|
168
|
+
params = {"group": group}
|
|
169
|
+
|
|
170
|
+
try:
|
|
171
|
+
response = self.session.delete(
|
|
172
|
+
endpoint,
|
|
173
|
+
params=params,
|
|
174
|
+
timeout=self.timeout,
|
|
175
|
+
verify=self.verify
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
if not response.ok:
|
|
179
|
+
error_msg = f"API request failed: {response.status_code} {response.reason}"
|
|
180
|
+
try:
|
|
181
|
+
error_data = response.json()
|
|
182
|
+
if "detail" in error_data:
|
|
183
|
+
error_msg += f" - {error_data['detail']}"
|
|
184
|
+
except:
|
|
185
|
+
pass
|
|
186
|
+
raise APIError(error_msg)
|
|
187
|
+
|
|
188
|
+
return response.json()
|
|
189
|
+
|
|
190
|
+
except requests.RequestException as e:
|
|
191
|
+
raise APIError(f"Request failed: {str(e)}")
|
|
192
|
+
|
|
193
|
+
def delete_group_from_dataset(self, dataset: str, group: str) -> Dict[str, Any]:
|
|
194
|
+
"""
|
|
195
|
+
Delete a group from a dataset.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
dataset: Name of the dataset
|
|
199
|
+
group: Name of the group to remove from the dataset
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
API response data
|
|
203
|
+
|
|
204
|
+
Raises:
|
|
205
|
+
APIError: If the API request fails
|
|
206
|
+
"""
|
|
207
|
+
endpoint = f"{self.api_url}/groups/datasets/{dataset}"
|
|
208
|
+
params = {"group": group}
|
|
209
|
+
|
|
210
|
+
try:
|
|
211
|
+
response = self.session.delete(
|
|
212
|
+
endpoint,
|
|
213
|
+
params=params,
|
|
214
|
+
timeout=self.timeout,
|
|
215
|
+
verify=self.verify
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
if not response.ok:
|
|
219
|
+
error_msg = f"API request failed: {response.status_code} {response.reason}"
|
|
220
|
+
try:
|
|
221
|
+
error_data = response.json()
|
|
222
|
+
if "detail" in error_data:
|
|
223
|
+
error_msg += f" - {error_data['detail']}"
|
|
224
|
+
except:
|
|
225
|
+
pass
|
|
226
|
+
raise APIError(error_msg)
|
|
227
|
+
|
|
228
|
+
return response.json()
|
|
229
|
+
|
|
230
|
+
except requests.RequestException as e:
|
|
231
|
+
raise APIError(f"Request failed: {str(e)}")
|
|
232
|
+
|