Skip to content

Commit 3a15dce

Browse files
authored
Merge pull request #209 from neo4j/from-snowflake
Add `from_snowflake` constructor
2 parents 4b4a43b + 61951e7 commit 3a15dce

17 files changed

+1147
-415
lines changed

.github/workflows/code-style.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ jobs:
3535
- run: pip install ".[dev]"
3636
- run: pip install ".[pandas]"
3737
- run: pip install ".[gds]"
38+
- run: pip install ".[snowflake]"
3839

3940
- name: Check code style
4041
run: cd ${GITHUB_WORKSPACE} && ./scripts/checkstyle.sh

.github/workflows/unit-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ jobs:
4242
- run: pip install ".[pandas]"
4343
- run: pip install ".[neo4j]"
4444
- run: pip install ".[gds]"
45+
- run: pip install ".[snowflake]"
4546

4647
- name: Run tests
4748
run: pytest tests/

changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@
66

77
## New features
88

9+
* Added new constructor `from_snowflake` that creates visualization graphs from Snowflake tables.
10+
911

1012
## Bug fixes
1113

1214

1315
## Improvements
1416

17+
* The `field` parameter of `color_nodes` now also accepts casing other than `snake_case`.
18+
1519

1620
## Other changes
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Import from Snowflake Tables
2+
----------------------------
3+
4+
.. automodule:: neo4j_viz.snowflake
5+
:members:
6+
:exclude-members: Orientation, VizProjectConfig, VizRelationshipTableConfig

docs/source/api-reference/render_options.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,5 @@
1818
.. autoenum:: neo4j_viz.options.Packing
1919
:members:
2020

21-
2221
.. autoenum:: neo4j_viz.Renderer
2322
:members:

docs/source/index.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ The library allows you to visualize graph data interactively in Python using a s
1111

1212
The library wraps the `Neo4j Visualization JavaScript library (NVL) <https://neo4j.com/docs/nvl/current/>`_, and
1313
provides additional features for working with graph data in Python.
14-
Notably, there are convenience methods for importing data from `Pandas DataFrames <https://pandas.pydata.org/>`_,
15-
`Neo4j Graph Data Science <https://neo4j.com/docs/graph-data-science/current/>`_ and `Neo4j Database <https://neo4j.com/docs/python-manual/current/>`_.
14+
Notably, there are convenience methods for importing data from source such as `Pandas DataFrames <https://pandas.pydata.org/>`_,
15+
`Neo4j Graph Data Science <https://neo4j.com/docs/graph-data-science/current/>`_, `Neo4j Database <https://neo4j.com/docs/python-manual/current/>`_
16+
and `Snowflake tables <https://docs.snowflake.com/>`_.
1617

1718
The source code is available on `GitHub <https://github.com/neo4j/python-graph-visualization>`_.
1819
If you have a suggestion on how we can improve the library or want to report a problem, you can create a `new issue <https://github.com/neo4j/python-graph-visualization/issues/new>`_.

docs/source/installation.rst

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ To install the additional dependencies required for the :doc:`from_dfs importer
2424
2525
pip install neo4j-viz[pandas]
2626
27+
2728
Neo4j ``from_neo4j`` importer
28-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
29+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2930

3031
To install the additional dependencies required for the :doc:`from_neo4j importer <./api-reference/from_neo4j>` you can run:
3132

@@ -43,6 +44,17 @@ To install the additional dependencies required for the :doc:`from_gds importer
4344
4445
pip install neo4j-viz[gds]
4546
47+
48+
Snowflake tables ``from_snowflake`` importer
49+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50+
51+
To install the additional dependencies required for the :doc:`from_snowflake importer <./api-reference/from_snowflake>` you can run:
52+
53+
.. code-block:: bash
54+
55+
pip install neo4j-viz[snowflake]
56+
57+
4658
Notebook tutorials
4759
~~~~~~~~~~~~~~~~~~
4860

docs/source/integration.rst

Lines changed: 126 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ In addition to creating graphs from scratch, with ``neo4j-viz`` as is shown in t
55
:doc:`Getting started section <./getting-started>`, you can also import data directly from external sources.
66
In this section we will cover how to import data from `Pandas DataFrames <https://pandas.pydata.org/>`_,
77
`Neo4j Graph Data Science <https://neo4j.com/docs/graph-data-science/current/>`_,
8-
`Neo4j Database <https://neo4j.com/docs/python-manual/current/>`_ and
9-
`GQL CREATE queries <https://neo4j.com/docs/cypher-manual/current/clauses/create/>`_.
8+
`Neo4j Database <https://neo4j.com/docs/python-manual/current/>`_,
9+
`GQL CREATE queries <https://neo4j.com/docs/cypher-manual/current/clauses/create/>`_,
10+
and `Snowflake tables <https://docs.snowflake.com/>`_.
1011

