geobox 1.0.0__tar.gz → 1.1.1__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.0.0 → geobox-1.1.1}/PKG-INFO +2 -2
  2. {geobox-1.0.0 → geobox-1.1.1}/README.md +1 -1
  3. {geobox-1.0.0 → geobox-1.1.1}/geobox/api.py +5 -5
  4. {geobox-1.0.0 → geobox-1.1.1}/geobox/enums.py +1 -1
  5. {geobox-1.0.0 → geobox-1.1.1}/geobox/file.py +6 -10
  6. {geobox-1.0.0 → geobox-1.1.1}/geobox/task.py +34 -20
  7. {geobox-1.0.0 → geobox-1.1.1}/geobox.egg-info/PKG-INFO +2 -2
  8. {geobox-1.0.0 → geobox-1.1.1}/pyproject.toml +1 -1
  9. {geobox-1.0.0 → geobox-1.1.1}/tests/test_api.py +4 -4
  10. {geobox-1.0.0 → geobox-1.1.1}/tests/test_file.py +7 -10
  11. {geobox-1.0.0 → geobox-1.1.1}/LICENSE +0 -0
  12. {geobox-1.0.0 → geobox-1.1.1}/geobox/__init__.py +0 -0
  13. {geobox-1.0.0 → geobox-1.1.1}/geobox/apikey.py +0 -0
  14. {geobox-1.0.0 → geobox-1.1.1}/geobox/attachment.py +0 -0
  15. {geobox-1.0.0 → geobox-1.1.1}/geobox/base.py +0 -0
  16. {geobox-1.0.0 → geobox-1.1.1}/geobox/basemap.py +0 -0
  17. {geobox-1.0.0 → geobox-1.1.1}/geobox/dashboard.py +0 -0
  18. {geobox-1.0.0 → geobox-1.1.1}/geobox/exception.py +0 -0
  19. {geobox-1.0.0 → geobox-1.1.1}/geobox/feature.py +0 -0
  20. {geobox-1.0.0 → geobox-1.1.1}/geobox/field.py +0 -0
  21. {geobox-1.0.0 → geobox-1.1.1}/geobox/log.py +0 -0
  22. {geobox-1.0.0 → geobox-1.1.1}/geobox/map.py +0 -0
  23. {geobox-1.0.0 → geobox-1.1.1}/geobox/model3d.py +0 -0
  24. {geobox-1.0.0 → geobox-1.1.1}/geobox/mosaic.py +0 -0
  25. {geobox-1.0.0 → geobox-1.1.1}/geobox/plan.py +0 -0
  26. {geobox-1.0.0 → geobox-1.1.1}/geobox/query.py +0 -0
  27. {geobox-1.0.0 → geobox-1.1.1}/geobox/raster.py +0 -0
  28. {geobox-1.0.0 → geobox-1.1.1}/geobox/route.py +0 -0
  29. {geobox-1.0.0 → geobox-1.1.1}/geobox/scene.py +0 -0
  30. {geobox-1.0.0 → geobox-1.1.1}/geobox/settings.py +0 -0
  31. {geobox-1.0.0 → geobox-1.1.1}/geobox/tile3d.py +0 -0
  32. {geobox-1.0.0 → geobox-1.1.1}/geobox/tileset.py +0 -0
  33. {geobox-1.0.0 → geobox-1.1.1}/geobox/usage.py +0 -0
  34. {geobox-1.0.0 → geobox-1.1.1}/geobox/user.py +0 -0
  35. {geobox-1.0.0 → geobox-1.1.1}/geobox/utils.py +0 -0
  36. {geobox-1.0.0 → geobox-1.1.1}/geobox/vectorlayer.py +0 -0
  37. {geobox-1.0.0 → geobox-1.1.1}/geobox/version.py +0 -0
  38. {geobox-1.0.0 → geobox-1.1.1}/geobox/view.py +0 -0
  39. {geobox-1.0.0 → geobox-1.1.1}/geobox/workflow.py +0 -0
  40. {geobox-1.0.0 → geobox-1.1.1}/geobox.egg-info/SOURCES.txt +0 -0
  41. {geobox-1.0.0 → geobox-1.1.1}/geobox.egg-info/dependency_links.txt +0 -0
  42. {geobox-1.0.0 → geobox-1.1.1}/geobox.egg-info/requires.txt +0 -0
  43. {geobox-1.0.0 → geobox-1.1.1}/geobox.egg-info/top_level.txt +0 -0
  44. {geobox-1.0.0 → geobox-1.1.1}/setup.cfg +0 -0
  45. {geobox-1.0.0 → geobox-1.1.1}/tests/test_apikey.py +0 -0
  46. {geobox-1.0.0 → geobox-1.1.1}/tests/test_attachment.py +0 -0
  47. {geobox-1.0.0 → geobox-1.1.1}/tests/test_basemap.py +0 -0
  48. {geobox-1.0.0 → geobox-1.1.1}/tests/test_dashboard.py +0 -0
  49. {geobox-1.0.0 → geobox-1.1.1}/tests/test_feature.py +0 -0
  50. {geobox-1.0.0 → geobox-1.1.1}/tests/test_field.py +0 -0
  51. {geobox-1.0.0 → geobox-1.1.1}/tests/test_log.py +0 -0
  52. {geobox-1.0.0 → geobox-1.1.1}/tests/test_map.py +0 -0
  53. {geobox-1.0.0 → geobox-1.1.1}/tests/test_model3d.py +0 -0
  54. {geobox-1.0.0 → geobox-1.1.1}/tests/test_mosaic.py +0 -0
  55. {geobox-1.0.0 → geobox-1.1.1}/tests/test_plan.py +0 -0
  56. {geobox-1.0.0 → geobox-1.1.1}/tests/test_query.py +0 -0
  57. {geobox-1.0.0 → geobox-1.1.1}/tests/test_raster.py +0 -0
  58. {geobox-1.0.0 → geobox-1.1.1}/tests/test_route.py +0 -0
  59. {geobox-1.0.0 → geobox-1.1.1}/tests/test_scene.py +0 -0
  60. {geobox-1.0.0 → geobox-1.1.1}/tests/test_settings.py +0 -0
  61. {geobox-1.0.0 → geobox-1.1.1}/tests/test_task.py +0 -0
  62. {geobox-1.0.0 → geobox-1.1.1}/tests/test_tile3d.py +0 -0
  63. {geobox-1.0.0 → geobox-1.1.1}/tests/test_tileset.py +0 -0
  64. {geobox-1.0.0 → geobox-1.1.1}/tests/test_usage.py +0 -0
  65. {geobox-1.0.0 → geobox-1.1.1}/tests/test_user.py +0 -0
  66. {geobox-1.0.0 → geobox-1.1.1}/tests/test_vectorlayer.py +0 -0
  67. {geobox-1.0.0 → geobox-1.1.1}/tests/test_version.py +0 -0
  68. {geobox-1.0.0 → geobox-1.1.1}/tests/test_view.py +0 -0
  69. {geobox-1.0.0 → geobox-1.1.1}/tests/test_workflow.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geobox
