Persistence

技術メモなど

ブラウザから直接S3にファイルをアップロードする方法

ブラウザからS3にファイルをアップロードする場合、S3のアクセスキーやシークレットキーを隠ぺいするためにブラウザ→サーバ→S3というようにサーバを経由してアップロードする事を考えますが、サーバを経由せずに直接S3にアップロードする方法がありました。

元の情報はこのページです。

devcenter.heroku.com

概要

何が行われているかというと、

  • ブラウザがサーバに対してS3のシグネチャ付きのURLを要求します。
  • サーバはS3に対してSDKシグネチャ付きのURLを要求します。
  • サーバはブラウザにS3から返されたシグネチャ付きのURLを返します。
  • ブラウザはアップロードしたいファイルを受け取ったURLにPUTします。

シグネチャ付きのURLにはアクセスキーが含まれますがシークレットキーは含まれないので、一応安全ではあります(ただあまり見せたくはないですが)。またこの方法をを取ることで、通信は2往復になりますがブラウザからサーバへファイルを送る必要がないので通信量・通信時間は少なくなります。

注意点

1つは情報元のページにもありますが、S3の『CORSの設定』で送信元Origin(ドメイン)からのPUTを許可しておくということです。この設定がない場合、403エラーで"No 'Access-Control-Allow-Origin' header is present on the requested resource."が返されます。

もう1つは、情報元のページに無いのですが、aws-sdkのconfig設定にregionとsignatureVersionの設定が必要でした。この設定がない場合は、403エラーで"SignatureDoesNotMatch"が返されます。一応PRを送ってGitHubのソースにはmergeされています。(と書いた後にもう一度再現させてみようと思ってsignatureVersionの設定を削除してリクエストしたらエラーにならずにできました。謎です。)

問題点

1つはやはり上にも書きましたが、アクセスキーが見えてしまうということです。アクセスキーとシークレットキーがセットでないと何もできないですが、重要なシステムではオススメできません。

もう一つは、ファイルに何か加工(例えば画像をリサイズするなど)したい場合、S3にアップロードした後で行うことになります。システムによってはアップロード後に非同期で加工でも問題ないかもしれませんが、DollFaceDetectorの場合はアップロード後すぐにAPIにファイルのURLを渡すので、先にリサイズなどの加工をする必要がありました。

顔認識APIについて調べました

Doll Face Detectorを開発するにあたり、顔認識&機械学習APIについて調べたことを書いていきます。

APIの選定条件

まず最低限必要な機能として、「静止画から顔を検出する」「登録した顔のデータから近いものを検索する」の2点が必要です。さらに、個人的なサービスなのでお金は掛けたくないので、 無料枠がどれだけあるかも重要なポイントです。あとは、「顔認識の精度」「機能の充実度」なども評価のポイントに成ります。

候補となったAPI

いくつか試したAPIを紹介します。

日本国内のサービス: PUX

pds.polestars.jp

まず日本国内のサービスで探すと、これくらしか見つかりませんでした。無料枠は月5000リクエスト、登録顔数10なので、本当に評価版として使える範囲の数になっています。提供されているAPIの機能自体も最低限という感じです。

項目 評価
無料枠の多さ
機能の充実度
顔認識の精度 ?(詳しく検証していない)

Microsoft機械学習サービス: Project Oxford

Microsoft Project Oxford Home

最近ベータ版が開始されたサービスで、一時話題になったHow Old do I Look?もこのプロジェクトの内の1つであるFaceAPIsのデモサイトです。現在ベータ版なので無料版しかないのですが、無料版は15アクセス/分という制限があります。まあそこまでアクセスはいかないだろうと思って、これを使うつもりで開発を始めたのですが、いざ作り始めると1回の処理で数回リクエストする必要があり、リクエストを減らすために自前のデータベースでAPI側のデータをキャッシュしたりしてるうちに、今度はAPIそのものが不安定になってきて(デモサイトでも同じ症状が出てました)、ベータ版の時点では実用に耐えないなということでやめました。

一応、APIアクセスについてはモジュール化して作っていたので、npmに公開しています。

www.npmjs.com

項目 評価
無料枠の多さ
機能の充実度
顔認識の精度

