This is an automated email from the ASF dual-hosted git repository.

dehowef pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/age.git


The following commit(s) were added to refs/heads/master by this push:
     new db0a4421 python driver psycopg3 (#1793)
db0a4421 is described below

commit db0a4421b5c0abc30507793f0da89a2a86b9cf25
Author: Matt <[email protected]>
AuthorDate: Tue Apr 30 01:16:34 2024 -0700

    python driver psycopg3 (#1793)
    
    * update for psycopg3
    
    * set a default argparse namespace  in case tests are run in such a way 
that argparse is bypassed.
---
 .gitignore                                      |   4 +
 drivers/python/age/__init__.py                  |  12 +-
 drivers/python/age/age.py                       |  79 +++---
 drivers/python/age/builder.py                   |   6 +-
 drivers/python/age/exceptions.py                |   2 +-
 drivers/python/age/networkx/age_to_networkx.py  |   6 +-
 drivers/python/age/networkx/lib.py              |  44 ++--
 drivers/python/age/networkx/networkx_to_age.py  |   6 +-
 drivers/python/requirements.txt                 | Bin 180 -> 176 bytes
 drivers/python/samples/apache-age-agtypes.ipynb |  71 +++++-
 drivers/python/samples/apache-age-basic.ipynb   | 104 +++++---
 drivers/python/samples/apache-age-note.ipynb    | 247 ++++--------------
 drivers/python/samples/networkx.ipynb           |   4 +-
 drivers/python/setup.py                         |   2 +-
 drivers/python/test_age_py.py                   | 318 +++++++++++++++---------
 drivers/python/test_networkx.py                 |  73 ++++--
 16 files changed, 519 insertions(+), 459 deletions(-)

diff --git a/.gitignore b/.gitignore
index e03dd04a..a8e809dd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,7 @@ build.sh
 *.dylib
 age--*.*.*.sql
 !age--*--*sql
+__pycache__
+**/__pycache__
+
+drivers/python/build
diff --git a/drivers/python/age/__init__.py b/drivers/python/age/__init__.py
index 5d0e31ef..63826909 100644
--- a/drivers/python/age/__init__.py
+++ b/drivers/python/age/__init__.py
@@ -13,6 +13,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
+import psycopg.conninfo as conninfo
 from . import age
 from .age import *
 from .models import *
@@ -23,10 +24,13 @@ def version():
     return VERSION.VERSION
 
 
-def connect(dsn=None, graph=None, connection_factory=None, 
cursor_factory=None, **kwargs):
-        ag = Age()
-        ag.connect(dsn=dsn, graph=graph, 
connection_factory=connection_factory, cursor_factory=cursor_factory, **kwargs)
-        return ag
+def connect(dsn=None, graph=None, connection_factory=None, 
cursor_factory=ClientCursor, **kwargs):
+
+    dsn = conninfo.make_conninfo('' if dsn is None else dsn, **kwargs)
+
+    ag = Age()
+    ag.connect(dsn=dsn, graph=graph, connection_factory=connection_factory, 
cursor_factory=cursor_factory, **kwargs)
+    return ag
 
 # Dummy ResultHandler
 rawPrinter = DummyResultHandler()
diff --git a/drivers/python/age/age.py b/drivers/python/age/age.py
index 40ad0c21..2d98e3ff 100644
--- a/drivers/python/age/age.py
+++ b/drivers/python/age/age.py
@@ -13,13 +13,14 @@
 # specific language governing permissions and limitations
 # under the License.
 
-import re 
-import psycopg2 
-from psycopg2 import errors
-from psycopg2 import extensions as ext
-from psycopg2 import sql
+import re
+import psycopg
+from psycopg.types import TypeInfo
+from psycopg.adapt import Loader
+from psycopg import sql
+from psycopg.client_cursor import ClientCursor
 from .exceptions import *
-from .builder import ResultHandler , parseAgeValue, newResultHandler
+from .builder import parseAgeValue
 
 
 _EXCEPTION_NoConnection = NoConnection()
@@ -27,26 +28,36 @@ _EXCEPTION_GraphNotSet = GraphNotSet()
 
 WHITESPACE = re.compile('\s')
 
-def setUpAge(conn:ext.connection, graphName:str):
+
+class AgeDumper(psycopg.adapt.Dumper):
+    def dump(self, obj: Any) -> bytes | bytearray | memoryview:
+        pass    
+    
+    
+class AgeLoader(psycopg.adapt.Loader):    
+    def load(self, data: bytes | bytearray | memoryview) -> Any | None:    
+        return parseAgeValue(data.decode('utf-8'))
+
+
+def setUpAge(conn:psycopg.connection, graphName:str):
     with conn.cursor() as cursor:
         cursor.execute("LOAD 'age';")
         cursor.execute("SET search_path = ag_catalog, '$user', public;")
 
-        cursor.execute("SELECT typelem FROM pg_type WHERE typname='_agtype'")
-        oid = cursor.fetchone()[0]
-        if oid == None :
-            raise AgeNotSet()
+        ag_info = TypeInfo.fetch(conn, 'agtype')
 
-        AGETYPE = ext.new_type((oid,), 'AGETYPE', parseAgeValue)
-        ext.register_type(AGETYPE)
-        # ext.register_adapter(Path, marshalAgtValue)
+        if not ag_info:
+            raise AgeNotSet()
+    
+        conn.adapters.register_loader(ag_info.oid, AgeLoader)
+        conn.adapters.register_loader(ag_info.array_oid, AgeLoader)
 
         # Check graph exists
         if graphName != None:
             checkGraphCreated(conn, graphName)
 
 # Create the graph, if it does not exist
-def checkGraphCreated(conn:ext.connection, graphName:str):
+def checkGraphCreated(conn:psycopg.connection, graphName:str):
     with conn.cursor() as cursor:
         cursor.execute(sql.SQL("SELECT count(*) FROM ag_graph WHERE 
name={graphName}").format(graphName=sql.Literal(graphName)))
         if cursor.fetchone()[0] == 0:
@@ -54,7 +65,7 @@ def checkGraphCreated(conn:ext.connection, graphName:str):
             conn.commit()
 
 
-def deleteGraph(conn:ext.connection, graphName:str):
+def deleteGraph(conn:psycopg.connection, graphName:str):
     with conn.cursor() as cursor:
         cursor.execute(sql.SQL("SELECT drop_graph({graphName}, 
true);").format(graphName=sql.Literal(graphName)))
         conn.commit()
@@ -82,7 +93,7 @@ def buildCypher(graphName:str, cypherStmt:str, columns:list) 
->str:
     stmtArr.append(");")
     return "".join(stmtArr)
 
-def execSql(conn:ext.connection, stmt:str, commit:bool=False, 
params:tuple=None) -> ext.cursor :
+def execSql(conn:psycopg.connection, stmt:str, commit:bool=False, 
params:tuple=None) -> psycopg.cursor :
     if conn == None or conn.closed:
         raise _EXCEPTION_NoConnection
     
@@ -101,14 +112,14 @@ def execSql(conn:ext.connection, stmt:str, 
commit:bool=False, params:tuple=None)
         raise SqlExecutionError("Execution ERR[" + str(cause) +"](" + stmt 
+")", cause)
 
 
-def querySql(conn:ext.connection, stmt:str, params:tuple=None) -> ext.cursor :
+def querySql(conn:psycopg.connection, stmt:str, params:tuple=None) -> 
psycopg.cursor :
     return execSql(conn, stmt, False, params)
 
 # Execute cypher statement and return cursor.
 # If cypher statement changes data (create, set, remove),
 # You must commit session(ag.commit())
 # (Otherwise the execution cannot make any effect.)
-def execCypher(conn:ext.connection, graphName:str, cypherStmt:str, 
cols:list=None, params:tuple=None) -> ext.cursor :
+def execCypher(conn:psycopg.connection, graphName:str, cypherStmt:str, 
cols:list=None, params:tuple=None) -> psycopg.cursor :
     if conn == None or conn.closed:
         raise _EXCEPTION_NoConnection
 
@@ -117,7 +128,7 @@ def execCypher(conn:ext.connection, graphName:str, 
cypherStmt:str, cols:list=Non
     cypherStmt = cypherStmt.replace("\n", "")
     cypherStmt = cypherStmt.replace("\t", "")
     cypher = str(cursor.mogrify(cypherStmt, params))
-    cypher = cypher[2:len(cypher)-1]
+    cypher = cypher.strip()
 
     preparedStmt = "SELECT * FROM age_prepare_cypher({graphName},{cypherStmt})"
 
@@ -145,12 +156,12 @@ def execCypher(conn:ext.connection, graphName:str, 
cypherStmt:str, cols:list=Non
         raise SqlExecutionError("Execution ERR[" + str(cause) +"](" + stmt 
+")", cause)
 
 
-def cypher(cursor:ext.cursor, graphName:str, cypherStmt:str, cols:list=None, 
params:tuple=None) -> ext.cursor :
+def cypher(cursor:psycopg.cursor, graphName:str, cypherStmt:str, 
cols:list=None, params:tuple=None) -> psycopg.cursor :
     #clean up the string for mogrification
     cypherStmt = cypherStmt.replace("\n", "")
     cypherStmt = cypherStmt.replace("\t", "")
     cypher = str(cursor.mogrify(cypherStmt, params))
-    cypher = cypher[2:len(cypher)-1]
+    cypher = cypher.strip()
 
     preparedStmt = "SELECT * FROM age_prepare_cypher({graphName},{cypherStmt})"
     
cursor.execute(sql.SQL(preparedStmt).format(graphName=sql.Literal(graphName),cypherStmt=sql.Literal(cypher)))
@@ -159,22 +170,22 @@ def cypher(cursor:ext.cursor, graphName:str, 
cypherStmt:str, cols:list=None, par
     cursor.execute(stmt)
 
 
-# def execCypherWithReturn(conn:ext.connection, graphName:str, cypherStmt:str, 
columns:list=None , params:tuple=None) -> ext.cursor :
+# def execCypherWithReturn(conn:psycopg.connection, graphName:str, 
cypherStmt:str, columns:list=None , params:tuple=None) -> psycopg.cursor :
 #     stmt = buildCypher(graphName, cypherStmt, columns)
 #     return execSql(conn, stmt, False, params)
 
-# def queryCypher(conn:ext.connection, graphName:str, cypherStmt:str, 
columns:list=None , params:tuple=None) -> ext.cursor :
+# def queryCypher(conn:psycopg.connection, graphName:str, cypherStmt:str, 
columns:list=None , params:tuple=None) -> psycopg.cursor :
 #     return execCypherWithReturn(conn, graphName, cypherStmt, columns, params)
 
 
 class Age:
     def __init__(self):
-        self.connection = None    # psycopg2 connection]
+        self.connection = None    # psycopg connection]
         self.graphName = None
 
     # Connect to PostgreSQL Server and establish session and type extension 
environment.
-    def connect(self, graph:str=None, dsn:str=None, connection_factory=None, 
cursor_factory=None, **kwargs):
-        conn = psycopg2.connect(dsn, connection_factory, cursor_factory, 
**kwargs)
+    def connect(self, graph:str=None, dsn:str=None, connection_factory=None, 
cursor_factory=ClientCursor, **kwargs):
+        conn = psycopg.connect(dsn, cursor_factory=cursor_factory, **kwargs)
         setUpAge(conn, graph)
         self.connection = conn
         self.graphName = graph
@@ -194,21 +205,21 @@ class Age:
     def rollback(self):
         self.connection.rollback()
 
-    def execCypher(self, cypherStmt:str, cols:list=None, params:tuple=None) -> 
ext.cursor :
+    def execCypher(self, cypherStmt:str, cols:list=None, params:tuple=None) -> 
psycopg.cursor :
         return execCypher(self.connection, self.graphName, cypherStmt, 
cols=cols, params=params)
 
-    def cypher(self, cursor:ext.cursor, cypherStmt:str, cols:list=None, 
params:tuple=None) -> ext.cursor :
+    def cypher(self, cursor:psycopg.cursor, cypherStmt:str, cols:list=None, 
params:tuple=None) -> psycopg.cursor :
         return cypher(cursor, self.graphName, cypherStmt, cols=cols, 
params=params)
 
-    # def execSql(self, stmt:str, commit:bool=False, params:tuple=None) -> 
ext.cursor :
+    # def execSql(self, stmt:str, commit:bool=False, params:tuple=None) -> 
psycopg.cursor :
     #     return execSql(self.connection, stmt, commit, params)
 
 
-    # def execCypher(self, cypherStmt:str, commit:bool=False, 
params:tuple=None) -> ext.cursor :
+    # def execCypher(self, cypherStmt:str, commit:bool=False, 
params:tuple=None) -> psycopg.cursor :
     #     return execCypher(self.connection, self.graphName, cypherStmt, 
commit, params)
 
-    # def execCypherWithReturn(self, cypherStmt:str, columns:list=None , 
params:tuple=None) -> ext.cursor :
+    # def execCypherWithReturn(self, cypherStmt:str, columns:list=None , 
params:tuple=None) -> psycopg.cursor :
     #     return execCypherWithReturn(self.connection, self.graphName, 
