MENU

Django Ninjaチュートリアル⑨(リクエストパーサー)

Django Ninjaチュートリアル⑨(リクエストパーサー)

前回までの記事はこちらです。

前回までの記事が読まれている前提で書いていきますので、まだ読んでいない方はこちらから読み進めて追いついてください。

それでは始めていきましょう。

目次

リクエストパーサーとは

今回は、Django Ninjaにおける、リクエストパーサーを見ていきます。

パーサー(Parser)とは?
ソースコードファイルを解析するコンパイラまたはインタプリタのモジュールのことを言います。
もう少しわかりやすくいうと、「テキストを解析して内容を別の表現に変換する」機能のこと。

Django NinjaにおけるParser

ほとんどのREST APIの場合、リクエストボディから送信されるデフォルトのコンテンツタイプはJSONの場合が多いですが、他のコンテンツタイプ(YAML、XML、CSVなど)を操作する必要が出てきた場合や、より高速なJSONパーサーを使用する必要がある場合などに備えて、Django Ninjaはparserを用意しています。

YAML(ヤメル、ヤムル)とは、構造化データやオブジェクトを文字列にシリアライズ(直列化)するためのデータ形式の一種。

https://ja.wikipedia.org/wiki/YAML

Extensible Markup Language(エクステンシブル マークアップ ランゲージ)は、基本的な構文規則を共通とすることで、任意の用途向けの言語に拡張することを容易としたことが特徴のマークアップ言語の総称である。
一般的にXML(エックスエムエル)と略称で呼ばれる。

https://ja.wikipedia.org/wiki/Extensible_Markup_Language

comma-separated values(略称:CSV)は、テキストデータをいくつかのフィールド(項目)に分け、区切り文字であるカンマ「,」で区切ったデータ形式。

https://ja.wikipedia.org/wiki/Comma-Separated_Values

parserを使用する

parserを使用する場合、基本的な書き方は、以下のとおりです。

api = NinjaAPI(parser = MyYamlParser())

また、独自のparserを作成する場合、ninja.parser.Parserクラスを拡張し、parse_bodyメソッドをオーバーライドすることで可能となります。

YAML Parserの例

Pyyamlのインストール

まずはpythonでyamlを扱うために必要なライブラリをインストールしていきます。
docker-compose upの状態で以下のコマンドを実行します。

docker-compose exec backend poetry add pyyaml

docker-composeを一度停止して、以下のコマンドを実行し、コンテナを再度ビルドします。

docker-compose build --no-cache

それでは実際にコードを書いていきます。

まずは、YAML Parserの例を見ていきます。
前回までに作成しているapi_v3.pyに追記していきます。
ソースコードは以下のとおりです。

from ninja import Schema
from datetime import date
from typing import List # add

〜略〜

# add
class Payload(Schema):
  ints: List[int]
  string: str
  f: float

Schema(Payload)について

Schemaは通常の型定義と同様の構成になっています。
わかりやすいように、項目と型に関連性を持たせて定義しています。
intsについては、項目をListで受け、リストの全ての項目に対し、int型を強制しています。

import yaml
from ninja import NinjaAPI, File, Form
from ninja.files import UploadedFile
from typing import List
from ninja.parser import Parser # add

from example.Schema.api_v3_schema import UserDetails, Payload # add

# add
class MyYamlParser(Parser):
  def parse_body(self, request):
    return yaml.safe_load(request.body)

app_v3 = NinjaAPI(
  title = "Django-Ninja Sample App3",
  version = "1.0.2",
  parser = MyYamlParser() # add
)

〜略〜

# add 4
@app_v3.post("/yaml")
def operation(request, payload: Payload):
  return payload.dict()

APIについて

Parserについて、Djnago Ninja(ninja)からParserimportapp_v3を作成する際に、parserを設定しています。
これにより、このファイルで定義するAPIに対してParserが適用になります。

そして、そのparserの中身についてですが、MyYamlParserというクラスを Parserを継承して定義しています。
内容としては、yaml.safe_load()を使用して、YAMLファイルを読み込み、実行可能な形へと変換します。
受け取る内容は、YAMLで作られたrequest.bodyを想定しています。

実行結果の例

例えば、以下のようなYAMLファイルを読み込んだとします。

ints: # list
 - 0
 - 1
string: hello
f: 3.14

これを、実行すると、

{
  "ints": [
    0,
    1
  ],
  "string": "hello",
  "f": 3.14
}

JSONに変換された結果が返されます。

自動生成ドキュメントは以下のようになると思います。

YAMLがJSONに変換された自動生成ドキュメントの結果

ORJSON パーサーの例

orjsonは、Python用の高速で正確なJSONライブラリです。JSON 用の最速のPythonライブラリで、標準ライブラリや他のサードパーティ製ライブラリよりも正確とされています(Django Ninjaの公式で推奨されています)。

まずは、orjsonをインストールします。
docker-compose upを実行した状態で、以下のコマンドを実行します。

docker-compose exec backend poetry add orjson

そして、docker-composeを閉じた後に、下記のコマンドを実行して、コンテナを再度ビルドします。

docker-compose build --no-cache

コンテナを再度ビルドした後、以下のように記載します。

import yaml
import orjson # add
from ninja import NinjaAPI, File, Form
from ninja.files import UploadedFile
from typing import List
from ninja.parser import Parser

from example.Schema.api_v3_schema import UserDetails, Payload

class MyYamlParser(Parser):
  def parse_body(self, request):
    return yaml.safe_load(request.body)

# add
class ORJSONParser(Parser):
  def parse_body(self, request):
    return orjson.loads(request.body)

app_v3 = NinjaAPI(
  title = "Django-Ninja Sample App3",
  version = "1.0.2",
  parser = ORJSONParser()
)

〜略〜

MyYamlParserクラスを作成した際と同様に、ORJSONParserを作成し、app_v3で読み込んでいます。
これで、ORJSONを利用したJSONの操作が可能となります。
(ORJSONの使い方はここでは省略します。Django NinjaでORJSONを使用する場合は、こうするのかというところまでとなります)

最後に

今回は、Django Ninjaにおけるリクエストパーサーの処理について見てきました。

YAMLやXMLなど様々データ形式に対応するためには必要な機能だと思います。
他のアプリケーションからデータを読み込むにしても、データ形式が合わず、読み込みができないといった問題に、ほんの数行で対応できるので便利な機能だと思います。

また、JSONの操作については、ORJSONを使った操作が可能で、他のライブラリ等よりも高速な処理が可能というメリットもあります。

個々の詳しい説明は、機会があれば勉強してみてからかなと思いますが、まずは取り掛かりとして、基本的な導入部分をチュートリアルにしたがって確認した記事となりました。

次回は、Django NinjaのSchemaについて見ていきます。

これまで何度も出てきているSchemaの考え方等が見えるのではないかと思います。

それでは、今回はここまでです。また次回もよろしくお願いします。

Django Ninjaチュートリアル⑨(リクエストパーサー)

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

はじめまして、ふじです。
Python、Django、FastAPI、React.js、Next.jsを学習している、ずっと文系のプログラミング独学者です。

目次