AWS GlueでS3上にあるPythonの外部ライブラリをインポートして利用する

題名の件、Glueで外部ライブラリをインポートしたので、その方法を書いておきます。

外部ライブラリ

何でも良いのですが、ググったら出てきたわかりやすいやつです。ASCIIアートを表示します。これをGlueにインポートして使えるようにしてみます。

github.com

$ python
Python 3.6.7 (default, Oct 22 2018, 11:32:17)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from art import *
>>> print(text2art("yomon8",font='block',chr_ignore=True))

 .----------------.  .----------------.  .----------------.  .----------------.  .-----------------.  .----------------.
| .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. |
| |  ____  ____  | || |     ____     | || | ____    ____ | || |     ____     | || | ____  _____  | || |     ____     | |
| | |_  _||_  _| | || |   .'    `.   | || ||_   \  /   _|| || |   .'    `.   | || ||_   \|_   _| | || |   .' __ '.   | |
| |   \ \  / /   | || |  /  .--.  \  | || |  |   \/   |  | || |  /  .--.  \  | || |  |   \ | |   | || |   | (__) |   | |
| |    \ \/ /    | || |  | |    | |  | || |  | |\  /| |  | || |  | |    | |  | || |  | |\ \| |   | || |   .`____'.   | |
| |    _|  |_    | || |  \  `--'  /  | || | _| |_\/_| |_ | || |  \  `--'  /  | || | _| |_\   |_  | || |  | (____) |  | |
| |   |______|   | || |   `.____.'   | || ||_____||_____|| || |   `.____.'   | || ||_____|\____| | || |  `.______.'  | |
| |              | || |              | || |              | || |              | || |              | || |              | |
| '--------------' || '--------------' || '--------------' || '--------------' || '--------------' || '--------------' |
 '----------------'  '----------------'  '----------------'  '----------------'  '----------------'  '----------------'

参照元

こちらに記述がある方法です。

docs.aws.amazon.com

アップロードパッケージ作成

GlueのSparkジョブは未だにPython2.7です。古いバージョンPCに入ってないので、docker使ってサクッとパッケージ作ります。

# ワークディレクトリで適当な名前のディレクトリ作成
$ mkdir art

# Dockerでpython:2.7をイメージ使って依存パッケージを出力
$ sudo docker run -it --rm -v $(pwd)/art:/art python:2.7 pip install -t /art art

# パッケージが出力されたディレクトリに移動
$ ls art/
art  art-3.6.dist-info  bin  coverage  coverage-4.5.3.dist-info
$ cd art/

# ZIPファイルを作成
$ zip -r ../art.zip ./*

# S3にアップロード
$ aws s3 cp ../art.zip s3://otomo-glue-libs/
upload: ../art.zip to s3://otomo-glue-libs/art.zip

GlueジョブにPythonの外部パッケージ設定

ジョブの設定で、S3のフルパスを設定します。

f:id:yomon8:20190621232307p:plain

GlueのPySparkコードから実行

GlueのLoggerに出力してみます。

from pyspark.context import SparkContext
from awsglue.context import GlueContext

sc = SparkContext()
glueContext = GlueContext(sc)
logger = glueContext.get_logger()

from art import *
logger.info(text2art("yomon8",font='block',chr_ignore=True))

出力結果

ズレてしまっていますが、S3にアップロードした外部ライブラリ使って出力できているようです。

f:id:yomon8:20190621233321p:plain

本当はこんなことしたかったわけではなく・・

変な題材で手順を書いてしまいましたが、そもそもはGlueでboto3を使おうとしたところ、メソッドが見つからないというエラーが発生したところに起因します。

boto3が古い

まさかと思い調べてみたらGlueのpysparkで使われているboto3のバージョンが 1.7.47と古いことが判明・・

import boto3
import botocore
logger.info('boto3.version->%s' % boto3.__version__)
logger.info('botocore.version->%s' % botocore.__version__)
19/06/21 21:50:41 INFO GlueLogger: boto3.version->1.7.47
19/06/21 21:50:41 INFO GlueLogger: botocore.version->1.10.70

boto3を最新化

上記のartモジュールと同じ手法でboto3を設定したら良い感じにバージョン上がりました。

2019/06/21 22:00:27 19/06/21 13:00:27 INFO GlueLogger: boto3.version->1.9.173
2019/06/21 22:00:27 19/06/21 13:00:27 INFO GlueLogger: botocore.version->1.12.173

しかし動かない

しかし、以下のエラーで動かない。

botocore.exceptions.DataNotFoundError: Unable to load data for: endpoints

原因はこれだと思われます。

What boto3 does for initialisation is it will download a bunch files and save it inside the distribution folder. Because your boto3 lives in a zip package, so obviously those files won't be able to it to there

stackoverflow.com

内容的にしょうがないと思えたので、せっかくだから外部ライブラリ利用の部分だけ手順として残しておきました。