1112

1213
.. contents:: On this page:
@@ -19,14 +20,14 @@ Pandas DataFrames
1920
-----------------
2021

2122
The ``neo4j-viz`` library provides a convenience method for importing data from Pandas DataFrames.
22-
These DataFrames can be created from many sources, such as CSV files or :doc:`Snowflake tables<./tutorials/snowpark-example>`.
23+
These DataFrames can be created from many sources, such as CSV files.
2324
It requires and additional dependency to be installed, which you can do by running:
2425

2526
.. code-block:: bash
2627
2728
pip install neo4j-viz[pandas]
2829
29-
Once you have installed the additional dependency, you can use the :doc:`from_gds <./api-reference/from_pandas>` method
30+
Once you have installed the additional dependency, you can use the :doc:`from_pandas <./api-reference/from_pandas>` method
3031
to import pandas DataFrames.
3132

3233
The ``from_dfs`` method takes two mandatory positional parameters:
@@ -82,9 +83,6 @@ and :doc:`Relationships <./api-reference/relationship>`.
8283
8384
VG = from_dfs(nodes, relationships)
8485
85-
For another example of the ``from_dfs`` importer in action, see the
86-
:doc:`Visualizing Snowflake Tables tutorial <./tutorials/snowpark-example>`.
87-
8886
8987
Neo4j Graph Data Science (GDS) library
9088
--------------------------------------
@@ -118,9 +116,9 @@ and will be used to determine the sizes of the nodes in the visualization.
118116

119117
The ``additional_node_properties`` parameter is also optional, and should be a list of additional node properties of the
120118
projection that you want to include in the visualization.
121-
The default is `None`, which means that all properties of the nodes in the projection will be included.
119+
The default is ``None``, which means that all properties of the nodes in the projection will be included.
122120
Apart from being visible through on-hover tooltips, these properties could be used to color the nodes, or give captions
123-
to them in the visualization, or simply included in the nodes' `Node.properties` maps without directly impacting the
121+
to them in the visualization, or simply included in the nodes' ``Node.properties`` maps without directly impacting the
124122
visualization.
125123