cypherStmt, columns, params)
 
-    # def queryCypher(self, cypherStmt:str, columns:list=None , 
params:tuple=None) -> ext.cursor :
-    #     return queryCypher(self.connection, self.graphName, cypherStmt, 
columns, params)
+    # def queryCypher(self, cypherStmt:str, columns:list=None , 
params:tuple=None) -> psycopg.cursor :
+    #     return queryCypher(self.connection, self.graphName, cypherStmt, 
columns, params)
diff --git a/drivers/python/age/builder.py b/drivers/python/age/builder.py
index 0f4d7119..a3815b82 100644
--- a/drivers/python/age/builder.py
+++ b/drivers/python/age/builder.py
@@ -18,8 +18,8 @@ from .gen.AgtypeParser import AgtypeParser
 from .gen.AgtypeVisitor import AgtypeVisitor
 from .models import *
 from .exceptions import *
-from antlr4 import *
-from antlr4.tree.Tree import *
+from antlr4 import InputStream, CommonTokenStream, ParserRuleContext
+from antlr4.tree.Tree import TerminalNode
 from decimal import Decimal
 
 resultHandler = None
@@ -42,7 +42,7 @@ def parseAgeValue(value, cursor=None):
     try:
         return resultHandler.parse(value)
     except Exception as ex:
-        raise AGTypeError(value)
+        raise AGTypeError(value, ex)
 
 
 class Antlr4ResultHandler(ResultHandler):
diff --git a/drivers/python/age/exceptions.py b/drivers/python/age/exceptions.py
index 8c46e8e9..3aa94f4b 100644
--- a/drivers/python/age/exceptions.py
+++ b/drivers/python/age/exceptions.py
@@ -13,7 +13,7 @@
 # specific language governing permissions and limitations
 # under the License.
 
-from psycopg2.errors import *
+from psycopg.errors import *
 
 class AgeNotSet(Exception):
     def __init__(self, name):
diff --git a/drivers/python/age/networkx/age_to_networkx.py 
b/drivers/python/age/networkx/age_to_networkx.py
index 3a16aa3a..4e27a547 100644
--- a/drivers/python/age/networkx/age_to_networkx.py
+++ b/drivers/python/age/networkx/age_to_networkx.py
@@ -14,13 +14,13 @@
 # under the License.
 
 from age import *
-import psycopg2
+import psycopg
 import networkx as nx
 from age.models import Vertex, Edge, Path
 from .lib import *
 
 
-def age_to_networkx(connection: psycopg2.connect,
+def age_to_networkx(connection: psycopg.connect,
                     graphName: str,
                     G: None | nx.DiGraph = None,
                     query: str | None = None
@@ -28,7 +28,7 @@ def age_to_networkx(connection: psycopg2.connect,
     """
     @params
     ---------------------
-    connection - (psycopg2.connect) Connection object
+    connection - (psycopg.connect) Connection object
     graphName - (str) Name of the graph
     G - (networkx.DiGraph) Networkx directed Graph [optional]
     query - (str) Cypher query [optional]
diff --git a/drivers/python/age/networkx/lib.py 
b/drivers/python/age/networkx/lib.py
index a4df0886..30865862 100644
--- a/drivers/python/age/networkx/lib.py
+++ b/drivers/python/age/networkx/lib.py
@@ -14,15 +14,15 @@
 # under the License.
 
 from age import *
-import psycopg2
+import json
+import psycopg
 import networkx as nx
-from psycopg2 import sql
-from psycopg2.extras import execute_values
+from psycopg import sql
 from typing import Dict, Any, List, Set
 from age.models import Vertex, Edge, Path
 
 
-def checkIfGraphNameExistInAGE(connection: psycopg2.connect,
+def checkIfGraphNameExistInAGE(connection: psycopg.connect,
                                graphName: str):
     """Check if the age graph exists"""
     with connection.cursor() as cursor:
@@ -35,7 +35,7 @@ def checkIfGraphNameExistInAGE(connection: psycopg2.connect,
             raise GraphNotFound(graphName)
 
 
-def getOidOfGraph(connection: psycopg2.connect,
+def getOidOfGraph(connection: psycopg.connect,
                   graphName: str) -> int:
     """Returns oid of a graph"""
     try:
@@ -49,7 +49,7 @@ def getOidOfGraph(connection: psycopg2.connect,
         print(e)
 
 
-def get_vlabel(connection: psycopg2.connect,
+def get_vlabel(connection: psycopg.connect,
                graphName: str):
     node_label_list = []
     oid = getOidOfGraph(connection, graphName)
@@ -65,7 +65,7 @@ def get_vlabel(connection: psycopg2.connect,
     return node_label_list
 
 
-def create_vlabel(connection: psycopg2.connect,
+def create_vlabel(connection: psycopg.connect,
                   graphName: str,
                   node_label_list: List):
     """create_vlabels from list if not exist"""
@@ -85,7 +85,7 @@ def create_vlabel(connection: psycopg2.connect,
         raise Exception(e)
 
 
-def get_elabel(connection: psycopg2.connect,
+def get_elabel(connection: psycopg.connect,
                graphName: str):
     edge_label_list = []
     oid = getOidOfGraph(connection, graphName)
@@ -100,7 +100,7 @@ def get_elabel(connection: psycopg2.connect,
     return edge_label_list
 
 
-def create_elabel(connection: psycopg2.connect,
+def create_elabel(connection: psycopg.connect,
                   graphName: str,
                   edge_label_list: List):
     """create_vlabels from list if not exist"""
@@ -169,7 +169,7 @@ def getEdgeLabelListAfterPreprocessing(G: nx.DiGraph):
     return edge_label_list
 
 
-def addAllNodesIntoAGE(connection: psycopg2.connect, graphName: str, G: 
nx.DiGraph, node_label_list: Set):
+def addAllNodesIntoAGE(connection: psycopg.connect, graphName: str, G: 
nx.DiGraph, node_label_list: Set):
     """Add all node to AGE"""
     try:
         queue_data = {label: [] for label in node_label_list}
@@ -181,23 +181,29 @@ def addAllNodesIntoAGE(connection: psycopg2.connect, 
graphName: str, G: nx.DiGra
 
         for label, rows in queue_data.items():
             table_name = """%s."%s" """ % (graphName, label)
-            insert_query = f"INSERT INTO {table_name} (properties) VALUES %s 
RETURNING id"
+            insert_query = f"INSERT INTO {table_name} (properties) VALUES (%s) 
RETURNING id"
             cursor = connection.cursor()
-            id_data[label] = execute_values(
-                cursor, insert_query, rows, fetch=True)
+            cursor.executemany(insert_query, rows, returning=True)
+            ids = []
+            while True:
+                ids.append(cursor.fetchone()[0])
+                if not cursor.nextset():
+                    break
+
+            id_data[label] = ids
             connection.commit()
             cursor.close()
             id_data[label].reverse()
 
         for node, data in G.nodes(data=True):
-            data['properties']['__gid__'] = id_data[data['label']][-1][0]
+            data['properties']['__gid__'] = id_data[data['label']][-1]
             id_data[data['label']].pop()
 
     except Exception as e:
         raise Exception(e)
 
 
-def addAllEdgesIntoAGE(connection: psycopg2.connect, graphName: str, G: 
nx.DiGraph, edge_label_list: Set):
+def addAllEdgesIntoAGE(connection: psycopg.connect, graphName: str, G: 
nx.DiGraph, edge_label_list: Set):
     """Add all edge to AGE"""
     try:
         queue_data = {label: [] for label in edge_label_list}
@@ -208,16 +214,16 @@ def addAllEdgesIntoAGE(connection: psycopg2.connect, 
graphName: str, G: nx.DiGra
 
         for label, rows in queue_data.items():
             table_name = """%s."%s" """ % (graphName, label)
-            insert_query = f"INSERT INTO {table_name} 
(start_id,end_id,properties) VALUES %s"
+            insert_query = f"INSERT INTO {table_name} 
(start_id,end_id,properties) VALUES (%s, %s, %s)"
             cursor = connection.cursor()
-            execute_values(cursor, insert_query, rows)
+            cursor.executemany(insert_query, rows)
             connection.commit()
             cursor.close()
     except Exception as e:
         raise Exception(e)
 
 
-def addAllNodesIntoNetworkx(connection: psycopg2.connect, graphName: str, G: 
nx.DiGraph):
+def addAllNodesIntoNetworkx(connection: psycopg.connect, graphName: str, G: 
nx.DiGraph):
     """Add all nodes to Networkx"""
     node_label_list = get_vlabel(connection, graphName)
     try:
@@ -235,7 +241,7 @@ def addAllNodesIntoNetworkx(connection: psycopg2.connect, 
graphName: str, G: nx.
         print(e)
 
 
-def addAllEdgesIntoNetworkx(connection: psycopg2.connect, graphName: str, G: 
nx.DiGraph):
+def addAllEdgesIntoNetworkx(connection: psycopg.connect, graphName: str, G: 
nx.DiGraph):
     """Add All edges to Networkx"""
     try:
         edge_label_list = get_elabel(connection, graphName)
diff --git a/drivers/python/age/networkx/networkx_to_age.py 
b/drivers/python/age/networkx/networkx_to_age.py
index 90cee97b..053193c8 100644
--- a/drivers/python/age/networkx/networkx_to_age.py
+++ b/drivers/python/age/networkx/networkx_to_age.py
@@ -14,18 +14,18 @@
 # under the License.
 
 from age import *
-import psycopg2
+import psycopg
 import networkx as nx
 from .lib import *
 
 
-def networkx_to_age(connection: psycopg2.connect,
+def networkx_to_age(connection: psycopg.connect,
                     G: nx.DiGraph,
                     graphName: str):
     """
     @params
     -----------
-    connection - (psycopg2.connect) Connection object
+    connection - (psycopg.connect) Connection object
 
     G - (networkx.DiGraph) Networkx directed Graph
 
diff --git a/drivers/python/requirements.txt b/drivers/python/requirements.txt
index 81d1ef75..b0593b79 100644
Binary files a/drivers/python/requirements.txt and 
b/drivers/python/requirements.txt differ
diff --git a/drivers/python/samples/apache-age-agtypes.ipynb 
b/drivers/python/samples/apache-age-agtypes.ipynb
index 141ff3f4..7055db98 100644
--- a/drivers/python/samples/apache-age-agtypes.ipynb
+++ b/drivers/python/samples/apache-age-agtypes.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 12,
    "id": "6301516b-a3fa-48e2-a95f-0f79903a6cdd",
    "metadata": {},
    "outputs": [],
@@ -22,10 +22,32 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 13,
    "id": "adf14fe9-692c-4701-86d4-8c84fd53d966",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<class 'dict'> | {\"name\": \"Smith\", \"num\":123, \"yn\":true, 
\"bigInt\":123456789123456789123456789123456789::numeric}  -->  {'name': 
'Smith', 'num': 123, 'yn': True, 'bigInt': 
Decimal('123456789123456789123456789123456789')}\n",
+      "<class 'list'> | [\"name\", \"Smith\", \"num\", 123, \"yn\", true, 
123456789123456789123456789123456789.8888::numeric]  -->  ['name', 'Smith', 
'num', 123, 'yn', True, 
Decimal('123456789123456789123456789123456789.8888')]\n",
+      "<class 'str'> | \"abcd\"  -->  abcd\n",
+      "<class 'int'> | 1234  -->  1234\n",
+      "<class 'float'> | 1234.56789  -->  1234.56789\n",
+      "<class 'decimal.Decimal'> | 
12345678901234567890123456789123456789.789::numeric  -->  
12345678901234567890123456789123456789.789\n",
+      "<class 'decimal.Decimal'> | 
12345678901234567890123456789123456789::numeric  -->  
12345678901234567890123456789123456789\n",
+      "<class 'bool'> | true  -->  True\n",
+      "<class 'float'> | -6.45161290322581e+46  -->  -6.45161290322581e+46\n",
+      "<class 'decimal.Decimal'> | -123456789.99::numeric  -->  
-123456789.99\n",
+      "<class 'decimal.Decimal'> | -6.45161290322581e+46::numeric  -->  
-6.45161290322581E+46\n",
+      "<class 'int'> | 1234  -->  1234\n",
+      "<class 'float'> | NaN  -->  nan\n",
+      "<class 'float'> | -Infinity  -->  -inf\n",
+      "<class 'float'> | Infinity  -->  inf\n"
+     ]
+    }
+   ],
    "source": [
     "\n",
     "mapStr = '{\"name\": \"Smith\", \"num\":123, \"yn\":true, 
\"bigInt\":123456789123456789123456789123456789::numeric}' \n",
@@ -57,10 +79,26 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 14,
    "id": "8881804e-d71d-4704-b74c-376ed55be808",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<class 'int'> 2251799813685425\n",
+      "<class 'str'> Person\n",
+      "<class 'str'> Smith\n",
+      "<class 'int'> 123\n",
+      "<class 'float'> 384.23424\n",
+      "<class 'decimal.Decimal'> 
123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789123456789\n",
+      "<class 'decimal.Decimal'> 123456789123456789123456789123456789.12345\n",
+      "<class 'bool'> True\n",
+      "<class 'NoneType'> None\n"
+     ]
+    }
+   ],
    "source": [
     "vertexExp = '''{\"id\": 2251799813685425, \"label\": \"Person\", \n",
     "    \"properties\": {\"name\": \"Smith\", \"numInt\":123, \"numFloat\": 
384.23424, \n",
@@ -82,10 +120,27 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 15,
    "id": "0a70e467-9587-4eb7-b97d-895223009bcc",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "<class 'int'> 2251799813685425\n",
+      "<class 'str'> Person\n",
+      "<class 'str'> Smith\n",
+      "<class 'int'> 2533274790396576\n",
+      "<class 'str'> workWith\n",
+      "<class 'int'> 3\n",
+      "<class 'decimal.Decimal'> 123456789123456789123456789.12345\n",
+      "<class 'int'> 2251799813685424\n",
+      "<class 'str'> Person\n",
+      "<class 'str'> Joe\n"
+     ]
+    }
+   ],
    "source": [
     "\n",
     "pathExp = '''[{\"id\": 2251799813685425, \"label\": \"Person\", 
\"properties\": {\"name\": \"Smith\"}}::vertex, \n",
@@ -138,7 +193,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.2"
+   "version": "3.11.1"
   }
  },
  "nbformat": 4,
