Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pythonで作るAPIサーバー

 Pythonで作るAPIサーバー

Oracle Cloud Hangout Cafe Season 6 #2
https://ochacafe.connpass.com/event/264280/

セッション動画: https://youtu.be/nAbrtfwhcuI

oracle4engineer
PRO

December 08, 2022
Tweet

More Decks by oracle4engineer

Other Decks in Technology

Transcript

  1. Pythonで作るAPIサーバー Oracle Cloud Hangout Cafe – Season 6 #4 Kyotaro

    Nonaka Solutions Architect Oracle Corporation Japan
  2. 1.はじめに 2.Python超基礎 3.PythonのWebフレームワーク 4.PythonでAPIサーバーを作ってみよう Agenda Copyright © 2022, Oracle and/or

    its affiliates 2
  3. はじめに Copyright © 2022, Oracle and/or its affiliates 3

  4. Copyright © 2022, Oracle and/or its affiliates 4 Pythonにほとんど触れたことがない人でもAPIサーバーを Pythonで実装できるように!

    はじめに – 本日のコンセプト
  5. Copyright © 2022, Oracle and/or its affiliates 5 • 野中

    恭大郎 • 日本オラクル ソリューションアーキテクト本部 • 前職はECパッケージのアプリエンジニア • 最近はポケモンSVをちまちま進めています 自己紹介 @non_kyon
  6. Python超基礎 Pythonの基礎知識とHello World ! Copyright © 2022, Oracle and/or its

    affiliates 6
  7. Copyright © 2022, Oracle and/or its affiliates 7 • 1990年代初頭ごろから公開

    • プログラムの「読みやすさ・わかりやすさ」を重視 • インデントがコードブロックとしての意味を持つ • 実用的で、高い拡張性も備える • システム管理 • ツール・アプリケーション開発 • 科学技術計算 • Webシステム Python超基礎 Pythonの概要
  8. Copyright © 2022, Oracle and/or its affiliates 8 Python? Anaconda?

    • Python: GeneralなPython → 今回はこっち! • Anaconda: 機械学習などに利用するディストリビューション Python2? Python3? • 2系と3系で互換性なし! • venvやpyenvなどで開発環境を分けて使い分け • 対応ライブラリ数に違いあり?とはいえ2系はサポートが2020年1月に終了 • ※この資料は全てpython3前提で記載しています Pythonのインストール • CentOS 8系であればPython3.6がプリインストール Python超基礎 Pythonの環境構築について
  9. Copyright © 2022, Oracle and/or its affiliates 9 PyPI(pip) •

    Pythonパッケージのインストールなどを行うユーティリティ • Python 3.4以降には標準で付属 venv(virtualenv) • 公式が提供するPythonのパッケージ管理ツール • Pythonプロジェクト毎に管理が可能 • バージョンを管理するPyenvとは使い分け(もしくは併せて利用) IDE(VS Code Jupyter) • VS Codeなどの多機能エディタにはPythonでの開発を支援する拡張機能が存在 • インタラクティブコンピューティング用としてのJupyter NotebookはPythonでの利用が一般的 Python超基礎 Pythonの環境構築について
  10. Copyright © 2022, Oracle and/or its affiliates 10 対話モード スクリプト化

    Demo: PythonでHello World $ python >>> print('Hello World!') print('Hello World!') ▪hello.py $ python hello.py
  11. PythonのWebフレームワーク Django / Flask / FastAPIの概要とざっくり比較 Copyright © 2022, Oracle

    and/or its affiliates 11
  12. Copyright © 2022, Oracle and/or its affiliates 12 Django •

    2005年リリース • MTVアーキテクチャ(後述) • 大規模アプリケーション • 主な事例 • Instagram • Mozilla • Bitbucket Flask • 2010年リリース • マイクロフレームワーク • 小規模アプリケーション/サービス • 主な事例 • Netflix • reddit • trivago FastAPI • 2019年リリース • マイクロフレームワーク • 小規模アプリケーション/サービス • 主な事例 • Uber(一部) • Netflix(一部) PythonのWebフレームワーク
  13. Copyright © 2022, Oracle and/or its affiliates 13 アメリカのカンザス州 Lawrence

    の新聞社のウェブ部門である World Online で開発 • 現在はボランティアチームによって運営 • https://www.djangoproject.com/foundation/teams • オープンソースライセンス(BSDライセンス) MTVアーキテクチャ • Model: データを取得 • Template: どのようにデータを表示するかを規定 • View: どのデータを表示するかを規定 • いわゆるControllerの機能はフレームワークに内包 • urls.pyによってルーティングを記述 Django ブラウザ urls.py View Model Template DB
  14. Copyright © 2022, Oracle and/or its affiliates 14 Django –

    Getting Started 簡単に動かす $ sudo python -m pip install Django $ python -m django --version import django print(django.get_version()) ▪hello.py $ python hello.py
  15. Copyright © 2022, Oracle and/or its affiliates 15 プロジェクトを作成 生成されたプロジェクトの構造

    Django – Getting Started Djangoプロジェクトを作成 $ django-admin startproject mysite mysite/ manage.py mysite/ __init__.py settings.py urls.py asgi.py wsgi.py • 外側のmysite/: プロジェクトのルートディレクトリ • manage.py: Djangoプロジェクトを操作するためのコマンドラインユーティリティ • 内側のmysite/: このプロジェクトの実際のPythonパッケージ • __init__.py: このディレクトリがPythonパッケージであることをPythonに知らせるための空のファイル • settings.py: Djangoプロジェクトの設定ファイル • urls.py: DjangoプロジェクトのURL宣言 • asgi.py: プロジェクトを提供する ASGI 互換 Web サーバーのエントリポイント • wsgi.py: プロジェクトをサーブするためのWSGI互換Webサーバーとのエントリーポイント
  16. Copyright © 2022, Oracle and/or its affiliates 16 サーバーの起動 開発用サーバー

    Django – Getting Started Djangoプロジェクトの起動 $ django-admin startproject mysite <IP:port> #IP:portはオプション Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. November 28, 2022 - 06:45:21 Django version 3.2.16, using settings 'mysite.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
  17. Copyright © 2022, Oracle and/or its affiliates 17 アプリケーションを動かしてみる View(どのデータを表示するかを記述するファイル)の作成

    Django – Getting Started Djangoアプリケーションを作成 $ python manage.py startapp polls
  18. Copyright © 2022, Oracle and/or its affiliates 18 Djangoでは、1つのProjectに複数のアプリケーションを持つので、 •

    どのアプリケーションにルーティングするか • どの関数にルーティングするか を分けて管理する Django – Getting Started Djangoアプリケーションのルーティング URLs (Project) View Model Template DB ブラウザ URLs (App1) URLs (App2)
  19. Copyright © 2022, Oracle and/or its affiliates 19 Django REST

    frameworkを利用 API認証のためのユーザー作成 • シリアライザー Demo: Djangoで簡単なAPIを作成 $ sudo python -m pip install djangorestframework $ python manage.py createsuperuser --email [email protected] --username admin
  20. Copyright © 2022, Oracle and/or its affiliates 20 • Viewsの実装

    • URLsによるルーティングの実装 Demo: Djangoで簡単なAPIを作成 ▪templateを介さずにデータをやりとり urls.py View Model Template DB
  21. Copyright © 2022, Oracle and/or its affiliates 21 • ModelViewSetを利用することでGET/POSTなどの

    全HTTPメソッドが使えるようになる(実装の簡略化) • サーバーの実行 Demo: Djangoで簡単なAPIを作成 $ python manage.py runserver ・ WebUIでデバッグ
  22. Copyright © 2022, Oracle and/or its affiliates 22 Armin Ronacherによって開発

    • オープンソースライセンス(BSDライセンス) テンプレートエンジンとしてJinja2、WSGIツールキットとして Werkzeug(ヴェルクツォイク)を利用 • Jinja2: pythonで利用できるHTMLテンプレートエンジン • Werkzeug: WSGIアプリケーションのためのユーティリティを 集めたライブラリ • WSGI(Web Server Gateway Interface): Pythonにおける、 WebアプリケーションとWebサーバを接続する標準仕様 • ASGI(Asynchronous Server Gateway Interface)WSGIの後 継仕様で、WebSocketと非同期通信をサポート データベースの抽象化など、必要に応じて拡張(Extension)を 行うのでいわゆるマイクロ・フレームワークとなる Flask ブラウザ Werkzeug Webサーバー
  23. Copyright © 2022, Oracle and/or its affiliates 23 環境構築とFlaskのインストール Flask

    – Getting Started 簡単に動かす $ mkdir myproject $ cd myproject $ python -m venv venv $ . venv/bin/activate $ pip install Flask ▪hello.py 何も指定しなければ text/html形式で返却 • dict型などのJSONオブジェ クトをそのまま返却すれば application/jsonになる Responseを利用することで Content-typeを指定可能
  24. Copyright © 2022, Oracle and/or its affiliates 24 • http://127.0.0.1:5000/にアクセス

    Flask – Getting Started 簡単に動かす $ export FLASK_APP=hello #起動するアプリを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)
  25. Copyright © 2022, Oracle and/or its affiliates 25 • Route()デコレータを使用して関数とURLを関連付け

    • <>を使って変数も扱える Flask – Getting Started Flaskアプリのルーティング
  26. Copyright © 2022, Oracle and/or its affiliates 26 • Route()デコレータ内でHTTPメソッドの記述が可能

    Flask – Getting Started HTTPメソッド
  27. Copyright © 2022, Oracle and/or its affiliates 27 Flask –

    Getting Started JSONを返却するAPI
  28. Copyright © 2022, Oracle and/or its affiliates 28 Flaskではディレクトリ構造などが特に定められているわけではない プラクティスとしては以下

    • flaskr/: アプリケーションのコードとファイルを含んだPythonパッケージ • tests/: テストモジュールを含んだディレクトリ • venv/: Flaskとその他の依存対象がインストールされたPythonの仮想環境 • その他のファイル: インストールなどに利用 Flask – Getting Started プロジェクトのレイアウト
  29. Copyright © 2022, Oracle and/or its affiliates 29 Getting Startedで記述したファイルにExtensionを追加し、JSONのレスポンスを取得

    Demo: Flaskで簡単なAPIを実装
  30. Copyright © 2022, Oracle and/or its affiliates 30 @tiangolo (Sebastián

    Ramírez)によって開発 • Python 3.6 以降でAPI を構築するためのWeb フレームワーク • オープンソース(MIT) REST APIの実装に特化 • OpenAPI準拠 • 自動ドキュメント生成 • プラグインによる拡張 Starlette/Pydanticベース • Starlette/Uvicorn: Web部分(ASGI Server) • Pydantic: データ部分(Validation/Serialization) FastAPI FastAPI Starlette Pydantic Uvicorn
  31. Copyright © 2022, Oracle and/or its affiliates 31 環境構築 アプリケーションの作成

    FastAPI – Getting Started 簡単なアプリの作成 $ mkdir fastapi $ cd fastapi $ python -m venv venv $ . venv/bin/activate $ pip install fastapi $ touch main.py ▪ main.py
  32. Copyright © 2022, Oracle and/or its affiliates 32 ASGIサーバーのインストール サーバーの起動

    実行 FastAPI – Getting Started アプリを実行 $ pip install "uvicorn[standard]" $ uvicorn main:app --reload INFO: Will watch for changes in these directories: ['/home/opc/python/fastapi'] INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [3157492] using watchgod INFO: Started server process [3157494] INFO: Waiting for application startup. INFO: Application startup complete. $ curl -X GET http://127.0.0.1:8000 {"Hello":"World"}
  33. Copyright © 2022, Oracle and/or its affiliates 33 関数とパスを関連付け パスパラメータの利用

    クエリパラメータの利用 FastAPI – Getting Started FastAPIのルーティング
  34. Copyright © 2022, Oracle and/or its affiliates 34 GETメソッド POSTメソッド

    FastAPI – Getting Started HTTPメソッドの利用
  35. Copyright © 2022, Oracle and/or its affiliates 35 [endpoint]/doc にアクセスすると、自動生成された

    Swagger UIを確認できる FastAPI – Getting Started 自動ドキュメント生成
  36. Copyright © 2022, Oracle and/or its affiliates 36 Demo: FastAPIで簡単なAPIを実装

  37. PythonでAPIサーバーを作ってみよう それぞれのWebフレームワークでDBと繋いでAPIを実装! Copyright © 2022, Oracle and/or its affiliates 37

  38. Copyright © 2022, Oracle and/or its affiliates 38 • cx_Oracleの名前が変わり、今後はpython-oracledbの利用が推奨

    • 現在Djangoはpython-oracledbをネイティブ・サポートしていない • ThinモードとThickモードがあり、ThinモードではOracle Clientライブラリを必要としない • SODAなどの一部機能を利用する場合はThickモードを利用 • Thickモードでは引き続きOracle Clientライブラリが必要 python-oracledb Driver | cx_Oracle Driver PythonでOracle Databaseを使用するためのドライバ #インストール $ pip install oracledb –-upgrade
  39. Copyright © 2022, Oracle and/or its affiliates 39 python-oracledbでAutonomous Database(ADB)と繋いでみる

    Autonomous Databaseと接続するために必要な Wallet を利用した接続
  40. Copyright © 2022, Oracle and/or its affiliates 40 python-oracledbでAutonomous Database(ADB)と繋いでみる

    Connection Pool を利用
  41. Copyright © 2022, Oracle and/or its affiliates 41 DjangoでAutonomous Databaseと接続するために必要な作業

    • Oracle Client のダウンロード&インストール • cx_Oracleのインストール • Walletをダウンロード/展開して中身のcwallet.sso, sqlnet.ora, tnsnames.ora を配置(下記どちらか) • /usr/lib/oracle/<version>/client64/lib/network/adminに配置 • 任意の場所 • 任意の場所に配置した場合、sqlnet.oraの中身を修正(青枠の部分をWalletのディレクトリに変更)する必要がある • 環境変数としてTNS_ADMINにWalletの配置先を設定 • 環境変数としてLD_LIBRARY_PATH=Oracle Clientのインストール先を指定 各フレームワークでデータベースと接続 Djangoで実装 WALLET_LOCATION = (SOURCE = (METHOD = file) (METHOD_DATA = (DIRECTORY="$HOME/Cloud/DB_WALLETDIR"))) SSL_SERVER_DN_MATCH=yes $ pip install cx_oracle
  42. Copyright © 2022, Oracle and/or its affiliates 42 • settings.pyの変更

    • Djangoの実行(Djangoのデフォルト画面が出れば接続成功) • 上手くいかない場合はpython manage.py migrate すれば上手くいく場合が多い 各フレームワークでデータベースと接続 Djangoで実装 (続き) $ python manage.py runserver
  43. Copyright © 2022, Oracle and/or its affiliates 43 FlaskはDBとの接続部分をフレームワークとしては持たない •

    単純にpython-oracledbをインストールすれば良い • ADBとの接続はWalletを利用した接続が可能 とは言えORMがないとデータが扱いづらいので SQL Alchemyを利用(後述) 各フレームワークでデータベースと接続 Flaskで実装
  44. Copyright © 2022, Oracle and/or its affiliates 44 FastAPIもDBとの接続部分をフレームワークとしては持たない •

    単純にpython-oracledbをインストールすれば良い • ADBとの接続はWalletを利用した接続が可能 とは言えORMがないとデータが扱いづらいので こちらもSQL Alchemyを利用(後述) 各フレームワークでデータベースと接続 FastAPIで実装
  45. Copyright © 2022, Oracle and/or its affiliates 45 ファイルを2つ準備 •

    Dockerfile • Requirements.txt • pip install していることからわかように、Djangoプロジェクト実装時に インストールが必要なパッケージをここにリストする • 例えば今回は django REST Frameworkも追加する これだけ準備すれば、あとはdocker build –t ~~ . だけでよい 各フレームワークでコンテナ化 Djangoで実装 ▪Dockerfile ▪requirements.txt
  46. Copyright © 2022, Oracle and/or its affiliates 46 Djangoと同様にファイルを2つ準備 •

    Dockerfile • Requirements.txt Flaskの場合はENVの設定が必要 各フレームワークでコンテナ化 Flaskで実装 ▪Dockerfile
  47. Copyright © 2022, Oracle and/or its affiliates 47 Python 3.7以上であればこんなにシンプル!

    3.6で実行する場合はこれまでと同様に3.6-slim-busterを利用し、requirementsにfastapiを記述 各フレームワークでコンテナ化 FastAPIで実装
  48. Copyright © 2022, Oracle and/or its affiliates 48 Django REST

    FrameworkはORM含めてフレームワーク化されている • 以下コマンドを実行 • 実行結果より、テーブルからmodel.pyの中身を取得できる(自動で生成される!) Demo: Djangoで簡単なCRUDアプリケーションを実装 $ python manage.py inspectdb
  49. Copyright © 2022, Oracle and/or its affiliates 49 • シリアライザの実装

    • Viewsの実装 • Routingの追加 Demo: Djangoで簡単なCRUDアプリケーションを実装
  50. Copyright © 2022, Oracle and/or its affiliates 50 ORMとしてFlask-SQLAlchemy(Extension)を利用 Flask-SQLAlchemyはcx_Oracleが必要なのでインストール

    djangoでATPと接続(p41)と同様の手順を実施 Demo: FlaskでORM(Object Relational Mapper)を利用 準備 $ pip install flask-sqlalchemy $ pip install cx_Oracle • PythonのORM • オープンソース(MIT) • 様々なデータベースをサポート Model Notes(テーブル名) ID: Number(PK) Text: VARCHAR2 class Notes id = … text= … ※ORMとは: オブジェクトとRDBの間でデータ形式の相互変換を行うもの
  51. Copyright © 2022, Oracle and/or its affiliates 51 Import DB接続の作成

    Demo: FlaskでORMを利用 ソースコード
  52. Copyright © 2022, Oracle and/or its affiliates 52 DBオブジェクト(Model)の作成 関数

    Demo: FlaskでORMを利用 ソースコード
  53. Copyright © 2022, Oracle and/or its affiliates 53 内容としてはflask-sqlalchemyを利用した場合とほぼ変わらないので割愛 •

    FastAPIにはExtensionのような概念がないので、ノーマルなSQL Alchemyをインストール FastAPIでORM(SQL Alchemy)を利用 $ pip install sqlalchemy
  54. Copyright © 2022, Oracle and/or its affiliates 54 APIサーバーと聞いてRESTはまず思い浮かぶ、、、でもgRPCやGraphQLだってある •

    本日は時間の都合上gRPCのみを紹介 (gRPCとGraphQLについて詳しくは以前のOCHaCafe参照!動画あります) APIはRESTだけじゃない – gRPCとGraphQL
  55. Copyright © 2022, Oracle and/or its affiliates 55 gRPCにはコンポーネントとして、 ServerとClientがある

    Server • リクエストを受け、レスポンスを返却するサービス層 Client • リクエストを送信し、レスポンスを受け取る • 内部的にServerのStubを保持しており、リクエスト送 信の実装は、このStubのメソッドを実行する形となる gRPCのおさらい – gRPCのコンポーネント
  56. Protocol Buffersによる実装 • Googleが開発(2008年にオープンソース化)したシリアライ ズフォーマット • IDL(インターフェース記述言語)を用いて、任意の言語のボ イラープレートコードを生成 • 結果的に、リクエスト/レスポンスのスキーマを最初に定義する開

    発スタイルとなる • 多言語に対応しており、異言語間のやり取りが発生しうる Microservicesアプリとの相性が良い • 型安全なスキーマ • デフォルトはこのProtocol Buffersであるものの、gRPCそ のものはJSONなどの形式にも対応 gRPCの特徴 – Protocol Buffers Copyright © 2022, Oracle and/or its affiliates 56 ▪ .protoファイル(IDL)
  57. Copyright © 2022, Oracle and/or its affiliates 57 gRPCのインストール gRPC

    toolsのインストール gRPC公式のサンプルを使用 https://grpc.io/docs/languages/python/quickstart/ gRPC with Python Quick start $ pip install grpcio $ pip install grpcio-tools # Clone the repository to get the example code: $ git clone -b v1.50.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc # Navigate to the "hello, world" Python example: $ cd grpc/examples/python/helloworld
  58. Copyright © 2022, Oracle and/or its affiliates 58 examples/python/helloworldディレクトリでgRPCサーバーを実行 ※環境によってはbuilder.pyが存在しないといったエラーが出るので、その場合はprotobufをアップデート

    別ターミナルを開き、gRPCクライアントを実行(※venvのactivateを忘れないように!!!) gRPC with Python Quick start 続き $ python greeter_server.py $ pip install protobuf==4.21.0 $ python greeter_client.py Will try to greet world ... Greeter client received: Hello, you!
  59. ご清聴ありがとうございました! Copyright © 2022, Oracle and/or its affiliates 59