人工知能企業のエンジニアの開発記録

人工知能企業のエンジニアの模索の記録です。pythonを基とした開発や、スキルアップのためのライフハックおよびそれらへの挑戦を書き連ねます。

自分が使っているPython開発環境を晒す(2.Web開発編)

前回の続きです。 今回は予告通り、pythonのWeb開発で使っているものの説明です。 pythonでもweb開発のライブラリ・フレームワークが豊富でユーザー数も多いです。 python機械学習ライブラリが増えてきた結果、webアプリと機械学習は親和性が高いものとなりました(多分)。 機械学習を使ったwebサービス作りたい方に参考なれば幸いです。

今回は特に用語やコード設計について盛り込んでおり、初心者向けではないのでご了承ください。 特にわからないところは、見出しの単語をぐぐって初心者向けの記事を読んだ方がいいかと(小声)

目次

Django

pythonでは一番有名なウェブアプリケーションフレームワークでしょうかね。

主な特徴としては

  • サーバーアプリの基本であるMVCを使って開発できる
  • MVCに従ったアプリの基本構造を自動生成する
  • DBのテーブル管理をdjango側がやってくれる
  • Ruby on Railsと比べるとルールに従う必要が少ない分、コード量が増えたり技量が必要となる

といった、Railsほどではなくても優しく、大規模Webアプリ向けとなっています。

djangoをpipでインストールすると扱えるCLIでプロジェクトディレクトリを作成できます。 また、作成したプロジェクトディレクトリ直下にあるmanage.pyというスクリプトでWebアプリの開発・管理ができます。 公式チュートリアルを見ればわかりますが、 モデル用、ビュー用、ルーティング用のpythonファイルが作られ、サーバーアプリ開発入門者にも雰囲気が掴めるようになっています。

...とは言っても、

  • 実質、テンプレートがビュー、view.pyがコントローラになっていて、名前がややこしい
  • モデル(model.py)やコントローラ(view.py)を単一ファイルになっている

といったRailsよりも汚くなったり、実装をするのが難し買ったりします。

反面Railsとは異なり処理が隠蔽されていないので、import文で簡単にオレオレ構造が作れます。 上記を対処すると

  • model.pyをモデルごとにコードを分割して、modelディレクトリにまとめる
  • view.pyの名前をcontroller.pyにする

ぐらいでしょうか。また、書き方のコツとして、

  • コントローラはモデルのデータを(加工して)ビューに渡すだけ
  • モデルを太らせる(モデルを重点に機能を実装する)

といったところでしょうか。 今はReduxクリーンアーキテクチャ の登場によって、サーバー側は自然と上記の書き方をせざるえなくなりましたが、 登場前はMVCの考え方(捉え方を間違っていないか) の議論がされていました。今の時代でも、MVCについて正しい理解をし、コントローラの役割を意識してモデルを太らせることを意識すれば、自然と構造的かつ綺麗にかけます。

Django REST framework

DjangoAPIを書く場合に重宝します。以下の記事を読むと雰囲気が掴めると思います。

上記の記事では

  • SerializerでモデルのJSON出力の仕方を定義
  • ViewSetでモデルに対するクエリ処理と、定義したSerializerに準じたAPI出力

を解説していますね。特に、モデルの読み書きをJSON形式のREST APIにするだけならこれだけで簡単かつ綺麗に組めます。

リクエスト・レスポンスの定義やコントローラの処理を細かく描きたい場合にも、APIViewResponseといったAPIも提供されています。 英語ですが、公式チュートリアルをざっと読むだけでもしたい処理が簡単にできるようになるのではないでしょうか。 最近は、ビューの処理をフロントエンドで完結できるようになり、 自分もフロントエンドのルーティング以外はこれを使ったAPIしか書いていません。 Djangoを使う際はこれと合わせて使っています。

また、Django REST framework JWT という REST API にJWT認証機能をつけることができるライブラリもあります。 リリースするときを考えて、一緒に使いたいですね。

Flask

小・中規模のサーバーフレームワークです。自分はプロトタイピングによく使っています。 ほぼ公式のコードですが、以下の数行ですぐにサーバーアプリが作れます。

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

if __name__ == '__main__':
  app.run()

