146 lines
6.1 KiB
Python
146 lines
6.1 KiB
Python
"""
|
||
Страница асинхронной загрузки файлов
|
||
"""
|
||
import streamlit as st
|
||
import asyncio
|
||
import threading
|
||
import time
|
||
from api_client import upload_file_to_api
|
||
from config import PARSER_TABS
|
||
|
||
|
||
def upload_file_async_background(endpoint, file_data, filename, task_id):
|
||
"""Асинхронная загрузка файла в фоновом режиме"""
|
||
try:
|
||
# Имитируем асинхронную работу
|
||
time.sleep(1) # Небольшая задержка для демонстрации
|
||
|
||
# Выполняем загрузку
|
||
result, status = upload_file_to_api(endpoint, file_data, filename)
|
||
|
||
# Сохраняем результат в session_state
|
||
if 'upload_tasks' not in st.session_state:
|
||
st.session_state.upload_tasks = {}
|
||
|
||
st.session_state.upload_tasks[task_id] = {
|
||
'status': 'completed' if status == 200 else 'failed',
|
||
'result': result,
|
||
'status_code': status,
|
||
'filename': filename,
|
||
'endpoint': endpoint,
|
||
'completed_at': time.time()
|
||
}
|
||
|
||
except Exception as e:
|
||
# Сохраняем ошибку
|
||
if 'upload_tasks' not in st.session_state:
|
||
st.session_state.upload_tasks = {}
|
||
|
||
st.session_state.upload_tasks[task_id] = {
|
||
'status': 'failed',
|
||
'error': str(e),
|
||
'filename': filename,
|
||
'endpoint': endpoint,
|
||
'completed_at': time.time()
|
||
}
|
||
|
||
|
||
def render_async_upload_page():
|
||
"""Рендер страницы асинхронной загрузки"""
|
||
st.title("🚀 Асинхронная загрузка файлов")
|
||
st.markdown("---")
|
||
|
||
st.info("""
|
||
**Асинхронная загрузка** позволяет загружать файлы без блокировки интерфейса.
|
||
После загрузки файл будет обработан в фоновом режиме, а вы сможете отслеживать прогресс на странице "Управление задачами".
|
||
""")
|
||
|
||
# Выбор парсера
|
||
st.subheader("📋 Выбор парсера")
|
||
|
||
# Создаем словарь парсеров с их асинхронными эндпоинтами
|
||
parser_endpoints = {
|
||
"Сводки ПМ": "/async/svodka_pm/upload-zip",
|
||
"Сводки СА": "/async/svodka_ca/upload",
|
||
"Мониторинг топлива": "/async/monitoring_fuel/upload-zip",
|
||
"Ремонт СА": "/svodka_repair_ca/upload", # Пока синхронный
|
||
"Статусы ремонта СА": "/statuses_repair_ca/upload", # Пока синхронный
|
||
"Мониторинг ТЭР": "/monitoring_tar/upload", # Пока синхронный
|
||
"Операционные справки": "/oper_spravka_tech_pos/upload" # Пока синхронный
|
||
}
|
||
|
||
selected_parser = st.selectbox(
|
||
"Выберите тип парсера для загрузки:",
|
||
list(parser_endpoints.keys()),
|
||
key="async_parser_select"
|
||
)
|
||
|
||
st.markdown("---")
|
||
|
||
# Загрузка файла
|
||
st.subheader("📤 Загрузка файла")
|
||
|
||
uploaded_file = st.file_uploader(
|
||
f"Выберите ZIP архив для парсера '{selected_parser}'",
|
||
type=['zip'],
|
||
key="async_file_upload"
|
||
)
|
||
|
||
if uploaded_file is not None:
|
||
st.success(f"✅ Файл выбран: {uploaded_file.name}")
|
||
st.info(f"📊 Размер файла: {uploaded_file.size / 1024 / 1024:.2f} MB")
|
||
|
||
if st.button("🚀 Загрузить асинхронно", key="async_upload_btn", use_container_width=True):
|
||
# Создаем уникальный ID задачи
|
||
task_id = f"task_{int(time.time())}_{uploaded_file.name}"
|
||
|
||
# Показываем сообщение о создании задачи
|
||
st.success("✅ Задача загрузки создана!")
|
||
st.info(f"ID задачи: `{task_id}`")
|
||
st.info("📋 Перейдите на страницу 'Управление задачами' для отслеживания прогресса")
|
||
|
||
# Запускаем загрузку в фоновом потоке
|
||
endpoint = parser_endpoints[selected_parser]
|
||
file_data = uploaded_file.read()
|
||
|
||
# Создаем поток для асинхронной загрузки
|
||
thread = threading.Thread(
|
||
target=upload_file_async_background,
|
||
args=(endpoint, file_data, uploaded_file.name, task_id)
|
||
)
|
||
thread.daemon = True
|
||
thread.start()
|
||
|
||
# Автоматически переключаемся на страницу задач
|
||
st.session_state.sidebar_tasks_clicked = True
|
||
st.rerun()
|
||
|
||
st.markdown("---")
|
||
|
||
# Информация о поддерживаемых форматах
|
||
with st.expander("ℹ️ Поддерживаемые форматы файлов"):
|
||
st.markdown("""
|
||
**Поддерживаемые форматы:**
|
||
- 📦 ZIP архивы с Excel файлами
|
||
- 📊 Excel файлы (.xlsx, .xls)
|
||
- 📋 CSV файлы (для некоторых парсеров)
|
||
|
||
**Ограничения:**
|
||
- Максимальный размер файла: 100 MB
|
||
- Количество файлов в архиве: до 50
|
||
- Поддерживаемые кодировки: UTF-8, Windows-1251
|
||
""")
|
||
|
||
# Статистика загрузок
|
||
st.subheader("📈 Статистика загрузок")
|
||
|
||
col1, col2, col3 = st.columns(3)
|
||
|
||
with col1:
|
||
st.metric("Всего загружено", "0", "0")
|
||
|
||
with col2:
|
||
st.metric("В обработке", "0", "0")
|
||
|
||
with col3:
|
||
st.metric("Завершено", "0", "0") |