diff --git a/drivers/python/samples/apache-age-basic.ipynb 
b/drivers/python/samples/apache-age-basic.ipynb
index f1749630..59de8e42 100644
--- a/drivers/python/samples/apache-age-basic.ipynb
+++ b/drivers/python/samples/apache-age-basic.ipynb
@@ -5,9 +5,9 @@
    "id": "2e236ac7-6f78-4a59-bed7-45f593d060c2",
    "metadata": {},
    "source": [
-    "# Basic Samples : Agtype mapper for Psycopg2 driver\n",
+    "# Basic Samples : Agtype mapper for psycopg driver\n",
     "\n",
-    "You can make transactions and queries for PostgreSQL with Psycopg2.\n",
+    "You can make transactions and queries for PostgreSQL with Psycopg.\n",
     "\n",
     "This module enable to mapping agtype to python class(Path, Vertex, 
Edge)\n",
     "\n",
@@ -16,26 +16,46 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 21,
    "id": "98a5863c-1e79-438e-81d4-d1f5354a1bdb",
    "metadata": {},
    "outputs": [],
    "source": [
-    "import psycopg2 \n",
+    "import psycopg \n",
     "import age\n",
     "\n",
     "GRAPH_NAME = \"test_graph\"\n",
-    "conn = psycopg2.connect(host=\"172.17.0.2\", port=\"5432\", 
dbname=\"postgres\", user=\"postgres\", password=\"agens\")\n",
-    "\n",
-    "age.setUpAge(conn, GRAPH_NAME)\n"
+    "ag = age.connect(host=\"172.17.0.2\", port=\"5432\", dbname=\"postgre\", 
user=\"postgres\", password=\"agens\", graph=GRAPH_NAME)\n",
+    "conn = ag.connection\n"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 22,
    "id": "ebcf65a5-de7c-4224-aacc-2695c9e5f8d5",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "CREATED:: {label:Person, id:844424930131971, properties:{name: Tom, 
title: Manager}}::VERTEX\n",
+      "------- [Select Vertices] --------\n",
+      "844424930131969 Person Joe Developer\n",
+      "--> {label:Person, id:844424930131969, properties:{name: Joe, title: 
Developer}}::VERTEX\n",
+      "844424930131970 Person Smith Developer\n",
+      "--> {label:Person, id:844424930131970, properties:{name: Smith, title: 
Developer}}::VERTEX\n",
+      "844424930131971 Person Tom Manager\n",
+      "--> {label:Person, id:844424930131971, properties:{name: Tom, title: 
Manager}}::VERTEX\n",
+      "<class 'psycopg.ClientCursor'>\n",
+      "------- [Select Paths] --------\n",
+      "1 Joe 2 workWith 5 1 Smith\n",
+      "--> [{label:Person, id:844424930131969, properties:{name: Joe, title: 
Developer}}::VERTEX,{label:workWith, id:1125899906842625, properties:{weight: 
5}, start_id:844424930131969, end_id:844424930131970}::EDGE,{label:Person, 
id:844424930131970, properties:{name: Smith, title: 
Developer}}::VERTEX]::PATH\n",
+      "1 Smith 2 workWith 3 1 Tom\n",
+      "--> [{label:Person, id:844424930131970, properties:{name: Smith, title: 
Developer}}::VERTEX,{label:workWith, id:1125899906842626, properties:{weight: 
3}, start_id:844424930131970, end_id:844424930131971}::EDGE,{label:Person, 
id:844424930131971, properties:{name: Tom, title: Manager}}::VERTEX]::PATH\n"
+     ]
+    }
+   ],
    "source": [
     "with conn.cursor() as cursor:\n",
     "    try :\n",
@@ -91,10 +111,21 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 23,
    "id": "f45f7c7d-2256-4aea-92f6-e0ad71017feb",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Joe workWith Smith\n",
+      "--> ('Joe', 'workWith', 'Smith')\n",
+      "Smith workWith Tom\n",
+      "--> ('Smith', 'workWith', 'Tom')\n"
+     ]
+    }
+   ],
    "source": [
     "with conn.cursor() as cursor:\n",
     "    try:\n",
@@ -111,10 +142,20 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 24,
    "id": "c40b9076-d45e-43e6-85ae-296ba68a3031",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Joe {'weight': 5} Smith\n",
+      "Smith {'weight': 3} Tom\n",
+      "Jack {'weight': 2} John\n"
+     ]
+    }
+   ],
    "source": [
     "with conn.cursor() as cursor:\n",
     "    try :\n",
@@ -152,10 +193,20 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 25,
    "id": "29ffe1b7-86df-446a-9df0-635be25a9eea",
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Joe 1125899906842625 {'weight': 5} Smith\n",
+      "Smith 1125899906842626 {'weight': 3} Tom\n",
+      "Jack 1125899906842627 {'weight': 2} John\n"
+     ]
+    }
+   ],
    "source": [
     "with conn.cursor() as cursor:\n",
     "    try:\n",
@@ -172,7 +223,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 26,
    "id": "428e6ddf-3958-49ff-af73-809b9a1ce42b",
    "metadata": {},
    "outputs": [],
@@ -180,25 +231,6 @@
     "age.deleteGraph(conn, GRAPH_NAME)\n",
     "conn.close()"
    ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "a4819e39-9f37-4dd5-bdbd-337b6d289158",
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "\n",
-    "    "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "02041ef2-9761-4eb3-b270-ded23e1caa6d",
-   "metadata": {},
-   "outputs": [],
-   "source": []
   }
  ],
  "metadata": {
@@ -217,7 +249,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.2"
+   "version": "3.11.1"
   }
  },
  "nbformat": 4,