全部無料のサービス: Face++

www.faceplusplus.com

中国のサービスで全部無料・制限なし(相当なアクセス数になってくると要相談とありますが)って、ちょっと信頼できるのか心配だったんですが、背に腹は変えられぬってことでこれを使いました。

登録すると最初はDeveloperモードとなり顔登録数が100までという制限がありましたが、サービスURLを公開した後でProductionモードにアップグレードするリクエストを送ると、2〜3日でなんの通知もなくProductionモードに変更されていました。

また機能的にもかなり充実していて、データはすべてFace++側で管理することができます。データそのものはAPIで取得できるので、定期的に全件取得しておけば万が一サービスがなくなっても他のサービスに移行することはできるかなと思っています。

モジュールも準備できしだいアップ予定。

項目 評価
無料枠の多さ
機能の充実度
顔認識の精度

その他

他にもたくさんの同種のサービスがありました。APIを探すのにとても役に立つのがMashapeというサイトです。

www.mashape.com

ここに顔認識系の有名どころのサービスがまとめられています。

Popular Face Detection/Recognition APIs from Mashape

これらひと通りデモを試してみましたが、認識できる精度についてはほぼすべて同じでした。唯一ちょっと違ったのがMicrosoftのサービスです。ただ、どちらが優れているというわけではなく、どちらも認識できる画像/できない画像がありました。ちなみにこれはドール画像の話で、人間の顔認識に関してはどちらもかなりの精度で認識されます。

DollFaceDetectorというサービスを作りました。

概要

このサービスは、顔認識&機械学習を使ってドール画像からそのドールの顔の型番を判定するサービスです。学習すればするほど精度が上がる(想定)なので、興味がある方はぜひ使ってみてください。

f:id:bisque3311:20150609011143j:plain

http://doll-face-detector.herokuapp.com/

開発背景

アイディア自体はかなり前からあったものですが、当時はまだ使えるAPIがなく、専門知識もないので自前で作るなんて途方も無いので、アイディア自体を寝かせておきました。最近になってまたAPIを捜してみたらかなりたくさんあって、これならできそうということで開発をはじめました。

あと、技術的に色々と使ってみたいものがあってその練習課題という意味もありました。構成としてはMEANスタック+Heroku(ホスティングのみ)+AWS(S3, dynamodb, lambda)あたりを使っています。次回以降の記事で、色々と得た知識を書いていこうと思います。

AWS Summit2015に行ってきた

6/2-3で行われたAWS Summit 2015と併設イベントのデベロッパーズカンファレンスに行ってきました。

聴講したセッションは次の通り。

Day1

  • Day1 キーノート(基調講演)
  • GitHub, AWS などの分散テクノロジーが実現する、デベロッパー主体のアプリケーションデリバリ
  • 【パネルディスカッション】デベロッパー視点でみた AWS
  • 【パネルディスカッション】デベロッパーが切り拓く、次の時代
  • 2035 年、その時デベロッパーはどう生きるか
  • 【パネルディスカッション】高まるゲームプレイ動画の価値。注目市場の今後の展望とは!?

Day2

以下、印象に残ったことを書いていきます。

Day1

Day1キーノート(基調講演)では、まずはじめにAWSの規模についての数字が紹介されました。世界中でどれだけAWSが使われているか、どのようなスピードで成長しているか、どれだけのサービスがあるか、など。この数字を見せられただけでAWSの凄さに圧倒され、だいぶお腹いっぱいになりましたw

GitHubのCEOスコットさんの話。今後はあらゆる業種の会社が全てソフトウェア会社になるということ。昔はOSSそれぞれに様々なルールがあってOSSに貢献するのは敷居が高かった、それで、Gitを使ったGitHubというフローを作って、ルールを統一することでOSSに貢献しやすくなったということ。GitHub Flowはソフトウェアの世界だけではなく、様々な世界に使える。例としてホワイトハウスGitHub上にドキュメントを公開していて、上院議会からプルリクがきたなんて話。プルリクを使うことで、変更に対する理由が残るので良い。最も重要な事はOSSに参加して貢献すること、それで得た経験は役に立つ。

