Корпоративный сайт на Flask с управляемым контентом, новостями, участниками, комитетами, главным медиаслайдером, бегущей строкой и формой обратной связи. Для редакторов предусмотрена закрытая административная панель Flask-Admin.
Проект изначально развивался как одностраничный промосайт, а затем был переработан в полноценное небольшое CMS-приложение. Основной упор сделан на простой запуск, безопасную работу с пользовательским HTML и файлами, а также возможность размещения на обычном Python-хостинге или cPanel Passenger.
- динамический главный слайдер с изображениями и видео;
- управление комитетами и направлениями работы;
- каталог участников с логотипами и внешними ссылками;
- публикация новостей с безопасным форматированием HTML;
- настраиваемая бегущая строка;
- форма обратной связи с SMTP-отправкой;
- административная панель с авторизацией и CSRF-защитой;
- проверка и оптимизация загружаемых изображений;
- автоматическое удаление неиспользуемых медиафайлов;
- миграции базы данных через Alembic/Flask-Migrate;
- стартовое наполнение для локального запуска;
- набор автоматических тестов.
- Python 3.12;
- Flask 3;
- Flask-SQLAlchemy;
- Flask-Admin;
- Flask-Login;
- Flask-WTF;
- Flask-Migrate / Alembic;
- SQLite;
- Pillow;
- Bleach;
- HTML, CSS и JavaScript без отдельного фронтенд-сборщика.
Откройте PowerShell в каталоге проекта:
Set-ExecutionPolicy -Scope Process Bypass
.\setup.ps1
.\start.ps1setup.ps1 выполнит следующие действия:
- создаст виртуальное окружение
.venv; - установит зависимости;
- предложит задать логин и пароль администратора;
- создаст безопасный
.env; - применит миграции;
- заполнит новую базу стартовыми данными и медиафайлами.
После запуска откройте:
- сайт:
http://127.0.0.1:5000; - админка:
http://127.0.0.1:5000/admin/; - проверка состояния:
http://127.0.0.1:5000/health.
Остановка сервера: Ctrl+C.
py -3.12 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
pip install -r requirements.txt
python scripts\bootstrap_env.py
python -m flask --app app:create_app db upgrade
python scripts\seed_demo_data.py
python app.pyЛокальные настройки хранятся в .env. Этот файл содержит секреты и не должен попадать в Git.
Пример доступен в .env.example:
FLASK_DEBUG=0
SECRET_KEY=replace-with-a-long-random-secret
ADMIN_USERNAME=admin
ADMIN_PASSWORD_HASH=replace-with-generated-hash
SESSION_COOKIE_SECURE=0
TRUST_PROXY_HEADERS=0
MAX_UPLOAD_MB=80
CONTACT_RATE_LIMIT_SECONDS=30
CONTACT_TO=recipient@example.com
SMTP_HOST=smtp.example.com
SMTP_PORT=465
SMTP_USER=sender@example.com
SMTP_PASSWORD=application-password
SMTP_USE_SSL=1.\.venv\Scripts\python.exe scripts\generate_admin_password.pyСкопируйте полученный хеш в ADMIN_PASSWORD_HASH внутри .env и перезапустите приложение.
Для работы формы обратной связи задайте:
CONTACT_TO— адрес получателя;SMTP_HOST— SMTP-сервер;SMTP_PORT— порт;SMTP_USER— имя пользователя;SMTP_PASSWORD— пароль приложения или SMTP-пароль;SMTP_USE_SSL—1для SSL,0для обычного подключения/STARTTLS согласно настройкам провайдера.
Не используйте основной пароль от почтового аккаунта, если сервис поддерживает отдельные пароли приложений.
По умолчанию используется SQLite-файл app.db в корне проекта. Файл базы игнорируется Git и создаётся локально.
Применить миграции:
.\.venv\Scripts\python.exe -m flask --app app:create_app db upgradeПосле изменения моделей создать миграцию:
.\.venv\Scripts\python.exe -m flask --app app:create_app db migrate -m "Описание изменения"
.\.venv\Scripts\python.exe -m flask --app app:create_app db upgradeНе редактируйте уже опубликованные миграции задним числом. Для каждого изменения схемы создавайте новый файл миграции.
Исходные данные находятся в seed/content.json, а исходные медиа — в static/seed_media.
Заполнить пустую базу:
.\.venv\Scripts\python.exe scripts\seed_demo_data.pyПолностью заменить текущее содержимое стартовым набором:
.\.venv\Scripts\python.exe scripts\seed_demo_data.py --forceКоманда --force удаляет текущие записи из основных таблиц. Используйте её только для локальной разработки или после резервного копирования.
Через /admin/ можно управлять:
- слайдами главного экрана;
- комитетами;
- участниками;
- новостями;
- элементами и настройками бегущей строки.
Загрузки проходят серверную проверку. Обычные изображения уменьшаются до разумного разрешения и сохраняются в WebP. SVG запрещён. Для видео и анимаций действуют отдельные ограничения формата и размера.
В проекте реализованы:
- хранение хеша пароля вместо открытого пароля;
- CSRF-защита форм;
- проверка безопасного внутреннего перенаправления после входа;
- фильтрация неопубликованных новостей;
- очистка HTML новостей через белый список;
- проверка реального формата загружаемых файлов;
- запрет SVG;
- ограничение размера загрузок;
- безопасные cookie-настройки;
- базовые защитные HTTP-заголовки;
- ограничение частоты отправки контактной формы;
- скрытое поле против автоматического спама.
Перед публикацией обязательно задайте собственные SECRET_KEY, логин, пароль администратора и SMTP-настройки.
.\test.ps1Или напрямую:
.\.venv\Scripts\python.exe -m pytestТесты проверяют основные сценарии авторизации, CSRF, API новостей, очистку HTML, валидацию формы и служебный маршрут /health.
Проверить соответствие файлов ссылкам в базе:
.\.venv\Scripts\python.exe scripts\check_media_integrity.pyУдалить неиспользуемые файлы из рабочего каталога загрузок:
.\.venv\Scripts\python.exe scripts\cleanup_uploads.pyПеред очисткой рекомендуется создать резервную копию базы и static/uploads.
itas-app/
├── .github/workflows/ # CI для GitHub Actions
├── migrations/ # миграции Alembic
├── scripts/ # настройка, seed и обслуживание
├── seed/ # стартовые данные
├── static/
│ ├── admin/ # стили административной панели
│ ├── css/ # стили публичной части
│ ├── fonts/ # локальные шрифты
│ ├── js/ # JavaScript-модули
│ ├── seed_media/ # исходные медиа стартового наполнения
│ └── uploads/ # рабочие пользовательские загрузки
├── templates/ # Jinja2-шаблоны
├── tests/ # тесты pytest
├── app.py # фабрика Flask-приложения и API
├── admin.py # административная панель
├── auth.py # вход и выход администратора
├── config.py # конфигурация приложения
├── models.py # основные модели SQLAlchemy
├── uploads.py # проверка и обработка файлов
├── setup.ps1 # первоначальная настройка
└── start.ps1 # локальный запуск
Для production не запускайте встроенный Flask-сервер напрямую из интернета. Используйте WSGI-сервер либо Passenger и HTTPS.
В репозитории присутствует passenger_wsgi.py для размещения на cPanel Passenger. Общая последовательность описана в документации по развёртыванию.
- rate limit формы хранится в памяти процесса и рассчитан на небольшой однопроцессный сайт;
- SQLite подходит для текущей нагрузки, но при активной многопользовательской записи лучше перейти на PostgreSQL;
- административная учётная запись пока одна и задаётся через окружение;
- медиаконтент хранится на локальном диске сервера.
Исходный код распространяется по лицензии MIT. Тексты, логотипы, фотографии, видео и другие материалы из static/seed_media могут принадлежать соответствующим организациям и не передаются автоматически по лицензии MIT. Подробности указаны в NOTICE.md.