stac-fastapi-core 6.10.0__py3-none-any.whl → 6.10.1__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.
stac_fastapi/core/core.py CHANGED
@@ -1006,14 +1006,31 @@ class TransactionsClient(AsyncBaseTransactionsClient):
1006
1006
  database=self.database, settings=self.settings
1007
1007
  )
1008
1008
  features = item_dict["features"]
1009
- processed_items = [
1009
+ all_prepped = [
1010
1010
  bulk_client.preprocess_item(
1011
1011
  feature, base_url, BulkTransactionMethod.INSERT
1012
1012
  )
1013
1013
  for feature in features
1014
1014
  ]
1015
+ # Filter out None values (skipped duplicates from DB check)
1016
+ processed_items = [item for item in all_prepped if item is not None]
1017
+ skipped_db_duplicates = len(all_prepped) - len(processed_items)
1018
+
1019
+ # Deduplicate items within the batch by ID (keep last occurrence)
1020
+ # This matches ES behavior where later items overwrite earlier ones
1021
+ seen_ids: dict = {}
1022
+ for item in processed_items:
1023
+ seen_ids[item["id"]] = item
1024
+ unique_items = list(seen_ids.values())
1025
+ skipped_batch_duplicates = len(processed_items) - len(unique_items)
1026
+ processed_items = unique_items
1027
+
1028
+ skipped = skipped_db_duplicates + skipped_batch_duplicates
1015
1029
  attempted = len(processed_items)
1016
1030
 
1031
+ if not processed_items:
1032
+ return f"No items to insert. {skipped} items were skipped (duplicates)."
1033
+
1017
1034
  success, errors = await self.database.bulk_async(
1018
1035
  collection_id=collection_id,
1019
1036
  processed_items=processed_items,
@@ -1027,7 +1044,7 @@ class TransactionsClient(AsyncBaseTransactionsClient):
1027
1044
  logger.info(
1028
1045
  f"Bulk async operation succeeded with {success} actions for collection {collection_id}."
1029
1046
  )
1030
- return f"Successfully added {success} Items. {attempted - success} errors occurred."
1047
+ return f"Successfully added {success} Items. {skipped} skipped (duplicates). {attempted - success} errors occurred."
1031
1048
 
1032
1049
  # Handle single item
1033
1050
  await self.database.create_item(
@@ -1340,18 +1357,35 @@ class BulkTransactionsClient(BaseBulkTransactionsClient):
1340
1357
  base_url = ""
1341
1358
 
1342
1359
  processed_items = []
1360
+ skipped_db_duplicates = 0
1343
1361
  for item in items.items.values():
1344
1362
  try:
1345
1363
  validated = Item(**item) if not isinstance(item, Item) else item
1346
- processed_items.append(
1347
- self.preprocess_item(
1348
- validated.model_dump(mode="json"), base_url, items.method
1349
- )
1364
+ prepped = self.preprocess_item(
1365
+ validated.model_dump(mode="json"), base_url, items.method
1350
1366
  )
1367
+ if prepped is not None:
1368
+ processed_items.append(prepped)
1369
+ else:
1370
+ skipped_db_duplicates += 1
1351
1371
  except ValidationError:
1352
1372
  # Immediately raise on the first invalid item (strict mode)
1353
1373
  raise
1354
1374
 
1375
+ # Deduplicate items within the batch by ID (keep last occurrence)
1376
+ # This matches ES behavior where later items overwrite earlier ones
1377
+ seen_ids: dict = {}
1378
+ for item in processed_items:
1379
+ seen_ids[item["id"]] = item
1380
+ unique_items = list(seen_ids.values())
1381
+ skipped_batch_duplicates = len(processed_items) - len(unique_items)
1382
+ processed_items = unique_items
1383
+
1384
+ skipped = skipped_db_duplicates + skipped_batch_duplicates
1385
+
1386
+ if not processed_items:
1387
+ return f"No items to insert. {skipped} items were skipped (duplicates)."
1388
+
1355
1389
  collection_id = processed_items[0]["collection"]
1356
1390
  attempted = len(processed_items)
1357
1391
  success, errors = self.database.bulk_sync(
@@ -1364,4 +1398,4 @@ class BulkTransactionsClient(BaseBulkTransactionsClient):
1364
1398
  else:
1365
1399
  logger.info(f"Bulk sync operation succeeded with {success} actions.")
1366
1400
 
1367
- return f"Successfully added/updated {success} Items. {attempted - success} errors occurred."
1401
+ return f"Successfully added/updated {success} Items. {skipped} skipped (duplicates). {attempted - success} errors occurred."
@@ -1,2 +1,2 @@
1
1
  """library version."""
2
- __version__ = "6.10.0"
2
+ __version__ = "6.10.1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stac_fastapi_core
3
- Version: 6.10.0
3
+ Version: 6.10.1
4
4
  Summary: Core library for the Elasticsearch and Opensearch stac-fastapi backends.
5
5
  Project-URL: Homepage, https://github.com/stac-utils/stac-fastapi-elasticsearch-opensearch
6
6
  License: MIT
@@ -2,7 +2,7 @@ stac_fastapi/core/__init__.py,sha256=8izV3IWRGdXmDOK1hIPQAanbWs9EI04PJCGgqG1ZGIs
2
2
  stac_fastapi/core/base_database_logic.py,sha256=JL7DRcDdqeaLbSPPGcIUMs7q6I3Gm_E5XCOwFG458Io,6053
3
3
  stac_fastapi/core/base_settings.py,sha256=R3_Sx7n5XpGMs3zAwFJD7y008WvGU_uI2xkaabm82Kg,239
4
4
  stac_fastapi/core/basic_auth.py,sha256=RhFv3RVSHF6OaqnaaU2DO4ncJ_S5nB1q8UNpnVJJsrk,2155
5
- stac_fastapi/core/core.py,sha256=OKgezb8kEaB10aeNpov4xxHabM7_5ABl3wD6VaVdChE,52300
5
+ stac_fastapi/core/core.py,sha256=YJ88BRgeeYFjo2jkIrZJ5hw2Wqo6GNIz5R98u45sdLI,53976
6
6
  stac_fastapi/core/datetime_utils.py,sha256=QygF2mJFfI_zqCwmSIec3HYqrsVsn3nUcaRQx3CD7Zw,4683
7
7
  stac_fastapi/core/queryables.py,sha256=0gKdxlmCVaIj3ODpmyIfzLChEB1nNKXPZhA3K9ApfL0,3755
8
8
  stac_fastapi/core/rate_limit.py,sha256=Gu8dAaJReGsj1L91U6m2tflU6RahpXDRs2-AYSKoybA,1318
@@ -11,7 +11,7 @@ stac_fastapi/core/route_dependencies.py,sha256=hdtuMkv-zY1vg0YxiCz1aKP0SbBcORqDG
11
11
  stac_fastapi/core/serializers.py,sha256=r9BhjoAWH5Kg6ypEugPZcJ7tPaFx8vWaMJkfoPW5Fdw,13443
12
12
  stac_fastapi/core/session.py,sha256=aXqu4LXfVbAAsChMVXd9gAhczA2bZPne6HqPeklAwMY,474
13
13
  stac_fastapi/core/utilities.py,sha256=B-tLc_H_v92q8ZNpzk-9nKQMKe-bVHUk64HpybGqYX0,10398
14
- stac_fastapi/core/version.py,sha256=bQiD_D-FuZl4YJZxrz9LK-THtzxnF7e-QdjJAiGBoSY,46
14
+ stac_fastapi/core/version.py,sha256=AD8oiYJE5bGoF51nIlCATcNL2aBRMbKASqetnSyzqGA,46
15
15
  stac_fastapi/core/extensions/__init__.py,sha256=oaK-UJDQSEISdQ8VtM0ESxpsv7Hx1HbAdmMnh6MTFD4,356
16
16
  stac_fastapi/core/extensions/aggregation.py,sha256=v1hUHqlYuMqfQ554g3cTp16pUyRYucQxPERbHPAFtf8,1878
17
17
  stac_fastapi/core/extensions/catalogs.py,sha256=JR9ireabml5zCcWVM1FPIWZjb87Ffnk81MQm8cnUi6I,45668
@@ -22,6 +22,6 @@ stac_fastapi/core/extensions/query.py,sha256=Xmo8pfZEZKPudZEjjozv3R0wLOP0ayjC9E6
22
22
  stac_fastapi/core/models/__init__.py,sha256=sUsEB7umGZVYXjT4EHqLwm8p2wevtRBdig2Ioj2ZdVQ,631
23
23
  stac_fastapi/core/models/links.py,sha256=5KEZKisFN34U4UuOzSQnDy0QdsUOT2VRuuY36vs-FGw,7074
24
24
  stac_fastapi/core/models/search.py,sha256=7SgAUyzHGXBXSqB4G6cwq9FMwoAS00momb7jvBkjyow,27
25
- stac_fastapi_core-6.10.0.dist-info/METADATA,sha256=DQkAL0txwG2gljAhY5jwcijSO-PIFXprbmD_SkwIVLU,3481
26
- stac_fastapi_core-6.10.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
27
- stac_fastapi_core-6.10.0.dist-info/RECORD,,
25
+ stac_fastapi_core-6.10.1.dist-info/METADATA,sha256=FT-TnAN6MIjD2IyQhovMvJxMgmDJ1vvQcRnApMlg1PY,3481
26
+ stac_fastapi_core-6.10.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
27
+ stac_fastapi_core-6.10.1.dist-info/RECORD,,