デベロッパは今後どう生き残るのかというテーマのディスカッションが2つ。

まず今後10年というテーマでスピーカーはnaoyaさん・Crowdworksの大場さん。結論としては、トップデベロッパですら正解はわからないし不安はある。だから逆に安心してってw 必要なことは、今起きていることに全力で取り組むしか無いということと、デベロッパとして自分の相対的なポジションを知っておくこと。もはや開発者は開発だけやればいいという時代ではなく、ビジネスのゴールに向かっていく責任があるということ。

続いて20年後というテーマで大前 研一氏・大前 創希氏による親子トーク。親子ならではの掛け合いが面白かったw 内容としては、今ある仕事の大部分はインド等の安い人材、もしくは、ロボットがやるようになる。生き残りたいのなら、とにかくロボットが出来ない仕事、つまり「発想・構想・コンセプトを生み出すことをやれ」ということ。ちなみにロボットは発想を生み出す仕事をできないのか?という問に対しては、「ロボットも発想はできるが、そこに独自性はなく価値は生まれない」とのこと。ユニークを生み出せるのは人間だけみたいな話でした。なんか哲学的。

Day2

GitHubのコービーさんがGitHub Flowについて解説。超イケメンな上に片言の日本語で挨拶とか、悶絶した人も多いんじゃないでしょうか。内容としては、プルリクをするときは準備が整ってなくてもとにかく早く表に出す事が大事で、そうすることでいろんな人に意見をもらえることに価値があるということ。それからコードの改変に関して、競合などでブロックしないようにすることが開発のスピードを保つ上でとても大事なのでそういう仕組(github/flipperを使っている。)を使うこと。Production Readness ReviewとPostship Health Checkを用いたPDCAは単純な仕組みだけど効果がある。バグを恐れずにデプロイのスピードを上げることで、結果的にバグの修正も早くなり前進し続けることができる。GitHub Flowを上手く運用するためには、ルールをドキュメント化する、自動化に投資する、テストやデプロイの信頼を構築する、早めにディスカッションする、複雑さが発生したら疑問視する、早くやってみること、などをあげていました。

DynamoDBについては、nanapiの秋田さん。KVS的に使う。特徴としては、キーの他にRangeキーを組み合わせて使える。課金はスループット(Read/Writeの量)なので、うまく節約するためのコツが色々。RDB的な使い方をしてしまうとスループット破産するので注意が必要。AWSの「よくある質問」がとても充実していてすごい。

CookPadの開発方式についてはCookPadの成田さんから、開発・テスト・デプロイの3点で紹介。開発については、開発に用いるデータはダミーデータではなく本番データを用いるべきということ。ステージング環境というのはあまり使われていなくて、本番環境で限られたユーザで試行運転をする。そのためのツールとしてChankoがある。テストはテストケースが膨大なのでRSpecを並列実行するRRRSpecっていうのを開発して2日かかったテストが数分になった。デプロイもサーバ数が膨大なのでmamiyaっていうのを開発して100台のEC2に12秒でデプロイできるようになった。これら3点全てで一貫しているのは、『効率の悪い作業を徹底的に効率化すること』がちゃんと行われているということです。もう一つ重要な事は「割れ窓」を放置しないということ。どちらも言われれば当たり前の事なんですが、その当たり前をちゃんとできるのは凄いと思います。

AWSの西谷さん・岩永さんからlambdaとRDSの紹介。lambdaはAWSの他の機能と簡単に連携できて、サーバレスでジョブを実行できるのでとても便利ですね。RDSもDBの厄介な部分を全部AWSがやってくれるので本当に便利だと思います。意外だったのは、SQLServerOracleも従量課金で利用できて、ライセンスは従量課金に含む方式と、既存のオンプレミス環境のライセンスをAWSに引き継ぐこともできるということでした。あとはPoint in Time Recoveryっていって、障害調査などである時点のバックアップをすぐに他のインスタンスで復元して見られるっていうのが便利だなと思いました。

個別のセッションについては以上。

ちなみにAWSからのセッションのスライドは全てアップされるそうです。

