Распространенным способом развертывания наших моделей машинного обучения является предоставление их через API веб-службы REST. И поскольку наша цель не создание веб-инструментов, мы предпочитаем использовать хорошо протестированную, готовую к использованию структуру, чтобы сократить время выхода на рынок.
При выборе фреймворка мы хотим получить правильный баланс между производительностью и производительностью. Обычно, если инструмент более специфичен и ближе к голому металлу, он будет работать лучше. Однако низкоуровневые библиотеки оставляют нам большую часть работы. С другой стороны, если фреймворк предоставляет слишком много абстракций, это может снизить производительность.
В этой статье кратко обсуждаются пять причин для принятия FastAPI в качестве основы для нашего REST API, а также причины, по которым он обеспечивает выдающийся баланс между производительностью и производительностью.
1. Высокая производительность
Согласно тесту TechEmpower, FastAPI — одна из самых быстрых доступных платформ Python, а ее производительность сопоставима с платформами NodeJS и Go.
2. Декларативная маршрутизация
Создавать маршруты и конечные точки с помощью FastAPI очень просто. Мы включаем декоратор вокруг метода, и он будет работать по пути, указанному в аргументе декоратора:
@app.post("/diabetes:predict") def predict(p): return __predict_batch([p])[0]
Чтобы получить параметр пути, нам нужно объявить имя параметра пути в шаблоне пути, а затем объявить параметр метода с тем же именем:
@app.get("/patients/{patient_id}") def get_patient(patient_id): pass
Любой другой параметр, объявленный в сигнатуре метода, обрабатывается как параметр запроса. Если метод имеет типизированные параметры, FastAPI автоматически преобразует параметры строки запроса в нужный тип. В приведенном ниже примере конечная точка поддерживает параметры «размер» и «страница», поэтому платформа автоматически преобразует параметры запроса в их правильный тип:
@app.get("/patients") def get_patient(page: int, size: int): pass
С FastAPI мы объявляем маршруты и их параметры близко к методу, который обслуживает конечную точку. Мы также получаем параметры маршрута непосредственно в параметрах метода, поэтому нам не нужно проверять общие структуры данных, чтобы находить и проверять параметры, что повышает нашу производительность.
3. Автоматическая сериализация и десериализация
FastAPI автоматически десериализует тела запросов в параметры метода. Чтобы получить тело запроса как объект в нашем методе, нам нужно создать класс модели Pydantic и объявить эту модель как тип нашего параметра. Например:
from pydantic import BaseModel class Patient(BaseModel): name: str address: str @app.post("/patients") def save_patient(patient: Patient): pass
С другой стороны, можно автоматически сериализовать модель в формат JSON, просто вернув объект. Например:
@app.get("/patient/{patient_id}") def save_patient(patient_id): return Patient('John Smith', '99 Nowhere Street')
Таким образом, с FastAPI нам не нужно беспокоиться об обработке сериализации и десериализации в нашем бизнес-коде.
4. Декларативная проверка
Поскольку у нас есть декларативная маршрутизация, мы проверяем наши параметры, объявляя их допустимые значения, вместо того, чтобы писать логику для их проверки. Первая альтернатива, в которой мы получаем автоматическую проверку, — это объявление типов параметров в сигнатуре метода. В следующем примере попытка передать аргумент, не являющийся целым числом, на страницу параметров и размер приведет к ошибке клиента:
@app.get("/patients") def get_patient(page: int, size: int): pass
Однако недостаточно только проверки типов параметров. Нам также необходимо проверить допустимый диапазон для них. В предыдущем случае не имеет смысла иметь отрицательные значения или нуль для страницы и размера. Поэтому мы можем изменить наш метод, чтобы он принимал только положительные числа:
@app.get("/patients") def get_patient(\ page: int = Query(..., gt=0),\ size: int = Query(..., gt=0)): pass
Мы также можем установить валидаторы для наших моделей. Например, мы можем проверить, что имя поля модели Patient будет принимать только буквы и иметь максимальную длину 50 символов:
class Patient(BaseModel): name: str = Field(regex='[a-zA-Z\s]*', max_length=50) address: str
Используя декларативную проверку, мы резко сокращаем объем кода в нашем приложении, так как нам не нужно писать логику для проверки наших параметров. А поскольку мы можем писать валидацию проще и быстрее, мы значительно повышаем качество и безопасность нашего API.
5. Автоматическое создание документации
Хорошая документация — неотъемлемая часть отличного API. Однако для большинства разработчиков это утомительная задача, и во многих случаях они вообще не пишут никакой документации. Даже для тех, кто любит писать документацию, написание страницы документации отнимает много времени, что может быть проблемой в проекте с коротким сроком.
С FastAPI у нас есть отличная документация для нашего API без каких-либо значительных дополнительных усилий. Это связано с тем, что FastAPI автоматически создает страницу документации OpenAPI (Swagger) для нашего API и делает ее доступной по пути нашего приложения/doc. Документация, созданная FastAPI, включает:
- Конечные точки нашего API
- Параметры запроса и ответы
- Возвращаемые коды
- Схемы сущностей, используемые в запросах и ответах
- Интерфейс для тестирования нашего API
Вся информация, используемая для создания страницы документации, поступает из нашего кода. Нет необходимости писать дополнительные файлы или выполнять дополнительные команды для создания документов. Вы начинаете обслуживать приложение, и документация уже есть.
Вывод
FastAPI — это отличный фреймворк, предлагающий выдающийся баланс между производительностью и продуктивностью. Декларативный характер маршрутов и проверки в сочетании с автоматическими функциями, такими как сериализация и документирование, позволяет нам писать высококачественные API с гораздо меньшим количеством кода, чтобы мы могли сосредоточиться на наших моделях и бизнес-целях.
Чтобы узнать больше о FastAPI, посетите сайт:
Первоначально опубликовано на https://reinforcement-learning4.fun 30 декабря 2020 г.