Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add export_parameters to metadata.json in export archives #3386

Merged
merged 6 commits into from
Oct 11, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 28 additions & 5 deletions aiida/tools/importexport/dbexport/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
)
from aiida.tools.importexport.common.utils import export_shard_uuid
from aiida.tools.importexport.dbexport.utils import (
check_licences, fill_in_query, serialize_dict, check_process_nodes_sealed, retrieve_linked_nodes
check_licenses, fill_in_query, serialize_dict, check_process_nodes_sealed, retrieve_linked_nodes
)

from .zip import ZipFolder
Expand Down Expand Up @@ -170,11 +170,15 @@ def export_tree(
exporting.
:raises `~aiida.common.exceptions.LicensingException`: if any node is licensed under forbidden license.
"""
from collections import defaultdict

if not silent:
print('STARTING EXPORT...')

all_fields_info, unique_identifiers = get_all_fields_info()

original_entities = defaultdict(list)

# The set that contains the nodes ids of the nodes that should be exported
given_data_entry_ids = set()
given_calculation_entry_ids = set()
Expand All @@ -195,17 +199,21 @@ def export_tree(
given_group_entry_ids.add(entry.id)
given_groups.add(entry)
elif issubclass(entry.__class__, orm.Node):
original_entities[NODE_ENTITY_NAME].append(entry.uuid)
CasperWA marked this conversation as resolved.
Show resolved Hide resolved
if issubclass(entry.__class__, orm.Data):
given_data_entry_ids.add(entry.pk)
elif issubclass(entry.__class__, orm.ProcessNode):
given_calculation_entry_ids.add(entry.pk)
elif issubclass(entry.__class__, orm.Computer):
original_entities[COMPUTER_ENTITY_NAME].append(entry.uuid)
given_computer_entry_ids.add(entry.pk)
else:
raise exceptions.ArchiveExportError(
'I was given {} ({}), which is not a Node, Computer, or Group instance'.format(entry, type(entry))
)

original_entities[GROUP_ENTITY_NAME] = [_.uuid for _ in given_groups]
CasperWA marked this conversation as resolved.
Show resolved Hide resolved

# Add all the nodes contained within the specified groups
for group in given_groups:
for entry in group.nodes:
Expand All @@ -221,7 +229,9 @@ def export_tree(
if not silent:
print('RETRIEVING LINKED NODES AND STORING LINKS...')

to_be_exported, links_uuid = retrieve_linked_nodes(given_calculation_entry_ids, given_data_entry_ids, **kwargs)
to_be_exported, links_uuid, link_follow_rules = retrieve_linked_nodes(
given_calculation_entry_ids, given_data_entry_ids, **kwargs
)

## Universal "entities" attributed to all types of nodes
# Logs
Expand Down Expand Up @@ -301,7 +311,7 @@ def export_tree(
builder.append(orm.Node, project=['id', 'attributes.source.license'], filters={'id': {'in': to_be_exported}})
# Skip those nodes where the license is not set (this is the standard behavior with Django)
node_licenses = list((a, b) for [a, b] in builder.all() if b is not None)
check_licences(node_licenses, allowed_licenses, forbidden_licenses)
check_licenses(node_licenses, allowed_licenses, forbidden_licenses)

############################################################
##### Start automatic recursive export data generation #####
Expand Down Expand Up @@ -425,22 +435,35 @@ def export_tree(
'node_extras': node_extras,
'export_data': export_data,
'links_uuid': links_uuid,
'groups_uuid': groups_uuid,
'groups_uuid': groups_uuid
}

# N.B. We're really calling zipfolder.open
# N.B. We're really calling zipfolder.open (if exporting a zipfile)
with folder.open('data.json', mode='w') as fhandle:
# fhandle.write(json.dumps(data, cls=UUIDEncoder))
fhandle.write(json.dumps(data))

# Add proper signature to unique identifiers & all_fields_info
# Ignore if a key doesn't exist in any of the two dictionaries

license_info = {'allowed_licenses': allowed_licenses, 'forbidden_licenses': forbidden_licenses}
CasperWA marked this conversation as resolved.
Show resolved Hide resolved
for name, value in license_info.items():
if value and not isinstance(value, list):
# The value is a function (can either be a function, a list or None)
license_info[name] = 'Function {} was used to check for {}'.format(value, name.replace('_', ' '))

metadata = {
'aiida_version': get_version(),
'export_version': EXPORT_VERSION,
'all_fields_info': all_fields_info,
'unique_identifiers': unique_identifiers,
'export_parameters': {
'link_follow_rules': link_follow_rules,
CasperWA marked this conversation as resolved.
Show resolved Hide resolved
'original_entities': original_entities,
CasperWA marked this conversation as resolved.
Show resolved Hide resolved
'license_info': license_info,
'include_comments': include_comments,
'include_logs': include_logs
}
}

with folder.open('metadata.json', 'w') as fhandle:
Expand Down
6 changes: 3 additions & 3 deletions aiida/tools/importexport/dbexport/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def fill_in_query(partial_query, originating_entity_str, current_entity_str, tag
fill_in_query(partial_query, current_entity_str, ref_model_name, new_tag_suffixes)


def check_licences(node_licenses, allowed_licenses, forbidden_licenses):
def check_licenses(node_licenses, allowed_licenses, forbidden_licenses):
"""Check licenses"""
from aiida.common.exceptions import LicensingException
from inspect import isfunction
Expand Down Expand Up @@ -384,7 +384,7 @@ def retrieve_linked_nodes(process_nodes, data_nodes, **kwargs): # pylint: disab
:param call_calc_backward: Follow CALL_CALC links in the backward direction (recursively).
:param call_work_backward: Follow CALL_WORK links in the backward direction (recursively).

:return: Set of retrieved Nodes and list of links information.
:return: Set of retrieved Nodes, list of links information, and updated dict of LINK_FLAGS.

:raises `~aiida.tools.importexport.common.exceptions.ExportValidationError`: if wrong or too many kwargs are given.
"""
Expand Down Expand Up @@ -579,4 +579,4 @@ def retrieve_linked_nodes(process_nodes, data_nodes, **kwargs): # pylint: disab
process_nodes.update(found_nodes - retrieved_nodes)
links_uuid_dict.update(links_uuids)

return retrieved_nodes, list(links_uuid_dict.values())
return retrieved_nodes, list(links_uuid_dict.values()), follow_links_rules
50 changes: 39 additions & 11 deletions docs/source/import_export/main.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,33 @@ Let's have a look at the contents of ``metadata.json``:
.. code-block:: json

{
"export_version": "0.6",
"export_version": "0.7",
"aiida_version": "1.0.0",
"export_parameters": {
CasperWA marked this conversation as resolved.
Show resolved Hide resolved
"link_follow_rules": {
"input_calc_forward": false,
"input_calc_backward": true,
"create_forward": true,
"create_backward": true,
"return_forward": true,
"return_backward": false,
"input_work_forward": false,
"input_work_backward": true,
"call_calc_forward": true,
"call_calc_backward": false,
"call_work_forward": true,
"call_work_backward": false
},
"original_entities": {
"Node": ["1024e35e-166b-4104-95f6-c1706df4ce15"]
},
"license_info": {
"allowed_licenses": null,
"forbidden_licenses": "Function valid_licenses was used to check for forbidden licenses"
},
"include_comments": true,
"include_logs": false
},
"unique_identifiers": {
"Computer": "uuid",
"Group": "uuid",
Expand Down Expand Up @@ -186,10 +211,10 @@ A sample of the ``data.json`` file follows:
{
"links_uuid": [
{
"output": "c208c9da-23b4-4c32-8f99-f9141ab28363",
"label": "parent_calc_folder",
"input": "eaaa114d-3d5b-42eb-a269-cf0e7a3a935d",
"type": "inputlink"
"output": "1024e35e-166b-4104-95f6-c1706df4ce15",
"label": "parameters",
"input": "628ba258-ccc1-47bf-bab7-8aee64b563ea",
"type": "input_calc"
}
],
"export_data": {
Expand Down Expand Up @@ -248,7 +273,7 @@ A sample of the ``data.json`` file follows:
"ctime": "2016-08-21T11:56:05.501162",
"mtime": "2016-08-21T11:56:05.501697",
"content": "vc-relax calculation with cold smearing",
"dbnode": 5921143,
"dbnode": 20063,
"user": 2
}
}
Expand Down Expand Up @@ -295,13 +320,16 @@ A sample of the ``data.json`` file follows:
"default_mpiprocs_per_machine": 8
},
"remote_workdir": "/scratch/aiida/aiida_run/10/24/e35e-166b-4104-95f6-c1706df4ce15",
"state": "FINISHED",
"process_state": "finished",
"max_wallclock_seconds": 900,
"retrieve_singlefile_list": [],
"scheduler_lastchecktime": "2015-10-02T20:30:36.481951",
"job_id": "13489"
},
"6480111": {}
"scheduler_lastchecktime": "2015-10-02T20:30:36.481951+00:00",
"job_id": "13489",
"exit_status": 0,
"process_status": null,
"process_label": "vc-relax",
"sealed": true
}
},
"node_extras": {
"5921143": {},
Expand Down