Skip to content

feat: draw/show SuperComponents in detail, expand it and show it's internal components in the visualisation diagram #9389

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

Merged
merged 25 commits into from
May 23, 2025

Conversation

davidsbatista
Copy link
Contributor

@davidsbatista davidsbatista commented May 15, 2025

Related Issues

Proposed Changes:

  • Added two new methods to the Pipeline
    • _find_super_components(self) - this will find all the SuperComponents in a Pipeline.
    • _merge_super_component_pipelines(self): this will expand all the SuperComponents in a pipeline. It will adjust the connections such that the internal components of a SuperComponent connect with the existing components of the Pipeline.

How did you test it?

  • unit tests, integration tests, manual verification

Notes for the reviewer

In case you want to test it, start a local mermaid server

docker run --platform linux/amd64 --publish 3000:3000 --cap-add=SYS_ADMIN ghcr.io/jihchi/mermaid.ink

Generate an image for the original pipeline, and the version with the expanded components

from pathlib import Path

from haystack import Pipeline
from haystack.components.preprocessors import DocumentPreprocessor
from haystack.components.writers import DocumentWriter
from haystack.document_stores.in_memory import InMemoryDocumentStore

document_store = InMemoryDocumentStore()

pipeline = Pipeline()
pipeline.add_component("preprocessor", DocumentPreprocessor())
pipeline.add_component("writer", DocumentWriter(document_store = document_store))
pipeline.connect("preprocessor", "writer")

# original pipeline
out_file = Path("original_pipeline.png")
pipeline.draw(out_file, server_url="http://localhost:3000")

# merged pipeline that includes all components
out_file = Path("merged_pipeline.png")
pipeline.draw(out_file, server_url="http://localhost:3000",  super_component_expansion=True)

# component by component
pp = Pipeline()
pp.add_component("splitter", DocumentSplitter())
pp.add_component("cleaner", DocumentCleaner())
pp.add_component("writer", DocumentWriter(document_store = document_store))

pp.connect("splitter.documents", "cleaner.documents")
pp.connect("cleaner", "writer")

out_file = Path("component_by_component.png")
pipeline.draw(out_file, server_url="http://localhost:3000",  super_component_expansion=True)

SuperComponent

original_pipeline

SuperComponent expanded (i.e.: super_component_expansion=True)

merged_pipeline

Pipeline with each components defined originaly

component_by_component

Checklist

  • I have read the contributors guidelines and the code of conduct
  • I have updated the related issue with new insights and changes
  • I added unit tests and updated the docstrings
  • I've used one of the conventional commit types for my PR title: fix:, feat:, build:, chore:, ci:, docs:, style:, refactor:, perf:, test: and added ! in case the PR includes breaking changes.
  • I documented my code
  • I ran pre-commit hooks and fixed any issue

@coveralls
Copy link
Collaborator

coveralls commented May 15, 2025

Pull Request Test Coverage Report for Build 15196767034

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • 67 unchanged lines in 2 files lost coverage.
  • Overall coverage decreased (-0.1%) to 90.227%

Files with Coverage Reduction New Missed Lines %
core/pipeline/base.py 26 93.51%
core/pipeline/draw.py 41 74.53%
Totals Coverage Status
Change from base Build 15186721509: -0.1%
Covered Lines: 11227
Relevant Lines: 12443

💛 - Coveralls

@davidsbatista davidsbatista changed the title Feat/draw supercomponents detail feat: draw/show SuperComponents in detail, expand it and show it's internal components in the visualisation diagram May 15, 2025
@davidsbatista davidsbatista marked this pull request as ready for review May 15, 2025 10:56
@davidsbatista davidsbatista requested review from a team as code owners May 15, 2025 10:56
@davidsbatista davidsbatista requested review from dfokina and vblagoje and removed request for a team May 15, 2025 10:56
@sjrl
Copy link
Contributor

sjrl commented May 16, 2025

Hey @davidsbatista could you also add the mermaid picture of your example? I think that would help with the review

@davidsbatista
Copy link
Contributor Author

@sjrl I've also added a version of the same pipeline, but defining each component, no SuperComponents used

@sjrl
Copy link
Contributor

sjrl commented May 20, 2025

Thanks @davidsbatista it's looking good! Looking back at the original issue do you think it would be possible to add this dotted box around where the super component is in the expanded view?

@davidsbatista
Copy link
Contributor Author

@sjrl did you do that yourself or the community member? Just to understand if that was programmatically or "photoshopped"

@sjrl
Copy link
Contributor

sjrl commented May 20, 2025

@sjrl did you do that yourself or the community member? Just to understand if that was programmatically or "photoshopped"

That was a community member. Originally from this comment.

