terrakio-core 0.3.9__tar.gz → 0.4.2__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.

Potentially problematic release.


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

Files changed (28) hide show
  1. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/PKG-INFO +1 -1
  2. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/pyproject.toml +1 -1
  3. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core/__init__.py +1 -1
  4. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core/async_client.py +21 -2
  5. terrakio_core-0.4.2/terrakio_core/client.py +134 -0
  6. terrakio_core-0.4.2/terrakio_core/convenience_functions/convenience_functions.py +529 -0
  7. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core/endpoints/mass_stats.py +71 -16
  8. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core/endpoints/model_management.py +424 -217
  9. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core/endpoints/user_management.py +5 -5
  10. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core/sync_client.py +106 -185
  11. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core.egg-info/PKG-INFO +1 -1
  12. terrakio_core-0.3.9/terrakio_core/client.py +0 -38
  13. terrakio_core-0.3.9/terrakio_core/convenience_functions/convenience_functions.py +0 -278
  14. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/README.md +0 -0
  15. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/setup.cfg +0 -0
  16. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core/config.py +0 -0
  17. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core/endpoints/auth.py +0 -0
  18. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core/endpoints/dataset_management.py +0 -0
  19. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core/endpoints/group_management.py +0 -0
  20. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core/endpoints/space_management.py +0 -0
  21. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core/exceptions.py +0 -0
  22. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core/helper/bounded_taskgroup.py +0 -0
  23. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core/helper/decorators.py +0 -0
  24. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core/helper/tiles.py +0 -0
  25. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core.egg-info/SOURCES.txt +0 -0
  26. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core.egg-info/dependency_links.txt +0 -0
  27. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core.egg-info/requires.txt +0 -0
  28. {terrakio_core-0.3.9 → terrakio_core-0.4.2}/terrakio_core.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: terrakio-core
3
- Version: 0.3.9
3
+ Version: 0.4.2
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "terrakio-core"
7
- version = "0.3.9"
7
+ version = "0.4.2"
8
8
  authors = [
9
9
  {name = "Yupeng Chao", email = "yupeng@haizea.com.au"},
10
10
  ]
@@ -5,7 +5,7 @@ Terrakio Core
5
5
  Core components for Terrakio API clients.
6
6
  """
7
7
 
8
- __version__ = "0.3.9"
8
+ __version__ = "0.4.2"
9
9
 
10
10
  from .async_client import AsyncClient
11
11
  from .sync_client import SyncClient as Client
@@ -182,6 +182,11 @@ class AsyncClient(BaseClient):
182
182
  out_crs: str = "epsg:4326",
183
183
  resolution: int = -1,
184
184
  geom_fix: bool = False,
185
+ drop_nan: bool = False,
186
+ spatial_reduction: str = None,
187
+ temporal_reduction: str = None,
188
+ max_memory_mb: int = 500,
189
+ stream_to_disk: bool = False,
185
190
  ):
186
191
  """
187
192
  Compute zonal statistics for all geometries in a GeoDataFrame.
@@ -195,11 +200,20 @@ class AsyncClient(BaseClient):
195
200
  out_crs (str): Output coordinate reference system
196
201
  resolution (int): Resolution parameter
197
202
  geom_fix (bool): Whether to fix the geometry (default False)
203
+ drop_nan (bool): Whether to drop NaN values from the results (default False)
204
+ spatial_reduction (str): Reduction operation for spatial dimensions (x, y).
205
+ Options: 'mean', 'median', 'min', 'max', 'std', 'var', 'sum', 'count'
206
+ temporal_reduction (str): Reduction operation for temporal dimension (time).
207
+ Options: 'mean', 'median', 'min', 'max', 'std', 'var', 'sum', 'count'
208
+ max_memory_mb (int): Maximum memory threshold in MB (default 500MB)
209
+ stream_to_disk (bool): Whether to stream datasets to disk as NetCDF files (default False)
210
+
198
211
  Returns:
199
212
  geopandas.GeoDataFrame: GeoDataFrame with added columns for results, or None if inplace=True
213
+ If stream_to_disk=True, large datasets are saved as NetCDF files with file paths stored.
200
214
 
201
215
  Raises:
202
- ValueError: If concurrency is too high
216
+ ValueError: If concurrency is too high or if data exceeds memory limit without streaming
203
217
  APIError: If the API request fails
