{"detail":[{"type":"int_parsing","loc":["path","item_id"],"msg":"Input should be a valid integer, unable to parse string as an integer","input":"foo","url":"https://errors.pydantic.dev/2.1/v/int_parsing"}]}
тому що параметр шляху має значення "foo", яке не є типом int.
І оскільки згенерована схема відповідає стандарту OpenAPI, існує багато сумісних інструментів.
З цієї причини FastAPI також надає альтернативну документацію API (використовуючи ReDoc), до якої можна отримати доступ за посиланням http://127.0.0.1:8000/redoc:
Таким чином, існує багато сумісних інструментів, включаючи інструменти для генерації коду для багатьох мов.
Вся валідація даних виконується за лаштунками за допомогою Pydantic, тому Ви отримуєте всі переваги від його використання. І можете бути впевнені, що все в надійних руках.
Ви можете використовувати ті самі оголошення типів з str, float, bool та багатьма іншими складними типами даних.
Декілька з них будуть розглянуті в наступних розділах посібника.
При створенні операцій шляху можуть виникати ситуації, коли шлях фіксований.
Наприклад, /users/me. Припустимо, що це шлях для отримання даних про поточного користувача.
А також у вас може бути шлях /users/{user_id}, щоб отримати дані про конкретного користувача за його ID.
Оскільки операції шляху оцінюються по черзі, Ви повинні переконатися, що шлях для /users/me оголошений перед шляхом для /users/{user_id}:
fromfastapiimportFastAPIapp=FastAPI()@app.get("/users/me")asyncdefread_user_me():return{"user_id":"the current user"}@app.get("/users/{user_id}")asyncdefread_user(user_id:str):return{"user_id":user_id}
Інакше шлях для /users/{user_id} також буде відповідати для /users/me, "вважаючи", що він отримує параметр user_id зі значенням "me".
Аналогічно, Ви не можете оголосити операцію шляху:
Якщо у вас є операція шляху, яка приймає параметр шляху, але Ви хочете, щоб можливі допустимі значення параметра шляху були попередньо визначені, Ви можете використати стандартний Python Enum.
Імпортуйте Enum і створіть підклас, що наслідується від str та Enum.
Наслідуючи від str, документація API зможе визначити, що значення повинні бути типу string, і правильно їх відобразить.
Після цього створіть атрибути класу з фіксованими значеннями, які будуть доступними допустимими значеннями:
fromenumimportEnumfromfastapiimportFastAPIclassModelName(str,Enum):alexnet="alexnet"resnet="resnet"lenet="lenet"app=FastAPI()@app.get("/models/{model_name}")asyncdefget_model(model_name:ModelName):ifmodel_nameisModelName.alexnet:return{"model_name":model_name,"message":"Deep Learning FTW!"}ifmodel_name.value=="lenet":return{"model_name":model_name,"message":"LeCNN all the images"}return{"model_name":model_name,"message":"Have some residuals"}
Потім створіть параметр шляху з анотацією типу, використовуючи створений вами клас enum (ModelName):
fromenumimportEnumfromfastapiimportFastAPIclassModelName(str,Enum):alexnet="alexnet"resnet="resnet"lenet="lenet"app=FastAPI()@app.get("/models/{model_name}")asyncdefget_model(model_name:ModelName):ifmodel_nameisModelName.alexnet:return{"model_name":model_name,"message":"Deep Learning FTW!"}ifmodel_name.value=="lenet":return{"model_name":model_name,"message":"LeCNN all the images"}return{"model_name":model_name,"message":"Have some residuals"}
Ви можете порівнювати його з елементами перелічування у створеному вами enum ModelName:
fromenumimportEnumfromfastapiimportFastAPIclassModelName(str,Enum):alexnet="alexnet"resnet="resnet"lenet="lenet"app=FastAPI()@app.get("/models/{model_name}")asyncdefget_model(model_name:ModelName):ifmodel_nameisModelName.alexnet:return{"model_name":model_name,"message":"Deep Learning FTW!"}ifmodel_name.value=="lenet":return{"model_name":model_name,"message":"LeCNN all the images"}return{"model_name":model_name,"message":"Have some residuals"}
Ви можете отримати фактичне значення (у цьому випадку це str), використовуючи model_name.value, або загалом your_enum_member.value:
fromenumimportEnumfromfastapiimportFastAPIclassModelName(str,Enum):alexnet="alexnet"resnet="resnet"lenet="lenet"app=FastAPI()@app.get("/models/{model_name}")asyncdefget_model(model_name:ModelName):ifmodel_nameisModelName.alexnet:return{"model_name":model_name,"message":"Deep Learning FTW!"}ifmodel_name.value=="lenet":return{"model_name":model_name,"message":"LeCNN all the images"}return{"model_name":model_name,"message":"Have some residuals"}
Порада
Ви також можете отримати доступ до значення "lenet", використовуючи ModelName.lenet.value.
Ви можете повертати елементи перелічування з вашої операції шляху, навіть вкладені у JSON-тіло (наприклад, dict).
Вони будуть перетворені на відповідні значення (у цьому випадку рядки) перед поверненням клієнту:
fromenumimportEnumfromfastapiimportFastAPIclassModelName(str,Enum):alexnet="alexnet"resnet="resnet"lenet="lenet"app=FastAPI()@app.get("/models/{model_name}")asyncdefget_model(model_name:ModelName):ifmodel_nameisModelName.alexnet:return{"model_name":model_name,"message":"Deep Learning FTW!"}ifmodel_name.value=="lenet":return{"model_name":model_name,"message":"LeCNN all the images"}return{"model_name":model_name,"message":"Have some residuals"}
На стороні клієнта Ви отримаєте відповідь у форматі JSON, наприклад:
OpenAPI не підтримує спосіб оголошення параметра шляху, що містить шлях всередині, оскільки це може призвести до сценаріїв, які складно тестувати та визначати.
Однак (одначе), Ви все одно можете зробити це в FastAPI, використовуючи один із внутрішніх інструментів Starlette.
Документація все ще працюватиме, хоча й не додаватиме опису про те, що параметр повинен містити шлях.