build: standardize runtime on Python 3.13

This commit is contained in:
2026-10-23 15:57:53 +03:00
parent f6cd4e8d75
commit c8b12f37e4
9 changed files with 84 additions and 61 deletions

1
.python-version Normal file
View File

@@ -0,0 +1 @@
3.13

View File

@@ -15,6 +15,8 @@ Your architecture uses Causal Attention (you predict the next token based only o
## Development Environment
- Рабочий виртуальный окружение (`.venv`) находится внутри `backend/`: `backend/.venv`.
- Backend требует Python 3.13 или новее; `.python-version` выбирает ветку 3.13 без закрепления patch-версии.
- Существующее `backend/.venv` на Python ниже 3.13 нужно пересоздать явно; `run.sh` откажет до чтения `.env`, записи файлов и подключения к БД.
## Тестовый стенд и запуск
@@ -39,7 +41,7 @@ healthcheck после запуска, поэтому первое открыт
При старте скрипт:
1. Проверяет `python3 >= 3.9` и `npm`.
1. Проверяет `python3 >= 3.13` и `npm`.
2. Загружает `backend/.env` до database preflight.
3. Берет URL БД из `DATABASE_URL` либо использует локальный PostgreSQL:
`postgresql+psycopg2://postgres:postgres@localhost:5432/ss_tools`.

View File

@@ -20,7 +20,7 @@
## Требования
- **Docker (рекомендуется):** Docker Engine 24+, Docker Compose v2, 4 GB RAM
- **Локальная разработка:** Python 3.9+, Node.js 18+, npm, 2 GB RAM, 5 GB диска
- **Локальная разработка:** Python 3.13+, Node.js 18+, npm, 2 GB RAM, 5 GB диска
## Архитектура
@@ -75,7 +75,7 @@ superset-tools/
## Технологический стек
**Backend:** Python 3.9+ (FastAPI 0.126, SQLAlchemy 2.0, APScheduler 3.11), PostgreSQL 16, Authlib, JWT, OpenAI API, GitPython, Playwright, lingua-language-detector
**Backend:** Python 3.13+ (FastAPI 0.126, SQLAlchemy 2.0, APScheduler 3.11), PostgreSQL 16, Authlib, JWT, OpenAI API, GitPython, Playwright, lingua-language-detector
**Frontend:** Svelte 5 (Runes), SvelteKit 2.49, Vite 7, Tailwind CSS 3, Vitest 4.1, Playwright 1.60
@@ -120,7 +120,7 @@ docker compose -f dist/docker/docker-compose.light.yml up -d
```bash
cd backend
python3 -m venv .venv
python3.13 -m venv .venv
source .venv/bin/activate
pip install -r requirements-backend.txt
python3 -m uvicorn src.app:app --reload --port 8000

View File

@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "superset-tools-backend"
version = "0.0.0"
requires-python = ">=3.11"
requires-python = ">=3.13"
[tool.setuptools]
include-package-data = true

View File

@@ -6,7 +6,7 @@
#
# Stages:
# 1. frontend-builder — node:20-alpine, npm ci + build, discarded
# 2. runtime — python:3.11-slim, backend deps (no playwright),
# 2. runtime — python:3.13-slim, backend deps (no playwright),
# copies frontend build, uvicorn serves both SPA + API on :8000
# ── Stage 1: Build Frontend ────────────────────────────────
@@ -26,7 +26,7 @@ COPY frontend/ ./
RUN npm run build
# ── Stage 2: Runtime ───────────────────────────────────────
FROM python:3.11-slim AS runtime
FROM python:3.13-slim AS runtime
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \

View File

@@ -1,12 +1,12 @@
# #region docker.backend.Dockerfile [C:3] [TYPE Module] [SEMANTICS docker,backend,build]
# @BRIEF Backend Dockerfile — Python 3.11 slim + Playwright + entrypoint с установкой сертификатов.
# @BRIEF Backend Dockerfile — Python 3.13 slim + Playwright + entrypoint с установкой сертификатов.
# @LAYER Infrastructure
# @RELATION DEPENDS_ON -> [EXT:path:docker/backend.entrypoint.sh]
# @RELATION DEPENDS_ON -> [EXT:path:backend/requirements-backend.txt]
# @PRE Docker builder context — корень проекта. backend/, docker/ доступны.
# @POST Образ с backend API, Playwright, entrypoint для bootstrap admin.
FROM python:3.11-slim
FROM python:3.13-slim
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

View File

@@ -200,7 +200,7 @@ install_ca_to_nss() {
# @RATIONALE Без wait-for-db enterprise-деплой с внешним PostgreSQL падает
# мгновенно — entrypoint интерпретирует connection refused как "пустая БД".
# @REJECTED Использование pg_isready напрямую отвергнуто — клиент psql может
# отсутствовать в python:3.11-slim образе. SQLAlchemy-проверка универсальна.
# отсутствовать в python:3.13-slim образе. SQLAlchemy-проверка универсальна.
wait_for_db() {
local max_attempts="${DB_WAIT_ATTEMPTS:-30}"
local delay="${DB_WAIT_DELAY:-2}"

120
run.sh
View File

@@ -10,6 +10,76 @@ set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$SCRIPT_DIR"
# #region Tooling.Run.Arguments [C:2] [TYPE Function]
# @POST Help and invalid arguments return before interpreter checks or startup side effects.
SKIP_INSTALL=false
# Help message
show_help() {
echo "Usage: ./run.sh [options]"
echo ""
echo "Options:"
echo " --help Show this help message"
echo " --skip-install Skip dependency checks and installation"
echo ""
echo "Environment Variables:"
echo " DEV_MODE Hot-reload mode (true/false). Default: false"
echo " Enables uvicorn --reload"
echo " BACKEND_PORT Port for the backend server (default: 8000)"
echo " FRONTEND_PORT Port for the frontend server (default: 5173)"
}
# Parse arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
--help) show_help; exit 0 ;;
--skip-install) SKIP_INSTALL=true ;;
*) echo "Unknown parameter passed: $1"; show_help; exit 1 ;;
esac
shift
done
# #endregion Tooling.Run.Arguments
# #region Tooling.Run.ValidateEnvironment [C:3] [TYPE Function]
# @PRE Validate Python before reading configuration, creating storage, generating secrets or probing the database.
# @POST Both the host and an existing backend virtual environment require Python 3.13 or newer.
# @REJECTED Checking only the host would let --skip-install keep using an existing Python 3.11 virtual environment.
validate_env() {
echo "Validating environment..."
if ! command -v python3 &> /dev/null; then
echo "Error: python3 is not installed."
exit 1
fi
if ! python3 -c 'import sys; exit(0) if sys.version_info >= (3, 13) else exit(1)'; then
PYTHON_VERSION=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
echo "Error: python3 version 3.13 or higher is required. Found $PYTHON_VERSION"
exit 1
fi
local backend_python="$PROJECT_ROOT/backend/.venv/bin/python"
if [ -d "$PROJECT_ROOT/backend/.venv" ]; then
if [ ! -x "$backend_python" ] || ! "$backend_python" -c 'import sys; exit(0) if sys.version_info >= (3, 13) else exit(1)'; then
echo "Error: backend/.venv must use Python 3.13 or higher. Recreate it with a supported Python before starting."
exit 1
fi
fi
if ! command -v npm &> /dev/null; then
echo "Error: npm is not installed."
exit 1
fi
PYTHON_VERSION=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
echo "Environment validation passed (Python $PYTHON_VERSION, npm $(npm -v))"
}
# #endregion Tooling.Run.ValidateEnvironment
validate_env
source "$SCRIPT_DIR/scripts/source_repository_identity_env.sh"
# Parse KEY=VALUE dotenv files without executing their contents. Existing process
@@ -51,7 +121,6 @@ load_dotenv "$PROJECT_ROOT/backend/.env"
DEV_MODE="${DEV_MODE:-false}"
BACKEND_PORT=${BACKEND_PORT:-8000}
FRONTEND_PORT=${FRONTEND_PORT:-5173}
SKIP_INSTALL=false
# Service-to-service shared secret validated by the backend for service
# principals (MCP service tokens, internal integrations). When unset, a random
@@ -79,58 +148,9 @@ fi
mkdir -p "$STORAGE_ROOT_PATH/repositories" "$STORAGE_ROOT_PATH/backups" "$STORAGE_ROOT_PATH/drafts"
export STORAGE_ROOT_PATH
# Help message
show_help() {
echo "Usage: ./run.sh [options]"
echo ""
echo "Options:"
echo " --help Show this help message"
echo " --skip-install Skip dependency checks and installation"
echo ""
echo "Environment Variables:"
echo " DEV_MODE Hot-reload mode (true/false). Default: false"
echo " Enables uvicorn --reload"
echo " BACKEND_PORT Port for the backend server (default: 8000)"
echo " FRONTEND_PORT Port for the frontend server (default: 5173)"
}
# Parse arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
--help) show_help; exit 0 ;;
--skip-install) SKIP_INSTALL=true ;;
*) echo "Unknown parameter passed: $1"; show_help; exit 1 ;;
esac
shift
done
echo "Starting Project Launch Script..."
# Environment validation
validate_env() {
echo "Validating environment..."
if ! command -v python3 &> /dev/null; then
echo "Error: python3 is not installed."
exit 1
fi
if ! python3 -c 'import sys; exit(0) if sys.version_info >= (3, 9) else exit(1)'; then
PYTHON_VERSION=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
echo "Error: python3 version 3.9 or higher is required. Found $PYTHON_VERSION"
exit 1
fi
if ! command -v npm &> /dev/null; then
echo "Error: npm is not installed."
exit 1
fi
PYTHON_VERSION=$(python3 -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
echo "Environment validation passed (Python $PYTHON_VERSION, npm $(npm -v))"
}
validate_env
# ── backend/.env was safely loaded before configuration defaults ──
if [ -f "backend/.env" ]; then

View File

@@ -28,7 +28,7 @@ def main() -> None:
docker(
"run", "-d", "--name", backend, "--network", network, "--network-alias", "backend",
"-v", f"{root / 'scripts/mcp_proxy_fixture.py'}:/fixture.py:ro",
"python:3.12-alpine", "python", "/fixture.py",
"python:3.13-alpine", "python", "/fixture.py",
)
docker(
"run", "-d", "--name", frontend, "--network", network,