geobox 1.4.2__py3-none-any.whl → 2.0.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.
Files changed (66) hide show
  1. geobox/__init__.py +2 -2
  2. geobox/aio/__init__.py +63 -0
  3. geobox/aio/api.py +2640 -0
  4. geobox/aio/apikey.py +263 -0
  5. geobox/aio/attachment.py +339 -0
  6. geobox/aio/base.py +262 -0
  7. geobox/aio/basemap.py +196 -0
  8. geobox/aio/dashboard.py +342 -0
  9. geobox/aio/feature.py +527 -0
  10. geobox/aio/field.py +321 -0
  11. geobox/aio/file.py +522 -0
  12. geobox/aio/layout.py +341 -0
  13. geobox/aio/log.py +145 -0
  14. geobox/aio/map.py +1034 -0
  15. geobox/aio/model3d.py +415 -0
  16. geobox/aio/mosaic.py +696 -0
  17. geobox/aio/plan.py +315 -0
  18. geobox/aio/query.py +693 -0
  19. geobox/aio/raster.py +869 -0
  20. geobox/aio/route.py +63 -0
  21. geobox/aio/scene.py +342 -0
  22. geobox/aio/settings.py +194 -0
  23. geobox/aio/task.py +402 -0
  24. geobox/aio/tile3d.py +339 -0
  25. geobox/aio/tileset.py +672 -0
  26. geobox/aio/usage.py +243 -0
  27. geobox/aio/user.py +507 -0
  28. geobox/aio/vectorlayer.py +1363 -0
  29. geobox/aio/version.py +273 -0
  30. geobox/aio/view.py +983 -0
  31. geobox/aio/workflow.py +341 -0
  32. geobox/api.py +14 -15
  33. geobox/apikey.py +28 -1
  34. geobox/attachment.py +27 -1
  35. geobox/base.py +4 -4
  36. geobox/basemap.py +30 -1
  37. geobox/dashboard.py +27 -0
  38. geobox/feature.py +33 -13
  39. geobox/field.py +33 -21
  40. geobox/file.py +40 -46
  41. geobox/layout.py +28 -1
  42. geobox/log.py +31 -7
  43. geobox/map.py +34 -2
  44. geobox/model3d.py +31 -37
  45. geobox/mosaic.py +28 -7
  46. geobox/plan.py +29 -3
  47. geobox/query.py +39 -14
  48. geobox/raster.py +26 -13
  49. geobox/scene.py +26 -0
  50. geobox/settings.py +30 -1
  51. geobox/task.py +28 -6
  52. geobox/tile3d.py +27 -1
  53. geobox/tileset.py +26 -5
  54. geobox/usage.py +32 -1
  55. geobox/user.py +62 -6
  56. geobox/utils.py +34 -0
  57. geobox/vectorlayer.py +40 -4
  58. geobox/version.py +25 -1
  59. geobox/view.py +37 -17
  60. geobox/workflow.py +27 -1
  61. {geobox-1.4.2.dist-info → geobox-2.0.1.dist-info}/METADATA +4 -1
  62. geobox-2.0.1.dist-info/RECORD +68 -0
  63. geobox-1.4.2.dist-info/RECORD +0 -38
  64. {geobox-1.4.2.dist-info → geobox-2.0.1.dist-info}/WHEEL +0 -0
  65. {geobox-1.4.2.dist-info → geobox-2.0.1.dist-info}/licenses/LICENSE +0 -0
  66. {geobox-1.4.2.dist-info → geobox-2.0.1.dist-info}/top_level.txt +0 -0
geobox/plan.py CHANGED
@@ -5,6 +5,8 @@ from .base import Base
5
5
 
6
6
  if TYPE_CHECKING:
7
7
  from . import GeoboxClient
8
+ from .aio import AsyncGeoboxClient
9
+ from .aio.plan import Plan as AsyncPlan
8
10
 
9
11
  class Plan(Base):
10
12
 
@@ -209,7 +211,7 @@ class Plan(Base):
209
211
  >>> from geobox import GeoboxClient
