[{"data":1,"prerenderedAt":688},["ShallowReactive",2],{"content-\u002Fcontents\u002Flambda_dev_env":3,"surroundPost-\u002Fcontents\u002Flambda_dev_env":679},{"id":4,"title":5,"body":6,"createdAt":668,"description":128,"draft":669,"extension":670,"meta":671,"navigation":239,"path":672,"seo":673,"stem":674,"tags":675,"thumbnail":677,"updatedAt":668,"__hash__":678},"contents\u002Fcontents\u002Flambda_dev_env.md","【AWS】python-lambda-localとlambda-uploaderを使ってみた",{"type":7,"value":8,"toc":661},"minimark",[9,14,18,21,24,27,30,33,36,40,43,46,59,70,77,83,86,89,92,96,102,113,116,122,147,150,153,182,188,217,223,258,261,281,287,290,296,299,302,391,398,401,409,412,421,424,427,451,454,576,590,593,596,599,602,617,620,623,626,631,634,639,642,645,648,651,654,657],[10,11,13],"h2",{"id":12},"aws-lambda-の開発時の不満","AWS Lambda の開発時の不満",[15,16,17],"p",{},"AWS Lambda は便利で使う機会が多いです。",[15,19,20],{},"ただ、ブラウザでコードを書いて修正していくのはちょっと大変です。",[15,22,23],{},"また、依存関係がある場合はローカルでいちいち zip に固めてアップロードするのもめんどうです。",[15,25,26],{},"できれば、慣れ親しんだエディターを使って、git で管理したりアップロードは GUI を操作せずにやりたいです。",[15,28,29],{},"ということで今回はおすすめの lambda 作成環境を紹介します。",[15,31,32],{},"使用言語は python です。",[15,34,35],{},"すでにいろいろな方がわかりやすい記事を書いているので、新しい内容はないかもです。",[10,37,39],{"id":38},"開発環境は何がベスト","開発環境は何がベスト？",[15,41,42],{},"Lambda の開発環境に関して私と同じような不満を持つ人は多いようでいろいろな改善方法がすでに存在します。",[15,44,45],{},"解決策としては、現状だと以下のような選択肢になるのではないでしょうか。",[47,48,49,53,56],"ul",{},[50,51,52],"li",{},"python-lambda-local",[50,54,55],{},"AWS SAM Local",[50,57,58],{},"cloud9",[15,60,61,62,65,66,69],{},"個人的に一番簡単なのは今回紹介する",[63,64,52],"code",{},"と",[63,67,68],{},"lambda-uploader","かなと思ってます。",[15,71,72,73,76],{},"AWS SAM Local でも似たことができますが、ちょっと複雑になります。",[74,75],"br",{},"\n簡単な Lambda 関数を一つアップロードする場合ではなく、API Gateway を組み合わせるなどの少し複雑な構成の場合には使えそうです。",[15,78,79,80,82],{},"cloud9 は単純にお金がかかるのでやめました。",[74,81],{},"\n多少の出費が許容できるなら選択肢に入ると思います。",[10,84,85],{"id":85},"今回作るもの",[15,87,88],{},"Lambda → Slack の通知システムです。",[15,90,91],{},"よくあるかなりわかりやすいものにしてみました。",[10,93,95],{"id":94},"python-lambda-local-の使い方","python-lambda-local の使い方",[15,97,98,99,101],{},"python-lambda-local でできることは、python で書かれた lambda の local テストです。",[74,100],{},"\nこれを使うことででいちいちアップロードして動作確認する必要がなくなります。",[15,103,104,105,112],{},"とりあえず、",[106,107,111],"a",{"href":108,"rel":109},"https:\u002F\u002Fgithub.com\u002FHDE\u002Fpython-lambda-local",[110],"nofollow","公式","をみてみます。",[15,114,115],{},"公式によると python 2.7 か 3.7 が必要なので pyenv で 3.7 を用意しました。",[15,117,118,119,121],{},"それでは",[63,120,52],{},"をインストールしていきます。",[123,124,129],"pre",{"className":125,"code":126,"language":127,"meta":128,"style":128},"language-bash shiki shiki-themes github-dark","pip install python-lambda-local\n","bash","",[63,130,131],{"__ignoreMap":128},[132,133,136,140,144],"span",{"class":134,"line":135},"line",1,[132,137,139],{"class":138},"svObZ","pip",[132,141,143],{"class":142},"sU2Wk"," install",[132,145,146],{"class":142}," python-lambda-local\n",[15,148,149],{},"まずは一番簡単なパターンで試そうと思います。",[15,151,152],{},"作業フォルダを作成し、そこで以下の 2 つのファイルを作成します。",[123,154,156],{"className":125,"code":155,"language":127,"meta":128,"style":128},".\n├── event.json\n└── lambda_handler.py\n",[63,157,158,164,173],{"__ignoreMap":128},[132,159,160],{"class":134,"line":135},[132,161,163],{"class":162},"sDLfK",".\n",[132,165,167,170],{"class":134,"line":166},2,[132,168,169],{"class":138},"├──",[132,171,172],{"class":142}," event.json\n",[132,174,176,179],{"class":134,"line":175},3,[132,177,178],{"class":138},"└──",[132,180,181],{"class":142}," lambda_handler.py\n",[15,183,184,187],{},[63,185,186],{},"event.json","の中身はこんな感じです。",[123,189,193],{"className":190,"code":191,"language":192,"meta":128,"style":128},"language-json shiki shiki-themes github-dark","{\n  \"answer\": \"hello\"\n}\n","json",[63,194,195,201,212],{"__ignoreMap":128},[132,196,197],{"class":134,"line":135},[132,198,200],{"class":199},"s95oV","{\n",[132,202,203,206,209],{"class":134,"line":166},[132,204,205],{"class":162},"  \"answer\"",[132,207,208],{"class":199},": ",[132,210,211],{"class":142},"\"hello\"\n",[132,213,214],{"class":134,"line":175},[132,215,216],{"class":199},"}\n",[15,218,219,222],{},[63,220,221],{},"lambda-handler.py","は以下のように書きました。",[123,224,228],{"className":225,"code":226,"language":227,"meta":128,"style":128},"language-py shiki shiki-themes github-dark","import json\n\ndef lambda_handler(event, context):\n    print(\"value = \" + event['answer'])\n    return event['answer']\n","py",[63,229,230,235,241,246,252],{"__ignoreMap":128},[132,231,232],{"class":134,"line":135},[132,233,234],{},"import json\n",[132,236,237],{"class":134,"line":166},[132,238,240],{"emptyLinePlaceholder":239},true,"\n",[132,242,243],{"class":134,"line":175},[132,244,245],{},"def lambda_handler(event, context):\n",[132,247,249],{"class":134,"line":248},4,[132,250,251],{},"    print(\"value = \" + event['answer'])\n",[132,253,255],{"class":134,"line":254},5,[132,256,257],{},"    return event['answer']\n",[15,259,260],{},"次はコンソールで以下のコマンドを実行",[123,262,264],{"className":125,"code":263,"language":127,"meta":128,"style":128},"python-lambda-local -f lambda_handler lambda_handler.py event.json\n",[63,265,266],{"__ignoreMap":128},[132,267,268,270,273,276,279],{"class":134,"line":135},[132,269,52],{"class":138},[132,271,272],{"class":162}," -f",[132,274,275],{"class":142}," lambda_handler",[132,277,278],{"class":142}," lambda_handler.py",[132,280,172],{"class":142},[15,282,283,286],{},[63,284,285],{},"-f","のあとに関数名とファイル名、最後に event ファイル名を指定して実行する。",[15,288,289],{},"結果は次のように出力される。",[15,291,292],{},[293,294],"img",{"alt":128,"src":295},"\u002Fimg\u002Flambda_dev_env\u002Fpython-lambda-local-test.png",[15,297,298],{},"これで簡単なものなら local で動作することが確かめられました。",[15,300,301],{},"さて、今回やりたいのは Slack へメッセージを送ることなので、コードを以下のように書き換えます。",[123,303,305],{"className":225,"code":304,"language":227,"meta":128,"style":128},"import json\nimport requests\nimport os\n\nSLACK_URL = os.environ[\"SLACK_URL\"]\n\ndef lambda_handler(event, context):\n\n    message = \"test\"\n    payload = {\n        \"text\":message\n    }\n    data = json.dumps(payload)\n    requests.post(SLACK_URL, data)\n\n    return event['answer']\n",[63,306,307,311,316,321,325,330,335,340,345,351,357,363,369,375,381,386],{"__ignoreMap":128},[132,308,309],{"class":134,"line":135},[132,310,234],{},[132,312,313],{"class":134,"line":166},[132,314,315],{},"import requests\n",[132,317,318],{"class":134,"line":175},[132,319,320],{},"import os\n",[132,322,323],{"class":134,"line":248},[132,324,240],{"emptyLinePlaceholder":239},[132,326,327],{"class":134,"line":254},[132,328,329],{},"SLACK_URL = os.environ[\"SLACK_URL\"]\n",[132,331,333],{"class":134,"line":332},6,[132,334,240],{"emptyLinePlaceholder":239},[132,336,338],{"class":134,"line":337},7,[132,339,245],{},[132,341,343],{"class":134,"line":342},8,[132,344,240],{"emptyLinePlaceholder":239},[132,346,348],{"class":134,"line":347},9,[132,349,350],{},"    message = \"test\"\n",[132,352,354],{"class":134,"line":353},10,[132,355,356],{},"    payload = {\n",[132,358,360],{"class":134,"line":359},11,[132,361,362],{},"        \"text\":message\n",[132,364,366],{"class":134,"line":365},12,[132,367,368],{},"    }\n",[132,370,372],{"class":134,"line":371},13,[132,373,374],{},"    data = json.dumps(payload)\n",[132,376,378],{"class":134,"line":377},14,[132,379,380],{},"    requests.post(SLACK_URL, data)\n",[132,382,384],{"class":134,"line":383},15,[132,385,240],{"emptyLinePlaceholder":239},[132,387,389],{"class":134,"line":388},16,[132,390,257],{},[15,392,393,394,397],{},"ポイントは外部ライブラリの",[63,395,396],{},"requests","が使用されていること。",[15,399,400],{},"lambda で外部ライブラリを使用するには layer を使うか、外部ライブラリも含めて zip に固めてアップロードする必要があります。",[15,402,403,404,408],{},"今回は",[106,405,68],{"href":406,"rel":407},"https:\u002F\u002Fgithub.com\u002Frackerlabs\u002Flambda-uploader",[110],"を利用して後者の方法で試していきます。",[15,410,411],{},"まずは pip でインストール",[123,413,415],{"className":225,"code":414,"language":227,"meta":128,"style":128},"pip install lambda-uploader\n",[63,416,417],{"__ignoreMap":128},[132,418,419],{"class":134,"line":135},[132,420,414],{},[15,422,423],{},"次は upload するための設定ファイルを用意します。",[15,425,426],{},"場所はこれまでの作業フォルダと同じで大丈夫なので、フォルダ内は以下のようになります。",[123,428,430],{"className":125,"code":429,"language":127,"meta":128,"style":128},"├── event.json\n├── lambda.json\n└── lambda_handler.py\n",[63,431,432,438,445],{"__ignoreMap":128},[132,433,434,436],{"class":134,"line":135},[132,435,169],{"class":138},[132,437,172],{"class":142},[132,439,440,442],{"class":134,"line":166},[132,441,169],{"class":138},[132,443,444],{"class":142}," lambda.json\n",[132,446,447,449],{"class":134,"line":175},[132,448,178],{"class":138},[132,450,181],{"class":142},[15,452,453],{},"設定ファイルは以下のように記述しました。",[123,455,457],{"className":190,"code":456,"language":192,"meta":128,"style":128},"{\n  \"name\": \"notify_func\",\n  \"description\": \"slack notification\",\n  \"region\": \"ap-northeast-1\",\n  \"runtime\": \"python3.7\",\n  \"handler\": \"lambda_handler.lambda_handler\",\n  \"role\": \"lambdaの実行ロール\",\n  \"requirements\": [\"requests\"],\n  \"timeout\": 5,\n  \"memory\": 128\n}\n",[63,458,459,463,476,488,500,512,524,536,550,562,572],{"__ignoreMap":128},[132,460,461],{"class":134,"line":135},[132,462,200],{"class":199},[132,464,465,468,470,473],{"class":134,"line":166},[132,466,467],{"class":162},"  \"name\"",[132,469,208],{"class":199},[132,471,472],{"class":142},"\"notify_func\"",[132,474,475],{"class":199},",\n",[132,477,478,481,483,486],{"class":134,"line":175},[132,479,480],{"class":162},"  \"description\"",[132,482,208],{"class":199},[132,484,485],{"class":142},"\"slack notification\"",[132,487,475],{"class":199},[132,489,490,493,495,498],{"class":134,"line":248},[132,491,492],{"class":162},"  \"region\"",[132,494,208],{"class":199},[132,496,497],{"class":142},"\"ap-northeast-1\"",[132,499,475],{"class":199},[132,501,502,505,507,510],{"class":134,"line":254},[132,503,504],{"class":162},"  \"runtime\"",[132,506,208],{"class":199},[132,508,509],{"class":142},"\"python3.7\"",[132,511,475],{"class":199},[132,513,514,517,519,522],{"class":134,"line":332},[132,515,516],{"class":162},"  \"handler\"",[132,518,208],{"class":199},[132,520,521],{"class":142},"\"lambda_handler.lambda_handler\"",[132,523,475],{"class":199},[132,525,526,529,531,534],{"class":134,"line":337},[132,527,528],{"class":162},"  \"role\"",[132,530,208],{"class":199},[132,532,533],{"class":142},"\"lambdaの実行ロール\"",[132,535,475],{"class":199},[132,537,538,541,544,547],{"class":134,"line":342},[132,539,540],{"class":162},"  \"requirements\"",[132,542,543],{"class":199},": [",[132,545,546],{"class":142},"\"requests\"",[132,548,549],{"class":199},"],\n",[132,551,552,555,557,560],{"class":134,"line":347},[132,553,554],{"class":162},"  \"timeout\"",[132,556,208],{"class":199},[132,558,559],{"class":162},"5",[132,561,475],{"class":199},[132,563,564,567,569],{"class":134,"line":353},[132,565,566],{"class":162},"  \"memory\"",[132,568,208],{"class":199},[132,570,571],{"class":162},"128\n",[132,573,574],{"class":134,"line":359},[132,575,216],{"class":199},[15,577,578,579,582,583,586,587,589],{},"ポイントは",[63,580,581],{},"role","の指定と",[63,584,585],{},"requirements","のところに使用する外部ライブラリを記述すること。",[74,588],{},"\nなのでロールはあらかじめ作成しておく必要があります。",[15,591,592],{},"あとは AWS の認証情報をあらかじめ設定しておくことです。",[15,594,595],{},"一度でも、aws cli を使った人なら問題ないと思います。",[15,597,598],{},"ここまできたらあとはコマンド一発でアップロードできます。",[15,600,601],{},"以下のコマンドをコンソールで実行します。",[123,603,605],{"className":125,"code":604,"language":127,"meta":128,"style":128},"lambda-uploader --variables '{\"SLACK_URL\": \"hogehoge\"}'\n",[63,606,607],{"__ignoreMap":128},[132,608,609,611,614],{"class":134,"line":135},[132,610,68],{"class":138},[132,612,613],{"class":162}," --variables",[132,615,616],{"class":142}," '{\"SLACK_URL\": \"hogehoge\"}'\n",[15,618,619],{},"オプションの variables は lambda で使用する環境変数です。slack の webhook の url を入れます。",[15,621,622],{},"なんとこのコマンドだけでコードが zip に固められ aws にアップロードされます。",[15,624,625],{},"コンソールでアップロードを確認し、test イベントを実行してみます。",[15,627,628],{},[293,629],{"alt":128,"src":630},"\u002Fimg\u002Flambda_dev_env\u002Fsuccess_upload.png",[15,632,633],{},"slack にもしっかりメッセージが飛んでます。",[15,635,636],{},[293,637],{"alt":128,"src":638},"\u002Fimg\u002Flambda_dev_env\u002Fslack.png",[15,640,641],{},"簡単ですね！",[10,643,644],{"id":644},"まとめ",[15,646,647],{},"今回は lambda の開発環境の紹介でした。",[15,649,650],{},"今まで便利なツールの存在を知りながら、コンソールでコードを書いていたのでようやくコンソールを卒業できてスッキリしました。",[15,652,653],{},"思っていたよりさくっとできたので、もっと早く試しておけばよかったです。",[15,655,656],{},"一番時間がかかったのが python 3.7 のインストールでした。",[658,659,660],"style",{},"html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}",{"title":128,"searchDepth":166,"depth":166,"links":662},[663,664,665,666,667],{"id":12,"depth":166,"text":13},{"id":38,"depth":166,"text":39},{"id":85,"depth":166,"text":85},{"id":94,"depth":166,"text":95},{"id":644,"depth":166,"text":644},"2019-11-30",false,"md",{},"\u002Fcontents\u002Flambda_dev_env",{"title":5,"description":128},"contents\u002Flambda_dev_env",[676],"AWS","\u002Fimg\u002Ftwitter-card.png","1uQD1KUFXw-tHB9-OVjKuD5bv3X4_BNt9WeT6Jw--Bo",[680,684],{"title":681,"path":682,"stem":683,"children":-1},"ついに読んだ「君たちはどう生きるか」","\u002Fcontents\u002Fkimitachiha_doikiruka","contents\u002Fkimitachiha_doikiruka",{"title":685,"path":686,"stem":687,"children":-1},"Learning Personalized Agents from Human Feedback","\u002Fcontents\u002Flearning-personalized-agents-from-human-feedback","contents\u002Flearning-personalized-agents-from-human-feedback",1784936719178]