上記app.pyというファイル名で保存すれば、python main.pyコマンドを実行して http://localhost:5000 で起動できます。

上記のようにデコレータにパスやメソッドを指定し、返り値にAPIやhtmlの出力を返してやるだけでサーバーアプリが書けます。 flask標準でテンプレートのレンダリングjsonのアウトプットのラッパー関数がある他、ステータスコードやヘッダを自分で設定できたりもします。 ただし、flaskにはデータベースの操作・管理機能はないので、使いたい場合にはSQLAlchemyなどのライブラリを使いましょう。

また、viewの関数のコードをファイルに分割することができ、flaskでもMVCベースのアプリが書けます。 下記のSQLAlchemyを使えば、多少規模が大きいアプリでも問題なく扱えることができます。

参考:Flaskで大きいアプリケーションを作るときのTips

他にもbottleやtornadoなど他にも小規模webライブラリはありますが、自分はflaskでほぼ不便なくコーディングできて、主にこれを扱っています。 ユーザー数も多い方らしく、追加機能となるライブラリも豊富です。

Flask-RESTful

FlaskでREST APIを書く場合に重宝します。標準でもJSONAPIは書けますが

  • メソッドごとに処理を分けて書ける
  • リクエスト時のパラメータを argparse のように定義ができる
  • レスポンス出力のスキーマを定義できる

といったアプリの保守性に優れたコードを書くことができます。

また、FlaskのBlueprintを使わずともFlask-RESTfulのAPI定義をファイルごとに分割できますが、 Blueprintを使った構築も公式でサポートされています。フロントエンドもFlaskでパス通す場合はBlueprint使った方がいいです。

SQLAlchemy

pythonRDBを扱うときに便利なDBライブラリです。 基本的な機能としては

といったDjangoRDB操作と似たような機能を持っています。前述の通りFlaskのような小規模サーバーライブラリは標準でRDBの操作機能を持っていませんので、 SQLAlchemyなどに頼ることになります。メソッドチェーンの容量でSQLの処理を書き連ねることができ、 最後にデータ呼び出しはallメソッド、データ書き込みはcommitメソッドで実行することができます。

具体的な使い方は他の記事に任せますが、テーブルごとにソースファイルを分けるのが難しいです。 個人的には分けて使いたかったので、以下のstackoverflowに上っていた対処法を参考にテーブルの定義を分割しています。

python - SQLAlchemy classes across files - Stack Overflow

自分はFlaskでデータベースを使いたいときに使っています。

jinja2

DjangoやFlaskで扱われているテンプレートエンジンです。

ただし、上記のようにREST APIを出力するだけのサーバーアプリを書く場合には全く必要ないです。 実際に私もこれに頼ることはほとんどなく、フロントエンドにおいてVue.jsでのプロトタイピングの際に文法が競合してむしろ迷惑になります。

Vue.jsを使う場合はこれを参考にjinja2の文法を変えています。

pipを使わずとも大抵Djangoやflaskについています。

uWSGI

pythonサーバーアプリのデプロイをする際に用います。 早い話、こいつがサーバーアプリの面倒をみる役割を持っています。 こいつを使う際は、uWSGIの設定ファイルを用意して使い(必須ではないが使った方がいい)、 アプリのパスやプロセスIDファイル、ログファイルを設定することになります。 ちなみに私はuWSGIとnginxを組み合わせて使っていますが、最近はサーバーレスな構築できるようになりuWSGIだけで十分なケースも現れました。 EC2にuWSGIとnginxを載せた時は結構大変でしたので、サーバーレスでuWSGIだけを使うのが良いと思います。

API Blueprint

APIの仕様書を書くのに特化したマークアップ言語です。 基本はMarkDown準拠でAPIパスに対し、メソッドごとに仕様の説明やパラメータ、リクエスト・レスポンスのJSONスキーマの定義などをこれで書きます。

共同開発には必須となるでしょう。

また、apiaryというサービスを使えば、ウェブ上でAPI Blueprint準拠のドキュメントが書け、これをベースにAPIのモックが書けます。

社内のアプリ開発に関しては、少人数のスタートアップなので、基本自分だけで開発していました。 そのため、ほとんど使う機会はありませんでしたが、そろそろ共同開発することも増えてきて導入を検討しています。