3
- Version: 1.0.0
3
+ Version: 1.1.1
4
4
  Summary: SDK for Geobox's APIs
5
5
  Author-email: Hamid Heydari <heydari.h62@gmail.com>
6
6
  License: MIT
@@ -29,7 +29,7 @@ Dynamic: license-file
29
29
 
30
30
  Geobox® is a cloud-based GIS platform that enables users (local governments, companies and individuals) to easily upload their geo-spatial data, publish them as geo-services, visualize and analyze their geo-content (geo-data or -services) and share them with others. Geobox is a modern, world-class and cloud-ready geo-spatial platform that provides standard, safe, efficient and easy to use GI-Services.
31
31
 
32
- Geobox SDK provides seamless integration with the Geobox API, enabling developers to work with geospatial data and services programmatically. This comprehensive toolkit empowers applications to leverage advanced geospatial capabilities including data management and analysis.
32
+ Geobox python SDK provides seamless integration with the Geobox API, enabling developers to work with geospatial data and services programmatically. This comprehensive toolkit empowers applications to leverage advanced geospatial capabilities including data management and analysis.
33
33
 
34
34
  Installation
35
35
  ============
@@ -3,7 +3,7 @@
3
3
 
4
4
  Geobox® is a cloud-based GIS platform that enables users (local governments, companies and individuals) to easily upload their geo-spatial data, publish them as geo-services, visualize and analyze their geo-content (geo-data or -services) and share them with others. Geobox is a modern, world-class and cloud-ready geo-spatial platform that provides standard, safe, efficient and easy to use GI-Services.
