dayjournal memo

Total 975 articles!!

Try #019 – さくらのレンタルサーバでFlaskを利用した住所検索APIを構築してみた

Yasunori Kirimoto's avatar


画像



画像



画像




画像




この記事は、「Python Advent Calendar 2018」の15日目の記事です。




さくらのレンタルサーバでFlaskを利用した住所検索APIを構築してみました!




今回は、「Serverless Advent Calendar 2018」の2日目の記事で書いた「ZappaでDBもパッケージしたサーバーレスAPIを構築してみた」のAPIを、さくらのレンタルサーバ(スタンダードプラン)で構築してみようと思います。



まずは、普段Macで利用しているような仮想環境を、さくらのレンタルサーバで構築してみます。




「ssh」でさくらのレンタルサーバに接続します。



ssh ユーザーアカウント@ユーザーアカウント.sakura.ne.jp



画像



シェルが、デフォルトで「csh」になっているので「bash」に変えます。



chsh -s /usr/local/bin/bash



画像



再接続してみます。環境がうまく動作しない場合は、再接続するとうまくきます。

画像



Pythonのデフォルトバージョンを確認します。2系になっているので、3系をインストールします。



python -V



画像



単純にPythonの3系をインストールすると、バージョンの切り替えができないので「pyenv」をインストールします。



git clone git://github.com/yyuu/pyenv.git ~/.pyenv



画像



インストールが完了したら、パスを通します。



echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init -)"' >> ~/.bash_profile



画像



TMPのパスも通します。パスを全て通したら、「cat」で「.bash_profile」の内容を確認します。



echo 'export TMPDIR="$HOME/tmp"' >> ~/.bash_profile
cat .bash_profile



画像



「pyenv」がインストールされているかを確認します。



pyenv -v



画像



「pyenv」だけだとPythonのバージョン切り替えしかできないので、今後のことも考えてバージョンごとの仮想環境を構築するために「virtualenv」もインストールします。



git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv



画像



今回は、「pyenv」にPython 3.6.4をインストールします。OpenSSLの参照先が古いエラーが出る場合があるので「CPPFLAGS」と「LDFLAGS」も指定します。



CPPFLAGS="-I/usr/local/ssl/include" LDFLAGS="-L/usr/local/ssl/lib" pyenv install 3.6.4



画像



「pyenv」にPython 3.6.4がインストールされたら、次に「flask_peewee_3.6.4」という仮想環境を構築します。

構築できたら仮想環境の切り替えと、切り替えできたかを確認します。



pyenv virtualenv 3.6.4 flask_peewee_3.6.4
pyenv global flask_peewee_3.6.4
pyenv version



画像



「pip」を最新に更新します。



pip install --upgrade pip



画像



ここまでで、さくらのレンタルサーバでのPython環境の構築が完了です。




次に、APIを構築していきます。



Flaskをインストールします。



pip install Flask



画像



peeweeをインストールします。



pip install peewee



画像



パッケージがインストールされたかを確認します。



pip list



画像



アプリ構築用に準備するファイル一覧

db.sqlite: 住所検索用のSQLiteファイル
app.py: Flask、peewee等を盛り込んだPythonファイル
index.cgi: CGIを動かす設定ファイル
.htaccess: サーバーの設定ファイル


さくらのレンタルサーバでPythonを動かす場合はCGIを利用します。


index.cgi


#!/home/day-journal/.pyenv/versions/flask_peewee_3.6.4/bin/python

import cgitb
cgitb.enable()

from wsgiref.handlers import CGIHandler
from app import app
CGIHandler().run(app)


app.py


#!/home/day-journal/.pyenv/versions/flask_peewee_3.6.4/bin/python
# -*- coding: utf-8 -*-

#モジュールインポート
from flask import Flask, jsonify, abort, make_response, request
from peewee import *

#SQLite読み込み
database = SqliteDatabase("db.sqlite")

#ベースModel作成
class BaseModel(Model):
    class Meta:
        database = database

#UserテーブルのModel作成
class address(BaseModel):
    id = TextField()
    code = TextField()
    prefectures = TextField()
    city = TextField()
    ward = TextField()
    address = TextField()
    number01 = TextField()
    number02 = TextField()
    url01 = TextField()
    url02 = TextField()
    lon = TextField()
    lat = TextField()
    level = TextField()
    address_all = TextField()

#flaskのインスタンス作成
app = Flask(__name__)

#日本語表示対応
app.config['JSON_AS_ASCII'] = False

#JSON取得処理
@app.route('/', methods=['GET'])
def get_m():
    #URLのKeyとDBのKeyを比較
    try:
        #クエリパラメータを取得
        m_address = request.args.get('address_all')
        if m_address is not None:
            #like演算子追加
            m_address_all =  str("*" + m_address +"*")
            #検索結果を取得
            query = address.select().where(address.address_all % m_address_all)
            #変数初期化
            result = {}
            count = 0
            #検索結果でJSON作成
            for m in query:
                count = count + 1
                result[str(count)] = {
                    "data":{
                        "lon":m.lon,
                        "lat":m.lat,
                        "level":m.level,
                        "address_all":m.address_all
                        },
                    "result":True
                    }
                #結果は100件まで
                if count == 100:
                    break
            #最後にカウントをJSONに追加
            result["count"] = count
        else:
            #エラーJSON作成
            result = {
                "error": "クエリ文字列を設定してください。",
                "result":False
                }
        #JSONを出力
        return make_response(jsonify(result))
    except address.DoesNotExist:
        abort(404)

#エラー処理
@app.errorhandler(404)
def not_found(error):
    #エラーJSON作成
    result = {
        "error": "存在しません。",
        "result":False
        }
    #エラーJSONを出力
    return make_response(jsonify(result), 404)

#app実行
if __name__ == '__main__':
    app.run()


.htaccess


RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /address/index.cgi/$1 [QSA,L]
<Files ~ "\.py$">
  deny from all
</Files>


構築したファイル一式を、さくらのレンタルサーバにアップロードします。



画像



最後に、実際に検索してみます。



https://api.day-journal.com/address/?address_all=北海道札幌市中央区



画像




さくらのレンタルサーバで、Flaskを利用した住所検索APIを構築できることを確認できました!



通常のレンタルサーバでは、VM等の仮想マシンに比べて安価な分、自由度が少ないためシェルが使えなかったり、ライブラリのインストールができなかったりします。

今回の検証で環境構築が可能だったのを確認できたため、より幅広い利用方法を考えられそうですね!




※「このアプリケーションの作成に当たっては、国土地理院長の承認を得て、同院発行の電子国土基本図(地名情報)住居表示住所を使用した。(承認番号 平30情使、第928号)」



book

Q&A