geobox 1.1.0__tar.gz → 1.2.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.1.0 → geobox-1.2.0}/PKG-INFO +1 -1
  2. {geobox-1.1.0 → geobox-1.2.0}/geobox/api.py +5 -5
  3. {geobox-1.1.0 → geobox-1.2.0}/geobox/enums.py +15 -1
  4. {geobox-1.1.0 → geobox-1.2.0}/geobox/file.py +36 -15
  5. {geobox-1.1.0 → geobox-1.2.0}/geobox.egg-info/PKG-INFO +1 -1
  6. {geobox-1.1.0 → geobox-1.2.0}/pyproject.toml +1 -1
  7. {geobox-1.1.0 → geobox-1.2.0}/tests/test_api.py +4 -4
  8. {geobox-1.1.0 → geobox-1.2.0}/tests/test_file.py +15 -21
  9. {geobox-1.1.0 → geobox-1.2.0}/LICENSE +0 -0
  10. {geobox-1.1.0 → geobox-1.2.0}/README.md +0 -0
  11. {geobox-1.1.0 → geobox-1.2.0}/geobox/__init__.py +0 -0
  12. {geobox-1.1.0 → geobox-1.2.0}/geobox/apikey.py +0 -0
  13. {geobox-1.1.0 → geobox-1.2.0}/geobox/attachment.py +0 -0
  14. {geobox-1.1.0 → geobox-1.2.0}/geobox/base.py +0 -0
  15. {geobox-1.1.0 → geobox-1.2.0}/geobox/basemap.py +0 -0
  16. {geobox-1.1.0 → geobox-1.2.0}/geobox/dashboard.py +0 -0
  17. {geobox-1.1.0 → geobox-1.2.0}/geobox/exception.py +0 -0
  18. {geobox-1.1.0 → geobox-1.2.0}/geobox/feature.py +0 -0
  19. {geobox-1.1.0 → geobox-1.2.0}/geobox/field.py +0 -0
  20. {geobox-1.1.0 → geobox-1.2.0}/geobox/log.py +0 -0
  21. {geobox-1.1.0 → geobox-1.2.0}/geobox/map.py +0 -0
  22. {geobox-1.1.0 → geobox-1.2.0}/geobox/model3d.py +0 -0
  23. {geobox-1.1.0 → geobox-1.2.0}/geobox/mosaic.py +0 -0
  24. {geobox-1.1.0 → geobox-1.2.0}/geobox/plan.py +0 -0
  25. {geobox-1.1.0 → geobox-1.2.0}/geobox/query.py +0 -0
  26. {geobox-1.1.0 → geobox-1.2.0}/geobox/raster.py +0 -0
  27. {geobox-1.1.0 → geobox-1.2.0}/geobox/route.py +0 -0
  28. {geobox-1.1.0 → geobox-1.2.0}/geobox/scene.py +0 -0
  29. {geobox-1.1.0 → geobox-1.2.0}/geobox/settings.py +0 -0
  30. {geobox-1.1.0 → geobox-1.2.0}/geobox/task.py +0 -0
  31. {geobox-1.1.0 → geobox-1.2.0}/geobox/tile3d.py +0 -0
  32. {geobox-1.1.0 → geobox-1.2.0}/geobox/tileset.py +0 -0
  33. {geobox-1.1.0 → geobox-1.2.0}/geobox/usage.py +0 -0
  34. {geobox-1.1.0 → geobox-1.2.0}/geobox/user.py +0 -0
  35. {geobox-1.1.0 → geobox-1.2.0}/geobox/utils.py +0 -0
  36. {geobox-1.1.0 → geobox-1.2.0}/geobox/vectorlayer.py +0 -0
  37. {geobox-1.1.0 → geobox-1.2.0}/geobox/version.py +0 -0
  38. {geobox-1.1.0 → geobox-1.2.0}/geobox/view.py +0 -0
  39. {geobox-1.1.0 → geobox-1.2.0}/geobox/workflow.py +0 -0
  40. {geobox-1.1.0 → geobox-1.2.0}/geobox.egg-info/SOURCES.txt +0 -0
  41. {geobox-1.1.0 → geobox-1.2.0}/geobox.egg-info/dependency_links.txt +0 -0
  42. {geobox-1.1.0 → geobox-1.2.0}/geobox.egg-info/requires.txt +0 -0
  43. {geobox-1.1.0 → geobox-1.2.0}/geobox.egg-info/top_level.txt +0 -0
  44. {geobox-1.1.0 → geobox-1.2.0}/setup.cfg +0 -0
  45. {geobox-1.1.0 → geobox-1.2.0}/tests/test_apikey.py +0 -0
  46. {geobox-1.1.0 → geobox-1.2.0}/tests/test_attachment.py +0 -0
  47. {geobox-1.1.0 → geobox-1.2.0}/tests/test_basemap.py +0 -0
  48. {geobox-1.1.0 → geobox-1.2.0}/tests/test_dashboard.py +0 -0
  49. {geobox-1.1.0 → geobox-1.2.0}/tests/test_feature.py +0 -0
  50. {geobox-1.1.0 → geobox-1.2.0}/tests/test_field.py +0 -0
  51. {geobox-1.1.0 → geobox-1.2.0}/tests/test_log.py +0 -0
  52. {geobox-1.1.0 → geobox-1.2.0}/tests/test_map.py +0 -0
  53. {geobox-1.1.0 → geobox-1.2.0}/tests/test_model3d.py +0 -0
  54. {geobox-1.1.0 → geobox-1.2.0}/tests/test_mosaic.py +0 -0
  55. {geobox-1.1.0 → geobox-1.2.0}/tests/test_plan.py +0 -0
  56. {geobox-1.1.0 → geobox-1.2.0}/tests/test_query.py +0 -0
  57. {geobox-1.1.0 → geobox-1.2.0}/tests/test_raster.py +0 -0
  58. {geobox-1.1.0 → geobox-1.2.0}/tests/test_route.py +0 -0
  59. {geobox-1.1.0 → geobox-1.2.0}/tests/test_scene.py +0 -0
  60. {geobox-1.1.0 → geobox-1.2.0}/tests/test_settings.py +0 -0
  61. {geobox-1.1.0 → geobox-1.2.0}/tests/test_task.py +0 -0
  62. {geobox-1.1.0 → geobox-1.2.0}/tests/test_tile3d.py +0 -0
  63. {geobox-1.1.0 → geobox-1.2.0}/tests/test_tileset.py +0 -0
  64. {geobox-1.1.0 → geobox-1.2.0}/tests/test_usage.py +0 -0
  65. {geobox-1.1.0 → geobox-1.2.0}/tests/test_user.py +0 -0
  66. {geobox-1.1.0 → geobox-1.2.0}/tests/test_vectorlayer.py +0 -0
  67. {geobox-1.1.0 → geobox-1.2.0}/tests/test_version.py +0 -0
  68. {geobox-1.1.0 → geobox-1.2.0}/tests/test_view.py +0 -0
  69. {geobox-1.1.0 → geobox-1.2.0}/tests/test_workflow.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geobox