diff --git a/drivers/python/samples/apache-age-note.ipynb 
b/drivers/python/samples/apache-age-note.ipynb
index 59c25bc5..d6bcf69b 100644
--- a/drivers/python/samples/apache-age-note.ipynb
+++ b/drivers/python/samples/apache-age-note.ipynb
@@ -131,12 +131,10 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "CREATED:  {label:Person, id:844424930131975, properties:{name: Jack, 
}}::VERTEX\n",
-      "CREATED:  844424930131976\n",
+      "CREATED:  {label:Person, id:844424930131971, properties:{name: 
Jack}}::VERTEX\n",
+      "CREATED:  844424930131972\n",
       "SET:  \"Manager\"\n",
-      "SET:  \"Manager\"\n",
-      "REMOVE Prop:  844424930131970\n",
-      "REMOVE Prop:  844424930131974\n"
+      "REMOVE Prop:  844424930131970\n"
      ]
     }
    ],
@@ -221,29 +219,17 @@
      "text": [
       "-- Query Vertices  --------------------\n",
       "844424930131969 Person Joe\n",
-      "--> {label:Person, id:844424930131969, properties:{name: Joe, 
}}::VERTEX\n",
+      "--> {label:Person, id:844424930131969, properties:{name: 
Joe}}::VERTEX\n",
       "844424930131971 Person Jack\n",
-      "--> {label:Person, id:844424930131971, properties:{name: Jack, 
}}::VERTEX\n",
+      "--> {label:Person, id:844424930131971, properties:{name: 
Jack}}::VERTEX\n",
       "844424930131972 Person Andy\n",
-      "--> {label:Person, id:844424930131972, properties:{name: Andy, title: 
Developer, }}::VERTEX\n",
-      "844424930131973 Person Joe\n",
-      "--> {label:Person, id:844424930131973, properties:{name: Joe, 
}}::VERTEX\n",
-      "844424930131975 Person Jack\n",
-      "--> {label:Person, id:844424930131975, properties:{name: Jack, 
}}::VERTEX\n",
-      "844424930131976 Person Andy\n",
-      "--> {label:Person, id:844424930131976, properties:{name: Andy, title: 
Developer, }}::VERTEX\n",
+      "--> {label:Person, id:844424930131972, properties:{name: Andy, title: 
Developer}}::VERTEX\n",
       "844424930131970 Person Smith\n",
-      "--> {label:Person, id:844424930131970, properties:{name: Smith, 
}}::VERTEX\n",
-      "844424930131974 Person Smith\n",
-      "--> {label:Person, id:844424930131974, properties:{name: Smith, 
}}::VERTEX\n",
+      "--> {label:Person, id:844424930131970, properties:{name: 
Smith}}::VERTEX\n",
       "-- Query Vertices with with multi columns. --------------------\n",
       "\"Person\" Joe\n",
       "\"Person\" Jack\n",
       "\"Person\" Andy\n",
-      "\"Person\" Joe\n",
-      "\"Person\" Jack\n",
-      "\"Person\" Andy\n",
-      "\"Person\" Smith\n",
       "\"Person\" Smith\n"
      ]
     }
@@ -305,14 +291,8 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "[{label:Person, id:844424930131972, properties:{name: Andy, title: 
Developer, }}::VERTEX,{label:workWith, id:1125899906842637, properties:{}, 
start_id:844424930131972, end_id:844424930131970}::EDGE,{label:Person, 
id:844424930131970, properties:{name: Smith, }}::VERTEX]::PATH\n",
-      "[{label:Person, id:844424930131972, properties:{name: Andy, title: 
Developer, }}::VERTEX,{label:workWith, id:1125899906842638, properties:{}, 
start_id:844424930131972, end_id:844424930131974}::EDGE,{label:Person, 
id:844424930131974, properties:{name: Smith, }}::VERTEX]::PATH\n",
-      "[{label:Person, id:844424930131976, properties:{name: Andy, title: 
Developer, }}::VERTEX,{label:workWith, id:1125899906842639, properties:{}, 
start_id:844424930131976, end_id:844424930131970}::EDGE,{label:Person, 
id:844424930131970, properties:{name: Smith, }}::VERTEX]::PATH\n",
-      "[{label:Person, id:844424930131976, properties:{name: Andy, title: 
Developer, }}::VERTEX,{label:workWith, id:1125899906842640, properties:{}, 
start_id:844424930131976, end_id:844424930131974}::EDGE,{label:Person, 
id:844424930131974, properties:{name: Smith, }}::VERTEX]::PATH\n",
-      "(a) {label:Person, id:844424930131969, properties:{name: Joe, 
}}::VERTEX : (r) {label:workWith, id:1125899906842641, properties:{weight: 5, 
}, start_id:844424930131969, end_id:844424930131971}::EDGE : (b) {label:Person, 
id:844424930131971, properties:{name: Jack, }}::VERTEX\n",
-      "(a) {label:Person, id:844424930131969, properties:{name: Joe, 
}}::VERTEX : (r) {label:workWith, id:1125899906842642, properties:{weight: 5, 
}, start_id:844424930131969, end_id:844424930131975}::EDGE : (b) {label:Person, 
id:844424930131975, properties:{name: Jack, }}::VERTEX\n",
-      "(a) {label:Person, id:844424930131973, properties:{name: Joe, 
}}::VERTEX : (r) {label:workWith, id:1125899906842643, properties:{weight: 5, 
}, start_id:844424930131973, end_id:844424930131971}::EDGE : (b) {label:Person, 
id:844424930131971, properties:{name: Jack, }}::VERTEX\n",
-      "(a) {label:Person, id:844424930131973, properties:{name: Joe, 
}}::VERTEX : (r) {label:workWith, id:1125899906842644, properties:{weight: 5, 
}, start_id:844424930131973, end_id:844424930131975}::EDGE : (b) {label:Person, 
id:844424930131975, properties:{name: Jack, }}::VERTEX\n"
+      "[{label:Person, id:844424930131972, properties:{name: Andy, title: 
Developer}}::VERTEX,{label:workWith, id:1125899906842627, properties:{}, 
start_id:844424930131972, end_id:844424930131970}::EDGE,{label:Person, 
id:844424930131970, properties:{name: Smith}}::VERTEX]::PATH\n",
+      "(a) {label:Person, id:844424930131969, properties:{name: Joe}}::VERTEX 
: (r) {label:workWith, id:1125899906842628, properties:{weight: 5}, 
start_id:844424930131969, end_id:844424930131971}::EDGE : (b) {label:Person, 
id:844424930131971, properties:{name: Jack}}::VERTEX\n"
      ]
     }
    ],
@@ -393,7 +373,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 7,
    "id": "7673e270-4ea3-4878-961c-8fc97106e1bd",
    "metadata": {},
    "outputs": [
@@ -401,156 +381,36 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "START: {label:Person, id:844424930131971, properties:{name: Jack, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842628, properties:{weight: 5, }, 
start_id:844424930131969, end_id:844424930131971}::EDGE\n",
-      "END: {label:Person, id:844424930131969, properties:{name: Joe, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131971, properties:{name: Jack, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842641, properties:{weight: 5, }, 
start_id:844424930131969, end_id:844424930131971}::EDGE\n",
-      "END: {label:Person, id:844424930131969, properties:{name: Joe, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131975, properties:{name: Jack, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842642, properties:{weight: 5, }, 
start_id:844424930131969, end_id:844424930131975}::EDGE\n",
-      "END: {label:Person, id:844424930131969, properties:{name: Joe, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131970, properties:{name: Smith, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842625, properties:{weight: 3, }, 
start_id:844424930131969, end_id:844424930131970}::EDGE\n",
-      "END: {label:Person, id:844424930131969, properties:{name: Joe, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131970, properties:{name: Smith, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842629, properties:{weight: 3, }, 
start_id:844424930131969, end_id:844424930131970}::EDGE\n",
-      "END: {label:Person, id:844424930131969, properties:{name: Joe, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131974, properties:{name: Smith, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842630, properties:{weight: 3, }, 
start_id:844424930131969, end_id:844424930131974}::EDGE\n",
-      "END: {label:Person, id:844424930131969, properties:{name: Joe, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131969, properties:{name: Joe, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842628, properties:{weight: 5, }, 
start_id:844424930131969, end_id:844424930131971}::EDGE\n",
-      "END: {label:Person, id:844424930131971, properties:{name: Jack, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131969, properties:{name: Joe, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842641, properties:{weight: 5, }, 
start_id:844424930131969, end_id:844424930131971}::EDGE\n",
-      "END: {label:Person, id:844424930131971, properties:{name: Jack, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131972, properties:{name: Andy, 
title: Developer, }}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842626, properties:{weight: 5, }, 
start_id:844424930131971, end_id:844424930131972}::EDGE\n",
-      "END: {label:Person, id:844424930131971, properties:{name: Jack, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131972, properties:{name: Andy, 
title: Developer, }}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842633, properties:{weight: 5, }, 
start_id:844424930131971, end_id:844424930131972}::EDGE\n",
-      "END: {label:Person, id:844424930131971, properties:{name: Jack, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131973, properties:{name: Joe, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842643, properties:{weight: 5, }, 
start_id:844424930131973, end_id:844424930131971}::EDGE\n",
-      "END: {label:Person, id:844424930131971, properties:{name: Jack, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131976, properties:{name: Andy, 
title: Developer, }}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842634, properties:{weight: 5, }, 
start_id:844424930131971, end_id:844424930131976}::EDGE\n",
-      "END: {label:Person, id:844424930131971, properties:{name: Jack, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131971, properties:{name: Jack, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842626, properties:{weight: 5, }, 
start_id:844424930131971, end_id:844424930131972}::EDGE\n",
-      "END: {label:Person, id:844424930131972, properties:{name: Andy, title: 
Developer, }}::VERTEX\n",
-      "START: {label:Person, id:844424930131971, properties:{name: Jack, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842633, properties:{weight: 5, }, 
start_id:844424930131971, end_id:844424930131972}::EDGE\n",
-      "END: {label:Person, id:844424930131972, properties:{name: Andy, title: 
Developer, }}::VERTEX\n",
-      "START: {label:Person, id:844424930131975, properties:{name: Jack, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842635, properties:{weight: 5, }, 
start_id:844424930131975, end_id:844424930131972}::EDGE\n",
-      "END: {label:Person, id:844424930131972, properties:{name: Andy, title: 
Developer, }}::VERTEX\n",
-      "START: {label:Person, id:844424930131970, properties:{name: Smith, 
}}::VERTEX\n",
+      "START: {label:Person, id:844424930131971, properties:{name: 
Jack}}::VERTEX\n",
+      "EDGE: {label:workWith, id:1125899906842628, properties:{weight: 5}, 
start_id:844424930131969, end_id:844424930131971}::EDGE\n",
+      "END: {label:Person, id:844424930131969, properties:{name: 
Joe}}::VERTEX\n",
+      "START: {label:Person, id:844424930131970, properties:{name: 
Smith}}::VERTEX\n",
+      "EDGE: {label:workWith, id:1125899906842625, properties:{weight: 3}, 
start_id:844424930131969, end_id:844424930131970}::EDGE\n",
+      "END: {label:Person, id:844424930131969, properties:{name: 
Joe}}::VERTEX\n",
+      "START: {label:Person, id:844424930131969, properties:{name: 
Joe}}::VERTEX\n",
+      "EDGE: {label:workWith, id:1125899906842628, properties:{weight: 5}, 
start_id:844424930131969, end_id:844424930131971}::EDGE\n",
+      "END: {label:Person, id:844424930131971, properties:{name: 
Jack}}::VERTEX\n",
+      "START: {label:Person, id:844424930131972, properties:{name: Andy, 
title: Developer}}::VERTEX\n",
+      "EDGE: {label:workWith, id:1125899906842626, properties:{weight: 5}, 
start_id:844424930131971, end_id:844424930131972}::EDGE\n",
+      "END: {label:Person, id:844424930131971, properties:{name: 
Jack}}::VERTEX\n",
+      "START: {label:Person, id:844424930131971, properties:{name: 
Jack}}::VERTEX\n",
+      "EDGE: {label:workWith, id:1125899906842626, properties:{weight: 5}, 
start_id:844424930131971, end_id:844424930131972}::EDGE\n",
+      "END: {label:Person, id:844424930131972, properties:{name: Andy, title: 
Developer}}::VERTEX\n",
+      "START: {label:Person, id:844424930131970, properties:{name: 
Smith}}::VERTEX\n",
       "EDGE: {label:workWith, id:1125899906842627, properties:{}, 
