docs: требования к Flask-приложению для Штурвала — health, no_cache, SSE, BOM, etc
Deploy drhider / validate (push) Waiting to run

This commit is contained in:
2026-07-14 21:58:56 +04:00
parent 8158a8bc01
commit 9b4060d8c5
+102
View File
@@ -178,6 +178,108 @@ api_bp.drhider()
│ → [(filename, bytes, mimetype), ...]
obfuscate_files(files, llm_client=LLMClient())
│ Scanner → Extractor → LLM NER → Obfuscator → Replacer → Builder
bytes (ZIP-архив с обезличенными документами + mapping.csv)
```
---
## Требования к Flask-приложению для Штурвала
### 1. `/health` — liveness probe
```python
@health_bp.route("/health")
def health():
return jsonify({"ok": True, "version": "0.0.26"})
```
**Обязательно.** Штурвал дёргает `/health` для readiness/liveness checks. Без этого под не поднимется. Ответ должен быть `200 OK`.
### 2. `no_cache` на все ответы
```python
@app.after_request
def no_cache(response):
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "0"
return response
```
**Критично для SPA-подобного UI.** Без этого nginx/браузер кэшируют страницу → F5 показывает старую версию, кнопки не работают, версия не обновляется.
### 3. `X-Accel-Buffering: no` для SSE
```python
return Response(
stream_with_context(generate()),
content_type="text/event-stream",
headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"}
)
```
**Критично для SSE-прогресса.** Без этого nginx буферизует поток → прогресс не отображается в реальном времени, все события приходят одним блоком в конце.
### 4. `MAX_CONTENT_LENGTH`
```python
app.config["MAX_CONTENT_LENGTH"] = 200 * 1024 * 1024 # 200 MB
```
Без этого Flask использует дефолтный лимит (~1MB) и отвергает docx/pdf.
### 5. `GeneratorExit` в SSE-генераторе
```python
try:
yield f"event: start\n..."
except GeneratorExit:
return # клиент отключился — не продолжаем обработку
```
**Критично.** При закрытии вкладки браузер рвёт SSE-соединение. Без `GeneratorExit` генератор продолжает слать запросы в LLM, тратя токены впустую.
### 6. `stream_with_context`
```python
from flask import stream_with_context
return Response(stream_with_context(generate()), ...)
```
**Обязательно для SSE.** Без этого Flask держит приложение заблокированным на время SSE-соединения, другие запросы не обрабатываются.
### 7. `sys.path` для импорта пакета drhider
```python
_sys_path_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if _sys_path_root not in sys.path:
sys.path.insert(0, _sys_path_root)
```
Штурвал запускает из `site/`, пакет `drhider/` на уровень выше. Без этого импорт не работает.
### 8. In-memory session storage
Сессии хранятся в `site/session.py` как `Dict[str, dict]`. **Не персистентны** — теряются при рестарте пода. Очистка по таймауту (2 часа).
### 9. LLM-клиент через переменные окружения
```python
LLM_KEY # API ключ
LLM_URL # эндпоинт (по умолчанию https://api.aillm.ru/v1/chat/completions)
LLM_MODEL # модель (по умолчанию gpt-oss-120b)
```
### 10. BOM в CSV
```python
buf.write('\ufeff'.encode('utf-8') + csv_str.encode('utf-8'))
```
BOM (`\ufeff`) нужен для корректного открытия CSV в Excel (чтобы русские буквы не ломались).
TwoPassObfuscator.obfuscate(files)