210
212
  >>> from geobox.plan import Plan
211
213
  >>> client = GeoboxClient()
212
- >>> plan = Workflow.get_plan_by_name(client, name='test')
214
+ >>> plan = Plan.get_plan_by_name(client, name='test')
213
215
  or
214
216
  >>> plan = client.get_plan_by_name(name='test')
215
217
  """
@@ -250,7 +252,7 @@ class Plan(Base):
250
252
  >>> from geobox.plan import Plan
251
253
  >>> client = GeoboxClient()
252
254
  >>> plan = Plan.get_plan(client, plan_id=1)
253
- >>> plan.update_plan(display_name="New Display Name")
255
+ >>> plan.update(display_name="New Display Name")
254
256
  """
255
257
  data = {
256
258
  "name": kwargs.get('name'),
@@ -285,4 +287,28 @@ class Plan(Base):
285
287
  >>> plan.delete()
286
288
  """
287
289
  super().delete(self.endpoint)
288
- self.plan_id = None
290
+ self.plan_id = None
291
+
292
+
293
+ def to_async(self, async_client: 'AsyncGeoboxClient') -> 'AsyncPlan':
294
+ """
295
+ Switch to async version of the plan instance to have access to the async methods
296
+
297
+ Args:
298
+ async_client (AsyncGeoboxClient): The async version of the GeoboxClient instance for making requests.
299
+
300
+ Returns:
301
+ geobox.aio.plan.Plan: the async instance of the plan.
302
+
303
+ Example:
304
+ >>> from geobox import Geoboxclient
305
+ >>> from geobox.aio import AsyncGeoboxClient
306
+ >>> from geobox.plan import Plan
307
+ >>> client = GeoboxClient()
308
+ >>> plan = Plan.get_plan(client, plan_id=1)
309
+ >>> async with AsyncGeoboxClient() as async_client:
310
+ >>> async_plan = plan.to_async(async_client)
311
+ """
312
+ from .aio.plan import Plan as AsyncPlan
313
+
314
+ return AsyncPlan(api=async_client, plan_id=self.plan_id, data=self.data)
geobox/query.py CHANGED
@@ -9,11 +9,11 @@ from .enums import QueryResultType, QueryGeometryType, QueryParamType
9
9
  if TYPE_CHECKING:
10
10
  from . import GeoboxClient
11
11
  from .user import User
12
+ from .aio import AsyncGeoboxClient
13
+ from .aio.query import Query as AsyncQuery
12
14
 
13
15
  class Query(Base):
14
- """
15
- A class to interact with queries in GeoBox.
16
- """
16
+
17
17
  BASE_ENDPOINT: str = 'queries/'
18
18
 
19
19
  def __init__(self,
@@ -83,6 +83,7 @@ class Query(Base):
83
83
  >>> client = GeoboxClient()
84
84
  >>> query = Query.get_query(client, uuid="12345678-1234-5678-1234-567812345678")
85
85
  >>> query.sql = 'SELECT * FROM some_layer'
86
+ >>> query.save()
86
87
  """
87
88
  self.data['sql'] = value
88
89
 
@@ -126,6 +127,7 @@ class Query(Base):
126
127
  >>> client = GeoboxClient()
127
128
  >>> query = Query.get_query(client, uuid="12345678-1234-5678-1234-567812345678")
128
129
  >>> query.params = [{'name': 'layer', 'value': '12345678-1234-5678-1234-567812345678', 'type': 'Layer'}]
130
+ >>> query.save()
129
131
  """
130
132
  if not isinstance(self.data.get('params'), list):
131
133
  self.data['params'] = []
@@ -344,9 +346,8 @@ class Query(Base):
344
346
  or
345
347
  >>> query = client.get_query(uuid="12345678-1234-5678-1234-567812345678")
346
348
  >>> query.add_param(name='param_name', value='param_value', type=QueryParamType.LAYER)
349
+ >>> query.save()
347
350
  """
348
- self._check_access()
349
-
350
351
  self.params.append({
351
352
  'name': name,
352
353
  'value': value,
@@ -378,9 +379,8 @@ class Query(Base):
378
379
  or
379
380
  >>> query = client.get_query(uuid="12345678-1234-5678-1234-567812345678")
380
381
  >>> query.remove_param(name='param_name')
382
+ >>> query.save()
381
383
  """
382
- self._check_access()
383
-
384
384
  for i, param in enumerate(self.params):
385
385
  if param.get('name') == name:
386
386
  self.params.pop(i)
@@ -424,9 +424,7 @@ class Query(Base):
424
424
  or
425
425
  >>> query = client.get_query(uuid="12345678-1234-5678-1234-567812345678")
426
426
  >>> query.execute(f='json')
427
- """
428
- self._check_access()
429
-
427
+ """
430
428
  if not self.sql:
431
429
  raise ValueError('"sql" parameter is required for this action!')
432
430
  if not self.params:
@@ -499,7 +497,6 @@ class Query(Base):
499
497
  >>> from geobox.query import Query
500
498
  >>> client = GeoboxClient()
501
499
  >>> query = Query.get_query(client, uuid="12345678-1234-5678-1234-567812345678")
502
- >>> query.sql = "SELECT * FROM some_layer"
503
500
  >>> query.save()
504
501
  """
505
502
  self.params = [item for item in self.params if item.get('value')]
@@ -620,8 +617,14 @@ class Query(Base):
620
617
 
621
618
  Returns:
622
619
  str: The thumbnail URL.
620
+
621
+ Example:
622
+ >>> from geobox import GeoboxClient
623
+ >>> from geobox.query import Query
624
+ >>> client = GeoboxClient()
625
+ >>> query = Query.get_query(client, uuid="12345678-1234-5678-1234-567812345678")
626
+ >>> query.thumbnail
623
627
  """
624
- self._check_access()
625
628
  return super().thumbnail()
626
629
 
627
630
 
@@ -646,8 +649,6 @@ class Query(Base):
646
649
  >>> query = Query.get_query(client, uuid="12345678-1234-5678-1234-567812345678")
647
650
  >>> query.save_as_layer(layer_name='test')
648
651
  """
649
- self._check_access()
650
-
651
652
  params = [{
652
653
  "name": item.get('name'),
653
654
  "type": item.get('type'),
@@ -665,3 +666,27 @@ class Query(Base):
665
666
  response = self.api.post(endpoint, data)
666
667
  task = Task.get_task(self.api, response.get('task_id'))
667
668
  return task
669
+
670
+
671
+ def to_async(self, async_client: 'AsyncGeoboxClient') -> 'AsyncQuery':
672
+ """
673
+ Switch to async version of the query instance to have access to the async methods
674
+
675
+ Args:
676
+ async_client (AsyncGeoboxClient): The async version of the GeoboxClient instance for making requests.
677
+
678
+ Returns:
679
+ geobox.aio.query.Query: the async instance of the query.
680
+
681
+ Example:
682
+ >>> from geobox import Geoboxclient
683
+ >>> from geobox.aio import AsyncGeoboxClient
684
+ >>> from geobox.query import Query
685
+ >>> client = GeoboxClient()
686
+ >>> query = Query.get_query(client, uuid="12345678-1234-5678-1234-567812345678")
687
+ >>> async with AsyncGeoboxClient() as async_client:
688
+ >>> async_query = query.to_async(async_client)
689
+ """
690
+ from .aio.query import Query as AsyncQuery
691
+
692
+ return AsyncQuery(api=async_client, uuid=self.uuid, data=self.data)
geobox/raster.py CHANGED
@@ -12,15 +12,11 @@ from .task import Task
12
12
  if TYPE_CHECKING:
13
13
  from . import GeoboxClient
14
14
  from .user import User
15
+ from .aio import AsyncGeoboxClient
16
+ from .aio.raster import Raster as AsyncRaster
15
17
 
16
18
  class Raster(Base):
17
- """
18
- A class to represent a Raster in Geobox.
19
19
 
20
- This class provides functionality to interact with rasters in Geobox.
21
- It supports various operations including CRUD operations on rasters, as well as advanced operations like getting statistics, points, and tiles.
22
- It also provides properties to access the raster data, and a method to download the raster.
23
- """
24
20
  BASE_ENDPOINT: str = 'rasters/'
25
21
 
26
22
  def __init__(self,
@@ -322,13 +318,6 @@ class Raster(Base):
322
318
 
323
319
  Raises:
324
320
  ValueError: If save_path does not end with a '/'.
325
-
326
- Example:
327
- >>> from geobox import GeoboxClient
328
- >>> from geobox.file import File
329
- >>> from geobox import GeoboxClient
330
- >>> client = GeoboxClient()
331
- >>> file_path = File.get_file(client, uuid="12345678-1234-5678-1234-567812345678")
332
321
  """
333
322
  # If save_path is provided, check if it ends with a '/'
334
323
  if save_path and save_path.endswith('/'):
@@ -848,3 +837,27 @@ class Raster(Base):
848
837
  >>> raster.cache_size
849
838
  """
850
839
  return super()._cache_size(self.endpoint)
840
+
841
+
842
+ def to_async(self, async_client: 'AsyncGeoboxClient') -> 'AsyncRaster':
843
+ """
844
+ Switch to async version of the raster instance to have access to the async methods
845
+
846
+ Args:
847
+ async_client (AsyncGeoboxClient): The async version of the GeoboxClient instance for making requests.
848
+
849
+ Returns:
850
+ geobox.aio.raster.Raster: the async instance of the raster.
851
+
852
+ Example:
853
+ >>> from geobox import Geoboxclient
854
+ >>> from geobox.aio import AsyncGeoboxClient
855
+ >>> from geobox.raster import Raster
856
+ >>> client = GeoboxClient()
857
+ >>> raster = Raster.get_raster(client, uuid="12345678-1234-5678-1234-567812345678")
858
+ >>> async with AsyncGeoboxClient() as async_client:
859
+ >>> async_raster = raster.to_async(async_client)
860
+ """
861
+ from .aio.raster import Raster as AsyncRaster
862
+
863
+ return AsyncRaster(api=async_client, uuid=self.uuid, data=self.data)
geobox/scene.py CHANGED
@@ -6,6 +6,8 @@ from .base import Base
6
6
  if TYPE_CHECKING:
7
7
  from . import GeoboxClient
8
8
  from .user import User
9
+ from .aio import AsyncGeoboxClient
10
+ from .aio.scene import Scene as AsyncScene
9
11
 
10
12
  class Scene(Base):
11
13
 
@@ -314,3 +316,27 @@ class Scene(Base):
314
316
  'limit': limit
315
317
  }
316
318
  return super()._get_shared_users(self.endpoint, params)
319
+
320
+
321
+ def to_async(self, async_client: 'AsyncGeoboxClient') -> 'AsyncScene':
322
+ """
323
+ Switch to async version of the scene instance to have access to the async methods
324
+
325
+ Args:
326
+ async_client (AsyncGeoboxClient): The async version of the GeoboxClient instance for making requests.
327
+
328
+ Returns:
329
+ geobox.aio.scene.Scene: the async instance of the scene.
330
+
331
+ Example:
332
+ >>> from geobox import Geoboxclient
333
+ >>> from geobox.aio import AsyncGeoboxClient
334
+ >>> from geobox.scene import Scene
335
+ >>> client = GeoboxClient()
336
+ >>> scene = Scene.get_scene(client, uuid="12345678-1234-5678-1234-567812345678")
337
+ >>> async with AsyncGeoboxClient() as async_client:
338
+ >>> async_scene = scene.to_async(async_client)
339
+ """
340
+ from .aio.scene import Scene as AsyncScene
341
+
342
+ return AsyncScene(api=async_client, uuid=self.uuid, data=self.data)
geobox/settings.py CHANGED
@@ -8,6 +8,9 @@ from .enums import MaxLogPolicy, InvalidDataPolicy, LoginFailurePolicy, MaxConcu
8
8
 
9
9
  if TYPE_CHECKING:
10
10
  from . import GeoboxClient
11
+ from .aio import AsyncGeoboxClient
12
+ from .aio.settings import SystemSettings as AsyncSystemSettings
13
+
11
14
 
12
15
  class SystemSettings(Base):
13
16
 
@@ -163,4 +166,30 @@ class SystemSettings(Base):
163
166
  "blocked_ip_addresses": kwargs.get('blocked_ip_addresses'),
164
167
 
165
168
  }
166
- return super()._update(self.BASE_ENDPOINT, data)
169
+ return super()._update(self.BASE_ENDPOINT, data)
170
+
171
+
172
+ def to_async(self, async_client: 'AsyncGeoboxClient') -> 'AsyncSystemSettings':
173
+ """
174
+ Switch to async version of the system settings instance to have access to the async methods
175
+
176
+ Args:
177
+ async_client (AsyncGeoboxClient): The async version of the GeoboxClient instance for making requests.
178
+
179
+ Returns:
180
+ geobox.aio.settings.SystemSettings: the async instance of the system settings.
181
+
182
+ Example:
183
+ >>> from geobox import Geoboxclient
184
+ >>> from geobox.aio import AsyncGeoboxClient
185
+ >>> from geobox.setting import SystemSettings
186
+ >>> client = GeoboxClient()
187
+ >>> settings = SystemSetting.get_system_settings(client)
188
+ or
189
+ >>> settings = client.get_system_settings()
190
+ >>> async with AsyncGeoboxClient() as async_client:
191
+ >>> async_settings = settings.to_async(async_client)
192
+ """
193
+ from .aio.settings import SystemSettings as AsyncSystemSettings
194
+
195
+ return AsyncSystemSettings(api=async_client, data=self.data)
geobox/task.py CHANGED
@@ -12,15 +12,12 @@ if TYPE_CHECKING:
12
12
  from .model3d import Model
13
13
  from .file import File
14
14
  from .tile3d import Tile3d
15
+ from .aio import AsyncGeoboxClient
16
+ from .aio.task import Task as AsyncTask
17
+
15
18
 
16
19
  class Task(Base):
17
- """
18
- A class to represent a task in Geobox.
19
20
 
20
- This class provides functionality to interact with tasks in Geobox.
21
- It supports various operations including getting tasks, as well as advanced operations like waiting for a task to finish.
22
- It also provides properties to access the task data, and a method to abort the task.
23
- """
24
21
  BASE_ENDPOINT: str = 'tasks/'
25
22
 
26
23
  def __init__(self,
@@ -377,3 +374,28 @@ class Task(Base):
377
374
  """
378
375
  return super()._get_detail(api, cls.BASE_ENDPOINT, uuid, factory_func=lambda api, item: Task(api, item['uuid'], item))
379
376
 
377
+
378
+ def to_async(self, async_client: 'AsyncGeoboxClient') -> 'AsyncTask':
379
+ """
380
+ Switch to async version of the task instance to have access to the async methods
381
+
382
+ Args:
383
+ async_client (AsyncGeoboxClient): The async version of the GeoboxClient instance for making requests.
384
+
385
+ Returns:
386
+ geobox.aio.task.Task: the async instance of the task.
387
+
388
+ Example:
389
+ >>> from geobox import Geoboxclient
390
+ >>> from geobox.aio import AsyncGeoboxClient
391
+ >>> from geobox.task import Task
392
+ >>> client = GeoboxClient()
393
+ >>> task = Task.get_task(client, uuid="12345678-1234-5678-1234-567812345678")
394
+ or
395
+ >>> task = client.get_task(uuid="12345678-1234-5678-1234-567812345678")
396
+ >>> async with AsyncGeoboxClient() as async_client:
397
+ >>> async_task = task.to_async(async_client)
398
+ """
399
+ from .aio.task import Task as AsyncTask
400
+
401
+ return AsyncTask(api=async_client, uuid=self.uuid, data=self.data)
geobox/tile3d.py CHANGED
@@ -6,6 +6,8 @@ from .base import Base
6
6
  if TYPE_CHECKING:
7
7
  from . import GeoboxClient
8
8
  from .user import User
9
+ from .aio import AsyncGeoboxClient
10
+ from .aio.tile3d import Tile3d as AsyncTile3d
9
11
 
10
12
 
11
13
  class Tile3d(Base):
@@ -310,4 +312,28 @@ class Tile3d(Base):
310
312
  >>> tile_json = tile.get_tileset_json()
311
313
  """
312
314
  endpoint = urljoin(self.endpoint, 'tileset.json')
313
- return self.api.get(endpoint)
315
+ return self.api.get(endpoint)
316
+
317
+
318
+ def to_async(self, async_client: 'AsyncGeoboxClient') -> 'AsyncTile3d':
319
+ """
320
+ Switch to async version of the 3d tile instance to have access to the async methods
321
+
322
+ Args:
323
+ async_client (AsyncGeoboxClient): The async version of the GeoboxClient instance for making requests.
324
+
325
+ Returns:
326
+ geobox.aio.tile3d.Tile3d: the async instance of the 3d tile.
327
+
328
+ Example:
329
+ >>> from geobox import Geoboxclient
330
+ >>> from geobox.aio import AsyncGeoboxClient
331
+ >>> from geobox.tile3d import Tile3d
332
+ >>> client = GeoboxClient()
333
+ >>> tile = Tile3d.get_3dtile(api=client, uuid="12345678-1234-5678-1234-567812345678")
334
+ >>> async with AsyncGeoboxClient() as async_client:
335
+ >>> async_tile = tile.to_async(async_client)
336
+ """
337
+ from .aio.tile3d import Tile3d as AsyncTile3d
338
+
339
+ return AsyncTile3d(api=async_client, uuid=self.uuid, data=self.data)
geobox/tileset.py CHANGED
@@ -9,14 +9,11 @@ from .task import Task
9
9
  if TYPE_CHECKING:
10
10
  from . import GeoboxClient
11
11
  from .user import User
12
+ from .aio import AsyncGeoboxClient
13
+ from .aio.tileset import Tileset as AsyncTileset
12
14
 
13
15
  class Tileset(Base):
14
- """
15
- A class to interact with tilesets in Geobox.
16
16
 
17
- This class provides functionality to interact with tilesets in Geobox.
18
- It supports various operations including CRUD operations on tilesets, as well as advanced operations like getting layers, and sharing tilesets.
19
- """
20
17
  BASE_ENDPOINT: str = 'tilesets/'
21
18
 
22
19
  def __init__(self,
@@ -635,3 +632,27 @@ class Tileset(Base):
635
632
  >>> tileset.clear_cache()
636
633
  """
637
634
  super()._clear_cache(endpoint=self.endpoint)
635
+
636
+
637
+ def to_async(self, async_client: 'AsyncGeoboxClient') -> 'AsyncTileset':
638
+ """
639
+ Switch to async version of the tileset instance to have access to the async methods
640
+
641
+ Args:
642
+ async_client (AsyncGeoboxClient): The async version of the GeoboxClient instance for making requests.
643
+
644
+ Returns:
645
+ geobox.aio.tileset.Tileset: the async instance of the tileset.
646
+
647
+ Example:
648
+ >>> from geobox import Geoboxclient
649
+ >>> from geobox.aio import AsyncGeoboxClient
650
+ >>> from geobox.tileset import Tileset
651
+ >>> client = GeoboxClient()
652
+ >>> tileset = Tileset.get_tileset(client, uuid="12345678-1234-5678-1234-567812345678")
653
+ >>> async with AsyncGeoboxClient() as async_client:
654
+ >>> async_tileset = tileset.to_async(async_client)
655
+ """
656
+ from .aio.tileset import Tileset as AsyncTileset
657
+
658
+ return AsyncTileset(api=async_client, uuid=self.uuid, data=self.data)
geobox/usage.py CHANGED
@@ -10,6 +10,8 @@ from .enums import UsageScale, UsageParam
10
10
 
11
11
  if TYPE_CHECKING:
12
12
  from . import GeoboxClient
13
+ from .aio import AsyncGeoboxClient
14
+ from .aio.usage import Usage as AsyncUsage
13
15
 
14
16
 
15
17
  class Usage(Base):
@@ -208,4 +210,33 @@ class Usage(Base):
208
210
  'user_id': user_id if user_id else None
209
211
  })
210
212
  endpoint = f"{cls.BASE_ENDPOINT}update"
211
- return api.post(endpoint, payload=data)
213
+ return api.post(endpoint, payload=data)
214
+
215
+
216
+ def to_async(self, async_client: 'AsyncGeoboxClient') -> 'AsyncUsage':
217
+ """
218
+ Switch to async version of the usage instance to have access to the async methods
219
+
220
+ Args:
221
+ async_client (AsyncGeoboxClient): The async version of the GeoboxClient instance for making requests.
222
+
223
+ Returns:
224
+ geobox.aio.usage.Usage: the async instance of the usage.
225
+
226
+ Example:
227
+ >>> from geobox import Geoboxclient
228
+ >>> from geobox.aio import AsyncGeoboxClient
229
+ >>> from geobox.usage import Usage
230
+ >>> client = GeoboxClient()
231
+ >>> user = client.get_user()
232
+ >>> usage = Usage.get_api_usage(client,
233
+ ... resource=user,
234
+ ... scale=UsageScale.Day,
235
+ ... param=UsageParam.Calls,
236
+ ... days_before_now=5)
237
+ >>> async with AsyncGeoboxClient() as async_client:
238
+ >>> async_usage = usage.to_async(async_client)
239
+ """
240
+ from .aio.usage import Usage as AsyncUsage
241
+
242
+ return AsyncUsage(api=async_client, user=self.user)
geobox/user.py CHANGED
@@ -8,6 +8,9 @@ from .plan import Plan
8
8
 
9
9
  if TYPE_CHECKING:
10
10
  from . import GeoboxClient
11
+ from .aio import AsyncGeoboxClient
12
+ from .aio.user import Session as AsyncSession
13
+ from .aio.user import User as AsyncUser
11
14
 
12
15
 
13
16
  class User(Base):
@@ -270,7 +273,7 @@ class User(Base):
270
273
  >>> from geobox.user import User
271
274
  >>> client = GeoboxClient()
272
275
  >>> user = User.get_user(client, user_id=1)
273
- >>> user.update_user(status=UserStatus.PENDING)
276
+ >>> user.update(status=UserStatus.PENDING)
274
277
  """
275
278
  data = {
276
279
  "username": kwargs.get('username'),
@@ -337,9 +340,9 @@ class User(Base):
337
340
  or
338
341
  >>> user = client.get_user(user_id=1)
339
342
 
340
- >>> user.get_user_sessions()
343
+ >>> user.get_sessions()
341
344
  or
342
- >>> client.get_user_sessions()
345
+ >>> client.get_sessions()
343
346
  """
344
347
  params = clean_data({
345
348
  'f': 'json'
@@ -370,7 +373,7 @@ class User(Base):
370
373
  >>> from geobox import GeoboxClient
371
374
  >>> from geobox.user import User
372
375
  >>> client = GeoboxClient()
373
- >>> user = client.get_user()
376
+ >>> user = client.get_user(user_id=1)
374
377
  >>> user.change_password(new_password='user_new_password')
375
378
  """
376
379
  data = clean_data({
@@ -382,7 +385,7 @@ class User(Base):
382
385
 
383
386
  def renew_plan(self) -> None:
384
387
  """
385
- Renew the user plan
388
+ Renew the user plan (privileges required)
386
389
 
387
390
  Returns:
388
391
  None
@@ -396,6 +399,31 @@ class User(Base):
396
399
  self.api.post(endpoint)
397
400
 
398
401
 
402
+ def to_async(self, async_client: 'AsyncGeoboxClient') -> 'AsyncUser':
403
+ """
404
+ Switch to async version of the user instance to have access to the async methods
405
+
406
+ Args:
407
+ async_client (AsyncGeoboxClient): The async version of the GeoboxClient instance for making requests.
408
+
409
+ Returns:
410
+ geobox.aio.user.User: the async instance of the user.
411
+
412
+ Example:
413
+ >>> from geobox import Geoboxclient
414
+ >>> from geobox.aio import AsyncGeoboxClient
415
+ >>> from geobox.user import User
416
+ >>> client = GeoboxClient()
417
+ >>> user = User.get_user(client) # without user_id parameter, it gets the current user
418
+ or
419
+ >>> user = client.get_user() # without user_id parameter, it gets the current user
420
+ >>> async with AsyncGeoboxClient() as async_client:
421
+ >>> async_user = user.to_async(async_client)
422
+ """
423
+ from .aio.user import User as AsyncUser
424
+
425
+ return AsyncUser(api=async_client, user_id=self.user_id, data=self.data)
426
+
399
427
 
400
428
 
401
429
  class Session(Base):
@@ -445,4 +473,32 @@ class Session(Base):
445
473
  'user_id': self.user.user_id,
446
474
  'session_uuid': self.uuid
447
475
  })
448
- self.user.api.post(self.endpoint, data)
476
+ self.user.api.post(self.endpoint, data)
477
+
478
+
479
+ def to_async(self, async_client: 'AsyncGeoboxClient') -> 'AsyncSession':
480
+ """
481
+ Switch to async version of the session instance to have access to the async methods
482
+
483
+ Args:
484
+ async_client (AsyncGeoboxClient): The async version of the GeoboxClient instance for making requests.
485
+
486
+ Returns:
487
+ geobox.aio.user.Session: the async instance of the session.
488
+
489
+ Example:
490
+ >>> from geobox import Geoboxclient
491
+ >>> from geobox.aio import AsyncGeoboxClient
492
+ >>> from geobox.user import User
493
+ >>> client = GeoboxClient()
494
+ >>> user = User.get_user(client) # without user_id parameter, it gets the current user
495
+ or
496
+ >>> user = client.get_user() # without user_id parameter, it gets the current user
497
+ >>> session = user.get_sessions()[0]
498
+ >>> async with AsyncGeoboxClient() as async_client:
499
+ >>> async_session = session.to_async(async_client)
500
+ """
501
+ from .aio.user import Session as AsyncSession
502
+
503
+ async_user = self.user.to_async(async_client=async_client)
504
+ return AsyncSession(uuid=self.uuid, data=self.data, user=async_user)
geobox/utils.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from urllib.parse import urlparse, parse_qs, urlencode, urlunparse
2
2
  import base64
3
+ import os
3
4
 
4
5
 
5
6
  def xor_encode(s, key=42):
@@ -8,6 +9,39 @@ def xor_encode(s, key=42):
8
9
  return encoded_bytes.decode('utf-8')
9
10
 
10
11
 
12
+ def get_save_path(save_path: str = None) -> str:
13
+ """
14
+ Get the path where the file should be saved.
15
+
16
+ Args:
17
+ save_path (str, optional): The path to save the file.
18
+
19
+ Returns:
20
+ str: The path where the file is saved.
21
+
22
+ Raises:
23
+ ValueError: If save_path does not end with a '/'.
24
+ """
25
+ # If save_path is provided, check if it ends with a '/'
26
+ if save_path and save_path.endswith('/'):
27
+ return f'{save_path}'
28
+
29
+ if save_path and not save_path.endswith('/'):
30
+ raise ValueError("save_path must end with a '/'")
31
+
32
+ return os.getcwd() + '/'
33
+
34
+
35
+ def get_unique_filename(save_path: str, file_name: str) -> str:
36
+ base, ext = os.path.splitext(file_name)
37
+ counter = 1
38
+ new_file = f"{save_path}{base}({counter}){ext}"
39
+ while os.path.exists(new_file):
40
+ new_file = f"{save_path}{base}({counter}){ext}"
41
+ counter += 1
42
+ return new_file
43
+
44
+
11
45
  def clean_data(data: dict) -> dict:
12
46
  """
13
47
  Cleans the input data by removing keys with None values.