私は、fastapi を使用してポスト API を作成しています。必要なリクエスト形式は次のとおりです。
{
"leadid":LD123,
"parties":[
{
"uid":123123,
"cust_name":"JOhn Doe",
}, ...]}
Python の fastapi コードは次のとおりです。
class Customer(BaseModel):
UID: str
CustName: str
class PackageIn(BaseModel):
lead_id: str
parties: Set[Customer]
# threshold: Optional[int] = 85
app = FastAPI()
@app.post('/')
async def nm_v2(package:PackageIn):
return {"resp":"Response"}
応答を送信するために SwaggerUI にアクセスすると、エラー「422 エラー: 処理できないエンティティ」が表示されます。また、SwaggerUI ドキュメントには次のように記載されています
{
"detail": [
{
"loc": [
"body"
],
"msg": "unhashable type: 'Customer'",
"type": "type_error"
}
]
}
Customer という別の pydantic ベースのクラスを作成せずに、リクエスト ペイロード用の dict() 構造を作成する方法がわかりません。エラーを修正する方法を教えてください。
1
party はカスタムのリストである必要がありますえーっ。これを顧客のセットとして定義しました。また、顧客属性の名前が間違っています。 UID != uid、大文字と小文字は区別されず、CustName != cust_name (変換を行っている場合を除く)。また、uid は str ではなく int である必要があります。
– アネロイド
2020 年 9 月 3 日 10:51
1
問題は Set[Customer] にあります。通常、pydantic モデルはハッシュ可能ではないため、set は指定された項目が既にコレクション内にあるかどうかを確認できません。
– Take_Care_
2020 年 9 月 3 日 10:51
また、leadid の値は文字列ではないようです。問題が発生する可能性があります。リクエストはプレーンな JSON で、Python に変換されてから pydantic モデルに変換されるため、二重引用符 " で囲むことをお勧めします。それは問題の根本原因ではないかもしれませんが、単なる提案です。
– lsabi
2020 年 9 月 3 日 16:11
------------------------
Pytdantic BaseClass はハッシュ可能ではありません。議論がありますこの機能については、おそらく実装されないと思います。ディスカッションには回避策があります。あなたのケースでは、これを試すことができます。
from pydantic import BaseModel
from typing import Set
class MyBaseModel(BaseModel):
def __hash__(self): # make hashable BaseModel subclass
return hash((type(self),) + tuple(self.__dict__.values()))
class Customer(MyBaseModel): # Use hashable sublclass for your model
UID: str
CustName: str
class PackageIn(BaseModel):
lead_id: str
parties: Set[Customer]
# threshold: Optional[int] = 85
data = {
"lead_id": 'LD123',
"parties": [
{
"UID": 123123,
"CustName": "JOhn Doe",
}]}
PackageIn.parse_obj(data) # This part fastapi will make on post request, just for test
> <PackageIn lead_id='LD123' parties={<Customer UID='123123' CustName='JOhn Doe'>}>
------------------------
後
https://github.com/pydantic/pydantic/pull/1881
オブジェクトをハッシュ可能にするには、frozen = True を追加できます (インスタンスは変更できないことに注意してください)
class Customer(BaseModel)::
UID: str
CustName: str
class Config:
frozen = True
1
これが私が最も気に入っている答えです。
– ヤアコフ・ブレスラー
2023 年 10 月 3 日 19:58