全体を通じては、まずAWSに対する認識がすごく変わりました。数年前のAWSっておそらくEC2とS3がメインで、いわゆるインフラサービスねって認識でしたが、今のAWSはインフラレイヤーだけでなくアプリケーションレイヤにも様々なサービスがあるので、ほとんどのサービスがAWSの中だけで構築できるインフラ・アプリケーションプラットフォームであるという認識になりました。

それから、デベロッパーズカンファレンスも併設されていたということもあり、AWS以外にも色々なセッションがありましたし、ランチブッフェorランチまで付いて参加費無料なのでデベロッパなら行き得しかないですね。また来年も行きたいと思います。

Macの環境構築メモ(ターミナル/シェル)

『エンジニアたるもの使う道具にはこだわりを持て』ということでMacの開発環境を色々といじってみました。こういうのは書いておかないとすぐ忘れてしまうので備忘のためにメモしておきます。

iTerm2

今までターミナルはMacのデフォルトのを使っていました。カラースキームとかも綺麗で特に不満は無かったのですが、定番のiTerm2を使ってみることにしました。

http://iterm2.com/

今のところ使っている機能としてはこのくらいです。

機能 ショートカット
検索する Ctrl+f
ペインを水平分割する Ctrl+d
ペインを垂直分割する Ctrl+Shift+d
ペインを移動する Ctrl+Option+方向キー
ペインを閉じる Ctrl+w
タブを移動する Cltr+Shift+[またはCltr+Shift+]

まだまだ機能はたくさんあるので使っていて不便を感じたら調べるといいですね。ちなみに私は前回入力したコマンドを再入力する際にキーを連打するのですが、押す回数が多いのでもっと簡単に履歴を探せる機能がほしいなと思ったんですが、これはターミナルではなく別の機能で実現できました。

iTerm2のカラースキームはここにたくさん(たくさん!)あるので、好きなモノをダウンロードしてインポートできます。

https://github.com/mbadolato/iTerm2-Color-Schemes

oh-my-zsh

oh-my-zshzshの設定を管理するためのツールです。zshは今までも使っていたのですが、カスタマイズはほとんどしていませんでした。入力補完とかは何もしなくてもついてくるので超便利ですけどね!

https://github.com/robbyrussell/oh-my-zsh

oh-my-zshには「テーマ」と「プラグイン」という2つの便利な機能があります。

テーマ

テーマは見た目の表示をカスタマイズしたテンプレートで、あらかじめたくさん(たくさん!)の種類が備わっていて、設定を変えるだけでそのテーマが使えるようになります。また、テーマはシェルスクリプトで書かれているので、ちょっとしたカスタマイズなら簡単にできます。

https://github.com/robbyrussell/oh-my-zsh/wiki/themes

私は"wedisagree"というテーマを使っているのですが、現在時刻は行ごとに出力しなくてもいいので削除しました。このテーマはカレントディレクトリのgitリポジトリの状態を表示してくれるので、ブランチの切り替え忘れとかを防げて便利ですね。

ZSH_THEME="wedisagree"

プラグイン

プラグインはコマンドのショートカット集のようなものです。

https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins

例えばbundlerというプラグインを入れてbeと打つと、bundle execが実行されます。今まではわざわざaliasを書いて設定していました。プラグインもあらかじめたくさん(たくさん!)備わっていて、設定に書くだけで使えるようになります。なお、各種プラグインの設定は、~/.oh-my-zsh/pluginsの中にある設定ファイルを見ると分かります。

plugins=(git osx brew bundler rails)

autojump

autojumpはディレクトリ移動を高速にするためのツールです。移動したことのあるディレクトリを記録し、次回以降はフルパスを入力しなくても、j [移動したいディレクトリの一部の文字]と入力するだけで移動できます。

インストールはHomebrew経由で入れてしまうのが簡単です。

brew install autojump

あとは、お使いのシェルのrcファイル(私は.zshrc)に以下を追加します。

[[ -s $(brew --prefix)/etc/profile.d/autojump.sh ]] && . $(brew --prefix)/etc/profile.d/autojump.sh

しかし、私の環境ではこのままでは以下のエラーとなりました。