@davidsbatista
Copy link
Contributor Author

I explored a way to draw a line around it, but I still haven't found a nice solution. Would you suggest having the nodes coloured differently?

Example:

merged_pipeline

@sjrl
Copy link
Contributor

sjrl commented May 20, 2025

Oh interesting, yeah I think any kind of visual difference would be nice! It would be great though if we could easily distinguish between different super components within the same pipeline. So maybe different shades of the same color? Also would it be possible to add a legend to indicate which color goes with which super component?

@github-actions github-actions bot added the type:documentation Improvements on the docs label May 21, 2025
@davidsbatista davidsbatista requested a review from sjrl May 21, 2025 10:03
vblagoje
vblagoje previously approved these changes May 21, 2025
Copy link
Member

@vblagoje vblagoje left a comment

Choose a reason for hiding this comment

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

Looks nice - would be great to later extract utils related to super components in pipeline and component being a super component!

def show(
self,
server_url: str = "https://mermaid.ink",
super_component_expansion: bool = False,
Copy link
Contributor

Choose a reason for hiding this comment

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

We should add super_component_expansion at the bottom of this function otherwise inserting it in the middle is a breaking change.

self,
path: Path,
server_url: str = "https://mermaid.ink",
super_component_expansion: bool = False,
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here we should move the new variable to the bottom of the function

@sjrl
Copy link
Contributor

sjrl commented May 21, 2025

Nice the color coding and the legend look great! Just a few other minor comments.

davidsbatista and others added 2 commits May 21, 2025 15:30
Co-authored-by: Sebastian Husch Lee <10526848+sjrl@users.noreply.github.com>
@davidsbatista
Copy link
Contributor Author

@sjrl I opted for forcing keyword arguments for draw() and show() - I think this is a better solution which also avoids problems if we need to add /remove any other parameters

@sjrl
Copy link
Contributor

sjrl commented May 21, 2025

@sjrl I opted for forcing keyword arguments for draw() and show() - I think this is a better solution which also avoids problems if we need to add /remove any other parameters

I agree with you in principle, but enforcing keyword arguments now is also a breaking change right?

@davidsbatista
Copy link
Contributor Author

davidsbatista commented May 21, 2025

@sjrl I opted for forcing keyword arguments for draw() and show() - I think this is a better solution which also avoids problems if we need to add /remove any other parameters

I agree with you in principle, but enforcing keyword arguments now is also a breaking change right?

I can try to write a wrapper so that we can ship this in the next release, with a warning. Then, after the 2.14 release remove the warning and the wrapper function.

:raises PipelineDrawingError:
If the function is called outside of a Jupyter notebook or if there is an issue with rendering.
"""
import warnings

warnings.warn(
Copy link
Member

Choose a reason for hiding this comment

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

Currently, we would show this warning even if there are no positional arguments. Can we show the warning only if there are any positional arguments? For example making use of inspect.getargvalues or with something similar to this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would suggest to show it either way - just calling the function should be a enough to trigger the warning to the user that it will have some breaking changes in the future.

I don't think it's noisy if we show it even if he/she doesn't call it with positional arguments.

Copy link
Contributor

@sjrl sjrl May 22, 2025

Choose a reason for hiding this comment

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

I think I'm with Julian on this one. I think it makes more sense only to show the warning if the user is using the function in a way that won't work in the future.

Especially since if you follow the example how to fix the warning, the warning message still appears which could be frustrating to the user.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think it's good to shadow this from the user, especially if the user calls the function for whatever use he/she might have.

Anyway, I will code this only to trigger the warning in case the user calls the draw() or show() function using positional arguments.

@davidsbatista davidsbatista requested review from sjrl and vblagoje May 22, 2025 08:07
@davidsbatista davidsbatista dismissed vblagoje’s stale review May 22, 2025 10:28

There are more changes requested

@davidsbatista
Copy link
Contributor Author

I've added a function decorator to check if the show() or draw() are ever called with positional arguments, and only in those cases a DeprecrationWarning is triggered - I've also added tests for all possible cases for the decorator function.

I added tests to calls to draw() and show() with positional arguments, without positional arguments to check if the warning is triggered and not triggered in the correct cases.

Copy link
Member

@julian-risch julian-risch left a comment

Choose a reason for hiding this comment

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

Looks good to me! 👍 Probably we will reuse the args_deprecated in future when we switch to kwargs only in other places too.

@davidsbatista davidsbatista merged commit 3342f17 into main May 23, 2025
20 checks passed
@davidsbatista davidsbatista deleted the feat/draw-supercomponents-detail branch May 23, 2025 08:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add option to Pipeline.draw to allow expansion of a SuperComponent
5 participants