import gradio as gr import torch import os from classifier_app import ClassifierApp, config from typing import Dict def create_interface(app: ClassifierApp) -> gr.Blocks: """Створення веб-інтерфейсу""" # Синхронізуємо інформацію перед створенням інтерфейсу initial_info = app.sync_system_info() with gr.Blocks() as demo: gr.Markdown("# SDC Classifier") with gr.Tabs(): # Вкладка 1: Тестування одного тексту with gr.TabItem("Тестування одного тексту"): with gr.Row(): with gr.Column(): text_input = gr.Textbox( label="Введіть текст для аналізу", lines=5, placeholder="Введіть текст..." ) threshold_slider = gr.Slider( minimum=0.0, maximum=1.0, value=0.3, step=0.05, label="Поріг впевненості" ) single_process_btn = gr.Button("Проаналізувати") with gr.Column(): result_text = gr.JSON(label="Результати аналізу") with gr.Accordion("Налаштування моделі", open=False): with gr.Row(): model_type = gr.Radio( choices=["OpenAI", "Local"], value="OpenAI", label="Тип моделі" ) model_choice = gr.Dropdown( choices=config.DEFAULT_OPENAI_MODELS, value=config.DEFAULT_OPENAI_MODELS[0], label="OpenAI model", visible=True ) local_model_path = gr.Textbox( value=config.DEFAULT_LOCAL_MODEL, label="Шлях до локальної моделі", visible=False ) device_choice = gr.Radio( choices=["cuda", "cpu"], value="cuda" if torch.cuda.is_available() else "cpu", label="Пристрій для локальної моделі", visible=False ) with gr.Row(): json_file = gr.File( label="Завантажити новий JSON з класами", file_types=[".json"] ) force_rebuild = gr.Checkbox( label="Примусово перебудувати signatures", value=False ) with gr.Row(): build_btn = gr.Button("Оновити signatures") build_out = gr.Label(label="Статус signatures") cache_stats = gr.JSON(label="Статистика кешу", value={}) # Вкладка 2: Інформація про систему with gr.TabItem("Інформація про систему"): system_info = gr.JSON( value=app.initial_info, label="Статус системи" ) system_md = gr.Markdown() system_md.value = app.update_system_markdown(app.initial_info) # Вкладка 3: Пакетна обробка with gr.TabItem("Пакетна обробка"): gr.Markdown("## 1) Завантаження даних") with gr.Row(): csv_input = gr.Textbox( value="messages.csv", label="CSV-файл" ) emb_input = gr.Textbox( value="embeddings.npy", label="Numpy Embeddings" ) load_btn = gr.Button("Завантажити дані") load_output = gr.Label(label="Результат завантаження") gr.Markdown("## 2) Класифікація") with gr.Row(): filter_in = gr.Textbox(label="Фільтр (опціонально)") batch_threshold = gr.Slider( minimum=0.0, maximum=1.0, value=0.3, step=0.05, label="Поріг впевненості" ) classify_btn = gr.Button("Класифікувати") classify_out = gr.Dataframe(label="Результат (Message / Target / Scores)") gr.Markdown("## 3) Зберегти результати") save_btn = gr.Button("Зберегти розмічені дані") save_out = gr.Label() # Підключення обробників подій model_type.change( fn=app.update_model_inputs, inputs=[ model_type, model_choice, local_model_path, device_choice ], outputs=[ model_choice, local_model_path, device_choice, system_info, system_md, build_out, cache_stats ] ) build_btn.click( fn=app.update_classifier_settings, inputs=[ json_file, model_type, model_choice, local_model_path, device_choice, force_rebuild ], outputs=[build_out, cache_stats, system_info, system_md] ) single_process_btn.click( fn=app.process_single_text, inputs=[text_input, threshold_slider], outputs=result_text ) load_btn.click( fn=app.load_data, inputs=[csv_input, emb_input], outputs=load_output ) classify_btn.click( fn=app.classify_batch, inputs=[filter_in, batch_threshold], outputs=classify_out ) save_btn.click( fn=app.save_results, inputs=[], outputs=save_out ) return demo def main(): try: print("\nЗапуск програми...") app = ClassifierApp() print("\nПочаток ініціалізації середовища...") init_result, classifier = app.initialize_environment() print("\nРезультат ініціалізації:") print(f"Статус: {init_result['status']}") if init_result.get('errors'): print("Помилки:", init_result['errors']) if classifier is None or init_result["status"] != "success": print("\nНе вдалося ініціалізувати середовище") return print(f"\nІнформація про систему:") print(f"Кількість завантажених класів: {len(init_result['classes_info']['classes_list'])}") print(f"Сигнатури: {'Завантажено' if os.path.exists(config.DEFAULT_SIGNATURES_FILE) else 'Створюються'}") demo = create_interface(app) demo.launch(server_name="0.0.0.0", server_port=7860, share=True) except Exception as e: print(f"\nКритична помилка в main(): {str(e)}") import traceback print("\nДетальний traceback:") print(traceback.format_exc()) if __name__ == "__main__": main()