中小企業診断士(登録予定)兼黄昏開発者のヨシダです。いかがお過ごしですか。
自己紹介は最下部で。
今日は様々なデータソースをLambdaで収集するシステムを作る中で、前半は診断士として経営におけるBIの重要性、後半は黄昏開発者としてAWSとPythonへ5つの注意点を述べます。
Ⅰ.AIが発展しても、経営判断を下すのは"ヒト"。だから可視化をBIで目指しています
1.何を作っているのか
GW、家族サービスの空き時間でAWS LambdaとAWS CloudWatchを使って、openWeatherMapから気象情報を取得するシステムを作っていました。
IoTで蓄積された数多の情報を、自社のビジネス判断に加工・可視化する流れは、AIの登場の置いても重要な経営判断材料には変わりありません。いや、AIのなぜそのような判断に至ったprocessの可視化という位置づけでBIはさらに重要性を増すとも考えられます。
気象情報を取得する、という行為はあくまで一例です。数多の情報を取得・加工する仕組みづくりの1つのSampleとして作りました。秋にHawaiiに行く用事があるので、気象情報を今からあつめておきたい目的もあります。
その際、Pythonのお作法や、AWS Lambdaのクセに苦労したのでご紹介します。
Ⅱ.AWS Lambda + AWS CloudWatch + Pythonの5つの注意点
1.[AWS Lambda]ファイルはプログラム実行ディレクトリに作れない
以下のSample1.pyの用に、csvを一時的に作ってwriterを作り、csvにデータ行を追加する処理はエラーになります。AWSの言い分は恐らく**「S3があるんだから勝手な場所に、一時ファイル作るのは禁止」**
import datetime
import pytz
(中略)
with open('Weatherlog_{0:%Y%m%d}'.format(now)+'.csv', 'a', newline='') as f:
## 上のwithでエラー""##
writer = csv.writer(f)
writer.writerow(略)
このwithの所でエラーになります。このお作法は理解出来ます、しかしわかりにくいんですよねAWSのマニュアル。
2.[AWS Lambda]Lambda-uploaderが作るZIPファイルは激重
AWS Lambdaで標準準備されているライブラリを使いこなせればベストなのですが、黄昏開発者のヨシダにとって、初体験のpythonではWeb記事のパズルプログラミングが限界です。記事が少ないAWS Lambdaのライブラリ利用は敷居が高いです。だからimportで一般的なライブラリを使います。
Lambda-uploaderを使って開発環境のライブラリもまとめてUPするのですが、**「あれ?28Mbyte??」と激重。**ダイエットどうにかならないでしょうか?
誰かAWS標準ライブラリの使い方ご教示いただけないでしょうか...
3.[AWS CloudWatch]cronはUTC基準
AWSの言い分は「無料枠でcron実行させてやるからUTCは我慢してください」でしょうか。
いやいや、1ドル払っているはずですが...という反論は野暮ですので辞めましょう。
CloudWatchを使って定期実行するのですが、基準がUTC基準ですので、何時に、みたいな実行をすると見当違いの時間に動き出します。注意です。
4.[Python]datetimeの使い方が面倒
import datetime
import pytz
(中略)
JST = pytz.timezone('Asia/Tokyo')
now = datetime.datetime.now(JST)##Way Japanese Python!!???
datetime関数から現在時刻を取得する時に現在日付を取得するとき、なぜdatetime.datetime.now()とネストしてnow()を指定しないと駄目なんですか?聞いた100人全員「面倒」って言うレベルではないでしょうか。
5.[AWS Lambda]boto3でCSVファイルに追記ができない
これは困りました。s3の特定バケットにCSVファイルを作り、1時間おきにファイルにAPI取得データを追記する、というプログラムを簡単に書こうを思い立つも、boto3ライブラリのadd関数は完全上書き。Delete-Insert、OH MY GOD!
import boto3
(中略)
file_contents = '中略'
file_contents = file_contents + '\n'
(中略)
s3 = boto3.resource('s3')
obj = s3.Object(bucket_name,file_name) ##S3の指定バケット指定ファイルを取得
bodychr = obj.get()['Body'].read().decode('utf-8') ##現在のファイル中身を取得
obj.put(Body=file_contents) ##(case01)取得したファイルを上書きする
obj.put(Body=bodychr + file_contents) ##(case02)取得したファイルに追記する
case01のロジックだと折角のS3ファイル内容を消して上書きします。
case02のようにファイル内容を取得し、最後尾に追加していくことで解決しました。
以上です。
-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-
ヨシダ:中小企業診断士(2018年登録予定) 兼 黄昏開発者
ブログもやっています。見てやって下さい!
空飛ぶITコンサルタント(http://yoshidaagri.hatenablog.com/)
-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-