Windows10でのPythonの一時ファイルtempfile.NamedTemporaryFileへのアクセス ~ Windowsではいったん閉じないと駄目

次のようにして、tempfileへアクセスしようとしたらエラー。

file = NamedTemporaryFile(suffix='.xlsx', delete=False)
s3.Bucket(bucket).download_file(key, file.name)

悩んで仕様を注意深く読むと。。。。
docs.python.org
f:id:graySpace:20200430134425p:plain

file = NamedTemporaryFile(suffix='.xlsx', delete=False)
filename = file.name
file.close() #Windows10では開いたままだとアクセスできないので閉じる
s3.Bucket(bucket).download_file(s3_key, filename)

AWS S3へboto3を使用してdataframeを保存する

下のようにすればOK。

import boto3
s3 = boto3.resource('s3')
s3_obj = s3.Object('bucket_name', key=u'test/output.csv')
s3_obj.put(Body=df.to_csv(None).encode('utf_8'))

ただ、注意点が1つあって、Objectの引数keyの指定は'[フォルダ名1]/[フォルダ名2]/[フォルダ名3]・・・/[フォルダ名N]/[ファイル名]'とする
例えば、S3のbucket_nameが"20200421.test.bucket.name.xxxx"で、その中に、「test1」というフォルダがあり、その配下に「test2」というフォルダがあり、そこに「output.csv」を保存したい場合は次のように書く。
注意すべきは最初のフォルダ名の前に「/」を入れないようにすること。

s3_obj = s3.Object('20200421.test.bucket.name.xxxx', key=u'test1/test2/output.csv')

OSError: [Errno 30] Read-only file system: ~ AWS Lambdaは/tmp/配下のファイルにしか書き込めない

AWS Lambdaでは/tmp配下のファイルにしか書き込めないので、一時ファイルを用意してそこに書き込んでから最後に元のファイルにコピーしようとしたけど、コピーも書き込みだから駄目だった。
エラーが出てから、そりゃそうかと思ったw。
これは、使いづらいなと思ったが、Lambdaとはそもそもインメモリーで処理することを前提とした設計(のはず)だから、永続化したファイルなんてそうそう使うべきではないのだ。
移行のポイントはこういうところだろうね。

tmp_file_path = '/tmp/'+"file.txt" ###Lambdaでは/tmp/配下のファイルにしか書き込めないので、一時ファイルを用意

shutil.copy2(src_file_path, tmp_file_path) 
excel_workbook.save(filename=tmp_file_path)
shutil.copy2(tmp_file_path, src_file_path) ###残念ながら、元のフォルダのファイルにコピーして戻そうとするとここでエラー

Build Failed Error: PythonPipBuilder:ResolveDependencies - {LibraryName==1.3.0(sdist)}

AWS Toolkit+PyCharmをWindows10で実行中に起きたことのメモ。

Projectのtemplate.yamlを右クリックして、Server ApplicationのDeployをしようとしたら次のエラー

Build Failed Error: PythonPipBuilder:ResolveDependencies - {LibraryName==1.3.0(sdist)}

以前も遭遇して、その時は下記に書かれているように「sam build --use-container」として「--use-container」を使用して解決。
github.com

ただ、今回は「--use-container」を指定する場所が分からない。。。
試しにコマンドラインでSAMでbuildを試みると、成功。

しばらく考えると、オプションチェックする場所を発見。。。
f:id:graySpace:20200421144709p:plain
これでbuild成功。

AWS サーバーレスアプリケーションモデル ~ チュートリアル: Hello World アプリケーションのデプロイの実施

今回のお題は「AWS サーバーレスアプリケーションモデル ~ チュートリアル: Hello World アプリケーションのデプロイの実施」

記事からの引用だが、前提条件はこれ。
f:id:graySpace:20200414145938p:plain

次の3つのステップを実施する。
動作環境はWSLで、OSはubuntu

#Step 1 - Download a sample application
sam init

#Step 2 - Build your application
cd sam-app
sam build

#Step 3 - Deploy your application
sam deploy --guided

ここまでは特に問題なし。詳細は記事参照

問題は「ステップ 4: アプリケーションをローカルでテストする (オプション)」。

ドキュメントに従って、API をローカルでホストする。

$sam local start-api
Error: Running AWS SAM projects locally requires Docker. Have you got it installed?

おかしい。。。WSLにもdockerをインストールしたのだが、Dockerが必要だと言われる。
ぐぐったら、次の記事に原因が書いてあった。
qiita.com

記事から引用させていただくと、原因は「WSL内のDockerはホストにはなれず、WSLはあくまでもクライアント」だから、利用できないようです。
f:id:graySpace:20200414152551p:plain

したがって、WindowsにインストールしたDockerを、WSLから使う必要がある。
そのために、下記設定を行う(これも記事から引用)。
f:id:graySpace:20200414152839p:plain

設定を行うと起動成功。

user@host:~/workspace/sam-app$ sam local start-api
Mounting HelloWorldFunction at http://127.0.0.1:3000/hello [GET]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2020-04-14 15:32:44 * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)

しかし、いくら待ってもAWSのマニュアル通りの出力にならない。
Docker イメージが読み込まれない。。。
f:id:graySpace:20200414153503p:plain

気にせず、curlで「curl http://127.0.0.1:3000/hello」もしくはブラウザで「http://127.0.0.1:3000/hello」を実行すると、Dockerイメージは読み込まれたが、502エラー。

Lambda returned empty body!
Invalid API Gateway Response Keys: {'errorMessage', 'errorType'} in {'errorType': 'Runtime.ImportModuleError', 'errorMessage': "Unable to import module 'app': No module named 'app'"}

2020-04-14 06:39:34 127.0.0.1 - - [14/Apr/2020 06:39:34] "GET /hello HTTP/1.1" 502 -
2020-04-14 06:39:34 127.0.0.1 - - [14/Apr/2020 06:39:34] "GET /favicon.ico HTTP/1.1" 403 -

1 回限りの呼び出しを実行してみるとDockerイメージの読み込みが行われたが、エラー。。。

user@host:~/workspace/sam-app$ sam local invoke HelloWorldFunction --event ./events/event.json
Invoking app.lambda_handler (python3.7)

Fetching lambci/lambda:python3.7 Docker container image......
Mounting /home/user/workspace/sam-app/.aws-sam/build/HelloWorldFunction as /var/task:ro,delegated inside runtime container
START RequestId: 143cbc71-xxb3-114b-b44c-ba4d31cda5fc Version: $LATEST
[ERROR] Runtime.ImportModuleError: Unable to import module 'app': No module named 'app'

END RequestId: 111xxxbc1272-aab3-114b-b84c-ba8d31cda9fc
REPORT RequestId: 7aera91cbc72-aaeraeraab3-1aera14b-b8aewra4c-baaera8d31arecda9fc Init Duration: 97.00 ms Duration: 2.98 ms
Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 23 MB

{"errorType":"Runtime.ImportModuleError","errorMessage":"Unable to import module 'app': No module named 'app'"}

「AWS サーバーレスアプリケーションモデル」のサンプルアプリ稼働時に「Error: Failed to create managed resources: Unable to locate credentials」

AWS サーバーレスアプリケーションモデル」のサンプルアプリ「チュートリアル: Hello World アプリケーションのデプロイ」を実施する際に、Credentialが設定されていなかった。
ついでに、AWS CLIもインストールしていなかったので、下記流れで設定。

1.AWS CLIをインストール
2.「aws configure list」コマンドでCredentialの確認
3.設定がされていなかったら「aws configure」で設定。

まず、「AWS サーバーレスアプリケーションモデル」のサンプルアプリ「チュートリアル: Hello World アプリケーションのデプロイ」を実施する際に、Credentialが設定されていなかったのでエラー「Error: Failed to create managed resources: Unable to locate credentials」

user@host:~/workspace$ cd sam-app/

user@host:~/workspace/sam-app$ ls
README.md events hello_world template.yaml tests

user@host:~/workspace/sam-app$ sam build
Building resource 'HelloWorldFunction'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource

Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided


user@host:~/workspace/sam-app$ sam deploy --guided
Configuring SAM deploy
======================

Looking for samconfig.toml : Not found

Setting default arguments for 'sam deploy'
=========================================
Stack Name [sam-app]:
AWS Region [us-east-1]:
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [y/N]:
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]:
Save arguments to samconfig.toml [Y/n]:
Error: Failed to create managed resources: Unable to locate credentials

AWS CLIをインストール
インストールしたら、credentialを確認。

user@host:~/workspace$ aws configure list
Name Value Type Location
---- ----- ---- --------
profile None None
access_key None None
secret_key None None
region None None

たしかに何も設定されていないので、「aws configure」で設定。

user@host:~/workspace$aws configure

WSLにAWS SAM CLIをインストールしようとしたら、「Error: patchelf must be installed: brew install patchelf」 ~  「brew install gcc」も「brew install patchelf」も実行できない

WSLにAWS SAM CLIをインストールしようとしたら、「Error: patchelf must be installed: brew install patchelf」となった。

結論から述べるとbrewgccはインストールできないから、apt-get installしろ」

WSLのOSはubuntu

user@host:~/workspace$ brew install aws-sam-cli
==> Installing aws-sam-cli from aws/tap
==> Installing dependencies for aws/tap/aws-sam-cli: patchelf, m4, gmp, mpfr, libmpc, isl@0.18, zlib, gcc, gdbm, openssl@1.1, ncurses, readline, sqlite, xz, bzip2, libffi and python
==> Installing aws/tap/aws-sam-cli dependency: patchelf
==> Downloading https://linuxbrew.bintray.com/bottles/patchelf-0.10.x86_64_linux.bottle.tar.gz
Already downloaded: /home/user/.cache/Homebrew/downloads/405227c46362964d2bc2e9ff6428fe082dff4dbd3a4b0b29453743f71923304b--patchelf-0.10.x86_64_linux.bottle.tar.gz
==> Pouring patchelf-0.10.x86_64_linux.bottle.tar.gz
Error: patchelf must be installed: brew install patchelf
Warning: Bottle installation failed: building from source.
Error: The following formula
patchelf cannot be installed as binary package and must be built from source.
Install Clang or run `brew install gcc`.

エラー内容を見ると、

「Error: patchelf must be installed: brew install patchelf」
「patchelf cannot be installed as binary package and must be built from sourceInstall Clang or run `brew install gcc`..」

ああ、「gccをインストールすればいいのか」ということで、「brew install gcc」を実行。ところが。。

user@host:~/workspace$ brew install gcc
==> Installing dependencies for gcc: patchelf, gmp, mpfr, libmpc, isl@0.18 and zlib
==> Installing gcc dependency: patchelf
==> Downloading https://linuxbrew.bintray.com/bottles/patchelf-0.10.x86_64_linux.bottle.tar.gz
Already downloaded: /home/user/.cache/Homebrew/downloads/405227c46362964d2bc2e9ff6428fe082dff4dbd3a4b0b29453743f71923304b--patchelf-0.10.x86_64_linux.bottle.tar.gz
==> Pouring patchelf-0.10.x86_64_linux.bottle.tar.gz
Error: patchelf must be installed: brew install patchelf
Warning: Bottle installation failed: building from source.
Error: The following formula
patchelf
cannot be installed as binary package and must be built from source.
Install Clang or run `brew install gcc`.

同じエラー。しかも、エラーメッセージ通りやると無限に終わらないw。
brewで駄目ならaptだろ。。。ということで、実行して事なきを得るが、こういうのは困るな。
20年経っても、依存性やらインストールやら、最初に検証する際には、そのへんの手間は殆ど変わっていない気がする。。。
一度検証終わって、パッケージに纏めてしまえば楽にはなっているんだけど。

user@host:~/workspace$ sudo apt install gcc

gccとclangをインストール後に、「brew install aws-sam-cli」を実行すると成功。