Python で Oracle Graph（Jupyter 導入）

![python.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410176/031d50c8-653d-9d16-9b05-08f11ec14251.jpeg)
Oracle Graph を Python で操作するために、まずは同じクラウド環境に Jupyter をインストールする方法を紹介します。以前の記事「Oracle Graph をクラウド上で構築（[ADB 編](https://qiita.com/ryotayamanaka/items/7769d1ed239bf997e3ff) と [DBCS 編](https://qiita.com/ryotayamanaka/items/ef3c7bef872daf276979)）」では Marketplace イメージを使用して Graph Server をセットアップしたので、今回はこのインスタンスに Jupyter をインストールします。

## Jupyter のインストール

Jupyter にウェブブラウザからアクセスするためのポート `8888` を開放します。
![Screen Shot 2022-05-03 at 14.11.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410176/e106c4b2-6d28-29c4-feb7-6c8aaf577dea.png)

ひとまず全ての IP アドレス `0.0.0.0/0` からアクセス可能としますが、実利用では適切に制限してください。
![Screen Shot 2022-05-03 at 15.00.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410176/0216a04a-afcb-2feb-7cf7-2be29588becb.png)

Compute インスタンスにログインします。

```
$ ssh <public_ip_address> -l opc -i <secret_key_file>
```

Jupyter をインストールします。ここでは次の手順に従っています。
- [Alternative for experienced Python users: Installing Jupyter with pip](https://jupyter.readthedocs.io/en/latest/install/notebook-classic.html)

```
$ sudo pip3 install --upgrade pip
$ pip3 install jupyter
```

`jupyter` コマンドが実行できることを確認します。
```
$ jupyter --version
Selected Jupyter core packages...
IPython          : 8.3.0
ipykernel        : 6.13.0
ipywidgets       : 7.7.0
jupyter_client   : 7.3.0
jupyter_core     : 4.10.0
jupyter_server   : 1.17.0
jupyterlab       : not installed
nbclient         : 0.6.0
nbconvert        : 6.5.0
nbformat         : 5.3.0
notebook         : 6.4.11
qtconsole        : 5.3.0
traitlets        : 5.1.1
```

コマンドが実行できない場合、PATH 環境変数が適切に設定されていることを確認してください。
```
$ vi ~/.bash_profile

# User specific environment and startup programs
PATH=$PATH:$HOME/.local/bin:$HOME/bin
export PATH

$ source ~/.bash_profile
```

設定ファイルを生成します。
```
$ jupyter notebook --generate-config
Writing default config to: /home/opc/.jupyter/jupyter_notebook_config.py
```

全ての IP アドレスからアクセスできるように設定を変更します。
```
$ vi /home/opc/.jupyter/jupyter_notebook_config.py

## The IP address the notebook server will listen on.
#c.NotebookApp.ip = 'localhost'
c.NotebookApp.ip = '*'
```

ログインパスワードを設定します。
```
$ jupyter notebook password
Enter password: 
Verify password: 
[NotebookPasswordApp] Wrote hashed password to /home/opc/.jupyter/jupyter_notebook_config.json
```

ファイアーウォールの `8888` ポートを開放するように設定します。
```
sudo firewall-cmd --permanent --zone=public --add-port=8888/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
```

Jupyter のルートとなるディレクトリを作成し、そのディレクトリに移動してから Jupyter を開始します。
```
$ mkdir ~/jupyter
$ cd ~/jupyter
$ jupyter notebook --no-browser
[W 03:30:05.192 NotebookApp] WARNING: The notebook server is listening on all IP addresses and not using encryption. This is not recommended.
[I 03:30:05.196 NotebookApp] Serving notebooks from local directory: /home/opc/jupyter
[I 03:30:05.196 NotebookApp] Jupyter Notebook 6.4.11 is running at:
[I 03:30:05.197 NotebookApp] http://oraclegraph-instance:8888/
[I 03:30:05.197 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
```

ウェブブラウザで `http://<ip_address>:8888/` にアクセスします。
![Screen Shot 2022-05-09 at 13.33.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410176/88acaa5b-a5a5-3cf7-4de7-40183ccc6d20.png)

パスワードを入力してログインします。
![Screen Shot 2022-05-09 at 13.34.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410176/474dce88-bbb2-2be7-b48c-0f7f024eee63.png)


## Graph Server への接続

早速、Graph Server に接続して PGQL クエリを実行してみましょう。
![Screen Shot 2022-05-09 at 16.41.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410176/20e0f69f-fe01-cda3-e65f-9b12f9e857f1.png)

まずはじめのセルでは、Graph Server へのセッションを作成しています。ここで入力するパスワードはデータベース・ユーザー `GRAPHUSER` に設定されているものです。Graph Server はデータベースに問い合わせて、このユーザーが無事に認証されればセッションを作成して、セッション ID を返します。

```py
import pypgx.pg.rdbms.graph_server as graph_server
from pypgx import setloglevel
from getpass import getpass

setloglevel("ROOT","WARN")

base_url = "https://localhost:7007"
username = "graphuser"
password = "<password>"

instance = graph_server.get_instance(base_url, username, password)
session = instance.create_session("jupyter")
analyst = session.create_analyst()

print(session)
```
```
PgxSession(id: 9021c495-f3c4-4040-9aae-4c38814fc59b, name: jupyter)
```

Graph Client のバージョン 22.4 からは以下のように import する方法が推奨です。

```python
# import pypgx.pg.rdbms.graph_server as graph_server
from opg4py import graph_server
```

デフォルトでロードされているグラフ `hr` を表示すると、ノードとエッジの数がわかります。
```py
graph = session.get_graph("hr")
graph
```
```
PgxGraph(name: hr, v: 215, e: 509, directed: True, memory(Mb): 0)
```

デフォルトでロードされているグラフ `hr` を表示すると、ノードとエッジの数がわかります。
```py
graph = session.get_graph("hr")
graph
```

PGQL クエリで 5 つのエッジとその両端のノードを取得します。
```py
session.query_pgql("""
SELECT *
FROM MATCH (v1)-[e]->(v2) ON hr
LIMIT 5
""").print()
```
```
+--------------------------------------------------------------------------------------+
| v1                               | v2                                | e             |
+--------------------------------------------------------------------------------------+
| PgxVertex[ID=38717052524494488]  | PgxVertex[ID=7146201194179991032] | PgxEdge[ID=0] |
| PgxVertex[ID=38717052524494488]  | PgxVertex[ID=8603461645393757903] | PgxEdge[ID=1] |
| PgxVertex[ID=589327002090697123] | PgxVertex[ID=8024468535509075467] | PgxEdge[ID=2] |
| PgxVertex[ID=751458733606462345] | PgxVertex[ID=751458733606462345]  | PgxEdge[ID=3] |
| PgxVertex[ID=751458733606462345] | PgxVertex[ID=751458733606462345]  | PgxEdge[ID=4] |
+--------------------------------------------------------------------------------------+
```

この環境を用いて、以降の記事では、クエリ結果の可視化やグラフ・アルゴリズムの実行方法について紹介します。