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

terrakio_core/__init__.py CHANGED
@@ -5,7 +5,7 @@ Terrakio Core
5
5
  Core components for Terrakio API clients.
6
6
  """
7
7
 
8
- __version__ = "0.4.96"
8
+ __version__ = "0.4.97"
9
9
 
10
10
  from .async_client import AsyncClient
11
11
  from .sync_client import SyncClient as Client
@@ -513,6 +513,35 @@ async def zonal_stats(
513
513
  job_name = await client.mass_stats.track_job([mass_stats_id])
514
514
  job_name = job_name[mass_stats_id]["name"]
515
515
  cloud_files_object = cloud_object(job_id = mass_stats_id, job_name = job_name, client = client)
516
+
517
+ # Attach id column behavior to cloud object via a wrapper method
518
+ async def _head_with_id(n = 5):
519
+ result_gdf = await cloud_files_object._head_async(n)
520
+ if id_column is not None and id_column in gdf.columns:
521
+ geometry_to_id = {geom.wkb: id_val for geom, id_val in zip(gdf.geometry, gdf[id_column])}
522
+ if hasattr(result_gdf.index, 'names') and 'geometry' in result_gdf.index.names:
523
+ if isinstance(result_gdf.index, pd.MultiIndex):
524
+ geometry_index = result_gdf.index.get_level_values('geometry')
525
+ else:
526
+ geometry_index = result_gdf.index
527
+ id_values = [geometry_to_id.get(geom.wkb) for geom in geometry_index]
528
+ result_gdf[id_column] = id_values
529
+ result_gdf = result_gdf.reset_index()
530
+ if 'time' in result_gdf.columns:
531
+ result_gdf = result_gdf.set_index([id_column, 'geometry', 'time'])
532
+ else:
533
+ result_gdf = result_gdf.set_index([id_column, 'geometry'])
534
+ else:
535
+ id_values = [geometry_to_id.get(geom.wkb) for geom in result_gdf['geometry']]
536
+ result_gdf[id_column] = id_values
537
+ if 'time' in result_gdf.columns:
538
+ result_gdf = result_gdf.set_index([id_column, 'geometry', 'time'])
539
+ else:
540
+ result_gdf = result_gdf.set_index([id_column, 'geometry'])
541
+ return result_gdf
542
+
543
+ # Monkey-patch a convenience method without modifying original class contract
544
+ cloud_files_object.head_with_id = lambda n=5: asyncio.run(_head_with_id(n))
516
545
  return cloud_files_object
517
546
 
518
547
  quries = []
@@ -539,5 +568,33 @@ async def zonal_stats(
539
568
  "is_cloud_backed": False,
540
569
  }
541
570
  gdf_with_datasets = expand_on_variables_and_time(gdf_with_datasets)
571
+
572
+ # If an id_column is provided, attach it to the result and include in the index
573
+ if id_column is not None and id_column in gdf.columns:
574
+ # Build a mapping from input geometries to id values (use WKB for robust equality)
575
+ geometry_to_id = {geom.wkb: id_val for geom, id_val in zip(gdf.geometry, gdf[id_column])}
576
+
577
+ # Determine geometry values in the result (index may be geometry or (geometry, time))
578
+ if hasattr(gdf_with_datasets.index, 'names') and 'geometry' in gdf_with_datasets.index.names:
579
+ if isinstance(gdf_with_datasets.index, pd.MultiIndex):
580
+ geometry_index = gdf_with_datasets.index.get_level_values('geometry')
581
+ else:
582
+ geometry_index = gdf_with_datasets.index
583
+ id_values = [geometry_to_id.get(geom.wkb) for geom in geometry_index]
584
+ gdf_with_datasets[id_column] = id_values
585
+ # Reset index to control index composition precisely, then set to desired levels
586
+ gdf_with_datasets = gdf_with_datasets.reset_index()
587
+ if 'time' in gdf_with_datasets.columns:
588
+ gdf_with_datasets = gdf_with_datasets.set_index([id_column, 'geometry', 'time'])
589
+ else:
590
+ gdf_with_datasets = gdf_with_datasets.set_index([id_column, 'geometry'])
591
+ else:
592
+ # geometry exists as a column
593
+ id_values = [geometry_to_id.get(geom.wkb) for geom in gdf_with_datasets['geometry']]
594
+ gdf_with_datasets[id_column] = id_values
595
+ if 'time' in gdf_with_datasets.columns:
596
+ gdf_with_datasets = gdf_with_datasets.set_index([id_column, 'geometry', 'time'])
597
+ else:
598
+ gdf_with_datasets = gdf_with_datasets.set_index([id_column, 'geometry'])
542
599
  return gdf_with_datasets
543
600
 
@@ -69,7 +69,7 @@ class DatasetManagement:
69
69
  name: Name of the dataset (required)
70
70
  collection: Dataset collection (default: 'terrakio-datasets')
71
71
  products: List of products
72
- dates_iso8601: List of dates
72
+ dates_iso8601: List of dates (will be automatically sorted chronologically)
73
73
  bucket: Storage bucket
74
74
  path: Storage path
75
75
  data_type: Data type
@@ -142,7 +142,7 @@ class DatasetManagement:
142
142
  append: Whether to append data or replace (default: True)
143
143
  collection: Dataset collection (default: 'terrakio-datasets')
144
144
  products: List of products
145
- dates_iso8601: List of dates
145
+ dates_iso8601: List of dates (will be automatically sorted chronologically)
146
146
  bucket: Storage bucket
147
147
  path: Storage path
148
148
  data_type: Data type
@@ -162,6 +162,10 @@ class DatasetManagement:
162
162
  Raises:
163
163
  APIError: If the API request fails
164
164
  """
