2017/05/20

PythonとBottleでJSONPを実装する練習

どうも。
Twitterでもちょいちょいつぶやいていますが、最近はPythonの軽量WebフレームワークであるBottleを触って遊んでいます。今回はJSONPを実装する練習をしてみました。

目次


  • 速い
  • シンプル(機能は少なめだが学習コストが低い)
  • Pythonの標準ライブラリ以外には依存関係が無い
  • 1ファイルのみで出来ている軽量フレームワーク

公式のサイトは英語ですが、ほどよく例が載っているので英語が苦手でもすぐにHello Worldできそうです。


とりあえず、公式サイトへのリンクを貼っておきます。




あまりに手軽なのでオンラインIDEのCoding Ground上で実装例のサンプルコードを書いてみます。(誤りがあったら指摘をお願いします。)



Coding Groundは若干動作がもっさりしていますが、無料で使えるオンラインIDEなので我慢しましょう。ガチで開発をやるならCloud9がお勧めです。Cloud9も無料で使うことができますが、アカウント登録が必要になります。


公式サイトにも載っていますがコマンドでやっちゃいましょう。


$ wget http://bottlepy.org/bottle.py

これでrootディレクトリの中に bottle.py ファイルがダウンロードされます。

左側にあるペインの更新ボタンを押すと bottle.py があるのが確認できます。

bottle.pyのダウンロードとペインの更新
$ python -V
Python 3.4.3

私が試したときは3.4.3でした。



まず、試しにHello, World!してみましょう。main.pyファイルを以下のように書き換えます。


# coding: utf-8
from bottle import route, run
 
@route('/')
def index():
    return "Hello, World!\n"
 
run(host='localhost', port=8080, debug=True)

画面下部のターミナルでは以下のように実行してみます。するとBottleでのサービスが開始されます。(Ctrl+Cでサービスが止まります)


$ python main.py
Bottle v0.13-dev server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.

main.pyの実行

なお、main.py を保存したらサービスを開始しなおして下さい。runのオプションにはreloader=True(保存したらサービスをリロードする)がありますが、Coding Groundでは勝手に保存してしまい、コーディングをミスっている時には大変なことになるのでここではあえて付けてません。


さて、ここまで出来たらサービスを開始した状態のまま、+ボタンを押してもうひとつターミナルを起動します。そこでhttpリクエストを投げるためcurlコマンドを叩いてみます。


$ curl http://localhost:8080/
Hello, World!

hello,world!

「Hello, World!」の文字列が返ってきたら成功です。



少し長くなりますが、先ほどの main.py を書き換えます。(APIで返すデータはてきとーです)


ただCoding Groundでは数分程度放置しているとコネクションが切れることがあります(サーバのリソースも限りあるし、無料だし仕方ないですね)。そのときは以下のようなメッセージが表示されます。


Disconnected! Trying to reconnect with the server...
Disconnected! Trying to reconnect with the server...

コネクションが切れた場合は、一旦保存ボタンを押してから「Project」メニューの「Refresh Project」を選択すると再度作業に取り掛かかることができます。


refresh project
# coding: utf-8
from bottle import route, run, request, response
import json
from collections import OrderedDict
 
@route('/')
def index():
    return "Hello, World!\n"
 
def jsonp(request, data):
    if (request.query.callback):
        return "%s(%s)" % (request.query.callback, json.dumps(data))
    return data
 
@route('/api')
def api():
    data = OrderedDict([
        ('title', "備忘録的な"),
        ('url', "http://errormaker.blog74.fc2.com/"),
    ])
    if (request.query.callback):
        response.content_type = "application/javascript; charset=utf-8"
    return jsonp(request, data)
 
run(host='localhost', port=8080, debug=True)

サービスを開始しなおして徐ろに`curl`コマンドを叩いてみましょう。

結果は下記のような感じになるはずです。(改行の出力がないのでプロンプトが末尾に出てしまいます)


sh-4.3$ curl http://localhost:8080/api
{"title": "\u5099\u5fd8\u9332\u7684\u306a", "url": "http://errormaker.blog74.fc2.com/"}sh-4.3$
sh-4.3$ curl http://localhost:8080/api?callback=JSON_CALLBACK
JSON_CALLBACK({"title": "\u5099\u5fd8\u9332\u7684\u306a", "url": "http://errormaker.blog74.fc2.com/"})sh-4.3$

jsonp

ついでに、JSONPではないようですが、マストドンちほーのAPIも叩いてみて比較してみるのも良いかもしれません。


$ curl https://mstdn.jp/api/v1/search?q=python


下記のサイトを参考にしたよ





[広告]

Amazon

関連記事

スポンサーリンク

スポンサーリンク

スポンサーリンク

コメント

非公開コメント