fair-cli 0.9.5__tar.gz → 0.9.6__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.
- {fair_cli-0.9.5 → fair_cli-0.9.6}/CITATION.cff +2 -2
- {fair_cli-0.9.5 → fair_cli-0.9.6}/PKG-INFO +1 -1
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/registry/sync.py +47 -50
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/session.py +3 -5
- {fair_cli-0.9.5 → fair_cli-0.9.6}/pyproject.toml +1 -1
- {fair_cli-0.9.5 → fair_cli-0.9.6}/CHANGELOG.md +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/LICENSE +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/README.md +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/__init__.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/cli.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/common.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/configuration/__init__.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/configuration/validation.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/exceptions.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/files.txt +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/history.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/identifiers.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/logging.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/register.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/registry/__init__.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/registry/file_formats.json +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/registry/file_types.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/registry/requests.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/registry/server.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/registry/storage.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/registry/versioning.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/run.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/staging.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/templates/__init__.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/templates/config.jinja +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/templates/hist.jinja +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/testing.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/user_config/__init__.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/user_config/globbing.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/user_config/validation.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/utilities.py +0 -0
- {fair_cli-0.9.5 → fair_cli-0.9.6}/fair/virtualenv.py +0 -0
|
@@ -26,7 +26,7 @@ authors:
|
|
|
26
26
|
affiliation: University of Glasgow
|
|
27
27
|
orcid: https://orcid.org/0000-0002-4424-9890
|
|
28
28
|
|
|
29
|
-
date-released:
|
|
29
|
+
date-released: 2024-08-04
|
|
30
30
|
keywords:
|
|
31
31
|
- FAIR Data Pipeline
|
|
32
32
|
- FAIR
|
|
@@ -36,4 +36,4 @@ license: BSD-2-Clause
|
|
|
36
36
|
message: If you use this software, please cite it using these metadata.
|
|
37
37
|
repository-code: https://github.com/FAIRDataPipeline/FAIR-CLI/
|
|
38
38
|
title: "The FAIR Data Pipeline command line tool"
|
|
39
|
-
version: 0.9.
|
|
39
|
+
version: 0.9.6
|
|
@@ -146,8 +146,7 @@ def sync_dependency_chain(
|
|
|
146
146
|
dest_token: str,
|
|
147
147
|
origin_token: str,
|
|
148
148
|
local_data_store: str = None,
|
|
149
|
-
public: bool = False
|
|
150
|
-
remote_author_url = None
|
|
149
|
+
public: bool = False
|
|
151
150
|
) -> typing.Dict[str, str]:
|
|
152
151
|
"""Push an object and all of its dependencies to the remote registry
|
|
153
152
|
|
|
@@ -187,7 +186,7 @@ def sync_dependency_chain(
|
|
|
187
186
|
)
|
|
188
187
|
|
|
189
188
|
_new_urls: typing.Dict[str, str] = {k: "" for k in _dependency_chain}
|
|
190
|
-
_writable_fields: typing.Dict[str, str] = {}
|
|
189
|
+
_writable_fields: typing.Dict[str, str] = {}
|
|
191
190
|
|
|
192
191
|
# For every object (and the order) in the dependency chain
|
|
193
192
|
# post the object then store the URL so it can be used to assemble those
|
|
@@ -224,9 +223,9 @@ def sync_dependency_chain(
|
|
|
224
223
|
object_url=object_url,
|
|
225
224
|
new_urls=_new_urls,
|
|
226
225
|
writable_data=_writable_data,
|
|
226
|
+
object_data = _obj_data,
|
|
227
227
|
local_data_store = local_data_store,
|
|
228
|
-
public = public
|
|
229
|
-
remote_author_url = remote_author_url
|
|
228
|
+
public = public
|
|
230
229
|
)
|
|
231
230
|
|
|
232
231
|
if not fdp_util.is_api_url(dest_uri, _new_url):
|
|
@@ -248,9 +247,9 @@ def _get_new_url(
|
|
|
248
247
|
object_url: str,
|
|
249
248
|
new_urls: typing.Dict,
|
|
250
249
|
writable_data: typing.Dict,
|
|
250
|
+
object_data = {},
|
|
251
251
|
local_data_store = None,
|
|
252
|
-
public = False
|
|
253
|
-
remote_author_url = None
|
|
252
|
+
public = False
|
|
254
253
|
) -> typing.Tuple[typing.Dict, typing.List]:
|
|
255
254
|
"""Internal Function to return a resgistry entry from the remote registry given an origin entry URL
|
|
256
255
|
If the entry does not exist it will be created
|
|
@@ -303,6 +302,7 @@ def _get_new_url(
|
|
|
303
302
|
# (as remote URL will never match local)
|
|
304
303
|
|
|
305
304
|
_obj_type = fdp_req.get_obj_type_from_url(object_url, token=origin_token)
|
|
305
|
+
_obj_id = fdp_req.get_obj_id_from_url(object_url)
|
|
306
306
|
|
|
307
307
|
_filters = {
|
|
308
308
|
k: v
|
|
@@ -317,19 +317,25 @@ def _get_new_url(
|
|
|
317
317
|
if dest_uri == origin_uri:
|
|
318
318
|
raise fdp_exc.InternalError("Cannot push object to its source address")
|
|
319
319
|
|
|
320
|
-
|
|
320
|
+
# If Public is true then any files will be uploaded to the remote registry
|
|
321
|
+
# If local_data_store is set we're pulling to a local registry
|
|
321
322
|
if public and not local_data_store:
|
|
323
|
+
# The remote data_store storage_root URL should always be the 1st storage_root
|
|
322
324
|
_remote_storage_root_url = urllib.parse.urljoin(dest_uri, "storage_root/1/")
|
|
323
|
-
|
|
325
|
+
# If the current objects a storage_root and the root is the first (data_store)
|
|
326
|
+
# then simply return the remote
|
|
327
|
+
if _obj_type == "storage_root" and _obj_id == '1':
|
|
324
328
|
return _remote_storage_root_url
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
329
|
+
# If the current object is a storage_location
|
|
330
|
+
elif _obj_type == "storage_location":
|
|
331
|
+
# Again if the storage_root is the data_store (storage_root 1)
|
|
332
|
+
if fdp_req.get_obj_id_from_url(object_data.get("storage_root", "/2")) == '1':
|
|
333
|
+
# Update the new object path and filter path
|
|
334
|
+
_new_obj_data["path"] = _filters["path"] = _new_obj_data["hash"]
|
|
335
|
+
# Update the new object storage_root
|
|
336
|
+
_new_obj_data["storage_root"] = _remote_storage_root_url
|
|
337
|
+
# Update the filters for storage_root to the ID
|
|
338
|
+
_filters["storage_root"] = fdp_req.get_obj_id_from_url(_remote_storage_root_url)
|
|
333
339
|
|
|
334
340
|
if _obj_type == "object":
|
|
335
341
|
_new_obj_data["authors"] = []
|
|
@@ -433,13 +439,13 @@ def get_new_author_url(
|
|
|
433
439
|
if k in _writable_fields
|
|
434
440
|
}
|
|
435
441
|
return _get_new_url(
|
|
436
|
-
origin_uri,
|
|
437
|
-
origin_token,
|
|
438
|
-
dest_uri,
|
|
439
|
-
dest_token,
|
|
440
|
-
author_url,
|
|
441
|
-
{},
|
|
442
|
-
_writable_data
|
|
442
|
+
origin_uri= origin_uri,
|
|
443
|
+
origin_token= origin_token,
|
|
444
|
+
dest_uri= dest_uri,
|
|
445
|
+
dest_token= dest_token,
|
|
446
|
+
object_url= author_url,
|
|
447
|
+
new_urls= {},
|
|
448
|
+
writable_data= _writable_data
|
|
443
449
|
)
|
|
444
450
|
|
|
445
451
|
def sync_data_products(
|
|
@@ -450,8 +456,7 @@ def sync_data_products(
|
|
|
450
456
|
remote_label: str,
|
|
451
457
|
data_products: typing.List[str],
|
|
452
458
|
local_data_store: str = None,
|
|
453
|
-
force: bool = False
|
|
454
|
-
remote_author_url = None
|
|
459
|
+
force: bool = False
|
|
455
460
|
) -> None:
|
|
456
461
|
"""Transfer data products from one registry to another
|
|
457
462
|
|
|
@@ -545,8 +550,7 @@ def sync_data_products(
|
|
|
545
550
|
dest_token=dest_token,
|
|
546
551
|
origin_token=origin_token,
|
|
547
552
|
local_data_store=local_data_store,
|
|
548
|
-
public=_is_public
|
|
549
|
-
remote_author_url = remote_author_url
|
|
553
|
+
public=_is_public
|
|
550
554
|
)
|
|
551
555
|
# If local_data_store assume we're syncing from remote to local
|
|
552
556
|
if local_data_store:
|
|
@@ -568,8 +572,8 @@ def sync_data_products(
|
|
|
568
572
|
for origin_input_code_run in origin_input_code_runs:
|
|
569
573
|
dest_component_url = get_dest_component_url(origin_component_url, dest_uri, dest_token, origin_token)
|
|
570
574
|
dest_inputs = [dest_component_url]
|
|
571
|
-
dest_inputs += get_dest_inputs(origin_input_code_run["inputs"], origin_uri, dest_uri, dest_token, origin_token, remote_label
|
|
572
|
-
sync_code_run(origin_uri, dest_uri, dest_token, origin_token, origin_input_code_run["uuid"], inputs= dest_inputs
|
|
575
|
+
dest_inputs += get_dest_inputs(origin_input_code_run["inputs"], origin_uri, dest_uri, dest_token, origin_token, remote_label)
|
|
576
|
+
sync_code_run(origin_uri, dest_uri, dest_token, origin_token, origin_input_code_run["uuid"], inputs= dest_inputs)
|
|
573
577
|
|
|
574
578
|
origin_output_code_runs = fdp_req.get(
|
|
575
579
|
origin_uri,
|
|
@@ -579,9 +583,10 @@ def sync_data_products(
|
|
|
579
583
|
)
|
|
580
584
|
for origin_output_code_run in origin_output_code_runs:
|
|
581
585
|
dest_component_url = get_dest_component_url(origin_component_url, dest_uri, dest_token, origin_token)
|
|
582
|
-
dest_inputs = get_dest_inputs(origin_output_code_run["inputs"], origin_uri, dest_uri, dest_token, origin_token, remote_label, force
|
|
583
|
-
sync_code_run(origin_uri, dest_uri, dest_token, origin_token, origin_output_code_run["uuid"], inputs= dest_inputs, outputs= [dest_component_url]
|
|
586
|
+
dest_inputs = get_dest_inputs(origin_output_code_run["inputs"], origin_uri, dest_uri, dest_token, origin_token, remote_label, force)
|
|
587
|
+
sync_code_run(origin_uri, dest_uri, dest_token, origin_token, origin_output_code_run["uuid"], inputs= dest_inputs, outputs= [dest_component_url])
|
|
584
588
|
logger.info(f"Synced Data Product: {data_product}")
|
|
589
|
+
|
|
585
590
|
def get_dest_component_url(
|
|
586
591
|
origin_component_url: str,
|
|
587
592
|
dest_uri: str,
|
|
@@ -626,8 +631,7 @@ def sync_code_runs(
|
|
|
626
631
|
remote_label: str,
|
|
627
632
|
code_runs: typing.List[str],
|
|
628
633
|
local_data_store: str = None,
|
|
629
|
-
force: bool = False
|
|
630
|
-
remote_author_url = None
|
|
634
|
+
force: bool = False
|
|
631
635
|
) -> None:
|
|
632
636
|
"""Transfer data code_run(s) from one registry to another
|
|
633
637
|
|
|
@@ -696,8 +700,7 @@ def sync_code_runs(
|
|
|
696
700
|
remote_label,
|
|
697
701
|
_origin_data_products_formatted,
|
|
698
702
|
local_data_store,
|
|
699
|
-
force
|
|
700
|
-
remote_author_url)
|
|
703
|
+
force)
|
|
701
704
|
|
|
702
705
|
# Iterate through formatted objects and get their new values from the remote registry
|
|
703
706
|
for _origin_data_product_formatted in _origin_data_products_formatted:
|
|
@@ -725,7 +728,7 @@ def sync_code_runs(
|
|
|
725
728
|
if _origin_data_product_formatted in _outputs_data_products:
|
|
726
729
|
_dest_outputs += _dest_object["components"]
|
|
727
730
|
logger.debug(f'attempting to sync coderun {code_run_uuid} with inputs {_dest_inputs} and outputs {_dest_outputs}')
|
|
728
|
-
sync_code_run(origin_uri, dest_uri, dest_token, origin_token, code_run_uuid, _dest_inputs, _dest_outputs
|
|
731
|
+
sync_code_run(origin_uri, dest_uri, dest_token, origin_token, code_run_uuid, _dest_inputs, _dest_outputs)
|
|
729
732
|
logger.info(f"Synced Code Run: {code_run_uuid}")
|
|
730
733
|
|
|
731
734
|
# Internal function to return the (remote) object associated with a code_run field containing and object url
|
|
@@ -772,8 +775,7 @@ def sync_code_run(
|
|
|
772
775
|
origin_token: str,
|
|
773
776
|
code_run_uuid: str,
|
|
774
777
|
inputs = [],
|
|
775
|
-
outputs = []
|
|
776
|
-
remote_author_url = None) -> typing.Dict:
|
|
778
|
+
outputs = []) -> typing.Dict:
|
|
777
779
|
"""_summary_
|
|
778
780
|
|
|
779
781
|
Args:
|
|
@@ -820,8 +822,7 @@ def sync_code_run(
|
|
|
820
822
|
origin_uri=origin_uri,
|
|
821
823
|
dest_token=dest_token,
|
|
822
824
|
origin_token=origin_token,
|
|
823
|
-
public= True
|
|
824
|
-
remote_author_url = remote_author_url
|
|
825
|
+
public= True
|
|
825
826
|
)
|
|
826
827
|
_dest_code_run_model_config = get_dest_object_url(code_run["model_config"], dest_uri, dest_token, origin_token)
|
|
827
828
|
upload_object(origin_uri, dest_uri, dest_token, origin_token, code_run["model_config"])
|
|
@@ -834,8 +835,7 @@ def sync_code_run(
|
|
|
834
835
|
origin_uri=origin_uri,
|
|
835
836
|
dest_token=dest_token,
|
|
836
837
|
origin_token=origin_token,
|
|
837
|
-
public= True
|
|
838
|
-
remote_author_url = remote_author_url
|
|
838
|
+
public= True
|
|
839
839
|
)
|
|
840
840
|
_dest_code_run_code_repo = get_dest_object_url(code_run["code_repo"], dest_uri, dest_token, origin_token)
|
|
841
841
|
# Sync Submision Script
|
|
@@ -845,8 +845,7 @@ def sync_code_run(
|
|
|
845
845
|
origin_uri=origin_uri,
|
|
846
846
|
dest_token=dest_token,
|
|
847
847
|
origin_token=origin_token,
|
|
848
|
-
public= True
|
|
849
|
-
remote_author_url = remote_author_url
|
|
848
|
+
public= True
|
|
850
849
|
)
|
|
851
850
|
_dest_code_run_submission_script = get_dest_object_url(code_run["submission_script"], dest_uri, dest_token, origin_token)
|
|
852
851
|
upload_object(origin_uri, dest_uri, dest_token, origin_token, code_run["submission_script"])
|
|
@@ -941,8 +940,7 @@ def get_dest_inputs(origin_inputs: typing.List,
|
|
|
941
940
|
dest_token: str,
|
|
942
941
|
origin_token: str,
|
|
943
942
|
remote_label: str,
|
|
944
|
-
force: bool = False
|
|
945
|
-
remote_author_url = None) -> list:
|
|
943
|
+
force: bool = False) -> list:
|
|
946
944
|
"""Returns a list of input component urls on the destination registry
|
|
947
945
|
from a given list of input component urls from the origin registry
|
|
948
946
|
assumes the destination componets already exists in the remote registry
|
|
@@ -963,7 +961,7 @@ def get_dest_inputs(origin_inputs: typing.List,
|
|
|
963
961
|
for origin_input in origin_inputs:
|
|
964
962
|
component_data_products = get_data_products_from_component(origin_input, origin_token)
|
|
965
963
|
if component_data_products:
|
|
966
|
-
sync_data_products(origin_uri, dest_uri, dest_token, origin_token, remote_label, format_data_product_list(component_data_products, origin_token), force= force
|
|
964
|
+
sync_data_products(origin_uri, dest_uri, dest_token, origin_token, remote_label, format_data_product_list(component_data_products, origin_token), force= force)
|
|
967
965
|
for data_product_url in component_data_products:
|
|
968
966
|
origin_data_product_object_url = fdp_req.url_get(data_product_url, origin_token)["object"]
|
|
969
967
|
dest_object_url = get_dest_object_url(origin_data_product_object_url, dest_uri, dest_token, origin_token)
|
|
@@ -976,8 +974,7 @@ def get_dest_inputs(origin_inputs: typing.List,
|
|
|
976
974
|
origin_uri=origin_uri,
|
|
977
975
|
dest_token=dest_token,
|
|
978
976
|
origin_token=origin_token,
|
|
979
|
-
public= is_component_public(origin_input, origin_token)
|
|
980
|
-
remote_author_url = remote_author_url
|
|
977
|
+
public= is_component_public(origin_input, origin_token)
|
|
981
978
|
)
|
|
982
979
|
dest_inputs.append(get_dest_component_url(origin_input, dest_uri, dest_token, origin_token))
|
|
983
980
|
return dest_inputs
|
|
@@ -411,8 +411,7 @@ class FAIR:
|
|
|
411
411
|
),
|
|
412
412
|
origin_token=fdp_req.local_token(),
|
|
413
413
|
remote_label=remote,
|
|
414
|
-
code_runs=_staged_code_runs
|
|
415
|
-
remote_author_url = remote_author_url
|
|
414
|
+
code_runs=_staged_code_runs
|
|
416
415
|
)
|
|
417
416
|
|
|
418
417
|
fdp_sync.sync_data_products(
|
|
@@ -423,8 +422,7 @@ class FAIR:
|
|
|
423
422
|
),
|
|
424
423
|
origin_token=fdp_req.local_token(),
|
|
425
424
|
remote_label=remote,
|
|
426
|
-
data_products=_staged_data_products
|
|
427
|
-
remote_author_url = remote_author_url
|
|
425
|
+
data_products=_staged_data_products
|
|
428
426
|
)
|
|
429
427
|
|
|
430
428
|
self._session_config.write_log_lines(
|
|
@@ -495,7 +493,7 @@ class FAIR:
|
|
|
495
493
|
|
|
496
494
|
self._logger.debug("Pulling data products locally")
|
|
497
495
|
|
|
498
|
-
# Only
|
|
496
|
+
# Only pull data products if there are any to do so, this covers the
|
|
499
497
|
# case whereby no remote has been setup and we just want to register
|
|
500
498
|
# items on the local registry
|
|
501
499
|
if _readables:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|