Neo.ClientError.Procedure.ProcedureCallFailed when constructing a GDS graph object from DataFrame
**Neo4j Version:** 5.10
**Operating System:** Ubuntu 20.04
**API:** Docker

Hello! When I use Graph Data Science to construct a graph with 1 node and 0 relationships, Neo4j throws a strange exception. I believe that this behavior may be unexpected and related to a potential bug since we should allow running some algorithms in the graph without relationships. Could you further confirm and investigate it? It would be highly appreciated!

### Steps to reproduce

Run the following python code:

```python
nodes = pandas.DataFrame(
    {
        "nodeId" : [0],
        "labels" : ["person"],
    }
)

relationships = pandas.DataFrame(
    {
        "sourceNodeId" : [],
        "targetNodeId" : [],
        "relationshipType" : []
    }
)

gds.graph.construct(
    graph_name="my_graph",
    nodes=nodes,
    relationships=relationships
)
```

### Expected behavior
Successfully constructing the graph object.

### Actual behavior
```
Neo.ClientError.Procedure.ProcedureCallFailed
```
**message**: Failed to invoke function `gds.graph.project`: Caused by: ```java.lang.IllegalArgumentException```: The node has to be either a NODE or an INTEGER, but got Double.

diff --git a/changelog.md b/changelog.md
index 27b7e64..c41bae5 100644
--- a/changelog.md
+++ b/changelog.md
@@ -20,6 +20,7 @@
 * Improved endpoint returning graphs to be used in `with` clauses. The expression `with gds.graph.project(...)[0] as G` can now be simplified to `with gds.graph.project(...) AS G`.
 * Improve the error message if GDS is not correctly installed on the server
 * Forward previously ignored Cypher warnings as Python warnings. This includes for instance deprecation warnings.
+* Make `gds.graph.construct` more robust by ignoring empty dataframes inside. This makes it less error-prone to construct nodes only graphs.
 
 
 
diff --git a/doc/sphinx/source/graph.rst b/doc/sphinx/source/graph.rst
index 14baac8..f4d7c08 100644
--- a/doc/sphinx/source/graph.rst
+++ b/doc/sphinx/source/graph.rst
@@ -5,7 +5,7 @@ This includes all the methods for projecting, deleting, and listing graphs, as w
 These all assume that an object of :class:`.GraphDataScience` is available as `gds`.
 
 
-.. py:function:: gds.graph.construct(graph_name: str, nodes: Union[DataFrame, List[DataFrame]], relationships: Union[DataFrame, List[DataFrame]], concurrency: int = 4, undirected_relationship_types: Optional[List[str]] = None) -> Graph
+.. py:function:: gds.graph.construct(graph_name: str, nodes: Union[DataFrame, List[DataFrame]], relationships: Optional[Union[DataFrame, List[DataFrame]]] = None, concurrency: int = 4, undirected_relationship_types: Optional[List[str]] = None) -> Graph
 
     Constructs a new graph in the graph catalog, using the provided node and relationship data frames.
 
diff --git a/graphdatascience/graph/graph_proc_runner.py b/graphdatascience/graph/graph_proc_runner.py
index 6b8e2d2..fbc615d 100644
--- a/graphdatascience/graph/graph_proc_runner.py
+++ b/graphdatascience/graph/graph_proc_runner.py
@@ -55,12 +55,20 @@ class GraphProcRunner(UncallableNamespace, IllegalAttrChecker):
         self,
         graph_name: str,
         nodes: Union[DataFrame, List[DataFrame]],
-        relationships: Union[DataFrame, List[DataFrame]],
+        relationships: Optional[Union[DataFrame, List[DataFrame]]] = None,
         concurrency: int = 4,
         undirected_relationship_types: Optional[List[str]] = None,
     ) -> Graph:
         nodes = nodes if isinstance(nodes, List) else [nodes]
