Диагностика по видео (ФПГ GigaDoc)

Веб-приложение: пользователь загружает или записывает видео с лицом → система извлекает кадры → отправляет в SDK ФПГ (GigaDoc) → показывает понятный диагноз с сохранением в SQLite, share-ссылками, экспортом PDF/DOCX и скачиванием записанного видео.

Требования (проверено на сервере)

Компонент Версия
Python 3.10.10
ffmpeg 4.2.7 (нужен для извлечения кадров)
Flask 3.1.1
waitress 3.0.2
websockets 10.4 (важно: API extra_headers/origin появился в 10.x)
requests 2.28.2
reportlab 5.0.1 (PDF-экспорт, кириллица через DejaVu)
python-docx 1.2.0 (DOCX-экспорт)

Установка зависимостей (на сервере venv могут быть сломаны — ставится через pip install --user):

pip install --user flask waitress websockets requests reportlab python-docx

Шрифты DejaVu для кириллицы в PDF (обычно уже есть в системе):

apt list --installed 2>/dev/null | grep fonts-dejavu || sudo apt install -y fonts-dejavu

Переменные окружения (секреты!)

Секреты не хранятся в репозитории — задаются через окружение:

Переменная Описание
FPG_CLIENT_ID client_id для OAuth SDK ФПГ (по умолчанию client_fpg_front)
FPG_CLIENT_SECRET client_secret для OAuth SDK ФПГ (обязательна, без неё авторизация не работает)

Развёртывание

1. Клонирование и структура

sudo mkdir -p /opt/med && sudo chown $USER:$USER /opt/med
git clone https://git.itguild.info/apuc/sber_med.git /opt/med
cd /opt/med
mkdir -p templates static videos

Приложение само создаёт при старте:

  • videos/ — сохранённые записи сканирования (рядом с app.py)
  • results.db — SQLite с результатами (share_id начиная с 10005)

2. Systemd-сервис

/etc/systemd/system/med.service:

[Unit]
Description=Med Diagnostics (FPG GigaDoc)
After=network.target

[Service]
Type=simple
User=apuc
WorkingDirectory=/opt/med
Environment=PYTHONUNBUFFERED=1
Environment=FPG_CLIENT_ID=client_fpg_front
Environment=FPG_CLIENT_SECRET=ВАШ_СЕКРЕТ
ExecStart=/usr/bin/python3 -c "from waitress import serve; from app import app; serve(app, host='127.0.0.1', port=8063, threads=8)"
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now med.service
sudo systemctl status med.service

3. Nginx (HTTPS)

/etc/nginx/sites-enabled/med.my-dpr.ru:

server {
    server_name med.my-dpr.ru;

    client_max_body_size 100M;   # видео до 100 МБ

    location / {
        proxy_pass http://127.0.0.1:8063;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 60s;
        client_body_timeout 300s;   # важно: мобильная сеть может загружать медленно
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/med.my-dpr.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/med.my-dpr.ru/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}

Сертификат: sudo certbot --nginx -d med.my-dpr.ru

4. Обновление кода

cd /opt/med && git pull
sudo systemctl restart med.service

Маршруты

Маршрут Описание
/ Главная: загрузка файла или сканирование с камеры
/analyze (POST) Принимает video (mp4/avi/mov/mkv/webm/m4v), возвращает диагноз + share_id/share_url/video_url
/r/<share_id> Публичная страница результата (с OG-тегами)
/download/<share_id>/pdf Экспорт в PDF
/download/<share_id>/docx Экспорт в DOCX
/download/<video_id>/video Скачивание записанного видео (есть даже при ошибке анализа)

Как работает анализ

  1. Видео сохраняется в videos/ (копия записи — доступна для скачивания)
  2. ffmpeg извлекает 300 кадров 1280×720 (bt709 + yuv420p — важно для iPhone MOV с P3/HDR)
  3. OAuth-токен → создание сессии → кадры по WebSocket (wss://gigadoc-sdk.sbermed.ai:8443, subprotocol bearer.<token>, Origin https://gigadoc.sbermed.ai)
  4. Интерпретация JSON SDK → summary/metrics/warnings/advice → сохранение в SQLite

Важные нюансы

  • SDK ФПГ не находит лицо на кадрах 640×480 — нужны кадры 1280×720.
  • Камерное сканирование (мобильные): canvas 720×720 (квадрат, без обрезки головы), MediaRecorder с битрейтом 1.5 Мбит/с (~1–2 МБ за 310 кадров), автоповтор fetch до 3 попыток при обрыве сети.
  • iOS MediaRecorder пишет mp4 (webm может не поддерживаться) — расширение выбирается из blob.type.
  • Порт 5000 на сервере занят другим сервисом — приложение слушает 8063.
  • Дисклеймер «не медицинский диагноз» — во всех отчётах и на страницах.
S
Description
No description provided
Readme
102 KiB
Languages
Python 70.6%
HTML 29.4%