geobox 1.2.3__tar.gz → 1.3.0__tar.gz

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 (69) hide show
  1. {geobox-1.2.3 → geobox-1.3.0}/PKG-INFO +1 -1
  2. {geobox-1.2.3 → geobox-1.3.0}/geobox/enums.py +1 -1
  3. {geobox-1.2.3 → geobox-1.3.0}/geobox/user.py +32 -5
  4. {geobox-1.2.3 → geobox-1.3.0}/geobox/vectorlayer.py +4 -1
  5. {geobox-1.2.3 → geobox-1.3.0}/geobox/view.py +1 -27
  6. {geobox-1.2.3 → geobox-1.3.0}/geobox.egg-info/PKG-INFO +1 -1
  7. {geobox-1.2.3 → geobox-1.3.0}/pyproject.toml +1 -1
  8. {geobox-1.2.3 → geobox-1.3.0}/tests/test_user.py +5 -0
  9. {geobox-1.2.3 → geobox-1.3.0}/tests/test_vectorlayer.py +10 -1
  10. {geobox-1.2.3 → geobox-1.3.0}/tests/test_view.py +1 -26
  11. {geobox-1.2.3 → geobox-1.3.0}/LICENSE +0 -0
  12. {geobox-1.2.3 → geobox-1.3.0}/README.md +0 -0
  13. {geobox-1.2.3 → geobox-1.3.0}/geobox/__init__.py +0 -0
  14. {geobox-1.2.3 → geobox-1.3.0}/geobox/api.py +0 -0
  15. {geobox-1.2.3 → geobox-1.3.0}/geobox/apikey.py +0 -0
  16. {geobox-1.2.3 → geobox-1.3.0}/geobox/attachment.py +0 -0
  17. {geobox-1.2.3 → geobox-1.3.0}/geobox/base.py +0 -0
  18. {geobox-1.2.3 → geobox-1.3.0}/geobox/basemap.py +0 -0
  19. {geobox-1.2.3 → geobox-1.3.0}/geobox/dashboard.py +0 -0
  20. {geobox-1.2.3 → geobox-1.3.0}/geobox/exception.py +0 -0
  21. {geobox-1.2.3 → geobox-1.3.0}/geobox/feature.py +0 -0
  22. {geobox-1.2.3 → geobox-1.3.0}/geobox/field.py +0 -0
  23. {geobox-1.2.3 → geobox-1.3.0}/geobox/file.py +0 -0
  24. {geobox-1.2.3 → geobox-1.3.0}/geobox/log.py +0 -0
  25. {geobox-1.2.3 → geobox-1.3.0}/geobox/map.py +0 -0
  26. {geobox-1.2.3 → geobox-1.3.0}/geobox/model3d.py +0 -0
  27. {geobox-1.2.3 → geobox-1.3.0}/geobox/mosaic.py +0 -0
  28. {geobox-1.2.3 → geobox-1.3.0}/geobox/plan.py +0 -0
  29. {geobox-1.2.3 → geobox-1.3.0}/geobox/query.py +0 -0
  30. {geobox-1.2.3 → geobox-1.3.0}/geobox/raster.py +0 -0
  31. {geobox-1.2.3 → geobox-1.3.0}/geobox/route.py +0 -0
  32. {geobox-1.2.3 → geobox-1.3.0}/geobox/scene.py +0 -0
  33. {geobox-1.2.3 → geobox-1.3.0}/geobox/settings.py +0 -0
  34. {geobox-1.2.3 → geobox-1.3.0}/geobox/task.py +0 -0
  35. {geobox-1.2.3 → geobox-1.3.0}/geobox/tile3d.py +0 -0
  36. {geobox-1.2.3 → geobox-1.3.0}/geobox/tileset.py +0 -0
  37. {geobox-1.2.3 → geobox-1.3.0}/geobox/usage.py +0 -0
  38. {geobox-1.2.3 → geobox-1.3.0}/geobox/utils.py +0 -0
  39. {geobox-1.2.3 → geobox-1.3.0}/geobox/version.py +0 -0
  40. {geobox-1.2.3 → geobox-1.3.0}/geobox/workflow.py +0 -0
  41. {geobox-1.2.3 → geobox-1.3.0}/geobox.egg-info/SOURCES.txt +0 -0
  42. {geobox-1.2.3 → geobox-1.3.0}/geobox.egg-info/dependency_links.txt +0 -0
  43. {geobox-1.2.3 → geobox-1.3.0}/geobox.egg-info/requires.txt +0 -0
  44. {geobox-1.2.3 → geobox-1.3.0}/geobox.egg-info/top_level.txt +0 -0
  45. {geobox-1.2.3 → geobox-1.3.0}/setup.cfg +0 -0
  46. {geobox-1.2.3 → geobox-1.3.0}/tests/test_api.py +0 -0
  47. {geobox-1.2.3 → geobox-1.3.0}/tests/test_apikey.py +0 -0
  48. {geobox-1.2.3 → geobox-1.3.0}/tests/test_attachment.py +0 -0
  49. {geobox-1.2.3 → geobox-1.3.0}/tests/test_basemap.py +0 -0
  50. {geobox-1.2.3 → geobox-1.3.0}/tests/test_dashboard.py +0 -0
  51. {geobox-1.2.3 → geobox-1.3.0}/tests/test_feature.py +0 -0
  52. {geobox-1.2.3 → geobox-1.3.0}/tests/test_field.py +0 -0
  53. {geobox-1.2.3 → geobox-1.3.0}/tests/test_file.py +0 -0
  54. {geobox-1.2.3 → geobox-1.3.0}/tests/test_log.py +0 -0
  55. {geobox-1.2.3 → geobox-1.3.0}/tests/test_map.py +0 -0
  56. {geobox-1.2.3 → geobox-1.3.0}/tests/test_model3d.py +0 -0
  57. {geobox-1.2.3 → geobox-1.3.0}/tests/test_mosaic.py +0 -0
  58. {geobox-1.2.3 → geobox-1.3.0}/tests/test_plan.py +0 -0
  59. {geobox-1.2.3 → geobox-1.3.0}/tests/test_query.py +0 -0
  60. {geobox-1.2.3 → geobox-1.3.0}/tests/test_raster.py +0 -0
  61. {geobox-1.2.3 → geobox-1.3.0}/tests/test_route.py +0 -0
  62. {geobox-1.2.3 → geobox-1.3.0}/tests/test_scene.py +0 -0
  63. {geobox-1.2.3 → geobox-1.3.0}/tests/test_settings.py +0 -0
  64. {geobox-1.2.3 → geobox-1.3.0}/tests/test_task.py +0 -0
  65. {geobox-1.2.3 → geobox-1.3.0}/tests/test_tile3d.py +0 -0
  66. {geobox-1.2.3 → geobox-1.3.0}/tests/test_tileset.py +0 -0
  67. {geobox-1.2.3 → geobox-1.3.0}/tests/test_usage.py +0 -0
  68. {geobox-1.2.3 → geobox-1.3.0}/tests/test_version.py +0 -0
  69. {geobox-1.2.3 → geobox-1.3.0}/tests/test_workflow.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geobox