165
+ # Sort dates_iso8601 chronologically if provided
166
+ if dates_iso8601 is not None:
167
+ dates_iso8601 = sorted(dates_iso8601)
168
+
165
169
  params = {"collection": collection, "append": str(append).lower()}
166
170
  payload = {"name": name}
167
171
  param_mapping = {
@@ -215,7 +219,7 @@ class DatasetManagement:
215
219
  append: Whether to append data or replace (default: True)
216
220
  collection: Dataset collection (default: 'terrakio-datasets')
217
221
  products: List of products
218
- dates_iso8601: List of dates
222
+ dates_iso8601: List of dates (will be automatically sorted chronologically)
219
223
  bucket: Storage bucket
220
224
  path: Storage path
221
225
  data_type: Data type
@@ -236,6 +240,10 @@ class DatasetManagement:
236
240
  Raises:
237
241
  APIError: If the API request fails
238
242
  """
243
+ # Sort dates_iso8601 chronologically if provided
244
+ if dates_iso8601 is not None:
245
+ dates_iso8601 = sorted(dates_iso8601)
246
+
239
247
  params = {"collection": collection, "append": str(append).lower()}
240
248
  payload = {"name": name}
241
249
  param_mapping = {
@@ -289,7 +297,7 @@ class DatasetManagement:
289
297
  name: Name of the dataset (required)
290
298
  collection: Dataset collection (default: 'terrakio-datasets')
291
299
  products: List of products
292
- dates_iso8601: List of dates
300
+ dates_iso8601: List of dates (will be automatically sorted chronologically)
293
301
  bucket: Storage bucket
294
302
  path: Storage path
295
303
  data_type: Data type
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: terrakio-core
3
- Version: 0.4.96
3
+ Version: 0.4.97
4
4
  Summary: Core package for the terrakio-python-api
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: aiofiles>=24.1.0
@@ -1,4 +1,4 @@
1
- terrakio_core/__init__.py,sha256=5fmKNGnXc1Yt5XJTaXPIfcmP2XVJFWPeH6apnD8xs5w,274
1
+ terrakio_core/__init__.py,sha256=HTlEcbJMNK-hrdq99CSMO6xU-A4UTVRBi3fVglJFSRQ,274
2
2
  terrakio_core/accessors.py,sha256=UZIi9y4RpBxouSmKuwuNYLIYqDxD8BH-GnUzwJuc1JI,47570
3
3
  terrakio_core/async_client.py,sha256=txdSsX3IwqtHlcS86u6N6vjV0-PIiermxNOIjEMQ3Yg,14950
4
4
  terrakio_core/client.py,sha256=VXP7BtJWIfpPPZR7_yNdSTcGwNgTwhb7KorusqkQrzk,5603
@@ -7,9 +7,9 @@ terrakio_core/exceptions.py,sha256=4qnpOM1gOxsNIXDXY4qwY1d3I4Myhp7HBh7b2D0SVrU,5
7
7
  terrakio_core/sync_client.py,sha256=jbG2sMnbR3QPvhAxQX2dBWeX_6f-Qx_MFSRLLpvfRh4,14604
8
8
  terrakio_core/convenience_functions/create_dataset_file.py,sha256=RDTAQnKUigyczv3EKhKrs34VMDZDCgL4iz0bge1d9e4,4774
9
9
  terrakio_core/convenience_functions/geoquries.py,sha256=7E3drOD5ffNk2-rKLbwKsNp3_Berq-S1lQk5wwHSuAo,3786
10
- terrakio_core/convenience_functions/zonal_stats.py,sha256=5YBy9V1QK0iovuLffuQY3M2n3NXpY8l__n-6F8vEuOY,20149
10
+ terrakio_core/convenience_functions/zonal_stats.py,sha256=Sg_T3_85acMPvZkDxBf3fMTmNXnEfKnjVCEB7SKT4Fc,23807
11
11
  terrakio_core/endpoints/auth.py,sha256=FdLsPScPIBo-Gxl6ZnE-46cp2molggAJtL72LssN3fg,6049
12
- terrakio_core/endpoints/dataset_management.py,sha256=BUm8IIlW_Q45vDiQp16CiJGeSLheI8uWRVRQtMdhaNk,13161
12
+ terrakio_core/endpoints/dataset_management.py,sha256=D2foX8DGbSXQ4vYLRt0Es3j96a_qfd920Ct3uN3dd7Y,13641
13
13
  terrakio_core/endpoints/group_management.py,sha256=VFl3jakjQa9OPi351D3DZvLU9M7fHdfjCzGhmyJsx3U,6309
14
14
  terrakio_core/endpoints/mass_stats.py,sha256=Vb6Tf8kKf5Hlch4ddsrQnfayfiK6z7NSjO8D0pop4p8,25699
15
15
  terrakio_core/endpoints/model_management.py,sha256=LH_gHPrqYA-_45KWpDBRcFbwHgm-Kg0zk1ealy7P_C0,52379
@@ -18,6 +18,6 @@ terrakio_core/endpoints/user_management.py,sha256=WlFr3EfK8iI6DfkpMuYLHZUPk2n7_D
18
18
  terrakio_core/helper/bounded_taskgroup.py,sha256=wiTH10jhKZgrsgrFUNG6gig8bFkUEPHkGRT2XY7Rgmo,677
19
19
  terrakio_core/helper/decorators.py,sha256=L6om7wmWNgCei3Wy5U0aZ-70OzsCwclkjIf7SfQuhCg,2289
20
20
  terrakio_core/helper/tiles.py,sha256=lcLCO6KiP05lCI9vngo3zCZJ6Z9C0pUxHSQS4H58EHc,2699
21
- terrakio_core-0.4.96.dist-info/METADATA,sha256=vX7L1UsQc_JDco4PWgnQgIdUehRq5CGFMftVJGz4pFs,1151
22
- terrakio_core-0.4.96.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
23
- terrakio_core-0.4.96.dist-info/RECORD,,
21
+ terrakio_core-0.4.97.dist-info/METADATA,sha256=wxkjwA2YX_vXeBnpenFaVjoglb7Muu84Oe5UdY5-jyM,1151
22
+ terrakio_core-0.4.97.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
23
+ terrakio_core-0.4.97.dist-info/RECORD,,