Skip to content

Commit cced13b

Browse files
authored
Reorder name in Component arguments (#111)
* Reorder name in Component arguments * Replace deprecated .dict() with .model_dump()
1 parent b89b932 commit cced13b

File tree

7 files changed

+112
-47
lines changed

7 files changed

+112
-47
lines changed

examples/pipeline/kg_builder_from_pdf.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,17 +139,16 @@ async def main(neo4j_driver: neo4j.Driver) -> dict[str, Any]:
139139

140140
# Set up the pipeline
141141
pipe = Pipeline()
142-
pipe.add_component("pdf_loader", PdfLoader())
142+
pipe.add_component(PdfLoader(), "pdf_loader")
143143
pipe.add_component(
144-
"splitter",
145144
LangChainTextSplitterAdapter(
146145
# chunk_size=50 for the sake of this demo
147146
CharacterTextSplitter(chunk_size=50, chunk_overlap=10, separator=".")
148147
),
148+
"splitter",
149149
)
150-
pipe.add_component("schema", SchemaBuilder())
150+
pipe.add_component(SchemaBuilder(), "schema")
151151
pipe.add_component(
152-
"extractor",
153152
LLMEntityRelationExtractor(
154153
llm=OpenAILLM(
155154
model_name="gpt-4o",
@@ -160,8 +159,9 @@ async def main(neo4j_driver: neo4j.Driver) -> dict[str, Any]:
160159
),
161160
on_error=OnError.RAISE,
162161
),
162+
"extractor",
163163
)
164-
pipe.add_component("writer", Neo4jWriter(neo4j_driver))
164+
pipe.add_component(Neo4jWriter(neo4j_driver), "writer")
165165
pipe.connect("pdf_loader", "splitter", input_config={"text": "pdf_loader.text"})
166166
pipe.connect("splitter", "extractor", input_config={"chunks": "splitter"})
167167
pipe.connect("schema", "extractor", input_config={"schema": "schema"})

examples/pipeline/kg_builder_from_text.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020

2121
import neo4j
2222
from langchain_text_splitters import CharacterTextSplitter
23-
from neo4j_genai.embeddings.openai import OpenAIEmbeddings
24-
from neo4j_genai.experimental.components.embedder import TextChunkEmbedder
2523
from neo4j_genai.experimental.components.entity_relation_extractor import (
2624
LLMEntityRelationExtractor,
2725
OnError,
@@ -76,16 +74,14 @@ async def main(neo4j_driver: neo4j.Driver) -> dict[str, Any]:
7674
pipe = Pipeline()
7775
# define the components
7876
pipe.add_component(
79-
"splitter",
8077
LangChainTextSplitterAdapter(
8178
# chunk_size=50 for the sake of this demo
8279
CharacterTextSplitter(chunk_size=50, chunk_overlap=10, separator=".")
8380
),
81+
"splitter",
8482
)
85-
pipe.add_component("chunk_embedder", TextChunkEmbedder(embedder=OpenAIEmbeddings()))
86-
pipe.add_component("schema", SchemaBuilder())
83+
pipe.add_component(SchemaBuilder(), "schema")
8784
pipe.add_component(
88-
"extractor",
8985
LLMEntityRelationExtractor(
9086
llm=OpenAILLM(
9187
model_name="gpt-4o",
@@ -96,8 +92,9 @@ async def main(neo4j_driver: neo4j.Driver) -> dict[str, Any]:
9692
),
9793
on_error=OnError.RAISE,
9894
),
95+
"extractor",
9996
)
100-
pipe.add_component("writer", Neo4jWriter(neo4j_driver))
97+
pipe.add_component(Neo4jWriter(neo4j_driver), "writer")
10198
# define the execution order of component
10299
# and how the output of previous components must be used
103100
pipe.connect("splitter", "chunk_embedder", input_config={"text_chunks": "splitter"})

src/neo4j_genai/experimental/components/schema.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,10 @@ def create_schema_model(
175175
Returns:
176176
SchemaConfig: A configured schema object.
177177
"""
178-
entity_dict = {entity.label: entity.dict() for entity in entities}
179-
relation_dict = {relation.label: relation.dict() for relation in relations}
178+
entity_dict = {entity.label: entity.model_dump() for entity in entities}
179+
relation_dict = {
180+
relation.label: relation.model_dump() for relation in relations
181+
}
180182

181183
try:
182184
return SchemaConfig(

src/neo4j_genai/experimental/pipeline/pipeline.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,10 @@ def from_template(
335335
"""Create a Pipeline from a pydantic model defining the components and their connections"""
336336
pipeline = Pipeline(store=store)
337337
for component in pipeline_template.components:
338-
pipeline.add_component(component.name, component.component)
338+
pipeline.add_component(
339+
component.component,
340+
component.name,
341+
)
339342
for edge in pipeline_template.connections:
340343
pipeline_edge = PipelineEdge(
341344
edge.start, edge.end, data={"input_config": edge.input_config}
@@ -363,7 +366,7 @@ def show_as_dict(self) -> dict[str, Any]:
363366
)
364367
return pipeline_config.model_dump()
365368

366-
def add_component(self, name: str, component: Component) -> None:
369+
def add_component(self, component: Component, name: str) -> None:
367370
task = TaskPipelineNode(name, component, self)
368371
self.add_node(task)
369372

tests/e2e/test_kb_builder_pipeline_e2e.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,25 @@ def kg_builder_pipeline(
9797
pipe = Pipeline()
9898
# define the components
9999
pipe.add_component(
100-
"splitter",
101100
text_splitter,
101+
"splitter",
102+
)
103+
pipe.add_component(
104+
chunk_embedder,
105+
"embedder",
106+
)
107+
pipe.add_component(
108+
schema_builder,
109+
"schema",
102110
)
103-
pipe.add_component("embedder", chunk_embedder)
104-
pipe.add_component("schema", schema_builder)
105111
pipe.add_component(
106-
"extractor",
107112
entity_relation_extractor,
113+
"extractor",
114+
)
115+
pipe.add_component(
116+
kg_writer,
117+
"writer",
108118
)
109-
pipe.add_component("writer", kg_writer)
110119
# define the execution order of component
111120
# and how the output of previous components must be used
112121
pipe.connect("splitter", "embedder", input_config={"text_chunks": "splitter"})

tests/unit/experimental/pipeline/test_orchestrator.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
@pytest.fixture(scope="function")
2121
def pipeline_branch() -> Pipeline:
2222
pipe = Pipeline()
23-
pipe.add_component("a", Component()) # type: ignore
24-
pipe.add_component("b", Component()) # type: ignore
25-
pipe.add_component("c", Component()) # type: ignore
23+
pipe.add_component(Component(), "a") # type: ignore
24+
pipe.add_component(Component(), "b") # type: ignore
25+
pipe.add_component(Component(), "c") # type: ignore
2626
pipe.connect("a", "b")
2727
pipe.connect("a", "c")
2828
return pipe
@@ -31,9 +31,9 @@ def pipeline_branch() -> Pipeline:
3131
@pytest.fixture(scope="function")
3232
def pipeline_aggregation() -> Pipeline:
3333
pipe = Pipeline()
34-
pipe.add_component("a", Component()) # type: ignore
35-
pipe.add_component("b", Component()) # type: ignore
36-
pipe.add_component("c", Component()) # type: ignore
34+
pipe.add_component(Component(), "a") # type: ignore
35+
pipe.add_component(Component(), "b") # type: ignore
36+
pipe.add_component(Component(), "c") # type: ignore
3737
pipe.connect("a", "b")
3838
pipe.connect("a", "c")
3939
return pipe

tests/unit/experimental/pipeline/test_pipeline.py

Lines changed: 74 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,14 @@ async def test_simple_pipeline_two_components() -> None:
3535
pipe = Pipeline()
3636
component_a = ComponentNoParam()
3737
component_b = ComponentNoParam()
38-
pipe.add_component("a", component_a)
39-
pipe.add_component("b", component_b)
38+
pipe.add_component(
39+
component_a,
40+
"a",
41+
)
42+
pipe.add_component(
43+
component_b,
44+
"b",
45+
)
4046
pipe.connect("a", "b", {})
4147
with mock.patch(
4248
"tests.unit.experimental.pipeline.test_pipeline.ComponentNoParam.run"
@@ -57,8 +63,14 @@ async def test_pipeline_parameter_propagation() -> None:
5763
pipe = Pipeline()
5864
component_a = ComponentPassThrough()
5965
component_b = ComponentPassThrough()
60-
pipe.add_component("a", component_a)
61-
pipe.add_component("b", component_b)
66+
pipe.add_component(
67+
component_a,
68+
"a",
69+
)
70+
pipe.add_component(
71+
component_b,
72+
"b",
73+
)
6274
# first component output product goes to second component input number1
6375
pipe.connect(
6476
"a",
@@ -90,9 +102,15 @@ async def test_pipeline_branches() -> None:
90102
component_c = AsyncMock(spec=Component)
91103
component_c.run = AsyncMock(return_value={})
92104

93-
pipe.add_component("a", component_a)
94-
pipe.add_component("b", component_b)
95-
pipe.add_component("c", component_c)
105+
pipe.add_component(
106+
component_a,
107+
"a",
108+
)
109+
pipe.add_component(
110+
component_b,
111+
"b",
112+
)
113+
pipe.add_component(component_c, "c")
96114
pipe.connect("a", "b")
97115
pipe.connect("a", "c")
98116
res = await pipe.run({})
@@ -110,9 +128,15 @@ async def test_pipeline_aggregation() -> None:
110128
component_c = AsyncMock(spec=Component)
111129
component_c.run = AsyncMock(return_value={})
112130

113-
pipe.add_component("a", component_a)
114-
pipe.add_component("b", component_b)
115-
pipe.add_component("c", component_c)
131+
pipe.add_component(
132+
component_a,
133+
"a",
134+
)
135+
pipe.add_component(
136+
component_b,
137+
"b",
138+
)
139+
pipe.add_component(component_c, "c")
116140
pipe.connect("a", "c")
117141
pipe.connect("b", "c")
118142
res = await pipe.run({})
@@ -124,8 +148,14 @@ async def test_pipeline_missing_param_on_init() -> None:
124148
pipe = Pipeline()
125149
component_a = ComponentAdd()
126150
component_b = ComponentAdd()
127-
pipe.add_component("a", component_a)
128-
pipe.add_component("b", component_b)
151+
pipe.add_component(
152+
component_a,
153+
"a",
154+
)
155+
pipe.add_component(
156+
component_b,
157+
"b",
158+
)
129159
pipe.connect("a", "b", {"number1": "a.result"})
130160
with pytest.raises(PipelineDefinitionError) as excinfo:
131161
await pipe.run({"a": {"number1": 1}})
@@ -140,8 +170,14 @@ async def test_pipeline_missing_param_on_connect() -> None:
140170
pipe = Pipeline()
141171
component_a = ComponentAdd()
142172
component_b = ComponentAdd()
143-
pipe.add_component("a", component_a)
144-
pipe.add_component("b", component_b)
173+
pipe.add_component(
174+
component_a,
175+
"a",
176+
)
177+
pipe.add_component(
178+
component_b,
179+
"b",
180+
)
145181
pipe.connect("a", "b", {"number1": "a.result"})
146182
with pytest.raises(PipelineDefinitionError) as excinfo:
147183
await pipe.run({"a": {"number1": 1, "number2": 2}})
@@ -156,8 +192,14 @@ async def test_pipeline_with_default_params() -> None:
156192
pipe = Pipeline()
157193
component_a = ComponentAdd()
158194
component_b = ComponentMultiply()
159-
pipe.add_component("a", component_a)
160-
pipe.add_component("b", component_b)
195+
pipe.add_component(
196+
component_a,
197+
"a",
198+
)
199+
pipe.add_component(
200+
component_b,
201+
"b",
202+
)
161203
pipe.connect("a", "b", {"number1": "a.result"})
162204
res = await pipe.run({"a": {"number1": 1, "number2": 2}})
163205
assert res == {"b": {"result": 6}} # (1+2)*2
@@ -168,8 +210,14 @@ async def test_pipeline_cycle() -> None:
168210
pipe = Pipeline()
169211
component_a = ComponentNoParam()
170212
component_b = ComponentNoParam()
171-
pipe.add_component("a", component_a)
172-
pipe.add_component("b", component_b)
213+
pipe.add_component(
214+
component_a,
215+
"a",
216+
)
217+
pipe.add_component(
218+
component_b,
219+
"b",
220+
)
173221
pipe.connect("a", "b", {})
174222
with pytest.raises(PipelineDefinitionError) as excinfo:
175223
pipe.connect("b", "a", {})
@@ -181,8 +229,14 @@ async def test_pipeline_wrong_component_name() -> None:
181229
pipe = Pipeline()
182230
component_a = ComponentNoParam()
183231
component_b = ComponentNoParam()
184-
pipe.add_component("a", component_a)
185-
pipe.add_component("b", component_b)
232+
pipe.add_component(
233+
component_a,
234+
"a",
235+
)
236+
pipe.add_component(
237+
component_b,
238+
"b",
239+
)
186240
with pytest.raises(PipelineDefinitionError) as excinfo:
187241
pipe.connect("a", "c", {})
188242
assert "a or c not in the Pipeline" in str(excinfo.value)

0 commit comments

Comments
 (0)