$ j
usage: autojump [-h] [-a DIRECTORY] [-i [WEIGHT]] [-d [WEIGHT]] [--complete]
                [--purge] [-s] [-v]
                [DIRECTORY [DIRECTORY ...]]
autojump: error: unrecognized arguments: -l

jエイリアスが本来ならばjobsになるはずなんですが、なぜかjobs -lとなるためエラーとなります。おそらくoh-my-zshの影響かと思うのですが、なぜこのようなエイリアスになるのかは分かりませんでした。対処として、先ほど追加したautojumpの設定の下に、alias j="jobs"を追記することでエイリアスの上書きができました。

他にzという同様のツールがありますが、こちらは[移動したいディレクトリの一部]が充分でない(候補がたくさんある)時でも、優先順位が一番高いディレクトリへ移動してしまうので、autojumpの方が使い勝手が良さそうです。

percol

percolは"対話的なgrepツール"だそうです。

https://github.com/mooz/percol

これを使って色々と便利なカスタマイズをしているブログ記事が見つかりましたが、今回はコマンド履歴の検索をしてみました。設定方法は以下のサイトで説明されている通りです。

http://blog.zoncoen.net/blog/2014/01/14/percol-autojump-with-zsh/

例えば、20回前に入力した長いコマンドを再度入力したいとき、今まではを20回押してましたが、これを使うとCommand+rインタラクティブモードになった後にコマンドの一部を入力して検索すると絞り込まれていきすぐに見つけることができます。

参考

http://qiita.com/bird_nitryn/items/bd063f0d7eb18287fec1

node.jsの環境構築メモ

Yeomanを使ってみようと思って、Macにインストールされているnode.jsをすごい久しぶりに触ろうとしたらエラーが起きたので、nodebrewを使って再構築したメモ。

node.jsのアンインストール

まずはじめに、Macにインストールされているnode.jsをアップデートし、npmパッケージを入れていこうと思ったら、node.jsをアップデートした後にnpmコマンドが使えなくなってしまいました。node.jsをアップデートする前から使えてたかどうかは不明です。(かなり長い間使っていなかったので。)

$ node -v
v0.8.16

$ n stable

     install : v0.12.2
       mkdir : /usr/local/n/versions/0.12.2
       fetch : http://nodejs.org/dist/v0.12.2/node-v0.12.2-darwin-x64.tar.gz
   installed : v0.12.2

$ node -v
v0.12.2

$ npm
module.js:338
    throw err;
          ^
Error: Cannot find module 'are-we-there-yet'
    at Function.Module._resolveFilename (module.js:336:15)
    at Function.Module._load (module.js:278:25)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Object.<anonymous> (/usr/local/Cellar/node/0.8.16/lib/node_modules/npm/node_modules/npmlog/log.js:2:16)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)

npmコマンドを叩くと上記のエラーが起きます。モジュールが足りないと言われるがそもそもnpmコマンドが使えないのでモジュールを入れる事ができませんでした。また、npmをアンインストールするにもnpmコマンドを使うので詰んでしまった。。

なので、node.jsから入れなおすことにしました。

ところで今使っているnode.jsはどうやって入れたものか?それがわからないと消し方もわからないのですが、まず一番ありそうなところで、Homebrewを確認してみます。

$ brew list node
...

brew経由でnodeが入っていた事は分かりましたが、フォルダ名が現在使っているバージョンとは違いました。これはアップデートする前のバージョンが表示されるのかもしれませんが、この時のログが流れてしまってもう確認できません。なんにせよもう必要がないのでアンインストールします。

$ brew uninstall node

もう一つの方法として、nodeをインストーラからインストールした場合の削除方法というのもありましたので、念のためこちらもやっておきます。また、あわせてnpmのグローバルでインストールしたパッケージも削除しました。手順は以下のサイトを参照しました。

http://whiskers.nukos.kitchen/2014/09/25/nodebrew.html

これでもまだnodeの実行モジュールが残っていてパスが通るので、手動で実行モジュールを削除しました。(たぶん正しい手順ではないです。)

$ which node
/usr/local/bin/node

$ sudo rm /usr/local/bin/node

nodebrewのインストール

