bertrend 0.4.7__tar.gz → 0.4.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {bertrend-0.4.7 → bertrend-0.4.9}/PKG-INFO +6 -1
- {bertrend-0.4.7 → bertrend-0.4.9}/README.md +5 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/data_provider/data_provider.py +39 -14
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/queue_management/bertrend_worker.py +82 -21
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/queue_management/queue_manager.py +49 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/queue_management/rabbitmq_config.py +4 -1
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/queue_monitor/app.py +156 -5
- bertrend-0.4.9/bertrend/services/article_scoring_server/config/default_config.toml +3 -0
- bertrend-0.4.9/bertrend/services/article_scoring_server/config/settings.py +32 -0
- bertrend-0.4.9/bertrend/services/article_scoring_server/models.py +21 -0
- bertrend-0.4.9/bertrend/services/article_scoring_server/routers/info.py +19 -0
- bertrend-0.4.9/bertrend/services/article_scoring_server/routers/scoring.py +43 -0
- bertrend-0.4.9/bertrend/services/article_scoring_server/scoring_service.py +12 -0
- bertrend-0.4.9/bertrend/services/article_scoring_server/start.py +18 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/data_provider/test_data_provider_base.py +40 -12
- bertrend-0.4.9/bertrend/tests/services/article_scoring/test_article_scoring_server.py +84 -0
- bertrend-0.4.9/bertrend/tests/services/queue_management/__init__.py +4 -0
- bertrend-0.4.9/bertrend/tests/services/queue_management/test_bertrend_worker.py +294 -0
- bertrend-0.4.9/bertrend/tests/services/queue_management/test_queue_manager.py +146 -0
- bertrend-0.4.9/bertrend/tests/services/scheduling/__init__.py +4 -0
- bertrend-0.4.9/bertrend/tests/services/summarizer/__init__.py +4 -0
- bertrend-0.4.9/bertrend/tests/services/summary/__init__.py +4 -0
- bertrend-0.4.9/bertrend/tests/utils/__init__.py +4 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/pyproject.toml +1 -1
- {bertrend-0.4.7 → bertrend-0.4.9}/AUTHORS.txt +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/LICENSE.md +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/BERTopicModel.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/BERTrend.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/article_scoring/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/article_scoring/article_scoring.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/article_scoring/prompts.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/article_scoring/scoring_agent.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/common/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/common/apscheduler_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/common/crontab_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/common/date_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/common/mail_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/common/scheduler_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/config/feeds/arxiv_feed.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/config/feeds/decarbonation_feed.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/config/feeds/feed_deep_research_example.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/config/feeds/llm_en_feed.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/config/feeds/llm_feed.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/config/feeds/nlp_feed.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/config/feeds/rte_feed.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/config/newsletters/arxiv_newsletter_from_last.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/config/newsletters/decarbonation_newsletter_from_last.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/config/newsletters/llm_en_newsletter_from_last.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/config/newsletters/llm_newsletter_from_last.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/config/newsletters/nlp_newsletter_from_last.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/config/newsletters/rte_newsletter_from_last.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/data_provider/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/data_provider/__main__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/data_provider/arxiv_provider.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/data_provider/atom_feed_provider.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/data_provider/bing_news_provider.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/data_provider/data_provider_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/data_provider/deep_research_provider.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/data_provider/google_news_provider.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/data_provider/newscatcher_provider.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/data_provider/rss_feed_provider.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/data_provider/utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/curebot/.streamlit/config.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/curebot/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/curebot/app.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/curebot/app_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/curebot/config.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/curebot/import_extraction_article.ipynb +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/curebot/prompts.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/curebot/start_newsletter_generator.sh +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/curebot/tabs/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/curebot/tabs/tab1.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/curebot/tabs/tab2.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/curebot/tabs/tab3.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/geoviz/.streamlit/config.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/geoviz/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/geoviz/app.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/geoviz/backend.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/start_apps.sh +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/exploration/stop_apps.sh +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/install_feeds_and_newsletters.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/newsletters/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/newsletters/__main__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/newsletters/newsletter_generation.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/newsletters/utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/.streamlit/config.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/.streamlit/secrets.toml.example +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/app.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/authentication.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/automated_report_generation.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/dashboard_analysis.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/dashboard_common.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/dashboard_comparative.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/dashboard_signals.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/data_model.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/detailed_report_template.html +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/feeds_common.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/feeds_config.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/feeds_data.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/i18n.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/i18n_translations.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/llm_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/models_info.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/perf_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/process_new_data.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/report_generation.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/report_generation_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/start_demo.sh +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/prospective_demo/utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/bertrend_service.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/config/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/config/default_config.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/config/settings.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/models/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/models/bertrend_app_models.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/models/data_provider_models.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/models/newsletters_models.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/routers/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/routers/bertrend_app.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/routers/data_provider.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/routers/info.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/routers/newsletters.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/start.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/status.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/bertrend/stop.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/queue_management/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/queue_management/client.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/queue_management/docker-compose-rabbitmq.yml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/queue_management/start_rabbitmq.sh +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/queue_monitor/.streamlit/config.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/queue_monitor/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/utils/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/utils/logging_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/config/bertopic_default_config.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/config/bertrend_default_config.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/config/parameters.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/config/services_default_config.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/demos_utils/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/demos_utils/data_loading_component.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/demos_utils/embed_documents_component.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/demos_utils/i18n.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/demos_utils/i18n_translations.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/demos_utils/icons.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/demos_utils/parameters_component.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/demos_utils/state_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/start_summarizer_app.sh +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/start_topic_analysis_app.sh +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/start_weak_signals_app.sh +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/streamlit_components/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/streamlit_components/clickable_df_component.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/streamlit_components/input_with_pills_component.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/summarization/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/summarization/summarizer_app.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/topic_analysis/.streamlit/config.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/topic_analysis/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/topic_analysis/app.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/topic_analysis/app_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/topic_analysis/demo_pages/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/topic_analysis/demo_pages/explore_topics.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/topic_analysis/demo_pages/newsletters_generation.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/topic_analysis/demo_pages/temporal_visualizations.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/topic_analysis/demo_pages/topic_visualizations.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/topic_analysis/demo_pages/training_page.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/topic_analysis/i18n_translations.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/weak_signals/.streamlit/config.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/weak_signals/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/weak_signals/app.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/weak_signals/i18n_translations.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/demos/weak_signals/visualizations_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/llm_utils/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/llm_utils/agent_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/llm_utils/newsletter.css +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/llm_utils/newsletter_features.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/llm_utils/newsletter_model.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/llm_utils/newsletter_outlook_template.html +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/llm_utils/newsletter_template.html +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/llm_utils/openai_client.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/llm_utils/prompts.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/metrics/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/metrics/temporal_metrics_embedding.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/metrics/topic_metrics.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/resources/common_ngrams.json +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/resources/stopwords-en.json +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/resources/stopwords-fr.json +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/resources/stopwords-rte.json +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/__init__.py +0 -0
- {bertrend-0.4.7/bertrend/services/embedding_server → bertrend-0.4.9/bertrend/services/article_scoring_server}/__init__.py +0 -0
- {bertrend-0.4.7/bertrend/services/embedding_server/routers → bertrend-0.4.9/bertrend/services/article_scoring_server/config}/__init__.py +0 -0
- {bertrend-0.4.7/bertrend/services/scheduling → bertrend-0.4.9/bertrend/services/article_scoring_server/routers}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/authentication.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/cert.pem +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_client.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_server/README.md +0 -0
- {bertrend-0.4.7/bertrend/services/scheduling/job_utils → bertrend-0.4.9/bertrend/services/embedding_server}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_server/bertrend_client_registry.json +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_server/config/default_config.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_server/config/settings.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_server/main.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_server/models.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_server/requirements.txt +0 -0
- {bertrend-0.4.7/bertrend/services/scheduling/models → bertrend-0.4.9/bertrend/services/embedding_server/routers}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_server/routers/authentication.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_server/routers/embeddings.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_server/routers/info.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_server/security.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_server/start.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_server/status.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_server/stop.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/embedding_service.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/key.pem +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/scheduling/.dockerignore +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/scheduling/Docker_setup.md +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/scheduling/Dockerfile +0 -0
- {bertrend-0.4.7/bertrend/services/summary → bertrend-0.4.9/bertrend/services/scheduling}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/scheduling/dashboard_scheduling.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/scheduling/docker-compose.yml +0 -0
- {bertrend-0.4.7/bertrend/services/summary_server → bertrend-0.4.9/bertrend/services/scheduling/job_utils}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/scheduling/job_utils/job_functions.py +0 -0
- {bertrend-0.4.7/bertrend/services/summary_server/config → bertrend-0.4.9/bertrend/services/scheduling/models}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/scheduling/models/scheduling_models.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/scheduling/requirements.txt +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/scheduling/routers/info.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/scheduling/routers/scheduling.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/scheduling/scheduling_service.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/scheduling/start_docker_scheduling_service.sh +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/summarizer.py +0 -0
- {bertrend-0.4.7/bertrend/services/summary_server/routers → bertrend-0.4.9/bertrend/services/summary}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/summary/abstractive_summarizer.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/summary/chatgpt_summarizer.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/summary/extractive_summarizer.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/summary/lexrank.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/summary/prompts.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/summary_client.py +0 -0
- {bertrend-0.4.7/bertrend/tests → bertrend-0.4.9/bertrend/services/summary_server}/__init__.py +0 -0
- {bertrend-0.4.7/bertrend/tests/apps → bertrend-0.4.9/bertrend/services/summary_server/config}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/summary_server/config/default_config.toml +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/summary_server/config/settings.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/summary_server/main.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/summary_server/models.py +0 -0
- {bertrend-0.4.7/bertrend/tests/core → bertrend-0.4.9/bertrend/services/summary_server/routers}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/summary_server/routers/info.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/summary_server/routers/summarize.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/services/summary_server/start.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/README_integration_tests.md +0 -0
- {bertrend-0.4.7/bertrend/tests/data_provider → bertrend-0.4.9/bertrend/tests}/__init__.py +0 -0
- {bertrend-0.4.7/bertrend/tests/demos → bertrend-0.4.9/bertrend/tests/apps}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/apps/test_process_new_data.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/conftest.py +0 -0
- {bertrend-0.4.7/bertrend/tests/demos/summarization → bertrend-0.4.9/bertrend/tests/core}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/core/test_bertrend.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/core/test_data_structure.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/core/test_representative_docs.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/core/test_temporal_metrics_embedding.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/core/test_topic_description.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/core/test_topic_metrics.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/core/test_topic_model.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/core/test_trend_analysis_data_structure.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/core/test_trend_analysis_prompts.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/core/test_trend_analysis_visualizations.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/core/test_trend_analysis_weak_signals.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/core/test_visualizations.py +0 -0
- {bertrend-0.4.7/bertrend/tests/llm → bertrend-0.4.9/bertrend/tests/data_provider}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/data_provider/test_arxiv_provider.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/data_provider/test_bing_news_provider.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/data_provider/test_data_provider_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/data_provider/test_deep_research_live.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/data_provider/test_deep_research_provider.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/data_provider/test_google_news_provider.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/data_provider/test_newscatcher_provider.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/data_provider/test_rss_atom_provider.py +0 -0
- {bertrend-0.4.7/bertrend/tests/services → bertrend-0.4.9/bertrend/tests/demos}/__init__.py +0 -0
- {bertrend-0.4.7/bertrend/tests/services/embedding → bertrend-0.4.9/bertrend/tests/demos/summarization}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/demos/summarization/test_summarizer_app.py +0 -0
- {bertrend-0.4.7/bertrend/tests/services/embedding_server → bertrend-0.4.9/bertrend/tests/llm}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/llm/test_agent_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/llm/test_article_scoring.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/llm/test_article_scoring_models.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/llm/test_newsletter_features.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/llm/test_newsletter_model.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/llm/test_openai_client.py +0 -0
- {bertrend-0.4.7/bertrend/tests/services/queue → bertrend-0.4.9/bertrend/tests/services}/__init__.py +0 -0
- {bertrend-0.4.7/bertrend/tests/services/scheduling → bertrend-0.4.9/bertrend/tests/services/article_scoring}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/bertrend/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/bertrend/test_bertrend_service.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/bertrend/test_models.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/bertrend/test_routers_bertrend_app.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/bertrend/test_routers_info.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/bertrend/test_routers_newsletters.py +0 -0
- {bertrend-0.4.7/bertrend/tests/services/summarizer → bertrend-0.4.9/bertrend/tests/services/embedding}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/embedding/test_embedding_client.py +0 -0
- {bertrend-0.4.7/bertrend/tests/services/summary → bertrend-0.4.9/bertrend/tests/services/embedding_server}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/embedding_server/test_models.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/embedding_server/test_routers.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/embedding_server/test_security.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/embedding_server/test_settings.py +0 -0
- {bertrend-0.4.7/bertrend/tests/utils → bertrend-0.4.9/bertrend/tests/services/queue}/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/queue/test_bertrend_worker.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/queue/test_client.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/queue/test_queue_manager.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/scheduling/test_job_exception_fix.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/scheduling/test_scheduling_service.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/scheduling/test_stress_test.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/summarizer/test_abstractive_summarizer.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/summarizer/test_chatgpt_summarizer.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/summarizer/test_extractive_summarizer.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/summarizer/test_summarizer.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/summary/test_summary_client.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/summary/test_summary_config.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/services/summary/test_summary_server.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/test_installation.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/test_integration.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/utils/test_apscheduler_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/utils/test_cache_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/utils/test_config_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/utils/test_crontab_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/utils/test_data_loading.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/utils/test_date_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/utils/test_lazy_scheduler.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/utils/test_mail_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/utils/test_multiworker.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/utils/test_scheduler_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/tests/utils/test_utils_init.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/topic_analysis/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/topic_analysis/data_structure.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/topic_analysis/prompts.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/topic_analysis/representative_docs.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/topic_analysis/topic_description.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/topic_analysis/visualizations.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/trend_analysis/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/trend_analysis/data_structure.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/trend_analysis/prompts.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/trend_analysis/signal_llm_template_en.html +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/trend_analysis/signal_llm_template_fr.html +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/trend_analysis/visualizations.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/trend_analysis/weak_signals.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/utils/__init__.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/utils/cache_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/utils/config_utils.py +0 -0
- {bertrend-0.4.7 → bertrend-0.4.9}/bertrend/utils/data_loading.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bertrend
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.9
|
|
4
4
|
Summary: BERTrend analyses topic evolution over time using state-of-the-art transformer models: topic modelling and LLM
|
|
5
5
|
License: LICENSE.md
|
|
6
6
|
License-File: AUTHORS.txt
|
|
@@ -448,6 +448,11 @@ Provides various statistics about topics:
|
|
|
448
448
|
|
|
449
449
|

