Oracle Cloud Hangout Cafe Season6 #4「Pythonで作るAPIサーバー」(2022年12月7日開催)
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
は、以下のコマンドでインストールできます。
$ 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をインストール
$ pip install cx_oracle
- Autonomous DatabaseのWalletをダウンロード、展開して中身の
cwallet.sso
、sqlnet.ora、 tnsnames.ora
を/usr/lib/oracle/<version>/client64/lib/network/admin
に配置 - 環境変数としてTNS_ADMINにWalletの配置先を設定
TNS_ADMIN=<Walletの配置先>
- 環境変数としてLD_LIBRARY_PATHにOracle Clientのインストール先を指定
LD_LIBRARY_PATH=<Oracle Clientの配置先>
settings.py
を変更します。
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.oracle', 'NAME': '<TNS名>', 'USER': '<データベースのユーザ名>', 'PASSWORD': '<データベースユーザのパスワード>', } }Djangoを実行します。Djangoのデフォルト画面が出れば接続成功です。
$ python manage.py runserver何かエラーが発生した場合は、データベースと同期することでうまくいく場合が多いので、以下のコマンドをお試しください。
$ python manage.py migrate
・Flask
FastAPIもデータベースとの接続部分をフレームワークとしては持たないため、単純にpython-oracledbをインストールするだけで接続できます。また、Autonomous DatabaseとはWalletを利用して接続できます。
import oracledb pool = oracledb.create_pool( user="<データベースのユーザ名>", password="<データベースユーザのパスワード>", dsn="<TNS名>", config_dir="<Walletの配置先>", wallet_location="<Walletの配置先>", wallet_password="<Walletのパスワード>" ) @app.route('/getTime', methods=['GET']) def get_time_db(): with pool.acquire() as connection: cursor = connection.cursor() sql = """select sysdate from dual""" for res in cursor.execute(sql): result = str(res) return result
・FastAPI
FastAPIもデータベースとの接続部分をフレームワークとしては持たないため、単純にpython-oracledbをインストールするだけで接続が可能です。以下は、Walletを利用してAutonomous Databaseと接続する場合の例です。
import oracledb pool = oracledb.create_pool( user="Glt;データベースのユーザ名>", password="<データベースユーザのパスワード>", dsn="<TNS名>", config_dir="<Walletの配置先>", wallet_location="<Walletの配置先>", wallet_password="<Walletのパスワード>" ) @app.get('/getTime') def get_time_db(): with pool.acquire() as connection: cursor = connection.cursor() sql = """select sysdate from dual""" for res in cursor.execute(sql): result = str(res) return result
各フレームワークでコンテナ化
ここからは、各フレームワークでコンテナ化する手順を解説します。
・Django
Djangoアプリケーションをコンテナ化するには、Dockerfile
とrequirements.txt
の2つのファイルが必要です。2つのファイルを用意して、docker image build -t ~~
を実行することでコンテナイメージを作成できます。
Dockerfileの中身は、以下のようになります。
FROM python:3.6-slim-buster ENV PYTHONUNBUFFERED 1 RUN mkdir /code WORKDIR /code ADD requirements.txt /code/ RUN pip install -r requirements.txt ADD . /code/ CMD python3 manage.py runserver
requirements.txtの中身には、Djangoプロジェクト実装時にインストールが必要なパッケージをリストします。例えばDjango REST Frameworkを利用する場合は、以下の通りです。
djangorestframework
・Flask
FlaskもDjangoと同様にDockerfile
とrequirements.txt
の2つのファイルが必要です。2つのファイルを用意して、docker image build -t ~~
を実行することでコンテナイメージを作成できます。
FROM python:3.6-slim-buster ENV PYTHONUNBUFFERED 1 RUN mkdir /code WORKDIR /code ADD requirements.txt /code/ RUN pip install -r requirements.txt ADD . /code/ ENV FLASK_APP hello.py #Flaskの場合はENVの設定が必要 CMD ["flask", "run"]
・FastAPI
Python3.7以降を使うと、非常に簡単にコンテナ化できます。
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7 COPY hello.py 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をインストールします。
$ python -m pip install grpciogRPC toolをインストールします。
$ python -m pip install grpcio-toolsgRPC公式のサンプルを使用します。
# Clone the repository to get the example code: $ git clone -b v1.61.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc # Navigate to the "hello, world" Python example: $ cd grpc/examples/python/helloworldexamples/python/helloworldディレクトリでgRPCサーバーを実行します。
$ python greeter_server.py環境によっては「builder.pyが存在しない」といったエラーが出るので、その場合はprotobufをアップデートします。
$ python -m pip install protobuf==<バージョン>別ターミナルを開き、gRPCクライアントを実行します。
$ python greeter_client.py Will try to greet world ... Greeter client received: Hello, you!
おわりに
今回は、PythonでAPIサーバを構築するにあたっての基礎的な部分を解説しました。それぞれのフレームワークにはそれぞれ良いところがあります。
- Django
- フレームワークとしての決まりごとがしっかりしている
- 歴史が古い
- 大規模なアプリケーション向き
- Flask
- 軽量
- 拡張性が高い
- 小規模なアプリケーション(or Microservices)向き
- FastAPI
- 最軽量
- 拡張性が高い
- 小規模なアプリケーション(or Microservices)向き
この記事をきっかけに、PythonによるAPIサーバの実装そのものに興味を持っていただく、または、実際にフレームワークを選択する際の参考にしていただければ幸いです。
連載バックナンバー
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」を活用してみよう