13.2 Connecting to the Graph Server (PGX)

This section explains how to connect to the graph server (PGX) running in remote mode or when deployed as a web application on Apache Tomcat or Oracle WebLogic Server.

The prerequisite requirement to connect to the graph server is to have the graph server (PGX) up and running. See Starting and Stopping the Graph Server (PGX) Using the Command Line for more information on the commands to start the graph server.

Note:

If you are using the graph server (PGX) as a library, see Using the Graph Server (PGX) as a Library for more information.

13.2.1 Connecting with the Graph Client CLIs

The simplest way to connect to a remote graph server (PGX) instance is to specify the base URL of the server along with the database user name required for the graph server (PGX) authentication as shown:

cd /opt/oracle/graph
./bin/opg4j --base_url https://<host>:<port> --username <graphuser>
cd /opt/oracle/graph
./bin/opg4py --base_url https://<host>:<port> --username <graphuser>
where :
  • <host>: is the server host name
  • <port>: is the server port
  • <graphuser>: is the database user

    You will be prompted for the database password.

See Also:

About Logging HTTP Requests

The graph shell suppresses all debugging messages by default. To see which HTTP requests are executed, set the log level for oracle.pgx to DEBUG, as shown in this example:

Note:

Enabling these logs can lead to sensitive information like passwords getting printed on the screen.
opg4j> loglevel("oracle.pgx","DEBUG")
===> Log level of oracle.pgx logger set to DEBUG
opg4j> session.readGraphWithProperties("bank_graph_analytics.json", "bank_graph");
06:29:03,702 DEBUG CommonsVfsProvider - resolve bank_graph_analytics.json
06:29:03,702 DEBUG AbstractConfigFactory - parse graph config from bank_graph_analytics.json (parent: file:///opt/oracle/graph)
06:29:03,709 DEBUG RemoteUtils - create session cookie (session ID = f5d029d7-2924-4cd4-86a9-6999c1ce5e3f)
06:29:03,713 DEBUG RemoteUtils - no value for the sticky cookie given
06:29:03,713 DEBUG RemoteUtils - create csrf token cookie (token = 36acbee2-6b78-4c13-b114-41040809833a)
06:29:03,713 DEBUG HttpRequestExecutor - Requesting POST https://localhost:7007/core/v1/loadGraph HTTP/1.1 with payload {"graphConfig":"HRcBVFVcO0dfXU9bUEhGEEYOdkMUElZYRFpcZgBeDxBYCxFcRGY2c21wIBUBEElAW11HQV5vVhpYAFRIFAMbeC5+NithRx9EEkwUVRADRlFBXVhGFlBpT0ZfSEFpAlZBQ1RXG1kTKiEXSREVCUAWU1dmElJfRlxKa11GDBJdSV1EQwMPd1paVhZfFxYXSREIB1gBEggbMEVMXEpUUV9HQUgWSV1FFVBDV01QVg1uAApZEF4IRA9GdHdqMGhkdhseFklREBBdQ1lCCFZDaU9cSxdUGzpFF1wQD1EBQhADRnZOUVZHWllHQUgWQVdXBVBDURsDQkFSEQBUEVY5DVAdb19YFEdEXF4QDktVDxdRUBQUBVhZV1tYSgZuFwRXCVY5CFQJVRADRnVsfHJtcWlzJjdrbHViQxUPXVxAZhdIEwAXXxEKCVsDEh4bAlhfX1hGFhcWEQBWQEsUHGQBFE9cSxdUGzpFF1wQD1EBQkEbXmxWEFJXTXJXDAhBQFYUWxtkchsVGw1QDgAXXxEnBVYLRVxNFxUBEFVdVUldDQMWF0MUAktIV01cZghUGjpYBEMWD1sDEghNFkJITxUQUExAAgZVXl1pFVhPWlxmVwJcBkcPR3EnKH47fn19IWQPHhtZUVRrFx1ESBoMQ1BDQlxeXBETT0dTCkELB0FGChBLAFVAQRtPaQEWDQVZSBoMQ1tMWFJmXhFQEw1qBF0HCkwQWVFKRkotMjkyAElr0w==","graphName":"bank_graph","_csrf_token":"36acbee2-6b78-4c13-b114-41040809833a"}
06:29:03,788 DEBUG HttpRequestExecutor - received HTTP status 202
06:29:03,789 DEBUG HttpRequestExecutor - {"futureId":"7f7a2206-8881-4c1e-909f-6e8778be617c"}
06:29:03,789 DEBUG PgxRemoteFuture - Requesting GET https://localhost:7007/core/v1/futures/x-future-id/status HTTP/1.1
06:29:03,801 DEBUG PgxRemoteFuture - Requesting GET https://localhost:7007/core/v1/futures/x-future-id/value HTTP/1.1
06:29:03,831 DEBUG RemoteUtils - received HTTP status 201
06:29:03,831 DEBUG RemoteUtils - {"id":"8B473228-0751-49A9-A945-9A0E4011AB69","links":[{"href":"https://localhost:7007/core/v1/graphs/x-graph-id","rel":"self","method":"GET","interaction":["async-polling"]},{"href":"https://localhost:7007/core/v1/graphs/x-graph-id","rel":"canonical","method":"GET","interaction":["async-polling"]}],"graphName":"bank_graph","vertexTables":{"Accounts":{"name":"Accounts","metaData":{"name":"Accounts","idType":"integer","labels":["Accounts"],"properties":[],"edgeProviderNamesWhereSource":["Transfers"],"edgeProviderNamesWhereDestination":["Transfers"],"id":null,"links":null},"providerLabels":["Accounts"],"entityKeyType":"integer","isIdentityKeyMapping":false,"vertexProperties":{},"vertexLabels":{"id":"04156FFE-A3C1-4A6D-87E5-879A0895BBD4","links":[{"href":"https://localhost:7007/core/v1/graphs/x-graph-id/properties/x-property-name","rel":"self","method":"GET","interaction":["async-polling"]},{"href":"https://localhost:7007/core/v1/graphs/x-graph-id/properties/x-property-name","rel":"canonical","method":"GET","interaction":["async-polling"]}],"dimension":-1,"propertyId":"04156FFE-A3C1-4A6D-87E5-879A0895BBD4","name":"__vertex_labels__","entityType":"vertex","type":"ro_string_set","namespace":"2C17C639-3771-3E30-88AE-34D6B380C5EC","transient":false},"transient":false}},"edgeTables":{"Transfers":{"name":"Transfers","metaData":{"name":"Transfers","idType":"long","directed":true,"labels":["Transfers"],"properties":[{"name":"AMOUNT","id":null,"propertyType":"float","dimension":0,"transient":true,"links":null,"propertyId":"AF2A2D0A-9C8C-478F-BD74-3444A7DD7339"}],"sourceVertexProviderName":"Accounts","destinationVertexProviderName":"Accounts","id":null,"links":null},"providerLabels":["Transfers"],"entityKeyType":"long","isIdentityKeyMapping":true,"sourceVertexTableName":"Accounts","destinationVertexTableName":"Accounts","edgeProperties":{"4046D845-D0C6-4231-A69B-F69D4963CD91":{"id":"4046D845-D0C6-4231-A69B-F69D4963CD91","links":[{"href":"https://localhost:7007/core/v1/graphs/x-graph-id/properties/x-property-name","rel":"self","method":"GET","interaction":["async-polling"]},{"href":"https://localhost:7007/core/v1/graphs/x-graph-id/properties/x-property-name","rel":"canonical","method":"GET","interaction":["async-polling"]}],"dimension":0,"propertyId":"4046D845-D0C6-4231-A69B-F69D4963CD91","name":"AMOUNT","entityType":"edge","type":"float","namespace":"2C17C639-3771-3E30-88AE-34D6B380C5EC","transient":false}},"edgeLabel":{"id":"9763546A-1860-49A4-9292-77D2AA04F4BB","links
06:29:03,836 DEBUG PgxSession - engine reports latest snapshot is 621849 milli-seconds old. Max age is 0 milli-seconds
06:29:03,836 DEBUG PgxSession - ==> try to check out newer snapshot
06:29:03,836 DEBUG RemoteUtils - create session cookie (session ID = f5d029d7-2924-4cd4-86a9-6999c1ce5e3f)
06:29:03,836 DEBUG RemoteUtils - no value for the sticky cookie given
06:29:03,836 DEBUG RemoteUtils - create csrf token cookie (token = 36acbee2-6b78-4c13-b114-41040809833a)
06:29:03,836 DEBUG HttpRequestExecutor - Requesting POST https://localhost:7007/core/v1/graphs/x-graph-id/refresh HTTP/1.1 with payload {"blockIfFull":false,"_csrf_token":"36acbee2-6b78-4c13-b114-41040809833a"}
06:29:03,878 DEBUG HttpRequestExecutor - received HTTP status 202
06:29:03,878 DEBUG HttpRequestExecutor - {"futureId":"898d546e-583f-4d37-9ca9-d1e10134037f"}
06:29:04,135 DEBUG PgxRemoteFuture - Requesting GET https://localhost:7007/core/v1/futures/x-future-id/status HTTP/1.1
06:29:04,828 DEBUG PgxRemoteFuture - Requesting GET https://localhost:7007/core/v1/futures/x-future-id/value HTTP/1.1
06:29:04,858 DEBUG RemoteUtils - received HTTP status 201
06:29:04,859 DEBUG RemoteUtils - {"id":"BE960B34-E135-4CF8-AB2F-E1A6E2D7DB60","links":[{"href":"https://localhost:7007/core/v1/graphs/x-graph-id","rel":"self","method":"GET","interaction":["async-polling"]},{"href":"https://localhost:7007/core/v1/graphs/x-graph-id","rel":"canonical","method":"GET","interaction":["async-polling"]}],"graphName":"bank_graph","vertexTables":{"Accounts":{"name":"Accounts","metaData":{"name":"Accounts","idType":"integer","labels":["Accounts"],"properties":[],"edgeProviderNamesWhereSource":["Transfers"],"edgeProviderNamesWhereDestination":["Transfers"],"id":null,"links":null},"providerLabels":["Accounts"],"entityKeyType":"integer","isIdentityKeyMapping":false,"vertexProperties":{},"vertexLabels":{"id":"19D95502-40D5-47F2-9F45-B1CD09ECB989","links":[{"href":"https://localhost:7007/core/v1/graphs/x-graph-id/properties/x-property-name","rel":"self","method":"GET","interaction":["async-polling"]},{"href":"https://localhost:7007/core/v1/graphs/x-graph-id/properties/x-property-name","rel":"canonical","method":"GET","interaction":["async-polling"]}],"dimension":-1,"propertyId":"19D95502-40D5-47F2-9F45-B1CD09ECB989","name":"__vertex_labels__","entityType":"vertex","type":"ro_string_set","namespace":"2C17C639-3771-3E30-88AE-34D6B380C5EC","transient":false},"transient":false}},"edgeTables":{"Transfers":{"name":"Transfers","metaData":{"name":"Transfers","idType":"long","directed":true,"labels":["Transfers"],"properties":[{"name":"AMOUNT","id":null,"propertyType":"float","dimension":0,"transient":true,"links":null,"propertyId":"9A49BC0C-F8AA-465A-B8D6-CA5A92BAE2C9"}],"sourceVertexProviderName":"Accounts","destinationVertexProviderName":"Accounts","id":null,"links":null},"providerLabels":["Transfers"],"entityKeyType":"long","isIdentityKeyMapping":true,"sourceVertexTableName":"Accounts","destinationVertexTableName":"Accounts","edgeProperties":{"FED6FE43-D311-46B6-9A5A-E8DC0D7B56C6":{"id":"FED6FE43-D311-46B6-9A5A-E8DC0D7B56C6","links":[{"href":"https://localhost:7007/core/v1/graphs/x-graph-id/properties/x-property-name","rel":"self","method":"GET","interaction":["async-polling"]},{"href":"https://localhost:7007/core/v1/graphs/x-graph-id/properties/x-property-name","rel":"canonical","method":"GET","interaction":["async-polling"]}],"dimension":0,"propertyId":"FED6FE43-D311-46B6-9A5A-E8DC0D7B56C6","name":"AMOUNT","entityType":"edge","type":"float","namespace":"2C17C639-3771-3E30-88AE-34D6B380C5EC","transient":false}},"edgeLabel":{"id":"371D2AC6-4EC5-45AD-8885-B3590F56D944","links
$5 ==> PgxGraph[name=bank_graph,N=1000,E=5001,created=1621160944599]
>>>setloglevel("oracle.pgx","DEBUG")
>>>session.read_graph_with_properties("/scratch/PG/data/bank_graph_analytics.json")
10:37:46.308 [main] DEBUG oracle.pgx.vfs.CommonsVfsProvider - resolve /scratch/PG/data/bank_graph_analytics.json
10:37:46.314 [main] DEBUG oracle.pgx.config.AbstractConfigFactory - parse graph config from /scratch/PG/data/bank_graph_analytics.json (parent: file:///scratch/PG/data)
10:37:46.464 [main] DEBUG oracle.pgx.client.RemoteUtils - create session cookie (session ID = 786242ef-a430-4964-8379-662079514d2e)
10:37:46.465 [main] DEBUG oracle.pgx.client.RemoteUtils - no value for the sticky cookie given
10:37:46.466 [main] DEBUG oracle.pgx.client.RemoteUtils - create csrf token cookie (token = f02ccd16-56e1-4e61-8d17-d6122f5ea48f)
10:37:46.565 [main] DEBUG oracle.pgx.client.HttpRequestExecutor - Requesting POST https://localhost:7007/core/v1/loadGraph HTTP/1.1 with payload {"graphConfig":"TBpAV0ZGAB5yEUZcRkRQXERHDwJoTBtGU09tU1hVQFxaRghHfnwUHhZcBAtIQw4RcU5XVkNaWUsRGxtGU09tRE5JUBMORlsLQ11RV0YQSURBDlVXWUNTGwxPD1tBUlhZU2lZVU5mWFBEFFsLUBoMRkZHABsBQ1BSRExWWEVRckxSVVVIaVhTXVIbDxN2JXwuaHl1cXtnKzJ+QxgRVkJGVFdADwIRRV1PW0UQHBVJR15EFxBfbEMURk1CAEQXQ11dREhTXEQWARpdVlRIFAwQeXMbSB1PRkYcR10UCBZBERRED1MRHA9aWFtRDwIReXhgcxRPbUpkGRNRAFUAaEhEXUJbAQNfEhYJa1YWUlNNcltcW0xAWBQIEl5dFx0WClMIUhoMEGBABAheB1FBQw8YG11RVGdHTklIFAwQXFhXUhMYRl4KVlxfXFMQXx0PAkZWUVlRZl1RVGdeVkldX1hVEg1fVF1HAU9JFVxTQUBbCwdZCFtdb1tRS0JRVWdDRVZbX1JXQhUDF3BXB10QWUxFEBgQAQNeFV1dUVldVlhrTldfQlRDFAwQZHhmdHJ3MG0scxoaEFBTEQdPAEdWb1lVW1pRclZSWlwPDBRwcXlyamVsKmFHGxpFXUFABgNyAltfRUBaGwwWa2p8emZsdXVmb359Fx0WAl0XWllCEA4QFwJPDEcRHA9ES1lEXhoJbEIPQk9CVRUDF1dYC1MRFRQUXFVfAEQXQ3V+f3h6bRRJAUMRQ0BdUxQIEkRNR1haAxBJFVZXX1EQX0RpJGdwYmRkbX97YxpOahUPRVlHQlRcakdRFkYAT2dGQFtEDAJIExYJEmxXWllBQ0xAFURwGhRcUVpcFwsWBlMLXGdRQFVCDTlMD1VfSVldWkUWUDgzNzmCqX+4","graphName":null,"_csrf_token":"f02ccd16-56e1-4e61-8d17-d6122f5ea48f"}
10:37:47.082 [main] DEBUG oracle.pgx.client.HttpRequestExecutor - received HTTP status 202
10:37:47.082 [main] DEBUG oracle.pgx.client.HttpRequestExecutor - {"futureId":"aeae66b7-e1d6-46f3-b78f-1c0d9642d308"}
10:37:47.086 [pgx-client-thread-2] DEBUG oracle.pgx.client.PgxRemoteFuture - Requesting GET https://localhost:7007/core/v1/futures/x-future-id/status HTTP/1.1
10:37:50.434 [pgx-client-thread-2] DEBUG oracle.pgx.client.PgxRemoteFuture - Requesting GET https://localhost:7007/core/v1/futures/x-future-id/value HTTP/1.1
10:37:50.539 [pgx-client-thread-2] DEBUG oracle.pgx.client.RemoteUtils - received HTTP status 201
10:37:50.539 [pgx-client-thread-2] DEBUG oracle.pgx.client.RemoteUtils - {"id":"2EE6F933-5679-4387-B79B-A4AAD0814DC6","links":[{"href":"https://localhost:7007/core/v1/graphs/x-graph-id","rel":"self","method":"GET","interaction":["async-polling"]},{"href":"https://localhost:7007/core/v1/graphs/x-graph-id","rel":"canonical","method":"GET","interaction":["async-polling"]}],"graphName":"bank_graph_analytics","vertexTables":{"Accounts":{"name":"Accounts","metaData":{"name":"Accounts","idType":"integer","labels":["Accounts"],"properties":[{"name":"ID","id":null,"propertyType":"integer","dimension":0,"transient":true,"links":null,"propertyId":"C933AB01-358B-4553-974D-0C54845719F2"},{"name":"NAME","id":null,"propertyType":"string","dimension":0,"transient":true,"links":null,"propertyId":"E0EDF68C-5AFE-4886-B3A0-385CE56F1814"}],"edgeProviderNamesWhereSource":["Transfers"],"edgeProviderNamesWhereDestination":["Transfers"],"id":null,"links":null},"providerLabels":["Accounts"],"keyPropertyName":null,"entityKeyType":"integer","isIdentityKeyMapping":false,"vertexProperties":{"F5023C5A-5294-4383-BA4F-0109C67A020F":{"id":"F5023C5A-5294-4383-BA4F-0109C67A020F","links":[{"href":"https://localhost:7007/core/v1/graphs/x-graph-id/properties/x-property-name","rel":"self","method":"GET","interaction":["async-polling"]},{"href":"https://localhost:7007/core/v1/graphs/x-graph-id/properties/x-property-name","rel":"canonical","method":"GET","interaction":["async-polling"]}],"dimension":0,"propertyId":"F5023C5A-5294-4383-BA4F-0109C67A020F","name":"ID","entityType":"vertex","type":"integer","namespace":"2C17C639-3771-3E30-88AE-34D6B380C5EC","transient":false},"C588F89E-53EB-46DD-A83D-1078138C42C7":{"id":"C588F89E-53EB-46DD-A83D-1078138C42C7","links":[{"href":"https://localhost:7007/core/v1/graphs/x-graph-id/properties/x-property-name","rel":"self","method":"GET","interaction":["async-polling"]},{"href":"https://localhost:7007/core/v1/graphs/x-graph-id/properties/x-property-name","rel":"canonical","method":"GET","interaction":["async-polling"]}],"dimension":0,"propertyId":"C588F89E-53EB-46DD-A83D-1078138C42C7","name":"NAME","entityType":"vertex","type":"string","namespace":"2C17C639-3771-3E30-88AE-34D6B380C5EC","transient":false}},"vertexLabels":{"id":"89FB1A38-BCDF-4FB0-9F8C-59471872BEA3","links":[{"href":"https://localhost:7007/core/v1/graphs/x-graph-id/properties/x-property-name","rel":"self","method":"GET","interaction":["async-polling"]},{"href":"https://localhost:7007/core/v1/graphs/x-graph-id/properties/x-property-name","rel":"canonical","method":"GET
10:37:50.655 [pgx-client-thread-2] DEBUG oracle.pgx.api.PgxSession - engine reports latest snapshot is 0 milli-seconds old. Max age is 0 milli-seconds
10:37:50.655 [pgx-client-thread-2] DEBUG oracle.pgx.api.PgxSession - ==> within range. Return snapshot
PgxGraph(name: bank_graph_analytics, v: 1000, e: 5001, directed: True, memory(Mb): 0)

13.2.2 Connecting with Java

You can obtain a connection to a remote graph server (PGX) instance by simply passing the base URL of the remote PGX instance to the getInstance() method. By doing this, your application automatically uses the PGX client libraries to connect to a remotely-located graph server (PGX).

You can specify the base URL when you initialize the graph server (PGX) instance using Java. An example is as follows. A URL to an graph server (PGX) is provided to the getInMemAnalyst API call.

import oracle.pgx.api.*;
import oracle.pg.rdbms.*;
ServerInstance instance = GraphServer.getInstance("https://<hostname>:<port>","<username>","<password>".toCharArray());
PgxSession session = instance.createSession("my-session");

Note:

See Java API Reference for more information on the Java APIs.

13.2.2.1 Starting and Stopping the PGX Engine

You can start the graph server (PGX ) from the application by making a call to instance.startEngine() which takes a JSON object as an argument for PGX configuration.

Note:

Stopping the PGX Engine

You can stop the PGX engine using one of the following APIs:

instance.shutdownEngineNow(); // cancels pending tasks, throws exception if engine is not running
instance.shutdownEngineNowIfRunning(); // cancels pending tasks, only tries to shut down if engine is running
if (instance.shutdownEngine(30, TimeUnit.SECONDS) == false) { 
  // doesn't accept new tasks but finishes up remaining tasks
  // pending tasks didn't finish after 30 seconds
}

Note:

Shutting down the PGX engine keeps the Apache Tomcat server alive, but new sessions cannot be created. Also, all the current sessions and tasks will be cancelled and terminated.

13.2.3 Connecting with Python

You can connect to a remote graph server (PGX) instance in your Python program. You must first authenticate with the remote server before you can create a session as illustrated in the following example:

import pypgx
import opg4py
import opg4py.graph_server as graph_server
pgql_conn = opg4py.pgql.get_connection("<username>","<password>", "<jdbc_url>")
pgql_statement = pgql_conn.create_statement()
pgql = """
        CREATE PROPERTY GRAPH bank_graph
        VERTEX TABLES (
          bank_accounts
            LABEL ACCOUNTS
            PROPERTIES (ID, NAME)
        )
        EDGE TABLES (
          bank_txns
            SOURCE KEY (from_acct_id) REFERENCES bank_accounts
            DESTINATION KEY (to_acct_id) REFERENCES bank_accounts
            LABEL TRANSFERS
            PROPERTIES (FROM_ACCT_ID, TO_ACCT_ID, AMOUNT, DESCRIPTION)
        ) OPTIONS(PG_VIEW)
"""
pgql_statement.execute(pgql)
instance = graph_server.get_instance("<base_url>", "<username>", "<password>")
session = instance.create_session("my_session")
graph = session.read_graph_by_name('BANK_GRAPH', 'pg_view')
analyst = session.create_analyst()
analyst.pagerank(graph)
rs = graph.query_pgql("SELECT id(x), x.pagerank FROM MATCH (x) LIMIT 5")
rs.print()

To execute, save the above program into a file named program.py and run the following command:

python3 program.py

You will see the following output:

+-------------------------------------------+
| id(x)             | pagerank              |
+-------------------------------------------+
| BANK_ACCOUNTS(2)  | 9.749447313256548E-4  |
| BANK_ACCOUNTS(4)  | 0.004584001759076056  |
| BANK_ACCOUNTS(6)  | 5.358461393401424E-4  |
| BANK_ACCOUNTS(8)  | 0.0013051552434930175 |
| BANK_ACCOUNTS(10) | 0.0015040122009364232 |
+-------------------------------------------+

Converting PGQL result set into pandas dataframe

Additionally, you can also convert the PGQL result set to a pandas.DataFrame object using the to_pandas() method. This makes it easier to perform various data filtering operations on the result set and it can also be used in Lambda functions. For example,
example_query = (
    "SELECT n.name AS name, n.age AS age "
    "WHERE (n)"
)
result_set = sample_graph.query_pgql(example_query)
result_df = result_set.to_pandas()

result_df['age_bin'] = result_df['age'].apply(lambda x: int(x)/20) # create age bins based on age ranges

Note:

To view the complete set of available Python APIs, see OPG4PY Python API Reference.