3
- Version: 1.2.3
3
+ Version: 1.3.0
4
4
  Summary: SDK for Geobox's APIs
5
5
  Author-email: Hamid Heydari <heydari.h62@gmail.com>
6
6
  License: MIT
@@ -257,7 +257,7 @@ class UserRole(Enum):
257
257
 
258
258
  EDITOR = "Editor"
259
259
 
260
- VIEWR = "Viewer"
260
+ VIEWER = "Viewer"
261
261
 
262
262
 
263
263
  class UserStatus(Enum):
@@ -36,6 +36,17 @@ class User(Base):
36
36
  str: A string representation of the User instance.
37
37
  """
38
38
  return f'User(id={self.id}, first_name={self.first_name}, last_name={self.last_name})'
39
+
40
+
41
+ @property
42
+ def role(self) -> 'UserRole':
43
+ """
44
+ User role property
45
+
46
+ Returns:
47
+ UserRole: the user role
48
+ """
49
+ return UserRole(self.data.get('role')) if self.data.get('role') else None
39
50
 
40
51
 
41
52
  @property
@@ -94,6 +105,7 @@ class User(Base):
94
105
  """
95
106
  params = {
96
107
  'f': 'json',
108
+ 'status': kwargs.get('status').value if kwargs.get('status') else None,
97
109
  'q': kwargs.get('q'),
98
110
  'search': kwargs.get('search'),
99
111
  'search_fields': kwargs.get('search_fields'),
@@ -264,18 +276,33 @@ class User(Base):
264
276
  >>> user.update_user(status=UserStatus.PENDING)
265
277
  """
266
278
  data = {
267
- "csrf_token": kwargs.get('csrf_token'),
268
279
  "username": kwargs.get('username'),
269
280
  "email": kwargs.get('email'),
270
281
  "first_name": kwargs.get('first_name'),
271
282
  "last_name": kwargs.get('last_name'),
272
- "mobile": kwargs.get('mobile'),
273
283
  "status": kwargs.get('status').value if kwargs.get('status') else None,
274
284
  "role": kwargs.get('role').value if kwargs.get('role') else None,
275
- "plan_id": kwargs.get('plan').id if kwargs.get('plan') else None,
276
- "expiration_date": kwargs.get('expiration_date')
277
285
  }
278
- return super()._update(self.endpoint, data)
286
+ data = clean_data(data)
287
+
288
+ try:
289
+ data['mobile'] = None if kwargs['mobile'] == '' else kwargs['mobile']
290
+ except:
291
+ pass
292
+
293
+ try:
294
+ data['plan_id'] = None if kwargs['plan'] == '' else kwargs['plan'].id
295
+ except:
296
+ pass
297
+
298
+ try:
299
+ data['expiration_date'] = None if kwargs['expiration_date'] == '' else kwargs['expiration_date']
300
+ except:
301
+ pass
302
+
303
+ response = self.api.put(self.endpoint, data)
304
+ self._update_properties(response)
305
+ return response
279
306
 
280
307
 
281
308
  def delete(self) -> None:
@@ -454,7 +454,10 @@ class VectorLayer(Base):
454
454
  >>> layer = VectorLayer.get_vector(api=client, uuid="12345678-1234-5678-1234-567812345678")
455
455
  >>> layer.wfs
456
456
  """
457
- return f'{self.api.base_url}{self.endpoint}wfs/'
457
+ if self.api.access_token:
458
+ return f'{self.api.base_url}{self.endpoint}wfs/'
459
+ elif self.api.apikey:
460
+ return f'{self.api.base_url}{self.endpoint}apikey:{self.api.apikey}/wfs/'
458
461
 
459
462
 
460
463
  def get_fields(self) -> List['Field']:
@@ -164,7 +164,7 @@ class VectorLayerView(VectorLayer):
164
164
  'include_settings': include_settings
165
165
  }
