はじめに
こんにちは、UNIBA のMJです。
今回の話は、とある案件で python を使ってお仕事した話です。
python といえば特に説明する必要のない有名な言語の一つです。
普段はフロントエンジニアとして仕事をしているのですが、「最近バックエンドの知識が欲しいなぁ」などと考えていて python を4月頃から触り始めました。
ユニバでは、node である javascript や rails である ruby などの言語を主に仕事で使用していますが、
厨二病である私は、誰もやってなかった python を選択しました(誰にもサポートを受けられず苦悶したので後悔)。
そんな折にちょうど良いタイミングで、バックエンド(最終的にはサーバなどは立てなかったのでバックエンドなのかどうなのかは甚だ疑問であるが、、、)柄みの案件があったので、挑戦してみたという次第です。
ちなみにかなり乱雑に書きます。あしからず
案件
どういった案件だったのか振り返ります。
- とある施設に設置するインスタレーション型のシステム
- 全体としては、写真を撮る -> プリントしてプレゼント -> おまけに web でも見れるよ
- 私の担当範囲と必要だった技術のあれこれ
- 写真を保存した時に、自動で 画像 と
htmlファイル をアップロードする仕組み(フォルダ監視 + テンプレート) - データのアップロード先は s3
- アップロード先のパスを base62 で暗号化する
- その他アプリケーションとしてケアするところ
- アップロード失敗した場合の挙動
- ログの出力
- etc...
- 写真を保存した時に、自動で 画像 と
実装に関して
今回の実装に関して運の良かったところは、サーバサイドの実装が入らなかったことです。
DB とかのあれこれに加えて、インフラの整備などを考えなくて済んだのかなり幸運でした。というかあったらかなり不安でした(社内で python でサーバやってる人いないし!!!)。
では、一つずつ振り返ります。
写真を保存した時に、自動で 画像 と htmlファイル をアップロードする仕組み(フォルダ監視 + テンプレート)
フォルダの監視には watchdog、 html の生成には jinja2 を使用しました。
2つともかなり使い易いライブラリになっています。特段説明する必要がないぐらいよく出来たライブラリです。
メインのスクリプトはこれのおかげでかなり楽ができました。
watchdog の使用に関して言えば、監視するフォルダの中身(ファイルの数や、変更される数など)によっては、テストが必要です。
今回の案件に関しては特に問題なしでした。
データのアップロード先は aws
aws の設定に関しては、普段は社内のバックエンドの人間に設定を任している箇所を自分が担当しました。
ドメインを route53 で取得するあたりで、契約の部分で少し面倒が起きましたのがいい思い出です。
s3 は basic認証 がかけられませんが、 IP での制限はかけれるのでテスト期間はそっちで対応しました。とはいえ SNSシェア 辺りの検証は少し面倒だったので次回は楽できるようにしたい。
python 側のアップロードは boto を使用しました。 amazon が公式に出しているとのことですが、正直リファレンスが読みづらく、通信の timeout の設定がうまくできなかったので少々辛い思いをしました。
加えて、bucket 名に . が入ってたりすると少し特殊な記述をしないといけない。という事実を公開直前で気づき少し冷や汗。ドメインと紐付けると . がつかざる終えないのでこれはライブラリ側で気を回してほしいなぁ、、、
アップロード先のパスを base62 で暗号化する
写真を公開にするにあたり、悪戯にダウンロードされないための予防策ですね。
はじめはの方は自分で実装していたのですが、最終的には basehash というライブラリを使用しました。
少し問題になったのは、他のアプリとの連携部分でした。
システムとして、python 以外に openFrameworks 製のアプリが動いており、そこで web へのリンクとして QR コードを生成していたのですが、C++ 側で生成した値 が python 側と合わない。アルゴリズム的には同じなんですが、それでも合わない。
原因は、hash の値が 大きすぎて C++ では普通には扱えなかったですね。要は big int な問題でした。
python の方は仕様の方でメモリがある分だけうまく計算してくれるとのことでした。大学などの研究分野で python が使われている理由はコレなんだろうなぁと推測。
結局、暗号化部分は C++ から python を叩いて結果を返すようにしました。if __name__ == '__main__': がとても役に立ちます。嬉しい。
その他アプリケーションとしてケアするところ
ここら辺が地味に大変でした。。。
例えば通信が切れていた場合、フレームを生成して「リトライしてください」というような警告を出すわけです。
警告画面はメインスレッドで出さなければいけないのです(知らなくて当初困惑していた素人)が、watchdog から呼び出した アップロードのプロセスは ライブラリの性質上 サブスレッドで動いているので、スレッド間で通信をしなければいけませんでした。
正直、html を普段いじっているおじさんには未知の世界でした。
これを解決してくれたのが、Queue クラスでした。 join と task_done を使って、プロセスのストップとゴーの連携を容易にすることができました。いやー便利。
ログの出力は、logging を使ってやりました。正直、ログローテーション的な部分はもう少し詰めたい。
あと、applescript で、ログイン時に自動起動するようにしたわけですが、その話は今回は省略
感想
python という言語を触ってみて思った事
- インデント記述良い
- if の記述良い
- pip 関連のライブラリ管理は少し慣れない
- モジュールとして分けてったら root フォルダがメタクソになった。ので次回はそこを考えたい。
- os の事を気軽に処理できるのが最高(フォルダ作ったり、ファイルコピーしたり)
- config.ini って結構イカしていると個人的には思った
- 二度と OS でダイアログ出したくない。
- やってる間、
nodeで実装したらと再三言われたが、挫けなかった自分を褒めたい
って具合でしょうか。
また python を使ったお仕事くるといいなぁ