FastAPI в Serverless-функции
У меня уже есть пост про то как запустить FastAPI в Serverless контейнере на Yandex Cloud, а также пост как в функции запустить популярные JS фреймворки. Пришло время взять понемногу из этих постов и запустить FastAPI в Serverless функции. Для этого нам понадобится python библиотека Mangum. Она не сказать что очень активно поддерживается. Это заметно и по истории коммитов и по тому что они упустили домен, где была документация и теперь там лежит рекламный блог. Недавно разработку подхватил другой разработчик. Восстановил документацию и это дает надежду на то что проект будет развиваться дальше.
Установка
pip install mangum
Также не забудьте добавить FastAPI и Mangum в ваш requirements.txt
.
fastapi
mangum
Пример
from mangum import Mangum
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
return {"item_id": item_id, "q": q}
handler = Mangum(app)
В принципе это почти всё, что нужно. Единственное, что нужно сделать, чтобы этот пример заработал в Yandex Cloud это поставить нашу функцию за API Gateway. Это нужно потому что адаптер Mangum ожидает на вход event в формате AWS. В Yandex Cloud это будет выглядеть так:
openapi: 3.0.0
info:
title: Sample API
version: 1.0.0
paths:
/:
x-yc-apigateway-any-method:
x-yc-apigateway-integration:
payload_format_version: '1.0'
function_id: d4e**************
tag: $latest
type: cloud_functions
Обратите внимание на строчку 9 payload_format_version: '1.0'
. Это нужно для того, чтобы указать API Gateway, что
функцию нужно вызывать с событием в формате AWS. Пример события:
{
"version": <версия формата запроса>,
"resource": <ресурс, соответствующий запросу в спецификации>,
"path": <фактический путь запроса>,
"httpMethod": <название HTTP-метода>,
"headers": <словарь со строковыми значениями HTTP-заголовков>,
"multiValueHeaders": <словарь со списками значений HTTP-заголовков>,
"queryStringParameters": <словарь queryString-параметров>,
"multiValueQueryStringParameters": <словарь списков значений queryString-параметров>,
"requestContext": <словарь с контекстом запроса>,
"pathParameters": <словарь значений параметров пути запроса>,
"body": <содержимое запроса>,
"isBase64Encoded": <true или false>,
// дополнительные поля:
"parameters": <словарь значений параметров запроса, описанных в спецификации OpenAPI>,
"multiValueParameters": <словарь со списками значений параметров запроса, описанных в спецификации OpenAPI>,
"operationId": <operationId, соответствующий запросу в спецификации OpenAPI>
}
Если этого не сделать, то в параметр path
будет передан не фактический путь запроса, а путь из спецификации. Например:
paths:
/{files+}:
get:
...
Для такой спецификации в параметр path
будет передано /{files+}
вместо фактического пути запроса. Поэтому очень
важно указать payload_format_version: '1.0'
, совместимый с AWS.
Жадные параметры
Если вы не хотите описывать все пути в спецификации, то можно использовать жадные параметры. Например:
openapi: 3.0.0
info:
title: Sample API
version: 1.0.0
paths:
/{proxy+}:
x-yc-apigateway-any-method:
parameters:
- name: proxy
in: path
required: true
schema:
type: string
x-yc-apigateway-integration:
payload_format_version: '1.0'
function_id: d4e**************
tag: $latest
type: cloud_functions
Заключение
Mangum позволяет запустить FastAPI в Serverless функции. Для его корректной работы в Yandex Cloud нужен правивильно настроенный API Gateway. В принципе это всё, что нужно для того, чтобы запустить FastAPI в Serverless функции.