3
- Version: 1.1.0
3
+ Version: 1.2.0
4
4
  Summary: SDK for Geobox's APIs
5
5
  Author-email: Hamid Heydari <heydari.h62@gmail.com>
6
6
  License: MIT
@@ -597,23 +597,23 @@ class GeoboxClient:
597
597
  return File.get_file(self, uuid=uuid)
598
598
 
599
599
 
600
- def get_file_by_name(self, name: str, user_id: int = None) -> Union['File', None]:
600
+ def get_files_by_name(self, name: str, user_id: int = None) -> List['File']:
601
601
  """
602
- Get a file by name
602
+ Get files by name
603
603
 
604
604
  Args:
605
605
  name (str): the name of the file to get
606
606
  user_id (int, optional): specific user. privileges required.
607
607
 
608
608
  Returns:
609
- File | None: returns the file if a file matches the given name, else None
609
+ List[File]: returns files that matches the given name
610
610
 
611
611
  Example:
612
612
  >>> from geobox import GeoboxClient
613
613
  >>> client = GeoboxClient()
614
- >>> file = client.get_file_by_name(name='test')
614
+ >>> files = client.get_files_by_name(name='test')
615
615
  """
616
- return File.get_file_by_name(self, name, user_id)
616
+ return File.get_files_by_name(self, name, user_id)
617
617
 
618
618
 
