はじまり
研究室の後輩に対してPython講習会を持ち回りで行っているんですが、自分の出番でAPI通信を勉強したくなりました。
少しだけDockerを作っていることから、DockerでDBとAPIサーバーが作れるようになったら便利かなと思い、トライしてみました。
Docker環境さえあれば、手軽にWebアプリの開発環境としても利用できます。
手に入る環境
わざわざ説明するまでもないかもしれませんが、構成と環境を書きました。
APIアクセスの場合、localhost:5000
にいけば、APIへフォワーディングされ、
DBへの直接接続の場合、localhost:27018
にいけばフォワーディングされます。
またlocalhost:10081
をブラウザ上で開けば、クライアントソフトであるMongo-Expressが立ち上がります。
なんか微妙にポートを変えている理由は、研究室のサーバーで既に使っているポートがあったためです。
あまり他の記事でも、ポート変更をしてなかったので、備忘録としても書いておきます。
フォルダ構成
├── Dockerfile
├── configdb
├── docker-compose.yml
└── src
├── app.py
├── mongo.py
└── requirements.txt
なんか自動的に生成されるフォルダとかは省いています。
DockerFile
はFlaskによるAPIサーバーの内容を記述、composeには、mongoとmongo-expressを書いています。
実際のコード
長々と失礼しました。ここからはコードの共有+説明です。
FROM python:3.6
ARG project_dir=/projects/
ADD src/requirements.txt $project_dir
WORKDIR $project_dir
RUN pip install -r requirements.txt
なんてことないPythonのイメージです。
composeにてVolumeなどを行っていきます。
version: '3.1'
services:
flask:
build: .
ports:
- "5000:5000"
volumes:
- "./src:/projects"
tty: true
environment:
TZ: Asia/Tokyo
api_mongo:
image: mongo:3.6.5
restart: always
ports:
- 27018:27017
volumes:
- /var/lib/mongo_data:/data/db
- ./configdb:/data/configdb
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: password
api_mongo-express:
image: mongo-express
restart: always
links:
- 'api_mongo:mongo'
ports:
- 10081:8081
environment:
ME_CONFIG_MONGODB_AUTH_DATABASE: admin
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: password
ME_CONFIG_BASICAUTH_USERNAME: admin
ME_CONFIG_BASICAUTH_PASSWORD: password
depends_on:
- api_mongo
個人的にミソだと思ったところはmongo-expressの場所の以下の記述です
links:
- 'api_mongo:mongo'
ここでDocker-compose内のMongodbの名前を入れてあげないと、expressが立ち上がりません。
from flask import Flask, jsonify, request
from mongo import get_mongo
app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False
@app.route('/')
def index():
return jsonify({
"message": "API立ち上がってまーす!"})
@app.route('/test')
def mongo_test():
conf = get_mongo()
col = conf['test']['test_col']
data = col.find_one()
return jsonify(data)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
一応、APIが立ち上がっているかだけ確認するlocalhost:5000/
と
APIにアクセスした上でMongoのコレクションを参照するlocalhost:5000/test
を実装しています。
from pymongo import MongoCliant
def get_mongo():
mongo_client = MongoClient('api_mongo', 27017)
mongo_client['admin'].authenticate("root","password")
return mongo_client
こちらはmongoのコネクションを獲得するための関数になります。
これのポイントとしては
mongo_client = MongoClient('api_mongo', 27017)
のapi_mongo
です。ここを自分はlocalhost
にしていたんですが、なかなかつながらなくて苦労しました。
なぜかというと、こちらのPythonファイルが動くflask
コンテナにおいてのlocalhost
という意味合いになってしまうためですね。
ゆえにDocker-compose時に出来上がるDockerNetWorkで名前解決のできる、docker-compose時につけた名前を書く必要があるというわけです。
flask
pymongo
flask と pymongoのpip をインストールします
早速起動
docker-compose up -d
後でflaskのコンテナに入りたいので、-dオプションを追加します。
コンテナが3つ立ち上がり、停止していないことを確認します
docker ps
次に、APIサーバーの起動を実際に行います。
そのためにflask
コンテナに入り、app.py を実行します。
docker-compose exec flask bash
## コンテナ内にて
python3 app.py
こうするとAPIサーバーが立ち上がります。
もしコードにタイポや間違いがあったら、上手く立ち上がらないと思います。
あとは、mongo-expressでも直接DBでもいいので、test
DBに対してtest_col
コレクションを作り、適当に値を入れ、
APIサーバーを実際叩いてみましょう!
curl localhost:5000/
curl localhost:5000/hello
問題なくちゃんと帰ってくれば、開発環境完成です。
終わりに
どこにも所属してないですが、アドベントカレンダー代わりに投稿しました。
今回はlocalで作りましたが、外部に公開したサーバとかと疎通させてみます。