

# チュートリアル: JupyterLab で Jupyter Notebook をセットアップして ETL スクリプトをテストおよびデバッグする
<a name="dev-endpoint-tutorial-local-jupyter"></a>

このチュートリアルでは、ローカルマシンで実行されている JupyterLab の Jupyter Notebook を開発エンドポイントに接続します。これは、デプロイする前に、AWS Glue 抽出、変換、ロード (ETL) スクリプトを対話的に実行、デバッグ、およびテストできるようにするためです。このチュートリアルでは、Secure Shell (SSH) ポートフォワーディングを使用して、ローカルマシンを AWS Glue 開発エンドポイントに接続します。詳細については、Wikipedia の「[Port forwarding](https://en.wikipedia.org/wiki/Port_forwarding)」を参照してください。

## ステップ1: JupyterLab と Sparkmagic をインストールする
<a name="dev-endpoint-tutorial-local-jupyter-install"></a>

JupyterLab は `conda` または `pip` を使用してインストールできます。`conda` は、Windows、macOS、および Linux で稼働するオープンソースのパッケージ管理システムおよび環境管理システムです。`pip` は Python のパッケージインストーラです。

macOS にインストールする場合は、Sparkmagic をインストールする前に Xcode をインストールしておく必要があります。

1. JupyterLab、Sparkmagic、および関連する拡張機能をインストールします。

   ```
   $ conda install -c conda-forge jupyterlab
   $ pip install sparkmagic
   $ jupyter nbextension enable --py --sys-prefix widgetsnbextension
   $ jupyter labextension install @jupyter-widgets/jupyterlab-manager
   ```

1. `Location` から `sparkmagic` ディレクトリをチェックします。

   ```
   $ pip show sparkmagic | grep Location
   Location: /Users/username/.pyenv/versions/anaconda3-5.3.1/lib/python3.7/site-packages
   ```

1. ディレクトリを、`Location` に対して返されたディレクトリに変更し、Scala と PySpark 用のカーネルをインストールします。

   ```
   $ cd /Users/username/.pyenv/versions/anaconda3-5.3.1/lib/python3.7/site-packages
   $ jupyter-kernelspec install sparkmagic/kernels/sparkkernel
   $ jupyter-kernelspec install sparkmagic/kernels/pysparkkernel
   ```

1. サンプルの `config` ファイルをダウンロードします。

   ```
   $ curl -o ~/.sparkmagic/config.json https://raw.githubusercontent.com/jupyter-incubator/sparkmagic/master/sparkmagic/example_config.json
   ```

   この設定ファイルでは、`driverMemory` や `executorCores` などの Spark 関連のパラメータを設定できます。

## ステップ 2: JupyterLab を起動する
<a name="dev-endpoint-tutorial-local-jupyter-start"></a>

JupyterLab を起動すると、デフォルトのウェブブラウザが自動的に開き、`http://localhost:8888/lab/workspaces/{workspace_name}` という URL が表示されます。

```
$ jupyter lab
```

## ステップ 3: 開発エンドポイントに接続するための SSH ポート転送を開始する
<a name="dev-endpoint-tutorial-local-jupyter-port-forward"></a>

次に、SSH ローカルポート転送を使用して、ローカルポート (ここでは `8998`) を AWS Glue で定義されたリモート送信先 (`169.254.76.1:8998`) に転送します。

1. SSH へのアクセスができる別のターミナルウィンドウを開きます。Microsoft Windows の場合、[Git for Windows](https://git-scm.com/downloads) に用意されている BASH シェルを使用するか、[Cygwin](https://www.cygwin.com/) をインストールすることができます。

1. 次のように変更した、以下の SSH コマンドを実行します。
   + `private-key-file-path` を、開発エンドポイントを作成するのに使用したパブリックキーに対応するプライベートキーを含む `.pem` ファイルへのパスに置き換えます。
   + `8998` とは異なるポートを転送している場合は、`8998` をローカルで実際に使用しているポート番号に置き換えます。この `169.254.76.1:8998` というアドレスはリモートポートです。変更することはできません。
   + `dev-endpoint-public-dns` を開発エンドポイントのパブリック DNS アドレスで置き換えます。このアドレスを確認するには、AWS Glue コンソールで開発エンドポイントに移動して名前を選択し、[**Endpoint details**] (エンドポイントの詳細) ページに一覧表示されている [**Public address**] (パブリックアドレス) をコピーします。

   ```
   ssh -i private-key-file-path -NTL 8998:169.254.76.1:8998 glue@dev-endpoint-public-dns
   ```

   以下のような警告メッセージが表示されます。

   ```
   The authenticity of host 'ec2-xx-xxx-xxx-xx.us-west-2.compute.amazonaws.com (xx.xxx.xxx.xx)'
   can't be established.  ECDSA key fingerprint is SHA256:4e97875Brt+1wKzRko+JflSnp21X7aTP3BcFnHYLEts.
   Are you sure you want to continue connecting (yes/no)?
   ```

   **yes** と入力し、JupyterLab を使用中はターミナルウィンドウを開いたままにしておきます。

1. SSH ポート転送が開発エンドポイントで正しく機能していることを確認します。

   ```
   $ curl localhost:8998/sessions
   {"from":0,"total":0,"sessions":[]}
   ```

## ステップ 4: ノートブックの段落でシンプルスクリプトフラグメントを実行する
<a name="dev-endpoint-tutorial-local-jupyter-list-schema"></a>

JupyterLab のノートブックは、開発エンドポイントで動作するようになっています。次のスクリプトフラグメントをノートブックに入力して実行します。

1. Spark が正常に実行されていることを確認します。次のコマンドによって、Sparkが `1` を計算して値を出力します。

   ```
   spark.sql("select 1").show()
   ```

1. AWS Glue Data Catalog 統合が機能しているかどうか確認します。次のコマンドで、データカタログ内のテーブルが一覧表示されます。

   ```
   spark.sql("show tables").show()
   ```

1. AWS Glue ライブラリを使用するシンプルスクリプトフラグメントが機能していることを確認します。

   次のスクリプトでは、AWS Glue Data Catalog の `persons_json` テーブルメタデータを使用して、サンプルデータから `DynamicFrame` を作成します。次に、このデータの項目数およびスキーマが出力されます。

```
import sys
from pyspark.context import SparkContext
from awsglue.context import GlueContext
 
# Create a Glue context
glueContext = GlueContext(SparkContext.getOrCreate())
 
# Create a DynamicFrame using the 'persons_json' table
persons_DyF = glueContext.create_dynamic_frame.from_catalog(database="legislators", table_name="persons_json")
 
# Print out information about *this* data
print("Count:  ", persons_DyF.count())
persons_DyF.printSchema()
```

スクリプトの出力は次のとおりです。

```
 Count:  1961
 root
 |-- family_name: string
 |-- name: string
 |-- links: array
 |    |-- element: struct
 |    |    |-- note: string
 |    |    |-- url: string
 |-- gender: string
 |-- image: string
 |-- identifiers: array
 |    |-- element: struct
 |    |    |-- scheme: string
 |    |    |-- identifier: string
 |-- other_names: array
 |    |-- element: struct
 |    |    |-- note: string
 |    |    |-- name: string
 |    |    |-- lang: string
 |-- sort_name: string
 |-- images: array
 |    |-- element: struct
 |    |    |-- url: string
 |-- given_name: string
 |-- birth_date: string
 |-- id: string
 |-- contact_details: array
 |    |-- element: struct
 |    |    |-- type: string
 |    |    |-- value: string
 |-- death_date: string
```

## トラブルシューティング
<a name="dev-endpoint-tutorial-local-jupyter-troubleshooting"></a>
+ JupyterLab のインストール中に、コンピュータが企業のプロキシまたはファイアウォールの内側にある場合、企業の IT 部門によって管理されるカスタムセキュリティプロファイルにより HTTP および SSL エラーが発生することがあります。

  `conda` が独自のリポジトリに接続できないときに、よく発生するエラーの例を次に示します。

  ```
  CondaHTTPError: HTTP 000 CONNECTION FAILED for url <https://repo.anaconda.com/pkgs/main/win-64/current_repodata.json>
  ```

  これは、会社が Python および JavaScript コミュニティで広く使用されているリポジトリへの接続をブロックすることがあるために発生した可能性があります。詳細については、JupyterLab ウェブサイトの「[Installation Problems](https://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html#installation-problems)」を参照してください。
+ 開発エンドポイントに接続しようとしたときに「*connection refused (接続拒否)*」エラーが発生した場合、古い開発エンドポイントを使用している可能性があります。新しい開発エンドポイントを作成して再接続してみます。