126124
The last optional property, ``node_radius_min_max``, can be used (and is used by default) to scale the node sizes for
@@ -285,3 +283,122 @@ In this small example, we create a visualization graph from a GQL ``CREATE`` que
285283
"""
286284
287285
VG = from_gql_create(query)
286+
287+
288+
Snowflake Tables
289+
----------------
290+
291+
The ``neo4j-viz`` library provides a convenience method for importing data from Snowflake tables.
292+
It requires and additional dependency to be installed, which you can do by running:
293+
294+
.. code-block:: bash
295+
296+
pip install neo4j-viz[snowflake]
297+
298+
Once you have installed the additional dependency, you can use the :doc:`from_snowflake <./api-reference/from_snowflake>` method
299+
to import Snowflake tables into a ``VisualizationGraph``.
300+
301+
The ``from_snowflake`` method takes two mandatory positional parameters:
302+
303+
* A ``snowflake.snowpark.Session`` object for the connection to Snowflake, and
304+
* A `project configuration <https://neo4j.com/docs/snowflake-graph-analytics/current/jobs/#jobs-project>`_ as a dictionary, that specifies how you want your tables to be projected as a graph.
305+
This configuration is the same as the project configuration of the `Neo4j Snowflake Graph Analytics application <https://neo4j.com/docs/snowflake-graph-analytics/current/>`_.
306+
307+
``from_snowflake`` also takes an optional property, ``node_radius_min_max``, that can be used (and is used by default) to
308+
scale the node sizes for the visualization.
309+
It is a tuple of two numbers, representing the radii (sizes) in pixels of the smallest and largest nodes respectively in
310+
the visualization.
311+
The node sizes will be scaled such that the smallest node will have the size of the first value, and the largest node
312+
will have the size of the second value.
313+
The other nodes will be scaled linearly between these two values according to their relative size.
314+
This can be useful if node sizes vary a lot, or are all very small or very big.
315+
316+
317+
Special columns
318+
~~~~~~~~~~~~~~~
319+
320+
It is possible to modify the visualization directly by including columns of certain specific names in the node and relationship tables.
321+
322+
All such special columns can be found :doc:`here <./api-reference/node>` for nodes and :doc:`here <./api-reference/relationship>` for relationships.
323+
Though listed in ``snake_case`` here, ``SCREAMING_SNAKE_CASE`` and ``camelCase`` are also supported.
324+
Some of the most commonly used special columns are:
325+
326+
* **Node sizes**: The sizes of nodes can be controlled by including a column named "SIZE" in node tables.
327+
The values in these columns should be of a numeric type. This can be useful for visualizing the relative importance or size of nodes in the graph, for example using a computed centrality score.
328+
329+
* **Captions**: The caption text of nodes and relationships can be controlled by including a column named "CAPTION" in the tables.
330+
The values in these columns should be of a string type. This can be useful for displaying additional information about the nodes, such as their names or labels. If no "CAPTION" column is provided, the default captions in the visualization will be the names of the corresponding node and relationship tables.
331+
332+
Please also note that you can further customize the visualization after the `VisualizationGraph` has been created, by using the methods described in the :doc:`Customizing the visualization <./customizing>` section.
333+
334+
335+
Default behavior
336+
~~~~~~~~~~~~~~~~
337+
338+
Unless there are "CAPTION" columns in the tables, the node and relationship captions will be set to the names of the corresponding tables.
339+
Similarly, if there are are no "COLOR" node table columns, the nodes will be colored be colored so that nodes from the same table have the same color, and different tables have different colors.
340+
341+
342+
Example
343+
~~~~~~~
344+
345+
In this small example, we import a toy graph representing a social network from two tables in Snowflake.
346+
347+
.. code-block:: python
348+
349+
from snowflake.snowpark import Session
350+
from neo4j_viz.snowflake import from_dfs
351+
352+
# Configure according to your own setup
353+
connection_parameters = {
354+
"account": os.environ.get("SNOWFLAKE_ACCOUNT"),
355+
"user": os.environ.get("SNOWFLAKE_USER"),
356+
"password": os.environ.get("SNOWFLAKE_PASSWORD"),
357+
"role": os.environ.get("SNOWFLAKE_ROLE"),
358+
"warehouse": os.environ.get("SNOWFLAKE_WAREHOUSE"),
359+
}
360+
361+
session.sql(
362+
"CREATE OR REPLACE TABLE EXAMPLE_DB.DATA_SCHEMA.PERSONS (NODEID VARCHAR);"
363+
).collect()
364+
365+
session.sql("""
366+
INSERT INTO EXAMPLE_DB.DATA_SCHEMA.PERSONS VALUES
367+
('Alice'),
368+
('Bob'),
369+
('Carol'),
370+
('Dave'),
371+
('Eve');
372+
""").collect()
373+
374+
session.sql(
375+
"CREATE OR REPLACE TABLE EXAMPLE_DB.DATA_SCHEMA.KNOWS (SOURCENODEID VARCHAR, TARGETNODEID VARCHAR);"
376+
).collect()
377+
378+
session.sql("""
379+
INSERT INTO EXAMPLE_DB.DATA_SCHEMA.KNOWS VALUES
380+
('Alice', 'Dave'),
381+
('Alice', 'Carol'),
382+
('Bob', 'Carol'),
383+
('Dave', 'Eve'),
384+
""").collect()
385+
386+
VG = from_snowflake(
387+
session,
388+
{
389+
"nodeTables": [
390+
"EXAMPLE_DB.DATA_SCHEMA.PERSONS",
391+
],
392+
"relationshipTables": {
393+
"EXAMPLE_DB.DATA_SCHEMA.KNOWS": {
394+
"sourceTable": "EXAMPLE_DB.DATA_SCHEMA.PERSONS",
395+
"targetTable": "EXAMPLE_DB.DATA_SCHEMA.PERSONS",
396+
"orientation": "UNDIRECTED",
397+
}
398+
},
399+
},
400+
)
401+
402+
For a full example of the ``from_snowflake`` importer in action, please see the
403+
:doc:`Visualizing Snowflake Tables tutorial <./tutorials/snowflake-example>`.
404+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"path": "../../../examples/snowflake-example.ipynb"
3+
}

docs/source/tutorials/snowpark-example.nblink

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)