terrakio-core 0.4.2__py3-none-any.whl → 0.4.4__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.

Potentially problematic release.


This version of terrakio-core might be problematic. Click here for more details.

@@ -1,6 +1,345 @@
1
+ # import asyncio
2
+ # import concurrent.futures
3
+ # import threading
4
+ # import functools
5
+ # import inspect
6
+ # from typing import Optional, Dict, Any, Union
7
+ # from geopandas import GeoDataFrame
8
+ # from shapely.geometry.base import BaseGeometry as ShapelyGeometry
9
+ # from .async_client import AsyncClient
10
+ # from typing import TYPE_CHECKING
11
+
12
+ # # # Add this after your other imports
13
+ # # if TYPE_CHECKING:
14
+ # # from .endpoints.dataset_management import DatasetManagement
15
+ # # from .endpoints.user_management import UserManagement
16
+ # # from .endpoints.mass_stats import MassStats
17
+ # # from .endpoints.group_management import GroupManagement
18
+ # # from .endpoints.space_management import SpaceManagement
19
+ # # from .endpoints.model_management import ModelManagement
20
+ # # from .endpoints.auth import AuthClient
21
+
22
+
23
+ # class SyncWrapper:
24
+ # """Generic synchronous wrapper with __dir__ support for runtime autocomplete."""
25
+
26
+ # def __init__(self, async_obj, sync_client):
27
+ # self._async_obj = async_obj
28
+ # self._sync_client = sync_client
29
+
30
+ # def __dir__(self):
31
+ # """Return list of attributes for autocomplete in interactive environments."""
32
+ # async_attrs = [attr for attr in dir(self._async_obj) if not attr.startswith('_')]
33
+ # wrapper_attrs = [attr for attr in object.__dir__(self) if not attr.startswith('_')]
34
+ # return list(set(async_attrs + wrapper_attrs))
35
+
36
+ # def __getattr__(self, name):
37
+ # """Dynamically wrap any method call to convert async to sync."""
38
+ # attr = getattr(self._async_obj, name)
39
+
40
+ # if callable(attr):
41
+ # @functools.wraps(attr)
42
+ # def sync_wrapper(*args, **kwargs):
43
+ # result = attr(*args, **kwargs)
44
+ # if hasattr(result, '__await__'):
45
+ # return self._sync_client._run_async(result)
46
+ # return result
47
+ # return sync_wrapper
48
+
49
+ # return attr
50
+
51
+
52
+ # class SyncClient:
53
+ # """
54
+ # Thread-safe synchronous wrapper for AsyncClient.
55
+ # Uses a persistent event loop in a dedicated thread to avoid event loop conflicts.
56
+ # """
57
+
58
+ # # datasets: 'DatasetManagement'
59
+ # # users: 'UserManagement'
60
+ # # mass_stats: 'MassStats'
61
+ # # groups: 'GroupManagement'
62
+ # # space: 'SpaceManagement'
63
+ # # model: 'ModelManagement'
64
+ # # auth: 'AuthClient'
65
+
66
+ # def __init__(self, url: Optional[str] = None, api_key: Optional[str] = None, verbose: bool = False):
67
+ # self._async_client = AsyncClient(url=url, api_key=api_key, verbose=verbose)
68
+ # self._context_entered = False
69
+ # self._closed = False
70
+
71
+ # # Thread and event loop management
72
+ # self._loop = None
73
+ # self._thread = None
74
+ # self._loop_ready = None
75
+ # self._loop_exception = None
76
+
77
+ # # Initialize endpoint managers
78
+ # print("we are here!!!!!!!!!!!!!!!!!")
79
+ # self.datasets = SyncWrapper(self._async_client.datasets, self)
80
+ # self.users = SyncWrapper(self._async_client.users, self)
81
+ # self.mass_stats = SyncWrapper(self._async_client.mass_stats, self)
82
+ # self.groups = SyncWrapper(self._async_client.groups, self)
83
+ # self.space = SyncWrapper(self._async_client.space, self)
84
+ # self.model = SyncWrapper(self._async_client.model, self)
85
+ # self.auth = SyncWrapper(self._async_client.auth, self)
86
+
87
+ # # Register cleanup
88
+ # import atexit
89
+ # atexit.register(self._cleanup)
90
+
91
+ # def _ensure_event_loop(self):
92
+ # """Ensure we have a persistent event loop in a dedicated thread."""
93
+ # if self._loop is None or self._loop.is_closed():
94
+ # self._loop_ready = threading.Event()
95
+ # self._loop_exception = None
96
+
97
+ # def run_loop():
98
+ # """Run the event loop in a dedicated thread."""
99
+ # try:
100
+ # # Create a new event loop for this thread
101
+ # self._loop = asyncio.new_event_loop()
102
+ # asyncio.set_event_loop(self._loop)
103
+
104
+ # # Signal that the loop is ready
105
+ # self._loop_ready.set()
106
+
107
+ # # Run the loop forever (until stopped)
108
+ # self._loop.run_forever()
109
+ # except Exception as e:
110
+ # self._loop_exception = e
111
+ # self._loop_ready.set()
112
+ # finally:
113
+ # # Clean up when the loop stops
114
+ # if self._loop and not self._loop.is_closed():
115
+ # self._loop.close()
116
+
117
+ # # Start the thread
118
+ # self._thread = threading.Thread(target=run_loop, daemon=True)
119
+ # self._thread.start()
120
+
121
+ # # Wait for the loop to be ready
122
+ # self._loop_ready.wait(timeout=10)
123
+
124
+ # if self._loop_exception:
125
+ # raise self._loop_exception
126
+
127
+ # if not self._loop_ready.is_set():
128
+ # raise RuntimeError("Event loop failed to start within timeout")
129
+
130
+ # def _run_async(self, coro):
131
+ # """
132
+ # Run async coroutine using persistent event loop.
133
+ # This is the core method that makes everything work.
134
+ # """
135
+ # # Ensure we have an event loop
136
+ # self._ensure_event_loop()
137
+
138
+ # if self._loop.is_closed():
139
+ # raise RuntimeError("Event loop is closed")
140
+
141
+ # # Create a future to get the result back from the event loop thread
142
+ # future = concurrent.futures.Future()
143
+
144
+ # async def run_with_context():
145
+ # """Run the coroutine with proper context management."""
146
+ # try:
147
+ # # Ensure the async client is properly initialized
148
+ # await self._ensure_context()
149
+
150
+ # # Run the actual coroutine
151
+ # result = await coro
152
+
153
+ # # Set the result on the future
154
+ # future.set_result(result)
155
+ # except Exception as e:
156
+ # # Set the exception on the future
157
+ # future.set_exception(e)
158
+
159
+ # # Schedule the coroutine on the persistent event loop
160
+ # self._loop.call_soon_threadsafe(
161
+ # lambda: asyncio.create_task(run_with_context())
162
+ # )
163
+
164
+ # # Wait for the result (with timeout to avoid hanging)
165
+ # try:
166
+ # return future.result(timeout=300) # 5 minute timeout
167
+ # except concurrent.futures.TimeoutError:
168
+ # raise RuntimeError("Async operation timed out after 5 minutes")
169
+
170
+ # async def _ensure_context(self):
171
+ # """Ensure the async client context is entered."""
172
+ # if not self._context_entered and not self._closed:
173
+ # await self._async_client.__aenter__()
174
+ # self._context_entered = True
175
+
176
+ # async def _exit_context(self):
177
+ # """Exit the async client context."""
178
+ # if self._context_entered and not self._closed:
179
+ # await self._async_client.__aexit__(None, None, None)
180
+ # self._context_entered = False
181
+
182
+ # def close(self):
183
+ # """Close the underlying async client session and stop the event loop."""
184
+ # if not self._closed:
185
+ # if self._loop and not self._loop.is_closed():
186
+ # # Schedule cleanup on the event loop
187
+ # future = concurrent.futures.Future()
188
+
189
+ # async def cleanup():
190
+ # """Clean up the async client."""
191
+ # try:
192
+ # await self._exit_context()
193
+ # future.set_result(None)
194
+ # except Exception as e:
195
+ # future.set_exception(e)
196
+
197
+ # # Run cleanup
198
+ # self._loop.call_soon_threadsafe(
199
+ # lambda: asyncio.create_task(cleanup())
200
+ # )
201
+
202
+ # # Wait for cleanup to complete
203
+ # try:
204
+ # future.result(timeout=10)
205
+ # except:
206
+ # pass # Ignore cleanup errors
207
+
208
+ # # Stop the event loop
209
+ # self._loop.call_soon_threadsafe(self._loop.stop)
210
+
211
+ # # Wait for thread to finish
212
+ # if self._thread and self._thread.is_alive():
213
+ # self._thread.join(timeout=5)
214
+
215
+ # self._closed = True
216
+
217
+ # def _cleanup(self):
218
+ # """Internal cleanup method called by atexit."""
219
+ # if not self._closed:
220
+ # try:
221
+ # self.close()
222
+ # except Exception:
223
+ # pass # Ignore cleanup errors
224
+
225
+ # def __dir__(self):
226
+ # """Return list of attributes for autocomplete in interactive environments."""
227
+ # default_attrs = [attr for attr in object.__dir__(self) if not attr.startswith('_')]
228
+ # async_client_attrs = [attr for attr in dir(self._async_client) if not attr.startswith('_')]
229
+ # endpoint_attrs = ['datasets', 'users', 'mass_stats', 'groups', 'space', 'model', 'auth']
230
+ # all_attrs = default_attrs + async_client_attrs + endpoint_attrs
231
+ # return list(set(all_attrs))
232
+
233
+ # # Your existing methods (geoquery, zonal_stats, etc.)
234
+ # def geoquery(
235
+ # self,
236
+ # expr: str,
237
+ # feature: Union[Dict[str, Any], ShapelyGeometry],
238
+ # in_crs: str = "epsg:4326",
239
+ # out_crs: str = "epsg:4326",
240
+ # resolution: int = -1,
241
+ # geom_fix: bool = False,
242
+ # **kwargs
243
+ # ):
244
+ # """Compute WCS query for a single geometry (synchronous version)."""
245
+ # coro = self._async_client.geoquery(
246
+ # expr=expr,
247
+ # feature=feature,
248
+ # in_crs=in_crs,
249
+ # out_crs=out_crs,
250
+ # output="netcdf",
251
+ # resolution=resolution,
252
+ # geom_fix=geom_fix,
253
+ # **kwargs
254
+ # )
255
+ # return self._run_async(coro)
256
+
257
+ # def zonal_stats(
258
+ # self,
259
+ # gdf: GeoDataFrame,
260
+ # expr: str,
261
+ # conc: int = 20,
262
+ # inplace: bool = False,
263
+ # in_crs: str = "epsg:4326",
264
+ # out_crs: str = "epsg:4326",
265
+ # resolution: int = -1,
266
+ # geom_fix: bool = False,
267
+ # drop_nan: bool = False,
268
+ # spatial_reduction: str = None,
269
+ # temporal_reduction: str = None,
270
+ # max_memory_mb: int = 500,
271
+ # stream_to_disk: bool = False,
272
+ # ):
273
+ # """Compute zonal statistics for all geometries in a GeoDataFrame (synchronous version)."""
274
+ # coro = self._async_client.zonal_stats(
275
+ # gdf=gdf,
276
+ # expr=expr,
277
+ # conc=conc,
278
+ # inplace=inplace,
279
+ # in_crs=in_crs,
280
+ # out_crs=out_crs,
281
+ # resolution=resolution,
282
+ # geom_fix=geom_fix,
283
+ # drop_nan=drop_nan,
284
+ # spatial_reduction=spatial_reduction,
285
+ # temporal_reduction=temporal_reduction,
286
+ # max_memory_mb=max_memory_mb,
287
+ # stream_to_disk=stream_to_disk
288
+ # )
289
+ # return self._run_async(coro)
290
+
291
+ # def create_dataset_file(
292
+ # self,
293
+ # aoi: str,
294
+ # expression: str,
295
+ # output: str,
296
+ # in_crs: str = "epsg:4326",
297
+ # res: float = 0.0001,
298
+ # region: str = "aus",
299
+ # to_crs: str = "epsg:4326",
300
+ # overwrite: bool = True,
301
+ # skip_existing: bool = False,
302
+ # non_interactive: bool = True,
303
+ # poll_interval: int = 30,
304
+ # download_path: str = "/home/user/Downloads",
305
+ # ) -> dict:
306
+ # """Create a dataset file using mass stats operations (synchronous version)."""
307
+ # coro = self._async_client.create_dataset_file(
308
+ # aoi=aoi,
309
+ # expression=expression,
310
+ # output=output,
311
+ # in_crs=in_crs,
312
+ # res=res,
313
+ # region=region,
314
+ # to_crs=to_crs,
315
+ # overwrite=overwrite,
316
+ # skip_existing=skip_existing,
317
+ # non_interactive=non_interactive,
318
+ # poll_interval=poll_interval,
319
+ # download_path=download_path,
320
+ # )
321
+ # return self._run_async(coro)
322
+
323
+ # # Context manager support
324
+ # def __enter__(self):
325
+ # """Context manager entry."""
326
+ # return self
327
+
328
+ # def __exit__(self, exc_type, exc_val, exc_tb):
329
+ # """Context manager exit."""
330
+ # self.close()
331
+
332
+ # def __del__(self):
333
+ # """Destructor to ensure session is closed."""
334
+ # if not self._closed:
335
+ # try:
336
+ # self._cleanup()
337
+ # except Exception:
338
+ # pass
339
+
340
+
1
341
  import asyncio
