Flask-RESTfulのサンプルがあんまりなかったので、作成しました。
まだまだ拙いですが、まとめます。
環境構築
vagrantでCentOS7を構築。その上で、nginxとPython3.6とMySQLを入れます。
vagrantについては割愛します。
MySQLについても、どうやったか忘れてしまいました。。。
MariaDBではなくMySQLにしたのでググって入れたと思います。今回はどちらでも構わないので、お好きな方を用意してください。
nginxのインストール
これは特に何も考えず、yumで入れました。
yum install nginx
Python3.6のインストール
こちらのサイトを参考にしました。
ありがとうございます。
まずはリポジトリを追加します。
yum install -y https://centos7.iuscommunity.org/ius-release.rpm
その後インストールします。
yum install python36u python36u-libs python36u-devel python36u-pip
※執筆時点では、Python3.6.2が入りました。
これで、以下のコマンドが使えるようになります。
* python3.6
* pip3.6
※普通にpythonとやると、CentOS7に初めから入っているPython2系が動いてしまいますので注意してください。
Pythonモジュールのインストール
以下コマンドで入れました。
pip3.6 install flask
pip3.6 install flask-restful
pip3.6 install pymysql
pip3.6 install sqlalchemy
pip3.6 install uwsgi
なんとなくまとめてではなく分けましたが、特に意味はありません。
上記を実行後、pip3.6 freeze
で確認すると、以下のような感じでした。
※他にも入れた状態から抜粋しているので、必ずしも同じではないかもしれません。
aniso8601==1.2.1
click==6.7
Flask==0.12.2
Flask-RESTful==0.3.6
itsdangerous==0.24
Jinja2==2.9.6
MarkupSafe==1.0
mccabe==0.2.1
pbr==3.1.1
pyflakes==0.8.1
PyMySQL==0.7.11
python-dateutil==2.6.1
pytz==2017.2
six==1.10.0
SQLAlchemy==1.1.13
uWSGI==2.0.15
Werkzeug==0.12.2
MySQLの設定
my.cnfに以下を追加しておきます。場所は/etc/my.cnf
か/etc/my.cnf.d/
配下にあると思います。
[mysqld]
# ~中略~
character-set-server=utf8 # ここを追加
[client] # ここを追加
default-character-set=utf8 # ここを追加
また、アプリケーションから接続するためのデータベースとユーザーを作っておきます。
mysqlにrootでログイン後、以下のSQLを実行します。
create database test; -- testデータベースの作成
grant all privileges on test.* to admin@localhost identified by 'Adm!n2017' with grant option;
/* localからtestデータベースへ接続して何でもできるadminユーザーを
Adm!n2017というパスワードでログインできるようにして作成します*/
パスワードはMySQLのルールが厳しくて適当に作ったものなので、まあ参考までに。
権限は、正直そんなに理解してないのですがおそらくこんな感じだったと思います。
nginxの設定
nginxに関しては、/etc/nginx/nginx.conf
にちょっと付け足すだけです。
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
include uwsgi_params; # ここを追加
uwsgi_pass unix:/usr/lib64/nginx/tmp/uwsgi.sock; # ここを追加
だいぶ端折りましたが、locationのところに2行追加しただけですね。
uwsgi-passに関しては、お好みで変えてください。自分は/tmpの下とかにしたらnginxがアクセスできなかったのでここになりました。
uwsgiとnginxがやり取りするためのソケットの指定なので、やり取りできればどこでもいいと思います。
IPアドレスについて
vagrantで仮想環境を作成したら、Virtualbox上で設定をいじれると思います。
確認しやすくするため、ネットワークアダプターを「ブリッジアダプター」に変更し、ホストと同じセグメントにします。
これは他の手段をお持ちなら行わなくても構いません。
コーディング
ここでようやくコーディングですが、説明といっても難しいので、ソースをGitHubで公開していますのでそちらからダウンロードしてみてください。。。
ソース配置場所
コーディングについて、ちょっと注意点がありました。
uwsgiを動かす時に使うuwsgi.iniというファイルがありますが、その中で
chdir = /var/www/uwsgi-restful
と指定していますので、ソース配置場所はこの場合/var/www/uwsgi-restful
になります。
ここは環境に合わせて変更してください。
動作確認
動かし方の正しい方法がよく理解できていないのですが、実際に動いている方法を書きます。
まずは、nginxを起動しましょう。
systemctl start nginx
次に、uwsgiを動かします。
cd /var/www/uwsgi-restful
uwsgi --ini uwsgi.ini
GitHubで公開しているソースありきになってしまい恐縮ですが、これで動き出します。
ちなみに、この時にMySQLに用意したtestデータベースに、model.pyで定義したusersテーブルがなければ作成されます。
動いている間はターミナルが使えないので、もう一つターミナルを用意しましょう。
GitHubで公開しているソースのtestsディレクトリにあるsample.pyを見てみてください。
"""とりあえずテスト用."""
import json
import requests
def get():
"""GETメソッドで問い合わせる."""
headers = {'Content-Type': 'application/json; utf-8'}
# URLは環境に合わせて変更してください
result = requests.get('http://192.168.0.204/hello', headers=headers)
print(result.status_code)
print(result.headers['Content-Type'])
print(result.content)
print(result.json())
def post():
"""POSTメソッドで問い合わせる."""
data = {'user_name': 'テスト', 'password': 'test', 'active': 1}
headers = {'Content-Type': 'application/json; utf-8'}
# URLは環境に合わせて変更してください
result = requests.post('http://192.168.0.204/hello',
data=json.dumps(data), headers=headers)
print(result.status_code)
print(result.headers['Content-Type'])
print(result.content)
print(result.json())
if __name__ == '__main__':
get()
post()
ユニットテストではなくひとまずの動作確認なのでやっつけですが。。。
URLやパラメーターなんかは適当にいじってもらって、適当にsample.pyを実行してもらうと、Flask-RESTfulからの応答が確認できると思います。
MySQLでレコードを見ると、データが挿入されています。
mysql> select * from users;
+---------+------------+----------+--------+-------------+-------------+-------------+
| user_id | user_name | password | active | create_date | update_date | delete_date |
+---------+------------+----------+--------+-------------+-------------+-------------+
| 1 | テスト | test | 1 | NULL | NULL | NULL |
+---------+------------+----------+--------+-------------+-------------+-------------+
6 rows in set (0.00 sec)
終わりに
本当はDockerコンテナ上で色々構築したかったのですが、そこまでは手付かずです・・・
本稿を執筆中にも間違いを直してGitHubにコミットしたりしてました・・・
なお、GitHub上のWikiにも似たようなことを書いてありますが、こちらではより詳細に記載しておきました。