start_id:844424930131972, end_id:844424930131970}::EDGE\n",
-      "END: {label:Person, id:844424930131972, properties:{name: Andy, title: 
Developer, }}::VERTEX\n",
-      "START: {label:Person, id:844424930131970, properties:{name: Smith, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842637, properties:{}, 
start_id:844424930131972, end_id:844424930131970}::EDGE\n",
-      "END: {label:Person, id:844424930131972, properties:{name: Andy, title: 
Developer, }}::VERTEX\n",
-      "START: {label:Person, id:844424930131974, properties:{name: Smith, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842638, properties:{}, 
start_id:844424930131972, end_id:844424930131974}::EDGE\n",
-      "END: {label:Person, id:844424930131972, properties:{name: Andy, title: 
Developer, }}::VERTEX\n",
-      "START: {label:Person, id:844424930131971, properties:{name: Jack, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842643, properties:{weight: 5, }, 
start_id:844424930131973, end_id:844424930131971}::EDGE\n",
-      "END: {label:Person, id:844424930131973, properties:{name: Joe, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131975, properties:{name: Jack, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842644, properties:{weight: 5, }, 
start_id:844424930131973, end_id:844424930131975}::EDGE\n",
-      "END: {label:Person, id:844424930131973, properties:{name: Joe, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131970, properties:{name: Smith, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842631, properties:{weight: 3, }, 
start_id:844424930131973, end_id:844424930131970}::EDGE\n",
-      "END: {label:Person, id:844424930131973, properties:{name: Joe, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131974, properties:{name: Smith, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842632, properties:{weight: 3, }, 
start_id:844424930131973, end_id:844424930131974}::EDGE\n",
-      "END: {label:Person, id:844424930131973, properties:{name: Joe, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131969, properties:{name: Joe, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842642, properties:{weight: 5, }, 
start_id:844424930131969, end_id:844424930131975}::EDGE\n",
-      "END: {label:Person, id:844424930131975, properties:{name: Jack, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131972, properties:{name: Andy, 
title: Developer, }}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842635, properties:{weight: 5, }, 
start_id:844424930131975, end_id:844424930131972}::EDGE\n",
-      "END: {label:Person, id:844424930131975, properties:{name: Jack, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131973, properties:{name: Joe, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842644, properties:{weight: 5, }, 
start_id:844424930131973, end_id:844424930131975}::EDGE\n",
-      "END: {label:Person, id:844424930131975, properties:{name: Jack, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131976, properties:{name: Andy, 
title: Developer, }}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842636, properties:{weight: 5, }, 
start_id:844424930131975, end_id:844424930131976}::EDGE\n",
-      "END: {label:Person, id:844424930131975, properties:{name: Jack, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131971, properties:{name: Jack, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842634, properties:{weight: 5, }, 
start_id:844424930131971, end_id:844424930131976}::EDGE\n",
-      "END: {label:Person, id:844424930131976, properties:{name: Andy, title: 
Developer, }}::VERTEX\n",
-      "START: {label:Person, id:844424930131975, properties:{name: Jack, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842636, properties:{weight: 5, }, 
start_id:844424930131975, end_id:844424930131976}::EDGE\n",
-      "END: {label:Person, id:844424930131976, properties:{name: Andy, title: 
Developer, }}::VERTEX\n",
-      "START: {label:Person, id:844424930131970, properties:{name: Smith, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842639, properties:{}, 
start_id:844424930131976, end_id:844424930131970}::EDGE\n",
-      "END: {label:Person, id:844424930131976, properties:{name: Andy, title: 
Developer, }}::VERTEX\n",
-      "START: {label:Person, id:844424930131974, properties:{name: Smith, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842640, properties:{}, 
start_id:844424930131976, end_id:844424930131974}::EDGE\n",
-      "END: {label:Person, id:844424930131976, properties:{name: Andy, title: 
Developer, }}::VERTEX\n",
-      "START: {label:Person, id:844424930131969, properties:{name: Joe, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842625, properties:{weight: 3, }, 
start_id:844424930131969, end_id:844424930131970}::EDGE\n",
-      "END: {label:Person, id:844424930131970, properties:{name: Smith, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131969, properties:{name: Joe, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842629, properties:{weight: 3, }, 
start_id:844424930131969, end_id:844424930131970}::EDGE\n",
-      "END: {label:Person, id:844424930131970, properties:{name: Smith, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131972, properties:{name: Andy, 
title: Developer, }}::VERTEX\n",
+      "END: {label:Person, id:844424930131972, properties:{name: Andy, title: 
Developer}}::VERTEX\n",
+      "START: {label:Person, id:844424930131969, properties:{name: 
Joe}}::VERTEX\n",
+      "EDGE: {label:workWith, id:1125899906842625, properties:{weight: 3}, 
start_id:844424930131969, end_id:844424930131970}::EDGE\n",
+      "END: {label:Person, id:844424930131970, properties:{name: 
Smith}}::VERTEX\n",
+      "START: {label:Person, id:844424930131972, properties:{name: Andy, 
title: Developer}}::VERTEX\n",
       "EDGE: {label:workWith, id:1125899906842627, properties:{}, 
start_id:844424930131972, end_id:844424930131970}::EDGE\n",
-      "END: {label:Person, id:844424930131970, properties:{name: Smith, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131972, properties:{name: Andy, 
title: Developer, }}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842637, properties:{}, 
start_id:844424930131972, end_id:844424930131970}::EDGE\n",
-      "END: {label:Person, id:844424930131970, properties:{name: Smith, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131973, properties:{name: Joe, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842631, properties:{weight: 3, }, 
start_id:844424930131973, end_id:844424930131970}::EDGE\n",
-      "END: {label:Person, id:844424930131970, properties:{name: Smith, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131976, properties:{name: Andy, 
title: Developer, }}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842639, properties:{}, 
start_id:844424930131976, end_id:844424930131970}::EDGE\n",
-      "END: {label:Person, id:844424930131970, properties:{name: Smith, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131969, properties:{name: Joe, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842630, properties:{weight: 3, }, 
start_id:844424930131969, end_id:844424930131974}::EDGE\n",
-      "END: {label:Person, id:844424930131974, properties:{name: Smith, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131972, properties:{name: Andy, 
title: Developer, }}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842638, properties:{}, 
start_id:844424930131972, end_id:844424930131974}::EDGE\n",
-      "END: {label:Person, id:844424930131974, properties:{name: Smith, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131973, properties:{name: Joe, 
}}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842632, properties:{weight: 3, }, 
start_id:844424930131973, end_id:844424930131974}::EDGE\n",
-      "END: {label:Person, id:844424930131974, properties:{name: Smith, 
}}::VERTEX\n",
-      "START: {label:Person, id:844424930131976, properties:{name: Andy, 
title: Developer, }}::VERTEX\n",
-      "EDGE: {label:workWith, id:1125899906842640, properties:{}, 
start_id:844424930131976, end_id:844424930131974}::EDGE\n",
-      "END: {label:Person, id:844424930131974, properties:{name: Smith, 
}}::VERTEX\n",
+      "END: {label:Person, id:844424930131970, properties:{name: 
Smith}}::VERTEX\n",
       "-- [Query path with multi columns --------\n",
       "Jack workWith 5 Joe\n",
-      "Jack workWith 5 Joe\n",
-      "Jack workWith 5 Joe\n",
-      "Smith workWith 3 Joe\n",
-      "Smith workWith 3 Joe\n",
-      "Smith workWith 3 Joe\n",
-      "Joe workWith 5 Jack\n",
-      "Joe workWith 5 Jack\n",
-      "Andy workWith 5 Jack\n",
-      "Andy workWith 5 Jack\n",
-      "Joe workWith 5 Jack\n",
-      "Andy workWith 5 Jack\n",
-      "Jack workWith 5 Andy\n",
-      "Jack workWith 5 Andy\n",
-      "Jack workWith 5 Andy\n",
-      "Jack workWith 5 Joe\n",
-      "Jack workWith 5 Joe\n",
-      "Smith workWith 3 Joe\n",
       "Smith workWith 3 Joe\n",
       "Joe workWith 5 Jack\n",
       "Andy workWith 5 Jack\n",
-      "Joe workWith 5 Jack\n",
-      "Andy workWith 5 Jack\n",
       "Jack workWith 5 Andy\n",
-      "Jack workWith 5 Andy\n",
-      "Joe workWith 3 Smith\n",
-      "Joe workWith 3 Smith\n",
-      "Joe workWith 3 Smith\n",
-      "Joe workWith 3 Smith\n",
       "Joe workWith 3 Smith\n"
      ]
     }
@@ -564,7 +424,7 @@
     "    print(\"END:\", path[2])  \n",
     "\n",
     "print(\"-- [Query path with multi columns --------\")\n",
-    "cursor = ag.execCypher(\"MATCH p=(a)-[b]-(c) WHERE b.weight>2 RETURN 
a,label(b), b.weight, c\", cols=[\"a\",\"bl\",\"bw\", \"c\"], params=(2,))\n",
+    "cursor = ag.execCypher(\"MATCH p=(a)-[b]-(c) WHERE b.weight>%s RETURN 
a,label(b), b.weight, c\", cols=[\"a\",\"bl\",\"bw\", \"c\"], params=(2,))\n",
     "for row in cursor:\n",
     "    start = row[0]\n",
     "    edgel = row[1]\n",
