geobox 2.1.0__py3-none-any.whl → 2.2.1__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.
- geobox/__init__.py +61 -63
- geobox/aio/__init__.py +61 -63
- geobox/aio/api.py +491 -574
- geobox/aio/apikey.py +263 -263
- geobox/aio/attachment.py +341 -339
- geobox/aio/base.py +261 -262
- geobox/aio/basemap.py +196 -196
- geobox/aio/dashboard.py +340 -342
- geobox/aio/feature.py +35 -35
- geobox/aio/field.py +315 -321
- geobox/aio/file.py +72 -72
- geobox/aio/layout.py +340 -341
- geobox/aio/log.py +23 -23
- geobox/aio/map.py +1033 -1034
- geobox/aio/model3d.py +415 -415
- geobox/aio/mosaic.py +696 -696
- geobox/aio/plan.py +314 -314
- geobox/aio/query.py +693 -693
- geobox/aio/raster.py +88 -454
- geobox/aio/{analysis.py → raster_analysis.py} +153 -170
- geobox/aio/route.py +4 -4
- geobox/aio/scene.py +340 -342
- geobox/aio/settings.py +18 -18
- geobox/aio/task.py +404 -402
- geobox/aio/tile3d.py +337 -339
- geobox/aio/tileset.py +102 -103
- geobox/aio/usage.py +52 -51
- geobox/aio/user.py +506 -507
- geobox/aio/vector_tool.py +1968 -0
- geobox/aio/vectorlayer.py +316 -414
- geobox/aio/version.py +272 -273
- geobox/aio/view.py +1019 -983
- geobox/aio/workflow.py +340 -341
- geobox/api.py +14 -98
- geobox/apikey.py +262 -262
- geobox/attachment.py +336 -337
- geobox/base.py +384 -384
- geobox/basemap.py +194 -194
- geobox/dashboard.py +339 -341
- geobox/enums.py +31 -1
- geobox/feature.py +31 -10
- geobox/field.py +320 -320
- geobox/file.py +4 -4
- geobox/layout.py +339 -340
- geobox/log.py +4 -4
- geobox/map.py +1031 -1032
- geobox/model3d.py +410 -410
- geobox/mosaic.py +696 -696
- geobox/plan.py +313 -313
- geobox/query.py +691 -691
- geobox/raster.py +5 -368
- geobox/{analysis.py → raster_analysis.py} +108 -128
- geobox/scene.py +341 -342
- geobox/settings.py +194 -194
- geobox/task.py +399 -400
- geobox/tile3d.py +337 -338
- geobox/tileset.py +4 -4
- geobox/usage.py +3 -3
- geobox/user.py +503 -503
- geobox/vector_tool.py +1968 -0
- geobox/vectorlayer.py +5 -110
- geobox/version.py +272 -272
- geobox/view.py +981 -981
- geobox/workflow.py +338 -339
- {geobox-2.1.0.dist-info → geobox-2.2.1.dist-info}/METADATA +15 -1
- geobox-2.2.1.dist-info/RECORD +72 -0
- geobox-2.1.0.dist-info/RECORD +0 -70
- {geobox-2.1.0.dist-info → geobox-2.2.1.dist-info}/WHEEL +0 -0
- {geobox-2.1.0.dist-info → geobox-2.2.1.dist-info}/licenses/LICENSE +0 -0
- {geobox-2.1.0.dist-info → geobox-2.2.1.dist-info}/top_level.txt +0 -0
geobox/aio/base.py
CHANGED
|
@@ -1,262 +1,261 @@
|
|
|
1
|
-
from typing import
|
|
2
|
-
from urllib.parse import urljoin, urlencode
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
from ..
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
from .
|
|
10
|
-
from .
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
response
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
"""
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
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
|
-
result = [await self.api.get_task(
|
|
204
|
-
elif len(response) ==
|
|
205
|
-
result = [await self.api.get_task(
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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
|
-
return await self._get_task(response, 'Failed to update cache')
|
|
1
|
+
from typing import List, Dict, Callable, TYPE_CHECKING, Union
|
|
2
|
+
from urllib.parse import urljoin, urlencode
|
|
3
|
+
|
|
4
|
+
from ..utils import clean_data
|
|
5
|
+
from ..base import Base
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from .user import AsyncUser
|
|
9
|
+
from .task import AsyncTask
|
|
10
|
+
from . import AsyncGeoboxClient
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AsyncBase(Base):
|
|
14
|
+
BASE_ENDPOINT = ''
|
|
15
|
+
|
|
16
|
+
def __init__(self, api, **kwargs):
|
|
17
|
+
"""
|
|
18
|
+
Initialize the Base class.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
api (AsyncGeoboxClient): The AsyncGeoboxClient client
|
|
22
|
+
uuid (str, optional): The UUID of the resource
|
|
23
|
+
data (dict, optional): The data of the resource
|
|
24
|
+
"""
|
|
25
|
+
super().__init__(api, **kwargs)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
async def _get_list(cls, api: 'AsyncGeoboxClient', endpoint: str, params: dict = {}, factory_func: Callable = None, geojson: bool = False) -> Union[List['Base'], int]:
|
|
30
|
+
"""Get a list of resources with optional filtering and pagination"""
|
|
31
|
+
query_string = urlencode(clean_data(params)) if params else ''
|
|
32
|
+
endpoint = urljoin(endpoint, f'?{query_string}')
|
|
33
|
+
response = await api.get(endpoint)
|
|
34
|
+
|
|
35
|
+
if params.get('return_count'):
|
|
36
|
+
return cls._get_count(response)
|
|
37
|
+
|
|
38
|
+
if not response:
|
|
39
|
+
return []
|
|
40
|
+
|
|
41
|
+
if geojson:
|
|
42
|
+
return cls._handle_geojson_response(api, response, factory_func)
|
|
43
|
+
|
|
44
|
+
return [factory_func(api, item) for item in response]
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@classmethod
|
|
48
|
+
async def _get_list_by_ids(cls, api: 'AsyncGeoboxClient', endpoint: str, params: dict = None, factory_func: Callable = None) -> List['Base']:
|
|
49
|
+
"""
|
|
50
|
+
Internal method to get a list of resources by their IDs.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
api (AsyncGeoboxClient): The AsyncGeoboxClient client
|
|
54
|
+
endpoint (str): The endpoint of the resource
|
|
55
|
+
params (dict): Additional parameters for filtering and pagination
|
|
56
|
+
factory_func (Callable): A function to create the resource object
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
List[Base]: The list of resource objects
|
|
60
|
+
"""
|
|
61
|
+
params = clean_data(params)
|
|
62
|
+
query_string = urlencode(params)
|
|
63
|
+
endpoint = urljoin(endpoint, f'?{query_string}')
|
|
64
|
+
response = await api.get(endpoint)
|
|
65
|
+
return [factory_func(api, item) for item in response]
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@classmethod
|
|
69
|
+
async def _get_detail(cls, api: 'AsyncGeoboxClient', endpoint: str, uuid: str, params: dict = {}, factory_func: Callable = None) -> 'Base':
|
|
70
|
+
"""
|
|
71
|
+
Internal method to get a single resource by UUID.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
api (AsyncGeoboxClient): The AsyncGeoboxClient client
|
|
75
|
+
uuid (str): The UUID of the resource
|
|
76
|
+
params (dict): Additional parameters for filtering and pagination
|
|
77
|
+
factory_func (Callable): A function to create the resource object
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
Base: The resource object
|
|
81
|
+
"""
|
|
82
|
+
query_strings = urlencode(clean_data(params))
|
|
83
|
+
endpoint = urljoin(endpoint, f'{uuid}/?{query_strings}')
|
|
84
|
+
response = await api.get(endpoint)
|
|
85
|
+
return factory_func(api, response)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@classmethod
|
|
89
|
+
async def _create(cls, api: 'AsyncGeoboxClient', endpoint: str, data: dict, factory_func: Callable = None) -> 'Base':
|
|
90
|
+
"""
|
|
91
|
+
Internal method to create a resource.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
api (AsyncGeoboxClient): The AsyncGeoboxClient client
|
|
95
|
+
data (dict): The data to create the resource with
|
|
96
|
+
factory_func (Callable): A function to create the resource object
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Base: The created resource object
|
|
100
|
+
"""
|
|
101
|
+
data = clean_data(data)
|
|
102
|
+
response = await api.post(endpoint, data)
|
|
103
|
+
return factory_func(api, response)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
async def _update(self, endpoint: str, data: dict, clean: bool = True) -> Dict:
|
|
107
|
+
"""
|
|
108
|
+
Update the resource.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
data (dict): The data to update the resource with
|
|
112
|
+
"""
|
|
113
|
+
if clean:
|
|
114
|
+
data = clean_data(data)
|
|
115
|
+
|
|
116
|
+
response = await self.api.put(endpoint, data)
|
|
117
|
+
self._update_properties(response)
|
|
118
|
+
return response
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
async def _delete(self, endpoint: str) -> None:
|
|
122
|
+
"""
|
|
123
|
+
Delete the resource.
|
|
124
|
+
"""
|
|
125
|
+
await self.api.delete(endpoint)
|
|
126
|
+
self.uuid = None
|
|
127
|
+
self.endpoint = None
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
async def _share(self, endpoint: str, users: List['AsyncUser']) -> None:
|
|
131
|
+
"""
|
|
132
|
+
Internal method to share the resource with the given user IDs.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
users (List[AsyncUser]): The user objects to share the resource with
|
|
136
|
+
"""
|
|
137
|
+
data = {"user_ids": [user.user_id for user in users]}
|
|
138
|
+
endpoint = urljoin(endpoint, f'share/')
|
|
139
|
+
await self.api.post(endpoint, data, is_json=False)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
async def _unshare(self, endpoint: str, users: List['AsyncUser']) -> None:
|
|
143
|
+
"""
|
|
144
|
+
Internal method to unshare the resource with the given user IDs.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
users (List[AsyncUser]): The user objects to unshare the resource with
|
|
148
|
+
"""
|
|
149
|
+
data = {"user_ids": [user.user_id for user in users]}
|
|
150
|
+
endpoint = urljoin(endpoint, f'unshare/')
|
|
151
|
+
await self.api.post(endpoint, data, is_json=False)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
async def _get_shared_users(self, endpoint: str, params: dict = None) -> List['AsyncUser']:
|
|
155
|
+
"""
|
|
156
|
+
Internal method to get the users that the resource is shared with.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
endpoint (str): resource endpoint
|
|
160
|
+
params (dict): Additional parameters for filtering and pagination
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
List[AsyncUser]: The users that the resource is shared with
|
|
164
|
+
"""
|
|
165
|
+
from .user import AsyncUser
|
|
166
|
+
|
|
167
|
+
params = clean_data(params)
|
|
168
|
+
query_strings = urlencode(params)
|
|
169
|
+
endpoint = urljoin(endpoint, f'shared-with-users/?{query_strings}')
|
|
170
|
+
response = await self.api.get(endpoint)
|
|
171
|
+
return [AsyncUser(self.api, item['id'], item) for item in response]
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
async def _get_settings(self, endpoint: str) -> Dict:
|
|
175
|
+
"""
|
|
176
|
+
Internal method to get the settings of the resource.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
endpoint (str): The endpoint of the resource
|
|
180
|
+
"""
|
|
181
|
+
endpoint = urljoin(endpoint, f'settings/?f=json')
|
|
182
|
+
return await self.api.get(endpoint)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
async def _set_settings(self, endpoint: str, data: dict) -> None:
|
|
186
|
+
"""
|
|
187
|
+
Internal method to set the settings of the resource.
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
endpoint (str): The endpoint of the resource
|
|
191
|
+
data (dict): The data to set the settings with
|
|
192
|
+
"""
|
|
193
|
+
endpoint = urljoin(endpoint, f'settings/')
|
|
194
|
+
return await self.api.put(endpoint, data)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
async def _get_task(self, response, error_message: str) -> List['AsyncUser']:
|
|
198
|
+
from .task import AsyncTask # avoid circular dependency
|
|
199
|
+
|
|
200
|
+
if len(response) == 1 and isinstance(response, list) and response[0].get('task_id'):
|
|
201
|
+
result = [await self.api.get_task(response[0].get('task_id'))]
|
|
202
|
+
elif len(response) == 2 and isinstance(response, list) and (response[0].get('task_id') and response[1].get('task_id')):
|
|
203
|
+
result = [await self.api.get_task(item.get('task_id')) for item in response]
|
|
204
|
+
elif len(response) == 1 and isinstance(response, dict) and response.get('task_id'):
|
|
205
|
+
result = [await self.api.get_task(response.get('task_id'))]
|
|
206
|
+
else:
|
|
207
|
+
raise ValueError(error_message)
|
|
208
|
+
|
|
209
|
+
return result
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
async def _seed_cache(self, endpoint: str, data: dict) -> List['AsyncTask']:
|
|
213
|
+
"""
|
|
214
|
+
Internal method to cache seed the resource.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
endpoint (str): The endpoint of the resource
|
|
218
|
+
data (dict): The data to cache seed with
|
|
219
|
+
"""
|
|
220
|
+
if data['workers'] not in [1, 2, 4, 8, 12, 16, 20, 24]:
|
|
221
|
+
raise ValueError("workers must be in [1, 2, 4, 8, 12, 16, 20, 24]")
|
|
222
|
+
|
|
223
|
+
data = clean_data(data)
|
|
224
|
+
endpoint = urljoin(endpoint, f'cache/seed/')
|
|
225
|
+
response = await self.api.post(endpoint, data)
|
|
226
|
+
return await self._get_task(response, 'Failed to seed cache')
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
async def _clear_cache(self, endpoint: str) -> None:
|
|
230
|
+
"""
|
|
231
|
+
Internal method to clear the cache of the resource.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
endpoint (str): The endpoint of the resource
|
|
235
|
+
"""
|
|
236
|
+
endpoint = urljoin(endpoint, f'cache/clear/')
|
|
237
|
+
await self.api.post(endpoint)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
async def _cache_size(self, endpoint: str) -> int:
|
|
241
|
+
"""
|
|
242
|
+
Internal method to get the size of the cache of the resource.
|
|
243
|
+
|
|
244
|
+
Args:
|
|
245
|
+
endpoint (str): The endpoint of the resource
|
|
246
|
+
"""
|
|
247
|
+
endpoint = urljoin(endpoint, f'cache/size/')
|
|
248
|
+
return await self.api.post(endpoint)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
async def _update_cache(self, endpoint: str, data: Dict = {}) -> List['AsyncTask']:
|
|
252
|
+
"""
|
|
253
|
+
Internal method to update the cache of the resource.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
endpoint (str): The endpoint of the resource
|
|
257
|
+
"""
|
|
258
|
+
data = clean_data(data)
|
|
259
|
+
endpoint = urljoin(endpoint, 'cache/update/')
|
|
260
|
+
response = await self.api.post(endpoint, data)
|
|
261
|
+
return await self._get_task(response, 'Failed to update cache')
|