Перейти к основному содержимому

2. Cameras

Для работы с камерами обязательно использование токена авторизации, если в документации конкретного эндпоинта не указано иное.

2.1 GET /cameras

Возвращает список всех зарегистрированных камер.

Используется для получения каталога камер и отображения их в интерфейсе labeler.

Query-параметры (необязательные)

  • q (string) — фильтр по подстроке в title.
  • top_left_corner_latitude* (float, -90..90) — широта левого верхнего угла окна просмотра камер.
  • top_left_corner_longitude* (float, -180..180) — долгота левого верхнего угла окна просмотра камер.
  • bottom_right_corner_latitude* (float, -90..90) — широта правого нижнего угла окна просмотра камер.
  • bottom_right_corner_longitude* (float, -180..180) — долгота правого нижнего угла окна просмотра камер.

* - Поддержка этих полей необязательна для создания MVP, но может потребоваться в дальнейшей разработке.

Response (200) Список объектов Camera.

Модель Camera

  • camera_id (integer) — уникальный идентификатор камеры.
  • title (string) — человекочитаемое описание камеры (адрес/куда смотрит).
  • source (string) — URL с видеопотоком камеры (напр. .m3u8) или строка для подключения (rtsp://...)
  • image_width (integer) — ширина изображения видеопотока в пикселях (напр., 1920)
  • image_height (integer) — высота изображения видеопотока в пикселях (напр., 1080)
  • calib (json) — вложенный json-объект с информацией о калибровке и вытягивании изображения с камеры. Сохраняется в одну ячейку таблицы БД. Может быть null.
  • latitude (float, -90..90) — широта камеры.
  • longitude (float, -180..180) — долгота камеры.
  • created_at (string, ISO 8601) — дата создания.
  • updated_at (string, ISO 8601) — дата обновления.

Пример запроса

GET /api/v0/cameras?q=просп HTTP/1.1
Host: api.parktrack.live
Authorization: Bearer <token>

Пример ответа (массив)

[
  {
    "camera_id": 1,
    "title": "Кронверкский просп., парковка напротив ИТМО",
    "source": "rtsp://...",
    "image_width": 1920,
    "image_height": 1080,
    "calib":     {
      "image_width": 1920,
      "image_height": 1080,
      "K":       [
        [
          1739.237279181759,
          0,
          947.5335576199107
        ],
        [
          0,
          2244.705015334057,
          564.6946579168148
        ],
        [
          0,
          0,
          1
        ]
      ],
      "D":       [
        -0.37062084436192333,
        0.05057465862770827,
        0.033198096980616335,
        0.012812747166936252
      ],
      "balance": 0,
      "model": "opencv_fisheye_k1k2k3k4"
    },
    "latitude": 59.955976,
    "longitude": 30.309426,
    "created_at": "2025-10-08T09:12:00Z",
    "updated_at": "2025-10-08T09:12:00Z"
  },
  {
    "camera_id": 2,
    "title": "Ломоносова, 9 — двор",
    "source": "https://... .m3u8",
    "image_width": 1920,
    "image_height": 1080,
    "calib": null,
    "latitude": 59.927366,
    "longitude": 30.338487,
    "created_at": "2025-10-08T09:15:00Z",
    "updated_at": "2025-10-08T09:15:00Z"
  }
]

Ошибки (в дополнение к общим)

КодТипОписание
422Unprocessable EntityВалидация не пройдена (например, координаты верхнего левого угла находятся правее или ниже координатов нижнего правого угла окна просмотра).

2.2 POST /cameras/new

Создаёт новую камеру.

Request body (required)

  • title (string, 1..200) — описание камеры (по какому адресу она находится и куда направлена).
  • source (string) — URL с видеопотоком камеры (напр. .m3u8) или строка для подключения (rtsp://...)
  • image_width" (integer) — ширина изображения видеопотока в пикселях (напр., 1920)
  • image_height (integer) — высота изображения видеопотока в пикселях (напр., 1080)
  • calib (json) — вложенный json-объект с информацией о калибровке и вытягивании изображения с камеры. Сохраняется в одну ячейку таблицы БД. Может быть null.
  • latitude (float, -90..90) — широта камеры.
  • longitude (float, -180..180) — долгота камеры.

Подсказки по валидации

  • Пустая строка или длина >200 символов — ошибка.

Response (201)

  • camera_id (integer) — числовой идентификатор созданной камеры.

Пример запроса

POST /api/v0/cameras/new HTTP/1.1
Host: api.parktrack.live
Content-Type: application/json
Authorization: Bearer <token>
{
  "title": "Кронверкский просп., парковка напротив ИТМО",
  "source": "https://... .m3u8",
  "image_width": 1920,
  "image_height": 1080,
  "calib": null,
  "latitude": 59.955976,
  "longitude": 30.309426
}

**Пример ответа (201)**
```json
{
"camera_id": 1
}

Ошибки (в дополнение к общим)

КодТипОписание
409ConflictКамера с таким title уже существует. Измени title или используй существующую камеру.
422Unprocessable EntityВалидация не пройдена (например, title пустой или слишком длинный). Исправь данные: title 1..200 символов.

Формат тела ошибки (рекомендуется)

{
"error_description": "title must be a non-empty string up to 200 chars"
}

Примеры неуспешных запросов

Неверный Content-Type

POST /api/v0/cameras/new HTTP/1.1
Content-Type: text/plain

Ответ (415)

{ "error_description": "Unsupported Media Type: expected application/json" }

Пустой title

POST /api/v0/cameras/new HTTP/1.1
Content-Type: application/json

{ "title": "" }

Ответ (422)

{
"error_description": "Validation error. Empty title"
}

Дубликат

POST /api/v0/cameras/new HTTP/1.1
Content-Type: application/json

{ "title": "Кронверкский просп., парковка напротив ИТМО", "latitude": 59.955976, "longitude": 30.309426 }

Ответ (409)

{
"error_description": "Camera with this title already exists"
}

2.3 GET /cameras/<camera_id>

Возвращает подробную информацию о конкретной камере.

Path-параметры

  • camera_id (integer, required) — идентификатор камеры.

Headers

  • Authorization: Bearer <token>

Response (200) — объект Camera

  • camera_id (integer) — уникальный идентификатор камеры.
  • title (string) — человекочитаемое описание камеры (адрес/куда смотрит).
  • source (string) — URL с видеопотоком камеры (напр. .m3u8) или строка для подключения (rtsp://...)
  • image_width" (integer) — ширина изображения видеопотока в пикселях (напр., 1920)
  • image_height (integer) — высота изображения видеопотока в пикселях (напр., 1080)
  • calib (json) — вложенный json-объект с информацией о калибровке и вытягивании изображения с камеры. Сохраняется в одну ячейку таблицы БД. Может быть null.
  • latitude (float, -90..90) — широта камеры.
  • longitude (float, -180..180) — долгота камеры.
  • created_at (string, ISO 8601) — дата создания.
  • updated_at (string, ISO 8601) — дата обновления.

Пример запроса

GET /api/v0/cameras/1 HTTP/1.1
Host: api.parktrack.live
Authorization: Bearer <token>

Пример ответа (200)

{
  "camera_id": 1,
  "title": "Кронверкский просп., парковка напротив ИТМО",
  "source": "https://... .m3u8",
  "image_width": 1920,
  "image_height": 1080,
  "calib": null,
  "latitude": 59.955976,
  "longitude": 30.309426,
  "created_at": "2025-10-08T08:00:00Z",
  "updated_at": "2025-10-08T08:10:00Z"
}

Ошибки (в дополнение к общим)

КодТипОписание
404Not FoundКамера с таким camera_id не найдена.

2.4 PUT /cameras/<camera_id>

Обновляет данные камеры. Допускается частичное обновление (поля, которых нет в теле, не меняются).

Path-параметры

  • camera_id (integer, required) — идентификатор камеры.

Headers

  • Content-Type: application/json
  • Authorization: Bearer <token>

Request body (любые из полей ниже; минимум одно поле)

  • title (string, 1..200) — описание камеры.
  • source (string) — URL с видеопотоком камеры (напр. .m3u8) или строка для подключения (rtsp://...)
  • image_width" (integer) — ширина изображения видеопотока в пикселях (напр., 1920)
  • image_height (integer) — высота изображения видеопотока в пикселях (напр., 1080)
  • calib (json) — вложенный json-объект с информацией о калибровке и вытягивании изображения с камеры. Сохраняется в одну ячейку таблицы БД. Может быть null.
  • latitude (float, -90..90) — широта камеры.
  • longitude (float, -180..180) — долгота камеры.

Серверные поля camera_id, created_at, updated_at изменяются/устанавливаются сервером и в теле запроса игнорируются.

Response (200) — объект Camera (актуальное состояние после обновления)

  • camera_id (integer)
  • title (string)
  • source (string)
  • image_width" (integer)
  • image_height (integer)
  • calib (json)
  • latitude (float)
  • longitude (float)
  • created_at (string, ISO 8601)
  • updated_at (string, ISO 8601)

Пример запроса — полное обновление

PUT /api/v0/cameras/1 HTTP/1.1
Host: api.parktrack.live
Content-Type: application/json
Authorization: Bearer <token>

{
"title": "Кронверкский просп., камера №1 (в сторону парка)",
"latitude": 59.955980,
"longitude": 30.309430
}

Пример запроса — частичное обновление (только title)

PUT /api/v0/cameras/1 HTTP/1.1
Host: api.parktrack.live
Content-Type: application/json
Authorization: Bearer <token>

{
"title": "Кронверкский просп., парковка напротив ИТМО (обновлено)"
}

Пример ответа (200)

{
"camera_id": 1,
"title": "Кронверкский просп., камера №1 (в сторону парка)",
"latitude": 59.95598,
"longitude": 30.30943,
"created_at": "2025-10-08T08:00:00Z",
"updated_at": "2025-10-08T09:02:11Z"
}

Ошибки (в дополнение к общим)

КодТипОписание
404Not FoundКамера с таким camera_id не найдена.
409ConflictКонфликт уникальности title.
422Unprocessable EntityВалидация не пройдена: title пустой или >200; latitude вне [-90, 90]; longitude вне [-180, 180].

Формат тела ошибки

{
"error_description": "Validation error: latitude must be between -90 and 90"
}

2.5 DELETE /cameras/<camera_id>

Удаляет камеру и все связанные с ней парковочные зоны и данные (при их наличии). Действие необратимо.

Path-параметры

  • camera_id (integer, required) — идентификатор камеры.

Headers

  • Authorization: Bearer <token>

Response (204) — камера успешно удалена, тело отсутствует.

Пример запроса

DELETE /api/v0/cameras/1 HTTP/1.1
Host: api.parktrack.live
Authorization: Bearer <token>

Ошибки

КодТипОписание
404Not FoundКамера с указанным camera_id не найдена.
409ConflictУдаление невозможно из-за зависимостей (есть парковочные зоны с этой камерой).

Пример ответа (404)

{
"error_description": "Camera not found"
}

2.6 GET /cameras/next

Возвращает следующую камеру для очередной детекции автомобилей.

Примеры:

  1. Если в прошлый раз этот эндпоинт вернул камеру с id=1, то вернуться должна камера с id=2;
  2. Если всего камер 3 и последний раз возвращалась камера с id=3, то вернуться должна камера с id=1.

Headers

  • Authorization: Bearer <token>

Пример запроса

GET /api/v0/cameras/next HTTP/1.1
Host: api.parktrack.live
Authorization: Bearer <token>

Пример ответа 1 (200)

{
"camera_id": 1,
"source": "https://<path>.m3u8",
"image_width": 1920,
"image_height": 1080,
"calib": null
}

Пример ответа 2 (200)

{
"camera_id": 1,
"source": "https://<path>.m3u8",
"image_width": 1920,
"image_height": 1080,
"calib": null
}

Ошибки

КодТипОписание
404Not FoundНе добавлено ни одной камеры

Пример ответа (404)

{
"error_description": "No cameras added"
}

2.7 GET /cameras/<camera_id>/snapshot

Возвращает кадр из видеопотока камеры (изображение, захваченное из source камеры).

Headers

  • Authorization: Bearer <token>

Пример запроса

GET /cameras/1/snapshot
Host: api.parktrack.live
Authorization: Bearer <token>

Пример ответа (200)

<изображение>

Ошибки

КодТипОписание
404Not FoundТакой камеры нет

Пример ответа (404)

{
"error_description": "Camera not found"
}