5
5
 
6
- Geobox SDK provides seamless integration with the Geobox API, enabling developers to work with geospatial data and services programmatically. This comprehensive toolkit empowers applications to leverage advanced geospatial capabilities including data management and analysis.
6
+ Geobox python SDK provides seamless integration with the Geobox API, enabling developers to work with geospatial data and services programmatically. This comprehensive toolkit empowers applications to leverage advanced geospatial capabilities including data management and analysis.
7
7
 
8
8
  Installation
9
9
  ============
@@ -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':
@@ -30,7 +30,7 @@ class FileType(Enum):
30
30
  GPX = '.gpx'
31
31
  GPKG = '.gpkg'
32
32
  GeoJSON = '.geojson'
33
- GeoTIFF = '.tif'
33
+ GeoTIFF = '.tiff'
34
34
 
35
35
  # Image Formats
36
36
  JPG = '.jpg'
@@ -188,9 +188,9 @@ class File(Base):
188
188
 
189
189
 
190
190
  @classmethod
191
- def get_file_by_name(cls, api: 'GeoboxClient', name: str, user_id: int = None) -> Union['File', None]:
191
+ def get_files_by_name(cls, api: 'GeoboxClient', name: str, user_id: int = None) -> List['File']:
192
192
  """
193
- Get a file by name
193
+ Get files by name
194
194
 
195
195
  Args:
196
196
  api (GeoboxClient): The GeoboxClient instance for making requests.
@@ -198,21 +198,17 @@ class File(Base):
198
198
  user_id (int, optional): specific user. privileges required.
199
199
 
200
200
  Returns:
201
- File | None: returns the file if a file matches the given name, else None
201
+ List[File]: returns files that matches the given name
202
202
 
203
203
  Example:
204
204
  >>> from geobox import GeoboxClient
205
205
  >>> from geobox.file import File
206
206
  >>> client = GeoboxClient()
207
- >>> file = File.get_file_by_name(client, name='test')
207
+ >>> files = File.get_file_by_name(client, name='test')
208
208
  or
209
- >>> file = client.get_file_by_name(name='test')
209
+ >>> files = client.get_file_by_name(name='test')
210
210
  """
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
211
+ return cls.get_files(api, q=f"name = '{name}'", user_id=user_id)
216
212
 
217
213
 
218
214
  def _get_save_path(self, save_path: str = None) -> str:
@@ -168,8 +168,31 @@ class Task(Base):
168
168
 
169
169
  return int((current / total) * 100)
170
170
 
171
+
172
+ def _wait(self, timeout: Union[int, None] = None, interval: int = 1, progress_bar: bool = True) -> 'TaskStatus':
173
+ start_time = time.time()
174
+ last_progress = 0
175
+ pbar = self._create_progress_bar() if progress_bar else None
176
+
177
+ try:
178
+ while True:
179
+ self._check_timeout(start_time, timeout)
180
+ status = self.status
181
+
182
+ if self._is_final_state(status):
183
+ self._update_progress_bar(pbar, last_progress, status)
184
+ return TaskStatus(status)
185
+
186
+ if pbar:
187
+ last_progress = self._update_progress_bar(pbar, last_progress)
188
+
189
+ time.sleep(interval)
190
+ finally:
191
+ if pbar:
192
+ pbar.close()
171
193
 