nodebrewはnode.jsやio.jsのバージョン管理ツールです。Rubyでいうrbenvみたいなものですね。他にもnode.jsのためのバージョン管理ツールが色々とありますが、nodebrewが一番環境をクリーンに保てて良いというのを目にしたのでこれにしました。実際、使うのは~/.nodebrewだけで、あとはパスを通すだけです。とってもクリーンですね!

インストール方法もこちらのサイトを参考にしたので、自分が改めて書くまででもないですね。

http://whiskers.nukos.kitchen/2014/09/25/nodebrew.html

基本的なコマンドだけメモしておきます。

  • nodebrew ls-remote
  • nodebrew install-binary [バージョン]
  • nodebrew uninstall [バージョン]
  • nodebrew list
  • nodebrew use [バージョン]

nodebrew install [バージョン]でもインストールできますが、ソースからコンパイルするため非常に時間がかかります。通常はinstall-binaryを使うといいですね。

参考

ちなみに、今から使うんだったらio.jsじゃない?って思ってちょっと調べてみたら、こんな記事が見つかりました。内容は記事を見ればわかるのでここには書きませんが、自分は特に最新機能が必要でない限りはnode.jsを使いつつ様子見しようと思います。

http://yosuke-furukawa.hatenablog.com/entry/2015/03/05/171527

『関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間』を読んだ

関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間』を一読したので感想を書いていきます。

この本の感想を3行でまとめると

パラダイムシフト

本書の前半半分は、命令形プログラミングと関数型プログラミングパラダイムの違いを非常に分かりやすく説明されています。自分が今まで書いていた命令形プログラミングはフローを作成して機能毎に分割して作っていましたが、関数型プログラミングはフローや状態を排除し論理毎に機能を作成し、必要になった時に必要な分だけ計算する(イベント駆動)という方法を取ります。「論理」と「計算」を分けて考えるという説明はわかりやすかったです。

一方の後半半分は、FRP(関数型リアクティブプログラミング)の説明になるのですが、アリストテレスピタゴラスプラトンデカルト、などの哲学思想(これはこれで読み物としては面白かったですが)とFRPを対比させて説明が進んでいくのですが、正直最後の方はついていけなくなりました。まあこの辺は、FRPだけを説明するのはもっと簡単だけど、筆者としてはその根本的な思想を伝えたかったのだと思います。なお、これらの大部分は著者のブログの記事(量子コンピュータ関連のエントリー)にも書いてありますので、興味があれば読んでみるとよろしいかと。

歴史的背景

会話形式で説明が進んでいく中でいくつものプログラミングに関する歴史が説明されており、読み物として面白かったです。例えばJavaScriptの生い立ちの話とか、命令形プログラミングから関数型プログラミングへのパラダイムシフトやの歴史、そして次のパラダイムシフトは何かなど。

本を読む姿勢

本書を買う前から著者のブログ等で著者の関数型プログラミングの説明に対する否定的な意見があることは知っていましたが、元々の意見が交わされていたサイトは削除されてしまい、今は罵り合いみたいな情報しか残っておらず、遅れて知った身としては何が正しいのか分かりません。ですから、果たして「この本を信頼して読んでよいのか?」という不安がありました。

しかしそもそも、正しい本の読み方としては、本を100%信用して読むのではなく、疑問を持ちながら読むことも必要だということを、『本を読む本 (講談社学術文庫)』という本の中でアドラーが言っていたのを思いだしました。本書を通じて関数型プログラミングに興味が湧いたので(この点に関しては間違いなく読んでよかったと言える)、他の関数型プログラミングに関する本や情報も今後調べて身につけていきたいと思います。

全体を通して

本書は科学哲学史の観点から関数型プログラミングの根本に迫るというアプローチを取っています。このへんは好き嫌いが別れるところかと思いますので本を購入される前に立ち読みをするなり著者のブログに目を通してみることをオススメします。しかし事実として、関数型プログラミングパラダイムシフトは既に起きており、オブジェクト指向に変わる次のスタンダードになりうるということは大いに共感できたし、実際に世の中の動向もここ数年で「イベント駆動」という方式を取るプロダクトがどんどん生み出されていますので、自分も今のうちに関数型プログラミングを勉強しておかないとなーと思いました。

次にやること