geobox 2.2.6__py3-none-any.whl → 2.3.0__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/aio/api.py +114 -1
- geobox/aio/table.py +1144 -0
- geobox/api.py +115 -0
- geobox/enums.py +5 -1
- geobox/field.py +21 -10
- geobox/table.py +1134 -0
- {geobox-2.2.6.dist-info → geobox-2.3.0.dist-info}/METADATA +2 -2
- {geobox-2.2.6.dist-info → geobox-2.3.0.dist-info}/RECORD +11 -9
- {geobox-2.2.6.dist-info → geobox-2.3.0.dist-info}/WHEEL +0 -0
- {geobox-2.2.6.dist-info → geobox-2.3.0.dist-info}/licenses/LICENSE +0 -0
- {geobox-2.2.6.dist-info → geobox-2.3.0.dist-info}/top_level.txt +0 -0
geobox/table.py
ADDED
|
@@ -0,0 +1,1134 @@
|
|
|
1
|
+
from typing import List, Dict, Optional, TYPE_CHECKING, Union, Any
|
|
2
|
+
from urllib.parse import urljoin
|
|
3
|
+
|
|
4
|
+
from geobox.enums import TableExportFormat
|
|
5
|
+
|
|
6
|
+
from .base import Base
|
|
7
|
+
from .task import Task
|
|
8
|
+
from .enums import FieldType
|
|
9
|
+
from .exception import NotFoundError
|
|
10
|
+
from .utils import clean_data
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from . import GeoboxClient
|
|
14
|
+
from .user import User
|
|
15
|
+
from .aio import AsyncGeoboxClient
|
|
16
|
+
from .file import File
|
|
17
|
+
from .aio.table import Table as AsyncTable, AsyncTableRow, AsyncTableField
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TableRow(Base):
|
|
22
|
+
|
|
23
|
+
def __init__(self,
|
|
24
|
+
table: 'Table',
|
|
25
|
+
data: Optional[Dict] = {},
|
|
26
|
+
):
|
|
27
|
+
"""
|
|
28
|
+
Constructs all the necessary attributes for the TableRow object.
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
table (Table): The table that the row belongs to.
|
|
32
|
+
data (Dict, optional): The data of the field.
|
|
33
|
+
"""
|
|
34
|
+
super().__init__(api=table.api, data=data)
|
|
35
|
+
self.table = table
|
|
36
|
+
self.endpoint = urljoin(table.endpoint, f'rows/{self.id}/') if self.data.get('id') else None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def __repr__(self) -> str:
|
|
40
|
+
"""
|
|
41
|
+
Return a string representation of the TableRow.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
str: The string representation of the TableRow.
|
|
45
|
+
"""
|
|
46
|
+
return f"TableRow(id={self.id}, table_name={self.table.data.get('name', 'None')})"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@classmethod
|
|
50
|
+
def create_row(cls, table: 'Table', **kwargs) -> 'TableRow':
|
|
51
|
+
"""
|
|
52
|
+
Create a new row in the table.
|
|
53
|
+
|
|
54
|
+
Each keyword argument represents a field value for the row, where:
|
|
55
|
+
- The keyword is the field name
|
|
56
|
+
- The value is the field value
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
table (Table): table instance
|
|
60
|
+
|
|
61
|
+
Keyword Args:
|
|
62
|
+
**kwargs: Arbitrary field values matching the table schema.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
TableRow: created table row instance
|
|
66
|
+
|
|
67
|
+
Example:
|
|
68
|
+
>>> from geobox import GeoboxClient
|
|
69
|
+
>>> from geobox.table import Table, TableRow
|
|
70
|
+
>>> client = GeoboxClient()
|
|
71
|
+
>>> table = client.get_table(uuid="12345678-1234-5678-1234-567812345678")
|
|
72
|
+
or
|
|
73
|
+
>>> table = Table.get_table(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
74
|
+
>>> row_data = {
|
|
75
|
+
'field1': 'value1'
|
|
76
|
+
}
|
|
77
|
+
>>> row = TableRow.create_row(table, row_data)
|
|
78
|
+
"""
|
|
79
|
+
endpoint = urljoin(table.endpoint, 'rows/')
|
|
80
|
+
return cls._create(table.api, endpoint, kwargs, factory_func=lambda api, item: TableRow(table, data=item))
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@classmethod
|
|
84
|
+
def get_row(cls,
|
|
85
|
+
table: 'Table',
|
|
86
|
+
row_id: int,
|
|
87
|
+
user_id: Optional[int],
|
|
88
|
+
) -> 'TableRow':
|
|
89
|
+
"""
|
|
90
|
+
Get a row by its id
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
table (Table): the table instance
|
|
94
|
+
row_id (int): the row id
|
|
95
|
+
user_id (int, optional): specific user. privileges required.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
TanbleRow: the table row instance
|
|
99
|
+
|
|
100
|
+
Example:
|
|
101
|
+
>>> from geobox import GeoboxClient
|
|
102
|
+
>>> from geobox.table import Table, TableRow
|
|
103
|
+
>>> client = GeoboxClient()
|
|
104
|
+
>>> table = client.get_table(uuid="12345678-1234-5678-1234-567812345678")
|
|
105
|
+
or
|
|
106
|
+
>>> table = Table.get_table(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
107
|
+
|
|
108
|
+
>>> row = TableRow.get_row(table, row_id=1)
|
|
109
|
+
"""
|
|
110
|
+
param = {
|
|
111
|
+
'f': 'json',
|
|
112
|
+
'user_id': user_id
|
|
113
|
+
}
|
|
114
|
+
endpoint = urljoin(table.endpoint, f'rows/')
|
|
115
|
+
return cls._get_detail(table.api, endpoint, uuid=row_id, params=param, factory_func=lambda api, item: TableRow(table, data=item))
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def update(self, **kwargs) -> Dict:
|
|
119
|
+
"""
|
|
120
|
+
Update a row
|
|
121
|
+
|
|
122
|
+
Keyword Args:
|
|
123
|
+
fields to update
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
Dict: updated row data
|
|
127
|
+
|
|
128
|
+
Example:
|
|
129
|
+
>>> from geobox import GeoboxClient
|
|
130
|
+
>>> client = GeoboxClient()
|
|
131
|
+
>>> table = client.get_table(uuid="12345678-1234-5678-1234-567812345678")
|
|
132
|
+
>>> row = table.get_row(row_id=1)
|
|
133
|
+
>>> row.update(field1='new_value')
|
|
134
|
+
"""
|
|
135
|
+
super()._update(self.endpoint, self.data, clean=False)
|
|
136
|
+
return self.data
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def delete(self) -> None:
|
|
140
|
+
"""
|
|
141
|
+
Delete a row
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
None
|
|
145
|
+
|
|
146
|
+
Example:
|
|
147
|
+
>>> from geobox import GeoboxClient
|
|
148
|
+
>>> client = GeoboxClient()
|
|
149
|
+
>>> table = client.get_table(uuid="12345678-1234-5678-1234-567812345678")
|
|
150
|
+
>>> row = table.get_row(row_id=1)
|
|
151
|
+
>>> row.delete()
|
|
152
|
+
"""
|
|
153
|
+
super()._delete(self.endpoint)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def to_async(self, async_client: 'AsyncGeoboxClient') -> 'AsyncTableRow':
|
|
157
|
+
"""
|
|
158
|
+
Switch to async version of the table row instance to have access to the async methods
|
|
159
|
+
|
|
160
|
+
Args:
|
|
161
|
+
async_client (AsyncGeoboxClient): The async version of the GeoboxClient instance for making requests.
|
|
162
|
+
|
|
163
|
+
Returns:
|
|
164
|
+
AsyncTableRow: the async instance of the TableRow.
|
|
165
|
+
|
|
166
|
+
Example:
|
|
167
|
+
>>> from geobox import Geoboxclient
|
|
168
|
+
>>> from geobox.aio import AsyncGeoboxClient
|
|
169
|
+
>>> client = GeoboxClient()
|
|
170
|
+
>>> table = client.get_table(uuid="12345678-1234-5678-1234-567812345678")
|
|
171
|
+
>>> row = table.get_row(row_id=1)
|
|
172
|
+
>>> async with AsyncGeoboxClient() as async_client:
|
|
173
|
+
>>> async_row = row.to_async(async_client)
|
|
174
|
+
"""
|
|
175
|
+
from .aio.table import AsyncTableRow
|
|
176
|
+
|
|
177
|
+
async_table = self.table.to_async(async_client=async_client)
|
|
178
|
+
return AsyncTableRow(table=async_table, data=self.data)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class TableField(Base):
|
|
183
|
+
|
|
184
|
+
def __init__(self,
|
|
185
|
+
table: 'Table',
|
|
186
|
+
data_type: 'FieldType',
|
|
187
|
+
field_id: int = None,
|
|
188
|
+
data: Optional[Dict] = {},
|
|
189
|
+
):
|
|
190
|
+
"""
|
|
191
|
+
Constructs all the necessary attributes for the Field object.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
table (Table): The table that the field belongs to.
|
|
195
|
+
data_type (FieldType): type of the field
|
|
196
|
+
field_id (int): the id of the field
|
|
197
|
+
data (Dict, optional): The data of the field.
|
|
198
|
+
"""
|
|
199
|
+
super().__init__(api=table.api, data=data)
|
|
200
|
+
self.table = table
|
|
201
|
+
self.field_id = field_id
|
|
202
|
+
if not isinstance(data_type, FieldType):
|
|
203
|
+
raise ValueError("data_type must be a FieldType instance")
|
|
204
|
+
self.data_type = data_type
|
|
205
|
+
self.endpoint = urljoin(table.endpoint, f'fields/{self.id}/') if self.data.get('id') else None
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def __repr__(self) -> str:
|
|
209
|
+
"""
|
|
210
|
+
Return a string representation of the field.
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
str: The string representation of the field.
|
|
214
|
+
"""
|
|
215
|
+
return f"TableField(id={self.id}, name={self.name}, data_type={self.data_type})"
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def __getattr__(self, name: str) -> Any:
|
|
219
|
+
"""
|
|
220
|
+
Get an attribute from the resource.
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
name (str): The name of the attribute
|
|
224
|
+
"""
|
|
225
|
+
if name == 'datatype':
|
|
226
|
+
return FieldType(self.data['datatype'])
|
|
227
|
+
return super().__getattr__(name)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
@property
|
|
231
|
+
def domain(self) -> Dict:
|
|
232
|
+
"""
|
|
233
|
+
Domain property
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
Dict: domain data
|
|
237
|
+
"""
|
|
238
|
+
return self.data.get('domain')
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
@domain.setter
|
|
242
|
+
def domain(self, value: Dict) -> None:
|
|
243
|
+
"""
|
|
244
|
+
Domain property setter
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
None
|
|
248
|
+
"""
|
|
249
|
+
self.data['domain'] = value
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
@classmethod
|
|
253
|
+
def create_field(cls,
|
|
254
|
+
table: 'Table',
|
|
255
|
+
name: str,
|
|
256
|
+
data_type: 'FieldType',
|
|
257
|
+
data: Dict = {},
|
|
258
|
+
) -> 'TableField':
|
|
259
|
+
"""
|
|
260
|
+
Create a new field
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
table (Table): field's table
|
|
264
|
+
name (str): name of the field
|
|
265
|
+
data_type (FieldType): type of the field
|
|
266
|
+
data (Dict, optional): the data of the field
|
|
267
|
+
|
|
268
|
+
Returns:
|
|
269
|
+
Field: the created field object
|
|
270
|
+
|
|
271
|
+
Example:
|
|
272
|
+
>>> from geobox import GeoboxClient
|
|
273
|
+
>>> from geobox.table import Table
|
|
274
|
+
>>> from geobox.field import Field
|
|
275
|
+
>>> client = GeoboxClient()
|
|
276
|
+
>>> table = client.get_table(uuid="12345678-1234-5678-1234-567812345678")
|
|
277
|
+
>>> field = Field.create_field(client, table=table, name='test', data_type=FieldType.Integer)
|
|
278
|
+
"""
|
|
279
|
+
data.update({
|
|
280
|
+
"name": name,
|
|
281
|
+
"datatype": data_type.value
|
|
282
|
+
})
|
|
283
|
+
endpoint = urljoin(table.endpoint, 'fields/')
|
|
284
|
+
return super()._create(table.api, endpoint, data, factory_func=lambda api, item: TableField(table, data_type, item['id'], item))
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def delete(self) -> None:
|
|
288
|
+
"""
|
|
289
|
+
Delete the field.
|
|
290
|
+
|
|
291
|
+
Returns:
|
|
292
|
+
None
|
|
293
|
+
|
|
294
|
+
Example:
|
|
295
|
+
>>> from geobox import GeoboxClient
|
|
296
|
+
>>> from geobox.field import TableField
|
|
297
|
+
>>> client = GeoboxClient()
|
|
298
|
+
>>> table = client.get_table(uuid="12345678-1234-5678-1234-567812345678")
|
|
299
|
+
>>> field = table.get_field(name='test')
|
|
300
|
+
>>> field.delete()
|
|
301
|
+
"""
|
|
302
|
+
super()._delete(self.endpoint)
|
|
303
|
+
self.field_id = None
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
def update(self, **kwargs) -> Dict:
|
|
307
|
+
"""
|
|
308
|
+
Update the field.
|
|
309
|
+
|
|
310
|
+
Keyword Args:
|
|
311
|
+
name (str): The name of the field.
|
|
312
|
+
display_name (str): The display name of the field.
|
|
313
|
+
description (str): The description of the field.
|
|
314
|
+
domain (Dict): the domain of the field
|
|
315
|
+
hyperlink (bool): the hyperlink field.
|
|
316
|
+
|
|
317
|
+
Returns:
|
|
318
|
+
Dict: The updated data.
|
|
319
|
+
|
|
320
|
+
Example:
|
|
321
|
+
>>> from geobox import GeoboxClient
|
|
322
|
+
>>> from geobox.field import TableField
|
|
323
|
+
>>> client = GeoboxClient()
|
|
324
|
+
>>> table = client.get_table(uuid="12345678-1234-5678-1234-567812345678")
|
|
325
|
+
>>> field = table.get_field(name='test')
|
|
326
|
+
>>> field.update(name="my_field", display_name="My Field", description="My Field Description")
|
|
327
|
+
"""
|
|
328
|
+
data = {
|
|
329
|
+
"name": kwargs.get('name'),
|
|
330
|
+
"display_name": kwargs.get('display_name'),
|
|
331
|
+
"description": kwargs.get('description'),
|
|
332
|
+
"domain": kwargs.get('domain'),
|
|
333
|
+
"hyperlink": kwargs.get('hyperlink')
|
|
334
|
+
}
|
|
335
|
+
return super()._update(self.endpoint, data)
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def update_domain(self,
|
|
339
|
+
range_domain: Dict = None,
|
|
340
|
+
list_domain: Dict = None,
|
|
341
|
+
) -> Dict:
|
|
342
|
+
"""
|
|
343
|
+
Update field domian values
|
|
344
|
+
|
|
345
|
+
Args:
|
|
346
|
+
range_domain (Dict): a dictionary with min and max keys.
|
|
347
|
+
list_domain (Dict): a dictionary containing the domain codes and values.
|
|
348
|
+
|
|
349
|
+
Returns:
|
|
350
|
+
Dict: the updated field domain
|
|
351
|
+
|
|
352
|
+
Example:
|
|
353
|
+
>>> from geobox import GeoboxClient
|
|
354
|
+
>>> client = GeoboxClient()
|
|
355
|
+
>>> field = client.get_table(uuid="12345678-1234-5678-1234-567812345678").get_fields()[0]
|
|
356
|
+
>>> range_d = {'min': 1, 'max': 10}
|
|
357
|
+
>>> field.update_domain(range_domain = range_d)
|
|
358
|
+
or
|
|
359
|
+
>>> list_d = {'1': 'value1', '2': 'value2'}
|
|
360
|
+
>>> field.update_domain(list_domain=list_d)
|
|
361
|
+
"""
|
|
362
|
+
if not self.domain:
|
|
363
|
+
self.domain = {'min': None, 'max': None, 'items': {}}
|
|
364
|
+
|
|
365
|
+
if range_domain:
|
|
366
|
+
self.domain['min'] = range_domain['min']
|
|
367
|
+
self.domain['max'] = range_domain['max']
|
|
368
|
+
|
|
369
|
+
if list_domain:
|
|
370
|
+
self.domain['items'] = {**self.domain['items'], **list_domain}
|
|
371
|
+
|
|
372
|
+
self.update(domain=self.domain)
|
|
373
|
+
return self.domain
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
def to_async(self, async_client: 'AsyncGeoboxClient') -> 'AsyncTableField':
|
|
377
|
+
"""
|
|
378
|
+
Switch to async version of the field instance to have access to the async methods
|
|
379
|
+
|
|
380
|
+
Args:
|
|
381
|
+
async_client (AsyncGeoboxClient): The async version of the GeoboxClient instance for making requests.
|
|
382
|
+
|
|
383
|
+
Returns:
|
|
384
|
+
AsyncField: the async instance of the field.
|
|
385
|
+
|
|
386
|
+
Example:
|
|
387
|
+
>>> from geobox import Geoboxclient
|
|
388
|
+
>>> from geobox.aio import AsyncGeoboxClient
|
|
389
|
+
>>> client = GeoboxClient()
|
|
390
|
+
>>> table = client.get_table(uuid="12345678-1234-5678-1234-567812345678")
|
|
391
|
+
>>> field = table.get_field(name='test')
|
|
392
|
+
>>> async with AsyncGeoboxClient() as async_client:
|
|
393
|
+
>>> async_field = field.to_async(async_client)
|
|
394
|
+
"""
|
|
395
|
+
from .aio.table import AsyncTableField
|
|
396
|
+
|
|
397
|
+
async_table = self.table.to_async(async_client=async_client)
|
|
398
|
+
return AsyncTableField(table=async_table, data_type=self.data_type, field_id=self.field_id, data=self.data)
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
class Table(Base):
|
|
403
|
+
|
|
404
|
+
BASE_ENDPOINT = 'tables/'
|
|
405
|
+
|
|
406
|
+
def __init__(self,
|
|
407
|
+
api: 'GeoboxClient',
|
|
408
|
+
uuid: str,
|
|
409
|
+
data: Optional[Dict] = {}):
|
|
410
|
+
"""
|
|
411
|
+
Initialize a table instance.
|
|
412
|
+
|
|
413
|
+
Args:
|
|
414
|
+
api (GeoboxClient): The GeoboxClient instance for making requests.
|
|
415
|
+
uuid (str): The unique identifier for the table.
|
|
416
|
+
data (Dict): The response data of the table.
|
|
417
|
+
"""
|
|
418
|
+
super().__init__(api, uuid=uuid, data=data)
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
@classmethod
|
|
422
|
+
def get_tables(cls, api: 'GeoboxClient', **kwargs) -> Union[List['Table'], int]:
|
|
423
|
+
"""
|
|
424
|
+
Get list of tables with optional filtering and pagination.
|
|
425
|
+
|
|
426
|
+
Args:
|
|
427
|
+
api (GeoboxClient): The GeoboxClient instance for making requests.
|
|
428
|
+
|
|
429
|
+
Keyword Args:
|
|
430
|
+
include_settings (bool): Whether to include table settings. default: False
|
|
431
|
+
temporary (bool): Whether to return temporary tables. default: False
|
|
432
|
+
q (str): query filter based on OGC CQL standard. e.g. "field1 LIKE '%GIS%' AND created_at > '2021-01-01'"
|
|
433
|
+
search (str): search term for keyword-based searching among search_fields or all textual fields if search_fields does not have value. NOTE: if q param is defined this param will be ignored
|
|
434
|
+
search_fields (str): comma separated list of fields for searching
|
|
435
|
+
order_by (str): comma separated list of fields for sorting results [field1 A|D, field2 A|D, …]. e.g. name A, type D. NOTE: "A" denotes ascending order and "D" denotes descending order.
|
|
436
|
+
return_count (bool): Whether to return total count. default: False.
|
|
437
|
+
skip (int): Number of items to skip. default: 0
|
|
438
|
+
limit (int): Number of items to return. default: 10
|
|
439
|
+
user_id (int): Specific user. privileges required
|
|
440
|
+
shared (bool): Whether to return shared tables. default: False
|
|
441
|
+
|
|
442
|
+
Returns:
|
|
443
|
+
List[Table] | int: A list of table instances or the total number of tables.
|
|
444
|
+
|
|
445
|
+
Example:
|
|
446
|
+
>>> from geobox import GeoboxClient
|
|
447
|
+
>>> from geobox.table import Table
|
|
448
|
+
>>> client = GeoboxClient()
|
|
449
|
+
>>> tables = client.get_tables(q="name LIKE '%My table%'")
|
|
450
|
+
or
|
|
451
|
+
>>> tables = Table.get_tables(client, q="name LIKE '%My table%'")
|
|
452
|
+
"""
|
|
453
|
+
params = {
|
|
454
|
+
'f': 'json',
|
|
455
|
+
'include_settings': kwargs.get('include_settings', False),
|
|
456
|
+
'temporary': kwargs.get('temporary'),
|
|
457
|
+
'q': kwargs.get('q'),
|
|
458
|
+
'search': kwargs.get('search'),
|
|
459
|
+
'search_fields': kwargs.get('search_fields'),
|
|
460
|
+
'order_by': kwargs.get('order_by'),
|
|
461
|
+
'return_count': kwargs.get('return_count', False),
|
|
462
|
+
'skip': kwargs.get('skip', 0),
|
|
463
|
+
'limit': kwargs.get('limit', 10),
|
|
464
|
+
'user_id': kwargs.get('user_id'),
|
|
465
|
+
'shared': kwargs.get('shared', False)
|
|
466
|
+
}
|
|
467
|
+
return super()._get_list(api, cls.BASE_ENDPOINT, params, factory_func=lambda api, item: Table(api, item['uuid'], item))
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
@classmethod
|
|
471
|
+
def create_table(cls,
|
|
472
|
+
api: 'GeoboxClient',
|
|
473
|
+
name: str,
|
|
474
|
+
display_name: Optional[str] = None,
|
|
475
|
+
description: Optional[str] = None,
|
|
476
|
+
temporary: bool = False,
|
|
477
|
+
fields: Optional[List[Dict]] = None,
|
|
478
|
+
) -> 'Table':
|
|
479
|
+
"""
|
|
480
|
+
Create a new table.
|
|
481
|
+
|
|
482
|
+
Args:
|
|
483
|
+
api (GeoboxClient): The GeoboxClient instance for making requests.
|
|
484
|
+
name (str): The name of the Table.
|
|
485
|
+
display_name (str, optional): The display name of the table.
|
|
486
|
+
description (str, optional): The description of the table.
|
|
487
|
+
temporary (bool, optional): Whether to create a temporary tables. default: False
|
|
488
|
+
fields (List[Dict], optional): raw table fields. you can use create_field method for simpler and safer field addition. required dictionary keys: name, datatype
|
|
489
|
+
|
|
490
|
+
Returns:
|
|
491
|
+
Table: The newly created table instance.
|
|
492
|
+
|
|
493
|
+
Raises:
|
|
494
|
+
ValidationError: If the table data is invalid.
|
|
495
|
+
|
|
496
|
+
Example:
|
|
497
|
+
>>> from geobox import GeoboxClient
|
|
498
|
+
>>> from geobox.table import Table
|
|
499
|
+
>>> client = GeoboxClient()
|
|
500
|
+
>>> table = client.create_table(name="my_table")
|
|
501
|
+
or
|
|
502
|
+
>>> table = Table.create_table(client, name="my_table")
|
|
503
|
+
"""
|
|
504
|
+
data = {
|
|
505
|
+
"name": name,
|
|
506
|
+
"display_name": display_name,
|
|
507
|
+
"description": description,
|
|
508
|
+
"temporary": temporary,
|
|
509
|
+
"fields": fields,
|
|
510
|
+
}
|
|
511
|
+
return super()._create(api, cls.BASE_ENDPOINT, data, factory_func=lambda api, item: Table(api, item['uuid'], item))
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
@classmethod
|
|
515
|
+
def get_table(cls, api: 'GeoboxClient', uuid: str, user_id: int = None) -> 'Table':
|
|
516
|
+
"""
|
|
517
|
+
Get a table by UUID.
|
|
518
|
+
|
|
519
|
+
Args:
|
|
520
|
+
api (GeoboxClient): The GeoboxClient instance for making requests.
|
|
521
|
+
uuid (str): The UUID of the table to get.
|
|
522
|
+
user_id (int): Specific user. privileges required.
|
|
523
|
+
|
|
524
|
+
Returns:
|
|
525
|
+
Table: The Table object.
|
|
526
|
+
|
|
527
|
+
Raises:
|
|
528
|
+
NotFoundError: If the table with the specified UUID is not found.
|
|
529
|
+
|
|
530
|
+
Example:
|
|
531
|
+
>>> from geobox import GeoboxClient
|
|
532
|
+
>>> from geobox.table import Table
|
|
533
|
+
>>> client = GeoboxClient()
|
|
534
|
+
>>> table = client.get_table(uuid="12345678-1234-5678-1234-567812345678")
|
|
535
|
+
or
|
|
536
|
+
>>> table = Table.get_table(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
537
|
+
"""
|
|
538
|
+
params = {
|
|
539
|
+
'f': 'json',
|
|
540
|
+
'user_id': user_id,
|
|
541
|
+
}
|
|
542
|
+
return super()._get_detail(api, cls.BASE_ENDPOINT, uuid, params, factory_func=lambda api, item: Table(api, item['uuid'], item))
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
@classmethod
|
|
546
|
+
def get_table_by_name(cls, api: 'GeoboxClient', name: str, user_id: int = None) -> Union['Table', None]:
|
|
547
|
+
"""
|
|
548
|
+
Get a table by name
|
|
549
|
+
|
|
550
|
+
Args:
|
|
551
|
+
api (GeoboxClient): The GeoboxClient instance for making requests.
|
|
552
|
+
name (str): the name of the table to get
|
|
553
|
+
user_id (int, optional): specific user. privileges required.
|
|
554
|
+
|
|
555
|
+
Returns:
|
|
556
|
+
Table | None: returns the table if a table matches the given name, else None
|
|
557
|
+
|
|
558
|
+
Example:
|
|
559
|
+
>>> from geobox import GeoboxClient
|
|
560
|
+
>>> from geobox.table import Table
|
|
561
|
+
>>> client = GeoboxClient()
|
|
562
|
+
>>> table = client.get_table_by_name(name='test')
|
|
563
|
+
or
|
|
564
|
+
>>> table = Table.get_table_by_name(client, name='test')
|
|
565
|
+
"""
|
|
566
|
+
tables = cls.get_tables(api, q=f"name = '{name}'", user_id=user_id)
|
|
567
|
+
if tables and tables[0].name == name:
|
|
568
|
+
return tables[0]
|
|
569
|
+
else:
|
|
570
|
+
return None
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
def update(self, **kwargs) -> Dict:
|
|
574
|
+
"""
|
|
575
|
+
Update the table.
|
|
576
|
+
|
|
577
|
+
Keyword Args:
|
|
578
|
+
name (str): The name of the table.
|
|
579
|
+
display_name (str): The display name of the table.
|
|
580
|
+
description (str): The description of the table.
|
|
581
|
+
|
|
582
|
+
Returns:
|
|
583
|
+
Dict: The updated table data.
|
|
584
|
+
|
|
585
|
+
Raises:
|
|
586
|
+
ValidationError: If the table data is invalid.
|
|
587
|
+
|
|
588
|
+
Example:
|
|
589
|
+
>>> from geobox import GeoboxClient
|
|
590
|
+
>>> from geobox.table import Table
|
|
591
|
+
>>> client = GeoboxClient()
|
|
592
|
+
>>> table = Table.get_table(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
593
|
+
>>> table.update_table(display_name="New Display Name")
|
|
594
|
+
"""
|
|
595
|
+
data = {
|
|
596
|
+
"name": kwargs.get('name'),
|
|
597
|
+
"display_name": kwargs.get('display_name'),
|
|
598
|
+
"description": kwargs.get('description'),
|
|
599
|
+
}
|
|
600
|
+
return super()._update(self.endpoint, data)
|
|
601
|
+
|
|
602
|
+
|
|
603
|
+
def delete(self) -> None:
|
|
604
|
+
"""
|
|
605
|
+
Delete the Table.
|
|
606
|
+
|
|
607
|
+
Returns:
|
|
608
|
+
None
|
|
609
|
+
|
|
610
|
+
Example:
|
|
611
|
+
>>> from geobox import GeoboxClient
|
|
612
|
+
>>> from geobox.table import Table
|
|
613
|
+
>>> client = GeoboxClient()
|
|
614
|
+
>>> table = Table.get_table(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
615
|
+
>>> table.delete()
|
|
616
|
+
"""
|
|
617
|
+
super()._delete(self.endpoint)
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
@property
|
|
621
|
+
def settings(self) -> Dict:
|
|
622
|
+
"""
|
|
623
|
+
Get the table's settings.
|
|
624
|
+
|
|
625
|
+
Returns:
|
|
626
|
+
Dict: The table settings.
|
|
627
|
+
|
|
628
|
+
Example:
|
|
629
|
+
>>> from geobox import GeoboxClient
|
|
630
|
+
>>> from geobox.table import Table
|
|
631
|
+
>>> client = GeoboxClient()
|
|
632
|
+
>>> table = Table.get_table(api=client, uuid="12345678-1234-5678-1234-567812345678")
|
|
633
|
+
>>> setting = table.setting
|
|
634
|
+
"""
|
|
635
|
+
return super()._get_settings(endpoint=self.endpoint)
|
|
636
|
+
|
|
637
|
+
|
|
638
|
+
def update_settings(self, settings: Dict) -> Dict:
|
|
639
|
+
"""
|
|
640
|
+
Update the settings
|
|
641
|
+
|
|
642
|
+
settings (Dict): settings dictionary
|
|
643
|
+
|
|
644
|
+
Returns:
|
|
645
|
+
Dict: updated settings
|
|
646
|
+
|
|
647
|
+
Example:
|
|
648
|
+
>>> from geobox import GeoboxClient
|
|
649
|
+
>>> client = GeoboxClient()
|
|
650
|
+
>>> table1 = client.get_table(uuid="12345678-1234-5678-1234-567812345678")
|
|
651
|
+
>>> table2 = client.get_table(uuid="12345678-1234-5678-1234-567812345678")
|
|
652
|
+
>>> table1.update_settings(table2.settings)
|
|
653
|
+
"""
|
|
654
|
+
return super()._set_settings(self.endpoint, settings)
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
def get_fields(self) -> List['TableField']:
|
|
658
|
+
"""
|
|
659
|
+
Get all fields of the table.
|
|
660
|
+
|
|
661
|
+
Returns:
|
|
662
|
+
List[TableField]: A list of Field instances representing the table's fields.
|
|
663
|
+
|
|
664
|
+
Example:
|
|
665
|
+
>>> from geobox import GeoboxClient
|
|
666
|
+
>>> from geobox.table import Table
|
|
667
|
+
>>> client = GeoboxClient()
|
|
668
|
+
>>> table = Table.get_table(api=client, uuid="12345678-1234-5678-1234-567812345678")
|
|
669
|
+
>>> fields = table.get_fields()
|
|
670
|
+
"""
|
|
671
|
+
endpoint = urljoin(self.endpoint, 'fields/')
|
|
672
|
+
return super()._get_list(api=self.api,
|
|
673
|
+
endpoint=endpoint,
|
|
674
|
+
factory_func=lambda api, item: TableField(table=self, data_type=FieldType(item['datatype']), field_id=item['id'], data=item))
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
def get_field(self, field_id: int) -> 'TableField':
|
|
678
|
+
"""
|
|
679
|
+
Get a specific field by ID.
|
|
680
|
+
|
|
681
|
+
Args:
|
|
682
|
+
field_id (int, optional): The ID of the field to retrieve.
|
|
683
|
+
|
|
684
|
+
Returns:
|
|
685
|
+
TableField: The requested field instance.
|
|
686
|
+
|
|
687
|
+
Raises:
|
|
688
|
+
NotFoundError: If the field with the specified ID is not found.
|
|
689
|
+
|
|
690
|
+
Example:
|
|
691
|
+
>>> from geobox import GeoboxClient
|
|
692
|
+
>>> from geobox.table import Table
|
|
693
|
+
>>> client = GeoboxClient()
|
|
694
|
+
>>> table = Table.get_table(api=client, uuid="12345678-1234-5678-1234-567812345678")
|
|
695
|
+
>>> field = table.get_field(field_id=1)
|
|
696
|
+
"""
|
|
697
|
+
field = next((f for f in self.get_fields() if f.id == field_id), None)
|
|
698
|
+
if not field:
|
|
699
|
+
raise NotFoundError(f'Field with ID {field_id} not found in table {self.name}')
|
|
700
|
+
|
|
701
|
+
return field
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
def get_field_by_name(self, name: str) -> 'TableField':
|
|
705
|
+
"""
|
|
706
|
+
Get a specific field by name.
|
|
707
|
+
|
|
708
|
+
Args:
|
|
709
|
+
name (str): The name of the field to retrieve.
|
|
710
|
+
|
|
711
|
+
Returns:
|
|
712
|
+
TableField: The requested field instance.
|
|
713
|
+
|
|
714
|
+
Raises:
|
|
715
|
+
NotFoundError: If the field with the specified name is not found.
|
|
716
|
+
|
|
717
|
+
Example:
|
|
718
|
+
>>> from geobox import GeoboxClient
|
|
719
|
+
>>> from geobox.table import Table
|
|
720
|
+
>>> client = GeoboxClient()
|
|
721
|
+
>>> table = Table.get_table(api=client, uuid="12345678-1234-5678-1234-567812345678")
|
|
722
|
+
>>> field = table.get_field_by_name(name='test')
|
|
723
|
+
"""
|
|
724
|
+
field = next((f for f in self.get_fields() if f.name == name), None)
|
|
725
|
+
if not field:
|
|
726
|
+
raise NotFoundError(f"Field with name '{name}' not found in table {self.name}")
|
|
727
|
+
|
|
728
|
+
return field
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
def add_field(self, name: str, data_type: 'FieldType', data: Dict = {}) -> 'TableField':
|
|
732
|
+
"""
|
|
733
|
+
Add a new field to the table.
|
|
734
|
+
|
|
735
|
+
Args:
|
|
736
|
+
name (str): The name of the new field.
|
|
737
|
+
data_type (FieldType): The data type of the new field.
|
|
738
|
+
data (Dict, optional): Additional field properties (display_name, description, etc.).
|
|
739
|
+
|
|
740
|
+
Returns:
|
|
741
|
+
Field: The newly created field instance.
|
|
742
|
+
|
|
743
|
+
Raises:
|
|
744
|
+
ValidationError: If the field data is invalid.
|
|
745
|
+
|
|
746
|
+
Example:
|
|
747
|
+
>>> from geobox import GeoboxClient
|
|
748
|
+
>>> from geobox.table import Table
|
|
749
|
+
>>> client = GeoboxClient()
|
|
750
|
+
>>> table = Table.get_table(api=client, uuid="12345678-1234-5678-1234-567812345678")
|
|
751
|
+
>>> field = table.add_field(name="new_field", data_type=FieldType.String)
|
|
752
|
+
"""
|
|
753
|
+
return TableField.create_field(table=self, name=name, data_type=data_type, data=data)
|
|
754
|
+
|
|
755
|
+
|
|
756
|
+
def calculate_field(self,
|
|
757
|
+
target_field: str,
|
|
758
|
+
expression: str,
|
|
759
|
+
q: Optional[str] = None,
|
|
760
|
+
search: Optional[str] = None,
|
|
761
|
+
search_fields: Optional[str] = None,
|
|
762
|
+
row_ids: Optional[str] = None,
|
|
763
|
+
run_async: bool = True,
|
|
764
|
+
user_id: Optional[int] = None,
|
|
765
|
+
) -> Union['Task', Dict]:
|
|
766
|
+
"""
|
|
767
|
+
Calculate values for a field based on an expression.
|
|
768
|
+
|
|
769
|
+
Args:
|
|
770
|
+
target_field (str): The field to calculate values for.
|
|
771
|
+
expression (str): The expression to use for calculation.
|
|
772
|
+
q (str, optional): Query to filter features. default: None.
|
|
773
|
+
search (str, optional): search term for keyword-based searching among search_fields or all textual fields if search_fields does not have value
|
|
774
|
+
search_fields (str, optional): comma separated list of fields for searching
|
|
775
|
+
row_ids (str, optional): List of specific row IDs to include. default: None
|
|
776
|
+
run_async (bool, optional): Whether to run the calculation asynchronously. default: True.
|
|
777
|
+
user_id (int, optional): Specific user. privileges required.
|
|
778
|
+
|
|
779
|
+
Returns:
|
|
780
|
+
Task | Dict: The task instance of the calculation operation or the api response if the run_async=False.
|
|
781
|
+
|
|
782
|
+
Example:
|
|
783
|
+
>>> from geobox import GeoboxClient
|
|
784
|
+
>>> from geobox.table import Table
|
|
785
|
+
>>> client = GeoboxClient()
|
|
786
|
+
>>> table = Table.get_table(api=client, uuid="12345678-1234-5678-1234-567812345678")
|
|
787
|
+
>>> task = table.calculate_field(target_field="target_field",
|
|
788
|
+
... expression="expression",
|
|
789
|
+
... q="name like 'my_layer'",
|
|
790
|
+
... row_ids=[1, 2, 3],
|
|
791
|
+
... run_async=True)
|
|
792
|
+
"""
|
|
793
|
+
data = clean_data({
|
|
794
|
+
"target_field": target_field,
|
|
795
|
+
"expression": expression,
|
|
796
|
+
"q": q,
|
|
797
|
+
"search": search,
|
|
798
|
+
"search_fields": search_fields,
|
|
799
|
+
"row_ids": row_ids,
|
|
800
|
+
"run_async": run_async,
|
|
801
|
+
"user_id": user_id
|
|
802
|
+
})
|
|
803
|
+
|
|
804
|
+
endpoint = urljoin(self.endpoint, 'calculateField/')
|
|
805
|
+
response = self.api.post(endpoint, data, is_json=False)
|
|
806
|
+
if run_async:
|
|
807
|
+
task = Task.get_task(self.api, response.get('task_id'))
|
|
808
|
+
return task
|
|
809
|
+
|
|
810
|
+
return response
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
def get_rows(self, **kwargs) -> List['TableRow']:
|
|
814
|
+
"""
|
|
815
|
+
Query rows of a table
|
|
816
|
+
|
|
817
|
+
Keyword Args:
|
|
818
|
+
q (str): Advanced filtering expression, e.g., 'status = "active" and age > 20'
|
|
819
|
+
search (str): Search term for keyword-based searching among fields/columns
|
|
820
|
+
search_fields (str): Comma separated column names to search in
|
|
821
|
+
row_ids (str): Comma separated list of row ids to filter for
|
|
822
|
+
fields (str): Comma separated column names to include in results, or [ALL]
|
|
823
|
+
exclude (str): Comma separated column names to exclude from result
|
|
824
|
+
order_by (str): Comma separated list for ordering, e.g., 'name A, id D'
|
|
825
|
+
skip (int): Number of records to skip for pagination. default: 0
|
|
826
|
+
limit (int): Maximum number of records to return. default: 100
|
|
827
|
+
return_count (bool): If true, returns only the count of matching rows
|
|
828
|
+
user_id (int): Specific user. privileges required
|
|
829
|
+
|
|
830
|
+
Returns:
|
|
831
|
+
List[TableRow]: list of table rows objects
|
|
832
|
+
|
|
833
|
+
Example:
|
|
834
|
+
>>> from geobox import GeoboxClient
|
|
835
|
+
>>> from geobox.table import Table
|
|
836
|
+
>>> client = GeoboxClient()
|
|
837
|
+
>>> table = client.get_table(uuid="12345678-1234-5678-1234-567812345678")
|
|
838
|
+
or
|
|
839
|
+
>>> table = Table.get_table(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
840
|
+
|
|
841
|
+
>>> rows = table.get_rows()
|
|
842
|
+
"""
|
|
843
|
+
params = {
|
|
844
|
+
'f': 'json',
|
|
845
|
+
'q': kwargs.get('q'),
|
|
846
|
+
'search': kwargs.get('search'),
|
|
847
|
+
'search_fields': kwargs.get('search_fields'),
|
|
848
|
+
'row_ids': kwargs.get('row_ids'),
|
|
849
|
+
'fields': kwargs.get('fields'),
|
|
850
|
+
'exclude': kwargs.get('exclude'),
|
|
851
|
+
'order_by': kwargs.get('order_by'),
|
|
852
|
+
'skip': kwargs.get('skip', 0),
|
|
853
|
+
'limit': kwargs.get('limit', 100),
|
|
854
|
+
'return_count': kwargs.get('return_count', False),
|
|
855
|
+
'user_id': kwargs.get('user_id'),
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
endpoint = f'{self.endpoint}rows/'
|
|
859
|
+
|
|
860
|
+
return super()._get_list(api=self.api,
|
|
861
|
+
endpoint=endpoint,
|
|
862
|
+
params=params,
|
|
863
|
+
factory_func=lambda api, item: TableRow(self, item))
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
def get_row(self,
|
|
867
|
+
row_id: int,
|
|
868
|
+
user_id: Optional[int] = None,
|
|
869
|
+
) -> 'TableRow':
|
|
870
|
+
"""
|
|
871
|
+
Get a row by its id
|
|
872
|
+
|
|
873
|
+
Args:
|
|
874
|
+
row_id (int): the row id
|
|
875
|
+
user_id (int, optional): specific user. privileges required.
|
|
876
|
+
|
|
877
|
+
Returns:
|
|
878
|
+
TanbleRow: the table row instance
|
|
879
|
+
|
|
880
|
+
Example:
|
|
881
|
+
>>> from geobox import GeoboxClient
|
|
882
|
+
>>> from geobox.table import Table
|
|
883
|
+
>>> client = GeoboxClient()
|
|
884
|
+
>>> table = client.get_table(uuid="12345678-1234-5678-1234-567812345678")
|
|
885
|
+
or
|
|
886
|
+
>>> table = Table.get_table(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
887
|
+
|
|
888
|
+
>>> row = table.get_row(row_id=1)
|
|
889
|
+
"""
|
|
890
|
+
return TableRow.get_row(self, row_id, user_id)
|
|
891
|
+
|
|
892
|
+
|
|
893
|
+
def create_row(self, **kwargs) -> 'TableRow':
|
|
894
|
+
"""
|
|
895
|
+
Create a new row in the table.
|
|
896
|
+
|
|
897
|
+
Each keyword argument represents a field value for the row, where:
|
|
898
|
+
- The keyword is the field name
|
|
899
|
+
- The value is the field value
|
|
900
|
+
|
|
901
|
+
Keyword Args:
|
|
902
|
+
**kwargs: Arbitrary field values matching the table schema.
|
|
903
|
+
|
|
904
|
+
Returns:
|
|
905
|
+
TableRow: created table row instance
|
|
906
|
+
|
|
907
|
+
Example:
|
|
908
|
+
>>> from geobox import GeoboxClient
|
|
909
|
+
>>> from geobox.table import Table
|
|
910
|
+
>>> client = GeoboxClient()
|
|
911
|
+
>>> table = client.get_table(uuid="12345678-1234-5678-1234-567812345678")
|
|
912
|
+
or
|
|
913
|
+
>>> table = Table.get_table(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
914
|
+
|
|
915
|
+
>>> row = table.create_row(
|
|
916
|
+
... field1=value1
|
|
917
|
+
... )
|
|
918
|
+
"""
|
|
919
|
+
return TableRow.create_row(self, **kwargs)
|
|
920
|
+
|
|
921
|
+
|
|
922
|
+
def import_rows(self,
|
|
923
|
+
file: 'File',
|
|
924
|
+
*,
|
|
925
|
+
file_encoding: str = "utf-8",
|
|
926
|
+
input_dataset: Optional[str] = None,
|
|
927
|
+
delimiter: str = ',',
|
|
928
|
+
has_header: bool = True,
|
|
929
|
+
report_errors: bool = False,
|
|
930
|
+
bulk_insert: bool = True,
|
|
931
|
+
) -> 'Task':
|
|
932
|
+
"""
|
|
933
|
+
Import rows from a CSV file into a table
|
|
934
|
+
|
|
935
|
+
Args:
|
|
936
|
+
file (File): file object to import.
|
|
937
|
+
file_encoding (str, optional): Character encoding of the input file. default: utf-8
|
|
938
|
+
input_dataset (str, optional): Name of the dataset in the input file.
|
|
939
|
+
delimiter (str, optional): the delimiter of the dataset. default: ,
|
|
940
|
+
has_header (bool, optional): Whether the file has header or not. default: True
|
|
941
|
+
report_errors (bool, optional): Whether to report import errors. default: False
|
|
942
|
+
bulk_insert (bool, optional):
|
|
943
|
+
|
|
944
|
+
Returns:
|
|
945
|
+
Task: The task instance of the import operation.
|
|
946
|
+
|
|
947
|
+
Raises:
|
|
948
|
+
ValidationError: If the import parameters are invalid.
|
|
949
|
+
|
|
950
|
+
Example:
|
|
951
|
+
>>> from geobox import GeoboxClient
|
|
952
|
+
>>> from geobox.table import Table
|
|
953
|
+
>>> client = GeoboxClient()
|
|
954
|
+
>>> table = Table.get_table(api=client, uuid="12345678-1234-5678-1234-567812345678")
|
|
955
|
+
>>> file = client.get_file(uuid="12345678-1234-5678-1234-567812345678")
|
|
956
|
+
>>> task = table.import_rows(
|
|
957
|
+
... file=file,
|
|
958
|
+
... )
|
|
959
|
+
"""
|
|
960
|
+
data = clean_data({
|
|
961
|
+
"file_uuid": file.uuid,
|
|
962
|
+
"file_encoding": file_encoding,
|
|
963
|
+
"input_dataset": file.name if not input_dataset else input_dataset,
|
|
964
|
+
"delimiter": delimiter,
|
|
965
|
+
"has_header": has_header,
|
|
966
|
+
"report_errors": report_errors,
|
|
967
|
+
"bulk_insert": bulk_insert,
|
|
968
|
+
})
|
|
969
|
+
|
|
970
|
+
endpoint = urljoin(self.endpoint, 'import-csv/')
|
|
971
|
+
response = self.api.post(endpoint, data, is_json=False)
|
|
972
|
+
task = Task.get_task(self.api, response.get('task_id'))
|
|
973
|
+
return task
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
def export_rows(self,
|
|
977
|
+
out_filename: str,
|
|
978
|
+
*,
|
|
979
|
+
out_format: 'TableExportFormat' = TableExportFormat.CSV,
|
|
980
|
+
q: Optional[str] = None,
|
|
981
|
+
search: Optional[str] = None,
|
|
982
|
+
search_fields: Optional[str] = None,
|
|
983
|
+
row_ids: Optional[str] = None,
|
|
984
|
+
fields: Optional[str] = None,
|
|
985
|
+
exclude: Optional[str] = None,
|
|
986
|
+
order_by: Optional[str] = None,
|
|
987
|
+
zipped: bool = False,
|
|
988
|
+
run_async: bool = True,
|
|
989
|
+
) -> Union['Task', str]:
|
|
990
|
+
"""
|
|
991
|
+
Export rows of a table to a file
|
|
992
|
+
|
|
993
|
+
Args:
|
|
994
|
+
out_filename (str): Name of the output file without the format (.csv)
|
|
995
|
+
out_format (TableExportFormat, optional): Format of the output file
|
|
996
|
+
q (str, optional): query filter based on OGC CQL standard. e.g. "field1 LIKE '%GIS%' AND created_at > '2021-01-01'"
|
|
997
|
+
search (str, optional): search term for keyword-based searching among search_fields or all textual fields if search_fields does not have value
|
|
998
|
+
search_fields (str, optional): comma separated list of fields for searching
|
|
999
|
+
row_ids (str, optional): List of specific row IDs to include
|
|
1000
|
+
fields (str, optional): List of specific field names to include
|
|
1001
|
+
exclude (str, optional): List of specific field names to exclude
|
|
1002
|
+
order_by (str, optional): comma separated list of fields for sorting results [field1 A|D, field2 A|D, …]. e.g. name A, type D. NOTE: "A" denotes ascending order and "D" denotes descending order.
|
|
1003
|
+
zipped (str, optional): Whether to compress the output file
|
|
1004
|
+
run_async (bool, optional): Whether to run the export asynchronously. default: True
|
|
1005
|
+
|
|
1006
|
+
Returns:
|
|
1007
|
+
Task | Dict: The task instance of the export operation (run_async=True) or the export result (run_async=False)
|
|
1008
|
+
|
|
1009
|
+
Raises:
|
|
1010
|
+
ValidationError: If the export parameters are invalid.
|
|
1011
|
+
|
|
1012
|
+
Example:
|
|
1013
|
+
>>> from geobox import GeoboxClient
|
|
1014
|
+
>>> from geobox.table import Table
|
|
1015
|
+
>>> client = GeoboxClient()
|
|
1016
|
+
>>> table = Table.get_table(api=client, uuid="12345678-1234-5678-1234-567812345678")
|
|
1017
|
+
>>> file = client.get_file(uuid="12345678-1234-5678-1234-567812345678")
|
|
1018
|
+
>>> task = table.export_rows(
|
|
1019
|
+
... file=file,
|
|
1020
|
+
... )
|
|
1021
|
+
"""
|
|
1022
|
+
data = clean_data({
|
|
1023
|
+
"out_filename": out_filename,
|
|
1024
|
+
"out_format": out_format.value if out_format else None,
|
|
1025
|
+
"q": q,
|
|
1026
|
+
"search": search,
|
|
1027
|
+
"search_fields": search_fields,
|
|
1028
|
+
"row_ids": row_ids,
|
|
1029
|
+
"fields": fields,
|
|
1030
|
+
"exclude": exclude,
|
|
1031
|
+
"order_by": order_by,
|
|
1032
|
+
"zipped": zipped,
|
|
1033
|
+
"run_async": run_async,
|
|
1034
|
+
})
|
|
1035
|
+
|
|
1036
|
+
endpoint = urljoin(self.endpoint, 'export/')
|
|
1037
|
+
response = self.api.post(endpoint, data, is_json=False)
|
|
1038
|
+
if run_async:
|
|
1039
|
+
task = Task.get_task(self.api, response.get('task_id'))
|
|
1040
|
+
return task
|
|
1041
|
+
|
|
1042
|
+
return response
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
def share(self, users: List['User']) -> None:
|
|
1046
|
+
"""
|
|
1047
|
+
Shares the table with specified users.
|
|
1048
|
+
|
|
1049
|
+
Args:
|
|
1050
|
+
users (List[User]): The list of user objects to share the table with.
|
|
1051
|
+
|
|
1052
|
+
Returns:
|
|
1053
|
+
None
|
|
1054
|
+
|
|
1055
|
+
Example:
|
|
1056
|
+
>>> from geobox import GeoboxClient
|
|
1057
|
+
>>> from geobox.table import Table
|
|
1058
|
+
>>> client = GeoboxClient()
|
|
1059
|
+
>>> table = Table.get_table(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
1060
|
+
>>> users = client.search_users(search='John')
|
|
1061
|
+
>>> table.share(users=users)
|
|
1062
|
+
"""
|
|
1063
|
+
super()._share(self.endpoint, users)
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
def unshare(self, users: List['User']) -> None:
|
|
1067
|
+
"""
|
|
1068
|
+
Unshares the table with specified users.
|
|
1069
|
+
|
|
1070
|
+
Args:
|
|
1071
|
+
users (List[User]): The list of user objects to unshare the table with.
|
|
1072
|
+
|
|
1073
|
+
Returns:
|
|
1074
|
+
None
|
|
1075
|
+
|
|
1076
|
+
Example:
|
|
1077
|
+
>>> from geobox import GeoboxClient
|
|
1078
|
+
>>> from geobox.table import Table
|
|
1079
|
+
>>> client = GeoboxClient()
|
|
1080
|
+
>>> table = Table.get_table(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
1081
|
+
>>> users = client.search_users(search='John')
|
|
1082
|
+
>>> table.unshare(users=users)
|
|
1083
|
+
"""
|
|
1084
|
+
super()._unshare(self.endpoint, users)
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
def get_shared_users(self, search: str = None, skip: int = 0, limit: int = 10) -> List['User']:
|
|
1088
|
+
"""
|
|
1089
|
+
Retrieves the list of users the table is shared with.
|
|
1090
|
+
|
|
1091
|
+
Args:
|
|
1092
|
+
search (str, optional): The search query.
|
|
1093
|
+
skip (int, optional): The number of users to skip.
|
|
1094
|
+
limit (int, optional): The maximum number of users to retrieve.
|
|
1095
|
+
|
|
1096
|
+
Returns:
|
|
1097
|
+
List[User]: The list of shared users.
|
|
1098
|
+
|
|
1099
|
+
Example:
|
|
1100
|
+
>>> from geobox import GeoboxClient
|
|
1101
|
+
>>> from geobox.table import Table
|
|
1102
|
+
>>> client = GeoboxClient()
|
|
1103
|
+
>>> table = Table.get_table(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
1104
|
+
>>> table.get_shared_users(search='John', skip=0, limit=10)
|
|
1105
|
+
"""
|
|
1106
|
+
params = {
|
|
1107
|
+
'search': search,
|
|
1108
|
+
'skip': skip,
|
|
1109
|
+
'limit': limit
|
|
1110
|
+
}
|
|
1111
|
+
return super()._get_shared_users(self.endpoint, params)
|
|
1112
|
+
|
|
1113
|
+
|
|
1114
|
+
def to_async(self, async_client: 'AsyncGeoboxClient') -> 'AsyncTable':
|
|
1115
|
+
"""
|
|
1116
|
+
Switch to async version of the table instance to have access to the async methods
|
|
1117
|
+
|
|
1118
|
+
Args:
|
|
1119
|
+
async_client (AsyncGeoboxClient): The async version of the GeoboxClient instance for making requests.
|
|
1120
|
+
|
|
1121
|
+
Returns:
|
|
1122
|
+
AsyncTable: the async instance of the table.
|
|
1123
|
+
|
|
1124
|
+
Example:
|
|
1125
|
+
>>> from geobox import Geoboxclient
|
|
1126
|
+
>>> from geobox.aio import AsyncGeoboxClient
|
|
1127
|
+
>>> client = GeoboxClient()
|
|
1128
|
+
>>> table = Table.get_table(client, uuid="12345678-1234-5678-1234-567812345678")
|
|
1129
|
+
>>> async with AsyncGeoboxClient() as async_client:
|
|
1130
|
+
>>> async_table = table.to_async(async_client)
|
|
1131
|
+
"""
|
|
1132
|
+
from .aio.table import AsyncTable
|
|
1133
|
+
|
|
1134
|
+
return AsyncTable(api=async_client, uuid=self.uuid, data=self.data)
|