172
- def wait(self, timeout: Union[int, None] = None, interval: int = 1, progress_bar: bool = True) -> 'TaskStatus':
194
+
195
+ def wait(self, timeout: Union[int, None] = None, interval: int = 1, progress_bar: bool = True, retry: int = 3) -> 'TaskStatus':
173
196
  """
174
197
  Wait for the task to finish.
175
198
 
@@ -177,6 +200,7 @@ class Task(Base):
177
200
  timeout (int, optional): Maximum time to wait in seconds.
178
201
  interval (int, optional): Time between status checks in seconds.
179
202
  progress_bar (bool, optional): Whether to show a progress bar. default: True
203
+ retry (int, optional): Number of times to retry if waiting for the task fails. default is 3
180
204
 
181
205
  Returns:
182
206
  TaskStatus: the status of the task(SUCCESS, FAILURE, ABORTED, PENDING, PROGRESS)
@@ -191,26 +215,16 @@ class Task(Base):
191
215
  >>> task = Task.get_task(client, uuid="12345678-1234-5678-1234-567812345678")
192
216
  >>> task.wait() # return the status of the task
193
217
  """
194
- start_time = time.time()
195
- last_progress = 0
196
- pbar = self._create_progress_bar() if progress_bar else None
197
-
198
- try:
199
- while True:
200
- self._check_timeout(start_time, timeout)
201
- status = self.status
202
-
203
- if self._is_final_state(status):
204
- self._update_progress_bar(pbar, last_progress, status)
205
- return TaskStatus(status)
206
-
207
- if pbar:
208
- last_progress = self._update_progress_bar(pbar, last_progress)
209
-
218
+ last_exception = None
219
+
220
+ for attempt in range(1, retry + 1):
221
+ try:
222
+ return self._wait(timeout, interval, progress_bar)
223
+ except Exception as e:
224
+ last_exception = e
225
+ print(f"[Retry {attempt}/{retry}] Task wait failed: {e}")
210
226
  time.sleep(interval)
211
- finally:
212
- if pbar:
213
- pbar.close()
227
+ raise last_exception
214
228
 
215
229
 
216
230
  def _create_progress_bar(self) -> 'tqdm':
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: geobox
3
- Version: 1.0.0
3
+ Version: 1.1.1
4
4
  Summary: SDK for Geobox's APIs
5
5
  Author-email: Hamid Heydari <heydari.h62@gmail.com>
6
6
  License: MIT
@@ -29,7 +29,7 @@ Dynamic: license-file
29
29
 
30
30
  Geobox® is a cloud-based GIS platform that enables users (local governments, companies and individuals) to easily upload their geo-spatial data, publish them as geo-services, visualize and analyze their geo-content (geo-data or -services) and share them with others. Geobox is a modern, world-class and cloud-ready geo-spatial platform that provides standard, safe, efficient and easy to use GI-Services.
31
31
 
32
- Geobox SDK provides seamless integration with the Geobox API, enabling developers to work with geospatial data and services programmatically. This comprehensive toolkit empowers applications to leverage advanced geospatial capabilities including data management and analysis.
32
+ Geobox python SDK provides seamless integration with the Geobox API, enabling developers to work with geospatial data and services programmatically. This comprehensive toolkit empowers applications to leverage advanced geospatial capabilities including data management and analysis.
33
33
 
34
34
  Installation
35
35
  ============
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "geobox"
7
- version = "1.0.0"
7
+ version = "1.1.1"
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():
@@ -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):
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