-        relationships = relationships if isinstance(relationships, List) else [relationships]
+
+        if isinstance(relationships, DataFrame):
+            relationships = [relationships]
+        elif relationships is None:
+            relationships = []
+
+        # Filter empty dataframes
+        nodes = [df for df in nodes if not df.empty]
+        relationships = [df for df in relationships if not df.empty]
 
         errors = []
 
diff --git a/graphdatascience/tests/integration/test_graph_construct.py b/graphdatascience/tests/integration/test_graph_construct.py
index 3198636..8cf710a 100644
--- a/graphdatascience/tests/integration/test_graph_construct.py
+++ b/graphdatascience/tests/integration/test_graph_construct.py
@@ -395,7 +395,6 @@ def test_graph_construct_with_arrow_multiple_dfs(gds: GraphDataScience) -> None:
 
 
 @pytest.mark.enterprise
-@pytest.mark.skip_on_aura  # Should not warn when targeting AuraDS
 @pytest.mark.compatible_with(min_inclusive=ServerVersion(2, 1, 0))
 def test_graph_construct_without_arrow_enterprise_warning(gds_without_arrow: GraphDataScience) -> None:
     nodes = DataFrame({"nodeId": [0, 1, 2, 3]})
@@ -477,6 +476,31 @@ def test_graph_alpha_construct_backward_compat_without_arrow(gds_without_arrow:
         gds_without_arrow.alpha.graph.construct("hello", nodes, relationships)
 
 
+def test_nodes_only_without__arrow(gds_without_arrow: GraphDataScience) -> None:
+    nodes = DataFrame({"nodeId": [0], "labels": ["person"]})
+    relationships = DataFrame({"sourceNodeId": [], "targetNodeId": [], "relationshipType": []})
+
+    with pytest.warns(UserWarning):
+        G = gds_without_arrow.graph.construct(graph_name="my_graph", nodes=nodes, relationships=relationships)
+
+    try:
+        assert G.node_count() == 1
+        assert G.node_properties("person") == []
+    finally:
+        G.drop()
+
+
+@pytest.mark.enterprise
+def test_nodes_only(gds: GraphDataScience) -> None:
+    nodes = DataFrame({"nodeId": [0], "labels": ["person"]})
+    relationships = DataFrame({"sourceNodeId": [], "targetNodeId": [], "relationshipType": []})
+
+    G = gds.graph.construct(graph_name="my_graph", nodes=nodes, relationships=relationships)
+
+    assert G.node_count() == 1
+    assert G.node_properties("person") == []
+
+
 @pytest.mark.enterprise
 @pytest.mark.compatible_with(min_inclusive=ServerVersion(2, 1, 0))
 def test_graph_alpha_construct_backward_compat_with_arrow(gds: GraphDataScience) -> None:
diff --git a/graphdatascience/tests/unit/test_graph_construct.py b/graphdatascience/tests/unit/test_graph_construct.py
index 3329f36..c91faf7 100644
--- a/graphdatascience/tests/unit/test_graph_construct.py
+++ b/graphdatascience/tests/unit/test_graph_construct.py
@@ -262,3 +262,15 @@ def test_graph_alpha_construct_backward_compat(runner: CollectingQueryRunner, gd
 
     with pytest.warns(DeprecationWarning):
         gds.alpha.graph.construct("hello", nodes, relationships, concurrency=2)
+
+
+def test_nodes_graph(gds: GraphDataScience, runner: CollectingQueryRunner) -> None:
+    gds.graph.construct("hello", nodes=DataFrame({"nodeId": [0, 1]}), concurrency=2)
+
+    query = runner.last_query()
+
+    gds.graph.construct("hello", nodes=DataFrame({"nodeId": [0, 1]}), relationships=[], concurrency=2)
+
+    other_query = runner.last_query()
+
+    assert query == other_query
['doc/sphinx/source/graph.rst', 'graphdatascience/tests/integration/test_graph_construct.py', 'changelog.md', 'graphdatascience/tests/unit/test_graph_construct.py', 'graphdatascience/graph/graph_proc_runner.py']