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')
2025-09-24 07:48:01.000 | DEBUG | cwl_loader:load_cwl_from_location:231 - Loading CWL document from https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl...
2025-09-24 07:48:01.089 | DEBUG | cwl_loader:_load_cwl_from_stream:234 - Reading stream from https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl...
2025-09-24 07:48:01.112 | DEBUG | cwl_loader:load_cwl_from_stream:206 - CWL data of type <class 'ruamel.yaml.comments.CommentedMap'> successfully loaded from stream
2025-09-24 07:48:01.113 | DEBUG | cwl_loader:load_cwl_from_yaml:146 - No needs to update the Raw CWL document since it targets already the v1.2
2025-09-24 07:48:01.113 | DEBUG | cwl_loader:load_cwl_from_yaml:148 - Parsing the raw CWL document to the CWL Utils DOM...
2025-09-24 07:48:01.379 | DEBUG | cwl_loader:load_cwl_from_yaml:161 - Raw CWL document successfully parsed to the CWL Utils DOM!
2025-09-24 07:48:01.379 | DEBUG | cwl_loader:load_cwl_from_yaml:163 - Dereferencing the steps[].run...
2025-09-24 07:48:01.380 | DEBUG | cwl_loader:_on_process:81 - Checking if https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl#stac must be externally imported...
2025-09-24 07:48:01.380 | DEBUG | cwl_loader:_on_process:85 - 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
2025-09-24 07:48:01.381 | DEBUG | cwl_loader:_on_process:81 - Checking if https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl#rio_stack must be externally imported...
2025-09-24 07:48:01.381 | DEBUG | cwl_loader:_on_process:85 - 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
2025-09-24 07:48:01.382 | DEBUG | cwl_loader:_on_process:81 - Checking if https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl#rio_warp_stack must be externally imported...
2025-09-24 07:48:01.382 | DEBUG | cwl_loader:_on_process:85 - 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
2025-09-24 07:48:01.382 | DEBUG | cwl_loader:_on_process:81 - Checking if https://raw.githubusercontent.com/eoap/how-to/refs/heads/main/cwl-workflows/conditional-workflows.cwl#rio_color must be externally imported...
2025-09-24 07:48:01.383 | DEBUG | cwl_loader:_on_process:85 - 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
2025-09-24 07:48:01.383 | DEBUG | cwl_loader:load_cwl_from_yaml:170 - steps[].run successfully dereferenced! Dereferencing the FQNs...
2025-09-24 07:48:01.384 | DEBUG | cwl_loader:load_cwl_from_yaml:174 - CWL document successfully dereferenced! Now verifying steps[].run integrity...
2025-09-24 07:48:01.384 | DEBUG | cwl_loader:load_cwl_from_yaml:178 - All steps[].run link are resolvable!
2025-09-24 07:48:01.384 | DEBUG | cwl_loader:load_cwl_from_yaml:181 - Sorting Process instances by dependencies....
2025-09-24 07:48:01.385 | DEBUG | cwl_loader:load_cwl_from_yaml:183 - Sorting process is over.
2025-09-24 07:48:01.385 | DEBUG | cwl_loader:_load_cwl_from_stream:243 - 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)