まひろ量子のハックログ

プログラミングや機械学習などの知識を記録・共有します

Falconを使い超簡単なAPIを作る 【所要時間たったの3分】

Falconとは

f:id:twx:20180908114858p:plain

Falcon - Bare-metal web API framework for Python

Falcon を使えばRESTful な Web API をサクッと作ることができる。業務で簡単なWeb API を用意する必要があったり、ハッカソンなどの短期間開発で疎結合なアークテクチャを作らなくてはならないときに重宝する。Falcon自体はpythonのモジュールだが、肝心のAPI部分は好きな言語で作っても全然構わない (pythonから呼べるようにしておけば良いというだけの話だ)。

この記事では、例として「文を単語分割する」という機能のWeb APIを作ってみようと思う。所要時間はタイトル通り3分だ。

準備 【1分】

「文を単語分割する」とは何か

たとえば、「今日も1日頑張るぞい」という文があったとき、これを単語にスペースで区切ってみると以下のようになる。

今日  も  1  日  頑張る  ぞい

このように、文を単語ごとに区切ることを単語分割という。このような処理は形態素解析ツールによって実現できる。有名なツールに、mecabというものがある。今回はこれを使う。

mecabのインストール

Ubuntuであれば、以下のようにapt-getでインストールできる。

sudo apt-get install mecab libmecab-dev mecab-ipadic
sudo apt-get install mecab-ipadic-utf8
echo "本日は晴天なり" | mecab # => 形態素解析できるかテストしてみよう

falconなどのpipモジュールの準備

以下のようにpipで必要なモジュールをインストールする。ここでは、falcon, falcon-multipart, gunicornをインストールする。

falcon-multipartは、マルチパート形式のPOSTメソッドでパラメータを受け取ることができるようにするモジュールだ。 gunicornは簡易的なWEBサーバだ。

pip install falcon
pip install falcon-multipart
pip gunicorn

サーバ側のコード【1分】

server.py

import falcon
import json
import subprocess
from falcon_multipart.middleware import MultipartMiddleware

# クロスオリジンを許可すする
class CORSMiddleware:
    def process_request(self, req, resp):
        resp.set_header('Access-Control-Allow-Origin', '*')

# shelコマンドを実行する関数
def do_command(command):
    proc = subprocess.Popen(
        command,
        shell  = True,
        stdin  = subprocess.PIPE,
        stdout = subprocess.PIPE,
        stderr = subprocess.PIPE
    )
    return proc.communicate()

class Mecab:

  def on_post(self, req, res):
    # POSTメソッドを受け付ける
    # sentenseという名前のパラメータを受け取る
    sentence = req.get_param('sentence')

    # 'echo hogehoge| mecab -Owakati'というコマンドをたたく。-Owakatiオプションでmecabをたたけば単語分割ができる。
    stdout, stderr = do_command('echo {} | mecab -Owakati'.format(sentence))

    # データを整形し、クライアントにレスポンスを返す
    resp = {
      'stdout': stdout.decode('utf-8').strip(),
      'stderr': stderr.decode('utf-8').strip()
    }
    res.body = json.dumps(resp)

# ミドルウェアを2つ設定している。前者はCORSを許可するために必要だ。これがないと異なるオリジンからのアクセスが許可されない。
api = falcon.API(middleware=[CORSMiddleware(), MultipartMiddleware()])

# /hogeなど任意のエンドポイントを設定できる。今回は / としている。
api.add_route('/', Mecab())

上のコードをサーバとして起動させよう。サーバ側で以下のコマンドを実行する。

gunicorn server:api

これで、デフォルトではhttp://127.0.0.1:8000でサーバが立ち上がる。

IPを指定したい場合は、以下のようにすれば良い。

gunicorn server:api -b xxx.xxx.xxx.xxx

クライアント側のコード【1分】

client.html

<html>
<body>

<p>単語に分割したい文を入力してください</p>
<input type="text" id="sentence"/>
<button id="send">送信</button>

<p>結果</p>
<span id="result"></span>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script>
$(document).ready(function () {

  $('#send').click(function (event) {
    var fd = new FormData();
    fd.append('sentence', $('#sentence').val());
    $.ajax({
      url: 'http://127.0.0.1:8000',
      type: 'POST',
      dataType: 'json',
      data: fd,
      processData: false,
      contentType: false
    })
    .done(function( res, textStatus, jqXHR ) {
      $('#result').text(res.stdout)
    });
  });
});
</script>

</body>
</html>

実行結果

f:id:twx:20180909013202p:plain

 ↓えいや

f:id:twx:20180909013210p:plain

できた!

以上、falconでAPIを簡単に作る方法をご紹介しました。

この記事を良いと思っていただけた方は下の「★+」ボタンのクリックと、SNSでのシェア、「読者になる」ボタンのクリックをお願いいたします! それではまた!

Kozuko Mahiro's Hacklog ―― Copyright © 2018 Mahiro Kazuko