2
342
  import functools
3
- import inspect
4
343
  from typing import Optional, Dict, Any, Union
5
344
  from geopandas import GeoDataFrame
6
345
  from shapely.geometry.base import BaseGeometry as ShapelyGeometry
@@ -21,13 +360,10 @@ class SyncWrapper:
21
360
  Return list of attributes for autocomplete in interactive environments.
22
361
  This enables autocomplete in Jupyter/iPython after instantiation.
23
362
  """
24
- # Get all public attributes from the wrapped async object
25
363
  async_attrs = [attr for attr in dir(self._async_obj) if not attr.startswith('_')]
26
364
 
27
- # Get all attributes from this wrapper instance
28
365
  wrapper_attrs = [attr for attr in object.__dir__(self) if not attr.startswith('_')]
29
366
 
30
- # Combine and return unique attributes
31
367
  return list(set(async_attrs + wrapper_attrs))
32
368
 
33
369
  def __getattr__(self, name):
@@ -59,7 +395,6 @@ class SyncClient:
59
395
  self._context_entered = False
60
396
  self._closed = False
61
397
 
62
- # Initialize endpoint managers
63
398
  self.datasets = SyncWrapper(self._async_client.datasets, self)
64
399
  self.users = SyncWrapper(self._async_client.users, self)
65
400
  self.mass_stats = SyncWrapper(self._async_client.mass_stats, self)
@@ -68,7 +403,6 @@ class SyncClient:
68
403
  self.model = SyncWrapper(self._async_client.model, self)
69
404
  self.auth = SyncWrapper(self._async_client.auth, self)
70
405
 
71
- # Register cleanup
72
406
  import atexit
73
407
  atexit.register(self._cleanup)
74
408
 
@@ -77,16 +411,12 @@ class SyncClient:
77
411
  Return list of attributes for autocomplete in interactive environments.
78
412
  This includes all methods from the async client plus the endpoint managers.
79
413
  """
