PythonでAPIサーバーを作ってみよう
データベースと接続して、APIを実装する準備を整えましょう。ここでは、Oracle Database前提で、特にOCI上のAutonomous Databaseを利用して解説します。
python-oracledbとcx_Oracle
python-oracledbとcx_OracleはどちらもPythonでOracle Databaseを使用するためのドライバです。元々Python用のドライバとしてはcx_Oracleがありましたが、名前が変わり、今後はpython-oracledbの利用が推奨となっています。
python-oracledb
は、以下のコマンドでインストールできます。
1 | $ python -m pip install oracledb |
各フレームワークでデータベースと接続
それでは、Django、Flask、FastAPIの各フレームワークでAutonomous Databaseに接続してみます。
・Django
元々Djangoはpython-oracledbをネイティブ・サポートしていませんでしたが、2023年12月リリースのv5.0からサポートされ、cx_Oracleはdeprecatedとなりました。しかしDjango5.0はLTSではないので、ここでは従来通りのcx_Oracleを利用した方法を解説します。
- Oracle Client
をダウンロードしてインストール
- cx_Oracleをインストール
- Autonomous DatabaseのWalletをダウンロード、展開して中身の
cwallet.sso
、sqlnet.ora、tnsnames.ora
を/usr/lib/oracle/<version>/client64/lib/network/admin
に配置
- 環境変数としてTNS_ADMINにWalletの配置先を設定
- 環境変数としてLD_LIBRARY_PATHにOracle Clientのインストール先を指定
LD_LIBRARY_PATH=<Oracle Clientの配置先>
settings.py
を変更します。
3 | 'ENGINE': 'django.db.backends.oracle', |
5 | 'USER': '<データベースのユーザ名>', |
6 | 'PASSWORD': '<データベースユーザのパスワード>', |
Djangoを実行します。Djangoのデフォルト画面が出れば接続成功です。
1 | $ python manage.py runserver |
何かエラーが発生した場合は、データベースと同期することでうまくいく場合が多いので、以下のコマンドをお試しください。
1 | $ python manage.py migrate |
・Flask
FastAPIもデータベースとの接続部分をフレームワークとしては持たないため、単純にpython-oracledbをインストールするだけで接続できます。また、Autonomous DatabaseとはWalletを利用して接続できます。
03 | pool = oracledb.create_pool( |
05 | password="<データベースユーザのパスワード>", |
07 | config_dir="<Walletの配置先>", |
08 | wallet_location="<Walletの配置先>", |
09 | wallet_password="<Walletのパスワード>" |
12 | @app.route('/getTime', methods=['GET']) |
14 | with pool.acquire() as connection: |
15 | cursor = connection.cursor() |
16 | sql = """select sysdate from dual""" |
17 | for res in cursor.execute(sql): |
・FastAPI
FastAPIもデータベースとの接続部分をフレームワークとしては持たないため、単純にpython-oracledbをインストールするだけで接続が可能です。以下は、Walletを利用してAutonomous Databaseと接続する場合の例です。
03 | pool = oracledb.create_pool( |
04 | user="Glt;データベースのユーザ名>", |
05 | password="<データベースユーザのパスワード>", |
07 | config_dir="<Walletの配置先>", |
08 | wallet_location="<Walletの配置先>", |
09 | wallet_password="<Walletのパスワード>" |
14 | with pool.acquire() as connection: |
15 | cursor = connection.cursor() |
16 | sql = """select sysdate from dual""" |
17 | for res in cursor.execute(sql): |
各フレームワークでコンテナ化
ここからは、各フレームワークでコンテナ化する手順を解説します。
・Django
Djangoアプリケーションをコンテナ化するには、Dockerfile
とrequirements.txt
の2つのファイルが必要です。2つのファイルを用意して、docker image build -t ~~
を実行することでコンテナイメージを作成できます。
Dockerfileの中身は、以下のようになります。
1 | FROM python:3.6-slim-buster |
5 | ADD requirements.txt /code/ |
6 | RUN pip install -r requirements.txt |
8 | CMD python3 manage.py runserver |
requirements.txtの中身には、Djangoプロジェクト実装時にインストールが必要なパッケージをリストします。例えばDjango REST Frameworkを利用する場合は、以下の通りです。
・Flask
FlaskもDjangoと同様にDockerfile
とrequirements.txt
の2つのファイルが必要です。2つのファイルを用意して、docker image build -t ~~
を実行することでコンテナイメージを作成できます。
1 | FROM python:3.6-slim-buster |
5 | ADD requirements.txt /code/ |
6 | RUN pip install -r requirements.txt |
8 | ENV FLASK_APP hello.py #Flaskの場合はENVの設定が必要 |
・FastAPI
Python3.7以降を使うと、非常に簡単にコンテナ化できます。
1 | FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7 |
3 | CMD ["uvicorn", "hello:app"] |
gRPC with Python
ここまでREST APIについて解説してきましたが、最後にgRPCを利用したPythonのAPIサーバについても少し触れておきます。
gRPCは、スキーマ駆動の開発、HTTP/2による高速通信、複数のストリーミング通信などを実現できる将来性のあるRPCフレームワークです。
・gRPCのコンポーネント
gRPCには、コンポーネントとしてServerとClientがあります。
- Server
- Client
- リクエストを送信し、レスポンスを受け取る
- 内部的にServerのStubを保持し、リクエスト送信の実装は、このStubのメソッドを実行する
・Protocol Buffers
gRPCは、一般的にデータをシリアライズする方式としてProtocol Buffers(Protobuf)を使用します。ProtobufはGoogleが開発(2008年にオープンソース化)したシリアライズフォーマットです。
- IDL(インターフェース記述言語)を用いて、任意言語のボイラープレートコードを生成
- リクエスト/レスポンスのスキーマを最初に定義する開発スタイル
- 多言語に対応しており、異言語間のやり取りが発生しうるMicroservicesアプリとの相性が良い
- 型安全なスキーマ
・Quick start
gRPCをインストールします。
1 | $ python -m pip install grpcio |
gRPC toolをインストールします。
1 | $ python -m pip install grpcio-tools |
gRPC公式のサンプルを使用します。
1 | # Clone the repository to get the example code: |
3 | # Navigate to the "hello, world" Python example: |
4 | $ cd grpc/examples/python/helloworld |
examples/python/helloworldディレクトリでgRPCサーバーを実行します。
1 | $ python greeter_server.py |
環境によっては「builder.pyが存在しない」といったエラーが出るので、その場合はprotobufをアップデートします。
1 | $ python -m pip install protobuf==<バージョン> |
別ターミナルを開き、gRPCクライアントを実行します。
1 | $ python greeter_client.py |
2 | Will try to greet world ... |
3 | Greeter client received: Hello, you! |
おわりに
今回は、PythonでAPIサーバを構築するにあたっての基礎的な部分を解説しました。それぞれのフレームワークにはそれぞれ良いところがあります。
- Django
- フレームワークとしての決まりごとがしっかりしている
- 歴史が古い
- 大規模なアプリケーション向き
- Flask
- 軽量
- 拡張性が高い
- 小規模なアプリケーション(or Microservices)向き
- FastAPI
- 最軽量
- 拡張性が高い
- 小規模なアプリケーション(or Microservices)向き
この記事をきっかけに、PythonによるAPIサーバの実装そのものに興味を持っていただく、または、実際にフレームワークを選択する際の参考にしていただければ幸いです。