diff --git a/fluidize/adapters/local/graph.py b/fluidize/adapters/local/graph.py index 70ea95f..ac55ee9 100644 --- a/fluidize/adapters/local/graph.py +++ b/fluidize/adapters/local/graph.py @@ -40,14 +40,14 @@ def get_graph(self, project: ProjectSummary) -> GraphData: processor = GraphProcessor(project) return processor.get_graph() - def insert_node(self, project: ProjectSummary, node: GraphNode, sim_global: bool = True) -> GraphNode: + def insert_node(self, node: GraphNode, project: ProjectSummary, sim_global: bool = True) -> GraphNode: """ Insert a new node into the project graph. Args: - project: The project to add the node to node: The node to insert - sim_global: Whether to use global simulations (placeholder for future) + project: The project to add the node to + sim_global: Whether to use global simulations Returns: The inserted node diff --git a/fluidize/managers/graph.py b/fluidize/managers/graph.py index 3842d94..83fa5d9 100644 --- a/fluidize/managers/graph.py +++ b/fluidize/managers/graph.py @@ -68,7 +68,7 @@ def add_node(self, node: GraphNode, sim_global: bool = True) -> "NodeManager": Returns: The added node """ - inserted_node = self.adapter.graph.insert_node(self.project, node, sim_global) + inserted_node = self.adapter.graph.insert_node(node=node, project=self.project, sim_global=sim_global) return self.get_node(inserted_node.id) def add_node_from_scratch( diff --git a/fluidize/managers/registry.py b/fluidize/managers/registry.py index c4b6094..c59e321 100644 --- a/fluidize/managers/registry.py +++ b/fluidize/managers/registry.py @@ -48,6 +48,7 @@ def create( ) return ProjectManager(self.adapter, project_summary) + # - [ ] ISSUE #1: Project not found error should be put out when invalid project is put with get def get(self, project_id: str) -> ProjectManager: """ Get a project by ID. diff --git a/fluidize/managers/runs.py b/fluidize/managers/runs.py index 4427f51..2719022 100644 --- a/fluidize/managers/runs.py +++ b/fluidize/managers/runs.py @@ -37,7 +37,7 @@ def run_flow(self, payload: RunFlowPayload) -> dict[str, Any]: Returns: Dictionary with flow_status and run_number """ - return self.adapter.runs.run_flow(self.project, payload) # type: ignore[no-any-return] + return self.adapter.runs.run_flow(project=self.project, payload=payload) # type: ignore[no-any-return] def list_runs(self) -> list[str]: """ diff --git a/pyproject.toml b/pyproject.toml index f0844da..3998446 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ classifiers = [ dependencies = [ "asciitree>=0.3.3", "docker>=7.1.0", - "fluidize-sdk>=0.6.0", + "fluidize-sdk>=0.7.0", "jinja2>=3.1.6", "mlflow>=3.1.4", "networkx>=3.2.1", diff --git a/tests/unit/backends/local/test_graph.py b/tests/unit/backends/local/test_graph.py index a61bbab..7576670 100644 --- a/tests/unit/backends/local/test_graph.py +++ b/tests/unit/backends/local/test_graph.py @@ -77,7 +77,7 @@ def test_insert_node_success(self, graph_handler, mock_processor, sample_project node = SampleGraphs.sample_nodes()[0] mock_processor.insert_node.return_value = node - result = graph_handler.insert_node(sample_project, node, True) + result = graph_handler.insert_node(node, sample_project, sim_global=True) assert result == node mock_processor.insert_node.assert_called_once_with(node, True) @@ -87,7 +87,7 @@ def test_insert_node_with_sim_global_false(self, graph_handler, mock_processor, node = SampleGraphs.sample_nodes()[1] mock_processor.insert_node.return_value = node - result = graph_handler.insert_node(sample_project, node, False) + result = graph_handler.insert_node(node, sample_project, sim_global=False) assert result == node mock_processor.insert_node.assert_called_once_with(node, False) @@ -97,7 +97,7 @@ def test_insert_node_default_sim_global(self, graph_handler, mock_processor, sam node = SampleGraphs.sample_nodes()[0] mock_processor.insert_node.return_value = node - result = graph_handler.insert_node(sample_project, node) + result = graph_handler.insert_node(node, sample_project) # sim_global defaults to True assert result == node mock_processor.insert_node.assert_called_once_with(node, True) # Default is True @@ -160,7 +160,7 @@ def test_processor_error_propagation_insert_node(self, graph_handler, mock_proce mock_processor.insert_node.side_effect = ValueError("Invalid node data") with pytest.raises(ValueError, match="Invalid node data"): - graph_handler.insert_node(sample_project, node) + graph_handler.insert_node(node, sample_project) def test_processor_error_propagation_delete_node(self, graph_handler, mock_processor, sample_project): """Test that processor errors are propagated for delete_node.""" @@ -196,7 +196,7 @@ def test_processor_creation_per_operation(self, sample_project): # Perform multiple operations handler.get_graph(sample_project) - handler.insert_node(sample_project, SampleGraphs.sample_nodes()[0]) + handler.insert_node(SampleGraphs.sample_nodes()[0], sample_project) handler.delete_node(sample_project, "test-id") # Verify processor was created for each operation @@ -245,7 +245,7 @@ def test_all_crud_operations_flow(self, sample_project): # Perform full CRUD cycle graph_data = handler.get_graph(sample_project) - inserted_node = handler.insert_node(sample_project, node) + inserted_node = handler.insert_node(node, sample_project) updated_node = handler.update_node_position(sample_project, node) handler.delete_node(sample_project, "test-node-id") upserted_edge = handler.upsert_edge(sample_project, edge) @@ -297,6 +297,9 @@ def test_individual_operations(self, sample_project, operation, method_name, arg handler_method = getattr(handler, operation) if operation == "ensure_graph_initialized": handler_method(sample_project) + elif operation == "insert_node": + # insert_node uses direct arguments + handler_method(args[0], sample_project, args[1]) else: handler_method(sample_project, *args) diff --git a/tests/unit/managers/test_project_graph.py b/tests/unit/managers/test_project_graph.py index f411022..5efcce9 100644 --- a/tests/unit/managers/test_project_graph.py +++ b/tests/unit/managers/test_project_graph.py @@ -97,10 +97,9 @@ def test_add_node_success(self, project_graph, mock_adapter): assert isinstance(result, NodeManager) assert result.node_id == node.id + # Verify that insert_node was called with correct arguments mock_adapter.graph.insert_node.assert_called_once_with( - project_graph.project, - node, - True, # Default sim_global=True + node=node, project=project_graph.project, sim_global=True ) def test_add_node_with_sim_global_false(self, project_graph, mock_adapter): @@ -112,7 +111,10 @@ def test_add_node_with_sim_global_false(self, project_graph, mock_adapter): assert isinstance(result, NodeManager) assert result.node_id == node.id - mock_adapter.graph.insert_node.assert_called_once_with(project_graph.project, node, False) + # Verify that insert_node was called with correct arguments + mock_adapter.graph.insert_node.assert_called_once_with( + node=node, project=project_graph.project, sim_global=False + ) def test_add_node_from_scratch_success(self, project_graph, mock_adapter): """Test successful node creation from scratch.""" @@ -296,8 +298,9 @@ def test_project_scoping(self, mock_adapter): # Verify each call was made with correct project context calls = mock_adapter.graph.insert_node.call_args_list assert len(calls) == 2 - assert calls[0][0][0] == project1 # First call with project1 - assert calls[1][0][0] == project2 # Second call with project2 + # Check that both calls received correct keyword arguments + assert calls[0].kwargs["project"] == project1 # First call with project1 + assert calls[1].kwargs["project"] == project2 # Second call with project2 def test_all_methods_delegate_to_adapter(self, project_graph, mock_adapter): """Test that all GraphManager methods properly delegate to adapter.""" @@ -385,10 +388,15 @@ def test_project_context_consistency(self, project_graph, mock_adapter): mock_adapter.graph.delete_edge.call_args_list, ] - # All calls should include the same project as first argument - for call_list in all_calls: + # All calls should include the same project (either as first argument or keyword) + for i, call_list in enumerate(all_calls): if call_list: # If method was called - assert call_list[0][0][0] == project + if i == 1: # insert_node call index + # For insert_node, check the project in keyword arguments + assert call_list[0].kwargs["project"] == project + else: + # For other calls, project is still the first argument + assert call_list[0][0][0] == project def test_get_parameters_success(self, project_graph, mock_adapter): """Test successful parameter retrieval through ProjectGraph.""" diff --git a/uv.lock b/uv.lock index e1f8dcf..f135c6e 100644 --- a/uv.lock +++ b/uv.lock @@ -759,7 +759,7 @@ dev = [ requires-dist = [ { name = "asciitree", specifier = ">=0.3.3" }, { name = "docker", specifier = ">=7.1.0" }, - { name = "fluidize-sdk", specifier = ">=0.6.0" }, + { name = "fluidize-sdk", specifier = ">=0.7.0" }, { name = "jinja2", specifier = ">=3.1.6" }, { name = "mlflow", specifier = ">=3.1.4" }, { name = "networkx", specifier = ">=3.2.1" }, @@ -786,7 +786,7 @@ dev = [ [[package]] name = "fluidize-sdk" -version = "0.6.0" +version = "0.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -796,9 +796,9 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f0/6d/41a511df1e9f2cfb6526a349162ea7032ef2ef3d4ced52b8ff81a036ca84/fluidize_sdk-0.6.0.tar.gz", hash = "sha256:cb4548e3ebac5c949b177a6f352edc91be5ffd82900dd0267159027ffb895633", size = 119144, upload-time = "2025-08-16T09:45:34.48Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ad/58/af4a33d85bdebfa45cf8994eff983ac23e98a1086cc8dd3cd4b1c4adad7e/fluidize_sdk-0.7.0.tar.gz", hash = "sha256:9f1e2b5c38409790ce36e0e5d85792575a2045c1780ba12a74f1fc7dec87ddb6", size = 119652, upload-time = "2025-08-18T00:45:01.689Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/6e/25a81bd993b6dec0733e7f4f13f199a40e3500222907bfab54fc5e946eea/fluidize_sdk-0.6.0-py3-none-any.whl", hash = "sha256:22db9101b88bbf0adea113057f96ce9436985ce3b9e635fedcdb421fff399ab2", size = 121524, upload-time = "2025-08-16T09:45:32.874Z" }, + { url = "https://files.pythonhosted.org/packages/01/e3/10c44e47f5fe50edb7d91fcdcc3613ec7ed8b34471e888d260f2415f52ae/fluidize_sdk-0.7.0-py3-none-any.whl", hash = "sha256:32744079456e5a5b6cc99e2ce1c48c9f42339f1e72a778383643711e0dcd1faf", size = 122274, upload-time = "2025-08-18T00:45:00.047Z" }, ] [[package]]