80
- # Get default attributes from this class
81
414
  default_attrs = [attr for attr in object.__dir__(self) if not attr.startswith('_')]
82
415
 
83
- # Get all public methods from the async client
84
416
  async_client_attrs = [attr for attr in dir(self._async_client) if not attr.startswith('_')]
85
417
 
86
- # Add endpoint managers
87
418
  endpoint_attrs = ['datasets', 'users', 'mass_stats', 'groups', 'space', 'model', 'auth']
88
419
 
89
- # Combine all attributes
90
420
  all_attrs = default_attrs + async_client_attrs + endpoint_attrs
91
421
 
92
422
  return list(set(all_attrs))
@@ -119,16 +449,10 @@ class SyncClient:
119
449
  gdf: GeoDataFrame,
120
450
  expr: str,
121
451
  conc: int = 20,
122
- inplace: bool = False,
123
452
  in_crs: str = "epsg:4326",
124
453
  out_crs: str = "epsg:4326",
125
454
  resolution: int = -1,
126
455
  geom_fix: bool = False,
127
- drop_nan: bool = False,
128
- spatial_reduction: str = None,
129
- temporal_reduction: str = None,
130
- max_memory_mb: int = 500,
131
- stream_to_disk: bool = False,
132
456
  ):
133
457
  """
134
458
  Compute zonal statistics for all geometries in a GeoDataFrame (synchronous version).
@@ -137,22 +461,13 @@ class SyncClient:
137
461
  gdf (GeoDataFrame): GeoDataFrame containing geometries
138
462
  expr (str): Terrakio expression to evaluate, can include spatial aggregations
139
463
  conc (int): Number of concurrent requests to make
140
- inplace (bool): Whether to modify the input GeoDataFrame in place
141
464
  in_crs (str): Input coordinate reference system
142
465
  out_crs (str): Output coordinate reference system
143
466
  resolution (int): Resolution parameter
144
467
  geom_fix (bool): Whether to fix the geometry (default False)
145
- drop_nan (bool): Whether to drop NaN values from the results (default False)
146
- spatial_reduction (str): Reduction operation for spatial dimensions (x, y).
147
- Options: 'mean', 'median', 'min', 'max', 'std', 'var', 'sum', 'count'
148
- temporal_reduction (str): Reduction operation for temporal dimension (time).
149
- Options: 'mean', 'median', 'min', 'max', 'std', 'var', 'sum', 'count'
150
- max_memory_mb (int): Maximum memory threshold in MB (default 500MB)
151
- stream_to_disk (bool): Whether to stream datasets to disk as NetCDF files (default False)
152
468
 
153
469
  Returns:
154
- geopandas.GeoDataFrame: GeoDataFrame with added columns for results, or None if inplace=True
155
- If stream_to_disk=True, large datasets are saved as NetCDF files with file paths stored.
470
+ geopandas.GeoDataFrame: GeoDataFrame with added columns for results
156
471
 
157
472
  Raises:
158
473
  ValueError: If concurrency is too high or if data exceeds memory limit without streaming
@@ -162,16 +477,10 @@ class SyncClient:
162
477
  gdf=gdf,
163
478
  expr=expr,
164
479
  conc=conc,
165
- inplace=inplace,
166
480
  in_crs=in_crs,
167
481
  out_crs=out_crs,
168
482
  resolution=resolution,
169
483
  geom_fix=geom_fix,
170
- drop_nan=drop_nan,
171
- spatial_reduction=spatial_reduction,
172
- temporal_reduction=temporal_reduction,
173
- max_memory_mb=max_memory_mb,
174
- stream_to_disk=stream_to_disk
175
484
  )
176
485
  return self._run_async(coro)
177
486
 
@@ -207,7 +516,6 @@ class SyncClient:
207
516
  )
208
517
  return self._run_async(coro)
209
518
 
210
- # Rest of the methods remain the same...
211
519
  async def _ensure_context(self):
212
520
  """Ensure the async client context is entered."""
213
521
  if not self._context_entered and not self._closed:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: terrakio-core
3
- Version: 0.4.2
3
+ Version: 0.4.4
4
4
  Summary: Core components for Terrakio API clients
5
5
  Author-email: Yupeng Chao <yupeng@haizea.com.au>
6
6
  Project-URL: Homepage, https://github.com/HaizeaAnalytics/terrakio-python-api
@@ -24,6 +24,7 @@ Requires-Dist: geopandas>=0.13.0
24
24
  Requires-Dist: google-cloud-storage>=2.0.0
25
25
  Requires-Dist: scipy>=1.7.0
26
26
  Requires-Dist: nest_asyncio
27
+ Requires-Dist: onnxruntime>=1.10.0
27
28
  Provides-Extra: ml
28
29
  Requires-Dist: torch>=2.7.1; extra == "ml"
29
30
  Requires-Dist: scikit-learn>=1.7.0; extra == "ml"
@@ -0,0 +1,22 @@
1
+ terrakio_core/__init__.py,sha256=tHjogyeQC-EKWpfPNnQqieQWGYRagVnj_LBiPP8vZrw,273
2
+ terrakio_core/accessors.py,sha256=qWLljU83YO7EUOefo_f6_P6ba6uiYMXwou0ihAHKBHQ,23706
3
+ terrakio_core/async_client.py,sha256=FYUuN1IboFkygylo0jFjEmhBGoHhzhAwG_KznkQR2y4,12449
4
+ terrakio_core/client.py,sha256=VXP7BtJWIfpPPZR7_yNdSTcGwNgTwhb7KorusqkQrzk,5603
5
+ terrakio_core/config.py,sha256=r8NARVYOca4AuM88VP_j-8wQxOk1s7VcRdyEdseBlLE,4193
6
+ terrakio_core/exceptions.py,sha256=4qnpOM1gOxsNIXDXY4qwY1d3I4Myhp7HBh7b2D0SVrU,529
7
+ terrakio_core/sync_client.py,sha256=HkLavfbT1sXGE1kTkiCDgNJxL9bErgOD6WihFrM-2xI,21873
8
+ terrakio_core/convenience_functions/convenience_functions.py,sha256=B7qbObjP4OuAUtrVf4Gi58c0q2EkTwOCOE568P0Q-EE,18607
9
+ terrakio_core/endpoints/auth.py,sha256=FdLsPScPIBo-Gxl6ZnE-46cp2molggAJtL72LssN3fg,6049
10
+ terrakio_core/endpoints/dataset_management.py,sha256=BUm8IIlW_Q45vDiQp16CiJGeSLheI8uWRVRQtMdhaNk,13161
11
+ terrakio_core/endpoints/group_management.py,sha256=VFl3jakjQa9OPi351D3DZvLU9M7fHdfjCzGhmyJsx3U,6309
12
+ terrakio_core/endpoints/mass_stats.py,sha256=6PSWWCpKLKMcFOoXfOAuROX8iSuG_dLyTYcw7gzhhZ4,23464
13
+ terrakio_core/endpoints/model_management.py,sha256=LH_gHPrqYA-_45KWpDBRcFbwHgm-Kg0zk1ealy7P_C0,52379
14
+ terrakio_core/endpoints/space_management.py,sha256=YWb55nkJnFJGlALJ520DvurxDqVqwYtsvqQPWzxzhDs,2266
15
+ terrakio_core/endpoints/user_management.py,sha256=WlFr3EfK8iI6DfkpMuYLHZUPk2n7_DHHO6z1hndmZB4,3816
16
+ terrakio_core/helper/bounded_taskgroup.py,sha256=wiTH10jhKZgrsgrFUNG6gig8bFkUEPHkGRT2XY7Rgmo,677
17
+ terrakio_core/helper/decorators.py,sha256=L6om7wmWNgCei3Wy5U0aZ-70OzsCwclkjIf7SfQuhCg,2289
18
+ terrakio_core/helper/tiles.py,sha256=xNtp3oDD912PN_FQV5fb6uQYhwfHANuXyIcxoVCCfZU,2632
19
+ terrakio_core-0.4.4.dist-info/METADATA,sha256=y2xrfAhs9JnlPKMyqj34QXXxS_AvY2tUyTrSM9SDFCY,1791
20
+ terrakio_core-0.4.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
21
+ terrakio_core-0.4.4.dist-info/top_level.txt,sha256=5cBj6O7rNWyn97ND4YuvvXm0Crv4RxttT4JZvNdOG6Q,14
22
+ terrakio_core-0.4.4.dist-info/RECORD,,
@@ -1,21 +0,0 @@
1
- terrakio_core/__init__.py,sha256=3u7gNX5T8lS09r7SNC2GfJoGhopey8IGP0YDyCxqFJ8,248
2
- terrakio_core/async_client.py,sha256=T0AEyhh5EwZ2_okRiHuXkLgCqovxl-fuQSejH7hXU0I,13801
3
- terrakio_core/client.py,sha256=-tGffOKGMyuowsvBwaV7Wtc_EZSWuSwv26_I5FkUank,5446
4
- terrakio_core/config.py,sha256=r8NARVYOca4AuM88VP_j-8wQxOk1s7VcRdyEdseBlLE,4193
5
- terrakio_core/exceptions.py,sha256=4qnpOM1gOxsNIXDXY4qwY1d3I4Myhp7HBh7b2D0SVrU,529
6
- terrakio_core/sync_client.py,sha256=UpPn9rHp6x6otxj3QJ1Scnac4stgIpTtb__gmXszYCA,10787
7
- terrakio_core/convenience_functions/convenience_functions.py,sha256=sBY2g7Vv3jakkuXnuFomXBWP0y6Q7q1K4ay3g4TxIoQ,21068
8
- terrakio_core/endpoints/auth.py,sha256=e_hdNE6JOGhRVlQMFdEoOmoMHp5EzK6CclOEnc_AmZw,5863
9
- terrakio_core/endpoints/dataset_management.py,sha256=BUm8IIlW_Q45vDiQp16CiJGeSLheI8uWRVRQtMdhaNk,13161
10
- terrakio_core/endpoints/group_management.py,sha256=VFl3jakjQa9OPi351D3DZvLU9M7fHdfjCzGhmyJsx3U,6309
11
- terrakio_core/endpoints/mass_stats.py,sha256=yhLCYRrdQPiWwJVCIPbzU5NV3xU5m62pxhYY1FucYjI,23130
12
- terrakio_core/endpoints/model_management.py,sha256=xB5i8LHYUgRIShHBRS1WhYOQpn0UiB_znP7LVDpMzOI,44616
13
- terrakio_core/endpoints/space_management.py,sha256=YWb55nkJnFJGlALJ520DvurxDqVqwYtsvqQPWzxzhDs,2266
14
- terrakio_core/endpoints/user_management.py,sha256=WlFr3EfK8iI6DfkpMuYLHZUPk2n7_DHHO6z1hndmZB4,3816
15
- terrakio_core/helper/bounded_taskgroup.py,sha256=wiTH10jhKZgrsgrFUNG6gig8bFkUEPHkGRT2XY7Rgmo,677
16
- terrakio_core/helper/decorators.py,sha256=L6om7wmWNgCei3Wy5U0aZ-70OzsCwclkjIf7SfQuhCg,2289
17
- terrakio_core/helper/tiles.py,sha256=xNtp3oDD912PN_FQV5fb6uQYhwfHANuXyIcxoVCCfZU,2632
18
- terrakio_core-0.4.2.dist-info/METADATA,sha256=4LwE_mXfB0r9XHp0DFsFeLZM4q1X8kEnu4FeJOkO-90,1756
19
- terrakio_core-0.4.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
20
- terrakio_core-0.4.2.dist-info/top_level.txt,sha256=5cBj6O7rNWyn97ND4YuvvXm0Crv4RxttT4JZvNdOG6Q,14
21
- terrakio_core-0.4.2.dist-info/RECORD,,