619
619
  def upload_file(self, path: str, user_id: int = None, scan_archive: bool = True) -> 'File':
@@ -21,6 +21,20 @@ class PublishFileType(Enum):
21
21
  MODEL3D = 'model3d'
22
22
 
23
23
  class FileType(Enum):
24
+ Compressed = 'Compressed'
25
+ Complex = 'Complex'
26
+ Image = 'Image'
27
+ Video = 'Video'
28
+ Document = 'Document'
29
+ GPKG = 'GPKG'
30
+ DXF = 'DXF'
31
+ Shapefile = 'Shapefile'
32
+ KML = 'KML'
33
+ GLB = 'GLB'
34
+ FileGDB = 'FileGDB'
35
+ GeoTIFF = 'GeoTIFF'
36
+
37
+ class FileFormat(Enum):
24
38
  # Spatial Data Formats
25
39
  Shapefile = '.shp'
26
40
  FileGDB = '.gdb'
@@ -30,7 +44,7 @@ class FileType(Enum):
30
44
  GPX = '.gpx'
31
45
  GPKG = '.gpkg'
32
46
  GeoJSON = '.geojson'
33
- GeoTIFF = '.tif'
47
+ # GeoTIFF = '.tiff'
34
48
 
35
49
  # Image Formats
36
50
  JPG = '.jpg'
@@ -6,7 +6,7 @@ import requests
6
6
  import sys
7
7
 
8
8
  from .base import Base
9
- from .enums import FileType, PublishFileType, InputGeomType
9
+ from .enums import FileFormat, PublishFileType, InputGeomType, FileType
10
10
  from .utils import clean_data
11
11
  from .task import Task
12
12
 
@@ -46,7 +46,7 @@ class File(Base):
46
46
  Returns:
47
47
  str: A string representation of the File object.
48
48
  """
49
- return f"File(uuid={self.uuid}, file_name={self.name}, file_type={self.file_type})"
49
+ return f"File(uuid={self.uuid}, file_name={self.name}, file_type={self.file_type.value})"
50
50
 
51
51
 
52
52
  @property
@@ -66,6 +66,23 @@ class File(Base):
66
66
  return self.data.get('layers', {}).get('layers', [])
67
67
 
68
68
 
69
+ @property
70
+ def file_type(self) -> 'FileType':
71
+ """
72
+ Get the file type
73
+
74
+ Returns:
75
+ FileType: the file type enumeration
76
+
77
+ Example:
78
+ >>> from geobox import GeoboxClient
79
+ >>> client = GeoboxClient()
80
+ >>> file = File.get_file(client, uuid="12345678-1234-5678-1234-567812345678")
81
+ >>> file.file_type
82
+ """
83
+ return FileType(self.data.get('file_type'))
84
+
85
+
69
86
  @classmethod
70
87
  def upload_file(cls, api: 'GeoboxClient', path: str, user_id: int = None, scan_archive: bool = True) -> 'File':
71
88
  """
@@ -97,7 +114,7 @@ class File(Base):
97
114
  raise FileNotFoundError(f"File not found: {path}")
98
115
 
99
116
  # Check if the file type is valid
100
- FileType(os.path.splitext(path)[1])
117
+ FileFormat(os.path.splitext(path)[1])
101
118
 
