Simple Example¶
Let's have a look at the different PlantUML diagrams that the cwl2puml APIs are able to generate, given, for example, the conditional-workflows Workflow.
1. Parsing¶
It is needed to read first a CWL document from a remote public URL:
In [1]:
Copied!
import cwl_loader
cwl_document = cwl_loader.load_cwl_from_location('https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl')
import cwl_loader
cwl_document = cwl_loader.load_cwl_from_location('https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl')
2026-06-26 12:47:20.079 | DEBUG | cwl_loader:load_cwl_from_location:369 - Loading CWL document from https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl...
2026-06-26 12:47:20.294 | DEBUG | cwl_loader:_load_cwl_from_stream:372 - Reading stream from https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl...
2026-06-26 12:47:20.317 | DEBUG | cwl_loader:load_cwl_from_stream:339 - CWL data of type <class 'ruamel.yaml.comments.CommentedMap'> successfully loaded from stream
2026-06-26 12:47:20.318 | DEBUG | cwl_loader:load_cwl_from_yaml:270 - No needs to update the Raw CWL document since it targets already the v1.2
2026-06-26 12:47:20.318 | DEBUG | cwl_loader:load_cwl_from_yaml:274 - Parsing the raw CWL document to the CWL Utils DOM...
2026-06-26 12:47:20.576 | DEBUG | cwl_loader:load_cwl_from_yaml:283 - Raw CWL document successfully parsed to the CWL Utils DOM!
2026-06-26 12:47:20.577 | DEBUG | cwl_loader:load_cwl_from_yaml:285 - Dereferencing the steps[].run...
2026-06-26 12:47:20.577 | DEBUG | cwl_loader:_on_process:175 - Checking if https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl#stac must be externally imported...
2026-06-26 12:47:20.578 | DEBUG | cwl_loader:_on_process:179 - run_url: https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl - uri: https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl
2026-06-26 12:47:20.578 | DEBUG | cwl_loader:_on_process:175 - Checking if https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl#rio_stack must be externally imported...
2026-06-26 12:47:20.579 | DEBUG | cwl_loader:_on_process:179 - run_url: https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl - uri: https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl
2026-06-26 12:47:20.579 | DEBUG | cwl_loader:_on_process:175 - Checking if https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl#rio_warp_stack must be externally imported...
2026-06-26 12:47:20.581 | DEBUG | cwl_loader:_on_process:179 - run_url: https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl - uri: https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl
2026-06-26 12:47:20.582 | DEBUG | cwl_loader:_on_process:175 - Checking if https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl#rio_color must be externally imported...
2026-06-26 12:47:20.582 | DEBUG | cwl_loader:_on_process:179 - run_url: https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl - uri: https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl
2026-06-26 12:47:20.583 | DEBUG | cwl_loader:load_cwl_from_yaml:289 - steps[].run successfully dereferenced! Dereferencing the FQNs...
2026-06-26 12:47:20.584 | DEBUG | cwl_loader:load_cwl_from_yaml:293 - CWL document successfully dereferenced! Now verifying steps[].run integrity...
2026-06-26 12:47:20.585 | DEBUG | cwl_loader:load_cwl_from_yaml:299 - All steps[].run link are resolvable!
2026-06-26 12:47:20.585 | DEBUG | cwl_loader:load_cwl_from_yaml:302 - Sorting Process instances by dependencies....
2026-06-26 12:47:20.586 | DEBUG | cwl_loader:load_cwl_from_yaml:304 - Sorting process is over.
2026-06-26 12:47:20.587 | DEBUG | cwl_loader:_load_cwl_from_stream:382 - Stream from https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl successfully load!
2. PlantUML diagrams¶
The samples below show how to render CWL document to a specific PlantUML diagram:
In [2]:
Copied!
from cwl2puml import (
to_puml,
DiagramType
)
from cwl_utils.parser import InputEnumSchema
from io import (
StringIO,
BytesIO
)
from IPython.display import display_png
from plantuml import deflate_and_encode
from PIL import Image
from urllib.request import urlopen
def render(
diagram_type: DiagramType,
debug: bool = False
):
out = StringIO()
to_puml(
cwl_document=cwl_document,
workflow_id='main', # 'main' by default, but define it for demo purposes
diagram_type=diagram_type,
output_stream=out
)
clear_output = out.getvalue()
if debug:
print(clear_output)
encoded = deflate_and_encode(clear_output)
diagram_url = f"https://uml.planttext.com/plantuml/png/{encoded}"
with urlopen(diagram_url) as url:
img = Image.open(BytesIO(url.read()))
display_png(img)
from cwl2puml import (
to_puml,
DiagramType
)
from cwl_utils.parser import InputEnumSchema
from io import (
StringIO,
BytesIO
)
from IPython.display import display_png
from plantuml import deflate_and_encode
from PIL import Image
from urllib.request import urlopen
def render(
diagram_type: DiagramType,
debug: bool = False
):
out = StringIO()
to_puml(
cwl_document=cwl_document,
workflow_id='main', # 'main' by default, but define it for demo purposes
diagram_type=diagram_type,
output_stream=out
)
clear_output = out.getvalue()
if debug:
print(clear_output)
encoded = deflate_and_encode(clear_output)
diagram_url = f"https://uml.planttext.com/plantuml/png/{encoded}"
with urlopen(diagram_url) as url:
img = Image.open(BytesIO(url.read()))
display_png(img)
In [3]:
Copied!
render(DiagramType.ACTIVITY)
render(DiagramType.ACTIVITY)
In [4]:
Copied!
render(DiagramType.COMPONENT)
render(DiagramType.COMPONENT)
In [5]:
Copied!
render(DiagramType.CLASS)
render(DiagramType.CLASS)
In [6]:
Copied!
render(DiagramType.SEQUENCE)
render(DiagramType.SEQUENCE)
In [7]:
Copied!
render(DiagramType.STATE)
render(DiagramType.STATE)