Как создать API на Python без усилий на деплой

Аватарка пользователя Елена Капаца

Разобрали на примере, как создать API на Python: выполнили деплой приложения на FastAPI, создали GET-запрос

Обложка поста Как создать API на Python без усилий на деплой

Разработчики нередко приходят к мысли создать API на Python (англ. Application Programming Interface — программный интерфейс приложения). Если вы лишь недавно повстречались с этим термином, обладаете идеей для своего такого ПО и хотите разобраться, как устроено содержимое проекта, статья познакомит с базовой терминологией и проведет от первого шага с подключением фреймворка FastAPI и до HTTP-запроса.

Немного про HTTP

Для тех, кто не знаком с концепцией, расскажу вкратце: это способ обмена данными от сервера к клиенту и обратно. Мы пользуемся им каждый день в подавляющем большинстве сервисов:

Как создать API на Python без усилий на деплой 1

Этот «протокол передачи гипертекста» (англ. HyperText Transfer Protocol) стал популярен в 90-х и сегодня де-факто является стандартом обмена между устройствами. Развертывая простенький проект на Django, вы тоже, кстати, пользуетесь HTTP.

Если вам интересна миграция с low-code CMS на Django, изучите эту статью.

Вы наверняка уже слышали про классические типы запросов: GET (получить) и POST (создать). Среди прочих выделю еще DELETE (удалить), INSERT (вставить) и UPDATE (обновить). Один из них мы реализуем своими руками в этом гайде.

Как создать API на Python без усилий на деплой 2

Деплой FastAPI на Railway

Чтобы вы могли быстрее пощупать новоиспеченное ПО, я использую фреймворк FastAPI. Создавая проект на его базе, вы подключите автоматом:

  • main.py — главный для разработчика файл, ответственный за HTTP-запросы;
  • requirements.txt, содержащий список всех необходимых сторонних инструментов с версиями;
  • .gitignore, описывающий файлы, которые при коммите стоит игнорировать, например, директорию виртуального окружения;
  • railway.json помогает серверу схватить настройки проекта и запускать API автоматически после каждого обновления.

Клонировав этот код с маркетплейса, вы найдете все необходимое, чтобы сдружиться с Railway. Это условно бесплатный сервис для развертывания ваших приложений, то есть круглосуточно доступный сервер. Он пришел отчасти на замену Heroku и предлагает любому пользователю 5 демо-долларов, которые расходуются довольно медленно, по паре центов в день.

Как создать API на Python без усилий на деплой 3

В следующие 3-5 минут проект саморазвернется: установятся библиотеки, настроится триггер для пересборки API в случае коммита. Давайте вместе пройдемся по логам и научимся их читать при проблемах в будущем:

Первое, что отдает нам Railway — это перечень запускаемых команд:

			╔══════════════════════════════ Nixpacks v1.19.0 ══════════════════════════════╗

║ setup      │ python38, gcc                                                   ║

║──────────────────────────────────────────────────────────────────────────────║

║ install    │ python -m venv --copies /opt/venv && . /opt/venv/bin/activate   ║

║            │ && pip install -r requirements.txt                              ║

║──────────────────────────────────────────────────────────────────────────────║

║ start      │ hypercorn main:app --bind "[::]:$PORT"                          ║

╚══════════════════════════════════════════════════════════════════════════════╝
		

Затем устанавливаются все необходимые библиотеки:

			#10 8.082 Collecting anyio<5,>=3.4.0

#10 8.093   Downloading anyio-4.1.0-py3-none-any.whl (83 kB)

 

#10 8.100      ━━━━━━━━━━━━━━━━━━━━━━ 83.9/83.9 kB 21.1 MB/s eta 0:00:00
		

Система уведомляет об успешно установленных инструментах:

			#10 9.476 Successfully installed annotated-types-0.6.0 anyio-4.1.0 exceptiongroup-1.2.0 fastapi-0.100.0 h11-0.14.0 h2-4.1.0 hpack-4.0.0 hypercorn-0.14.4 hyperframe-6.0.1 idna-3.6 priority-2.0.0 pydantic-2.5.2 pydantic-core-2.14.5 sniffio-1.3.0 starlette-0.27.0 tomli-2.0.1 typing-extensions-4.8.0 wsproto-1.2.0
		