166
166
  return super()._get_list_by_ids(api=api,
167
- endpoint=f'{cls.BASE_ENDPOINT}get-views/',
167
+ endpoint=f'{cls.BASE_ENDPOINT}get-layers/',
168
168
  params=params,
169
169
  factory_func=lambda api, item: VectorLayerView(api, item['uuid'], LayerType(item['layer_type']), item))
170
170
 
@@ -407,32 +407,6 @@ class VectorLayerView(VectorLayer):
407
407
  >>> field = view.get_field_by_name(name='test')
408
408
  """
409
409
  return super().get_field_by_name(name)
410
-
411
-
412
- def add_field(self, name: str, data_type: 'FieldType', data: Dict = {}) -> 'Field':
413
- """
414
- Add a new field to the vector layer view.
415
-
416
- Args:
417
- name (str): The name of the new field.
418
- data_type (FieldType): The data type of the new field.
419
- data (Dict): Additional field properties (display_name, description, etc.).
420
-
421
- Returns:
422
- Field: The newly created field instance.
423
-
424
- Raises:
425
- ValidationError: If the field data is invalid.
426
- ApiRequestError: If the API request fails.
427
-
428
- Example:
429
- >>> from geobox import GeoboxClient
430
- >>> from geobox.view import VectorLayerView
431
- >>> client = GeoboxClient()
432
- >>> view = VectorLayerView.get_view(client, uuid="12345678-1234-5678-1234-567812345678")
433
- >>> field = view.add_field(name="new_field", data_type=FieldType.String)
434
- """
435
- return super().add_field(name, data_type, data)
436
410
 
437
411
 
438
412
  def calculate_field(self, target_field: str, expression: str, q: str = None, bbox: List[float] = None,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geobox
3
- Version: 1.2.3
3
+ Version: 1.3.0
4
4
  Summary: SDK for Geobox's APIs
5
5
  Author-email: Hamid Heydari <heydari.h62@gmail.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "geobox"
7
- version = "1.2.3"
7
+ version = "1.3.0"
8
8
  description = "SDK for Geobox's APIs"
9
9
  authors = [
10
10
  {name = "Hamid Heydari", email = "heydari.h62@gmail.com"}
@@ -19,6 +19,11 @@ def test_repr(api, mock_user_data):
19
19
  assert repr(user) == f"User(id={user.id}, first_name=test 1, last_name=test 1)"
20
20
 
21
21
 
22
+ def test_role(api, mock_admin_user_data):
23
+ user = User(api, user_id=mock_admin_user_data['id'], data=mock_admin_user_data)
24
+ assert user.role == UserRole.ACCOUNT_ADMIN
25
+
26
+
22
27
  def test_status(api, mock_admin_user_data):
23
28
  user = User(api, user_id=mock_admin_user_data['id'], data=mock_admin_user_data)
24
29
  assert user.status == UserStatus.DISABLED
@@ -254,12 +254,21 @@ def test_create_version(api, mock_vector_data, layer_type, mock_version_data):
254
254
 
255
255
 
256
256
  @pytest.mark.parametrize("layer_type", [type for type in LayerType])
257
- def test_wfs(api, mock_vector_data, layer_type):
257
+ def test_wfs_access_token(api, mock_vector_data, layer_type):
258
258
  layer = VectorLayer(api, uuid=mock_vector_data['uuid'], data=mock_vector_data, layer_type=layer_type)
259
259
  wfs_url = layer.wfs
260
260
  assert wfs_url == f'{api.base_url}{layer.endpoint}wfs/'
261
261
 
262
262
 
263
+ @pytest.mark.parametrize("layer_type", [type for type in LayerType])
264
+ def test_wfs_apikey(api, mock_vector_data, layer_type):
265
+ api.access_token = None
266
+ api.apikey = '123456789'
267
+ layer = VectorLayer(api, uuid=mock_vector_data['uuid'], data=mock_vector_data, layer_type=layer_type)
268
+ wfs_url = layer.wfs
269
+ assert wfs_url == f'{api.base_url}{layer.endpoint}apikey:{api.apikey}/wfs/'
270
+
271
+
263
272
  @pytest.mark.parametrize("layer_type", [type for type in LayerType])
264
273
  def test_get_fields(api, mock_vector_data, layer_type, mock_field_data):
265
274
  """Test getting the fields of a layer."""
@@ -138,7 +138,7 @@ def test_get_views_by_ids(api, mock_view_data, layer_type):
138
138
 
139
139
  layers = VectorLayerView.get_views_by_ids(api, [1, 2])
140
140
 
141
- api.get.assert_called_once_with(f'{VectorLayerView.BASE_ENDPOINT}get-views/?ids=%5B1%2C+2%5D&include_settings=False')
141
+ api.get.assert_called_once_with(f'{VectorLayerView.BASE_ENDPOINT}get-layers/?ids=%5B1%2C+2%5D&include_settings=False')
142
142
  assert len(layers) == 2
143
143
  assert all(isinstance(m, VectorLayerView) for m in layers)
144
144
  assert layers[0].data == {**mock_view_data, **{'id': 1}}
@@ -330,31 +330,6 @@ def test_get_field_by_name(api, mock_view_data, layer_type, mock_field_data):
330
330
  view.get_field_by_name(name=mock_field_data['name'])
331
331
 
332
332
 
333
- @pytest.mark.parametrize("layer_type", [type for type in LayerType])
334
- def test_add_field(api, mock_view_data, layer_type, mock_field_data):
335
- """Test adding a field to a layer."""
336
- view = VectorLayerView(
337
- api=api,
338
- uuid=mock_view_data['uuid'],
339
- layer_type=layer_type,
340
- data=mock_view_data
341
- )
342
- api.post.return_value = mock_field_data
343
- del mock_field_data['created_at']
344
- field = view.add_field(name=mock_field_data['name'], data_type=FieldType.String, data=mock_field_data)
345
- assert isinstance(field, Field)
346
- assert field.name == mock_field_data['name']
347
- assert field.data_type == FieldType.String
348
- assert field.layer == view
349
- assert field.endpoint == f'{view.endpoint}fields/{field.id}/'
350
- assert field.data == mock_field_data
351
- expected_data = {'id': mock_field_data['id'],
352
- 'name': mock_field_data['name'],
353
- 'datatype': mock_field_data['datatype'],
354
- 'hyperlink': mock_field_data['hyperlink']}
355
- api.post.assert_called_once_with(f'{view.endpoint}fields/', expected_data)
356
-
357
-
358
333
  @pytest.mark.parametrize("layer_type", [type for type in LayerType])
359
334
  def test_calculate_field(api, mock_view_data, layer_type, mock_success_task_data):
360
335
  """Test calculating a field."""
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes