import asyncio from neo4j_graphrag.experimental.pipeline.component import Component, DataModel from neo4j_graphrag.experimental.pipeline.pipeline import Pipeline from neo4j_graphrag.experimental.pipeline.notification import EventType, Event from neo4j_graphrag.experimental.pipeline.types.context import RunContext # Define some example components with progress notifications class OutputModel(DataModel): result: int class SlowAdder(Component): """A component that slowly adds numbers and reports progress""" def __init__(self, number: int) -> None: self.number = number async def run_with_context(self, context_: RunContext, value: int) -> OutputModel: # Simulate work with progress updates for i in range(value): await asyncio.sleep(0.5) # Simulate work await context_.notify( message=f"Added {i + 1}/{value}", data={"current": i + 1, "total": value}, ) return OutputModel(result=value + self.number) class SlowMultiplier(Component): """A component that slowly multiplies numbers and reports progress""" def __init__(self, multiplier: int) -> None: self.multiplier = multiplier async def run_with_context(self, context_: RunContext, value: int) -> OutputModel: # Simulate work with progress updates for i in range(3): # Always do 3 steps await asyncio.sleep(0.7) # Simulate work await context_.notify( message=f"Multiplication step {i + 1}/3", data={"step": i + 1, "total": 3}, ) return OutputModel(result=value * self.multiplier) async def callback(event: Event) -> None: await asyncio.sleep(0.1) async def main() -> None: # Create pipeline pipeline = Pipeline(callback=callback) # Add components pipeline.add_component(SlowAdder(number=3), "adder") pipeline.add_component(SlowMultiplier(multiplier=2), "multiplier") # Connect components pipeline.connect("adder", "multiplier", {"value": "adder.result"}) print("\n=== Running pipeline with streaming ===") # Run pipeline with streaming - see events as they happen async for event in pipeline.stream( {"adder": {"value": 2}}, raise_exception=False, # default is True ): if event.event_type == EventType.PIPELINE_STARTED: print("Stream: Pipeline started!") elif event.event_type == EventType.PIPELINE_FINISHED: print(f"Stream: Pipeline finished! Final results: {event.payload}") elif event.event_type == EventType.PIPELINE_FAILED: print(f"Stream: Pipeline failed with message: {event.message}") elif event.event_type == EventType.TASK_STARTED: print( f"Stream: Task {event.task_name} started with inputs: {event.payload}" # type: ignore ) elif event.event_type == EventType.TASK_PROGRESS: print(f"Stream: Task {event.task_name} progress - {event.message}") # type: ignore elif event.event_type == EventType.TASK_FINISHED: print( f"Stream: Task {event.task_name} finished with result: {event.payload}" # type: ignore ) if __name__ == "__main__": asyncio.run(main())