docs: миграция на tgFlaskForm и производительность Flask; контур flask_app; UI без лишних описаний
Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
.venv
|
||||
__pycache__
|
||||
*.pyc
|
||||
.env
|
||||
.git
|
||||
*.md
|
||||
@@ -0,0 +1,7 @@
|
||||
# Порт HTTP (не пересекать с :3107 текущего compose)
|
||||
PORT=3108
|
||||
FLASK_DEBUG=1
|
||||
SECRET_KEY=change-me-in-dev-only
|
||||
|
||||
# В Docker задайте WEB_USE_WAITRESS=1 (см. docker-compose.dev.yml)
|
||||
# WEB_USE_WAITRESS=1
|
||||
@@ -0,0 +1,21 @@
|
||||
# Новый Flask-контур (отдельный от Node/React). Dev: см. docker-compose.dev.yml
|
||||
FROM python:3.11-slim
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=1 \
|
||||
PORT=3108 \
|
||||
WEB_USE_WAITRESS=1 \
|
||||
FLASK_DEBUG=0
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY run.py .
|
||||
COPY app ./app
|
||||
|
||||
EXPOSE 3108
|
||||
|
||||
CMD ["python", "run.py"]
|
||||
@@ -0,0 +1,54 @@
|
||||
# Flask-контур тестирования (тот же стек, отдельный деплой)
|
||||
|
||||
Здесь — **новое** приложение на **Python / Flask** в духе `HR_TG_Bot/tgFlaskForm` (шаблоны + серверный рендер, без React). Старый стек (`backend/` + `frontend/`) пока не удаляется: оба контура могут существовать параллельно, пока не зафиксирована политика «один источник записи» и cutover.
|
||||
|
||||
## Запуск в Docker (рекомендуется)
|
||||
|
||||
Из **корня** репозитория TestingWebApp. Сервис **не** зависит от `testing-backend` и **не** требует внешней сети Postgres для старта (только внутренняя сеть compose).
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.dev.yml up -d --build testing-flask
|
||||
```
|
||||
|
||||
Когда подключите БД из контейнера к `hr_postgres_dev` / `clinic_tests`, в `docker-compose.dev.yml` у сервиса `testing-flask` добавьте сеть `postgres` (как у `testing-backend`).
|
||||
|
||||
- **URL:** http://localhost:3108
|
||||
- **Проверка:** http://localhost:3108/health
|
||||
|
||||
Вместе со старым UI и API:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.dev.yml up -d --build
|
||||
```
|
||||
|
||||
Тогда Node-интерфейс остаётся на **http://localhost:3107**, Flask — на **3108**.
|
||||
|
||||
## Запуск локально (без Docker)
|
||||
|
||||
```bash
|
||||
cd flask_app
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
||||
pip install -r requirements.txt
|
||||
cp .env.example .env # при необходимости поправьте PORT
|
||||
python run.py
|
||||
```
|
||||
|
||||
По умолчанию: **http://127.0.0.1:3108** , проверка: **http://127.0.0.1:3108/health**
|
||||
Для режима как в Docker (waitress): в `.env` задайте `WEB_USE_WAITRESS=1`.
|
||||
|
||||
## Зачем отдельная папка
|
||||
|
||||
- Один **стек** с кабинетом / мини-приложением — проще переносить экраны и запросы из `HR_TG_Bot/tgFlaskForm/webApp/interfaces/testing/`.
|
||||
- **Отдельный** процесс и порт — без риска сломать текущий `docker-compose.dev.yml` с Node до готовности.
|
||||
|
||||
## Дальнейшие шаги (код)
|
||||
|
||||
1. Подключить БД (`clinic_tests` **или** `hr_bot_test` + `testing_*` — одно из двух, см. [docs/migration-to-tgflaskform.md](../docs/migration-to-tgflaskform.md) §0).
|
||||
2. Переносить маршруты и шаблоны по образцу `tgFlaskForm` (blueprint `testing`, `db/queries/testing_queries.py`, шаблоны `cabinet/testing/`).
|
||||
3. ETL при переходе на HR-БД: `HR_TG_Bot/tgFlaskForm/tools/migrate_clinic_tests_to_hr.py`.
|
||||
|
||||
## Связанные документы
|
||||
|
||||
- [docs/migration-to-tgflaskform.md](../docs/migration-to-tgflaskform.md)
|
||||
- [README корня репозитория](../README.md)
|
||||
@@ -0,0 +1,29 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import secrets
|
||||
|
||||
from flask import Flask, jsonify
|
||||
|
||||
|
||||
def create_app() -> Flask:
|
||||
app = Flask(
|
||||
__name__,
|
||||
instance_relative_config=True,
|
||||
template_folder='templates',
|
||||
static_folder='static',
|
||||
static_url_path='/static',
|
||||
)
|
||||
sk = (os.environ.get('SECRET_KEY') or '').strip()
|
||||
app.config['SECRET_KEY'] = sk or secrets.token_hex(32)
|
||||
|
||||
@app.route('/health')
|
||||
def health():
|
||||
return jsonify(status='ok', service='testing-flask-app')
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
from flask import render_template
|
||||
|
||||
return render_template('index.html')
|
||||
|
||||
return app
|
||||
@@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Тестирование</title>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
||||
@@ -0,0 +1,3 @@
|
||||
Flask>=3.0.0,<4
|
||||
python-dotenv>=1.0.0
|
||||
waitress>=3.0.0
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Точка входа: dev — встроенный сервер Flask, prod — waitress."""
|
||||
import os
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv(os.path.join(os.path.dirname(__file__), '.env'))
|
||||
|
||||
from app import create_app
|
||||
|
||||
app = create_app()
|
||||
|
||||
def _use_waitress() -> bool:
|
||||
if os.environ.get('FLASK_ENV') == 'production':
|
||||
return True
|
||||
v = (os.environ.get('WEB_USE_WAITRESS') or '').strip().lower()
|
||||
return v in ('1', 'true', 'yes', 'on')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
port = int(os.environ.get('PORT', '3108'))
|
||||
if _use_waitress():
|
||||
from waitress import serve
|
||||
|
||||
serve(app, host='0.0.0.0', port=port)
|
||||
else:
|
||||
app.run(host='0.0.0.0', port=port, debug=os.environ.get('FLASK_DEBUG') == '1')
|
||||
Reference in New Issue
Block a user