start new interface

This commit is contained in:
jze9
2025-04-07 02:11:33 +05:00
parent 4c72b79e86
commit a7e85b949c
25 changed files with 274 additions and 9655 deletions

165
app/.gitignore vendored
View File

@@ -1,2 +1,163 @@
data_base_hesh
__pycache__
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
*.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# Flet
storage/

View File

@@ -1,2 +1,81 @@
# user_app
user_app_copp
# App app
## Run the app
### uv
Run as a desktop app:
```
uv run flet run
```
Run as a web app:
```
uv run flet run --web
```
### Poetry
Install dependencies from `pyproject.toml`:
```
poetry install
```
Run as a desktop app:
```
poetry run flet run
```
Run as a web app:
```
poetry run flet run --web
```
For more details on running the app, refer to the [Getting Started Guide](https://flet.dev/docs/getting-started/).
## Build the app
### Android
```
flet build apk -v
```
For more details on building and signing `.apk` or `.aab`, refer to the [Android Packaging Guide](https://flet.dev/docs/publish/android/).
### iOS
```
flet build ipa -v
```
For more details on building and signing `.ipa`, refer to the [iOS Packaging Guide](https://flet.dev/docs/publish/ios/).
### macOS
```
flet build macos -v
```
For more details on building macOS package, refer to the [macOS Packaging Guide](https://flet.dev/docs/publish/macos/).
### Linux
```
flet build linux -v
```
For more details on building Linux package, refer to the [Linux Packaging Guide](https://flet.dev/docs/publish/linux/).
### Windows
```
flet build windows -v
```
For more details on building Windows package, refer to the [Windows Packaging Guide](https://flet.dev/docs/publish/windows/).

File diff suppressed because it is too large Load Diff

View File

@@ -1,311 +0,0 @@
import flet as ft
from flet_core.types import OptionalControlEventCallable
import json
import requests
color = [
"#f0ece2",
"#dfd3c3",
"#c7b198",
"#596e79",
"#7E93A0FF"
]
class DataPicer(ft.DatePicker):
def __init__(self,creation_time, handle_dismissal: OptionalControlEventCallable = None,handle_change: OptionalControlEventCallable = None):
import datetime
super().__init__(
current_date=creation_time,
first_date=datetime.datetime(year=2023, month=10, day=1),
last_date=datetime.datetime(year=2027, month=10, day=1),
on_change=handle_change,
on_dismiss=handle_dismissal,
)
class JsonJober:
@classmethod
def read_json(cls, path_file: str = ""):
"""Чтение json файла"""
with open(path_file, 'r', encoding='utf-8') as file:
data = json.load(file)
return data if isinstance(data, list) else [data]
class Text(ft.Text):
def __init__(self, value: str = ""):
super().__init__(
value=value,
size=24,
color=color[3]
)
class Loger(ft.SnackBar):
def __init__(self, text):
super().__init__(
content=ft.Text(value=text, color=color[3], size=24)
)
class Field(ft.TextField):
def __init__(self, label: str = "", password: bool = False):
super().__init__(
max_lines=1,
border_color=color[3],
color=color[3],
text_size=24,
label=label,
expand=True,
password=password,
can_reveal_password=password,
label_style=ft.TextStyle(
color=color[3],
size=24
),
)
class Button(ft.ElevatedButton):
def __init__(self, text: str = "", on_click: OptionalControlEventCallable = None):
super().__init__(
color=color[3],
bgcolor=color[1],
text=text,
on_click=on_click,
style=ft.ButtonStyle(
overlay_color=color[4],
text_style=ft.TextStyle(
size=24
)
)
)
class TextCellFilter(ft.Container):
def __init__(self,id:int=0, value: str = "", on_click: OptionalControlEventCallable = None):
self.id = id
super().__init__(
border=ft.border.all(1, color[3]),
border_radius=ft.border_radius.all(5),
content=ft.Text(
value=value,
no_wrap=False,
size=24,
color=color[3],
),
on_click=on_click
)
class DownList(ft.Container):
def __init__(self, page: ft.Page, column=[],columns={}, filter=None, load_first: bool = False):
self.columns = columns
if columns:
column = columns["name"]
self.dialog = DropdownDialog(load_first=load_first, data_set=column, on_click=self.on_click_text)
self.filter = filter
self.view_text = Text()
self._id_ = -1
super().__init__(
expand=True,
width=300,
border=ft.border.all(1, color[3]),
border_radius=ft.border_radius.all(5),
content=self.view_text,
on_click=self.open_dialog
)
def load_professions(self):
self.filter.dialog = DropdownDialog(
load_first=False,
data_set=Observer.Professions,
on_click=self.filter.on_click_text
)
def load_positions(self):
self.filter.dialog = DropdownDialog(
load_first=False,
data_set=Observer.Positions,
on_click=self.filter.on_click_text
)
def load_other_positions(self):
self.filter.dialog = DropdownDialog(
load_first=False,
data_set=[],
dismiss=self.filter.click_field
)
def update_filter_list(self):
if self.filter is None:
return
self.filter.view_text.value = ""
if self.view_text.value == "Профессии рабочих":
self.load_professions()
elif self.view_text.value == "Должности служащих, руководителей":
self.load_positions()
elif self.view_text.value == "Иные должности, не указанные в ОКПДТР":
self.load_other_positions()
self.page.update()
self.filter = self.filter
def click_field(self, e):
self.view_text.value = self.dialog.filter_text.value
self.page.close(self.dialog)
self.page.update()
def on_click_text(self, e):
if self.columns:
self._id_ = e.control.id
self.view_text.value = e.control.content.value
self.page.close(self.dialog)
self.update_filter_list()
self.page.update()
def open_dialog(self, e):
self.page.open(self.dialog)
def change_filter_text(self, e):
self.view_text.value = e.control.content.value
self.hidden_text.value = e.control.content.value
self.update()
class ObserverMethod:
@classmethod
def load_dropdown(cls, name_list: str = "", column: str = "", name_lists=[], columns=[]):
from user_data import User_data as ud
if ud.suggestions is None:
ud.suggestions = JsonJober.read_json(path_file=ud.path_json)
if columns:
return cls._load_columns(suggestions=ud.suggestions[0], columns=columns, name_list=name_list)
if name_list:
return cls._load_name_list(ud.suggestions[0], name_list, column)
return cls._load_name_lists(ud.suggestions[0], name_lists)
@staticmethod
def _load_columns(suggestions, columns, name_list=""):
lists = {}
if name_list in suggestions:
for col in columns:
lists[col] = [item for item in suggestions[name_list][col]]
return lists
@staticmethod
def _load_name_list(suggestions, name_list, column):
temp_data_list = []
if column:
if column in suggestions[name_list]:
temp_data_list = [item for item in suggestions[name_list][column]]
else:
temp_data_list = [item for item in suggestions[name_list]]
return temp_data_list
@staticmethod
def _load_name_lists(suggestions, name_lists):
temp_data_list = []
for col in name_lists:
if col in suggestions:
temp_data_list.extend([item for item in suggestions[col]])
return temp_data_list
class Observer:
inn_manufacturing_enterprises = ObserverMethod.load_dropdown(name_list="Manufacturing_enterprises", columns=["name", "inn"])
Manufacturing_enterprises = ObserverMethod.load_dropdown(name_list="Manufacturing_enterprises", column="name")
Classification_professions = ObserverMethod.load_dropdown(name_list="Classification_professions")
Professions = ObserverMethod.load_dropdown(name_list="Professions")
Positions = ObserverMethod.load_dropdown(name_list="Positions")
Specialization = ObserverMethod.load_dropdown(name_list="Specialization")
class DropdownDialog(ft.AlertDialog):
def __init__(self, data_set, dismiss: OptionalControlEventCallable = None, on_click: OptionalControlEventCallable = None, load_first: bool = False):
self.data_set = data_set
self.load_first = load_first
self.filter_text = ft.TextField(on_change=self.filter_data)
self.result = ft.Column(height=230, width=400, controls=[], scroll=True)
self.on_click = on_click
self.init_dialog()
super().__init__(
content=ft.Column(
height=300,
width=500,
controls=[
ft.Row(controls=[self.filter_text]),
self.result,
ft.Button(text="Закрыть", on_click=dismiss),
]
),
on_dismiss=dismiss
)
def init_dialog(self):
temp = []
if not self.load_first:
for itemx, item in enumerate(self.data_set):
if itemx >= 100:
self.result.controls = temp
return
temp.append(TextCellFilter(value=item, on_click=self.on_click,id=itemx))
else:
for iitem, item in enumerate(self.data_set):
temp.append(TextCellFilter(value=item, on_click=self.on_click,id=iitem))
self.result.controls = temp
def filter_data(self, e):
if len(e.control.value) < 3:
return
filter_text = e.control.value.lower()
filtered_data = []
for iitem,item in enumerate(self.data_set):
if filter_text in item.lower():
filtered_data.append(TextCellFilter(value=item, on_click=self.on_click,id=iitem))
self.result.controls = filtered_data
self.result.update()
class DataGrid(ft.DataTable):
def __init__(self, page: ft.Page):
self.page = page
self.column_name = None
self.load_column_names()
super().__init__(columns=self.add_list_column_names())
def return_data(self):
return self.rows
def load_column_names(self):
if not self.column_name:
url = "http://localhost:8001/api-data-base/get_name_column?table_name=%D0%A1ollection_form_opk"
try:
response = requests.post(url)
if response.status_code == 200:
self.column_name = response.json()
else:
print(f"Error: Received status code {response.status_code}")
except requests.exceptions.RequestException as e:
print(f"Error: {e}")
def add_list_column_names(self):
temp_data = []
if self.column_name:
for col in self.column_name:
if col not in ["id", "ПОО", "Субъект_рф", "ИНН_ОПК", "время_создания", "указаноеремя"]:
temp_data.append(ft.DataColumn(label=Text(value=col)))
return temp_data
def load_new_row(self):
temp_data = []
temp = DownList(page=self.page, column=Observer.Professions)
for col in self.column_name:
if col in ["id", "ПОО", "Субъект_рф", "ИНН_ОПК", "время_создания", "указаноеремя"]:
continue
if col == "ОПК":
temp_data.append(ft.DataCell(content=DownList(load_first=True, page=self.page, columns=Observer.inn_manufacturing_enterprises)))
elif col == "Группа_профессий_должностей":
temp_data.append(ft.DataCell(content=DownList(filter=temp, load_first=True, page=self.page, column=Observer.Classification_professions)))
elif col == "Наименование_профессии":
temp_data.append(ft.DataCell(content=temp))
elif col == "Профессии_специальности_СПО":
temp_data.append(ft.DataCell(content=DownList(page=self.page, column=Observer.Specialization)))
else:
temp_data.append(ft.DataCell(content=Field()))
return temp_data
def add_new_row(self, e):
self.rows.append(ft.DataRow(cells=self.load_new_row()))
self.update()

View File

@@ -1,39 +0,0 @@
FROM python:3.11.8-slim AS build
# Устанавливаем рабочую директорию
WORKDIR /app
# Копируем файл с зависимостями в контейнер
COPY ./app/requirements.txt .
# Устанавливаем необходимые зависимости
RUN pip install -r requirements.txt
# Устанавливаем необходимые утилиты
RUN apt-get update && \
apt-get install -y wget unzip xz-utils git clang cmake ninja-build pkg-config curl libgtk-3-dev
# Устанавливаем Flutter SDK
RUN wget https://storage.googleapis.com/flutter_infra_release/releases/stable/linux/flutter_linux_3.24.0-stable.tar.xz && \
tar xf flutter_linux_3.24.0-stable.tar.xz && \
mv flutter /usr/local/flutter && \
git config --global --add safe.directory /usr/local/flutter && \
/usr/local/flutter/bin/flutter doctor
# Обновляем PATH для Flutter
ENV PATH="/usr/local/flutter/bin:${PATH}"
# Копируем файл с кодом в контейнер
COPY ./app/ .
# Выполняем сборку проекта
RUN flet build web
# Используем официальный образ Nginx для развертывания
FROM nginx:latest AS final
# Копируем собранные файлы в директорию Nginx
COPY --from=build /app/build/web /usr/share/nginx/html
# Копируем конфигурационный файл Nginx (если требуется)
COPY ./app/nginx.conf /etc/nginx/nginx.conf

View File

@@ -1,16 +1,6 @@
import flet as ft
from view import ViewsHendler
import designer as ds
def main():
print("Hello from app!")
def main(page: ft.Page):
page.title = "COPP"
def PageLoading(route):
print(page.route)
page.views.clear()
page.views.append(ViewsHendler(page=page)[page.route])
page.update()
page.on_route_change = PageLoading
page.go("/")
ft.app(target=main, port=80345 ,assets_dir="assets")
if __name__ == "__main__":
main()

View File

@@ -1,121 +0,0 @@
import flet as ft
from designer import color, Button, Text, DataPicer, DataGrid, DownList, Field, Loger,Observer
from user_data import User_data
import pydantic as pd
import datetime
import json
class Add_new_data(ft.View):
def __init__(self, page: ft.Page):
self.data_grid = DataGrid(page=page)
self.creation_time = datetime.datetime.today()
super().__init__(
route="/add_new_data",
bgcolor=color[2],
controls=[
ft.Column(
controls=[
ft.Container(
padding=ft.padding.all(20),
border_radius=ft.border_radius.all(10),
height=70,
expand=True,
bgcolor=color[3],
content=ft.Row(
expand=True,
controls=[
Button(text="профиль"),
Button(text="мои данные"),
Button(text="заполнить данные"),
]
)
),
ft.Container(
content=ft.Row(
scroll=True,
controls=[
ft.Column(
controls=[
self.data_grid,
Button(text="+", on_click=self.data_grid.add_new_row),
Button(text="сохранить", on_click=self.open_data_picer),
]
),
]
),
),
]
)
]
)
def send_data_to_api(self, save_data, api_url: str):
import requests
headers = {'Content-Type': 'application/json'}
response = requests.post(api_url, headers=headers, data=json.dumps(save_data))
return response
def validdate(self, item, column):
columns = {}
count_void = 0
icol = 1
current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
columns[column[icol]] = current_time
icol += 1
columns[column[icol]] = str(self.creation_time.strftime("%Y-%m-%d"))
icol += 1
columns[column[icol]] = User_data.name_poo
icol += 1
columns[column[icol]] = "test"
icol += 1
for cell in item.cells:
print(f"{icol}")
if isinstance(cell.content, DownList):
if cell.content.view_text.value == "":
Loger(text="строку с пустыми выподающими списками")
break
elif cell.content._id_ != -1:
columns[column[icol]] = Observer.inn_manufacturing_enterprises["inn"][cell.content._id_]
icol += 1
columns[column[icol]] = cell.content.view_text.value
else:
columns[column[icol]] = cell.content.view_text.value
elif isinstance(cell.content, Field):
if cell.content.value == "":
columns[column[icol]] = "0"
else:
columns[column[icol]] = cell.content.value
icol += 1
return columns
def handle_change(self, e):
self.creation_time = e.control.value
self.save_data()
def handle_dismissal(self, e):
pass
def open_data_picer(self, e):
self.page.open(
DataPicer(creation_time=self.creation_time, handle_change=self.handle_change, handle_dismissal=self.handle_dismissal)
)
def save_data(self):
temp = self.data_grid.return_data()
column = self.data_grid.column_name
rows = []
for item in temp:
rows.append(self.validdate(item=item, column=column))
print(f"{rows=}")
table_name = "Сollection_form_opk"
api_url = f'http://localhost:8001/api-data-base/insert_table'
save_data_instance = {
"data": rows
}
response = self.send_data_to_api(save_data_instance, api_url)
if response.status_code == 200:
print("Данные успешно отправлены")
else:
print(f"Ошибка при отправке данных: {response.status_code}")

View File

@@ -1,20 +0,0 @@
import flet as ft
import designer as des
class Add_user_data(ft.View):
def __init__(self,page:ft.Page,route:str=""):
super().__init__(
bgcolor=des.color[2],
route=route,
controls=[
ft.Column(
controls=[
ft.Row(
controls=[
]
)
]
)
]
)

View File

@@ -1,80 +0,0 @@
import flet as ft
from designer import Field, color, Button, Loger, JsonJober
import requests
class Login(ft.Column):
def __init__(self, page: ft.Page = None):
self.page = page
self.login = Field(label="Login"),
self.password = Field(label="Password", password=True)
super().__init__(
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
expand=True,
controls=[
ft.Row(
alignment=ft.MainAxisAlignment.CENTER,
controls=[
ft.Text(color=color[1], size=42, value="Copp")
]
),
ft.Row(
alignment=ft.MainAxisAlignment.CENTER,
controls=[
self.login[0]
]
),
ft.Row(
alignment=ft.MainAxisAlignment.CENTER,
controls=[
self.password
]
),
ft.Row(
alignment=ft.MainAxisAlignment.CENTER,
controls=[
Button(text="Enter", on_click=self.enter_go_to_next_page)
]
)
]
)
def Load_user_inf(self, response):
from user_data import User_data as ud
if response is not None:
# Используем .get() для безопасного доступа к ключам
ud.id = response.get("id")
ud.inn = response.get("inn") # Если ключ 'inn' отсутствует, будет None
ud.name_poo = response.get("name_poo")
ud.mail = response.get("mail")
ud.suggestions = JsonJober.read_json(ud.path_json)
print(f"{ud.id=}, {ud.inn=}, {ud.name_poo=}, {ud.mail=}")
else:
print("Ошибка: Пустой ответ от сервера")
def enter_go_to_next_page(self, e):
url = "http://localhost:8000/api/api/login"
data = {
"login": self.login[0].value,
"password": self.password.value
}
try:
response = requests.post(url, json=data)
if response.status_code == 200:
# Получаем JSON-данные из ответа
response_data = response.json() # Используем метод .json() для извлечения данных
# Проверяем сообщение в ответе
if response_data.get("message") == "Авторизация успешна.":
user = response_data.get("user") # Достаем пользователя из ответа
if user.get("id") == 0:
self.page.open(Loger(text="Неверные данные"))
else:
self.Load_user_inf(response=user)
self.page.go("/user_info")
elif response_data.get("message") == "Неверные данные":
self.page.open(Loger(text="Неверные данные"))
else:
print("Ошибка:", response.status_code, response.text)
except requests.exceptions.RequestException as e:
print(f"Ошибка запроса: {e}")

View File

@@ -1,32 +0,0 @@
import flet as ft
import designer as des
class My_data(ft.View):
def __init__(self,page:ft.Page,route:str="/my_data"):
super().__init__(
bgcolor=des.color[2],
route=route,
controls=[
ft.Column(
controls=[
ft.Container(
padding=ft.padding.all(20),
border_radius=ft.border_radius.all(10),
height=70,
expand=True,
bgcolor=des.color[3],
content=ft.Row(
expand=True,
controls=[
des.Button(text="профиль"),
des.Button(text="мои данные",on_click = self.go_to_my_data),
des.Button(text="заполнить данные", on_click=self.go_to_data),
]
)
),
]
)
]
)

View File

@@ -1,5 +0,0 @@
import flet as ft
import designer as ds
import requests
from user_data import User_data as ud

View File

@@ -1,48 +0,0 @@
import flet as ft
from designer import color, Button,Text
from user_data import User_data
class User_info(ft.View):
def __init__(self, page:ft.Page):
super().__init__(
route="/user_info",
bgcolor=color[2],
controls=[
ft.Column(
controls=[
ft.Container(
padding=ft.padding.all(20),
border_radius=ft.border_radius.all(10),
height=70,
expand=True,
bgcolor=color[3],
content=ft.Row(
expand=True,
controls=[
Button(text="профиль"),
Button(text="мои данные",on_click = self.go_to_my_data),
Button(text="заполнить данные", on_click=self.go_to_data),
]
)
),
ft.Container(
expand=True,
content=ft.Column(
controls=[
ft.Row(controls=[Text(value="Имя ПОО"),Text(value=User_data.name_poo)]),
ft.Row(controls=[Text(value="ИНН"),Text(value=User_data.inn)]),
ft.Row(controls=[Text(value="Mail"),Text(value=User_data.mail)])
]
)
)
]
)
]
)
def go_to_info(self,e):
self.page.go("/user_info")
def go_to_my_data(self,e):
self.page.go("/my_data")
def go_to_data(self,e):
self.page.go("/add_new_data")

View File

@@ -1,5 +0,0 @@
flet
flet-core
flet-desktop
bcrypt
requests

BIN
app/src/assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

26
app/src/main.py Normal file
View File

@@ -0,0 +1,26 @@
import flet as ft
def main(page: ft.Page):
counter = ft.Text("0", size=50, data=0)
def increment_click(e):
counter.data += 1
counter.value = str(counter.data)
counter.update()
page.floating_action_button = ft.FloatingActionButton(
icon=ft.Icons.ADD, on_click=increment_click
)
page.add(
ft.SafeArea(
ft.Container(
counter,
alignment=ft.alignment.center,
),
expand=True,
)
)
ft.app(main)

View File

@@ -1,7 +0,0 @@
class User_data():
id:int=0
name_poo:str=""
inn:str=""
mail:str=""
suggestions = None
path_json:str="./assets/test.json"

View File

@@ -1,17 +0,0 @@
import flet as ft
from designer import color
from pages import login,user_info,add_new_data,my_data
def ViewsHendler(page:ft.Page):
return {
"/":ft.View(
route="/",
controls=[
login.Login(page=page)
],
bgcolor=color[2]
),
"/user_info":user_info.User_info(page=page),
"/my_data":my_data.My_data(page=page),
"/add_new_data":add_new_data.Add_new_data(page=page)
}

View File

@@ -1,2 +0,0 @@
# api
api-copp

View File

@@ -1,20 +0,0 @@
from kafka import KafkaProducer,KafkaConsumer
import redis
import json
redis_client = redis.StrictRedis(host="redis", port=6379, db=0)
consumer = KafkaConsumer(
'login-topic',
bootstrap_servers='kafka:9092',
value_deserializer=lambda x: json.loads(x.decode('utf-8')),
api_version = (0,10,2),
auto_offset_reset='earliest',
group_id='0'
)
producer = KafkaProducer(
bootstrap_servers='kafka:9092',
api_version = (0,10,2),
value_serializer=lambda v: json.dumps(v).encode('utf-8')
)

View File

@@ -1,15 +0,0 @@
# Используем официальный образ Python
FROM python:3.11.8-slim AS build
# Устанавливаем рабочую директорию
WORKDIR /api
# Копируем файл с зависимостями в контейнер
COPY ./server/api/requirements.txt .
# Устанавливаем необходимые зависимости
RUN pip install -r requirements.txt
# Копируем файл с кодом в контейнер
COPY ./server/api/ .
FROM build AS final
WORKDIR /api
# Команда для запуска приложения
CMD ["python", "-u", "main.py"]

View File

@@ -1,9 +0,0 @@
from fastapi import FastAPI
from router import router
app = FastAPI(title="api")
app.include_router(router)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)

View File

@@ -1,13 +0,0 @@
from pydantic import BaseModel
class collection_form(BaseModel):
login:str
data:list
class Message(BaseModel):
key: str
value: str
class Login(BaseModel):
login:str
password:str

View File

@@ -1,6 +0,0 @@
fastapi
uvicorn
kafka-python
python-dotenv
redis
httpx

View File

@@ -1,43 +0,0 @@
import model_messege as mm
from config_kafka import producer, consumer, redis_client
import threading
import json
from fastapi import APIRouter
import httpx
router = APIRouter(prefix="/api")
@router.post("/api/validation_collection_form")
async def validation_collection_form():
return {
"message": "Ошибка валидации формы"
}
@router.post("/api/login")
async def login(auth_request: mm.Login):
login = auth_request.login
password = auth_request.password
print(f"login: {login}, password: {password}")
# Отправляем данные в другую API
async with httpx.AsyncClient() as client:
response = await client.post("http://api-data-base:8001/api-data-base/login", json={'login': login, 'password': password})
# Проверяем статус ответа
if response.status_code == 200:
user_data = response.json()
return {
"message": "Авторизация успешна.",
"user": user_data
}
else:
return {
"message": "Ошибка авторизации",
"user": None
}
@router.on_event("shutdown")
def shutdown_event():
producer.close()