From 421183b7e3b79ca549c70c21269eeeaa6dd0214e Mon Sep 17 00:00:00 2001 From: apuc Date: Mon, 7 Sep 2026 19:03:40 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20README=20=D1=81=20=D0=B8=D0=BD=D1=81=D1=82=D1=80=D1=83?= =?UTF-8?q?=D0=BA=D1=86=D0=B8=D0=B5=D0=B9=20=D0=BF=D0=BE=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B7=D0=B2=D1=91=D1=80=D1=82=D1=8B=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..f4a5454 --- /dev/null +++ b/README.md @@ -0,0 +1,146 @@ +# Диагностика по видео (ФПГ 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`): + +```bash +pip install --user flask waitress websockets requests reportlab python-docx +``` + +Шрифты DejaVu для кириллицы в PDF (обычно уже есть в системе): +```bash +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. Клонирование и структура + +```bash +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`: + +```ini +[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 +``` + +```bash +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`: + +```nginx +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. Обновление кода + +```bash +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/` | Публичная страница результата (с OG-тегами) | +| `/download//pdf` | Экспорт в PDF | +| `/download//docx` | Экспорт в DOCX | +| `/download//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.`, 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. +- Дисклеймер «не медицинский диагноз» — во всех отчётах и на страницах. \ No newline at end of file