Oracle Cloud Hangout Cafe Season6 #4「Pythonで作るAPIサーバー」(2022年12月7日開催)
Flask
Flaskは、Armin Ronacherによって開発されたオープンソースライセンス(BSDライセンス)のフレームワークです。テンプレートエンジンとしてJinja2、WSGIツールキットとしてWerkzeug(ヴェルクツォイク)を利用しています。
- Jinja2: Pythonで利用できるHTMLテンプレートエンジン
- Werkzeug: WSGIアプリケーションのためのユーティリティを集めたライブラリ
データベースの抽象化など、必要に応じて拡張(Extension)を行う軽量なフレームワークです。
・Flask - Getting Started
実際にFlaskを動かしてみましょう。以下のコマンドを実行して、Flaskをインストールします。
$ python -m pip install Flask次のように
hello.py
ファイルを作成します。
from flask import Flask, Response app = Flask(__name__) @app.route('/hello') def hello(): return 'Hello, World' @app.route('/hello/Flaskのサーバを起動します。') def name(name): response = Response('Hello, '+ name) response.mimetype = 'text/plain' return response
$ export FLASK_APP=hello.py #起動するアプリをFlaskに伝える $ export FLASK_ENV=development #サーバーを開発モードに設定 $ flask run * Serving Flask app 'hello' (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
http://127.0.0.1:5000/hello
にアクセスします。
・Flaskプロジェクトのレイアウト
Flaskではディレクトリ構造などが特に定められているわけではありませんが、プロジェクト内に以下のようなディレクトリを持つことがプラクティスとされています。
flaskr/
: アプリケーションのコードとファイルを含んだPythonパッケージtests/
: テストモジュールを含んだディレクトリvenv/
: Flaskとその他の依存対象がインストールされたPythonの仮想環境- その他のファイル: インストールなどに利用
・Flaskアプリケーションのルーティング
Flaskでは、Route()デコレータを使用して関数とURLを関連付けできます。変数を扱いたい場合には< >
を利用します。デコレータとは、関数やクラスにフレームワークの機能などを付加するための修飾子です。
・FlaskアプリケーションのHTTPメソッド
HTTPメソッドの記述も、Route()デコレータ内で行います。
@app.route('/book/json', methods=['GET']) def book(): book = Book('example title', 'example author') return jsonify(book.__dict__)
・Flaskで簡単なAPIを作成
実際にAPIを作成してみます。FlaskはDjangoよりもAPIに特化したフレームワークのため、簡単に実装できます。返却する値としてJSONを利用したいため、Extensionを追加してJSONレスポンスを取得するAPIを作成します。
hello.py
という名前のファイルを作成し、中身を以下のようにします。
from flask import Flask, Response, jsonify class Book: def __init__(self, title, author): self.title = title self.author = author app = Flask(__name__) @app.route('/hello') def hello(): return 'Hello, World' @app.route('/hello/先述の') def name(name): response = Response('Hello, '+ name) response.mimetype = 'text/plain' return response @app.route('/book/json', methods=['GET']) def book(): book = Book('example title', 'example author') return jsonify(book.__dict__)
flask run
コマンドを利用し、サーバを起動します。
$ export FLASK_APP=hello.py #起動するアプリをFlaskに伝える $ export FLASK_ENV=development #サーバーを開発モードに設定 $ flask run別のターミナルから
curl
を実行します。
$ curl -X GET http://127.0.0.1:5000/book/json { "author": "example author", "title": "example title" }
FastAPI
FastAPIは@tiangolo(Sebastián Ramírez)によって開発された、Python 3.6以降でAPIを構築するためのオープンソース(MIT)・Webフレームワークです。REST APIの実装に特化しており、OpenAPIに準拠しています。自動でAPIドキュメントを生成する機能があり、Flaskのようにプラグインによる拡張も可能です。Starlette/Uvicorn/Pydanticをベースにしたフレームワークで、以下を担う構造です。
- Starlette/Uvicorn: Web部分(ASGI Server)
- Pydantic: データ部分(Validation/Serialization)
・FastAPI - Getting Started
実際にFastAPIを動かしてみましょう。以下のコマンドを実行して、FastAPIをインストールします。
$ python -m pip install fastapi以下のように
hello.py
ファイルを作成します。
from fastapi import FastAPI app = FastAPI() @app.get('/') def read_root(): return {'hello':'world'}アプリケーションの実行のためにASGIサーバ(ASGIについては先述)のインストールが必要です。Uvicornをインストールします。
$ python -m pip install "uvicorn[standard]"Uvicornを起動します。
$ uvicorn hello:app --reload INFO: Will watch for changes in these directories: ['/home/opc/develop/python/fastapi'] INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [13722] using watchgod INFO: Started server process [13724] INFO: Waiting for application startup. INFO: Application startup complete.curlコマンドを実行します。
$ curl -X GET http://127.0.0.1:8000 {"hello":"world"}
・FastAPIアプリケーションのHTTPメソッド
FastAPIのHTTPメソッド指定はFlaskとは若干異なり、それぞれのデコレータが用意されています。
class Item(BaseModel): id: int @app.post('/items/') async def post_item(item: Item): return item
・FastAPIアプリケーションのルーティング
関数とパスを関連付ける形でアプリケーションのルーティングを行います。
@app.get('/') def read_root(): return {'hello':'world'}パスパラメータを利用できます。
@app.get('/items/{item_id}') def get_item(item_id: int, q: str = None): return {'item_id': item_id, 'q': q}クエリパラメータを(`?item_id=1000`のように)渡すことも可能です。
@app.get('/items/') async def get_item(item_id: int = 0): return {'item_id': item_id}
・FastAPIの自動ドキュメント生成[endpoint]/docs
にアクセスすると、自動生成された Swagger UIにアクセスできます。
・FastAPIで簡単なAPIを作成
ここまでのサンプルコードをhello.py
に記述します。
from fastapi import FastAPI app = FastAPI() @app.get('/') def read_root(): return {'hello':'world'} @app.get('/items/{item_id}') def get_item(item_id: int, q: str = None): return {'item_id': item_id, 'q': q} @app.get('/items/') async def get_item(item_id: int = 0): return {'item_id': item_id} from pydantic import BaseModel class Item(BaseModel): id: int @app.post('/items/') async def post_item(item: Item): return itemASGIサーバを起動します。
$ uvicorn hello:app別のターミナルからAPIを実行してみます。
$ curl -X GET http://127.0.0.1:8000/items/1 {"item_id":1,"q":null} $ curl -X GET http://127.0.0.1:8000/items/?item_id=1000 {"item_id":1000} $ curl -X 'POST' \ > 'http://127.0.0.1:8000/items/' \ > -H 'accept: application/json' \ > -H 'Content-Type: application/json' \ > -d '{ > "id": 0 > }' {"id":0}
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- 「Python」+「PostgreSQL」のWebアプリ環境でデータの読み書きをしてみよう
- 「Dockerfile」を書いてコンテナを構築してみよう
- 「Pulumi Automation API」でPulumi CLIの機能をコード化しよう
- GitLabを用いた継続的インテグレーション
- Slackを独自アプリケーションで拡張する
- CloudサービスとRPAの連携
- VNC環境とRaspberry Piで簡単電子工作(7)
- TFXを使った機械学習パイプラインの構築(実装編その2)
- TFXを使った機械学習パイプラインの構築(デプロイ編)
- Policy as Codeでインフラのコンプライアンスを自動実現! 「Pulumi CrossGuard」を活用してみよう