Конфигурация проекта - nemopss/mpt-kpi GitHub Wiki
1.4.5 .flake8
Данный конфигурационный файл используется для настройки инструмента проверки кода Flake8, который анализирует Python-код на соответствие стандартам стиля PEP 8 и выявляет ошибки программирования.
[flake8]
exclude =
migrations
media
max-line-length = 120
ignore =
# Avoid using null=True on string-based fields such CharField.
DJ01
# prefer-logging-interpolation: Use lazy % formatting in logging functions.
PIE803
T101
per-file-ignores =
common/num2t/__init__.py:S001
backend/common/num2t/__init__.py:S001
integration/models.py:E800
backend/integration/models.py:E800
business/tests/api/test_integration.py:Q001
backend/business/tests/api/test_integration.py:Q001
[pep8]
# https://pep8.readthedocs.io/en/latest/intro.html#error-codes
# E501
max-line-length = 120
• exclude: Определяет директории и файлы, исключаемые из проверки.
• max-line-length: Устанавливает максимальную длину строки. Параметр задан как 120 символов, что позволяет сохранять читаемость кода.
• ignore: Список ошибок, которые следует игнорировать при проверке. В данном случае игнорируются следующие коды:
-
DJ01: Предупреждение, связанное с использованием null=True для строковых полей, таких как CharField.
-
PIE803: Рекомендуется использовать ленивое форматирование с помощью % в функциях журналирования.
-
T101: Код типа ошибки, который будет проигнорирован.
• per-file-ignores: Позволяет игнорировать определенные ошибки для указанных файлов или модулей.
1.4.6 pyproject.toml
Этот файл конфигурации предназначен для настройки инструмента Ruff, который используется для статического анализа кода на Python. Он содержит правила форматирования и исключения для определённых директорий и файлов.
# https://github.com/charliermarsh/ruff#configuration
[tool.ruff]
line-length = 120
# Exclude a variety of commonly ignored directories.
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".hg",
".mypy_cache",
".nox",
".pants.d",
".ruff_cache",
".svn",
".tox",
".venv",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"node_modules",
"venv",
# custom
"migrations",
]
[tool.ruff.per-file-ignores]
"main/views.py" = [
"E402",
"E721",
]
• line-length: Данная настройка указывает максимальную длину строки, установленную на 120 символов. Это значение может быть изменено в зависимости от стандартов кодирования.
Параметр exclude используется для указания директорий, которые должны быть исключены из анализа. В данном случае исключены следующие каталоги:
• .git, .hg: системы контроля версий,
• .venv, node_modules: каталоги, содержащие зависимости,
• .mypy_cache, pypackages: кеши инструментов.
Дополнительно включена пользовательская директория "migrations", чтобы исключить её из анализа.
Параметр per-file-ignores позволяет задавать игнорирование определённых правил для указанных файлов. В данном случае, для файла "main/views.py" игнорируются следующие коды ошибок:
• E402: Импорт не на верхнем уровне (imports not at top level);
• E721: Использование == для проверки на None (do not compare types, use is instead).
1.4.7 extensions.py
В этом файле определяются расширения Flask, которые будут использованы в приложении. Эти расширения предоставляют базовую функциональность для работы с базой данных, миграциями, аутентификацией пользователей и отправкой электронной почты.
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
from flask_mail import Mail
db = SQLAlchemy()
migrate = Migrate()
login_manager = LoginManager()
mail = Mail()
• db: Объект, который предоставляет основные методы и функционал для работы с базой данных через ORM (Object-Relational Mapping). Он позволяет управлять моделями, выполнять запросы к базе данных и обрабатывать транзакции.
• migrate: Объект, который отвечает за управление миграциями базы данных. С его помощью вы можете создавать, обновлять и откатывать изменения в структуре базы данных, максимально упрощая процесс внедрения новых моделей и изменений схемы.
• login_manager: Объект, который управляет аутентификацией пользователей. Он предоставляет инструменты для управления сессиями пользователей, а также для защиты маршрутов, доступ к которым имеют только авторизованные пользователи.
• mail: Объект, который используется для отправки электронной почты. Этот расширение предоставляет интерфейс для настройки и отправки писем прямо из приложения, включая поддержки HTML и вложений.
1.4.8 requirements.dev.in
requiremnts.dev.in является входным файлом для управления зависимостями разработки. Он содержит список библиотек, необходимых для выполнения тестирования и линтинга кода:
# An extremely fast Python linter, written in Rust.
ruff
flake8
pytest
• ruff: быстрый линтер для Python, написанный на Rust;
• flake8: инструмент для проверки стиля кода;
• pytest: библиотека для написания тестов.
1.4.9 requirements.dev.txt
requiremnts.dev.in является автоматически сгенерированным результатом выполнения команды pip-compile с использованием requirements.dev.in. Он содержит фиксированные версии зависимостей, что позволяет избежать проблем с совместимостью:
#
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile requirements.dev.in
#
flake8==7.1.1
# via -r requirements.dev.in
iniconfig==2.0.0
# via pytest
mccabe==0.7.0
# via flake8
packaging==24.1
# via pytest
pluggy==1.5.0
# via pytest
pycodestyle==2.12.1
# via flake8
pyflakes==3.2.0
# via flake8
pytest==8.3.3
# via -r requirements.dev.in
ruff==0.6.5
# via -r requirements.dev.in
1.4.10 requirements.in
В данном файле перечислены основные зависимости приложения, которые необходимы для его функционирования. Он включает в себя различные библиотеки для веб-разработки на Flask:
requests~=2.32.3
mysql-connector-python~=9.0.0
Flask~=3.0.3
Flask-Cors~=5.0.0
Flask-RESTful~=0.3.10
Flask-SQLAlchemy~=3.1.1
Flask-Migrate~=4.0.7
Flask-Login~=0.6.3
Flask-Mail~=0.10.0
• requests: для работы с HTTP запросами;
• mysql-connector-python: библиотека для работы с базой данных MySQL;
• Flask: основной фреймворк для создания веб-приложений;
• Flask-Cors: для обработки CORS (Cross-Origin Resource Sharing);
• Flask-RESTful: для создания RESTful API;
• Flask-SQLAlchemy: для работы с базами данных;
• Flask-Migrate: для управления миграциями базы данных;
• Flask-Login: для управления аутентификацией;
• Flask-Mail: для отправки электронной почты.
1.4.11 requirements.txt
requirements.txt - файл также создается автоматически с помощью pip-compile и содержит окончательные версии зависимостей, включая все зависимости, упомянутые в requirements.in.
#
# This file is autogenerated by pip-compile with Python 3.12
# by the following command:
#
# pip-compile
#
alembic==1.14.0
# via flask-migrate
aniso8601==9.0.1
# via flask-restful
blinker==1.8.2
# via
# flask
# flask-mail
certifi==2024.8.30
# via requests
charset-normalizer==3.4.0
# via requests
click==8.1.7
# via flask
flask==3.0.3
# via
# -r requirements.in
# flask-cors
# flask-login
# flask-mail
# flask-migrate
# flask-restful
# flask-sqlalchemy
flask-cors==5.0.0
# via -r requirements.in
flask-login==0.6.3
# via -r requirements.in
flask-mail==0.10.0
# via -r requirements.in
flask-migrate==4.0.7
# via -r requirements.in
flask-restful==0.3.10
# via -r requirements.in
flask-sqlalchemy==3.1.1
# via
# -r requirements.in
# flask-migrate
greenlet==3.1.1
# via sqlalchemy
idna==3.10
# via requests
itsdangerous==2.2.0
# via flask
jinja2==3.1.4
# via flask
mako==1.3.8
# via alembic
markupsafe==2.1.5
# via
# jinja2
# mako
# werkzeug
mysql-connector-python==9.0.0
# via -r requirements.in
pytz==2024.2
# via flask-restful
requests==2.32.3
# via -r requirements.in
six==1.16.0
# via flask-restful
sqlalchemy==2.0.36
# via
# alembic
# flask-sqlalchemy
typing-extensions==4.12.2
# via
# alembic
# sqlalchemy
urllib3==2.2.3
# via requests
werkzeug==3.0.4
# via
# flask
# flask-login
1.4.12 dev.Dockerfile
Данный файл предназначен для установки необходимых зависимостей и разработки приложения.
FROM python:3.12
ENV PYTHONUNBUFFERED 1
WORKDIR /app/
COPY requirements.txt .
COPY requirements.dev.txt .
RUN python -m pip install --upgrade pip && \
pip install pip-tools && \
pip install -r requirements.txt && \
pip install -r requirements.dev.txt
COPY . .
CMD ["python", "main.py"]
• FROM python:3.12: Использует образ Python версии 3.12;
• ENV PYTHONUNBUFFERED 1: Устанавливает переменную окружения, чтобы вывод Python не буферизовался (это полезно для логирования);
• WORKDIR /app/: Устанавливает рабочий каталог в контейнере;
• COPY requirements.txt . и COPY requirements.dev.txt .: Копирует файлы зависимостей внутрь контейнера;
• RUN python -m pip install --upgrade pip ...: Обновляет pip и устанавливает зависимости;
• COPY . .: Копирует все файлы приложения в контейнер;
• CMD ["python", "main.py"]: Команда для запуска приложения при старте контейнера.
1.4.13 Dockerfile
Этот файл используется для создания оптимизированного образа для продакшн-окружения.
FROM python:3.12 AS builder
WORKDIR /app/
RUN apt update \
&& apt install -y --no-install-recommends gcc \
&& rm -rf /var/lib/apt/lists/*
RUN --mount=type=bind,source=requirements.txt,target=/app/requirements.txt \
pip wheel --no-cache-dir --no-deps -r /app/requirements.txt --wheel-dir /app/wheels
RUN --mount=type=bind,source=requirements.txt,target=/app/requirements.dev.txt \
pip wheel --no-cache-dir --no-deps -r /app/requirements.dev.txt --wheel-dir /app/wheels
#2#
FROM python:3.12-slim
COPY --from=builder /app/wheels /wheels
RUN pip install --upgrade pip && pip install --no-cache --no-cache-dir /wheels/*
WORKDIR /app
COPY . .
CMD ["python", "backend.py"]
• FROM python:3.12 AS builder: Первая стадия сборки, которая использует полный образ Python;
• RUN apt update ...: устанавливает компилятор C (gcc), необходимый для некоторых зависимостей, которые могут требовать компиляции;
• RUN --mount=type=bind,...: Использует механизм монтирования для установки зависимостей в виде wheel-файлов в папку /wheels (это делает сборку более быстрой и позволяет избежать повторной установки);
• FROM python:3.12-slim: Начинает вторую стадию с легкого образа Python, чтобы уменьшить размер конечного образа;
• COPY --from=builder /app/wheels /wheels: Копирование сгенерированных wheel-файлов из первой стадии в текущий образ;
• RUN pip install ...: Устанавливает зависимости из wheel-файлов;
• WORKDIR /app и COPY . .: Копирует файлы приложения в конечный образ;
• CMD ["python", "backend.py"]: Основная команда запуска приложения.
1.4.14 init.sql
Данный SQL-скрипт предназначен для инициализации базы данных mpt_kpi. Скрипт включает создание необходимых таблиц и заполнение их начальными данными.
CREATE DATABASE IF NOT EXISTS mpt_kpi;
USE mpt_kpi;
CREATE TABLE IF NOT EXISTS Role (
role_id INT AUTO_INCREMENT PRIMARY KEY,
role_name VARCHAR(45) NOT NULL,
role_points INT NOT NULL,
role_description VARCHAR(125)
);
CREATE TABLE IF NOT EXISTS Users (
user_id INT AUTO_INCREMENT PRIMARY KEY,
user_name VARCHAR(45) NOT NULL,
user_surname VARCHAR(45) NOT NULL,
user_patronymic VARCHAR(45) NOT NULL,
user_email VARCHAR(45) NOT NULL,
user_phone VARCHAR(45) NOT NULL,
user_passhash VARCHAR(100) NOT NULL,
user_role VARCHAR(100) NOT NULL,
user_login VARCHAR(45) NOT NULL,
is_admin BOOLEAN NOT NULL DEFAULT FALSE,
role_role_id INT,
FOREIGN KEY (role_role_id) REFERENCES Role(role_id)
);
CREATE TABLE IF NOT EXISTS Criteria (
criteria_ID INT AUTO_INCREMENT PRIMARY KEY,
criteria_name VARCHAR(255) NOT NULL,
rating_from INT NOT NULL,
score_before INT NOT NULL
);
CREATE TABLE IF NOT EXISTS Certificates (
certificate_ID INT AUTO_INCREMENT PRIMARY KEY,
uploaded_by INT NOT NULL,
criteria_id INT NOT NULL,
is_approved BOOLEAN NOT NULL DEFAULT TRUE,
rating INT NOT NULL,
file_path VARCHAR(255) NOT NULL,
FOREIGN KEY (uploaded_by) REFERENCES Users(user_id),
FOREIGN KEY (criteria_id) REFERENCES Criteria(criteria_id)
);
INSERT INTO mpt_kpi.role VALUES ('1', 'Работник', '5', 'Работает');
INSERT INTO mpt_kpi.users VALUES ('1', 'Иван', 'Иванов', 'Иванович', '[email protected]', '79251232233', 'dsadxz', 'Работник', 'IvanII', '0', '1');
INSERT INTO mpt_kpi.criteria VALUES ('1', 'Доп. выходы', '1', '5');
INSERT INTO mpt_kpi.certificates VALUES ('1', '1', '1', '1', '5', 'file.path');
• CREATE DATABASE IF NOT EXISTS mpt_kpi: Создание базы данных, если она еще не была создана;
• USE mpt_kpi: Переключается на базу данных mpt_kpi.
Таблица Role предназначена для хранения информации о ролях пользователей. Структура таблицы включает следующие поля:
• role_id: уникальный идентификатор роли (PRIMARY KEY);
• role_name: наименование роли;
• role_points: количество баллов, связанных с ролью;
• role_description: описание роли.
Таблица Users содержит информацию о пользователях системы. Структура таблицы включает следующие поля.
• user_id: уникальный идентификатор пользователя (PRIMARY KEY).
• user_name: имя пользователя.
• user_surname: фамилия пользователя.
• user_patronymic: отчество пользователя.
• user_email: электронная почта пользователя.
• user_phone: номер телефона пользователя.
• user_passhash: хеш пароля.
• user_role: наименование роли пользователя.
• user_login: логин пользователя.
• is_admin: булево значение, указывающее, является ли пользователь администратором.
• role_role_id: внешний ключ, ссылающийся на идентификатор роли в таблице Role.
Таблица Criteria используется для хранения критериев оценивания. Структура таблицы включает следующие поля.
• criteria_ID: уникальный идентификатор критерия (PRIMARY KEY).
• criteria_name: название критерия.
• rating_from: минимальный рейтинг, с которого начинается оценка.
• score_before: предшествующий балл.
Таблица Certificates предназначена для хранения информации о сертификатах. Структура таблицы включает следующие поля:
• certificate_ID: уникальный идентификатор сертификата (PRIMARY KEY).
• uploaded_by: идентификатор пользователя, загрузившего сертификат (внешний ключ).
• criteria_id: идентификатор критерия, к которому относится сертификат (внешний ключ).
• is_approved: булево значение, указывающее, одобрен ли сертификат.
• rating: рейтинг сертификата.
• file_path: путь к файлу сертификата.
Команды, приведенные ниже, вставляют начальные данные в таблицы.
• INSERT INTO mpt_kpi.role VALUES ('1', 'Работник', '5', 'Работает'): Добавляется одна запись в таблицу Role с ролью "Работник".
• INSERT INTO mpt_kpi.users VALUES ('1', 'Иван', 'Иванов', 'Иванович', '[email protected]', '79251232233', 'dsadxz', 'Работник', 'IvanII', '0', '1'): Добавляется один пользователь в таблицу Users.
• INSERT INTO mpt_kpi.criteria VALUES ('1', 'Доп. выходы', '1', '5'): Добавляется один критерий в таблицу Criteria.
• INSERT INTO mpt_kpi.certificates VALUES ('1', '1', '1', '1', '5', 'file.path'): Добавляется один сертификат в таблицу Certificates.
1.4.15 models.py
В данном файле определены модели базы данных, используемые в приложении, которое работает с Flask и SQLAlchemy. В модели представлены Position и User, реализующие соответствующие сущности для хранения информации о должностях и пользователях системы.
from flask_login import UserMixin
from werkzeug.security import check_password_hash, generate_password_hash
from extensions import db
class Position(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False, unique=True)
score_threshold = db.Column(db.Integer, nullable=False)
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(50), nullable=False)
last_name = db.Column(db.String(50), nullable=False)
middle_name = db.Column(db.String(50))
position_id = db.Column(db.Integer, db.ForeignKey("position.id"))
phone_number = db.Column(db.String(15), unique=True)
email = db.Column(db.String(120), unique=True, nullable=False)
password_hash = db.Column(db.String(128))
is_admin = db.Column(db.Boolean, default=False)
position = db.relationship("Position", backref=db.backref("users", lazy=True))
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
Модель Position
class Position(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False, unique=True)
score_threshold = db.Column(db.Integer, nullable=False)
• id: Уникальный идентификатор должности. Является первичным ключом.
• name: Название должности. Обязательное поле, должно быть уникальным.
• score_threshold: Пороговое значение для оценки, связанное с должностью. Обязательное поле.
Модель User
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(50), nullable=False)
last_name = db.Column(db.String(50), nullable=False)
middle_name = db.Column(db.String(50))
position_id = db.Column(db.Integer, db.ForeignKey("position.id"))
phone_number = db.Column(db.String(15), unique=True)
email = db.Column(db.String(120), unique=True, nullable=False)
password_hash = db.Column(db.String(128))
is_admin = db.Column(db.Boolean, default=False)
position = db.relationship("Position", backref=db.backref("users", lazy=True))
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
• id: Уникальный идентификатор пользователя. Является первичным ключом.
• first_name: Имя пользователя. Обязательное поле.
• last_name: Фамилия пользователя. Обязательное поле.
• middle_name: Отчество пользователя. Необязательное поле.
• position_id: Идентификатор должности пользователя. Является внешним ключом, ссылающимся на модель Position.
• phone_number: Номер телефона пользователя. Должен быть уникальным.
• email: Электронная почта пользователя. Обязательное поле, должно быть уникальным.
• password_hash: Хэш пароля пользователя. Хранится в зашифрованном виде.
• is_admin: Флаг, указывающий, является ли пользователь администратором. По умолчанию устанавливается в значение False.
Методы
• set_password(self, password): Устанавливает хэшированный пароль для пользователя.
• check_password(self, password): Проверяет введённый пароль на соответствие хранившемуся хэшу.
1.4.16 config.py
В данном файле определяется класс конфигурации Config, который содержит настройки приложения. Эти настройки управляют различными параметрами, такими как секретный ключ, параметры подключения к базе данных и настройки для отправки электронной почты.
import os
class Config:
SECRET_KEY = os.getenv("SECRET_KEY", "mysecret")
SQLALCHEMY_DATABASE_URI = os.getenv("DATABASE_URL", "sqlite:///app.db")
SQLALCHEMY_TRACK_MODIFICATIONS = False
MAIL_SERVER = "smtp.example.com"
MAIL_PORT = 587
MAIL_USE_TLS = True
MAIL_USERNAME = os.getenv("MAIL_USERNAME")
MAIL_PASSWORD = os.getenv("MAIL_PASSWORD")
MAIL_DEFAULT_SENDER = os.getenv("MAIL_DEFAULT_SENDER")
• SECRET_KEY: Секретный ключ используется Flask для защиты данных, таких как сессии и куки. Он может быть извлечен из переменной окружения SECRET_KEY, что обеспечивает безопасность, однако в случае отсутствия переменной будет использовано значение по умолчанию "mysecret".
• SQLALCHEMY_DATABASE_URI: Этот атрибут указывает URI для подключения к базе данных. Значение может быть получено из переменной окружения DATABASE_URL, что позволяет гибко изменять базу данных без изменения кода. Если переменная не установлена, используется значение по умолчанию sqlite:///app.db (SQLite).
• SQLALCHEMY_TRACK_MODIFICATIONS: Данный параметр отключает отслеживание изменений объектов в SQLAlchemy, что снижает затрату памяти и улучшает производительность.
• MAIL_SERVER: Указывает сервер для отправки электронной почты.
• MAIL_PORT: Определяет порт, используемый для подключения к почтовому серверу.
• MAIL_USE_TLS: Включает использование TLS (Transport Layer Security) для безопасной передачи данных.
• MAIL_USERNAME: Имя пользователя для аутентификации на почтовом сервере, значение извлекается из переменной окружения MAIL_USERNAME.
• MAIL_PASSWORD: Пароль для аутентификации на почтовом сервере, значение извлекается из переменной окружения MAIL_PASSWORD.
• MAIL_DEFAULT_SENDER: Адрес электронной почты по умолчанию, с которого будут отправляться письма, значение извлекается из переменной окружения MAIL_DEFAULT_SENDER.