dafab-client 2.2.0__tar.gz → 2.2.3__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.
Files changed (104) hide show
  1. {dafab_client-2.2.0 → dafab_client-2.2.3}/PKG-INFO +1 -1
  2. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/common/plugins.py +1 -1
  3. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/rse/rsemanager.py +14 -0
  4. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/example_notebooks/dafab_dasi_workflows.ipynb +8 -8
  5. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/example_notebooks/dafab_operator_workflows.ipynb +15 -17
  6. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/example_notebooks/dafab_skim_workflows.ipynb +14 -14
  7. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/demo_imports.py +6 -1
  8. dafab_client-2.2.3/dafab_client/helpers/file_management/Deletion/delete_file_of_scope_name.py +123 -0
  9. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/file_management/Deletion/delete_replica_of_scope_name.py +30 -6
  10. dafab_client-2.2.3/dafab_client/helpers/resources/schemas/dasi-original-item.schema.json +4729 -0
  11. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/runtime_paths.py +1 -0
  12. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client.egg-info/PKG-INFO +1 -1
  13. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client.egg-info/SOURCES.txt +2 -1
  14. {dafab_client-2.2.0 → dafab_client-2.2.3}/pyproject.toml +1 -1
  15. dafab_client-2.2.0/dafab_client/helpers/file_management/Deletion/delete_file_of_scope_name.py +0 -68
  16. {dafab_client-2.2.0 → dafab_client-2.2.3}/MANIFEST.in +0 -0
  17. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/__init__.py +0 -0
  18. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/__init__.py +0 -0
  19. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/client/__init__.py +0 -0
  20. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/client/accountclient.py +0 -0
  21. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/client/baseclient.py +0 -0
  22. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/client/client.py +0 -0
  23. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/client/credentialclient.py +0 -0
  24. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/client/didclient.py +0 -0
  25. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/client/downloadclient.py +0 -0
  26. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/client/pingclient.py +0 -0
  27. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/client/replicaclient.py +0 -0
  28. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/client/rseclient.py +0 -0
  29. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/client/scopeclient.py +0 -0
  30. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/client/uploadclient.py +0 -0
  31. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/common/cache.py +0 -0
  32. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/common/checksum.py +0 -0
  33. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/common/client.py +0 -0
  34. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/common/config.py +0 -0
  35. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/common/constants.py +0 -0
  36. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/common/constraints.py +0 -0
  37. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/common/didtype.py +0 -0
  38. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/common/exception.py +0 -0
  39. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/common/extra.py +0 -0
  40. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/common/filter.py +0 -0
  41. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/common/logging.py +0 -0
  42. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/common/pcache.py +0 -0
  43. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/common/types.py +0 -0
  44. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/common/utils.py +0 -0
  45. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/core/rse.py +0 -0
  46. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/dafab_lib.py +0 -0
  47. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/global_utils.py +0 -0
  48. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/overridden_rucio_client.py +0 -0
  49. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/rse/__init__.py +0 -0
  50. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/rse/protocols/__init__.py +0 -0
  51. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/rse/protocols/gfal.py +0 -0
  52. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/rse/protocols/protocol.py +0 -0
  53. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/rse/protocols/webdav.py +0 -0
  54. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/rse/translation.py +0 -0
  55. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/secrets/user_dafab/config +0 -0
  56. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/secrets/user_dafab/rucio_ca_bundle.pem +0 -0
  57. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/_rucio/version.py +0 -0
  58. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/example_notebooks/dafab_simple_user_workflows.ipynb +0 -0
  59. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/System/check_available_accounts.py +0 -0
  60. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/System/check_storage.py +0 -0
  61. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/__init__.py +0 -0
  62. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/check_server_health.py +0 -0
  63. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/container_management/ensure_container.py +0 -0
  64. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/container_management/list_containers.py +0 -0
  65. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/dataset_management/ensure_dataset.py +0 -0
  66. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/dataset_management/list_datasets.py +0 -0
  67. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/dataset_management/scope_management.py +0 -0
  68. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/db_bootstrap/account_manager.py +0 -0
  69. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/did_management/operations.py +0 -0
  70. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/file_management/Insertion/upload_file_of_scope_name.py +0 -0
  71. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/file_management/Retrieval/download_file_of_scope_name.py +0 -0
  72. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/file_management/Workflows/manage_derived_assets.py +0 -0
  73. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/file_management/list_files.py +0 -0
  74. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/filtering/filter_by_bbox.py +0 -0
  75. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/filtering/filter_by_bbox_and_timerange.py +0 -0
  76. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/filtering/filter_by_enhanced_filter.py +0 -0
  77. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/filtering/filter_by_relationships.py +0 -0
  78. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/filtering/filter_by_timerange.py +0 -0
  79. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/filtering/mapper.py +0 -0
  80. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/Insertion/set_metadata.py +0 -0
  81. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/Operations/common.py +0 -0
  82. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/Operations/delete_metadata_for_did.py +0 -0
  83. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/Operations/insert_metadata_for_did.py +0 -0
  84. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/Operations/update_metadata_for_did.py +0 -0
  85. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/Operations/upsert_metadata_for_did.py +0 -0
  86. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/Patch/patch_metadata_for_dids.py +0 -0
  87. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/Preflight/validate_derived_item_file.py +0 -0
  88. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/Preflight/validate_facet_value_catalog_file.py +0 -0
  89. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/Preflight/validate_original_item_file.py +0 -0
  90. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/Retrieval/Complete/get_metadata_for_scope_name.py +0 -0
  91. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/Retrieval/Partial/get_single_metadata_for_scope_name.py +0 -0
  92. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/Workflows/sync_spatial_bbox_integrity.py +0 -0
  93. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/Workflows/update_derived_item.py +0 -0
  94. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/Workflows/update_original_item.py +0 -0
  95. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/metadata_management/document_api.py +0 -0
  96. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/resources/schemas/Schema_Copernicus_with_dafab.json +0 -0
  97. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/resources/schemas/Schema_DaFab_Facet_Value_Catalog.json +0 -0
  98. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/resources/schemas/dafab-smart_agriculture-item.schema.json +0 -0
  99. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client/helpers/resources/schemas/dafab-water_analysis-item.schema.json +0 -0
  100. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client.egg-info/dependency_links.txt +0 -0
  101. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client.egg-info/requires.txt +0 -0
  102. {dafab_client-2.2.0 → dafab_client-2.2.3}/dafab_client.egg-info/top_level.txt +0 -0
  103. {dafab_client-2.2.0 → dafab_client-2.2.3}/readme.md +0 -0
  104. {dafab_client-2.2.0 → dafab_client-2.2.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dafab_client
3
- Version: 2.2.0
3
+ Version: 2.2.3
4
4
  Summary: DaFab helper client built on top of Rucio client modules.
5
5
  Author: DaFab
6
6
  License-Expression: Apache-2.0
@@ -104,7 +104,7 @@ class PolicyPackageAlgorithms:
104
104
  if vo == DEFAULT_VO:
105
105
  vo = ''
106
106
  package = cls._get_policy_package_name(vo)
107
- except (NoOptionError, NoSectionError):
107
+ except (ConfigNotFound, NoOptionError, NoSectionError):
108
108
  cls._default_algorithms[type_for_vo] = default_algorithm
109
109
  return default_algorithm
110
110
 
@@ -37,6 +37,18 @@ if TYPE_CHECKING:
37
37
  from dafab_client._rucio.rse.protocols.protocol import RSEProtocol
38
38
 
39
39
 
40
+ def _normalize_protocol_impl_path(impl: str) -> str:
41
+ """Resolve vendored protocol implementations under ``dafab_client._rucio``.
42
+
43
+ RSE configurations still commonly advertise protocol classes under the upstream
44
+ ``rucio.rse.protocols`` namespace. Inside this client repository we vendor those
45
+ modules under ``dafab_client._rucio.rse.protocols`` instead.
46
+ """
47
+ if impl.startswith("rucio.rse.protocols."):
48
+ return impl.replace("rucio.", "dafab_client._rucio.", 1)
49
+ return impl
50
+
51
+
40
52
  def get_scope_protocol(vo: str = DEFAULT_VO) -> 'Callable':
41
53
  """
42
54
  Returns the callable protocol to translate the pfn to a name/scope pair
@@ -238,6 +250,8 @@ def create_protocol(
238
250
  raise exception.RSEProtocolNotSupported('Protocol %s operation %s on domain %s not supported' % (protocol_attr, operation, domain))
239
251
 
240
252
  # Instantiate protocol
253
+ protocol_attr = copy.copy(protocol_attr)
254
+ protocol_attr['impl'] = _normalize_protocol_impl_path(protocol_attr['impl'])
241
255
  comp = protocol_attr['impl'].split('.')
242
256
  prefix = '.'.join(comp[-2:]) + ': '
243
257
  logger = formatted_logger(logger, prefix + "%s")
@@ -99,7 +99,7 @@
99
99
  "metadata": {},
100
100
  "source": [
101
101
  "original_item_ready = dc.ensure_item(ORIGINAL_ITEM_ID)\n",
102
- "print(dc.as_json({\"scope\": STAC_SCOPE, \"item\": ORIGINAL_ITEM_ID, \"ready\": original_item_ready}))\n"
102
+ "print(dc.as_json({\"scope\": STAC_SCOPE, \"item\": ORIGINAL_ITEM_ID, \"ready\": original_item_ready}))"
103
103
  ],
104
104
  "id": "d9f3dc23de1b778b",
105
105
  "outputs": [],
@@ -122,7 +122,7 @@
122
122
  " name=STAC_COLLECTION_ID,\n",
123
123
  " members=[{\"scope\": STAC_SCOPE, \"name\": ORIGINAL_ITEM_ID}],\n",
124
124
  ")\n",
125
- "print(dc.as_json({\"collection\": STAC_COLLECTION_ID, \"item\": ORIGINAL_ITEM_ID, \"attached\": original_item_attached}))\n"
125
+ "print(dc.as_json({\"collection\": STAC_COLLECTION_ID, \"item\": ORIGINAL_ITEM_ID, \"attached\": original_item_attached}))"
126
126
  ],
127
127
  "id": "025de93d608242fa",
128
128
  "outputs": [],
@@ -156,7 +156,7 @@
156
156
  " expected_collection_id=STAC_COLLECTION_ID,\n",
157
157
  " check_catalog_state=False,\n",
158
158
  ")\n",
159
- "print(dc.as_json(original_item_pre_publish_validation))\n"
159
+ "print(dc.as_json(original_item_pre_publish_validation))"
160
160
  ],
161
161
  "id": "8f988f1e6d08439a",
162
162
  "outputs": [],
@@ -180,7 +180,7 @@
180
180
  " metadata_path=ORIGINAL_ITEM_FILE,\n",
181
181
  " scope=STAC_SCOPE,\n",
182
182
  " op=\"upsert\",\n",
183
- ")\n"
183
+ ")"
184
184
  ],
185
185
  "id": "6e822f1f67784d8f",
186
186
  "outputs": [],
@@ -216,7 +216,7 @@
216
216
  " check_related_links=True,\n",
217
217
  " autofix=False,\n",
218
218
  ")\n",
219
- "print(dc.as_json(original_item_post_publish_validation))\n"
219
+ "print(dc.as_json(original_item_post_publish_validation))"
220
220
  ],
221
221
  "id": "6a3d46629ee90eaf",
222
222
  "outputs": [],
@@ -254,7 +254,7 @@
254
254
  " autofix=True,\n",
255
255
  " autofix_include_related_links=True,\n",
256
256
  ")\n",
257
- "print(dc.as_json(original_item_post_publish_autofix))\n"
257
+ "print(dc.as_json(original_item_post_publish_autofix))"
258
258
  ],
259
259
  "id": "8b170b8be6c16f37",
260
260
  "outputs": [],
@@ -293,7 +293,7 @@
293
293
  " full_scan=False,\n",
294
294
  " dry_run=False,\n",
295
295
  ")\n",
296
- "print(dc.as_json(dasi_extent_integrity_report))\n"
296
+ "print(dc.as_json(dasi_extent_integrity_report))"
297
297
  ],
298
298
  "id": "115a8a08718400ab",
299
299
  "outputs": [],
@@ -312,4 +312,4 @@
312
312
  },
313
313
  "nbformat": 4,
314
314
  "nbformat_minor": 5
315
- }
315
+ }
@@ -89,9 +89,7 @@
89
89
  {
90
90
  "cell_type": "code",
91
91
  "metadata": {},
92
- "source": [
93
- "dc.list_accounts()\n"
94
- ],
92
+ "source": "dc.list_accounts()",
95
93
  "id": "9a621cf10199837c",
96
94
  "outputs": [],
97
95
  "execution_count": null
@@ -115,7 +113,7 @@
115
113
  " email=\"d.xenakis@cern.ch\",\n",
116
114
  " account_type=\"SERVICE\",\n",
117
115
  ")\n",
118
- "print(dc.as_json(result))\n"
116
+ "print(dc.as_json(result))"
119
117
  ],
120
118
  "id": "9f13ef7c6bdaba11",
121
119
  "outputs": [],
@@ -140,7 +138,7 @@
140
138
  " email=\"d.xenakis@cern.ch\",\n",
141
139
  " authtype=\"userpass\",\n",
142
140
  " password=\"dafab\",\n",
143
- ")\n"
141
+ ")"
144
142
  ],
145
143
  "id": "effe4b3ff4628db9",
146
144
  "outputs": [],
@@ -163,7 +161,7 @@
163
161
  " account=\"dafab_admin\",\n",
164
162
  " scope=STAC_SCOPE,\n",
165
163
  ")\n",
166
- "print(dc.as_json(scope_result))\n"
164
+ "print(dc.as_json(scope_result))"
167
165
  ],
168
166
  "id": "80228e542f59a1ec",
169
167
  "outputs": [],
@@ -183,7 +181,7 @@
183
181
  "metadata": {},
184
182
  "source": [
185
183
  "catalog_ready = dc.ensure_catalog(ROOT_CATALOG_ID, scope=STAC_SCOPE)\n",
186
- "print(dc.as_json({\"scope\": STAC_SCOPE, \"catalog\": ROOT_CATALOG_ID, \"ready\": catalog_ready}))\n"
184
+ "print(dc.as_json({\"scope\": STAC_SCOPE, \"catalog\": ROOT_CATALOG_ID, \"ready\": catalog_ready}))"
187
185
  ],
188
186
  "id": "3f583ef42110fbdf",
189
187
  "outputs": [],
@@ -203,7 +201,7 @@
203
201
  "metadata": {},
204
202
  "source": [
205
203
  "collection_ready = dc.ensure_collection(STAC_COLLECTION_ID, scope=STAC_SCOPE)\n",
206
- "print(dc.as_json({\"scope\": STAC_SCOPE, \"collection\": STAC_COLLECTION_ID, \"ready\": collection_ready}))\n"
204
+ "print(dc.as_json({\"scope\": STAC_SCOPE, \"collection\": STAC_COLLECTION_ID, \"ready\": collection_ready}))"
207
205
  ],
208
206
  "id": "6703b9e57f133a07",
209
207
  "outputs": [],
@@ -223,7 +221,7 @@
223
221
  "metadata": {},
224
222
  "source": [
225
223
  "water_facet_ready = dc.ensure_catalog(FACET_PARENT_CATALOG_ID, scope=STAC_SCOPE)\n",
226
- "print(dc.as_json({\"scope\": STAC_SCOPE, \"catalog\": FACET_PARENT_CATALOG_ID, \"ready\": water_facet_ready}))\n"
224
+ "print(dc.as_json({\"scope\": STAC_SCOPE, \"catalog\": FACET_PARENT_CATALOG_ID, \"ready\": water_facet_ready}))"
227
225
  ],
228
226
  "id": "799da3f5efc2e22e",
229
227
  "outputs": [],
@@ -247,7 +245,7 @@
247
245
  " name=STAC_COLLECTION_ID,\n",
248
246
  " members=[{\"scope\": STAC_SCOPE, \"name\": FACET_PARENT_CATALOG_ID}],\n",
249
247
  ")\n",
250
- "print(dc.as_json({\"collection\": STAC_COLLECTION_ID, \"facet_parent_catalog\": FACET_PARENT_CATALOG_ID, \"attached\": attached_facet_parent}))\n"
248
+ "print(dc.as_json({\"collection\": STAC_COLLECTION_ID, \"facet_parent_catalog\": FACET_PARENT_CATALOG_ID, \"attached\": attached_facet_parent}))"
251
249
  ],
252
250
  "id": "597a53067be47faf",
253
251
  "outputs": [],
@@ -271,7 +269,7 @@
271
269
  " name=STAC_COLLECTION_ID,\n",
272
270
  " members=[{\"scope\": STAC_SCOPE, \"name\": FACET_PARENT_CATALOG_ID}],\n",
273
271
  ")\n",
274
- "print(dc.as_json({\"collection\": STAC_COLLECTION_ID, \"facet_parent_catalog\": FACET_PARENT_CATALOG_ID, \"detached\": detached_facet_parent}))\n"
272
+ "print(dc.as_json({\"collection\": STAC_COLLECTION_ID, \"facet_parent_catalog\": FACET_PARENT_CATALOG_ID, \"detached\": detached_facet_parent}))"
275
273
  ],
276
274
  "id": "4ae568166158268c",
277
275
  "outputs": [],
@@ -295,7 +293,7 @@
295
293
  " name=ROOT_CATALOG_ID,\n",
296
294
  " members=[{\"scope\": STAC_SCOPE, \"name\": STAC_COLLECTION_ID}],\n",
297
295
  ")\n",
298
- "print(dc.as_json({\"root_catalog\": ROOT_CATALOG_ID, \"collection\": STAC_COLLECTION_ID, \"attached\": attached_collection}))\n"
296
+ "print(dc.as_json({\"root_catalog\": ROOT_CATALOG_ID, \"collection\": STAC_COLLECTION_ID, \"attached\": attached_collection}))"
299
297
  ],
300
298
  "id": "a4daa175ec0df7c5",
301
299
  "outputs": [],
@@ -320,7 +318,7 @@
320
318
  " metadata_path=root_catalog_metadata_path,\n",
321
319
  " scope=STAC_SCOPE,\n",
322
320
  " op=\"upsert\",\n",
323
- ")\n"
321
+ ")"
324
322
  ],
325
323
  "id": "973cf44be5fb9e44",
326
324
  "outputs": [],
@@ -363,7 +361,7 @@
363
361
  " metadata_path=collection_metadata_path,\n",
364
362
  " scope=STAC_SCOPE,\n",
365
363
  " op=\"upsert\",\n",
366
- " )\n"
364
+ " )"
367
365
  ],
368
366
  "id": "35be8d32e735a750",
369
367
  "outputs": [],
@@ -406,7 +404,7 @@
406
404
  " metadata_path=facet_parent_catalog_metadata_path,\n",
407
405
  " scope=STAC_SCOPE,\n",
408
406
  " op=\"upsert\",\n",
409
- " )\n"
407
+ " )"
410
408
  ],
411
409
  "id": "c018bd7919e1fe4f",
412
410
  "outputs": [],
@@ -428,7 +426,7 @@
428
426
  " stac_namespace=STAC_SCOPE,\n",
429
427
  " limit=50,\n",
430
428
  ")\n",
431
- "print(dc.as_json(missing_asset_audit))\n"
429
+ "print(dc.as_json(missing_asset_audit))"
432
430
  ],
433
431
  "id": "96052be7d1f3f215",
434
432
  "outputs": [],
@@ -447,4 +445,4 @@
447
445
  },
448
446
  "nbformat": 4,
449
447
  "nbformat_minor": 5
450
- }
448
+ }
@@ -92,7 +92,7 @@
92
92
  "\n",
93
93
  "DERIVED_ASSET_KEY = \"dafab-field-boundaries\"\n",
94
94
  "\n",
95
- "DERIVED_ASSET_FILE = \"docs/notebooks/demo-data/uploads/assets/smart_agriculture/S2A_30TYN_20200311_1_L2A/field-boundaries-S2A_30TYN_20200311_1_L2A-10-v1.2.0.geojson\"\n"
95
+ "DERIVED_ASSET_FILE = \"docs/notebooks/demo-data/uploads/assets/smart_agriculture/S2A_30TYN_20200311_1_L2A/field-boundaries-S2A_30TYN_20200311_1_L2A-10-v1.2.0.geojson\""
96
96
  ],
97
97
  "id": "26839e4a804af97b",
98
98
  "outputs": [],
@@ -112,7 +112,7 @@
112
112
  "metadata": {},
113
113
  "source": [
114
114
  "facet_value_ready = dc.ensure_catalog(FACET_VALUE_CATALOG_ID, scope=STAC_SCOPE)\n",
115
- "print(dc.as_json({\"scope\": STAC_SCOPE, \"catalog\": FACET_VALUE_CATALOG_ID, \"ready\": facet_value_ready}))\n"
115
+ "print(dc.as_json({\"scope\": STAC_SCOPE, \"catalog\": FACET_VALUE_CATALOG_ID, \"ready\": facet_value_ready}))"
116
116
  ],
117
117
  "id": "cc274dac9e3476ae",
118
118
  "outputs": [],
@@ -136,7 +136,7 @@
136
136
  " name=FACET_PARENT_CATALOG_ID,\n",
137
137
  " members=[{\"scope\": STAC_SCOPE, \"name\": FACET_VALUE_CATALOG_ID}],\n",
138
138
  ")\n",
139
- "print(dc.as_json({\"facet_parent_catalog\": FACET_PARENT_CATALOG_ID, \"facet_value_catalog\": FACET_VALUE_CATALOG_ID, \"attached\": attached_to_parent}))\n"
139
+ "print(dc.as_json({\"facet_parent_catalog\": FACET_PARENT_CATALOG_ID, \"facet_value_catalog\": FACET_VALUE_CATALOG_ID, \"attached\": attached_to_parent}))"
140
140
  ],
141
141
  "id": "ea0727f08cab3f2b",
142
142
  "outputs": [],
@@ -167,7 +167,7 @@
167
167
  " schema_path=FACET_VALUE_CATALOG_SCHEMA,\n",
168
168
  " scope=STAC_SCOPE,\n",
169
169
  ")\n",
170
- "print(dc.as_json(facet_catalog_validation))\n"
170
+ "print(dc.as_json(facet_catalog_validation))"
171
171
  ],
172
172
  "id": "ed711690e254b61f",
173
173
  "outputs": [],
@@ -230,7 +230,7 @@
230
230
  " metadata_path=facet_value_catalog_metadata_path,\n",
231
231
  " scope=STAC_SCOPE,\n",
232
232
  " op=\"upsert\",\n",
233
- " )\n"
233
+ " )"
234
234
  ],
235
235
  "id": "261b4fccfb4a524b",
236
236
  "outputs": [],
@@ -251,7 +251,7 @@
251
251
  "id": "73319312",
252
252
  "source": [
253
253
  "derived_item_ready = dc.ensure_item(DERIVED_ITEM_ID, scope=STAC_SCOPE)\n",
254
- "print(dc.as_json({\"scope\": STAC_SCOPE, \"item\": DERIVED_ITEM_ID, \"ready\": derived_item_ready}))\n"
254
+ "print(dc.as_json({\"scope\": STAC_SCOPE, \"item\": DERIVED_ITEM_ID, \"ready\": derived_item_ready}))"
255
255
  ],
256
256
  "outputs": [],
257
257
  "execution_count": null
@@ -274,7 +274,7 @@
274
274
  " name=FACET_VALUE_CATALOG_ID,\n",
275
275
  " members=[{\"scope\": STAC_SCOPE, \"name\": DERIVED_ITEM_ID}],\n",
276
276
  ")\n",
277
- "print(dc.as_json({\"facet_value_catalog\": FACET_VALUE_CATALOG_ID, \"item\": DERIVED_ITEM_ID, \"attached\": attached_item}))\n"
277
+ "print(dc.as_json({\"facet_value_catalog\": FACET_VALUE_CATALOG_ID, \"item\": DERIVED_ITEM_ID, \"attached\": attached_item}))"
278
278
  ],
279
279
  "id": "4c448873861601fb",
280
280
  "outputs": [],
@@ -307,7 +307,7 @@
307
307
  " expected_collection_id=DERIVED_ITEM_COLLECTION_ID,\n",
308
308
  " check_catalog_state=False,\n",
309
309
  ")\n",
310
- "print(dc.as_json(derived_item_pre_publish_validation))\n"
310
+ "print(dc.as_json(derived_item_pre_publish_validation))"
311
311
  ],
312
312
  "outputs": [],
313
313
  "execution_count": null
@@ -330,7 +330,7 @@
330
330
  " metadata_path=DERIVED_ITEM_FILE,\n",
331
331
  " scope=STAC_SCOPE,\n",
332
332
  " op=\"upsert\",\n",
333
- ")\n"
333
+ ")"
334
334
  ],
335
335
  "id": "b2fd4845e909172d",
336
336
  "outputs": [],
@@ -358,7 +358,7 @@
358
358
  " overwrite=True,\n",
359
359
  " scope=STAC_SCOPE,\n",
360
360
  ")\n",
361
- "print(dc.as_json(published_derived_asset))\n"
361
+ "print(dc.as_json(published_derived_asset))"
362
362
  ],
363
363
  "id": "84e19cd6f860efc0",
364
364
  "outputs": [],
@@ -397,7 +397,7 @@
397
397
  " check_catalog_state=True,\n",
398
398
  " autofix=False,\n",
399
399
  ")\n",
400
- "print(dc.as_json(derived_item_post_publish_validation))\n"
400
+ "print(dc.as_json(derived_item_post_publish_validation))"
401
401
  ],
402
402
  "outputs": [],
403
403
  "execution_count": null
@@ -433,7 +433,7 @@
433
433
  " check_catalog_state=True,\n",
434
434
  " autofix=True,\n",
435
435
  ")\n",
436
- "print(dc.as_json(derived_item_post_publish_autofix))\n"
436
+ "print(dc.as_json(derived_item_post_publish_autofix))"
437
437
  ],
438
438
  "outputs": [],
439
439
  "execution_count": null
@@ -476,7 +476,7 @@
476
476
  " full_scan=True,\n",
477
477
  " dry_run=False,\n",
478
478
  ")\n",
479
- "print(dc.as_json(skim_extent_integrity_report))\n"
479
+ "print(dc.as_json(skim_extent_integrity_report))"
480
480
  ],
481
481
  "outputs": [],
482
482
  "execution_count": null
@@ -494,4 +494,4 @@
494
494
  },
495
495
  "nbformat": 4,
496
496
  "nbformat_minor": 5
497
- }
497
+ }
@@ -13,7 +13,7 @@ from .db_bootstrap.account_manager import add_rucio_account, add_rucio_identity
13
13
  from .dataset_management.ensure_dataset import ensure_item
14
14
  from .dataset_management.list_datasets import get_items
15
15
  from .dataset_management.scope_management import ensure_scope_for_account, list_stac_scopes
16
- from .did_management.operations import attach_stac_members, detach_stac_members
16
+ from .did_management.operations import attach_stac_members, detach_stac_members, get_stac_objects
17
17
  from .filtering.filter_by_bbox import get_items_by_bbox
18
18
  from .filtering.filter_by_bbox_and_timerange import get_items_by_bbox_and_timerange
19
19
  from .filtering.filter_by_enhanced_filter import get_items_by_enhanced_filter
@@ -36,6 +36,8 @@ from .file_management.Workflows.manage_derived_assets import (
36
36
  list_item_asset_entries,
37
37
  publish_derived_asset,
38
38
  )
39
+ from .file_management.Deletion.delete_file_of_scope_name import delete_file
40
+ from .file_management.Deletion.delete_replica_of_scope_name import delete_replica
39
41
  from .metadata_management.Insertion.set_metadata import set_metadata
40
42
  from .metadata_management.Preflight.validate_derived_item_file import validate_derived_item
41
43
  from .metadata_management.Preflight.validate_facet_value_catalog_file import validate_facet_value_catalog_file
@@ -56,6 +58,8 @@ __all__ = [
56
58
  "build_stable_asset_href",
57
59
  "check_storage",
58
60
  "detach_stac_members",
61
+ "delete_file",
62
+ "delete_replica",
59
63
  "download_all_derived_item_assets",
60
64
  "download_asset_from_stable_href",
61
65
  "download_item_asset",
@@ -78,6 +82,7 @@ __all__ = [
78
82
  "get_related_item_ids_from_original_item",
79
83
  "get_sibling_derived_item_ids",
80
84
  "get_source_original_item_ids_from_derived_item",
85
+ "get_stac_objects",
81
86
  "list_accounts",
82
87
  "list_catalogs_and_collections",
83
88
  "list_derived_items_with_missing_assets",
@@ -0,0 +1,123 @@
1
+ import argparse
2
+ import time
3
+ import traceback
4
+
5
+ import requests
6
+
7
+ from dafab_client._rucio.dafab_lib import connection_manager, upload_manager
8
+ from dafab_client._rucio.common.exception import AccessDenied, RucioException, SourceNotFound
9
+ from dafab_client._rucio.global_utils import setup_logger
10
+
11
+ LOG = setup_logger(__name__)
12
+
13
+ SIGNED_DELETE_TIMEOUT = 120
14
+
15
+
16
+ def _delete_file_via_signed_url(
17
+ fname: str,
18
+ scope: str,
19
+ rse: str,
20
+ timeout: int = SIGNED_DELETE_TIMEOUT,
21
+ ) -> bool:
22
+ """Delete a file through a signed HTTPS URL when the RSE supports sign_url."""
23
+ client = connection_manager()
24
+ did_str = f"{scope}:{fname}"
25
+ pfn_map = client.lfns2pfns(
26
+ rse=rse,
27
+ lfns=[did_str],
28
+ protocol_domain="wan",
29
+ operation="delete",
30
+ scheme="https",
31
+ )
32
+ delete_pfn = pfn_map.get(did_str)
33
+ if not isinstance(delete_pfn, str) or not delete_pfn.strip():
34
+ raise RucioException(f"Unable to resolve a delete PFN for {did_str} on {rse}.")
35
+
36
+ rse_info = client.get_rse(rse)
37
+ sign_service = rse_info.get("sign_url")
38
+ if not sign_service:
39
+ raise RucioException(f"RSE {rse} does not advertise sign_url support.")
40
+
41
+ signed_url = client.get_signed_url(rse, str(sign_service), "delete", delete_pfn)
42
+ response = requests.delete(signed_url, timeout=timeout)
43
+ if response.status_code in {200, 202, 204}:
44
+ return True
45
+ if response.status_code == 404:
46
+ raise SourceNotFound()
47
+ if response.status_code in {401, 403}:
48
+ raise AccessDenied(response.text or "Signed delete was rejected by the storage service.")
49
+ raise RucioException(
50
+ f"Signed delete failed with HTTP {response.status_code}: {response.text[:200]}"
51
+ )
52
+
53
+
54
+ def delete_file(fname: str, scope: str = 'dafab', rse: str = 'MELUXINA_S3'):
55
+ """
56
+ Remove a file from an RSE in Rucio.
57
+
58
+ For signed-URL storages such as ``MELUXINA_S3``, the helper resolves the PFN
59
+ through the server and performs a direct HTTPS DELETE using a signed URL.
60
+ Other RSEs fall back to the legacy upload-client delete path.
61
+
62
+ Parameters
63
+ ----------
64
+ fname : str
65
+ Name of the file to delete.
66
+ scope : str, optional
67
+ Rucio scope of the file, by default ``'dafab'``.
68
+ rse : str, optional
69
+ Target RSE from which the file is deleted, by default ``'MELUXINA_S3'``.
70
+
71
+ Returns
72
+ -------
73
+ bool
74
+ ``True`` if the file was removed successfully, ``False`` after all retry attempts failed.
75
+ """
76
+ max_retries = 5
77
+ retry_delay = 30 # seconds
78
+
79
+ for attempt in range(max_retries):
80
+ try:
81
+ client = connection_manager()
82
+ rse_info = client.get_rse(rse)
83
+ if rse_info.get("sign_url"):
84
+ _delete_file_via_signed_url(fname, scope, rse)
85
+ else:
86
+ uploader = upload_manager()
87
+ uploader.delete_file(fname, scope, rse)
88
+ LOG.result(f"The deletion process of file '{fname}' from {rse} RSE finished.\n")
89
+ return True
90
+ except SourceNotFound:
91
+ LOG.result(f"The file '{scope}:{fname}' is already absent from {rse}.\n")
92
+ return True
93
+ except AccessDenied as e:
94
+ LOG.warning(
95
+ f"Access denied while deleting the file '{scope}:{fname}' from {rse}: {e}\n"
96
+ )
97
+ return False
98
+ except Exception as e:
99
+ LOG.warning(f"Attempt {attempt + 1}/{max_retries}: An unexpected error of type '{type(e).__name__}' occurred "
100
+ f"while deleting the '{fname}' file from {rse} RSE: {e}\n")
101
+
102
+ # Get the full traceback for debugging:
103
+ traceback.print_exc()
104
+
105
+ if attempt < max_retries - 1: # Don't sleep after the last attempt
106
+ LOG.warning(f"Retrying in {retry_delay} seconds...")
107
+ time.sleep(retry_delay)
108
+
109
+ LOG.warning("All retry attempts exhausted.")
110
+ return False
111
+
112
+
113
+ if __name__ == '__main__':
114
+ parser = argparse.ArgumentParser(description='Delete file of a Copernicus metadata filename.')
115
+ parser.add_argument('filename', type=str,
116
+ help='Copernicus metadata filename (e.g., field-boundaries-S2A_10SGG_20230426_0_L2A-v1.1.0.geojson).')
117
+
118
+ args = parser.parse_args()
119
+
120
+ filename = args.filename
121
+
122
+ deletion_success = delete_file(filename)
123
+ exit(0 if deletion_success else 1)
@@ -3,12 +3,18 @@ import argparse
3
3
  import traceback
4
4
 
5
5
  from dafab_client._rucio.dafab_lib import connection_manager
6
+ from dafab_client._rucio.common.exception import AccessDenied, ReplicaNotFound
6
7
  from dafab_client._rucio.global_utils import setup_logger
7
8
 
8
9
  LOG = setup_logger(__name__)
9
10
 
10
11
 
11
- def delete_replica(fname, rse: str = 'MELUXINA_S3'):
12
+ def delete_replica(
13
+ fname: str,
14
+ rse: str = 'MELUXINA_S3',
15
+ scope: str = 'dafab',
16
+ ignore_availability: bool = True,
17
+ ):
12
18
  """
13
19
  Remove a file replica from Rucio.
14
20
 
@@ -22,6 +28,10 @@ def delete_replica(fname, rse: str = 'MELUXINA_S3'):
22
28
  Name of the file whose replica should be removed.
23
29
  rse : str, optional
24
30
  Target RSE from which to delete the replica, by default ``'MELUXINA_S3'``.
31
+ scope : str, optional
32
+ Rucio scope of the file, by default ``'dafab'``.
33
+ ignore_availability : bool, optional
34
+ Ignore RSE availability while deleting the replica, by default ``True``.
25
35
 
26
36
  Returns
27
37
  -------
@@ -37,18 +47,30 @@ def delete_replica(fname, rse: str = 'MELUXINA_S3'):
37
47
  # Get a client connection
38
48
  cl = connection_manager()
39
49
 
40
- success = cl.delete_replica(fname, rse)
50
+ success = cl.delete_replicas(
51
+ rse=rse,
52
+ files=[{'scope': scope, 'name': fname}],
53
+ ignore_availability=ignore_availability,
54
+ )
41
55
  if success:
42
- LOG.result(f"The '{fname}' replica is deregistered from the catalog.\n")
56
+ LOG.result(f"The '{scope}:{fname}' replica is deregistered from {rse}.\n")
43
57
  return True
44
58
  else:
45
- LOG.warning(f"Deletion of the '{fname}' replica from the database was not successful.\n")
59
+ LOG.warning(f"Deletion of the '{scope}:{fname}' replica from {rse} was not successful.\n")
46
60
  return False
47
61
 
62
+ except ReplicaNotFound:
63
+ LOG.result(f"The '{scope}:{fname}' replica is already absent from {rse}.\n")
64
+ return True
65
+ except AccessDenied as e:
66
+ LOG.warning(
67
+ f"Access denied while deleting the '{scope}:{fname}' replica from {rse}: {e}\n"
68
+ )
69
+ return False
48
70
  except Exception as e:
49
71
  LOG.warning(f"Attempt {attempt + 1}/{max_retries}: An unexpected error "
50
72
  f"of type '{type(e).__name__}' occurred "
51
- f"while deleting the '{fname}' replica from Rucio database: {e}\n")
73
+ f"while deleting the '{scope}:{fname}' replica from {rse}: {e}\n")
52
74
 
53
75
  # Get the full traceback for debugging:
54
76
  traceback.print_exc()
@@ -65,10 +87,12 @@ if __name__ == '__main__':
65
87
  parser = argparse.ArgumentParser(description='Remove replica of a Copernicus metadata filename.')
66
88
  parser.add_argument('filename', type=str,
67
89
  help='Copernicus metadata filename (e.g., field-boundaries-S2B_43QDB_20240408_0_L2A.geojson).')
90
+ parser.add_argument('--scope', default='dafab', help='Rucio scope of the file. Defaults to dafab.')
91
+ parser.add_argument('--rse', default='MELUXINA_S3', help='RSE from which to remove the replica.')
68
92
 
69
93
  args = parser.parse_args()
70
94
 
71
95
  filename = args.filename
72
96
 
73
- deletion_success = delete_replica(filename)
97
+ deletion_success = delete_replica(filename, scope=args.scope, rse=args.rse)
74
98
  exit(0 if deletion_success else 1)