204
218
  """
205
219
  return await _zonal_stats(
@@ -211,7 +225,12 @@ class AsyncClient(BaseClient):
211
225
  in_crs=in_crs,
212
226
  out_crs=out_crs,
213
227
  resolution=resolution,
214
- geom_fix=geom_fix
228
+ geom_fix=geom_fix,
229
+ drop_nan=drop_nan,
230
+ spatial_reduction=spatial_reduction,
231
+ temporal_reduction=temporal_reduction,
232
+ max_memory_mb=max_memory_mb,
233
+ stream_to_disk=stream_to_disk
215
234
  )
216
235
 
217
236
  async def create_dataset_file(
@@ -0,0 +1,134 @@
1
+ from typing import Optional
2
+ import logging
3
+ import warnings
4
+ from terrakio_core.config import read_config_file, DEFAULT_CONFIG_FILE
5
+ from abc import abstractmethod
6
+ import xarray as xr
7
+
8
+
9
+ class BaseClient():
10
+ def __init__(self, url: Optional[str] = None, api_key: Optional[str] = None, verbose: bool = False):
11
+
12
+ self.verbose = verbose
13
+ self.logger = logging.getLogger("terrakio")
14
+ if verbose:
15
+ self.logger.setLevel(logging.INFO)
16
+ else:
17
+ self.logger.setLevel(logging.WARNING)
18
+
19
+ self.timeout = 300
20
+ self.retry = 3
21
+
22
+ self.session = None
23
+
24
+ self.url = url
25
+ self.key = api_key
26
+
27
+ config = read_config_file(DEFAULT_CONFIG_FILE, logger=self.logger)
28
+
29
+ if self.url is None:
30
+ self.url = config.get('url')
31
+
32
+ if self.key is None:
33
+ self.key = config.get('key')
34
+
35
+ self.token = config.get('token')
36
+
37
+ # Apply xarray printing fix to prevent crashes with GeoDataFrames
38
+ self._apply_xarray_fix()
39
+
40
+ def _apply_xarray_fix(self):
41
+ """
42
+ Apply xarray printing fix to prevent crashes when GeoDataFrames contain xarray objects.
43
+ This fix is applied automatically when the client is initialized.
44
+ """
45
+ try:
46
+
47
+ # Check if fix is already applied globally
48
+ if hasattr(xr.DataArray, '_terrakio_fix_applied'):
49
+ if self.verbose:
50
+ self.logger.info("xarray printing fix already applied")
51
+ return
52
+
53
+ # Store original methods for potential restoration
54
+ if not hasattr(xr.DataArray, '_original_iter'):
55
+ xr.DataArray._original_iter = xr.DataArray.__iter__
56
+ xr.Dataset._original_iter = xr.Dataset.__iter__
57
+
58
+ # Define safe iteration methods that prevent pandas from iterating
59
+ # but leave __repr__ and __str__ untouched for normal xarray printing
60
+ def safe_dataarray_iter(self):
61
+ # Return infinite iterator that always yields the same safe value
62
+ name = getattr(self, 'name', None) or 'unnamed'
63
+ shape_str = 'x'.join(map(str, self.shape)) if hasattr(self, 'shape') else 'unknown'
64
+ placeholder = f"<DataArray '{name}' {shape_str}>"
65
+ while True:
66
+ yield placeholder
67
+
68
+ def safe_dataset_iter(self):
69
+ # Return infinite iterator that always yields the same safe value
70
+ num_vars = len(self.data_vars) if hasattr(self, 'data_vars') else 0
71
+ num_dims = len(self.dims) if hasattr(self, 'dims') else 0
72
+ placeholder = f"<Dataset: {num_vars} vars, {num_dims} dims>"
73
+ while True:
74
+ yield placeholder
75
+
76
+ # Apply only the iteration fix - leave __repr__ and __str__ untouched
77
+ xr.DataArray.__iter__ = safe_dataarray_iter
78
+ xr.Dataset.__iter__ = safe_dataset_iter
79
+
80
+ # Mark as applied to avoid duplicate applications
81
+ xr.DataArray._terrakio_fix_applied = True
82
+ xr.Dataset._terrakio_fix_applied = True
83
+
84
+ if self.verbose:
85
+ self.logger.info("xarray iteration fix applied - GeoDataFrames with xarray objects will print safely, direct xarray printing unchanged")
86
+
87
+ except ImportError:
88
+ # xarray not installed, skip the fix
89
+ if self.verbose:
90
+ self.logger.info("xarray not installed, skipping printing fix")
91
+ except Exception as e:
92
+ # Log warning but don't fail initialization
93
+ warning_msg = f"Failed to apply xarray printing fix: {e}"
94
+ warnings.warn(warning_msg)
95
+ if self.verbose:
96
+ self.logger.warning(warning_msg)
97
+
98
+ def restore_xarray_printing(self):
99
+ """
100
+ Restore original xarray printing behavior.
101
+ Call this method if you want to see full xarray representations again.
102
+ """
103
+ try:
104
+ import xarray as xr
105
+
106
+ if hasattr(xr.DataArray, '_original_iter'):
107
+ xr.DataArray.__iter__ = xr.DataArray._original_iter
108
+ xr.Dataset.__iter__ = xr.Dataset._original_iter
109
+
110
+ # Remove the fix markers
111
+ if hasattr(xr.DataArray, '_terrakio_fix_applied'):
112
+ delattr(xr.DataArray, '_terrakio_fix_applied')
113
+ if hasattr(xr.Dataset, '_terrakio_fix_applied'):
114
+ delattr(xr.Dataset, '_terrakio_fix_applied')
115
+
116
+ if self.verbose:
117
+ self.logger.info("Original xarray iteration behavior restored")
118
+ else:
119
+ if self.verbose:
120
+ self.logger.info("No xarray fix to restore")
121
+
122
+ except ImportError:
123
+ if self.verbose:
124
+ self.logger.info("xarray not available")
125
+ except Exception as e:
126
+ warning_msg = f"Failed to restore xarray printing: {e}"
127
+ warnings.warn(warning_msg)
128
+ if self.verbose:
129
+ self.logger.warning(warning_msg)
130
+
131
+ @abstractmethod
132
+ def _setup_session(self):
133
+ """Initialize the HTTP session - implemented by sync/async clients"""
134
+ pass