|
|
450
450
|
|
|
451
|
+
## Article Scoring Service
|
|
452
|
+
|
|
453
|
+
For service setup and API details, see:
|
|
454
|
+
[`docs/services/article_scoring_service.md`](docs/services/article_scoring_service.md).
|
|
455
|
+
|
|
451
456
|
## Support
|
|
452
457
|
|
|
453
458
|
Please use the 'Issues' section to report and discuss any problems with BERTrend.
|
|
@@ -364,6 +364,11 @@ Provides various statistics about topics:
|
|
|
364
364
|
|
|
365
365
|

|
|
366
366
|
|
|
367
|
+
## Article Scoring Service
|
|
368
|
+
|
|
369
|
+
For service setup and API details, see:
|
|
370
|
+
[`docs/services/article_scoring_service.md`](docs/services/article_scoring_service.md).
|
|
371
|
+
|
|
367
372
|
## Support
|
|
368
373
|
|
|
369
374
|
Please use the 'Issues' section to report and discuss any problems with BERTrend.
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
# See AUTHORS.txt
|
|
3
3
|
# SPDX-License-Identifier: MPL-2.0
|
|
4
4
|
# This file is part of BERTrend.
|
|
5
|
-
import asyncio
|
|
6
5
|
import os
|
|
7
6
|
from abc import ABC, abstractmethod
|
|
8
7
|
from pathlib import Path
|
|
@@ -10,6 +9,7 @@ from pathlib import Path
|
|
|
10
9
|
import jsonlines
|
|
11
10
|
import langdetect
|
|
12
11
|
import pandas as pd
|
|
12
|
+
import requests
|
|
13
13
|
from dateutil import parser
|
|
14
14
|
from goose3 import Goose
|
|
15
15
|
from joblib import Parallel, delayed
|
|
@@ -17,12 +17,11 @@ from loguru import logger
|
|
|
17
17
|
from newspaper import Article
|
|
18
18
|
|
|
19
19
|
from bertrend.article_scoring.article_scoring import QualityLevel
|
|
20
|
-
from bertrend.article_scoring.scoring_agent import score_articles
|
|
21
|
-
from bertrend.utils.data_loading import TEXT_COLUMN
|
|
22
20
|
from bertrend.bertrend_apps.data_provider.utils import (
|
|
23
21
|
decode_google_news_url,
|
|
24
22
|
wait_if_seen_url,
|
|
25
23
|
)
|
|
24
|
+
from bertrend.utils.data_loading import TEXT_COLUMN
|
|
26
25
|
|
|
27
26
|
# Ensures to write with +rw for both user and groups
|
|
28
27
|
os.umask(0o002)
|
|
@@ -85,27 +84,53 @@ class DataProvider(ABC):
|
|
|
85
84
|
|
|
86
85
|
@staticmethod
|
|
87
86
|
def evaluate_quality(
|
|
88
|
-
articles: list[dict], minimum_quality_level: QualityLevel
|
|
87
|
+
articles: list[dict], minimum_quality_level: QualityLevel = QualityLevel.AVERAGE
|
|
89
88
|
) -> list[dict]:
|
|
90
89
|
texts = [article[TEXT_COLUMN] for article in articles]
|
|
90
|
+
article_scoring_service_url = os.getenv("ARTICLE_SCORING_SERVICE_URL")
|
|
91
|
+
|
|
92
|
+
if not article_scoring_service_url:
|
|
93
|
+
logger.warning(
|
|
94
|
+
"ARTICLE_SCORING_SERVICE_URL is not set; skipping article quality filtering."
|
|
95
|
+
)
|
|
96
|
+
return articles
|
|
97
|
+
|
|
98
|
+
try:
|
|
99
|
+
response = requests.post(
|
|
100
|
+
f"{article_scoring_service_url.rstrip('/')}/score",
|
|
101
|
+
json={"articles": texts},
|
|
102
|
+
timeout=300,
|
|
103
|
+
)
|
|
104
|
+
response.raise_for_status()
|
|
105
|
+
payload = response.json()
|
|
106
|
+
results = payload.get("results", [])
|
|
107
|
+
except requests.RequestException as exc:
|
|
108
|
+
logger.warning(
|
|
109
|
+
f"Article scoring service unavailable at {article_scoring_service_url}: {exc}. "
|
|
110
|
+
"Skipping article quality filtering."
|
|
111
|
+
)
|
|
112
|
+
return articles
|
|
91
113
|
|
|
92
|
-
|
|
93
|
-
|
|
114
|
+
if len(results) != len(texts):
|
|
115
|
+
logger.warning(
|
|
116
|
+
"Article scoring service returned an unexpected number of results; "
|
|
117
|
+
"skipping article quality filtering."
|
|
118
|
+
)
|
|
119
|
+
return articles
|
|
94
120
|
|
|
95
|
-
# Filter out articles with quality <
|
|
121
|
+
# Filter out articles with quality < minimum_quality_level
|
|
96
122
|
filtered_articles = [
|
|
97
123
|
{
|
|
98
124
|
**article,
|
|
99
|
-
"quality_metrics": results[i]
|
|
100
|
-
"overall_quality": results[i]
|
|
125
|
+
"quality_metrics": results[i]["quality_metrics"],
|
|
126
|
+
"overall_quality": results[i]["overall_quality"],
|
|
101
127
|
}
|
|
102
|
-
# 1. Ensure output is NOT None before proceeding
|
|
103
128
|
for i, article in enumerate(articles)
|
|
104
|
-
if results[i].
|
|
105
|
-
|
|
106
|
-
and results[i].
|
|
129
|
+
if results[i].get("overall_quality") in QualityLevel.__members__
|
|
130
|
+
and QualityLevel[results[i]["overall_quality"]] >= minimum_quality_level
|
|
131
|
+
and not results[i].get("error")
|
|
107
132
|
]
|
|
108
|
-
|
|
133
|
+
|
|
109
134
|
logger.info(
|
|
110
135
|
f"Filtered out {len(articles) - len(filtered_articles)} articles with quality < {minimum_quality_level.name}"
|
|
111
136
|
)
|
|
@@ -253,6 +253,45 @@ class BertrendWorker:
|
|
|
253
253
|
"traceback": traceback.format_exc(),
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
+
def _get_retry_count(self, message: aio_pika.abc.AbstractIncomingMessage) -> int:
|
|
257
|
+
"""Return the current retry count stored in the message header x-retry-count."""
|
|
258
|
+
headers = message.headers or {}
|
|
259
|
+
try:
|
|
260
|
+
return int(headers.get("x-retry-count", 0))
|
|
261
|
+
except (TypeError, ValueError):
|
|
262
|
+
return 0
|
|
263
|
+
|
|
264
|
+
async def _nack_or_discard(
|
|
265
|
+
self,
|
|
266
|
+
message: aio_pika.abc.AbstractIncomingMessage,
|
|
267
|
+
reason: str,
|
|
268
|
+
correlation_id: str | None,
|
|
269
|
+
):
|
|
270
|
+
"""
|
|
271
|
+
Retry the message if the retry limit has not been reached, otherwise
|
|
272
|
+
reject it (requeue=False) so it goes to the DLQ.
|
|
273
|
+
|
|
274
|
+
Delegates the retry-limit check to republish_with_retry(), which
|
|
275
|
+
returns False when the limit is reached (and skips publishing).
|
|
276
|
+
The original message is always rejected with requeue=False so that
|
|
277
|
+
RabbitMQ does not re-deliver the same copy.
|
|
278
|
+
"""
|
|
279
|
+
retry_count = self._get_retry_count(message)
|
|
280
|
+
republished = await self.queue_manager.republish_with_retry(
|
|
281
|
+
message, retry_count
|
|
282
|
+
)
|
|
283
|
+
if republished:
|
|
284
|
+
logger.warning(
|
|
285
|
+
f"Message {correlation_id} failed (attempt {retry_count + 1}/{self.config.max_retries}) "
|
|
286
|
+
f"— republished with incremented retry count. Reason: {reason}"
|
|
287
|
+
)
|
|
288
|
+
else:
|
|
289
|
+
logger.warning(
|
|
290
|
+
f"Message {correlation_id} exceeded max retries ({self.config.max_retries}) "
|
|
291
|
+
f"— sending to DLQ. Reason: {reason}"
|
|
292
|
+
)
|
|
293
|
+
await message.reject(requeue=False)
|
|
294
|
+
|
|
256
295
|
async def callback(
|
|
257
296
|
self,
|
|
258
297
|
message: aio_pika.abc.AbstractIncomingMessage,
|
|
@@ -268,41 +307,63 @@ class BertrendWorker:
|
|
|
268
307
|
|
|
269
308
|
logger.info(f"Request endpoint: {request_data.get('endpoint')}")
|
|
270
309
|
|
|
271
|
-
# Process request
|
|
272
|
-
response_data = await
|
|
310
|
+
# Process request with a timeout to avoid blocking the queue indefinitely
|
|
311
|
+
response_data = await asyncio.wait_for(
|
|
312
|
+
self.process_request(request_data),
|
|
313
|
+
timeout=self.config.job_timeout,
|
|
314
|
+
)
|
|
273
315
|
|
|
274
316
|
# Add metadata
|
|
275
317
|
response_data["correlation_id"] = correlation_id
|
|
276
318
|
response_data["request_data"] = request_data
|
|
277
319
|
|
|
278
|
-
# Publish response/error if reply_to is specified
|
|
279
|
-
if message.reply_to:
|
|
280
|
-
if response_data.get("status") == "error":
|
|
281
|
-
await self.queue_manager.publish_error(
|
|
282
|
-
error_data=response_data, correlation_id=correlation_id
|
|
283
|
-
)
|
|
284
|
-
else:
|
|
285
|
-
await self.queue_manager.publish_response(
|
|
286
|
-
response_data=response_data, correlation_id=correlation_id
|
|
287
|
-
)
|
|
288
|
-
|
|
289
|
-
# Acknowledge message
|
|
290
|
-
await message.ack()
|
|
291
|
-
logger.info(
|
|
292
|
-
f"Completed request: {correlation_id} - Status: {response_data.get('status')}"
|
|
293
|
-
)
|
|
294
|
-
|
|
295
320
|
except json.JSONDecodeError as e:
|
|
296
321
|
logger.error(f"Invalid message format: {str(e)}")
|
|
297
322
|
# Reject and don't requeue invalid messages
|
|
298
323
|
await message.reject(requeue=False)
|
|
324
|
+
return
|
|
325
|
+
|
|
326
|
+
except asyncio.TimeoutError:
|
|
327
|
+
await self._nack_or_discard(
|
|
328
|
+
message,
|
|
329
|
+
reason=f"job timed out after {self.config.job_timeout}s",
|
|
330
|
+
correlation_id=correlation_id,
|
|
331
|
+
)
|
|
332
|
+
return
|
|
299
333
|
|
|
300
334
|
except Exception as e:
|
|
301
335
|
logger.error(f"Error processing message: {str(e)}")
|
|
302
336
|
logger.error(traceback.format_exc())
|
|
337
|
+
await self._nack_or_discard(
|
|
338
|
+
message,
|
|
339
|
+
reason=str(e),
|
|
340
|
+
correlation_id=correlation_id,
|
|
341
|
+
)
|
|
342
|
+
return
|
|
303
343
|
|
|
304
|
-
|
|
305
|
-
|
|
344
|
+
# Acknowledge message before publishing the response, so that the message
|
|
345
|
+
# is always acked regardless of any subsequent publish failure
|
|
346
|
+
await message.ack()
|
|
347
|
+
logger.info(
|
|
348
|
+
f"Completed request: {correlation_id} - Status: {response_data.get('status')}"
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
# Publish response/error if reply_to is specified
|
|
352
|
+
if message.reply_to:
|
|
353
|
+
try:
|
|
354
|
+
if response_data.get("status") == "error":
|
|
355
|
+
await self.queue_manager.publish_error(
|
|
356
|
+
error_data=response_data, correlation_id=correlation_id
|
|
357
|
+
)
|
|
358
|
+
else:
|
|
359
|
+
await self.queue_manager.publish_response(
|
|
360
|
+
response_data=response_data, correlation_id=correlation_id
|
|
361
|
+
)
|
|
362
|
+
except Exception as e:
|
|
363
|
+
logger.error(
|
|
364
|
+
f"Failed to publish response for {correlation_id}: {str(e)}"
|
|
365
|
+
)
|
|
366
|
+
logger.error(traceback.format_exc())
|
|
306
367
|
|
|
307
368
|
async def start(self):
|
|
308
369
|
"""Start the worker"""
|
{bertrend-0.4.7 → bertrend-0.4.9}/bertrend/bertrend_apps/services/queue_management/queue_manager.py
RENAMED
|
@@ -159,6 +159,55 @@ class QueueManager:
|
|
|
159
159
|
|
|
160
160
|
await queue.consume(callback, no_ack=False)
|
|
161
161
|
|
|
162
|
+
async def republish_with_retry(
|
|
163
|
+
self,
|
|
164
|
+
original_message: aio_pika.abc.AbstractIncomingMessage,
|
|
165
|
+
retry_count: int,
|
|
166
|
+
) -> bool:
|
|
167
|
+
"""Republish a failed message with an incremented x-retry-count header.
|
|
168
|
+
|
|
169
|
+
RabbitMQ does not modify headers on requeue, so we must republish
|
|
170
|
+
manually with the updated counter instead of using nack(requeue=True).
|
|
171
|
+
|
|
172
|
+
Returns True if the message was republished, False if the retry limit
|
|
173
|
+
has already been reached and the message was not republished.
|
|
174
|
+
"""
|
|
175
|
+
new_retry_count = retry_count + 1
|
|
176
|
+
if new_retry_count > self.config.max_retries:
|
|
177
|
+
logger.warning(
|
|
178
|
+
f"Message {original_message.correlation_id} has reached the maximum "
|
|
179
|
+
f"retry limit ({self.config.max_retries}) — not republishing."
|
|
180
|
+
)
|
|
181
|
+
return False
|
|
182
|
+
|
|
183
|
+
if not self.channel or self.channel.is_closed:
|
|
184
|
+
await self.connect()
|
|
185
|
+
|
|
186
|
+
# Carry over all existing headers and bump the retry counter
|
|
187
|
+
headers = dict(original_message.headers or {})
|
|
188
|
+
headers["x-retry-count"] = new_retry_count
|
|
189
|
+
|
|
190
|
+
message = aio_pika.Message(
|
|
191
|
+
body=original_message.body,
|
|
192
|
+
headers=headers,
|
|
193
|
+
delivery_mode=aio_pika.DeliveryMode.PERSISTENT,
|
|
194
|
+
priority=original_message.priority,
|
|
195
|
+
correlation_id=original_message.correlation_id,
|
|
196
|
+
content_type=original_message.content_type,
|
|
197
|
+
reply_to=original_message.reply_to,
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
await self.channel.default_exchange.publish(
|
|
201
|
+
message,
|
|
202
|
+
routing_key=self.config.request_queue,
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
logger.info(
|
|
206
|
+
f"Republished message {original_message.correlation_id} "
|
|
207
|
+
f"with x-retry-count={new_retry_count}"
|
|
208
|
+
)
|
|
209
|
+
return True
|
|
210
|
+
|
|
162
211
|
async def publish_response(self, response_data: dict, correlation_id: str):
|
|
163
212
|
"""Publish response to response queue_management"""
|
|
164
213
|
if not self.channel or self.channel.is_closed:
|
|
@@ -36,5 +36,8 @@ class RabbitMQConfig:
|
|
|
36
36
|
prefetch_count: int = int(os.getenv("RABBITMQ_PREFETCH_COUNT", 1))
|
|
37
37
|
|
|
38
38
|
# Retry configuration
|
|
39
|
-
max_retries: int = int(os.getenv("RABBITMQ_MAX_RETRIES",
|
|
39
|
+
max_retries: int = int(os.getenv("RABBITMQ_MAX_RETRIES", 2))
|
|
40
40
|
retry_delay: int = int(os.getenv("RABBITMQ_RETRY_DELAY", 5000)) # milliseconds
|
|
41
|
+
|
|
42
|
+
# Job timeout: max seconds a single job may run before being nacked (default: 1 hour)
|
|
43
|
+
job_timeout: int = int(os.getenv("RABBITMQ_JOB_TIMEOUT", 3600))
|
|
@@ -60,6 +60,18 @@ class RabbitMQAdminClient:
|
|
|
60
60
|
r.raise_for_status()
|
|
61
61
|
return r.json()
|
|
62
62
|
|
|
63
|
+
def get_consumers(self) -> List[Dict[str, Any]]:
|
|
64
|
+
url = f"{self.base_url}/api/consumers/{self._vhost_path()}"
|
|
65
|
+
r = self._session.get(url, timeout=5)
|
|
66
|
+
r.raise_for_status()
|
|
67
|
+
return r.json()
|
|
68
|
+
|
|
69
|
+
def get_channels(self) -> List[Dict[str, Any]]:
|
|
70
|
+
url = f"{self.base_url}/api/channels"
|
|
71
|
+
r = self._session.get(url, timeout=5)
|
|
72
|
+
r.raise_for_status()
|
|
73
|
+
return r.json()
|
|
74
|
+
|
|
63
75
|
def peek_messages(self, name: str, count: int = 10) -> List[Dict[str, Any]]:
|
|
64
76
|
url = f"{self.base_url}/api/queues/{self._vhost_path()}/{quote(name, safe='')}/get"
|
|
65
77
|
payload = {
|
|
@@ -262,7 +274,14 @@ client = RabbitMQAdminClient(client_cfg, management_url=mgmt_url)
|
|
|
262
274
|
|
|
263
275
|
# --- Data Fetching ---
|
|
264
276
|
queue_data = {}
|
|
265
|
-
global_stats = {
|
|
277
|
+
global_stats = {
|
|
278
|
+
"total": 0,
|
|
279
|
+
"requests": 0,
|
|
280
|
+
"responses": 0,
|
|
281
|
+
"failed": 0,
|
|
282
|
+
"unacked": 0,
|
|
283
|
+
"consumers": 0,
|
|
284
|
+
}
|
|
266
285
|
error_msg = None
|
|
267
286
|
|
|
268
287
|
try:
|
|
@@ -272,9 +291,14 @@ try:
|
|
|
272
291
|
|
|
273
292
|
# Aggregation
|
|
274
293
|
global_stats["total"] += info.get("messages", 0)
|
|
275
|
-
global_stats["ready"] += info.get("messages_ready", 0)
|
|
276
294
|
global_stats["unacked"] += info.get("messages_unacknowledged", 0)
|
|
277
295
|
global_stats["consumers"] += info.get("consumers", 0)
|
|
296
|
+
if "requests" in q:
|
|
297
|
+
global_stats["requests"] += info.get("messages", 0)
|
|
298
|
+
elif "responses" in q or "response" in q:
|
|
299
|
+
global_stats["responses"] += info.get("messages", 0)
|
|
300
|
+
elif "failed" in q:
|
|
301
|
+
global_stats["failed"] += info.get("messages", 0)
|
|
278
302
|
|
|
279
303
|
except Exception as e:
|
|
280
304
|
error_msg = str(e)
|
|
@@ -288,18 +312,33 @@ if error_msg:
|
|
|
288
312
|
|
|
289
313
|
# 1. Global Overview Row
|
|
290
314
|
st.markdown(f"### {DASHBOARD_ICON} System Overview")
|
|
291
|
-
kpi1, kpi2, kpi3, kpi4 = st.columns(
|
|
315
|
+
kpi1, kpi2, kpi3, kpi4, kpi5, kpi6 = st.columns(6)
|
|
292
316
|
kpi1.metric(
|
|
293
317
|
"Total Backlog", global_stats["total"], help="Total messages in all selected queues"
|
|
294
318
|
)
|
|
295
|
-
kpi2.metric(
|
|
319
|
+
kpi2.metric(
|
|
320
|
+
"Requests",
|
|
321
|
+
global_stats["requests"],
|
|
322
|
+
help="Messages in bertrend_requests queue",
|
|
323
|
+
)
|
|
296
324
|
kpi3.metric(
|
|
325
|
+
"Responses",
|
|
326
|
+
global_stats["responses"],
|
|
327
|
+
help="Messages in bertrend_responses queue",
|
|
328
|
+
)
|
|
329
|
+
kpi4.metric(
|
|
330
|
+
"Failed",
|
|
331
|
+
global_stats["failed"],
|
|
332
|
+
delta_color="inverse",
|
|
333
|
+
help="Messages in bertrend_failed queue",
|
|
334
|
+
)
|
|
335
|
+
kpi5.metric(
|
|
297
336
|
"Unacknowledged",
|
|
298
337
|
global_stats["unacked"],
|
|
299
338
|
delta_color="inverse",
|
|
300
339
|
help="Messages currently being processed but not acked",
|
|
301
340
|
)
|
|
302
|
-
|
|
341
|
+
kpi6.metric("Active Consumers", global_stats["consumers"])
|
|
303
342
|
|
|
304
343
|
st.divider()
|
|
305
344
|
|
|
@@ -327,6 +366,108 @@ else:
|
|
|
327
366
|
|
|
328
367
|
st.divider()
|
|
329
368
|
|
|
369
|
+
# B. Unacknowledged Messages Details
|
|
370
|
+
unacked_count = info.get("messages_unacknowledged", 0)
|
|
371
|
+
with st.expander(
|
|
372
|
+
f"Unacknowledged Messages ({unacked_count})",
|
|
373
|
+
expanded=unacked_count > 0,
|
|
374
|
+
):
|
|
375
|
+
if unacked_count == 0:
|
|
376
|
+
st.info("No unacknowledged messages in this queue.", icon=INFO_ICON)
|
|
377
|
+
else:
|
|
378
|
+
try:
|
|
379
|
+
all_consumers = client.get_consumers()
|
|
380
|
+
all_channels = client.get_channels()
|
|
381
|
+
|
|
382
|
+
# Filter consumers for this queue
|
|
383
|
+
queue_consumers = [
|
|
384
|
+
c
|
|
385
|
+
for c in all_consumers
|
|
386
|
+
if c.get("queue", {}).get("name") == qname
|
|
387
|
+
]
|
|
388
|
+
|
|
389
|
+
# Build a map of channel_name -> channel details
|
|
390
|
+
channel_map = {ch.get("name"): ch for ch in all_channels}
|
|
391
|
+
|
|
392
|
+
if not queue_consumers:
|
|
393
|
+
st.warning(
|
|
394
|
+
"Unacknowledged messages exist but no active consumers found. "
|
|
395
|
+
"Messages may be held by a disconnected consumer."
|
|
396
|
+
)
|
|
397
|
+
else:
|
|
398
|
+
st.caption(
|
|
399
|
+
f"{len(queue_consumers)} consumer(s) holding unacknowledged messages:"
|
|
400
|
+
)
|
|
401
|
+
for cons in queue_consumers:
|
|
402
|
+
ch_name = cons.get("channel_details", {}).get(
|
|
403
|
+
"name", ""
|
|
404
|
+
)
|
|
405
|
+
ch = channel_map.get(ch_name, {})
|
|
406
|
+
ch_unacked = ch.get("messages_unacknowledged", 0)
|
|
407
|
+
consumer_tag = cons.get("consumer_tag", "unknown")
|
|
408
|
+
peer_host = cons.get("channel_details", {}).get(
|
|
409
|
+
"peer_host", "?"
|
|
410
|
+
)
|
|
411
|
+
peer_port = cons.get("channel_details", {}).get(
|
|
412
|
+
"peer_port", ""
|
|
413
|
+
)
|
|
414
|
+
prefetch = cons.get("prefetch_count", 0)
|
|
415
|
+
ack_required = cons.get("ack_required", True)
|
|
416
|
+
|
|
417
|
+
with st.container(border=True):
|
|
418
|
+
cc1, cc2, cc3, cc4 = st.columns(4)
|
|
419
|
+
cc1.metric("Unacked (channel)", ch_unacked)
|
|
420
|
+
cc2.markdown(f"**Consumer Tag**\n`{consumer_tag}`")
|
|
421
|
+
cc3.markdown(
|
|
422
|
+
f"**Client**\n`{peer_host}:{peer_port}`"
|
|
423
|
+
)
|
|
424
|
+
cc4.markdown(
|
|
425
|
+
f"**Prefetch / Ack required**\n`{prefetch}` / `{ack_required}`"
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
# Channel-level stats
|
|
429
|
+
ch_stats = ch.get("message_stats", {})
|
|
430
|
+
ack_rate = (
|
|
431
|
+
ch_stats.get("ack_details", {}).get("rate", 0.0)
|
|
432
|
+
if ch_stats
|
|
433
|
+
else 0.0
|
|
434
|
+
)
|
|
435
|
+
deliver_rate = (
|
|
436
|
+
ch_stats.get("deliver_details", {}).get(
|
|
437
|
+
"rate", 0.0
|
|
438
|
+
)
|
|
439
|
+
if ch_stats
|
|
440
|
+
else 0.0
|
|
441
|
+
)
|
|
442
|
+
total_acked = (
|
|
443
|
+
ch_stats.get("ack", 0) if ch_stats else 0
|
|
444
|
+
)
|
|
445
|
+
total_delivered = (
|
|
446
|
+
ch_stats.get("deliver", 0) if ch_stats else 0
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
sc1, sc2, sc3, sc4 = st.columns(4)
|
|
450
|
+
sc1.metric("Ack Rate", f"{ack_rate:.2f}/s")
|
|
451
|
+
sc2.metric("Deliver Rate", f"{deliver_rate:.2f}/s")
|
|
452
|
+
sc3.metric("Total Acked", total_acked)
|
|
453
|
+
sc4.metric("Total Delivered", total_delivered)
|
|
454
|
+
|
|
455
|
+
# Connection info
|
|
456
|
+
conn = ch.get("connection_details", {})
|
|
457
|
+
if conn:
|
|
458
|
+
st.caption(
|
|
459
|
+
f"Connection: `{conn.get('name', ch_name)}` "
|
|
460
|
+
f"— state: `{ch.get('state', '?')}`"
|
|
461
|
+
)
|
|
462
|
+
|
|
463
|
+
except Exception as e:
|
|
464
|
+
st.error(
|
|
465
|
+
f"Failed to fetch consumer/channel details: {e}",
|
|
466
|
+
icon=ERROR_ICON,
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
st.divider()
|
|
470
|
+
|
|
330
471
|
# B. Message Peeking Interface
|
|
331
472
|
c_head, c_peek_n, c_sort = st.columns([3, 1, 1])
|
|
332
473
|
c_head.subheader("Message Browser")
|
|
@@ -546,6 +687,7 @@ else:
|
|
|
546
687
|
obj = d["obj"]
|
|
547
688
|
|
|
548
689
|
props = m.get("properties", {})
|
|
690
|
+
headers = props.get("headers") or {}
|
|
549
691
|
corr_id = props.get("correlation_id", "No-ID")
|
|
550
692
|
msg_size = (
|
|
551
693
|
m.get("payload_bytes", 0)
|
|
@@ -562,6 +704,9 @@ else:
|
|
|
562
704
|
info_tags.append(f"User: {d['user']}")
|
|
563
705
|
if d["model_id"]:
|
|
564
706
|
info_tags.append(f"Model: {d['model_id']}")
|
|
707
|
+
retry_count = headers.get("x-retry-count")
|
|
708
|
+
if retry_count is not None:
|
|
709
|
+
info_tags.append(f"Retry: {retry_count}")
|
|
565
710
|
|
|
566
711
|
info_str = f" | {' | '.join(info_tags)}" if info_tags else ""
|
|
567
712
|
label = f"#{idx + 1} | {fmt} | CID: {corr_id}{info_str} | {msg_size} bytes"
|
|
@@ -617,6 +762,12 @@ else:
|
|
|
617
762
|
"Key": "App ID",
|
|
618
763
|
"Val": str(props.get("app_id") or ""),
|
|
619
764
|
},
|
|
765
|
+
{
|
|
766
|
+
"Key": "x-retry-count",
|
|
767
|
+
"Val": str(headers.get("x-retry-count"))
|
|
768
|
+
if headers.get("x-retry-count") is not None
|
|
769
|
+
else "",
|
|
770
|
+
},
|
|
620
771
|
]
|
|
621
772
|
).dropna()
|
|
622
773
|
st.dataframe(meta_df, hide_index=True, width="stretch")
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Copyright (c) 2024-2026, RTE (https://www.rte-france.com)
|
|
2
|
+
# See AUTHORS.txt
|
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
# This file is part of BERTrend.
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import tomllib
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from pydantic_settings import BaseSettings
|
|
11
|
+
|
|
12
|
+
DEFAULT_CONFIG_FILE = Path(__file__).parent / "default_config.toml"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ArticleScoringAPIConfig(BaseSettings):
|
|
16
|
+
host: str
|
|
17
|
+
port: int
|
|
18
|
+
number_workers: int
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_config() -> ArticleScoringAPIConfig:
|
|
22
|
+
"""
|
|
23
|
+
Return the configuration for the summary API.
|
|
24
|
+
The configuration is loaded from a toml file.
|
|
25
|
+
The path to the toml file can be specified using the environment variable `SUMMARY_API_CONFIG_FILE`.
|
|
26
|
+
If the environment variable is not set, the default configuration file is used.
|
|
27
|
+
"""
|
|
28
|
+
config_file = os.environ.get("ARTICLE_SCORING_API_CONFIG_FILE", None)
|
|
29
|
+
if config_file is None:
|
|
30
|
+
config_file = DEFAULT_CONFIG_FILE
|
|
31
|
+
with open(config_file, "rb") as f:
|
|
32
|
+
return ArticleScoringAPIConfig(**tomllib.load(f))
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Copyright (c) 2024-2026, RTE (https://www.rte-france.com)
|
|
2
|
+
# See AUTHORS.txt
|
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
# This file is part of BERTrend.
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ScoreArticlesRequest(BaseModel):
|
|
10
|
+
articles: list[str]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ScoredArticle(BaseModel):
|
|
14
|
+
article_index: int
|
|
15
|
+
quality_metrics: dict | None = None
|
|
16
|
+
overall_quality: str | None = None
|
|
17
|
+
error: str | None = None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ScoreArticlesResponse(BaseModel):
|
|
21
|
+
results: list[ScoredArticle]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Copyright (c) 2024-2026, RTE (https://www.rte-france.com)
|
|
2
|
+
# See AUTHORS.txt
|
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
# This file is part of BERTrend.
|
|
5
|
+
|
|
6
|
+
from fastapi import APIRouter
|
|
7
|
+
from starlette.responses import RedirectResponse
|
|
8
|
+
|
|
9
|
+
router = APIRouter()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@router.get("/health")
|
|
13
|
+
def health():
|
|
14
|
+
return {"status": "ok"}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@router.get("/", summary="Redirect to API documentation")
|
|
18
|
+
def root():
|
|
19
|
+
return RedirectResponse(url="/docs")
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Copyright (c) 2024-2026, RTE (https://www.rte-france.com)
|
|
2
|
+
# See AUTHORS.txt
|
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
# This file is part of BERTrend.
|
|
5
|
+
|
|
6
|
+
from fastapi import APIRouter, HTTPException
|
|
7
|
+
|
|
8
|
+
from bertrend.article_scoring.scoring_agent import score_articles
|
|
9
|
+
from bertrend.services.article_scoring_server.models import (
|
|
10
|
+
ScoreArticlesRequest,
|
|
11
|
+
ScoreArticlesResponse,
|
|
12
|
+
ScoredArticle,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
router = APIRouter()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@router.post("/score", response_model=ScoreArticlesResponse)
|
|
19
|
+
async def score(request: ScoreArticlesRequest):
|
|
20
|
+
try:
|
|
21
|
+
score_results = await score_articles(request.articles)
|
|
22
|
+
except Exception as e:
|
|
23
|
+
raise HTTPException(
|
|
24
|
+
status_code=500,
|
|
25
|
+
detail=f"Failed to score articles: {e}",
|
|
26
|
+
) from e
|
|
27
|
+
|
|
28
|
+
results = []
|
|
29
|
+
for index, item in enumerate(score_results):
|
|
30
|
+
quality_metrics = item.output.serialize_model() if item.output else None
|
|
31
|
+
overall_quality = (
|
|
32
|
+
item.output.quality_level.name if item.output and not item.error else None
|
|
33
|
+
)
|
|
34
|
+
results.append(
|
|
35
|
+
ScoredArticle(
|
|
36
|
+
article_index=index,
|
|
37
|
+
quality_metrics=quality_metrics,
|
|
38
|
+
overall_quality=overall_quality,
|
|
39
|
+
error=item.error,
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
return ScoreArticlesResponse(results=results)
|