Создание API с использованием FastAPI для модели классификации, созданной с использованием pycaret

Я использую pycaret в качестве рабочего процесса машинного обучения, я пытался создать API с помощью FastAPI. Я впервые играю на производственном уровне, поэтому меня немного смущает API.

У меня есть 10 функций; age: float, live_province: str, live_city: str, live_area_big: str, live_area_small: str, sex: float, marital: float, bank: str, salary: float, amount: float и метка, содержащая двоичное значение (0 и 1).

Это мой скрипт для создания API.

from pydantic import BaseModel
import numpy as np
from pycaret.classification import *

import uvicorn
from fastapi import FastAPI

app = FastAPI()

model = load_model('catboost_cm_creditable')

class Data(BaseModel):
    age: float
    live_province: str
    live_city: str
    live_area_big: str
    live_area_small: str
    sex: float
    marital: float
    bank: str
    salary: float
    amount: float

input_dict = Data

@app.post("/predict")
def predict(model, input_dict):
    predictions_df = predict_model(estimator=model, data=input_dict)
    predictions = predictions_df['Score'][0]
    return predictions

Когда я пытался бежать uvicorn script:app и перешел в документацию, я не могу найти параметр для своих функций, параметры показывают только модель и input_dict

Как включить мои функции в параметры в API?

2 ответа

Вам нужно ввести подсказку для вашей модели Pydantic, чтобы она работала с вашим FastAPI

Представьте, что вы действительно работаете со стандартным Python, когда вам нужно задокументировать эту функцию,

def some_function(price: int) ->int:
    return price

С Pydantic нет ничего, кроме приведенного выше примера.

Ваш class Data на самом деле питон @dataclass со сверхспособностями (происходит от Pydantic)

from fastapi import Depends

class Data(BaseModel):
    age: float
    live_province: str
    live_city: str
    live_area_big: str
    live_area_small: str
    sex: float
    marital: float
    bank: str
    salary: float
    amount: float


@app.post("/predict")
def predict(data: Data = Depends()):
    predictions_df = predict_model(estimator=model, data=data)
    predictions = predictions_df["Score"][0]
    return predictions

Есть одна маленькая хитрость: с Depends вы получите отдельные запросы, например, когда вы определяете каждое поле по отдельности.

С зависимостями

Без зависимостей

Ваша проблема связана с определением функции API. Вы добавили аргумент для ввода данных, но не указали FastAPI его тип. Также я предполагаю, что вы имеете в виду не использовать модель, которую вы загрузили глобально, вместо того, чтобы получить ее в качестве параметра. Также вам не нужно создавать глобальный экземпляр для ваших входных данных, поскольку вы хотите получить его от пользователя.

Поэтому просто измените подпись своей функции на:

def predict(input_dict: Data):

и удалите строку:

input_dict = Data

(Это просто создает псевдоним для вашего класса Data, названный input_dict)

В итоге вы получите:

app = FastAPI()

model = load_model('catboost_cm_creditable')

class Data(BaseModel):
    age: float
    live_province: str
    live_city: str
    live_area_big: str
    live_area_small: str
    sex: float
    marital: float
    bank: str
    salary: float
    amount: float

@app.post("/predict")
def predict(input_dict: Data):
    predictions_df = predict_model(estimator=model, data=input_dict)
    predictions = predictions_df['Score'][0]
    return predictions

Также я бы порекомендовал изменить название класса Data к чему-то более ясному и легкому для понимания, даже DataUnit было бы лучше на мой взгляд как Data слишком общий.

Другие вопросы по тегам