102
119
  data = clean_data({
103
120
  "user_id": user_id,
@@ -188,9 +205,9 @@ class File(Base):
188
205
 
189
206
 
190
207
  @classmethod
191
- def get_file_by_name(cls, api: 'GeoboxClient', name: str, user_id: int = None) -> Union['File', None]:
208
+ def get_files_by_name(cls, api: 'GeoboxClient', name: str, user_id: int = None) -> List['File']:
192
209
  """
193
- Get a file by name
210
+ Get files by name
194
211
 
195
212
  Args:
196
213
  api (GeoboxClient): The GeoboxClient instance for making requests.
@@ -198,21 +215,17 @@ class File(Base):
198
215
  user_id (int, optional): specific user. privileges required.
199
216
 
200
217
  Returns:
201
- File | None: returns the file if a file matches the given name, else None
218
+ List[File]: returns files that matches the given name
202
219
 
203
220
  Example:
204
221
  >>> from geobox import GeoboxClient
205
222
  >>> from geobox.file import File
206
223
  >>> client = GeoboxClient()
207
- >>> file = File.get_file_by_name(client, name='test')
224
+ >>> files = File.get_file_by_name(client, name='test')
208
225
  or
209
- >>> file = client.get_file_by_name(name='test')
226
+ >>> files = client.get_file_by_name(name='test')
210
227
  """
211
- files = cls.get_files(api, q=f"name = '{name}'", user_id=user_id)
212
- if files and files[0].name == name:
213
- return files[0]
214
- else:
215
- return None
228
+ return cls.get_files(api, q=f"name = '{name}'", user_id=user_id)
216
229
 
217
230
 
218
231
  def _get_save_path(self, save_path: str = None) -> str:
@@ -359,8 +372,8 @@ class File(Base):
359
372
 
360
373
 
361
374
  def publish(self,
362
- publish_as: 'PublishFileType',
363
375
  name: str,
376
+ publish_as: 'PublishFileType' = None,
364
377
  input_geom_type: 'InputGeomType' = None,
365
378
  input_layer: str = None,
366
379
  input_dataset: str = None,
@@ -374,8 +387,8 @@ class File(Base):
374
387
  Publishes a file as a layer.
375
388
 
376
389
  Args:
377
- publish_as (PublishFileType): The type of layer to publish as.
378
390
  name (str): The name of the layer.
391
+ publish_as (PublishFileType): The type of layer to publish as.
379
392
  input_geom_type (InputGeomType, optional): The geometry type of the layer.
380
393
  input_layer (str, optional): The name of the input layer.
381
394
  input_dataset (str, optional): The name of the input dataset.
@@ -405,6 +418,14 @@ class File(Base):
405
418
  ... input_srid=4326,
406
419
  ... file_encoding='utf-8')
407
420
  """
421
+ if not publish_as:
422
+ if self.file_type.value in ['GeoJSON', 'GPKG', 'DXF', 'GPX', 'Shapefile', 'KML', 'CSV', 'FileGDB']:
423
+ publish_as = PublishFileType.VECTOR
424
+ elif self.file_type.value in ['GeoTIFF']:
425
+ publish_as = PublishFileType.RASTER
426
+ elif self.file_type.value in ['GLB']:
427
+ publish_as = PublishFileType.MODEL3D
428
+
408
429
  data = clean_data({
409
430
  "publish_as": publish_as.value if isinstance(publish_as, PublishFileType) else publish_as,
410
431
  "layer_name": name,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geobox
3
- Version: 1.1.0
3
+ Version: 1.2.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.1.0"
7
+ version = "1.2.0"
8
8
  description = "SDK for Geobox's APIs"
9
9
  authors = [
10
10
  {name = "Hamid Heydari", email = "heydari.h62@gmail.com"}
@@ -737,7 +737,7 @@ def test_get_file(mock_file_data):
737
737
  assert file.data == mock_file_data
738
738
 
739
739
 
740
- def test_get_file_by_name(mock_file_data):
740
+ def test_get_files_by_name(mock_file_data):
741
741
  with patch('geobox.api.GeoboxClient.get_access_token') as mock_get_token, \
742
742
  patch('geobox.api.GeoboxClient.get') as mock_get:
743
743
 
@@ -745,10 +745,10 @@ def test_get_file_by_name(mock_file_data):
745
745
  mock_get.return_value = [mock_file_data]
746
746
 
747
747
  client = GeoboxClient(username='testuser', password='testpassword')
748
- file = client.get_file_by_name(name=mock_file_data['name'])
748
+ files = client.get_files_by_name(name=mock_file_data['name'])
749
749
 
750
- assert isinstance(file, File)
751
- assert file.data == mock_file_data
750
+ assert isinstance(files[0], File)
751
+ assert files[0].data == mock_file_data
752
752
 
753
753
 
754
754
  def test_upload_file():
@@ -24,7 +24,7 @@ def test_properties(api, mock_file_data):
24
24
  """Test File properties."""
25
25
  file = File(api, uuid=mock_file_data['uuid'], data=mock_file_data)
26
26
  assert file.name == 'world_boundaries.shp'
27
- assert file.file_type == 'Shapefile'
27
+ assert file.file_type.value == 'Shapefile'
28
28
  assert file.size == 7588516
29
29
  assert file.feature_count == 394
30
30
  assert file.layer_count == 1
@@ -77,7 +77,7 @@ def test_upload_file_invalid_type(api):
77
77
  # Use the actual extension string
78
78
  invalid_extension = os.path.splitext(temp_file_path)[1]
79
79
 
80
- with pytest.raises(ValueError, match=f".invalid' is not a valid FileType"):
80
+ with pytest.raises(ValueError, match=f".invalid' is not a valid FileFormat"):
81
81
  File.upload_file(api, temp_file_path)
82
82
 
83
83
  # Clean up
@@ -108,7 +108,7 @@ def test_get_files(api):
108
108
  api.get.assert_called_once_with(f"{File.BASE_ENDPOINT}?f=json&search=test&search_fields=name&return_count=False&skip=0&limit=2&shared=False")
109
109
 
110
110
 
111
- def test_get_file_by_uuid(api, mock_file_data):
111
+ def test_get_file(api, mock_file_data):
112
112
  """Test getting file by UUID."""
113
113
  with patch.object(api, 'get', return_value=mock_file_data):
114
114
  file = File.get_file(api, uuid=mock_file_data['uuid'])
@@ -118,18 +118,15 @@ def test_get_file_by_uuid(api, mock_file_data):
118
118
  api.get.assert_called_once_with(f"{file.endpoint}info/?f=json")
119
119
 
120
120
 
121
- def test_get_file_by_name(api, mock_file_data):
121
+ def test_get_files_by_name(api, mock_file_data):
122
122
  """Test getting file by name."""
123
123
  mock_response = [mock_file_data]
124
124
  with patch.object(api, 'get', return_value=mock_response):
125
- file = File.get_file_by_name(api, name=mock_file_data['name'])
126
- assert isinstance(file, File)
127
- assert file.uuid == mock_file_data['uuid']
128
- assert file.name == mock_file_data['name']
129
- api.get.assert_called_once_with(f"{file.BASE_ENDPOINT}?f=json&q=name+%3D+%27world_boundaries.shp%27&return_count=False&skip=0&limit=10&shared=False")
130
- # not found
131
- file = File.get_file_by_name(api, name='not_found')
132
- assert file == None
125
+ files = File.get_files_by_name(api, name=mock_file_data['name'])
126
+ assert isinstance(files[0], File)
127
+ assert files[0].uuid == mock_file_data['uuid']
128
+ assert files[0].name == mock_file_data['name']
129
+ api.get.assert_called_once_with(f"{files[0].BASE_ENDPOINT}?f=json&q=name+%3D+%27world_boundaries.shp%27&return_count=False&skip=0&limit=10&shared=False")
133
130
 
134
131
 
135
132
  def test_download(api, mock_file_data):
@@ -268,24 +265,21 @@ def test_delete(api, mock_file_data):
268
265
  api.delete.assert_called_once_with(f'files/{mock_file_data["uuid"]}/')
269
266
 
270
267
 
271
- @pytest.mark.parametrize("publish_type,geom_type", [
272
- (publish_type, geom_type)
273
- for publish_type in PublishFileType
274
- for geom_type in InputGeomType
268
+ @pytest.mark.parametrize("file_type", [
269
+ (type)
270
+ for type in FileType
275
271
  ])
276
- def test_publish(api, mock_file_data, publish_type, mock_success_task_data, geom_type):
272
+ def test_publish(api, mock_file_data, mock_success_task_data, file_type):
277
273
  """Test file publishing with all combinations of publish types and geometry types."""
278
274
  mock_response = {
279
275
  'task_id': mock_success_task_data['id']
280
276
  }
281
-
277
+ mock_file_data['file_type'] = file_type.value
282
278
  with patch.object(api, 'post', return_value=mock_response) as mock_post:
283
279
  with patch.object(api, 'get', return_value=mock_success_task_data) as mock_post:
284
280
  file = File(api, uuid=mock_file_data['uuid'], data=mock_file_data)
285
281
  result = file.publish(
286
- publish_as=publish_type,
287
- name='test_layer',
288
- input_geom_type=geom_type
282
+ name='test_layer'
289
283
  )
290
284
 
291
285
  # Verify the response
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
File without changes
File without changes