@@ -588,7 +448,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 8,
    "id": "5771219a",
    "metadata": {},
    "outputs": [
@@ -596,22 +456,14 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Joe workWith ['Smith', 'Smith', 'Jack', 'Jack', 'Smith', 'Jack']\n",
-      "Smith workWith ['Joe', 'Joe', 'Andy', 'Andy', 'Joe', 'Andy']\n",
-      "Jack workWith ['Joe', 'Joe', 'Andy', 'Andy', 'Joe', 'Andy']\n",
-      "Andy workWith ['Smith', 'Smith', 'Jack', 'Jack', 'Smith', 'Jack']\n",
-      "Joe workWith ['Jack', 'Smith', 'Jack', 'Smith']\n",
-      "Smith workWith ['Andy', 'Joe', 'Andy', 'Joe']\n",
-      "Jack workWith ['Joe', 'Joe', 'Andy', 'Andy']\n",
-      "Andy workWith ['Jack', 'Smith', 'Jack', 'Smith']\n",
-      "Joe workWith ['Smith', 'Smith', 'Jack', 'Jack', 'Smith', 'Jack']\n",
-      "Smith workWith ['Joe', 'Joe', 'Andy', 'Andy', 'Joe', 'Andy']\n",
-      "Jack workWith ['Joe', 'Joe', 'Andy', 'Andy', 'Joe', 'Andy']\n",
-      "Andy workWith ['Smith', 'Smith', 'Jack', 'Jack', 'Smith', 'Jack']\n",
-      "Joe workWith ['Jack', 'Smith', 'Jack', 'Smith']\n",
-      "Smith workWith ['Andy', 'Joe', 'Andy', 'Joe']\n",
-      "Jack workWith ['Joe', 'Joe', 'Andy', 'Andy']\n",
-      "Andy workWith ['Jack', 'Smith', 'Jack', 'Smith']\n"
+      "Joe workWith ['Jack', 'Smith']\n",
+      "Smith workWith ['Joe', 'Andy']\n",
+      "Jack workWith ['Joe', 'Andy']\n",
+      "Andy workWith ['Jack', 'Smith']\n",
+      "Joe workWith ['Jack', 'Smith']\n",
+      "Smith workWith ['Joe', 'Andy']\n",
+      "Jack workWith ['Joe', 'Andy']\n",
+      "Andy workWith ['Jack', 'Smith']\n"
      ]
     }
    ],
@@ -642,7 +494,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 9,
    "id": "c8b36687-c842-4663-a7aa-084ae618301e",
    "metadata": {},
    "outputs": [
@@ -714,7 +566,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": 10,
    "id": "7f93e698-888a-4dde-b327-e591659e051f",
    "metadata": {},
    "outputs": [
@@ -726,22 +578,13 @@
       "844424930131969\n",
       "844424930131971\n",
       "844424930131972\n",
-      "844424930131973\n",
-      "844424930131975\n",
-      "844424930131976\n",
       "844424930131970\n",
-      "844424930131974\n",
       "-- Query properties --------------------\n",
       "{'name': 'Joe'}\n",
       "{'name': 'Jack'}\n",
       "{'name': 'Andy', 'title': 'Developer'}\n",
-      "{'name': 'Joe'}\n",
-      "{'name': 'Jack'}\n",
-      "{'name': 'Andy', 'title': 'Developer'}\n",
-      "{'name': 'Smith'}\n",
       "{'name': 'Smith'}\n",
       "-- Query property value --------------------\n",
-      "Developer\n",
       "Developer\n"
      ]
     }
@@ -777,7 +620,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 11,
    "id": "e15b0654-66d2-4da4-af66-6f776e6729ac",
    "metadata": {},
    "outputs": [],
diff --git a/drivers/python/samples/networkx.ipynb 
b/drivers/python/samples/networkx.ipynb
index 20fc566d..759dee28 100644
--- a/drivers/python/samples/networkx.ipynb
+++ b/drivers/python/samples/networkx.ipynb
@@ -6,12 +6,12 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "import psycopg2\n",
+    "import psycopg\n",
     "from age.networkx import *\n",
     "from age import *\n",
     "import networkx as nx\n",
     "\n",
-    "conn = psycopg2.connect(\n",
+    "conn = psycopg.connect(\n",
     "    host=\"localhost\",\n",
     "    port=\"5432\",\n",
     "    dbname=\"postgres\",\n",
diff --git a/drivers/python/setup.py b/drivers/python/setup.py
index 15be9e73..1da49d9c 100644
--- a/drivers/python/setup.py
+++ b/drivers/python/setup.py
@@ -30,7 +30,7 @@ setup(
     url              = 
'https://github.com/apache/age/tree/master/drivers/python',
     download_url     = 'https://github.com/apache/age/releases' ,
     license          = 'Apache2.0',
-    install_requires = [ 'psycopg2', 'antlr4-python3-runtime==4.11.1'],
+    install_requires = [ 'psycopg', 'antlr4-python3-runtime==4.11.1'],
     packages         = ['age', 'age.gen','age.networkx'],
     keywords         = ['Graph Database', 'Apache AGE', 'PostgreSQL'],
     python_requires  = '>=3.9',
diff --git a/drivers/python/test_age_py.py b/drivers/python/test_age_py.py
index 8048844f..f904fb9e 100644
--- a/drivers/python/test_age_py.py
+++ b/drivers/python/test_age_py.py
@@ -20,7 +20,6 @@ import decimal
 import age
 import argparse
 
-DSN = "host=localhost port=5432 dbname=postgres user=postgres password=agens"
 TEST_HOST = "localhost"
 TEST_PORT = 5432
 TEST_DB = "postgres"
@@ -28,12 +27,32 @@ TEST_USER = "postgres"
 TEST_PASSWORD = "agens"
 TEST_GRAPH_NAME = "test_graph"
 
+
 class TestAgeBasic(unittest.TestCase):
     ag = None
+    args: argparse.Namespace = argparse.Namespace(
+        host=TEST_HOST,
+        port=TEST_PORT,
+        database=TEST_DB,
+        user=TEST_USER,
+        password=TEST_PASSWORD,
+        graphName=TEST_GRAPH_NAME
+    )
+
     def setUp(self):
         print("Connecting to Test Graph.....")
-        self.ag = age.connect(graph=TEST_GRAPH_NAME, host=TEST_HOST, 
port=TEST_PORT, dbname=TEST_DB, user=TEST_USER, password=TEST_PASSWORD)
-
+        args = dict(
+            host=self.args.host,
+            port=self.args.port,
+            dbname=self.args.database,
+            user=self.args.user,
+            password=self.args.password,
+        )
+
+        dsn = "host={host} port={port} dbname={dbname} user={user} 
password={password}".format(
+            **args
+        )
+        self.ag = age.connect(dsn, graph=self.args.graphName, **args)
 
     def tearDown(self):
         # Clear test data
@@ -42,43 +61,52 @@ class TestAgeBasic(unittest.TestCase):
         self.ag.close()
 
     def testExec(self):
-
         print("\n---------------------------------------------------")
         print("Test 1: Checking single and multi column Returns.....")
         print("---------------------------------------------------\n")
 
         ag = self.ag
         # Create and Return single column
-        cursor = ag.execCypher("CREATE (n:Person {name: %s, title: 
'Developer'}) RETURN n", params=('Andy',))
+        cursor = ag.execCypher(
+            "CREATE (n:Person {name: %s, title: 'Developer'}) RETURN n",
+            params=("Andy",),
+        )
         for row in cursor:
             print("Vertex: %s , Type: %s " % (Vertex, type(row[0])))
 
-
         # Create and Return multi columns
-        cursor = ag.execCypher("CREATE (n:Person {name: %s, title: %s}) RETURN 
id(n), n.name", cols=['id','name'], params=('Jack','Manager'))
+        cursor = ag.execCypher(
+            "CREATE (n:Person {name: %s, title: %s}) RETURN id(n), n.name",
+            cols=["id", "name"],
+            params=("Jack", "Manager"),
+        )
         row = cursor.fetchone()
         print("Id: %s , Name: %s" % (row[0], row[1]))
         self.assertEqual(int, type(row[0]))
         ag.commit()
         print("\nTest 1 Successful....")
 
-
-
-
     def testQuery(self):
-
         print("\n--------------------------------------------------")
-        print("Test 2: Testing CREATE and query relationships....." )
+        print("Test 2: Testing CREATE and query relationships.....")
         print("--------------------------------------------------\n")
 
         ag = self.ag
-        ag.execCypher("CREATE (n:Person {name: %s}) ", params=('Jack',))
-        ag.execCypher("CREATE (n:Person {name: %s}) ", params=('Andy',))
-        ag.execCypher("CREATE (n:Person {name: %s}) ", params=('Smith',))
-        ag.execCypher("MATCH (a:Person), (b:Person) WHERE a.name = 'Andy' AND 
b.name = 'Jack' CREATE (a)-[r:worksWith {weight: 3}]->(b)")
-        ag.execCypher("""MATCH (a:Person), (b:Person)
+        ag.execCypher("CREATE (n:Person {name: %s}) ", params=("Jack",))
+        ag.execCypher("CREATE (n:Person {name: %s}) ", params=("Andy",))
+        ag.execCypher("CREATE (n:Person {name: %s}) ", params=("Smith",))
+        ag.execCypher(
+            "MATCH (a:Person), (b:Person) WHERE a.name = 'Andy' AND b.name = 
'Jack' CREATE (a)-[r:worksWith {weight: 3}]->(b)"
+        )
+        ag.execCypher(
+            """MATCH (a:Person), (b:Person)
                     WHERE  a.name = %s AND b.name = %s
-                    CREATE p=((a)-[r:worksWith]->(b)) """, params=('Jack', 
'Smith',))
+                    CREATE p=((a)-[r:worksWith]->(b)) """,
+            params=(
+                "Jack",
+                "Smith",
+            ),
+        )
 
         ag.commit()
 
@@ -89,20 +117,25 @@ class TestAgeBasic(unittest.TestCase):
             print("EDGE:", path[1])
             print("END:", path[2])
 
-        cursor = ag.execCypher("MATCH p=(a)-[b]-(c) WHERE b.weight>2 RETURN 
a,label(b), b.weight, c", cols=["a","bl","bw", "c"], params=(2,))
+        cursor = ag.execCypher(
+            "MATCH p=(a)-[b]-(c) WHERE b.weight>%s RETURN a,label(b), 
b.weight, c",
+            cols=["a", "bl", "bw", "c"],
+            params=(2,),
+        )
         for row in cursor:
             start = row[0]
             edgel = row[1]
             edgew = row[2]
             end = row[3]
-            print("Relationship: %s %s %s. Edge weight: %s" % (start["name"] , 
edgel,end["name"], edgew))
-            #Assert that the weight of the edge is greater than 2
+            print(
+                "Relationship: %s %s %s. Edge weight: %s"
+                % (start["name"], edgel, end["name"], edgew)
+            )
+            # Assert that the weight of the edge is greater than 2
             self.assertEqual(edgew > 2, True)
         print("\nTest 2 Successful...")
 
-
     def testChangeData(self):
-
         print("\n-------------------------------------------------------")
         print("Test 3: Testing changes in data using SET and REMOVE.....")
         print("-------------------------------------------------------\n")
@@ -112,14 +145,23 @@ class TestAgeBasic(unittest.TestCase):
         # Commit automatically
         ag.execCypher("CREATE (n:Person {name: 'Joe'})")
 
-        cursor = ag.execCypher("CREATE (n:Person {name: %s, title: 
'Developer'}) RETURN n", params=('Smith',))
+        cursor = ag.execCypher(
+            "CREATE (n:Person {name: %s, title: 'Developer'}) RETURN n",
+            params=("Smith",),
+        )
         row = cursor.fetchone()
         print("CREATED: ", row[0])
 
         # You must commit explicitly
         ag.commit()
 
-        cursor = ag.execCypher("MATCH (n:Person {name: %s}) SET n.title=%s 
RETURN n", params=('Smith','Manager',))
+        cursor = ag.execCypher(
+            "MATCH (n:Person {name: %s}) SET n.title=%s RETURN n",
+            params=(
+                "Smith",
+                "Manager",
+            ),
+        )
         row = cursor.fetchone()
         vertex = row[0]
         title1 = vertex["title"]
@@ -133,38 +175,39 @@ class TestAgeBasic(unittest.TestCase):
 
         self.assertEqual(title1, title2)
 
-        cursor = ag.execCypher("MATCH (n:Person {name: %s}) SET 
n.bigNum=-6.45161e+46::numeric RETURN n", params=('Smith',))
+        cursor = ag.execCypher(
+            "MATCH (n:Person {name: %s}) SET n.bigNum=-6.45161e+46::numeric 
RETURN n",
+            params=("Smith",),
+        )
         row = cursor.fetchone()
         vertex = row[0]
         for row in cursor:
-            print("SET bigNum: ", vertex['bigNum'])
+            print("SET bigNum: ", vertex["bigNum"])
 
         bigNum1 = vertex["bigNum"]
 
         self.assertEqual(decimal.Decimal("-6.45161e+46"), bigNum1)
         ag.commit()
 
-
         cursor = ag.execCypher("MATCH (p:Person {name: 'Smith'}) RETURN 
p.bigNum")
         row = cursor.fetchone()
         bigNum2 = row[0]
 
         self.assertEqual(bigNum1, bigNum2)
 
-
-        cursor = ag.execCypher("MATCH (n:Person {name: %s}) REMOVE n.title 
RETURN n", params=('Smith',))
+        cursor = ag.execCypher(
+            "MATCH (n:Person {name: %s}) REMOVE n.title RETURN n", 
params=("Smith",)
+        )
         for row in cursor:
             print("REMOVE Prop title: ", row[0])
-            #Assert that the title property is removed
-            self.assertIsNone(row[0].properties.get('title'))
+            # Assert that the title property is removed
+            self.assertIsNone(row[0].properties.get("title"))
         print("\nTest 3 Successful....")
 
         # You must commit explicitly
         ag.commit()
 
-
     def testCypher(self):
-
         print("\n--------------------------")
         print("Test 4: Testing Cypher.....")
         print("--------------------------\n")
@@ -172,12 +215,12 @@ class TestAgeBasic(unittest.TestCase):
         ag = self.ag
 
         with ag.connection.cursor() as cursor:
-            try :
-                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=('Joe',))
-                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=('Jack',))
-                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=('Andy',))
-                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=('Smith',))
-                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=('Tom',))
+            try:
+                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=("Joe",))
+                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=("Jack",))
+                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=("Andy",))
+                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=("Smith",))
+                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=("Tom",))
 
                 # You must commit explicitly
                 ag.commit()
