Skip to content

Implement serialization to Galaxy Format 2 - #3

Merged
loichuder merged 1 commit into
mainfrom
impl-serialize
Mar 9, 2026
Merged

loichuder merged 1 commit into
mainfrom
impl-serialize

Conversation

@loichuder

@loichuder loichuder commented Mar 3, 2026 •

Copy link
Copy Markdown
Member

For #1

Based on https://galaxyproject.github.io/gxformat2/v19_09.html

The workflow from test_engine imports fine in Galaxy so I guess that's a win?

Here is the converted workflow for reference:

class: GalaxyWorkflow
id: galaxy_test
inputs: []
label: An Ewoks workflow to test Galaxy
outputs: []
steps:
- out: []
  state: {a: 1}
  tool_id: ewokscore.tests.examples.tasks.sumtask.SumTask
  type: tool
- out: []
  state: {b: 2}
  tool_id: ewokscore.tests.examples.tasks.sumtask.SumTask
  type: tool
- in:
    a: {source: 0/result}
    b: {source: 1/result}
    delay: {source: 1/result}
  out: []
  state: {b: 1}
  tool_id: ewokscore.tests.examples.tasks.sumtask.SumTask
  type: tool

Comment thread pyproject.toml
force-single-line = true

[project.entry-points."ewoks.engines"]
"gxwf" = "ewoksgalaxy.engine:GalaxyWorkflowEngine"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I choose gxwf to reuse the acronym from the gxformat2 package: https://github.com/galaxyproject/gxformat2?tab=readme-ov-file#gxformat2

I dismissed the other alternative .ga since it refers to the "classic" Galaxy format for which there is no spec.

Comment thread pyproject.toml
[tool.ruff.lint.per-file-ignores]
# Ignore `S101` (assert used violations) in all test files
"*/test_*.py" = ["S101"]
"*/test_*.py" = ["S101", "S603"]

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To allow subprocess.run in the tests

Comment thread pyproject.toml Outdated
]
requires-python = ">=3.10"
dependencies = ["ewokscore"]
dependencies = ["ewokscore", "ruamel.yaml", "gxformat2"]

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gxformat2 is only used in the tests for now to lint the converted workflows but I plan to use it in the functional code later.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I didn't realize that pyyaml was part of the deps of ewokscore. I'll replace ruamel.yaml for pyyaml after the review.

Comment thread src/ewoksgalaxy/io.py
Comment on lines +45 to +46
"inputs": [], # TODO
"outputs": [], # TODO

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the specs, these are required but I am still unsure about what to put inside.

Comment thread src/ewoksgalaxy/io.py
if label is not None:
step["label"] = label

default_inputs = node.get("default_inputs")

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "state" of a tool can be stored in tool_state (raw JSON string) or in state (structured YAML mapping).

I choose to store in state to ease readability.

@loichuder
loichuder force-pushed the impl-serialize branch 2 times, most recently from eab80ac to 8c85bbc Compare March 3, 2026 14:52
Comment thread src/ewoksgalaxy/io.py
galaxy_step_indices: dict[str, int] = {}
for i, node in enumerate(graph_dict["nodes"]):
steps.append(_ewoks_node_to_galaxy_step(node))
galaxy_step_indices[node["id"]] = i

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As Orange, Galaxy can only have integers as id. Steps can be stored either as a map with int as keys or an array. I chose the latter.

Note that I keep a mapping between ewoks ids (str) and galaxy ids (int) so I can correctly distribute the data mapping when converting links to galaxy inputs.

Comment thread src/ewoksgalaxy/io.py
if "in" not in steps[target_id]:
steps[target_id]["in"] = {}
steps[target_id]["in"].update(
_ewoks_link_to_galaxy_input(link, galaxy_step_indices)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Data mapping in Galaxy is included in the target node under in key.

The in value is a dictionary with target_input as key and {source: id/source_output} as value:

- in:
    a: {source: 0/result}
    b: {source: 1/result}
    delay: {source: 1/result}

@loichuder
loichuder requested a review from woutdenolf March 3, 2026 14:54
Comment thread src/ewoksgalaxy/engine.py
Comment thread src/ewoksgalaxy/tests/test_io.py
@loichuder
loichuder force-pushed the impl-serialize branch 3 times, most recently from 2412ab1 to f07e3b3 Compare March 6, 2026 07:51
@codecov

codecov Bot commented Mar 6, 2026

Copy link
Copy Markdown

Welcome to Codecov 🎉

Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests.

ℹ️ You can also turn on project coverage checks and project coverage reporting on Pull Request comment

Thanks for integrating Codecov - We've got you covered ☂️

@loichuder
loichuder merged commit 1b7b6e9 into main Mar 9, 2026
8 checks passed
@loichuder
loichuder deleted the impl-serialize branch March 9, 2026 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants