AWS Lambda で Python3 + Chainer を使う方法
概要
Python3 + Chainer を使った API を AWS の API Gateway + Lambda で動かす方法を紹介します。
ちなみに Deep Chord というウェブアプリのバックエンドで使っています。
以下の2点がポイントです。
動作環境
方法
EC2 上で Chainer をビルド
Amazon Linux 2 の EC2 インスタンスを立ち上げ、以下のコマンドで Chainer をインストールします。インスタンスは t2.micro などの無料のインスタンスで十分です。
# Lambda で動かす Python のバージョンと合わせます sudo yum -y install python37 python37-pip # Chainer のインストール (Numpyなども一緒にインストールされます) pip3.7 install chainer==1.12 --user
生成されたファイルのダウンロード
Chalice のプロジェクトの vendor フォルダに上記でビルドされた Chainer とその依存ライブラリをダウンロードします。
# Chalice のプロジェクトを作成(作成済みの場合は省略) chalice new-project プロジェクト名 # プロジェクト内に vendor フォルダを作成 cd プロジェクト名 mkdir vendor # vendor フォルダ内に EC2 でビルドしたライブラリをダウンロード scp -r -i [秘密鍵のパス] ec2-user@[EC2のIPアドレス]:./.local/lib/python3.7/site-packages/ ./vendor/
app.py の作成
Chalice プロジェクトの requirements.txt
には chainer は書かず、あとは普通に app.py
の中で import chainer
すると、vendor
フォルダ内の chainer を参照してくれます。
参考情報
numpy とかは requirements.txt
に書いておくだけで、例えば Mac 上で開発してても Lambda (というかAmazon Linux) で動くようにいい感じに Chalice がビルドしてデプロイしてくれるらしい。Chainer も最新版なら大丈夫なのかな?
ダウンロードした vendor フォルダを覗いてみたら .so
ファイルは Chainer じゃなくて、 Chainer が依存している protobuf とかの中に入ってた。ローカルでのビルドは依存ライブラリ側の方で失敗しているのかも...
参考URL
免責事項
※ 投稿内容は個人的な見解であり、所属する企業を代表するものではありません。
Django を AWS ECS(FARGATE) + ELB で動かすときの ALLOWED_HOSTS の設定
めちゃくちゃ苦戦したのでメモ。
困ったこと
Django のアプリを ECS(FARGATE) 上で動かすと Invalid HTTP_HOST header: '10.0.X.Y'. You may need to add '10.0.X.Y' to ALLOWED_HOSTS.
みたいなエラーが出て、 ELB のヘルスチェックで落ちる。
だからといって、 ALLOWED_HOSTS = ['*']
みたいにするのはセキュリティ的にも気持ち的にもやりたくない。
解決策
Stack overflow に同じ問題にぶち当たっている人がいた。
通常の ALLOWED_HOSTS
の設定の下に、以下を追加すれば良いみたい。
try: resp = requests.get('http://169.254.170.2/v2/metadata') data = resp.json() container_meta = data['Containers'][0] EC2_PRIVATE_IP = container_meta['Networks'][0]['IPv4Addresses'][0] ALLOWED_HOSTS.append(EC2_PRIVATE_IP) except requests.exceptions.RequestException: pass
これで当該のエラーが出なくなって、タスクが再起動されまくる悪夢から解放されました!
参考URL
Debian Stretch で Bluetooth イヤホンを A2DP で利用する
本記事では、Debian Stretch の PC で Bluetooth イヤホンを A2DP プロファイルで利用する方法を説明します。
動作環境
Debian Stretch で Bluetooth で音楽再生
Debian Stretch をインストールするとデフォルトで Bluetooth のオーディオが利用できるのですが、デフォルトのままではモノラルの低音質(HSP/HFP プロファイル) での再生しかできなかったため、追加の設定を行うことでステレオの高音質(A2DP プロファイル)で再生できるようにしました。
必要なパッケージを追加
以下のコマンドで Bluetooth のオーディオ関連のパッケージを追加します。
sudo apt-get install pulseaudio pulseaudio-module-bluetooth pavucontrol bluez-firmware
そして、Bluetooth とオーディオのサービスを再起動します。
sudo service bluetooth restart sudo killall pulseaudio
Bluetooth のペアリング
All Settings > Bluetooth からイヤホンとペアリングします。
オーディオの設定
All Settings > Sound Settings > Output で先程ペアリングしたイヤホンを選択すると、Profile として A2DP もしくは High Fidelity Playback (A2DP Sink) が選択できるので、こちらを選択することでステレオ再生ができるようになりました。
関連URL
Gorm で PostgreSQL の JSONB 型の key, value で絞り込む
この記事では、Golang の ORM である Gorm を使って、 PostgreSQL の JSONB 型の中身の key や value による絞り込みをかける方法を紹介しています。
動作環境
- Go 1.10
- PostgreSQL 9.6
Gorm で PostgreSQL の JSONB を絞り込む
モデル
例えば、以下のような、JSON 型の任意のタグを持てるデータ型について考えます。
type TaggedData struct { ID uint32 `gorm:"NOT NULL;primary_key" sql:"TYPE:serial"` Name string `json:"name" gorm:"NOT NULL"` Tags postgres.Jsonb `json:"tags"` }
ここに、3件のデータを登録します。
host := "localhost" user := "postgres" password := "" db := "tagged" client, err := gorm.Open("postgres", fmt.Sprintf( "host=%s user=%s password=%s dbname=%s sslmode=disable", host, user, password, db, )) if err != nil { fmt.Printf("%v\n", err) return } // テーブルを作成 client.AutoMigrate(&TaggedData{}) // データを登録 client.Create(&TaggedData{Name: "data1", Tags: postgres.Jsonb{[]byte(`{"key1": "val1"}`)}}) client.Create(&TaggedData{Name: "data2", Tags: postgres.Jsonb{[]byte(`{"key1": "val1", "key2": "val2"}`)}}) client.Create(&TaggedData{Name: "data3", Tags: postgres.Jsonb{[]byte(`{"key1": "val3", "key2": "val2", "key3": {"key4": "val4"}}`)}})
JSONB の値で検索
例えば Tags
が "key1" == "val1"
のデータを検索してみます。
data := []TaggedData{} // JSONB の値で検索 res := client.Where("tags ->> 'key1' = ?", "val1").Find(&data) if res.Error != nil { fmt.Printf("%v\n", res.Error) return } // 結果を表示 for _, d := range data { fmt.Println(d.Name) }
結果は以下のようになります。
data1 data2
続いて、 "key2" == "val2"
のデータを検索してみます。
res := client.Where("tags ->> 'key2' = ?", "val2").Find(&data)
結果は以下の通りで、data1 の Tags
は "key2"
というフィールドを持っていませんが、エラーにはなりません。
data2 data3
入れ子になっているフィールドを検索することもできます。
// 入れ子のフィールドを検索 res := client.Where("tags #>> '{key3, key4}' = ?", "val4").Find(&data)
こちらも想定通り動きました。結果は以下。
data3
プログラム全体
package main import ( "fmt" "github.com/jinzhu/gorm" "github.com/jinzhu/gorm/dialects/postgres" ) type TaggedData struct { ID uint32 `gorm:"NOT NULL;primary_key" sql:"TYPE:serial"` Name string `json:"name" gorm:"NOT NULL"` Tags postgres.Jsonb `json:"tags"` } func main() { host := "localhost" user := "postgres" password := "" db := "tagged" client, err := gorm.Open("postgres", fmt.Sprintf( "host=%s user=%s password=%s dbname=%s sslmode=disable", host, user, password, db, )) if err != nil { fmt.Printf("%v\n", err) return } client.AutoMigrate(&TaggedData{}) client.Create(&TaggedData{Name: "data1", Tags: postgres.Jsonb{[]byte(`{"key1": "val1"}`)}}) client.Create(&TaggedData{Name: "data2", Tags: postgres.Jsonb{[]byte(`{"key1": "val1", "key2": "val2"}`)}}) client.Create(&TaggedData{Name: "data3", Tags: postgres.Jsonb{[]byte(`{"key1": "val3", "key2": "val2", "key3": {"key4": "val4"}}`)}}) data := []TaggedData{} res := client.Where("tags ->> 'key1' = ?", "val1").Find(&data) if res.Error != nil { fmt.Printf("%v\n", res.Error) return } for _, d := range data { fmt.Println(d.Name) } data = []TaggedData{} res = client.Where("tags ->> 'key2' = ?", "val2").Find(&data) if res.Error != nil { fmt.Printf("%v\n", res.Error) return } for _, d := range data { fmt.Println(d.Name) } res = client.Where("tags #>> '{key3, key4}' = ?", "val4").Find(&data) if res.Error != nil { fmt.Printf("%v\n", res.Error) return } for _, d := range data { fmt.Println(d.Name) } if err := client.DropTable(&TaggedData{}); err != nil { fmt.Printf("%v\n", err) return } }
参考URL
Debian Stretch に protobuf 3.6 をインストール
本記事では Debian 9 Stretch に protobuf 3.6 をインストールする方法を紹介しています。
C++ で gRPC/protobuf を利用するためには、ソースからコンパイルする必要があります。 deb パッケージ提供してほしい。。。
環境
- Debian 9 Stretch
- protobuf v3.6.0
インストール手順
protobuf/README.md at master · google/protobuf · GitHub を参考にインストールします。
依存パッケージのインストール
$ sudo apt-get install autoconf automake libtool curl make g++ unzip
protobuf のリポジトリをクローン
$ git clone https://github.com/google/protobuf.git
$ cd protobuf
$ git checkout v3.6.0
サブモジュールの更新
$ git submodule update --init --recursive $ ./autogen.sh
コンパイル&インストール
$ ./configure $ make # 10分〜20分くらいかかります $ make check # 5分〜10分くらいかかります $ sudo make install $ sudo ldconfig
これで protoc コマンド等が利用できるようになります!