@@ -186,10 +229,19 @@ class TestAgeBasic(unittest.TestCase):
                 ag.rollback()
 
         with ag.connection.cursor() as cursor:
-            try :# Create Edges
-                ag.cypher(cursor,"MATCH (a:Person), (b:Person) WHERE a.name = 
'Joe' AND b.name = 'Smith' CREATE (a)-[r:worksWith {weight: 3}]->(b)")
-                ag.cypher(cursor,"MATCH (a:Person), (b:Person) WHERE  a.name = 
'Andy' AND b.name = 'Tom' CREATE (a)-[r:worksWith {weight: 1}]->(b)")
-                ag.cypher(cursor,"MATCH (a:Person {name: 'Jack'}), (b:Person 
{name: 'Andy'}) CREATE (a)-[r:worksWith {weight: 5}]->(b)")
+            try:  # Create Edges
+                ag.cypher(
+                    cursor,
+                    "MATCH (a:Person), (b:Person) WHERE a.name = 'Joe' AND 
b.name = 'Smith' CREATE (a)-[r:worksWith {weight: 3}]->(b)",
+                )
+                ag.cypher(
+                    cursor,
+                    "MATCH (a:Person), (b:Person) WHERE  a.name = 'Andy' AND 
b.name = 'Tom' CREATE (a)-[r:worksWith {weight: 1}]->(b)",
+                )
+                ag.cypher(
+                    cursor,
+                    "MATCH (a:Person {name: 'Jack'}), (b:Person {name: 
'Andy'}) CREATE (a)-[r:worksWith {weight: 5}]->(b)",
+                )
 
                 # You must commit explicitly
                 ag.commit()
@@ -197,12 +249,16 @@ class TestAgeBasic(unittest.TestCase):
                 print(ex)
                 ag.rollback()
 
-
         # With Params
