pygeobox 1.0.1__py3-none-any.whl → 1.0.2__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.
pygeobox/model3d.py CHANGED
@@ -1,334 +1,334 @@
1
- from typing import Dict, List, Optional, Optional, Union, TYPE_CHECKING
2
- from urllib.parse import urljoin, urlencode
3
-
4
- from .base import Base
5
- from .exception import ApiRequestError
6
-
7
- if TYPE_CHECKING:
8
- from . import GeoboxClient
9
- from .user import User
10
-
11
- class Model(Base):
12
- """
13
- A class representing a 3D model in Geobox.
14
- """
15
- BASE_ENDPOINT = '3dmodels/'
16
-
17
- def __init__(self,
18
- api: 'GeoboxClient',
19
- uuid: str,
20
- data: Optional[Dict] = {}):
21
- """
22
- Initialize a 3D Model instance.
23
-
24
- Args:
25
- api (GeoboxClient): The GeoboxClient instance for making requests.
26
- uuid (str): The unique identifier for the model.
27
- data (Dict, optional): The data of the model.
28
- """
29
- super().__init__(api, uuid=uuid, data=data)
30
-
31
-
32
- @classmethod
33
- def get_models(cls, api: 'GeoboxClient', **kwargs) -> Union[List['Model'], int]:
34
- """
35
- Get a list of models with optional filtering and pagination.
36
-
37
- Args:
38
- api (GeoboxClient): The GeoboxClient instance for making requests.
39
-
40
- Keyword Args:
41
- q (str): query filter based on OGC CQL standard. e.g. "field1 LIKE '%GIS%' AND created_at > '2021-01-01'".
42
- 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.
43
- search_fields (str): comma separated list of fields for searching.
44
- 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.
45
- return_count (bool): whether to return total count. default is False.
46
- skip (int): number of models to skip. default is 0.
47
- limit (int): maximum number of models to return. default is 10.
48
- user_id (int): specific user. privileges required.
49
- shared (bool): Whether to return shared models. default is False.
50
-
51
- Returns:
52
- List[Model] | int: A list of Model objects or the count number.
53
-
54
- Example:
55
- >>> from geobox import GeoboxClient
56
- >>> from geobox.model3d import Model
57
- >>> client = GeoboxClient()
58
- >>> models = Model.get_models(api=client,
59
- ... search="my_model",
60
- ... search_fields="name, description",
61
- ... order_by="name A",
62
- ... return_count=True,
63
- ... skip=0,
64
- ... limit=10,
65
- ... shared=False)
66
- or
67
- >>> models = client.get_models(search="my_model",
68
- ... search_fields="name, description",
69
- ... order_by="name A",
70
- ... return_count=True,
71
- ... skip=0,
72
- ... limit=10,
73
- ... shared=False)
74
- """
75
- params = {
76
- 'f': 'json',
77
- 'q': kwargs.get('q'),
78
- 'search': kwargs.get('search'),
79
- 'search_fields': kwargs.get('search_fields'),
80
- 'order_by': kwargs.get('order_by'),
81
- 'return_count': kwargs.get('return_count', False),
82
- 'skip': kwargs.get('skip', 0),
83
- 'limit': kwargs.get('limit', 10),
84
- 'user_id': kwargs.get('user_id'),
85
- 'shared': kwargs.get('shared', False)
86
- }
87
- return super()._get_list(api, cls.BASE_ENDPOINT, params, factory_func=lambda api, item: Model(api, item['uuid'], item))
88
-
89
-
90
- @classmethod
91
- def get_model(cls, api: 'GeoboxClient', uuid: str, user_id: int = None) -> 'Model':
92
- """
93
- Get a model by its UUID.
94
-
95
- Args:
96
- api (GeoboxClient): The GeoboxClient instance for making requests.
97
- uuid (str): The UUID of the model to get.
98
- user_id (int, optional): Specific user. privileges required.
99
-
100
- Returns:
101
- Model: The model object.
102
-
103
- Raises:
104
- NotFoundError: If the model with the specified UUID is not found.
105
-
106
- Example:
107
- >>> from geobox import GeoboxClient
108
- >>> from geobox.model3d import Model
109
- >>> client = GeoboxClient()
110
- >>> model = Model.get_model(client, uuid="12345678-1234-5678-1234-567812345678")
111
- or
112
- >>> model = client.get_model(uuid="12345678-1234-5678-1234-567812345678")
113
- """
114
- params = {
115
- 'f': 'json',
116
- 'user_id': user_id
117
- }
118
- return super()._get_detail(api, cls.BASE_ENDPOINT, uuid, params, factory_func=lambda api, item: Model(api, item['uuid'], item))
119
-
120
-
121
- @classmethod
122
- def get_model_by_name(cls, api: 'GeoboxClient', name: str, user_id: int = None) -> Union['Model', None]:
123
- """
124
- Get a model by name
125
-
126
- Args:
127
- api (GeoboxClient): The GeoboxClient instance for making requests.
128
- name (str): the name of the model to get
129
- user_id (int, optional): specific user. privileges required.
130
-
131
- Returns:
132
- Model | None: returns the model if a model matches the given name, else None
133
-
134
- Example:
135
- >>> from geobox import GeoboxClient
136
- >>> from geobox.model3d import Model
137
- >>> client = GeoboxClient()
138
- >>> model = Model.get_model_by_name(client, name='test')
139
- or
140
- >>> model = client.get_model_by_name(name='test')
141
- """
142
- models = cls.get_models(api, q=f"name = '{name}'", user_id=user_id)
143
- if models and models[0].name == name:
144
- return models[0]
145
- else:
146
- return None
147
-
148
-
149
- def update(self, **kwargs) -> Dict:
150
- """
151
- Update the model's properties.
152
-
153
- Keyword Args:
154
- name (str): The new name for the model.
155
- description (str): The new description for the model.
156
- settings (Dict): The new settings for the model.
157
- thumbnail (str): The new thumbnail for the model.
158
-
159
- Returns:
160
- Dict: The updated model data.
161
-
162
- Raises:
163
- ValidationError: If the update data is invalid.
164
-
165
- Example:
166
- >>> from geobox import GeoboxClient
167
- >>> from geobox.model3d import Model
168
- >>> client = GeoboxClient()
169
- >>> model = Model.get_model(api=client, uuid="12345678-1234-5678-1234-567812345678")
170
- >>> settings = {
171
- ... "model_settings": {
172
- ... "scale": 0,
173
- ... "rotation": [
174
- ... 0
175
- ... ],
176
- ... "location": [
177
- ... 0
178
- ... ]
179
- ... },
180
- ... "view_settings": {
181
- ... "center": [
182
- ... 0
183
- ... ],
184
- ... "zoom": 0,
185
- ... "pitch": 0,
186
- ... "bearing": 0
187
- ... }
188
- ... }
189
- >>> model.update(name="new_name", description="new_description", settings=settings, thumbnail="new_thumbnail")
190
- """
191
- data = {
192
- 'name': kwargs.get('name'),
193
- 'description': kwargs.get('description'),
194
- 'settings': kwargs.get('settings'),
195
- 'thumbnail': kwargs.get('thumbnail')
196
- }
197
- return super()._update(self.endpoint, data)
198
-
199
-
200
- def delete(self) -> None:
201
- """
202
- Delete the model.
203
-
204
- Returns:
205
- None
206
-
207
- Example:
208
- >>> from geobox import GeoboxClient
209
- >>> from geobox.model3d import Model
210
- >>> client = GeoboxClient()
211
- >>> model = Model.get_model(api=client, uuid="12345678-1234-5678-1234-567812345678")
212
- >>> model.delete()
213
- """
214
- super().delete(self.endpoint)
215
-
216
-
217
- def get_content(self) -> bytes:
218
- """
219
- Get the raw content of the 3D model.
220
-
221
- Returns:
222
- bytes: The raw content of the 3D model in glTF format.
223
-
224
- Raises:
225
- ApiRequestError: If the API request fails.
226
-
227
- Example:
228
- >>> from geobox import GeoboxClient
229
- >>> from geobox.model3d import Model
230
- >>> client = GeoboxClient()
231
- >>> model = Model.get_model(api=client, uuid="12345678-1234-5678-1234-567812345678")
232
- >>> content = model.get_content()
233
- >>> # Save the content to a file
234
- >>> with open('model.gltf', 'wb') as f:
235
- ... f.write(content)
236
- """
237
- endpoint = urljoin(self.api.base_url, f'{self.endpoint}/content/')
238
- response = self.api.session.get(endpoint)
239
-
240
- if response.status_code != 200:
241
- raise ApiRequestError(f"Failed to get model content: {response.status_code}")
242
-
243
- return response.content
244
-
245
-
246
- @property
247
- def thumbnail(self) -> str:
248
- """
249
- Get the thumbnail URL of the model.
250
-
251
- Returns:
252
- str: The thumbnail of the model.
253
-
254
- Example:
255
- >>> from geobox import GeoboxClient
256
- >>> from geobox.model3d import Model
257
- >>> client = GeoboxClient()
258
- >>> model = Model.get_model(api=client, uuid="12345678-1234-5678-1234-567812345678")
259
- >>> model.thumbnail
260
- """
261
- if not self.uuid:
262
- raise ValueError("Model UUID is required.")
263
-
264
- endpoint = urljoin(self.api.base_url, f'{self.endpoint}/thumbnail.png')
265
- return endpoint
266
-
267
-
268
- def share(self, users: List['User']) -> None:
269
- """
270
- Shares the model with specified users.
271
-
272
- Args:
273
- users (List[users]): The list of user objects to share the model with.
274
-
275
- Returns:
276
- None
277
-
278
- Example:
279
- >>> from geobox import GeoboxClient
280
- >>> from geobox.model3d import Model
281
- >>> client = GeoboxClient()
282
- >>> model = Model.get_model(client, uuid="12345678-1234-5678-1234-567812345678")
283
- >>> users = client.search_users(search='John')
284
- >>> model.share(users=users)
285
- """
286
- super()._share(self.endpoint, users)
287
-
288
-
289
- def unshare(self, users: List['User']) -> None:
290
- """
291
- Unshares the model with specified users.
292
-
293
- Args:
294
- users (List[User]): The list of user objects to unshare the model with.
295
-
296
- Returns:
297
- None
298
-
299
- Example:
300
- >>> from geobox import GeoboxClient
301
- >>> from geobox.model3d import Model
302
- >>> client = GeoboxClient()
303
- >>> model = Model.get_model(client, uuid="12345678-1234-5678-1234-567812345678")
304
- >>> users = client.search_users(search='John')
305
- >>> model.unshare(users=users)
306
- """
307
- super()._unshare(self.endpoint, users)
308
-
309
-
310
- def get_shared_users(self, search: str = None, skip: int = 0, limit: int = 10) -> List['User']:
311
- """
312
- Retrieves the list of users the model is shared with.
313
-
314
- Args:
315
- search (str, optional): The search query.
316
- skip (int, optional): The number of users to skip.
317
- limit (int, optional): The maximum number of users to retrieve.
318
-
319
- Returns:
320
- List[User]: The list of shared users.
321
-
322
- Example:
323
- >>> from geobox import GeoboxClient
324
- >>> from geobox.model3d import Model
325
- >>> client = GeoboxClient()
326
- >>> model = Model.get_model(client, uuid="12345678-1234-5678-1234-567812345678")
327
- >>> model.get_shared_users(search='John', skip=0, limit=10)
328
- """
329
- params = {
330
- 'search': search,
331
- 'skip': skip,
332
- 'limit': limit
333
- }
334
- return super()._get_shared_users(self.endpoint, params)
1
+ from typing import Dict, List, Optional, Optional, Union, TYPE_CHECKING
2
+ from urllib.parse import urljoin, urlencode
3
+
4
+ from .base import Base
5
+ from .exception import ApiRequestError
6
+
7
+ if TYPE_CHECKING:
8
+ from . import GeoboxClient
9
+ from .user import User
10
+
11
+ class Model(Base):
12
+ """
13
+ A class representing a 3D model in Geobox.
14
+ """
15
+ BASE_ENDPOINT = '3dmodels/'
16
+
17
+ def __init__(self,
18
+ api: 'GeoboxClient',
19
+ uuid: str,
20
+ data: Optional[Dict] = {}):
21
+ """
22
+ Initialize a 3D Model instance.
23
+
24
+ Args:
25
+ api (GeoboxClient): The GeoboxClient instance for making requests.
26
+ uuid (str): The unique identifier for the model.
27
+ data (Dict, optional): The data of the model.
28
+ """
29
+ super().__init__(api, uuid=uuid, data=data)
30
+
31
+
32
+ @classmethod
33
+ def get_models(cls, api: 'GeoboxClient', **kwargs) -> Union[List['Model'], int]:
34
+ """
35
+ Get a list of models with optional filtering and pagination.
36
+
37
+ Args:
38
+ api (GeoboxClient): The GeoboxClient instance for making requests.
39
+
40
+ Keyword Args:
41
+ q (str): query filter based on OGC CQL standard. e.g. "field1 LIKE '%GIS%' AND created_at > '2021-01-01'".
42
+ 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.
43
+ search_fields (str): comma separated list of fields for searching.
44
+ 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.
45
+ return_count (bool): whether to return total count. default is False.
46
+ skip (int): number of models to skip. default is 0.
47
+ limit (int): maximum number of models to return. default is 10.
48
+ user_id (int): specific user. privileges required.
49
+ shared (bool): Whether to return shared models. default is False.
50
+
51
+ Returns:
52
+ List[Model] | int: A list of Model objects or the count number.
53
+
54
+ Example:
55
+ >>> from geobox import GeoboxClient
56
+ >>> from geobox.model3d import Model
57
+ >>> client = GeoboxClient()
58
+ >>> models = Model.get_models(api=client,
59
+ ... search="my_model",
60
+ ... search_fields="name, description",
61
+ ... order_by="name A",
62
+ ... return_count=True,
63
+ ... skip=0,
64
+ ... limit=10,
65
+ ... shared=False)
66
+ or
67
+ >>> models = client.get_models(search="my_model",
68
+ ... search_fields="name, description",
69
+ ... order_by="name A",
70
+ ... return_count=True,
71
+ ... skip=0,
72
+ ... limit=10,
73
+ ... shared=False)
74
+ """
75
+ params = {
76
+ 'f': 'json',
77
+ 'q': kwargs.get('q'),
78
+ 'search': kwargs.get('search'),
79
+ 'search_fields': kwargs.get('search_fields'),
80
+ 'order_by': kwargs.get('order_by'),
81
+ 'return_count': kwargs.get('return_count', False),
82
+ 'skip': kwargs.get('skip', 0),
83
+ 'limit': kwargs.get('limit', 10),
84
+ 'user_id': kwargs.get('user_id'),
85
+ 'shared': kwargs.get('shared', False)
86
+ }
87
+ return super()._get_list(api, cls.BASE_ENDPOINT, params, factory_func=lambda api, item: Model(api, item['uuid'], item))
88
+
89
+
90
+ @classmethod
91
+ def get_model(cls, api: 'GeoboxClient', uuid: str, user_id: int = None) -> 'Model':
92
+ """
93
+ Get a model by its UUID.
94
+
95
+ Args:
96
+ api (GeoboxClient): The GeoboxClient instance for making requests.
97
+ uuid (str): The UUID of the model to get.
98
+ user_id (int, optional): Specific user. privileges required.
99
+
100
+ Returns:
101
+ Model: The model object.
102
+
103
+ Raises:
104
+ NotFoundError: If the model with the specified UUID is not found.
105
+
106
+ Example:
107
+ >>> from geobox import GeoboxClient
108
+ >>> from geobox.model3d import Model
109
+ >>> client = GeoboxClient()
110
+ >>> model = Model.get_model(client, uuid="12345678-1234-5678-1234-567812345678")
111
+ or
112
+ >>> model = client.get_model(uuid="12345678-1234-5678-1234-567812345678")
113
+ """
114
+ params = {
115
+ 'f': 'json',
116
+ 'user_id': user_id
117
+ }
118
+ return super()._get_detail(api, cls.BASE_ENDPOINT, uuid, params, factory_func=lambda api, item: Model(api, item['uuid'], item))
119
+
120
+
121
+ @classmethod
122
+ def get_model_by_name(cls, api: 'GeoboxClient', name: str, user_id: int = None) -> Union['Model', None]:
123
+ """
124
+ Get a model by name
125
+
126
+ Args:
127
+ api (GeoboxClient): The GeoboxClient instance for making requests.
128
+ name (str): the name of the model to get
129
+ user_id (int, optional): specific user. privileges required.
130
+
131
+ Returns:
132
+ Model | None: returns the model if a model matches the given name, else None
133
+
134
+ Example:
135
+ >>> from geobox import GeoboxClient
136
+ >>> from geobox.model3d import Model
137
+ >>> client = GeoboxClient()
138
+ >>> model = Model.get_model_by_name(client, name='test')
139
+ or
140
+ >>> model = client.get_model_by_name(name='test')
141
+ """
142
+ models = cls.get_models(api, q=f"name = '{name}'", user_id=user_id)
143
+ if models and models[0].name == name:
144
+ return models[0]
145
+ else:
146
+ return None
147
+
148
+
149
+ def update(self, **kwargs) -> Dict:
150
+ """
151
+ Update the model's properties.
152
+
153
+ Keyword Args:
154
+ name (str): The new name for the model.
155
+ description (str): The new description for the model.
156
+ settings (Dict): The new settings for the model.
157
+ thumbnail (str): The new thumbnail for the model.
158
+
159
+ Returns:
160
+ Dict: The updated model data.
161
+
162
+ Raises:
163
+ ValidationError: If the update data is invalid.
164
+
165
+ Example:
166
+ >>> from geobox import GeoboxClient
167
+ >>> from geobox.model3d import Model
168
+ >>> client = GeoboxClient()
169
+ >>> model = Model.get_model(api=client, uuid="12345678-1234-5678-1234-567812345678")
170
+ >>> settings = {
171
+ ... "model_settings": {
172
+ ... "scale": 0,
173
+ ... "rotation": [
174
+ ... 0
175
+ ... ],
176
+ ... "location": [
177
+ ... 0
178
+ ... ]
179
+ ... },
180
+ ... "view_settings": {
181
+ ... "center": [
182
+ ... 0
183
+ ... ],
184
+ ... "zoom": 0,
185
+ ... "pitch": 0,
186
+ ... "bearing": 0
187
+ ... }
188
+ ... }
189
+ >>> model.update(name="new_name", description="new_description", settings=settings, thumbnail="new_thumbnail")
190
+ """
191
+ data = {
192
+ 'name': kwargs.get('name'),
193
+ 'description': kwargs.get('description'),
194
+ 'settings': kwargs.get('settings'),
195
+ 'thumbnail': kwargs.get('thumbnail')
196
+ }
197
+ return super()._update(self.endpoint, data)
198
+
199
+
200
+ def delete(self) -> None:
201
+ """
202
+ Delete the model.
203
+
204
+ Returns:
205
+ None
206
+
207
+ Example:
208
+ >>> from geobox import GeoboxClient
209
+ >>> from geobox.model3d import Model
210
+ >>> client = GeoboxClient()
211
+ >>> model = Model.get_model(api=client, uuid="12345678-1234-5678-1234-567812345678")
212
+ >>> model.delete()
213
+ """
214
+ super().delete(self.endpoint)
215
+
216
+
217
+ def get_content(self) -> bytes:
218
+ """
219
+ Get the raw content of the 3D model.
220
+
221
+ Returns:
222
+ bytes: The raw content of the 3D model in glTF format.
223
+
224
+ Raises:
225
+ ApiRequestError: If the API request fails.
226
+
227
+ Example:
228
+ >>> from geobox import GeoboxClient
229
+ >>> from geobox.model3d import Model
230
+ >>> client = GeoboxClient()
231
+ >>> model = Model.get_model(api=client, uuid="12345678-1234-5678-1234-567812345678")
232
+ >>> content = model.get_content()
233
+ >>> # Save the content to a file
234
+ >>> with open('model.gltf', 'wb') as f:
235
+ ... f.write(content)
236
+ """
237
+ endpoint = urljoin(self.api.base_url, f'{self.endpoint}/content/')
238
+ response = self.api.session.get(endpoint)
239
+
240
+ if response.status_code != 200:
241
+ raise ApiRequestError(f"Failed to get model content: {response.status_code}")
242
+
243
+ return response.content
244
+
245
+
246
+ @property
247
+ def thumbnail(self) -> str:
248
+ """
249
+ Get the thumbnail URL of the model.
250
+
251
+ Returns:
252
+ str: The thumbnail of the model.
253
+
254
+ Example:
255
+ >>> from geobox import GeoboxClient
256
+ >>> from geobox.model3d import Model
257
+ >>> client = GeoboxClient()
258
+ >>> model = Model.get_model(api=client, uuid="12345678-1234-5678-1234-567812345678")
259
+ >>> model.thumbnail
260
+ """
261
+ if not self.uuid:
262
+ raise ValueError("Model UUID is required.")
263
+
264
+ endpoint = urljoin(self.api.base_url, f'{self.endpoint}/thumbnail.png')
265
+ return endpoint
266
+
267
+
268
+ def share(self, users: List['User']) -> None:
269
+ """
270
+ Shares the model with specified users.
271
+
272
+ Args:
273
+ users (List[users]): The list of user objects to share the model with.
274
+
275
+ Returns:
276
+ None
277
+
278
+ Example:
279
+ >>> from geobox import GeoboxClient
280
+ >>> from geobox.model3d import Model
281
+ >>> client = GeoboxClient()
282
+ >>> model = Model.get_model(client, uuid="12345678-1234-5678-1234-567812345678")
283
+ >>> users = client.search_users(search='John')
284
+ >>> model.share(users=users)
285
+ """
286
+ super()._share(self.endpoint, users)
287
+
288
+
289
+ def unshare(self, users: List['User']) -> None:
290
+ """
291
+ Unshares the model with specified users.
292
+
293
+ Args:
294
+ users (List[User]): The list of user objects to unshare the model with.
295
+
296
+ Returns:
297
+ None
298
+
299
+ Example:
300
+ >>> from geobox import GeoboxClient
301
+ >>> from geobox.model3d import Model
302
+ >>> client = GeoboxClient()
303
+ >>> model = Model.get_model(client, uuid="12345678-1234-5678-1234-567812345678")
304
+ >>> users = client.search_users(search='John')
305
+ >>> model.unshare(users=users)
306
+ """
307
+ super()._unshare(self.endpoint, users)
308
+
309
+
310
+ def get_shared_users(self, search: str = None, skip: int = 0, limit: int = 10) -> List['User']:
311
+ """
312
+ Retrieves the list of users the model is shared with.
313
+
314
+ Args:
315
+ search (str, optional): The search query.
316
+ skip (int, optional): The number of users to skip.
317
+ limit (int, optional): The maximum number of users to retrieve.
318
+
319
+ Returns:
320
+ List[User]: The list of shared users.
321
+
322
+ Example:
323
+ >>> from geobox import GeoboxClient
324
+ >>> from geobox.model3d import Model
325
+ >>> client = GeoboxClient()
326
+ >>> model = Model.get_model(client, uuid="12345678-1234-5678-1234-567812345678")
327
+ >>> model.get_shared_users(search='John', skip=0, limit=10)
328
+ """
329
+ params = {
330
+ 'search': search,
331
+ 'skip': skip,
332
+ 'limit': limit
333
+ }
334
+ return super()._get_shared_users(self.endpoint, params)