Первый работающий API

Path-параметры и типы

Содержание курса

Поиск по id: существующий ключ и KeyError

Допустим, у нас есть каталог из двух переговорных комнат, хранящийся в словаре с целочисленными ключами:

from fastapi import FastAPI

app = FastAPI()

rooms_by_id = {
    1: {"id": 1, "name": "Лондон", "floor": 2},
    2: {"id": 2, "name": "Берлин", "floor": 3},
}

@app.get("/api/rooms")
def list_rooms():
    return list(rooms_by_id.values())

@app.get("/api/rooms/{room_id}")
def get_room(room_id: int):
    return rooms_by_id[room_id]

GET /api/rooms/1 вернёт {"id": 1, "name": "Лондон", "floor": 2}. FastAPI преобразует "1" в 1, функция обращается к словарю по ключу 1 — всё работает.

GET /api/rooms/abc — 422 ещё до словаря, как разобрали выше.

GET /api/rooms/999 — интереснее. Строка "999" успешно преобразуется в int, проверка типа пройдена. Но ключа 999 в rooms_by_id нет. Python выбросит KeyError, FastAPI не поймает его автоматически, и клиент получит 500 Internal Server Error.

Вот принципиальное различие: аннотация int гарантирует только форму значения — что оно целое число. Она ничего не знает о содержимом словаря. Проверка типа и проверка существования записи — два независимых шага. Первый делает FastAPI, второй — ваш код.