-        cursor = ag.execCypher("""MATCH (a:Person), (b:Person)
+        cursor = ag.execCypher(
+            """MATCH (a:Person), (b:Person)
                 WHERE  a.name = %s AND b.name = %s
                 CREATE p=((a)-[r:worksWith]->(b)) RETURN p""",
-                params=('Andy', 'Smith',))
+            params=(
+                "Andy",
+                "Smith",
+            ),
+        )
 
         for row in cursor:
             print("CREATED EDGE: %s" % row[0])
@@ -213,25 +269,22 @@ class TestAgeBasic(unittest.TestCase):
 
         for row in cursor:
             print("CREATED EDGE WITH PROPERTIES: %s" % row[0])
-            self.assertEqual(row[0][1].properties['weight'], 5)
+            self.assertEqual(row[0][1].properties["weight"], 5)
 
         print("\nTest 4 Successful...")
 
-
-
     def testMultipleEdges(self):
-
         print("\n------------------------------------")
         print("Test 5: Testing Multiple Edges.....")
         print("------------------------------------\n")
 
         ag = self.ag
         with ag.connection.cursor() as cursor:
-            try :
-                ag.cypher(cursor, "CREATE (n:Country {name: %s}) ", 
params=('USA',))
-                ag.cypher(cursor, "CREATE (n:Country {name: %s}) ", 
params=('France',))
-                ag.cypher(cursor, "CREATE (n:Country {name: %s}) ", 
params=('Korea',))
-                ag.cypher(cursor, "CREATE (n:Country {name: %s}) ", 
params=('Russia',))
+            try:
+                ag.cypher(cursor, "CREATE (n:Country {name: %s}) ", 
params=("USA",))
+                ag.cypher(cursor, "CREATE (n:Country {name: %s}) ", 
params=("France",))
+                ag.cypher(cursor, "CREATE (n:Country {name: %s}) ", 
params=("Korea",))
+                ag.cypher(cursor, "CREATE (n:Country {name: %s}) ", 
params=("Russia",))
 
                 # You must commit explicitly after all executions.
                 ag.connection.commit()
@@ -240,10 +293,19 @@ class TestAgeBasic(unittest.TestCase):
                 raise ex
 
         with ag.connection.cursor() as cursor:
-            try :# Create Edges
-                ag.cypher(cursor,"MATCH (a:Country), (b:Country) WHERE a.name 
= 'USA' AND b.name = 'France' CREATE (a)-[r:distance {unit:'miles', value: 
4760}]->(b)")
-                ag.cypher(cursor,"MATCH (a:Country), (b:Country) WHERE  a.name 
= 'France' AND b.name = 'Korea' CREATE (a)-[r:distance {unit: 'km', value: 
9228}]->(b)")
-                ag.cypher(cursor,"MATCH (a:Country {name: 'Korea'}), 
(b:Country {name: 'Russia'}) CREATE (a)-[r:distance {unit:'km', value: 
3078}]->(b)")
+            try:  # Create Edges
+                ag.cypher(
+                    cursor,
+                    "MATCH (a:Country), (b:Country) WHERE a.name = 'USA' AND 
b.name = 'France' CREATE (a)-[r:distance {unit:'miles', value: 4760}]->(b)",
+                )
+                ag.cypher(
+                    cursor,
+                    "MATCH (a:Country), (b:Country) WHERE  a.name = 'France' 
AND b.name = 'Korea' CREATE (a)-[r:distance {unit: 'km', value: 9228}]->(b)",
+                )
+                ag.cypher(
+                    cursor,
+                    "MATCH (a:Country {name: 'Korea'}), (b:Country {name: 
'Russia'}) CREATE (a)-[r:distance {unit:'km', value: 3078}]->(b)",
+                )
 
                 # You must commit explicitly
                 ag.connection.commit()
@@ -251,7 +313,6 @@ class TestAgeBasic(unittest.TestCase):
                 ag.rollback()
                 raise ex
 
-
         cursor = ag.execCypher("""MATCH p=(:Country 
{name:"USA"})-[:distance]-(:Country)-[:distance]-(:Country)
                 RETURN p""")
 
@@ -263,7 +324,9 @@ class TestAgeBasic(unittest.TestCase):
                 if e.gtype == age.TP_VERTEX:
                     output.append(e.label + " " + e["name"])
                 elif e.gtype == age.TP_EDGE:
-                    output.append("---- (distance " + str(e["value"]) + " " + 
e["unit"] + ") --->")
+                    output.append(
+                        "---- (distance " + str(e["value"]) + " " + e["unit"] 
+ ") --->"
+                    )
                 else:
                     output.append("Unknown element. " + str(e))
 
@@ -271,14 +334,11 @@ class TestAgeBasic(unittest.TestCase):
 
         formatted_output = " ".join(output)
         print("PATH WITH MULTIPLE EDGES: %s" % formatted_output)
-        self.assertEqual(5,count)
+        self.assertEqual(5, count)
 
         print("\nTest 5 Successful...")
 
-
-
     def testCollect(self):
-
         print("\n--------------------------")
         print("Test 6: Testing COLLECT.....")
         print("--------------------------\n")
@@ -286,12 +346,12 @@ class TestAgeBasic(unittest.TestCase):
         ag = self.ag
 
         with ag.connection.cursor() as cursor:
-            try :
-                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=('Joe',))
-                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=('Jack',))
-                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=('Andy',))
-                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=('Smith',))
-                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=('Tom',))
+            try:
+                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=("Joe",))
+                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=("Jack",))
+                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=("Andy",))
+                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=("Smith",))
+                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=("Tom",))
 
                 # You must commit explicitly
                 ag.commit()
@@ -300,10 +360,19 @@ class TestAgeBasic(unittest.TestCase):
                 ag.rollback()
 
         with ag.connection.cursor() as cursor:
-            try :# Create Edges
-                ag.cypher(cursor,"MATCH (a:Person), (b:Person) WHERE a.name = 
'Joe' AND b.name = 'Smith' CREATE (a)-[r:worksWith {weight: 3}]->(b)")
-                ag.cypher(cursor,"MATCH (a:Person), (b:Person) WHERE  a.name = 
'Joe' AND b.name = 'Tom' CREATE (a)-[r:worksWith {weight: 1}]->(b)")
-                ag.cypher(cursor,"MATCH (a:Person {name: 'Joe'}), (b:Person 
{name: 'Andy'}) CREATE (a)-[r:worksWith {weight: 5}]->(b)")
+            try:  # Create Edges
+                ag.cypher(
+                    cursor,
+                    "MATCH (a:Person), (b:Person) WHERE a.name = 'Joe' AND 
b.name = 'Smith' CREATE (a)-[r:worksWith {weight: 3}]->(b)",
+                )
+                ag.cypher(
+                    cursor,
+                    "MATCH (a:Person), (b:Person) WHERE  a.name = 'Joe' AND 
b.name = 'Tom' CREATE (a)-[r:worksWith {weight: 1}]->(b)",
+                )
+                ag.cypher(
+                    cursor,
+                    "MATCH (a:Person {name: 'Joe'}), (b:Person {name: 'Andy'}) 
CREATE (a)-[r:worksWith {weight: 5}]->(b)",
+                )
 
                 # You must commit explicitly
                 ag.commit()
@@ -313,24 +382,29 @@ class TestAgeBasic(unittest.TestCase):
 
         print(" -------- TESTING COLLECT #1 --------")
         with ag.connection.cursor() as cursor:
-            ag.cypher(cursor, "MATCH (a)-[:worksWith]->(c) WITH a as V, 
COLLECT(c) as CV RETURN V.name, CV", cols=["V","CV"])
+            ag.cypher(
+                cursor,
+                "MATCH (a)-[:worksWith]->(c) WITH a as V, COLLECT(c) as CV 
RETURN V.name, CV",
+                cols=["V", "CV"],
+            )
             for row in cursor:
                 nm = row[0]
                 collected = row[1]
                 print(nm, "worksWith", [i["name"] for i in collected])
-                self.assertEqual(3,len(collected))
-
+                self.assertEqual(3, len(collected))
 
         print(" -------- TESTING COLLECT #2 --------")
-        for row in ag.execCypher("MATCH (a)-[:worksWith]->(c) WITH a as V, 
COLLECT(c) as CV RETURN V.name, CV", cols=["V1","CV"]):
+        for row in ag.execCypher(
+            "MATCH (a)-[:worksWith]->(c) WITH a as V, COLLECT(c) as CV RETURN 
V.name, CV",
+            cols=["V1", "CV"],
+        ):
             nm = row[0]
             collected = row[1]
             print(nm, "worksWith", [i["name"] for i in collected])
-            self.assertEqual(3,len(collected))
+            self.assertEqual(3, len(collected))
         print("\nTest 6 Successful...")
 
     def testSerialization(self):
-
         print("\n---------------------------------------")
         print("Test 6: Testing Vertex Serialization.....")
         print("-----------------------------------------\n")
@@ -339,11 +413,11 @@ class TestAgeBasic(unittest.TestCase):
 
         with ag.connection.cursor() as cursor:
             try:
-                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=('Joe',))
-                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=('Jack',))
-                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=('Andy',))
-                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=('Smith',))
-                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=('Tom',))
+                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=("Joe",))
+                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=("Jack",))
+                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=("Andy",))
+                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=("Smith",))
+                ag.cypher(cursor, "CREATE (n:Person {name: %s}) ", 
params=("Tom",))
 
                 # You must commit explicitly
                 ag.commit()
@@ -375,42 +449,48 @@ class TestAgeBasic(unittest.TestCase):
         print("Vertex.toString() 'properties' field is formatted properly.")
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     parser = argparse.ArgumentParser()
 
-    parser.add_argument('-host',
-                        '--host',
-                        help='Optional Host Name. Default Host is "127.0.0.1" 
',
-                        default="127.0.0.1")
-    parser.add_argument('-port',
-                        '--port',
-                        help='Optional Port Number. Default port no is 5432',
-                        default=5432)
-    parser.add_argument('-db',
-                        '--database',
-                        help='Required Database Name',
-                        required=True)
-    parser.add_argument('-u',
-                        '--user',
-                        help='Required Username Name',
-                        required=True)
-    parser.add_argument('-pass',
-                        '--password',
-                        help='Required Password for authentication',
-                        required=True)
-    parser.add_argument('-gn',
-                        '--graphName',
-                        help='Optional Graph Name to be created. Default 
graphName is "test_graph"',
-                        default="test_graph")
+    parser.add_argument(
+        "-host",
+        "--host",
+        help='Optional Host Name. Default Host is "127.0.0.1" ',
+        default=TEST_HOST,
+    )
+    parser.add_argument(
+        "-port",
+        "--port",
+        help="Optional Port Number. Default port no is 5432",
+        default=TEST_PORT,
+    )
+    parser.add_argument(
+        "-db", "--database", help="Required Database Name", default=TEST_DB
+    )
+    parser.add_argument(
+        "-u", "--user", help="Required Username Name", default=TEST_USER
+    )
+    parser.add_argument(
+        "-pass",
+        "--password",
+        help="Required Password for authentication",
+        default=TEST_PASSWORD,
+    )
+    parser.add_argument(
+        "-gn",
+        "--graphName",
+        help='Optional Graph Name to be created. Default graphName is 
"test_graph"',
+        default=TEST_GRAPH_NAME,
+    )
 
     args = parser.parse_args()
     suite = unittest.TestSuite()
-    suite.addTest(TestAgeBasic('testExec'))
-    suite.addTest(TestAgeBasic('testQuery'))
-    suite.addTest(TestAgeBasic('testChangeData'))
-    suite.addTest(TestAgeBasic('testCypher'))
-    suite.addTest(TestAgeBasic('testMultipleEdges'))
-    suite.addTest(TestAgeBasic('testCollect'))
-    suite.addTest(TestAgeBasic('testSerialization'))
+    suite.addTest(TestAgeBasic("testExec"))
+    suite.addTest(TestAgeBasic("testQuery"))
+    suite.addTest(TestAgeBasic("testChangeData"))
+    suite.addTest(TestAgeBasic("testCypher"))
+    suite.addTest(TestAgeBasic("testMultipleEdges"))
+    suite.addTest(TestAgeBasic("testCollect"))
+    suite.addTest(TestAgeBasic("testSerialization"))
     TestAgeBasic.args = args
     unittest.TextTestRunner().run(suite)
diff --git a/drivers/python/test_networkx.py b/drivers/python/test_networkx.py
index 290d4c47..310d2cf5 100644
--- a/drivers/python/test_networkx.py
+++ b/drivers/python/test_networkx.py
@@ -26,22 +26,38 @@ TEST_GRAPH_NAME = "test_graph"
 ORIGINAL_GRAPH = "original_graph"
 EXPECTED_GRAPH = "expected_graph"
 
+TEST_HOST = "localhost"
+TEST_PORT = 5432
+TEST_DB = "postgres"
+TEST_USER = "postgres"
+TEST_PASSWORD = "agens"
+
 
 class TestAgeToNetworkx(unittest.TestCase):
     ag = None
+    args: argparse.Namespace = argparse.Namespace(
+        host=TEST_HOST,
+        port=TEST_PORT,
+        database=TEST_DB,
+        user=TEST_USER,
+        password=TEST_PASSWORD,
+        graphName=TEST_GRAPH_NAME
+    )
 
     def setUp(self):
+        args = dict(
+            host=self.args.host,
+            port=self.args.port,
+            dbname=self.args.database,
+            user=self.args.user,
+            password=self.args.password
+        )
 
-        TEST_DB = self.args.database
-        TEST_USER = self.args.user
-        TEST_PASSWORD = self.args.password
-        TEST_PORT = self.args.port
-        TEST_HOST = self.args.host
-        self.ag = age.connect(graph=TEST_GRAPH_NAME, host=TEST_HOST, 
port=TEST_PORT,
-                              dbname=TEST_DB, user=TEST_USER, 
password=TEST_PASSWORD)
+        dsn = "host={host} port={port} dbname={dbname} user={user} 
password={password}".format(**args)
+        self.ag = age.connect(dsn, graph=TEST_GRAPH_NAME, **args)
 
     def tearDown(self):
-        age.deleteGraph(self.ag.connection, self.ag.graphName)
+        age.deleteGraph(self.ag.connection, TEST_GRAPH_NAME)
         self.ag.close()
 
     def compare_networkX(self, G, H):
@@ -215,19 +231,28 @@ class TestNetworkxToAGE(unittest.TestCase):
     ag = None
     ag1 = None
     ag2 = None
+    args: argparse.Namespace = argparse.Namespace(
+        host=TEST_HOST,
+        port=TEST_PORT,
+        database=TEST_DB,
+        user=TEST_USER,
+        password=TEST_PASSWORD,
+        graphName=TEST_GRAPH_NAME
+    )
 
     def setUp(self):
-        TEST_DB = self.args.database
-        TEST_USER = self.args.user
-        TEST_PASSWORD = self.args.password
-        TEST_PORT = self.args.port
-        TEST_HOST = self.args.host
-        self.ag = age.connect(graph=TEST_GRAPH_NAME, host=TEST_HOST, 
port=TEST_PORT,
-                              dbname=TEST_DB, user=TEST_USER, 
password=TEST_PASSWORD)
-        self.ag1 = age.connect(graph=ORIGINAL_GRAPH, host=TEST_HOST, 
port=TEST_PORT,
-                               dbname=TEST_DB, user=TEST_USER, 
password=TEST_PASSWORD)
-        self.ag2 = age.connect(graph=EXPECTED_GRAPH, host=TEST_HOST, 
port=TEST_PORT,
-                               dbname=TEST_DB, user=TEST_USER, 
password=TEST_PASSWORD)
+        args = dict(
+            host=self.args.host,
+            port=self.args.port,
+            dbname=self.args.database,
+            user=self.args.user,
+            password=self.args.password
+        )
+
+        dsn = "host={host} port={port} dbname={dbname} user={user} 
password={password}".format(**args)
+        self.ag = age.connect(dsn, graph=TEST_GRAPH_NAME, **args)
+        self.ag1 = age.connect(dsn, graph=ORIGINAL_GRAPH, **args)
+        self.ag2 = age.connect(dsn, graph=EXPECTED_GRAPH, **args)
         self.graph = nx.DiGraph()
 
     def tearDown(self):
@@ -441,23 +466,23 @@ if __name__ == "__main__":
     parser.add_argument('-host',
                         '--host',
                         help='Optional Host Name. Default Host is "127.0.0.1" 
',
-                        default="127.0.0.1")
+                        default=TEST_HOST)
     parser.add_argument('-port',
                         '--port',
                         help='Optional Port Number. Default port no is 5432',
-                        default=5432)
+                        default=TEST_PORT)
     parser.add_argument('-db',
                         '--database',
                         help='Required Database Name',
-                        required=True)
+                        default=TEST_DB)
     parser.add_argument('-u',
                         '--user',
                         help='Required Username Name',
-                        required=True)
+                        default=TEST_USER)
     parser.add_argument('-pass',
                         '--password',
                         help='Required Password for authentication',
-                        required=True)
+                        default=TEST_PASSWORD)
 
     args = parser.parse_args()
     suite = unittest.TestSuite()

Reply via email to