Если вы намереваетесь повторить мой путь с другим шаблоном, то наверняка столкнетесь с крушением билда. Сборки устаревают быстро, конфликт зависимостей никто не отменял, и прежде чем темплейт заработал, мне пришлось пройти 4 попытки по другим ссылкам.

Деплой успешно выполнен:

Как создать API на Python без усилий на деплой 4

В разделе Settings блока FastAPI вы найдете перманентный URL, ведущий на поддомен Railway. Он позволит обращаться к вашему API с любого устройства:

Как создать API на Python без усилий на деплой 5

По умолчанию в главном файле проекта из методов только / (root-метод). Выглядит он таким образом, вскоре мы познакомимся поближе:

			@app.get("/")
async def root():
    return {"greeting": "Hello, World!", "message": "Welcome to FastAPI!"}
		

Перейдя по ссылке fastapi-production-fd50.up.railway.app я получу hello-world-приветствие:

Как создать API на Python без усилий на деплой 6

Cоздаем глагол GET

Для разработки собственных методов мне понадобится запустить этот же проект на ноутбуке. Потому теперь я клонирую себе репозиторий (он добавился в листинг моего аккаунта на GitHub):

Как создать API на Python без усилий на деплой 7

Открыв эту новую директорию в VSCode, создаю виртуальное окружение и устанавливаю инструменты:

			python3 -m venv fastapi_env
pip3 install -r requirements.txt
		

Чтобы файлы fastapi_env не попали в репозиторий и не усложнили тем самым чтение коммита, исключим эту подпапку с помощью .gitignore, добавив строку:

			fastapi_env\
		

Для запуска API в режиме отладки на своей машине используется специальная утилита hypercorn:

			hypercorn main:app --reload
		

Теперь тот же root-метод доступен по адресу 127.0.0.1:8000:

Как создать API на Python без усилий на деплой 8

Чтобы от гайд был полезнее, я использую пример из своей практики. При каждодневной выгрузке логов разговоров с моим ботом мне приходится указывать временной интервал.

			payload = {"filters": [{"key": "MESSAGE_TIME", "type": "DATE_TIME_RANGE", "from": "2023-11-17T20:59:99.999Z", "to": "2023-11-18T20:59:99.999Z"}]}
		

Это тело запроса для библиотеки requests, и оно содержит смещение (сервер расположен где-то в UTC±0:00, то есть полночь там наступает на три часа раньше, чем в Москве):

Как создать API на Python без усилий на деплой 9

Каждый раз обсчитывать смещение при тестах неудобно, особенно, когда выгружаешь логи за период, не равный 24 часам. Так что давайте создадим метод, чтобы рассчитывал смещение. Для этого в main.py добавлю декоратор @app.get("/get") (на самом деле, вместо get можно поставить любое слово) и функцию get_time():

			...

import datetime
from datetime import timedelta

...
today = datetime.today().date()
yesterday = today - timedelta(days=7)

...
@app.get("/get")
async def get_time():
    return {"time": datetime.datetime.now() - timedelta(hours=3, minutes=0)}
		

Первый собственный метод готов. Теперь проверим его работу, перейдя по ссылке http://127.0.0.1:8000/get:

Как создать API на Python без усилий на деплой 10

Создав коммит с такой функцией, вы получите автоматический редеплой от Railway и работающий метод /get по ссылке fastapi-production-fd50.up.railway.app/get. Вместо datetime.datetime.now() несложно подставить другое интересующее время и получить смещение от него.

Как создать API на Python без усилий на деплой 11

Заключение

Практика показывает: найти реальную причину для своего API сложнее, чем создать его. Давайте повторим: для собственного API вам потребуется:

  • Найти сервер, на котором интерфейс будет базироваться. Свой ноутбук — это не сервер для продакшена;
  • Выбрать фреймворк для API (например, FastAPI / litestar);
  • Создать проект фреймворка по документации или с темплейта и развернуть его на сервере;
  • Описать собственные методы;
  • Погордиться собой, ведь свой эндпоинт — это очень круто!

Познакомиться с моим проектом вы можете на GitHub.

Какой сервис для деплоя вы предпочитаете?
Railway
Сам настраиваю VPS
Другое (укажите в комментариях)
API
Python
1521