diff --git a/README.md b/README.md index fe918e9b..0d008d57 100644 --- a/README.md +++ b/README.md @@ -49,19 +49,19 @@ def multiply(x, y): wg = WorkGraph("test_add_multiply") wg.add_task(add, name="add1") wg.add_task(multiply, name="multiply1") -wg.add_link(wg.tasks["add1"].outputs["result"], wg.tasks["multiply1"].inputs["x"]) +wg.add_link(wg.tasks.add1.outputs.result, wg.tasks.multiply1.inputs.x) ``` -Prepare inputs and submit the workflow: +Prepare inputs and run the workflow: ```python from aiida import load_profile load_profile() -wg.submit(inputs = {"add1": {"x": 2, "y": 3}, "multiply1": {"y": 4}}, wait=True) -print("Result of multiply1 is", wg.tasks["multiply1"].outputs[0].value) +wg.run(inputs = {"add1": {"x": 2, "y": 3}, "multiply1": {"y": 4}}) +print("Result of multiply1 is", wg.tasks.multiply1.outputs.result.value) ``` ## Web ui To use the web ui, first install the web ui package: diff --git a/docs/gallery/autogen/quick_start.py b/docs/gallery/autogen/quick_start.py index d7f0b7a8..3fef1f7a 100644 --- a/docs/gallery/autogen/quick_start.py +++ b/docs/gallery/autogen/quick_start.py @@ -107,7 +107,7 @@ def multiply(x, y): wg = WorkGraph("add_multiply_workflow") add_task = wg.add_task(add, name="add1") # link the output of the `add` task to one of the `x` input of the `multiply` task. -wg.add_task(multiply, name="multiply1", x=add_task.outputs["result"]) +wg.add_task(multiply, name="multiply1", x=add_task.outputs.result) # export the workgraph to html file so that it can be visualized in a browser wg.to_html() @@ -128,8 +128,8 @@ def multiply(x, y): ) print("State of WorkGraph: {}".format(wg.state)) -print("Result of add : {}".format(wg.tasks["add1"].outputs[0].value)) -print("Result of multiply : {}".format(wg.tasks["multiply1"].outputs[0].value)) +print("Result of add : {}".format(wg.tasks.add1.outputs.result.value)) +print("Result of multiply : {}".format(wg.tasks.multiply1.outputs.result.value)) ###################################################################### @@ -141,172 +141,6 @@ def multiply(x, y): generate_node_graph(wg.pk) -###################################################################### -# Remote job -# ---------- -# -# The ``PythonJob`` is a built-in task that allows users to run Python -# functions on a remote computer. -# -# In this case, we use define the task using normal function instead of -# ``calcfunction``. Thus, user does not need to install AiiDA on the -# remote computer. -# - -from aiida_workgraph import WorkGraph, task - -# define add task -@task() -def add(x, y): - return x + y - - -# define multiply task -@task() -def multiply(x, y): - return x * y - - -wg = WorkGraph("second_workflow") -# You might need to adapt the label to python3 if you use this as your default python -wg.add_task("PythonJob", function=add, name="add", command_info={"label": "python"}) -wg.add_task( - "PythonJob", - function=multiply, - name="multiply", - x=wg.tasks["add"].outputs[0], - command_info={"label": "python"}, -) - -# export the workgraph to html file so that it can be visualized in a browser -wg.to_html() -# visualize the workgraph in jupyter-notebook -# wg - - -###################################################################### -# Submit the workgraph -# ~~~~~~~~~~~~~~~~~~~~ -# -# **Code**: We can set the ``computer`` to the remote computer where we -# want to run the job. This will create a code ``python@computer`` if not -# exists. Of course, you can also set the ``code`` directly if you have -# already created the code. -# -# **Data**: Users can (and is recoomaneded) use normal Python data as -# input. The workgraph will transfer the data to AiiDA data -# (``PickledData``) using pickle. -# -# **Python Version**: since pickle is used to store and load data, the -# Python version on the remote computer should match the one used in the -# localhost. One can use conda to create a virtual environment with the -# same Python version. Then activate the environment before running the -# script. -# -# .. code:: python -# -# # For real applications, one can pass metadata to the scheduler to activate the conda environment -# metadata = { -# "options": { -# 'custom_scheduler_commands' : 'module load anaconda\nconda activate py3.11\n', -# } -# } -# - -from aiida_workgraph.utils import generate_node_graph - -# ------------------------- Submit the calculation ------------------- -# For real applications, one can pass metadata to the scheduler to activate the conda environment -metadata = { - "options": { - # 'custom_scheduler_commands' : 'module load anaconda\nconda activate py3.11\n', - "custom_scheduler_commands": "", - } -} - -wg.submit( - inputs={ - "add": {"x": 2, "y": 3, "computer": "localhost", "metadata": metadata}, - "multiply": {"y": 4, "computer": "localhost", "metadata": metadata}, - }, - wait=True, -) -# ------------------------- Print the output ------------------------- -print( - "\nResult of multiply is {} \n\n".format( - wg.tasks["multiply"].outputs["result"].value - ) -) -# ------------------------- Generate node graph ------------------- -generate_node_graph(wg.pk) - - -###################################################################### -# Use parent folder -# ~~~~~~~~~~~~~~~~~ -# -# The parent_folder parameter allows a task to access the output files of -# a parent task. This feature is particularly useful when you want to -# reuse data generated by a previous computation in subsequent -# computations. In the following example, the multiply task uses the -# ``result.txt`` file created by the add task. -# -# By default, the content of the parent folder is symlinked to the working -# directory. In the function, you can access the parent folder using the -# relative path. For example, ``./parent_folder/result.txt``. -# - -from aiida_workgraph import WorkGraph, task - -# define add task -@task() -def add(x, y): - z = x + y - with open("result.txt", "w") as f: - f.write(str(z)) - - -# define multiply task -@task() -def multiply(x, y): - with open("parent_folder/result.txt", "r") as f: - z = int(f.read()) - return x * y + z - - -wg = WorkGraph("third_workflow") -# You might need to adapt the label to python3 if you use this as your default python -wg.add_task("PythonJob", function=add, name="add", command_info={"label": "python"}) -wg.add_task( - "PythonJob", - function=multiply, - name="multiply", - parent_folder=wg.tasks["add"].outputs["remote_folder"], - command_info={"label": "python"}, -) - -wg.to_html() - - -###################################################################### -# Submit the calculation -# - -# ------------------------- Submit the calculation ------------------- -wg.submit( - inputs={ - "add": {"x": 2, "y": 3, "computer": "localhost"}, - "multiply": {"x": 3, "y": 4, "computer": "localhost"}, - }, - wait=True, -) -print( - "\nResult of multiply is {} \n\n".format( - wg.tasks["multiply"].outputs["result"].value - ) -) - - ###################################################################### # CalcJob and WorkChain # --------------------- @@ -341,7 +175,7 @@ def multiply(x, y): wg = WorkGraph("test_add_multiply") add1 = wg.add_task(ArithmeticAddCalculation, name="add1", x=Int(2), y=Int(3), code=code) add2 = wg.add_task(ArithmeticAddCalculation, name="add2", y=Int(3), code=code) -wg.add_link(wg.tasks["add1"].outputs["sum"], wg.tasks["add2"].inputs["x"]) +wg.add_link(wg.tasks.add1.outputs.sum, wg.tasks.add2.inputs.x) wg.to_html() @@ -350,7 +184,7 @@ def multiply(x, y): # wg.submit(wait=True) -print("Result of task add1: {}".format(wg.tasks["add2"].outputs["sum"].value)) +print("Result of task add1: {}".format(wg.tasks.add2.outputs.sum.value)) from aiida_workgraph.utils import generate_node_graph @@ -413,7 +247,7 @@ def add_multiply(x, y, z): wg = WorkGraph() wg.add_task(add, name="add", x=x, y=y) wg.add_task(multiply, name="multiply", x=z) - wg.add_link(wg.tasks["add"].outputs["result"], wg.tasks["multiply"].inputs["y"]) + wg.add_link(wg.tasks.add.outputs.result, wg.tasks.multiply.inputs.y) # don't forget to return the `wg` return wg @@ -431,7 +265,7 @@ def add_multiply(x, y, z): add_multiply1 = wg.add_task(add_multiply, x=Int(2), y=Int(3), z=Int(4)) add_multiply2 = wg.add_task(add_multiply, x=Int(2), y=Int(3)) # link the output of a task to the input of another task -wg.add_link(add_multiply1.outputs["multiply"], add_multiply2.inputs["z"]) +wg.add_link(add_multiply1.outputs.multiply, add_multiply2.inputs.z) wg.submit(wait=True) print("WorkGraph state: ", wg.state) @@ -440,9 +274,7 @@ def add_multiply(x, y, z): # Get the result of the tasks: # -print( - "Result of task add_multiply1: {}".format(add_multiply1.outputs["multiply"].value) -) +print("Result of task add_multiply1: {}".format(add_multiply1.outputs.multiply.value)) generate_node_graph(wg.pk) diff --git a/docs/gallery/built-in/autogen/shelljob.py b/docs/gallery/built-in/autogen/shelljob.py index 7632ef71..6bbca441 100644 --- a/docs/gallery/built-in/autogen/shelljob.py +++ b/docs/gallery/built-in/autogen/shelljob.py @@ -31,7 +31,7 @@ wg.submit(wait=True) # Print out the result: -print("\nResult: ", date_task.outputs["stdout"].value.get_content()) +print("\nResult: ", date_task.outputs.stdout.value.get_content()) # %% # Under the hood, an AiiDA ``Code`` instance ``date`` will be created on the ``localhost`` computer. In addition, it is also @@ -93,7 +93,7 @@ wg.submit(wait=True) # Print out the result: -print("\nResult: ", date_task.outputs["stdout"].value.get_content()) +print("\nResult: ", date_task.outputs.stdout.value.get_content()) # %% # Running a shell command with files as arguments @@ -117,7 +117,7 @@ wg.submit(wait=True) # Print out the result: -print("\nResult: ", cat_task.outputs["stdout"].value.get_content()) +print("\nResult: ", cat_task.outputs.stdout.value.get_content()) # %% # Create a workflow @@ -157,7 +157,7 @@ def parser(dirpath): name="expr_2", command="expr", arguments=["{result}", "*", "{z}"], - nodes={"z": Int(4), "result": expr_1.outputs["result"]}, + nodes={"z": Int(4), "result": expr_1.outputs.result}, parser=PickledData(parser), parser_outputs=[{"name": "result"}], ) diff --git a/docs/gallery/concept/autogen/socket.py b/docs/gallery/concept/autogen/socket.py index 5f86d399..09e41c00 100644 --- a/docs/gallery/concept/autogen/socket.py +++ b/docs/gallery/concept/autogen/socket.py @@ -85,8 +85,7 @@ def add(x: int, y: float) -> float: return x + y -for input in add.task().inputs: - print("{:30s}: {:20s}".format(input.name, input.identifier)) +print("inputs: ", add.task().inputs) ###################################################################### diff --git a/docs/gallery/concept/autogen/task.py b/docs/gallery/concept/autogen/task.py index 7685d841..d18724f9 100644 --- a/docs/gallery/concept/autogen/task.py +++ b/docs/gallery/concept/autogen/task.py @@ -94,7 +94,7 @@ def add_minus(x, y): wg = WorkGraph() add_minus1 = wg.add_task(add_minus, name="add_minus1") multiply1 = wg.add_task(multiply, name="multiply1") -wg.add_link(add_minus1.outputs["sum"], multiply1.inputs["x"]) +wg.add_link(add_minus1.outputs.sum, multiply1.inputs.x) ###################################################################### @@ -124,14 +124,8 @@ def add_minus(x, y): wg = WorkGraph() norm_task = wg.add_task(NormTask, name="norm1") -print("Inputs:") -for input in norm_task.inputs: - if "." not in input.name: - print(f" - {input.name}") -print("Outputs:") -for output in norm_task.outputs: - if "." not in output.name: - print(f" - {output.name}") +print("Inputs: ", norm_task.inputs) +print("Outputs: ", norm_task.outputs) ###################################################################### # For specifying the outputs, the most explicit way is to provide a list of dictionaries, as shown above. In addition, diff --git a/docs/gallery/concept/autogen/workgraph.py b/docs/gallery/concept/autogen/workgraph.py index 118357f2..12d01da9 100644 --- a/docs/gallery/concept/autogen/workgraph.py +++ b/docs/gallery/concept/autogen/workgraph.py @@ -33,7 +33,7 @@ def add(x, y): # %% # Add a link between tasks: -wg.add_link(add1.outputs["result"], add2.inputs["x"]) +wg.add_link(add1.outputs.result, add2.inputs.x) wg.to_html() # %% diff --git a/docs/gallery/howto/autogen/aggregate.py b/docs/gallery/howto/autogen/aggregate.py index 91d68164..41d01d7c 100644 --- a/docs/gallery/howto/autogen/aggregate.py +++ b/docs/gallery/howto/autogen/aggregate.py @@ -114,7 +114,7 @@ def aggregate( for i in range(2): # this can be chosen as wanted generator_task = wg.add_task(generator, name=f"generator{i}", seed=Int(i)) wg.add_link( - generator_task.outputs["result"], + generator_task.outputs.result, aggregate_task.inputs["collected_values"], ) @@ -128,7 +128,7 @@ def aggregate( # %% # Print the output -print("aggregate_task result", aggregate_task.outputs["sum"].value) +print("aggregate_task result", aggregate_task.outputs.sum.value) # %% @@ -200,12 +200,12 @@ def aggregate(**collected_values): ) wg.add_link( - generator_int_task.outputs["result"], + generator_int_task.outputs.result, aggregate_task.inputs["collected_ints"], ) wg.add_link( - generator_float_task.outputs["result"], + generator_float_task.outputs.result, aggregate_task.inputs["collected_floats"], ) wg.to_html() @@ -269,7 +269,7 @@ def generator_loop(nb_iterations: Int): aggregate_task = wg.add_task( aggregate, name="aggregate_task", - collected_values=generator_loop_task.outputs["result"], + collected_values=generator_loop_task.outputs.result, ) wg.to_html() @@ -283,7 +283,7 @@ def generator_loop(nb_iterations: Int): # %% # Print the output -print("aggregate_task result", aggregate_task.outputs["result"].value) +print("aggregate_task result", aggregate_task.outputs.result.value) # %% diff --git a/docs/gallery/howto/autogen/graph_builder.py b/docs/gallery/howto/autogen/graph_builder.py index f67d1a04..f5b074f0 100644 --- a/docs/gallery/howto/autogen/graph_builder.py +++ b/docs/gallery/howto/autogen/graph_builder.py @@ -52,7 +52,7 @@ def add_multiply(x=None, y=None, z=None): wg = WorkGraph() wg.add_task(add, name="add", x=x, y=y) wg.add_task(multiply, name="multiply", x=z) - wg.add_link(wg.tasks["add"].outputs["result"], wg.tasks["multiply"].inputs["y"]) + wg.add_link(wg.tasks.add.outputs.result, wg.tasks.multiply.inputs.y) return wg @@ -61,9 +61,7 @@ def add_multiply(x=None, y=None, z=None): add_multiply1 = wg.add_task(add_multiply(x=Int(2), y=Int(3), z=Int(4))) add_multiply2 = wg.add_task(add_multiply(x=Int(2), y=Int(3))) # link the output of a task to the input of another task -wg.add_link( - add_multiply1.outputs["multiply.result"], add_multiply2.inputs["multiply.x"] -) +wg.add_link(add_multiply1.outputs.multiply.result, add_multiply2.inputs.multiply.x) wg.to_html() # %% @@ -72,7 +70,7 @@ def add_multiply(x=None, y=None, z=None): wg.submit(wait=True) # (2+3)*4 = 20 # (2+3)*20 = 100 -assert add_multiply2.outputs["multiply.result"].value == 100 +assert add_multiply2.outputs.multiply.result.value == 100 # %% # Generate node graph from the AiiDA process @@ -115,7 +113,7 @@ def add_multiply(x, y, z): wg = WorkGraph() wg.add_task(add, name="add", x=x, y=y) wg.add_task(multiply, name="multiply", x=z) - wg.add_link(wg.tasks["add"].outputs[0], wg.tasks["multiply"].inputs["y"]) + wg.add_link(wg.tasks.add.outputs[0], wg.tasks.multiply.inputs.y) # Don't forget to return the `wg` return wg @@ -133,7 +131,7 @@ def add_multiply(x, y, z): add_multiply1 = wg.add_task(add_multiply, x=Int(2), y=Int(3), z=Int(4)) add_multiply2 = wg.add_task(add_multiply, x=Int(2), y=Int(3)) # link the output of a task to the input of another task -wg.add_link(add_multiply1.outputs[0], add_multiply2.inputs["z"]) +wg.add_link(add_multiply1.outputs[0], add_multiply2.inputs.z) wg.submit(wait=True) assert add_multiply2.outputs[0].value == 100 wg.to_html() @@ -211,7 +209,7 @@ def for_loop(nb_iterations: Int): # Running the workgraph. wg.submit(wait=True) -print("Output of last task", task.outputs["result"].value) # 1 + 1 result +print("Output of last task", task.outputs.result.value) # 1 + 1 result # %% # Plotting provenance @@ -250,15 +248,15 @@ def if_then_else(i: Int): wg = WorkGraph("Nested workflow: If") task1 = wg.add_task(if_then_else, i=Int(1)) -task2 = wg.add_task(if_then_else, i=task1.outputs["result"]) +task2 = wg.add_task(if_then_else, i=task1.outputs.result) wg.to_html() # %% # Running the workgraph. wg.submit(wait=True) -print("Output of first task", task1.outputs["result"].value) # 1 + 1 result -print("Output of second task", task2.outputs["result"].value) # 2 % 2 result +print("Output of first task", task1.outputs.result.value) # 1 + 1 result +print("Output of second task", task2.outputs.result.value) # 2 % 2 result # %% # Plotting provenance diff --git a/docs/gallery/howto/autogen/parallel.py b/docs/gallery/howto/autogen/parallel.py index 240c22b4..b8866fd8 100644 --- a/docs/gallery/howto/autogen/parallel.py +++ b/docs/gallery/howto/autogen/parallel.py @@ -132,7 +132,7 @@ def sum(**datas): # print("State of WorkGraph: {}".format(wg.state)) -print("Result of task add1: {}".format(wg.tasks["sum1"].outputs["result"].value)) +print("Result of task add1: {}".format(wg.tasks.sum1.outputs.result.value)) # %% diff --git a/docs/gallery/tutorial/autogen/eos.py b/docs/gallery/tutorial/autogen/eos.py index 51a1c09e..c57c3729 100644 --- a/docs/gallery/tutorial/autogen/eos.py +++ b/docs/gallery/tutorial/autogen/eos.py @@ -102,8 +102,8 @@ def eos(**datas): scale_structure1 = wg.add_task(scale_structure, name="scale_structure1") all_scf1 = wg.add_task(all_scf, name="all_scf1") eos1 = wg.add_task(eos, name="eos1") -wg.add_link(scale_structure1.outputs["structures"], all_scf1.inputs["structures"]) -wg.add_link(all_scf1.outputs["result"], eos1.inputs["datas"]) +wg.add_link(scale_structure1.outputs.structures, all_scf1.inputs.structures) +wg.add_link(all_scf1.outputs.result, eos1.inputs.datas) wg.to_html() # visualize the workgraph in jupyter-notebook # wg @@ -183,8 +183,8 @@ def eos(**datas): } # ------------------------------------------------------- # set the input parameters for each task -wg.tasks["scale_structure1"].set({"structure": si, "scales": [0.95, 1.0, 1.05]}) -wg.tasks["all_scf1"].set({"scf_inputs": scf_inputs}) +wg.tasks.scale_structure1.set({"structure": si, "scales": [0.95, 1.0, 1.05]}) +wg.tasks.all_scf1.set({"scf_inputs": scf_inputs}) print("Waiting for the workgraph to finish...") wg.submit(wait=True, timeout=300) # one can also run the workgraph directly @@ -196,7 +196,7 @@ def eos(**datas): # -data = wg.tasks["eos1"].outputs["result"].value.get_dict() +data = wg.tasks["eos1"].outputs.result.value.get_dict() print("B: {B}\nv0: {v0}\ne0: {e0}\nv0: {v0}".format(**data)) # %% @@ -216,8 +216,8 @@ def eos_workgraph(structure=None, scales=None, scf_inputs=None): ) all_scf1 = wg.add_task(all_scf, name="all_scf1", scf_inputs=scf_inputs) eos1 = wg.add_task(eos, name="eos1") - wg.add_link(scale_structure1.outputs["structures"], all_scf1.inputs["structures"]) - wg.add_link(all_scf1.outputs["result"], eos1.inputs["datas"]) + wg.add_link(scale_structure1.outputs.structures, all_scf1.inputs.structures) + wg.add_link(all_scf1.outputs.result, eos1.inputs.datas) return wg @@ -268,7 +268,7 @@ def eos_workgraph(structure=None, scales=None, scf_inputs=None): eos_wg_task = wg.add_task( eos_workgraph, name="eos1", scales=[0.95, 1.0, 1.05], scf_inputs=scf_inputs ) -wg.add_link(relax_task.outputs["output_structure"], eos_wg_task.inputs["structure"]) +wg.add_link(relax_task.outputs.output_structure, eos_wg_task.inputs["structure"]) # ------------------------------------------------------- # One can submit the workgraph directly # wg.submit(wait=True, timeout=300) diff --git a/docs/gallery/tutorial/autogen/qe.py b/docs/gallery/tutorial/autogen/qe.py index aaab06bb..fe3323ce 100644 --- a/docs/gallery/tutorial/autogen/qe.py +++ b/docs/gallery/tutorial/autogen/qe.py @@ -147,7 +147,7 @@ # ------------------------- Print the output ------------------------- print( "Energy of an un-relaxed N2 molecule: {:0.3f}".format( - pw1.outputs["output_parameters"].value.get_dict()["energy"] + pw1.outputs.output_parameters.value.get_dict()["energy"] ) ) # @@ -238,8 +238,8 @@ def atomization_energy(output_atom, output_mol): ) # create the task to calculate the atomization energy atomization = wg.add_task(atomization_energy, name="atomization_energy") -wg.add_link(pw_n.outputs["output_parameters"], atomization.inputs["output_atom"]) -wg.add_link(pw_n2.outputs["output_parameters"], atomization.inputs["output_mol"]) +wg.add_link(pw_n.outputs.output_parameters, atomization.inputs.output_atom) +wg.add_link(pw_n2.outputs.output_parameters, atomization.inputs.output_mol) wg.to_html() @@ -249,9 +249,7 @@ def atomization_energy(output_atom, output_mol): wg.submit(wait=True, timeout=300) -print( - "Atomization energy: {:0.3f} eV".format(atomization.outputs["result"].value.value) -) +print("Atomization energy: {:0.3f} eV".format(atomization.outputs.result.value.value)) # %% @@ -305,7 +303,7 @@ def pw_parameters(paras, relax_type): }, ) paras_task = wg.add_task(pw_parameters, "parameters", paras=paras, relax_type="relax") -wg.add_link(paras_task.outputs[0], pw_relax1.inputs["base.pw.parameters"]) +wg.add_link(paras_task.outputs[0], pw_relax1.inputs.base.pw.parameters) # One can submit the workgraph directly # wg.submit(wait=True, timeout=200) # print( @@ -341,10 +339,10 @@ def pw_parameters(paras, relax_type): # we can now inspect the inputs of the workchain print("The inputs for the PwBaseWorkchain are:") print("-" * 80) -pprint(pw_relax1.inputs["base"].value) +pprint(pw_relax1.inputs.base._value) print("\nThe input parameters for pw are:") print("-" * 80) -pprint(pw_relax1.inputs["base"].value["pw"]["parameters"].get_dict()) +pprint(pw_relax1.inputs.base.pw.parameters.value.get_dict()) # %% diff --git a/docs/gallery/tutorial/autogen/zero_to_hero.py b/docs/gallery/tutorial/autogen/zero_to_hero.py index 617e2e8e..3c93ba3f 100644 --- a/docs/gallery/tutorial/autogen/zero_to_hero.py +++ b/docs/gallery/tutorial/autogen/zero_to_hero.py @@ -70,7 +70,7 @@ def multiply(x, y): # wg = WorkGraph("add_multiply_workflow") wg.add_task(add, name="add1") -wg.add_task(multiply, name="multiply1", x=wg.tasks["add1"].outputs["result"]) +wg.add_task(multiply, name="multiply1", x=wg.tasks.add1.outputs.result) # export the workgraph to html file so that it can be visualized in a browser wg.to_html() # visualize the workgraph in jupyter-notebook @@ -92,11 +92,9 @@ def multiply(x, y): inputs={"add1": {"x": Int(2), "y": Int(3)}, "multiply1": {"y": Int(4)}}, wait=True ) # ------------------------- Print the output ------------------------- -assert wg.tasks["multiply1"].outputs["result"].value == 20 +assert wg.tasks.multiply1.outputs.result.value == 20 print( - "\nResult of multiply1 is {} \n\n".format( - wg.tasks["multiply1"].outputs["result"].value - ) + "\nResult of multiply1 is {} \n\n".format(wg.tasks.multiply1.outputs.result.value) ) # ------------------------- Generate node graph ------------------- generate_node_graph(wg.pk) @@ -118,7 +116,7 @@ def multiply(x, y): wg = WorkGraph("test_calcjob") new = wg.add_task new(ArithmeticAddCalculation, name="add1") -wg.add_task(ArithmeticAddCalculation, name="add2", x=wg.tasks["add1"].outputs["sum"]) +wg.add_task(ArithmeticAddCalculation, name="add2", x=wg.tasks.add1.outputs.sum) wg.to_html() # @@ -134,7 +132,7 @@ def multiply(x, y): # visualize the task -wg.tasks["add1"].to_html() +wg.tasks.add1.to_html() # # %% @@ -183,8 +181,8 @@ def atomization_energy(output_atom, output_mol): wg.add_task( atomization_energy, name="atomization_energy", - output_atom=pw_atom.outputs["output_parameters"], - output_mol=pw_mol.outputs["output_parameters"], + output_atom=pw_atom.outputs.output_parameters, + output_mol=pw_mol.outputs.output_parameters, ) # export the workgraph to html file so that it can be visualized in a browser wg.to_html() @@ -265,7 +263,7 @@ def atomization_energy(output_atom, output_mol): } # # ------------------------- Set the inputs ------------------------- -wg.tasks["pw_atom"].set( +wg.tasks.pw_atom.set( { "code": pw_code, "structure": structure_n, @@ -275,7 +273,7 @@ def atomization_energy(output_atom, output_mol): "metadata": metadata, } ) -wg.tasks["pw_mol"].set( +wg.tasks.pw_mol.set( { "code": pw_code, "structure": structure_n2, @@ -290,17 +288,17 @@ def atomization_energy(output_atom, output_mol): # ------------------------- Print the output ------------------------- print( "Energy of a N atom: {:0.3f}".format( - wg.tasks["pw_atom"].outputs["output_parameters"].value.get_dict()["energy"] + wg.tasks.pw_atom.outputs.output_parameters.value.get_dict()["energy"] ) ) print( "Energy of an un-relaxed N2 molecule: {:0.3f}".format( - wg.tasks["pw_mol"].outputs["output_parameters"].value.get_dict()["energy"] + wg.tasks.pw_mol.outputs.output_parameters.value.get_dict()["energy"] ) ) print( "Atomization energy: {:0.3f} eV".format( - wg.tasks["atomization_energy"].outputs["result"].value.value + wg.tasks.atomization_energy.outputs.result.value.value ) ) # @@ -364,9 +362,9 @@ def add_multiply_if_generator(x, y): wg.add_task( add_multiply_if_generator, name="add_multiply_if1", - x=wg.tasks["add1"].outputs["result"], + x=wg.tasks.add1.outputs.result, ) -wg.add_task(add, name="add2", x=wg.tasks["add_multiply_if1"].outputs["result"]) +wg.add_task(add, name="add2", x=wg.tasks.add_multiply_if1.outputs.result) wg.to_html() # @@ -383,8 +381,8 @@ def add_multiply_if_generator(x, y): wait=True, ) # ------------------------- Print the output ------------------------- -assert wg.tasks["add2"].outputs["result"].value == 7 -print("\nResult of add2 is {} \n\n".format(wg.tasks["add2"].outputs["result"].value)) +assert wg.tasks.add2.outputs.result.value == 7 +print("\nResult of add2 is {} \n\n".format(wg.tasks.add2.outputs.result.value)) # # %% # Note: one can not see the detail of the `add_multiply_if1` before you running it. @@ -465,9 +463,9 @@ def eos(**datas): wg = WorkGraph("eos") scale_structure1 = wg.add_task(scale_structure, name="scale_structure1") all_scf1 = wg.add_task( - all_scf, name="all_scf1", structures=scale_structure1.outputs["structures"] + all_scf, name="all_scf1", structures=scale_structure1.outputs.structures ) -eos1 = wg.add_task(eos, name="eos1", datas=all_scf1.outputs["result"]) +eos1 = wg.add_task(eos, name="eos1", datas=all_scf1.outputs.result) wg.to_html() # @@ -489,8 +487,8 @@ def eos_workgraph(structure=None, scales=None, scf_inputs=None): ) all_scf1 = wg.add_task(all_scf, name="all_scf1", scf_inputs=scf_inputs) eos1 = wg.add_task(eos, name="eos1") - wg.add_link(scale_structure1.outputs["structures"], all_scf1.inputs["structures"]) - wg.add_link(all_scf1.outputs["result"], eos1.inputs["datas"]) + wg.add_link(scale_structure1.outputs.structures, all_scf1.inputs.structures) + wg.add_link(all_scf1.outputs.result, eos1.inputs.datas) return wg @@ -500,7 +498,7 @@ def eos_workgraph(structure=None, scales=None, scf_inputs=None): wg = WorkGraph("relax_eos") relax_task = wg.add_task(PwCalculation, name="relax1") eos_wg_task = wg.add_task( - eos_workgraph, name="eos1", structure=relax_task.outputs["output_structure"] + eos_workgraph, name="eos1", structure=relax_task.outputs.output_structure ) wg.to_html() diff --git a/docs/source/built-in/monitor.ipynb b/docs/source/built-in/monitor.ipynb index 25be2343..293b9b9e 100644 --- a/docs/source/built-in/monitor.ipynb +++ b/docs/source/built-in/monitor.ipynb @@ -67,10 +67,10 @@ "wg2.add_task(add, \"add2\",x=1, y=2, t=5)\n", "wg2.submit(wait=True)\n", "wg1.wait()\n", - "print(\"ctime of add1: \", wg1.tasks[\"add1\"].node.ctime)\n", - "print(\"citme of add2: \", wg2.tasks[\"add2\"].node.ctime)\n", + "print(\"ctime of add1: \", wg1.tasks.add1.node.ctime)\n", + "print(\"citme of add2: \", wg2.tasks.add2.node.ctime)\n", "# calculate the time difference between the creation of the two task nodes\n", - "time_difference = wg1.tasks[\"add1\"].node.ctime - wg2.tasks[\"add2\"].node.ctime\n", + "time_difference = wg1.tasks.add1.node.ctime - wg2.tasks.add2.node.ctime\n", "assert time_difference.total_seconds() > 5" ] }, diff --git a/docs/source/built-in/pythonjob.ipynb b/docs/source/built-in/pythonjob.ipynb index a7e286ad..bcb76f71 100644 --- a/docs/source/built-in/pythonjob.ipynb +++ b/docs/source/built-in/pythonjob.ipynb @@ -106,7 +106,7 @@ "wg = WorkGraph(\"first_workflow\")\n", "wg.add_task(add, name=\"add\")\n", "# we can also use a normal python function directly, but provide the \"PythonJob\" as the first argument\n", - "wg.add_task(\"PythonJob\", function=multiply, name=\"multiply\", x=wg.tasks[\"add\"].outputs[0])\n", + "wg.add_task(\"PythonJob\", function=multiply, name=\"multiply\", x=wg.tasks.add.outputs[0])\n", "\n", "# visualize the workgraph\n", "wg.to_html()\n", @@ -362,7 +362,7 @@ " \"metadata\": metadata}},\n", " wait=True)\n", "#------------------------- Print the output -------------------------\n", - "print(\"\\nResult of multiply is {} \\n\\n\".format(wg.tasks[\"multiply\"].outputs['result'].value))\n", + "print(\"\\nResult of multiply is {} \\n\\n\".format(wg.tasks.multiply.outputs.result.value))\n", "#------------------------- Generate node graph -------------------\n", "generate_node_graph(wg.pk)" ] @@ -421,7 +421,7 @@ "wg = WorkGraph(\"PythonJob_parent_folder\")\n", "wg.add_task(\"PythonJob\", function=add, name=\"add\")\n", "wg.add_task(\"PythonJob\", function=multiply, name=\"multiply\",\n", - " parent_folder=wg.tasks[\"add\"].outputs[\"remote_folder\"],\n", + " parent_folder=wg.tasks.add.outputs.remote_folder,\n", " )\n", "\n", "wg.to_html()" @@ -457,7 +457,7 @@ "wg.submit(inputs = {\"add\": {\"x\": 2, \"y\": 3, \"computer\": \"localhost\"},\n", " \"multiply\": {\"x\": 3, \"y\": 4, \"computer\": \"localhost\"}},\n", " wait=True)\n", - "print(\"\\nResult of multiply is {} \\n\\n\".format(wg.tasks[\"multiply\"].outputs['result'].value))" + "print(\"\\nResult of multiply is {} \\n\\n\".format(wg.tasks.multiply.outputs.result.value))" ] }, { @@ -526,7 +526,7 @@ " },\n", " },\n", " wait=True)\n", - "print(\"\\nResult of add is {} \\n\\n\".format(wg.tasks[\"add\"].outputs['result'].value))" + "print(\"\\nResult of add is {} \\n\\n\".format(wg.tasks.add.outputs['result'].value))" ] }, { @@ -615,8 +615,8 @@ "pw_atom = wg.add_task(\"PythonJob\", function=emt, name=\"emt_atom\")\n", "pw_mol = wg.add_task(\"PythonJob\", function=emt, name=\"emt_mol\")\n", "wg.add_task(\"PythonJob\", function=atomization_energy, name=\"atomization_energy\",\n", - " energy_atom=pw_atom.outputs[\"result\"],\n", - " energy_molecule=pw_mol.outputs[\"result\"])\n", + " energy_atom=pw_atom.outputs.result,\n", + " energy_molecule=pw_mol.outputs.result)\n", "wg.to_html()" ] }, @@ -904,9 +904,9 @@ "#------------------------- Submit the calculation -------------------\n", "wg.submit(wait=True, timeout=200)\n", "#------------------------- Print the output -------------------------\n", - "print('Energy of a N atom: {:0.3f}'.format(wg.tasks['emt_atom'].outputs[\"result\"].value.value))\n", - "print('Energy of an un-relaxed N2 molecule: {:0.3f}'.format(wg.tasks['emt_mol'].outputs[\"result\"].value.value))\n", - "print('Atomization energy: {:0.3f} eV'.format(wg.tasks['atomization_energy'].outputs[\"result\"].value.value))\n", + "print('Energy of a N atom: {:0.3f}'.format(wg.tasks['emt_atom'].outputs.result.value.value))\n", + "print('Energy of an un-relaxed N2 molecule: {:0.3f}'.format(wg.tasks['emt_mol'].outputs.result.value.value))\n", + "print('Atomization energy: {:0.3f} eV'.format(wg.tasks['atomization_energy'].outputs.result.value.value))\n", "#------------------------- Generate node graph -------------------\n", "generate_node_graph(wg.pk)\n" ] @@ -981,7 +981,7 @@ "\n", "wg = WorkGraph(\"PythonJob_shell_command\")\n", "wg.add_task(\"PythonJob\", function=add, name=\"add\")\n", - "wg.add_task(\"PythonJob\", function=multiply, name=\"multiply\", x=wg.tasks[\"add\"].outputs[0])\n", + "wg.add_task(\"PythonJob\", function=multiply, name=\"multiply\", x=wg.tasks.add.outputs[0])\n", "\n", "# visualize the workgraph\n", "wg.to_html()\n" @@ -1191,7 +1191,7 @@ " \"multiply\": {\"y\": 4, \"computer\": \"localhost\"}},\n", " wait=True)\n", "#------------------------- Print the output -------------------------\n", - "print(\"\\nResult of multiply is {} \\n\\n\".format(wg.tasks[\"multiply\"].outputs['result'].value))\n", + "print(\"\\nResult of multiply is {} \\n\\n\".format(wg.tasks.multiply.outputs.result.value))\n", "#------------------------- Generate node graph -------------------\n", "generate_node_graph(wg.pk)" ] @@ -1546,14 +1546,14 @@ " # -------- calculate_enegies -----------\n", "calculate_enegies_task = wg.add_task(calculate_enegies,\n", " name=\"calculate_enegies\",\n", - " scaled_atoms=scale_atoms_task.outputs[\"scaled_atoms\"],\n", + " scaled_atoms=scale_atoms_task.outputs.scaled_atoms,\n", " )\n", " # -------- fit_eos -----------\n", "wg.add_task(\"PythonJob\",\n", " function=fit_eos,\n", " name=\"fit_eos\",\n", - " volumes=scale_atoms_task.outputs[\"volumes\"],\n", - " emt_results=calculate_enegies_task.outputs[\"results\"],\n", + " volumes=scale_atoms_task.outputs.volumes,\n", + " emt_results=calculate_enegies_task.outputs.results,\n", " )\n", "wg.to_html()" ] @@ -1598,7 +1598,7 @@ " )\n", "\n", "print(\"The fitted EOS parameters are:\")\n", - "wg.tasks[\"fit_eos\"].outputs[\"result\"].value.value\n" + "wg.tasks[\"fit_eos\"].outputs.result.value.value\n" ] }, { @@ -2257,8 +2257,8 @@ "wg.add_task(add, name=\"add\", x=1, y=-2)\n", "wg.submit(wait=True)\n", "\n", - "print(\"exit status: \", wg.tasks[\"add\"].node.exit_status)\n", - "print(\"exit message: \", wg.tasks[\"add\"].node.exit_message)" + "print(\"exit status: \", wg.tasks.add.node.exit_status)\n", + "print(\"exit message: \", wg.tasks.add.node.exit_message)" ] }, { diff --git a/docs/source/built-in/shelljob.ipynb b/docs/source/built-in/shelljob.ipynb index 142de3de..079801e4 100644 --- a/docs/source/built-in/shelljob.ipynb +++ b/docs/source/built-in/shelljob.ipynb @@ -249,19 +249,19 @@ "# bc command to calculate the expression\n", "bc_task_1 = wg.add_task(\"ShellJob\", name=\"bc_task_1\", command=\"bc\", arguments=[\"{expression}\"],\n", " parser=PickledData(parser),\n", - " nodes={'expression': echo_task_1.outputs[\"stdout\"]},\n", + " nodes={'expression': echo_task_1.outputs.stdout},\n", " parser_outputs=[{\"name\": \"result\"}],\n", " )\n", "# echo result + z expression\n", "echo_task_2 = wg.add_task(\"ShellJob\", name=\"echo_task_2\", command=\"echo\",\n", " arguments=[\"{result}\", \"*\", \"{z}\"],\n", " nodes={'z': Int(4),\n", - " \"result\": bc_task_1.outputs[\"result\"]},\n", + " \"result\": bc_task_1.outputs.result},\n", " )\n", "# bc command to calculate the expression\n", "bc_task_2 = wg.add_task(\"ShellJob\", name=\"bc_task_2\", command=\"bc\", arguments=[\"{expression}\"],\n", " parser=PickledData(parser),\n", - " nodes={'expression': echo_task_2.outputs[\"stdout\"]},\n", + " nodes={'expression': echo_task_2.outputs.stdout},\n", " parser_outputs=[{\"name\": \"result\"}],\n", " )\n", "display(wg.to_html())\n", diff --git a/docs/source/howto/context.ipynb b/docs/source/howto/context.ipynb index 9ccbca59..eea0b1cf 100644 --- a/docs/source/howto/context.ipynb +++ b/docs/source/howto/context.ipynb @@ -137,10 +137,10 @@ "# Set the context of the workgraph\n", "wg.context = {\"x\": 2, \"data.y\": 3}\n", "get_ctx1 = wg.add_task(\"workgraph.get_context\", name=\"get_ctx1\", key=\"x\")\n", - "add1 = wg.add_task(add, \"add1\", x=get_ctx1.outputs[\"result\"],\n", + "add1 = wg.add_task(add, \"add1\", x=get_ctx1.outputs.result,\n", " y=\"{{data.y}}\")\n", "set_ctx1 = wg.add_task(\"workgraph.set_context\", name=\"set_ctx1\", key=\"x\",\n", - " value=add1.outputs[\"result\"])\n", + " value=add1.outputs.result)\n", "wg.to_html()\n", "# wg" ] diff --git a/tests/conftest.py b/tests/conftest.py index 7facdb73..e553dc25 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -88,7 +88,7 @@ def wg_calcjob(add_code) -> WorkGraph: wg = WorkGraph(name="test_debug_math") add1 = wg.add_task(ArithmeticAddCalculation, "add1", x=2, y=3, code=add_code) add2 = wg.add_task(ArithmeticAddCalculation, "add2", x=4, code=add_code) - wg.add_link(add1.outputs["sum"], add2.inputs["y"]) + wg.add_link(add1.outputs.sum, add2.inputs["y"]) return wg @@ -233,11 +233,11 @@ def wg_engine(decorated_add, add_code) -> WorkGraph: add3 = wg.add_task(decorated_add, "add3", x=2, y=3) add4 = wg.add_task(ArithmeticAddCalculation, "add4", x=2, y=4, code=code) add5 = wg.add_task(decorated_add, "add5", x=2, y=5) - wg.add_link(add0.outputs["sum"], add2.inputs["x"]) - wg.add_link(add1.outputs[0], add3.inputs["x"]) - wg.add_link(add3.outputs[0], add4.inputs["x"]) - wg.add_link(add2.outputs["sum"], add5.inputs["x"]) - wg.add_link(add4.outputs["sum"], add5.inputs["y"]) + wg.add_link(add0.outputs.sum, add2.inputs.x) + wg.add_link(add1.outputs[0], add3.inputs.x) + wg.add_link(add3.outputs[0], add4.inputs.x) + wg.add_link(add2.outputs.sum, add5.inputs.x) + wg.add_link(add4.outputs.sum, add5.inputs["y"]) return wg diff --git a/tests/test_action.py b/tests/test_action.py index 82ad8954..bca6dcdd 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -23,20 +23,20 @@ def test_pause_play_task(wg_calcjob): wg.submit() # wait for the workgraph to launch add1 wg.wait(tasks={"add1": ["CREATED"]}, timeout=40, interval=5) - assert wg.tasks["add1"].node.process_state.value.upper() == "CREATED" - assert wg.tasks["add1"].node.process_status == "Paused through WorkGraph" + assert wg.tasks.add1.node.process_state.value.upper() == "CREATED" + assert wg.tasks.add1.node.process_status == "Paused through WorkGraph" # pause add2 after submit wg.pause_tasks(["add2"]) wg.play_tasks(["add1"]) # wait for the workgraph to launch add2 wg.wait(tasks={"add2": ["CREATED"]}, timeout=40, interval=5) - assert wg.tasks["add2"].node.process_state.value.upper() == "CREATED" - assert wg.tasks["add2"].node.process_status == "Paused through WorkGraph" + assert wg.tasks.add2.node.process_state.value.upper() == "CREATED" + assert wg.tasks.add2.node.process_status == "Paused through WorkGraph" # I disabled the following lines because the test is not stable # Seems the daemon is not responding to the play signal wg.play_tasks(["add2"]) wg.wait(interval=5) - assert wg.tasks["add2"].outputs["sum"].value == 9 + assert wg.tasks.add2.outputs.sum.value == 9 def test_pause_play_error_handler(wg_calcjob, finished_process_node): diff --git a/tests/test_awaitable_task.py b/tests/test_awaitable_task.py index 3bb552a7..f10b5808 100644 --- a/tests/test_awaitable_task.py +++ b/tests/test_awaitable_task.py @@ -17,11 +17,11 @@ async def awaitable_func(x, y): wg = WorkGraph(name="test_awaitable_decorator") awaitable_func1 = wg.add_task(awaitable_func, "awaitable_func1", x=1, y=2) - add1 = wg.add_task(decorated_add, "add1", x=1, y=awaitable_func1.outputs["result"]) + add1 = wg.add_task(decorated_add, "add1", x=1, y=awaitable_func1.outputs.result) wg.run() report = get_workchain_report(wg.process, "REPORT") assert "Waiting for child processes: awaitable_func1" in report - assert add1.outputs["result"].value == 4 + assert add1.outputs.result.value == 4 def test_monitor_decorator(): @@ -60,7 +60,7 @@ def test_time_monitor(decorated_add): wg.run() report = get_workchain_report(wg.process, "REPORT") assert "Waiting for child processes: monitor1" in report - assert add1.outputs["result"].value == 3 + assert add1.outputs.result.value == 3 def test_file_monitor(decorated_add, tmp_path): @@ -84,7 +84,7 @@ async def create_test_file(filepath="/tmp/test_file_monitor.txt", t=2): wg.run() report = get_workchain_report(wg.process, "REPORT") assert "Waiting for child processes: monitor1" in report - assert add1.outputs["result"].value == 3 + assert add1.outputs.result.value == 3 @pytest.mark.usefixtures("started_daemon_client") @@ -105,7 +105,7 @@ def test_task_monitor(decorated_add): wg1.add_task(decorated_add, "add1", x=1, y=2, t=5) wg1.submit(wait=True) wg2.wait() - assert wg2.tasks["add1"].node.ctime > wg1.tasks["add1"].node.ctime + assert wg2.tasks.add1.node.ctime > wg1.tasks.add1.node.ctime @pytest.mark.usefixtures("started_daemon_client") diff --git a/tests/test_calcfunction.py b/tests/test_calcfunction.py index d6c86d00..add763b9 100644 --- a/tests/test_calcfunction.py +++ b/tests/test_calcfunction.py @@ -11,7 +11,7 @@ def test_run(wg_calcfunction: WorkGraph) -> None: print("state: ", wg.state) # print("results: ", results[]) assert wg.tasks["sumdiff2"].node.outputs.sum == 9 - assert wg.tasks["sumdiff2"].outputs["sum"].value == 9 + assert wg.tasks["sumdiff2"].outputs.sum.value == 9 @pytest.mark.usefixtures("started_daemon_client") @@ -27,4 +27,4 @@ def add(**kwargs): wg = WorkGraph("test_dynamic_inputs") wg.add_task(add, name="add1", x=orm.Int(1), y=orm.Int(2)) wg.run() - assert wg.tasks["add1"].outputs["result"].value == 3 + assert wg.tasks.add1.outputs.result.value == 3 diff --git a/tests/test_calcjob.py b/tests/test_calcjob.py index 74768f5f..ff2eb327 100644 --- a/tests/test_calcjob.py +++ b/tests/test_calcjob.py @@ -8,4 +8,4 @@ def test_submit(wg_calcjob: WorkGraph) -> None: wg = wg_calcjob wg.name = "test_submit_calcjob" wg.submit(wait=True) - assert wg.tasks["add2"].outputs["sum"].value == 9 + assert wg.tasks.add2.outputs.sum.value == 9 diff --git a/tests/test_ctx.py b/tests/test_ctx.py index bffbc872..5e44cae7 100644 --- a/tests/test_ctx.py +++ b/tests/test_ctx.py @@ -16,14 +16,14 @@ def test_workgraph_ctx(decorated_add: Callable) -> None: wg.context = {"x": Float(2), "data.y": Float(3), "array": array} add1 = wg.add_task(decorated_add, "add1", x="{{ x }}", y="{{ data.y }}") wg.add_task( - "workgraph.set_context", name="set_ctx1", key="x", value=add1.outputs["result"] + "workgraph.set_context", name="set_ctx1", key="x", value=add1.outputs.result ) get_ctx1 = wg.add_task("workgraph.get_context", name="get_ctx1", key="x") # test the task can wait for another task get_ctx1.waiting_on.add(add1) - add2 = wg.add_task(decorated_add, "add2", x=get_ctx1.outputs["result"], y=1) + add2 = wg.add_task(decorated_add, "add2", x=get_ctx1.outputs.result, y=1) wg.run() - assert add2.outputs["result"].value == 6 + assert add2.outputs.result.value == 6 @pytest.mark.usefixtures("started_daemon_client") @@ -38,6 +38,6 @@ def test_task_set_ctx(decorated_add: Callable) -> None: assert str(e) == "Keys {'resul'} are not in the outputs of this task." add1.set_context({"sum": "result"}) add2 = wg.add_task(decorated_add, "add2", y="{{ sum }}") - wg.add_link(add1.outputs[0], add2.inputs["x"]) + wg.add_link(add1.outputs[0], add2.inputs.x) wg.submit(wait=True) - assert add2.outputs["result"].value == 10 + assert add2.outputs.result.value == 10 diff --git a/tests/test_data_task.py b/tests/test_data_task.py index e2939d65..74304edf 100644 --- a/tests/test_data_task.py +++ b/tests/test_data_task.py @@ -16,7 +16,7 @@ def test_data_task(identifier, data) -> None: wg = WorkGraph("test_normal_task") task1 = wg.add_task(identifier, name="task1", value=data) wg.run() - assert task1.outputs["result"].value == data + assert task1.outputs.result.value == data def test_data_dict_task(): @@ -25,7 +25,7 @@ def test_data_dict_task(): wg = WorkGraph("test_data_dict_task") task1 = wg.add_task("workgraph.aiida_dict", name="task1", value={"a": 1}) wg.run() - assert task1.outputs["result"].value == {"a": 1} + assert task1.outputs.result.value == {"a": 1} def test_data_list_task(): @@ -34,4 +34,4 @@ def test_data_list_task(): wg = WorkGraph("test_data_list_task") task1 = wg.add_task("workgraph.aiida_list", name="task1", value=[1, 2, 3]) wg.run() - assert task1.outputs["result"].value == [1, 2, 3] + assert task1.outputs.result.value == [1, 2, 3] diff --git a/tests/test_decorator.py b/tests/test_decorator.py index 5e9b1fa6..2ef736ba 100644 --- a/tests/test_decorator.py +++ b/tests/test_decorator.py @@ -192,7 +192,7 @@ def test_decorator_calcfunction(decorated_add: Callable) -> None: wg = WorkGraph(name="test_decorator_calcfunction") wg.add_task(decorated_add, "add1", x=2, y=3) wg.submit(wait=True, timeout=100) - assert wg.tasks["add1"].outputs["result"].value == 5 + assert wg.tasks.add1.outputs.result.value == 5 def test_decorator_workfunction(decorated_add_multiply: Callable) -> None: @@ -201,7 +201,7 @@ def test_decorator_workfunction(decorated_add_multiply: Callable) -> None: wg = WorkGraph(name="test_decorator_workfunction") wg.add_task(decorated_add_multiply, "add_multiply1", x=2, y=3, z=4) wg.submit(wait=True, timeout=100) - assert wg.tasks["add_multiply1"].outputs["result"].value == 20 + assert wg.tasks["add_multiply1"].outputs.result.value == 20 @pytest.mark.usefixtures("started_daemon_client") @@ -211,10 +211,10 @@ def test_decorator_graph_builder(decorated_add_multiply_group: Callable) -> None add1 = wg.add_task("workgraph.test_add", "add1", x=2, y=3) add_multiply1 = wg.add_task(decorated_add_multiply_group, "add_multiply1", y=3, z=4) sum_diff1 = wg.add_task("workgraph.test_sum_diff", "sum_diff1") - wg.add_link(add1.outputs[0], add_multiply1.inputs["x"]) - wg.add_link(add_multiply1.outputs["result"], sum_diff1.inputs["x"]) + wg.add_link(add1.outputs[0], add_multiply1.inputs.x) + wg.add_link(add_multiply1.outputs.result, sum_diff1.inputs.x) # use run to check if graph builder workgraph can be submit inside the engine wg.run() assert wg.tasks["add_multiply1"].process.outputs.result.value == 32 - assert wg.tasks["add_multiply1"].outputs["result"].value == 32 - assert wg.tasks["sum_diff1"].outputs["sum"].value == 32 + assert wg.tasks["add_multiply1"].outputs.result.value == 32 + assert wg.tasks["sum_diff1"].outputs.sum.value == 32 diff --git a/tests/test_engine.py b/tests/test_engine.py index 04c4fea5..fc99a95c 100644 --- a/tests/test_engine.py +++ b/tests/test_engine.py @@ -50,4 +50,4 @@ def test_max_number_jobs(add_code) -> None: wg.submit(wait=True, timeout=40) report = get_workchain_report(wg.process, "REPORT") assert "tasks ready to run: add2" in report - wg.tasks["add2"].outputs["sum"].value == 2 + wg.tasks.add2.outputs.sum.value == 2 diff --git a/tests/test_error_handler.py b/tests/test_error_handler.py index 007484d0..d2400811 100644 --- a/tests/test_error_handler.py +++ b/tests/test_error_handler.py @@ -14,7 +14,7 @@ def handle_negative_sum(task: Task): # modify task inputs task.set( { - "x": orm.Int(abs(task.inputs["x"].value)), + "x": orm.Int(abs(task.inputs.x.value)), "y": orm.Int(abs(task.inputs["y"].value)), } ) @@ -44,4 +44,4 @@ def handle_negative_sum(task: Task): ) report = get_workchain_report(wg.process, "REPORT") assert "Run error handler: handle_negative_sum." in report - assert wg.tasks["add1"].outputs["sum"].value == 3 + assert wg.tasks.add1.outputs.sum.value == 3 diff --git a/tests/test_failed_node.py b/tests/test_failed_node.py index 9849c42a..edc5be26 100644 --- a/tests/test_failed_node.py +++ b/tests/test_failed_node.py @@ -11,7 +11,7 @@ def test_failed_node(decorated_sqrt: Callable, decorated_add: Callable) -> None: wg = WorkGraph(name="test_failed_node") wg.add_task(decorated_add, "add1", x=Float(1), y=Float(2)) sqrt1 = wg.add_task(decorated_sqrt, "sqrt1", x=Float(-1)) - wg.add_task(decorated_sqrt, "sqrt2", x=sqrt1.outputs["result"]) + wg.add_task(decorated_sqrt, "sqrt2", x=sqrt1.outputs.result) wg.submit(wait=True) # print("results: ", results[]) assert wg.process.exit_status == 302 diff --git a/tests/test_for.py b/tests/test_for.py index fdd6fa47..d70adaab 100644 --- a/tests/test_for.py +++ b/tests/test_for.py @@ -22,7 +22,7 @@ def add_multiply_for(sequence): add1 = wg.add_task(decorated_add, name="add1", x="{{ total }}") # update the context variable add1.set_context({"total": "result"}) - wg.add_link(multiply1.outputs["result"], add1.inputs["y"]) + wg.add_link(multiply1.outputs.result, add1.inputs["y"]) # don't forget to return the workgraph return wg @@ -30,6 +30,6 @@ def add_multiply_for(sequence): wg = WorkGraph("test_for") for1 = wg.add_task(add_multiply_for, sequence=range(5)) add1 = wg.add_task(decorated_add, name="add1", y=orm.Int(1)) - wg.add_link(for1.outputs["result"], add1.inputs["x"]) + wg.add_link(for1.outputs.result, add1.inputs.x) wg.submit(wait=True, timeout=200) assert add1.node.outputs.result.value == 21 diff --git a/tests/test_if.py b/tests/test_if.py index 458810bd..c63b03b8 100644 --- a/tests/test_if.py +++ b/tests/test_if.py @@ -7,16 +7,16 @@ def test_if_task(decorated_add, decorated_multiply, decorated_compare): wg = WorkGraph("test_if") add1 = wg.add_task(decorated_add, name="add1", x=1, y=1) condition1 = wg.add_task(decorated_compare, name="condition1", x=1, y=0) - add2 = wg.add_task(decorated_add, name="add2", x=add1.outputs["result"], y=2) - if1 = wg.add_task("If", name="if_true", conditions=condition1.outputs["result"]) + add2 = wg.add_task(decorated_add, name="add2", x=add1.outputs.result, y=2) + if1 = wg.add_task("If", name="if_true", conditions=condition1.outputs.result) if1.children.add("add2") multiply1 = wg.add_task( - decorated_multiply, name="multiply1", x=add1.outputs["result"], y=2 + decorated_multiply, name="multiply1", x=add1.outputs.result, y=2 ) if2 = wg.add_task( "If", name="if_false", - conditions=condition1.outputs["result"], + conditions=condition1.outputs.result, invert_condition=True, ) if2.children.add("multiply1") @@ -24,13 +24,13 @@ def test_if_task(decorated_add, decorated_multiply, decorated_compare): select1 = wg.add_task( "workgraph.select", name="select1", - true=add2.outputs["result"], - false=multiply1.outputs["result"], - condition=condition1.outputs["result"], + true=add2.outputs.result, + false=multiply1.outputs.result, + condition=condition1.outputs.result, ) - add3 = wg.add_task(decorated_add, name="add3", x=select1.outputs["result"], y=1) + add3 = wg.add_task(decorated_add, name="add3", x=select1.outputs.result, y=1) wg.run() - assert add3.outputs["result"].value == 5 + assert add3.outputs.result.value == 5 def test_empty_if_task(): diff --git a/tests/test_link.py b/tests/test_link.py index 54a189bd..87f86592 100644 --- a/tests/test_link.py +++ b/tests/test_link.py @@ -20,10 +20,10 @@ def sum(**datas): float2 = wg.add_task("workgraph.aiida_node", pk=Float(2.0).store().pk) float3 = wg.add_task("workgraph.aiida_node", pk=Float(3.0).store().pk) sum1 = wg.add_task(sum, "sum1") - sum1.inputs["datas"]._link_limit = 100 - wg.add_link(float1.outputs[0], sum1.inputs["datas"]) - wg.add_link(float2.outputs[0], sum1.inputs["datas"]) - wg.add_link(float3.outputs[0], sum1.inputs["datas"]) + sum1.inputs.datas._link_limit = 100 + wg.add_link(float1.outputs[0], sum1.inputs.datas) + wg.add_link(float2.outputs[0], sum1.inputs.datas) + wg.add_link(float3.outputs[0], sum1.inputs.datas) # wg.submit(wait=True) wg.run() assert sum1.node.outputs.result.value == 6 diff --git a/tests/test_normal_function.py b/tests/test_normal_function.py index 0b2cb5c8..21d06188 100644 --- a/tests/test_normal_function.py +++ b/tests/test_normal_function.py @@ -10,9 +10,9 @@ def test_normal_function_run( wg = WorkGraph(name="test_normal_function_run") add1 = wg.add_task(decorated_normal_add, "add1", x=2, y=3) add2 = wg.add_task(decorated_add, "add2", x=6) - wg.add_link(add1.outputs["result"], add2.inputs["y"]) + wg.add_link(add1.outputs.result, add2.inputs["y"]) wg.run() - assert wg.tasks["add2"].node.outputs.result == 11 + assert wg.tasks.add2.node.outputs.result == 11 @pytest.mark.usefixtures("started_daemon_client") @@ -23,6 +23,6 @@ def test_normal_function_submit( wg = WorkGraph(name="test_normal_function_submit") add1 = wg.add_task(decorated_normal_add, "add1", x=2, y=3) add2 = wg.add_task(decorated_add, "add2", x=6) - wg.add_link(add1.outputs["result"], add2.inputs["y"]) + wg.add_link(add1.outputs.result, add2.inputs["y"]) wg.submit(wait=True) - assert wg.tasks["add2"].node.outputs.result == 11 + assert wg.tasks.add2.node.outputs.result == 11 diff --git a/tests/test_pythonjob.py b/tests/test_pythonjob.py index 1302a207..50645178 100644 --- a/tests/test_pythonjob.py +++ b/tests/test_pythonjob.py @@ -33,19 +33,19 @@ def multiply(x: Any, y: Any) -> Any: wg.add_task( decorted_multiply, name="multiply1", - x=wg.tasks["add1"].outputs["sum"], + x=wg.tasks.add1.outputs.sum, y=3, computer="localhost", command_info={"label": python_executable_path}, ) # wg.submit(wait=True) wg.run() - assert wg.tasks["add1"].outputs["sum"].value.value == 3 - assert wg.tasks["add1"].outputs["diff"].value.value == -1 - assert wg.tasks["multiply1"].outputs["result"].value.value == 9 + assert wg.tasks.add1.outputs.sum.value.value == 3 + assert wg.tasks.add1.outputs["diff"].value.value == -1 + assert wg.tasks.multiply1.outputs.result.value.value == 9 # process_label and label - assert wg.tasks["add1"].node.process_label == "PythonJob" - assert wg.tasks["add1"].node.label == "add1" + assert wg.tasks.add1.node.process_label == "PythonJob" + assert wg.tasks.add1.node.label == "add1" def test_PythonJob_kwargs(fixture_localhost, python_executable_path): @@ -72,10 +72,10 @@ def add(x, y=1, **kwargs): ) # data inside the kwargs should be serialized separately wg.process.inputs.wg.tasks.add1.inputs.kwargs.sockets.m.property.value == 2 - assert wg.tasks["add1"].outputs["result"].value.value == 8 + assert wg.tasks.add1.outputs.result.value.value == 8 # load the workgraph wg = WorkGraph.load(wg.pk) - assert wg.tasks["add1"].inputs["kwargs"]._value == {"m": 2, "n": 3} + assert wg.tasks.add1.inputs["kwargs"]._value == {"m": 2, "n": 3} def test_PythonJob_namespace_output_input(fixture_localhost, python_executable_path): @@ -176,11 +176,11 @@ def multiply(x_folder_name, y_folder_name): name="multiply", ) wg.add_link( - wg.tasks["add1"].outputs["remote_folder"], + wg.tasks.add1.outputs.remote_folder, wg.tasks["multiply"].inputs["copy_files"], ) wg.add_link( - wg.tasks["add2"].outputs["remote_folder"], + wg.tasks.add2.outputs.remote_folder, wg.tasks["multiply"].inputs["copy_files"], ) # ------------------------- Submit the calculation ------------------- @@ -206,7 +206,7 @@ def multiply(x_folder_name, y_folder_name): }, }, ) - assert wg.tasks["multiply"].outputs["result"].value.value == 25 + assert wg.tasks["multiply"].outputs.result.value.value == 25 def test_load_pythonjob(fixture_localhost, python_executable_path): @@ -230,10 +230,10 @@ def add(x: str, y: str) -> str: }, # wait=True, ) - assert wg.tasks["add"].outputs["result"].value.value == "Hello, World!" + assert wg.tasks.add.outputs.result.value.value == "Hello, World!" wg = WorkGraph.load(wg.pk) - wg.tasks["add"].inputs["x"].value = "Hello, " - wg.tasks["add"].inputs["y"].value = "World!" + wg.tasks.add.inputs.x.value = "Hello, " + wg.tasks.add.inputs["y"].value = "World!" def test_exit_code(fixture_localhost, python_executable_path): @@ -247,7 +247,7 @@ def handle_negative_sum(task: Task): task.set( { - "x": abs(task.inputs["x"].value), + "x": abs(task.inputs.x.value), "y": abs(task.inputs["y"].value), } ) @@ -284,5 +284,5 @@ def add(x: array, y: array) -> array: == "Some elements are negative" ) # the final task should have exit status 0 - assert wg.tasks["add1"].node.exit_status == 0 - assert (wg.tasks["add1"].outputs["sum"].value.value == array([2, 3])).all() + assert wg.tasks.add1.node.exit_status == 0 + assert (wg.tasks.add1.outputs.sum.value.value == array([2, 3])).all() diff --git a/tests/test_shell.py b/tests/test_shell.py index c0e90757..ce15ca7c 100644 --- a/tests/test_shell.py +++ b/tests/test_shell.py @@ -112,7 +112,7 @@ def parser(dirpath): name="job2", command="bc", arguments=["{expression}"], - nodes={"expression": job1.outputs["stdout"]}, + nodes={"expression": job1.outputs.stdout}, parser=parser, parser_outputs=[ {"identifier": "workgraph.any", "name": "result"} @@ -123,4 +123,4 @@ def parser(dirpath): wg = WorkGraph(name="test_shell_graph_builder") add_multiply1 = wg.add_task(add_multiply, x=Int(2), y=Int(3)) wg.submit(wait=True) - assert add_multiply1.outputs["result"].value.value == 5 + assert add_multiply1.outputs.result.value.value == 5 diff --git a/tests/test_socket.py b/tests/test_socket.py index 34f00b5e..ac6ba4e2 100644 --- a/tests/test_socket.py +++ b/tests/test_socket.py @@ -30,8 +30,8 @@ def test_type_mapping(data_type, data, identifier) -> None: def add(x: data_type): pass - assert add.task().inputs["x"]._identifier == identifier - assert add.task().inputs["x"].property.identifier == identifier + assert add.task().inputs.x._identifier == identifier + assert add.task().inputs.x.property.identifier == identifier add_task = add.task() add_task.set({"x": data}) # test set data from context @@ -71,8 +71,8 @@ def test_aiida_data_socket() -> None: def add(x: data_type): pass - assert add.task().inputs["x"]._identifier == identifier - assert add.task().inputs["x"].property.identifier == identifier + assert add.task().inputs.x._identifier == identifier + assert add.task().inputs.x.property.identifier == identifier add_task = add.task() add_task.set({"x": data}) # test set data from context @@ -156,7 +156,7 @@ def my_task(x: data_type): pass my_task1 = wg.add_task(my_task, name="my_task", x=socket_value) - socket = my_task1.inputs["x"] + socket = my_task1.inputs.x socket_node_value = socket.get_node_value() assert isinstance(socket_node_value, type(node_value)) diff --git a/tests/test_task_from_workgraph.py b/tests/test_task_from_workgraph.py index 18a5e379..d93d24a8 100644 --- a/tests/test_task_from_workgraph.py +++ b/tests/test_task_from_workgraph.py @@ -25,9 +25,7 @@ def test_build_task_from_workgraph(decorated_add: Callable) -> None: # create a sub workgraph sub_wg = WorkGraph("build_task_from_workgraph") sub_wg.add_task(decorated_add, name="add1", x=1, y=3) - sub_wg.add_task( - decorated_add, name="add2", x=2, y=sub_wg.tasks["add1"].outputs["result"] - ) + sub_wg.add_task(decorated_add, name="add2", x=2, y=sub_wg.tasks.add1.outputs.result) # wg = WorkGraph("build_task_from_workgraph") add1_task = wg.add_task(decorated_add, name="add1", x=1, y=3) @@ -35,8 +33,8 @@ def test_build_task_from_workgraph(decorated_add: Callable) -> None: # the default value of the namespace is None assert wg_task.inputs["add1"]._value == {} wg.add_task(decorated_add, name="add2", y=3) - wg.add_link(add1_task.outputs["result"], wg_task.inputs["add1.x"]) - wg.add_link(wg_task.outputs["add2.result"], wg.tasks["add2"].inputs["x"]) + wg.add_link(add1_task.outputs.result, wg_task.inputs["add1.x"]) + wg.add_link(wg_task.outputs["add2.result"], wg.tasks.add2.inputs.x) assert len(wg_task.inputs) == 3 assert len(wg_task.outputs) == 4 # wg.submit(wait=True) diff --git a/tests/test_tasks.py b/tests/test_tasks.py index 2b33f0b6..9c7cf378 100644 --- a/tests/test_tasks.py +++ b/tests/test_tasks.py @@ -15,12 +15,12 @@ def sum_diff(x, y): wg = WorkGraph("test_normal_task") task1 = wg.add_task(sum_diff, name="sum_diff", x=2, y=3) task2 = wg.add_task( - decorated_add, name="add", x=task1.outputs["sum"], y=task1.outputs["diff"] + decorated_add, name="add", x=task1.outputs.sum, y=task1.outputs["diff"] ) wg.run() print("node: ", task2.node.outputs.result) wg.update() - assert task2.outputs["result"].value == 4 + assert task2.outputs.result.value == 4 def test_task_collection(decorated_add: Callable) -> None: @@ -67,7 +67,7 @@ def test_set_non_dynamic_namespace_socket(decorated_add) -> None: task2 = wg.add_task(WorkChainWithNestNamespace) task2.set( { - "non_dynamic_port": {"a": task1.outputs["result"], "b": orm.Int(2)}, + "non_dynamic_port": {"a": task1.outputs.result, "b": orm.Int(2)}, } ) assert len(task2.inputs["non_dynamic_port.a"]._links) == 1 @@ -84,7 +84,7 @@ def test_set_namespace_socket(decorated_add) -> None: task2 = wg.add_task(WorkChainWithNestNamespace) task2.set( { - "add": {"x": task1.outputs["result"], "y": orm.Int(2)}, + "add": {"x": task1.outputs.result, "y": orm.Int(2)}, } ) assert len(task2.inputs["add.x"]._links) == 1 @@ -108,8 +108,8 @@ def test_set_dynamic_port_input(decorated_add) -> None: dynamic_port={ "input1": None, "input2": orm.Int(2), - "input3": task1.outputs["result"], - "nested": {"input4": orm.Int(4), "input5": task1.outputs["result"]}, + "input3": task1.outputs.result, + "nested": {"input4": orm.Int(4), "input5": task1.outputs.result}, }, ) wg.add_link(task1.outputs["_wait"], task2.inputs["dynamic_port.input1"]) @@ -154,7 +154,7 @@ def test_set_inputs_from_builder(add_code) -> None: builder.x = 1 builder.y = 2 add1.set_from_builder(builder) - assert add1.inputs["x"].value == 1 + assert add1.inputs.x.value == 1 assert add1.inputs["y"].value == 2 assert add1.inputs["code"].value == add_code with pytest.raises( diff --git a/tests/test_while.py b/tests/test_while.py index 6c677e85..6644ae79 100644 --- a/tests/test_while.py +++ b/tests/test_while.py @@ -47,37 +47,33 @@ def raw_python_code(): # --------------------------------------------------------------------- # the `result` of compare1 taskis used as condition compare1 = wg.add_task(decorated_compare, name="compare1", x="{{m}}", y=10) - while1 = wg.add_task("While", name="while1", conditions=compare1.outputs["result"]) + while1 = wg.add_task("While", name="while1", conditions=compare1.outputs.result) add11 = wg.add_task(decorated_add, name="add11", x=1, y=1) # --------------------------------------------------------------------- compare2 = wg.add_task(decorated_compare, name="compare2", x="{{n}}", y=5) - while2 = wg.add_task("While", name="while2", conditions=compare2.outputs["result"]) - add21 = wg.add_task( - decorated_add, name="add21", x="{{n}}", y=add11.outputs["result"] - ) + while2 = wg.add_task("While", name="while2", conditions=compare2.outputs.result) + add21 = wg.add_task(decorated_add, name="add21", x="{{n}}", y=add11.outputs.result) add21.waiting_on.add("add1") - add22 = wg.add_task(decorated_add, name="add22", x=add21.outputs["result"], y=1) + add22 = wg.add_task(decorated_add, name="add22", x=add21.outputs.result, y=1) add22.set_context({"n": "result"}) while2.children.add(["add21", "add22"]) # --------------------------------------------------------------------- compare3 = wg.add_task(decorated_compare, name="compare3", x="{{l}}", y=5) while3 = wg.add_task( - "While", name="while3", max_iterations=1, conditions=compare3.outputs["result"] + "While", name="while3", max_iterations=1, conditions=compare3.outputs.result ) add31 = wg.add_task(decorated_add, name="add31", x="{{l}}", y=1) add31.waiting_on.add("add22") - add32 = wg.add_task(decorated_add, name="add32", x=add31.outputs["result"], y=1) + add32 = wg.add_task(decorated_add, name="add32", x=add31.outputs.result, y=1) add32.set_context({"l": "result"}) while3.children.add(["add31", "add32"]) # --------------------------------------------------------------------- - add12 = wg.add_task( - decorated_add, name="add12", x="{{m}}", y=add32.outputs["result"] - ) + add12 = wg.add_task(decorated_add, name="add12", x="{{m}}", y=add32.outputs.result) add12.set_context({"m": "result"}) while1.children.add(["add11", "while2", "while3", "add12", "compare2", "compare3"]) # --------------------------------------------------------------------- add2 = wg.add_task( - decorated_add, name="add2", x=add12.outputs["result"], y=add31.outputs["result"] + decorated_add, name="add2", x=add12.outputs.result, y=add31.outputs.result ) # wg.submit(wait=True, timeout=100) wg.run() @@ -85,7 +81,7 @@ def raw_python_code(): for link in wg.process.base.links.get_outgoing().all(): if isinstance(link.node, orm.ProcessNode): print(link.node.label, link.node.outputs.result) - assert add2.outputs["result"].value.value == raw_python_code().value + assert add2.outputs.result.value.value == raw_python_code().value @pytest.mark.usefixtures("started_daemon_client") @@ -102,10 +98,10 @@ def test_while_workgraph(decorated_add, decorated_multiply, decorated_compare): ) add1 = wg.add_task(decorated_add, name="add1", y=3) add1.set_context({"n": "result"}) - wg.add_link(multiply1.outputs["result"], add1.inputs["x"]) + wg.add_link(multiply1.outputs.result, add1.inputs.x) wg.submit(wait=True, timeout=100) assert wg.execution_count == 4 - assert wg.tasks["add1"].outputs["result"].value == 29 + assert wg.tasks.add1.outputs.result.value == 29 @pytest.mark.usefixtures("started_daemon_client") @@ -126,7 +122,7 @@ def my_while(n=0, limit=100): ) add1 = wg.add_task(decorated_add, name="add1", y=3) add1.set_context({"n": "result"}) - wg.add_link(multiply1.outputs["result"], add1.inputs["x"]) + wg.add_link(multiply1.outputs.result, add1.inputs.x) return wg # ----------------------------------------- @@ -134,8 +130,8 @@ def my_while(n=0, limit=100): add1 = wg.add_task(decorated_add, name="add1", x=orm.Int(25), y=orm.Int(25)) my_while1 = wg.add_task(my_while, n=orm.Int(1)) add2 = wg.add_task(decorated_add, name="add2", y=orm.Int(2)) - wg.add_link(add1.outputs["result"], my_while1.inputs["limit"]) - wg.add_link(my_while1.outputs["result"], add2.inputs["x"]) + wg.add_link(add1.outputs.result, my_while1.inputs["limit"]) + wg.add_link(my_while1.outputs.result, add2.inputs.x) wg.submit(wait=True, timeout=100) - assert add2.outputs["result"].value < 31 + assert add2.outputs.result.value < 31 assert my_while1.node.outputs.execution_count == 2 diff --git a/tests/test_workgraph.py b/tests/test_workgraph.py index e335ae56..1badd386 100644 --- a/tests/test_workgraph.py +++ b/tests/test_workgraph.py @@ -9,9 +9,7 @@ def test_from_dict(decorated_add): """Export NodeGraph to dict.""" wg = WorkGraph("test_from_dict") task1 = wg.add_task(decorated_add, x=2, y=3) - wg.add_task( - "workgraph.test_sum_diff", name="sumdiff2", x=4, y=task1.outputs["result"] - ) + wg.add_task("workgraph.test_sum_diff", name="sumdiff2", x=4, y=task1.outputs.result) wgdata = wg.to_dict() wg1 = WorkGraph.from_dict(wgdata) assert len(wg.tasks) == len(wg1.tasks) @@ -23,7 +21,7 @@ def test_add_task(): wg = WorkGraph("test_add_task") add1 = wg.add_task(ArithmeticAddCalculation, name="add1") add2 = wg.add_task(ArithmeticAddCalculation, name="add2") - wg.add_link(add1.outputs["sum"], add2.inputs["x"]) + wg.add_link(add1.outputs.sum, add2.inputs.x) assert len(wg.tasks) == 2 assert len(wg.links) == 1 @@ -62,12 +60,12 @@ def test_save_load(wg_calcfunction, decorated_add): wg2 = WorkGraph.load(wg.process.pk) assert len(wg.tasks) == len(wg2.tasks) # check the executor of the decorated task - callable = wg2.tasks["add1"].get_executor()["callable"] + callable = wg2.tasks.add1.get_executor()["callable"] assert isinstance(callable, PickledFunction) assert callable.value(1, 2) == 3 # TODO, the following code is not working # wg2.save() - # assert wg2.tasks["add1"].executor == decorated_add + # assert wg2.tasks.add1.executor == decorated_add # remove the extra, will raise an error wg.process.base.extras.delete(WORKGRAPH_EXTRA_KEY) with pytest.raises( @@ -118,7 +116,7 @@ def test_reset_message(wg_calcjob): # wait for the daemon to start the workgraph time.sleep(3) wg = WorkGraph.load(wg.process.pk) - wg.tasks["add2"].set({"y": orm.Int(10).store()}) + wg.tasks.add2.set({"y": orm.Int(10).store()}) wg.save() wg.wait() report = get_workchain_report(wg.process, "REPORT") @@ -135,7 +133,7 @@ def test_restart_and_reset(wg_calcfunction): "workgraph.test_sum_diff", "sumdiff3", x=4, - y=wg.tasks["sumdiff2"].outputs["sum"], + y=wg.tasks["sumdiff2"].outputs.sum, ) wg.name = "test_restart_0" wg.submit(wait=True) @@ -168,7 +166,7 @@ def test_extend_workgraph(decorated_add_multiply_group): assert "group_add1" in [ task.name for task in wg.tasks["group_multiply1"].waiting_on ] - wg.add_link(add1.outputs[0], wg.tasks["group_add1"].inputs["x"]) + wg.add_link(add1.outputs[0], wg.tasks["group_add1"].inputs.x) wg.run() assert wg.tasks["group_multiply1"].node.outputs.result == 45 diff --git a/tests/test_zone.py b/tests/test_zone.py index 007e286e..b46d575d 100644 --- a/tests/test_zone.py +++ b/tests/test_zone.py @@ -9,9 +9,9 @@ def test_zone_task(decorated_add): wg.context = {} add1 = wg.add_task(decorated_add, name="add1", x=1, y=1) wg.add_task(decorated_add, name="add2", x=1, y=1) - add3 = wg.add_task(decorated_add, name="add3", x=1, y=add1.outputs["result"]) - wg.add_task(decorated_add, name="add4", x=1, y=add3.outputs["result"]) - wg.add_task(decorated_add, name="add5", x=1, y=add3.outputs["result"]) + add3 = wg.add_task(decorated_add, name="add3", x=1, y=add1.outputs.result) + wg.add_task(decorated_add, name="add4", x=1, y=add3.outputs.result) + wg.add_task(decorated_add, name="add5", x=1, y=add3.outputs.result) zone1 = wg.add_task("workgraph.zone", name="Zone1") zone1.children.add(["add2", "add3"]) wg.run() diff --git a/tests/widget/test_widget.py b/tests/widget/test_widget.py index c7cb34a8..44307330 100644 --- a/tests/widget/test_widget.py +++ b/tests/widget/test_widget.py @@ -14,7 +14,7 @@ def test_workgraph_widget(wg_calcfunction, decorated_add): assert len(value["links"]) == 2 # check required sockets # there are more than 2 inputs, but only 2 are required - assert len(wg.tasks["add1"].inputs) > 2 + assert len(wg.tasks.add1.inputs) > 2 assert len(value["nodes"]["add1"]["inputs"]) == 2 # to_html data = wg.to_html()