8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Python bottleでWeb API サーバーを立てる時の基本的な書き方

Last updated at Posted at 2019-08-23

はじめに

PythonのWebフレームワークといえばDjangoやFlask等が有名だと思いますが、Pythonで手軽にサクッとAPIサーバーを立ててみたいという時には、bottleはかなり有効な選択肢になります。本記事では、PythonのWebフレームワークの一つであるbottleを用いてAPIサーバーを立てる時の基本的な書き方について説明します。

実行環境

macOS Mojave 10.14.6
Python 3.7.3
bottle 0.12.17

インストール

Python の仮想環境まではできているとします。
bootle のインストールは普通に

pip install bottle

でできます。

Hello world

from bottle import get, run

@get("/hello")
def hello():
    return "Hello, world."

if __name__ == '__main__':
    run(host="localhost", port=8080)

これを実行し、ブラウザから http://localhost:8080/hello にアクセスすると画面上に Hello, world. の文字が表示されます。

ルーティング

このソースコードでは、@get デコレータで /hello へのGETリクエストに対する処理を指定しています。その他のHTTPメソッドについては、@post@put@deleteデコレータを用いることでそれぞれPOSTメソッド、PUTメソッド、DELETEメソッドに対する処理を指定することができます。

また、以下のように動的なルーティングを指定することもできます。

@get("/hello/<name>")
def hello(name):
    return f"Hello, {name}."

この例だと、http://localhost/hello/takeshi にアクセスすると画面に Hello, takeshi. と表示されます。パスパラメータを関数の引数として受け取れるわけです。

リクエストの情報を受け取る

bottle.request を用いると、リクエストに関する各種情報を扱えます。

from bottle import get, request

@get("/hello")
def hello():
    limit = request.params.get("limit")
    body = request.json
    header = request.get_header("Content-Type")

request.params はクエリパラメータの一覧を返します。
返り値の型は bottle.FormDict で、dict 型とほとんど同じように使えます。
dict にしたければ dict(requset.params) とすることもできます。

request.json はリクエストヘッダに Content-Type: application/json が指定されているとき、リクエストボディを dict で返します。
Content-Typeapplication/json でないときは None が返ります。
Content-Type にかかわらず request.body でリクエストボディを取得することができますが、request.jsondict 型を返してくれて扱いやすいので、 リクエストボディは json で受け取るようにするのが良いと思います。

request.get_header(name) はリクエストヘッダを取得します。
request.headers ですべてのリクエストヘッダに一気にアクセスすることもできます。

HTTPレスポンスを返す

ここまでの例では関数は文字列を返していましたが、APIサーバーでは bottle.HTTPResponse クラスのオブジェクトを返すほうが良いです。

from bottle import get, HTTPResponse

@get("/hello")
def hello():
    header = {"Content-Type": "application/json"}
    body = {"message": "OK"}
    res = HTTPResponse(status=200, body=body, headers=header)
    return res

HTTPResponse オブジェクトはステータスコードとレスポンスボディとレスポンスヘッダを渡して生成します。
レスポンスボディとレスポンスヘッダは後でつけることもできます。
ステータスコードは省略するとデフォルトのステータスコードが付与され、多くの場合 200 となるようです。

res = HTTPResponse()
res.body = {"message": "OK"}
res.set_header("Content-Type", "application/json")
# 上記と同じ res ができる

おまけ:Herokuにデプロイする時は

Herokuではポートを動的に用意するらしいので、ポートの設定は環境変数を使って行います。具体的には、os モジュールをインポートして run 関数を以下のように書き換えるだけです。

run(host="0.0.0.0", port=int(os.environ.get("PORT", 5000)))

おわりに

以上、bottleを使ってAPIサーバーを立てる時のよく使われると思われる書き方を一通りまとめてみました。
また他に何かあれば追記します。

参考リンク

Bottle: Python Web Framework(公式)
BottleのRequest/Responseオブジェクトをマスター
Bottleを使って書いたWebアプリをHerokuに置くときにrun()を書き換えるのはなんで?

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?