bertrend 0.3.22__tar.gz → 0.3.24__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.3.22 → bertrend-0.3.24}/PKG-INFO +19 -15
- {bertrend-0.3.22 → bertrend-0.3.24}/README.md +15 -11
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/BERTopicModel.py +3 -3
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/BERTrend.py +1 -1
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/article_scoring/scoring_agent.py +0 -1
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/demos_utils/data_loading_component.py +1 -1
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/streamlit_components/clickable_df_component.py +3 -1
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/topic_analysis/demo_pages/explore_topics.py +1 -1
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/llm_utils/newsletter_features.py +3 -2
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/llm_utils/openai_client.py +1 -6
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/metrics/temporal_metrics_embedding.py +3 -5
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/authentication.py +24 -23
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_client.py +42 -36
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/routers/authentication.py +1 -1
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/start.py +6 -3
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/status.py +6 -6
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_service.py +11 -9
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/scheduling/docker-compose.yml +0 -1
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/scheduling/job_utils/job_functions.py +10 -11
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/scheduling/routers/scheduling.py +11 -6
- bertrend-0.3.24/bertrend/tests/apps/test_lazy_scheduler.py +72 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/apps/test_models.py +5 -24
- bertrend-0.3.24/bertrend/tests/apps/test_multiworker.py +58 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/apps/test_process_new_data.py +3 -3
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/core/test_bertrend.py +6 -5
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/core/test_temporal_metrics_embedding.py +0 -2
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/core/test_topic_metrics.py +0 -3
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/llm/test_agent_utils.py +5 -2
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/services/embedding/test_embedding_client.py +7 -0
- bertrend-0.3.24/bertrend/tests/services/scheduling/test_job_exception_fix.py +74 -0
- bertrend-0.3.24/bertrend/tests/services/scheduling/test_stress_test.py +311 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/services/summarizer/test_abstractive_summarizer.py +0 -2
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/services/summarizer/test_extractive_summarizer.py +0 -2
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/test_integration.py +5 -5
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/utils/test_apscheduler_utils.py +26 -43
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/utils/test_crontab_utils.py +1 -3
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/topic_analysis/visualizations.py +1 -1
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/utils/data_loading.py +7 -1
- bertrend-0.3.24/bertrend_apps/__init__.py +43 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/common/apscheduler_utils.py +169 -58
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/common/crontab_utils.py +16 -4
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/common/scheduler_utils.py +16 -20
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/data_provider/arxiv_provider.py +3 -3
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/data_provider/data_provider.py +22 -6
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/data_provider/newscatcher_provider.py +8 -4
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/data_provider/utils.py +6 -7
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/curebot/app_utils.py +3 -2
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/geolocalization/spacy/dbpedia.py +5 -6
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/newsletters/__main__.py +1 -2
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/newsletters/newsletter_generation.py +2 -1
- bertrend-0.3.24/bertrend_apps/prospective_demo/.streamlit/secrets.toml.example +9 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/app.py +29 -2
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/authentication.py +8 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/automated_report_generation.py +25 -14
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/dashboard_analysis.py +14 -8
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/dashboard_signals.py +1 -1
- bertrend-0.3.24/bertrend_apps/prospective_demo/docs/architecture.md +82 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/feeds_config.py +21 -7
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/i18n_translations.py +8 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/models_info.py +27 -17
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/process_new_data.py +8 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/report_generation.py +11 -4
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/report_generation_utils.py +0 -1
- bertrend-0.3.24/bertrend_apps/services/config/default_config.toml +3 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/config/settings.py +0 -1
- bertrend-0.3.24/bertrend_apps/services/models/newsletters_models.py +16 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/routers/bertrend_app.py +2 -2
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/routers/data_provider.py +1 -2
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/routers/newsletters.py +20 -16
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/start.py +2 -6
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/status.py +6 -6
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/utils/logging_utils.py +4 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/pyproject.toml +5 -5
- bertrend-0.3.22/bertrend_apps/__init__.py +0 -36
- bertrend-0.3.22/bertrend_apps/config/newsletters/decarbonation_newsletter_from_scratch.toml +0 -38
- bertrend-0.3.22/bertrend_apps/config/newsletters/rte_newsletter_from_scratch.toml +0 -38
- bertrend-0.3.22/bertrend_apps/prospective_demo/.streamlit/secrets.toml +0 -14
- bertrend-0.3.22/bertrend_apps/services/config/default_config.toml +0 -4
- bertrend-0.3.22/bertrend_apps/services/models/newsletters_models.py +0 -34
- {bertrend-0.3.22 → bertrend-0.3.24}/AUTHORS.txt +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/LICENSE.md +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/article_scoring/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/article_scoring/article_scoring.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/article_scoring/prompts.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/config/bertopic_default_config.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/config/bertrend_default_config.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/config/parameters.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/config/services_default_config.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/demos_utils/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/demos_utils/embed_documents_component.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/demos_utils/i18n.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/demos_utils/i18n_translations.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/demos_utils/icons.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/demos_utils/parameters_component.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/demos_utils/state_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/start_summarizer_app.sh +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/start_topic_analysis_app.sh +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/start_weak_signals_app.sh +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/streamlit_components/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/streamlit_components/input_with_pills_component.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/summarization/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/summarization/summarizer_app.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/topic_analysis/.streamlit/config.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/topic_analysis/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/topic_analysis/app.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/topic_analysis/app_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/topic_analysis/demo_pages/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/topic_analysis/demo_pages/newsletters_generation.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/topic_analysis/demo_pages/temporal_visualizations.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/topic_analysis/demo_pages/topic_visualizations.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/topic_analysis/demo_pages/training_page.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/topic_analysis/i18n_translations.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/weak_signals/.streamlit/config.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/weak_signals/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/weak_signals/app.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/weak_signals/i18n_translations.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/weak_signals/visualizations_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/llm_utils/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/llm_utils/agent_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/llm_utils/newsletter.css +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/llm_utils/newsletter_model.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/llm_utils/newsletter_outlook_template.html +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/llm_utils/newsletter_template.html +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/llm_utils/prompts.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/metrics/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/metrics/topic_metrics.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/resources/common_ngrams.json +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/resources/stopwords-en.json +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/resources/stopwords-fr.json +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/resources/stopwords-rte.json +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/cert.pem +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/README.md +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/bertrend_client_registry.json +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/config/default_config.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/config/settings.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/main.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/models.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/requirements.txt +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/routers/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/routers/embeddings.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/routers/info.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/security.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/stop.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/key.pem +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/scheduling/.dockerignore +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/scheduling/Docker_setup.md +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/scheduling/Dockerfile +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/scheduling/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/scheduling/dashboard.html +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/scheduling/job_utils/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/scheduling/models/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/scheduling/models/scheduling_models.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/scheduling/requirements.txt +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/scheduling/routers/info.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/scheduling/scheduling_service.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/summarizer.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/summary/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/summary/abstractive_summarizer.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/summary/chatgpt_summarizer.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/summary/extractive_summarizer.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/summary/lexrank.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/summary/prompts.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/README_integration_tests.md +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/apps/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/apps/test_bertrend_service.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/apps/test_routers_bertrend_app.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/apps/test_routers_info.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/conftest.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/core/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/core/test_data_structure.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/core/test_representative_docs.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/core/test_topic_description.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/core/test_topic_model.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/core/test_trend_analysis_data_structure.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/core/test_trend_analysis_prompts.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/core/test_trend_analysis_visualizations.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/core/test_trend_analysis_weak_signals.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/core/test_visualizations.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/llm/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/llm/test_article_scoring.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/llm/test_article_scoring_models.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/llm/test_newsletter_features.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/llm/test_newsletter_model.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/llm/test_openai_client.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/services/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/services/embedding/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/services/scheduling/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/services/scheduling/test_scheduling_service.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/services/summarizer/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/services/summarizer/test_chatgpt_summarizer.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/services/summarizer/test_summarizer.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/test_installation.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/utils/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/utils/test_cache_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/utils/test_config_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/utils/test_data_loading.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/utils/test_date_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/utils/test_mail_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/utils/test_scheduler_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/tests/utils/test_utils_init.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/topic_analysis/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/topic_analysis/data_structure.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/topic_analysis/prompts.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/topic_analysis/representative_docs.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/topic_analysis/topic_description.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/trend_analysis/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/trend_analysis/data_structure.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/trend_analysis/prompts.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/trend_analysis/signal_llm_template_en.html +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/trend_analysis/signal_llm_template_fr.html +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/trend_analysis/visualizations.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/trend_analysis/weak_signals.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/utils/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/utils/cache_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend/utils/config_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/common/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/common/date_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/common/mail_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/config/feeds/arxiv_feed.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/config/feeds/decarbonation_feed.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/config/feeds/llm_en_feed.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/config/feeds/llm_feed.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/config/feeds/nlp_feed.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/config/feeds/rte_feed.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/config/newsletters/arxiv_newsletter_from_last.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/config/newsletters/decarbonation_newsletter_from_last.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/config/newsletters/llm_en_newsletter_from_last.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/config/newsletters/llm_newsletter_from_last.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/config/newsletters/nlp_newsletter_from_last.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/config/newsletters/rte_newsletter_from_last.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/data_provider/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/data_provider/__main__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/data_provider/atom_feed_provider.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/data_provider/bing_news_provider.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/data_provider/data_provider_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/data_provider/google_news_provider.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/data_provider/rss_feed_provider.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/curebot/.streamlit/config.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/curebot/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/curebot/app.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/curebot/config.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/curebot/import_extraction_article.ipynb +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/curebot/prompts.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/curebot/start_newsletter_generator.sh +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/curebot/tabs/tab1.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/curebot/tabs/tab2.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/curebot/tabs/tab3.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/dataviz/Main_page.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/dataviz/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/dataviz/pages/1_Data_feeds.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/geolocalization/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/geolocalization/entity_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/geolocalization/spacy/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/geolocalization/spacy/common_factory.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/geolocalization/spacy/nlp.config +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/geolocalization/spacy/utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/start_apps.sh +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/exploration/stop_apps.sh +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/install_feeds_and_newsletters.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/newsletters/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/newsletters/utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/.streamlit/config.toml +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/dashboard_common.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/dashboard_comparative.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/data_model.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/detailed_report_template.html +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/docs/automated_report_generation.md +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/feeds_common.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/feeds_data.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/i18n.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/llm_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/perf_utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/start_demo.sh +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/prospective_demo/utils.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/bertrend_service.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/models/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/models/bertrend_app_models.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/models/data_provider_models.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/routers/__init__.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/routers/info.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/stop.py +0 -0
- {bertrend-0.3.22 → bertrend-0.3.24}/bertrend_apps/services/utils/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bertrend
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.24
|
|
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
|
|
@@ -42,7 +42,7 @@ Requires-Dist: langdetect (>=1.0.9)
|
|
|
42
42
|
Requires-Dist: loguru (>=0.7.3)
|
|
43
43
|
Requires-Dist: lxml-html-clean (>=0.2.2)
|
|
44
44
|
Requires-Dist: markdown (>=3.7)
|
|
45
|
-
Requires-Dist:
|
|
45
|
+
Requires-Dist: newscatcher-sdk (>=1.4.0) ; extra == "apps"
|
|
46
46
|
Requires-Dist: newspaper4k (>=0.9.3.1) ; extra == "apps"
|
|
47
47
|
Requires-Dist: nltk (>=3.9.1)
|
|
48
48
|
Requires-Dist: numpy (<2)
|
|
@@ -53,6 +53,7 @@ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc (==1.25.0)
|
|
|
53
53
|
Requires-Dist: pandas (>=2.2.2)
|
|
54
54
|
Requires-Dist: plotly (>=5.24.1)
|
|
55
55
|
Requires-Dist: plotly-resampler (>=0.10.0)
|
|
56
|
+
Requires-Dist: psutil (>=7.2.1)
|
|
56
57
|
Requires-Dist: pyarrow (>=21.0.0)
|
|
57
58
|
Requires-Dist: pygooglenews (>=0.1.3) ; extra == "apps"
|
|
58
59
|
Requires-Dist: pylabeladjust (==0.1.13)
|
|
@@ -60,8 +61,8 @@ Requires-Dist: pytest (>=8.4.0)
|
|
|
60
61
|
Requires-Dist: pytest-asyncio
|
|
61
62
|
Requires-Dist: python-dotenv (>=1.1.1)
|
|
62
63
|
Requires-Dist: requests (>=2.32.3)
|
|
64
|
+
Requires-Dist: ruff (>=0.14.14)
|
|
63
65
|
Requires-Dist: scikit-learn (>=1.5.2)
|
|
64
|
-
Requires-Dist: scipy (==1.12)
|
|
65
66
|
Requires-Dist: seaborn (>=0.13.2)
|
|
66
67
|
Requires-Dist: sentence-transformers (==3.0.1)
|
|
67
68
|
Requires-Dist: sentencepiece (>=0.2.0)
|
|
@@ -72,7 +73,6 @@ Requires-Dist: supervisor (>=4.3.0)
|
|
|
72
73
|
Requires-Dist: thefuzz (>=0.22.1)
|
|
73
74
|
Requires-Dist: tiktoken (>=0.8.0)
|
|
74
75
|
Requires-Dist: tldextract (>=2.0.1)
|
|
75
|
-
Requires-Dist: tokenizers (<0.20.0)
|
|
76
76
|
Requires-Dist: torch (>=2.7.0)
|
|
77
77
|
Requires-Dist: tqdm (>=4.67.1)
|
|
78
78
|
Requires-Dist: typer (>=0.16.0)
|
|
@@ -94,6 +94,11 @@ Description-Content-Type: text/markdown
|
|
|
94
94
|

|
|
95
95
|

|
|
96
96
|
|
|
97
|
+
## News
|
|
98
|
+
2025-11-24: BERTrend has been integrated into the [Netminer 5](https://netminer.gitbook.io/netminer5/module-reference/text/bertopic/bertrend) data analysis tool !
|
|
99
|
+
|
|
100
|
+
## Overview
|
|
101
|
+
|
|
97
102
|

|
|
98
103
|
|
|
99
104
|
## Paper
|
|
@@ -174,11 +179,10 @@ Recommended steps:
|
|
|
174
179
|
- Misc: `CUDA_VISIBLE_DEVICES`
|
|
175
180
|
2. Use a virtual environment and install dependencies inside it:
|
|
176
181
|
```bash
|
|
177
|
-
|
|
182
|
+
uv venv --python 3.13
|
|
178
183
|
source .venv/bin/activate # Windows: .venv\\Scripts\\activate
|
|
179
|
-
pip install
|
|
180
|
-
pip install
|
|
181
|
-
pip install python-dotenv # ensures .env is auto-loaded
|
|
184
|
+
uv pip install . # or uv pip install .[apps]
|
|
185
|
+
uv pip install python-dotenv # ensures .env is auto-loaded
|
|
182
186
|
```
|
|
183
187
|
3. Notes
|
|
184
188
|
- If `python-dotenv` isn’t installed, `.env` won’t be auto-loaded; you can either install it or export variables via your shell/runner.
|
|
@@ -188,7 +192,7 @@ Recommended steps:
|
|
|
188
192
|
### Hardware and Software Requirements
|
|
189
193
|
|
|
190
194
|
- Recommended: at least one GPU with 16GB RAM for faster processing
|
|
191
|
-
- Python >= 3.
|
|
195
|
+
- Python >= 3.13 is required
|
|
192
196
|
|
|
193
197
|
### Docker Installation
|
|
194
198
|
|
|
@@ -198,28 +202,28 @@ For detailed instructions on using BERTrend with Docker, see the [Docker documen
|
|
|
198
202
|
|
|
199
203
|
### Package Installation
|
|
200
204
|
|
|
201
|
-
- (Recommended): create a new python environment using `
|
|
205
|
+
- (Recommended): create a new python environment using `uv`:
|
|
202
206
|
|
|
203
|
-
`
|
|
207
|
+
`uv venv --python 3.13`
|
|
204
208
|
|
|
205
209
|
|
|
206
210
|
- Installation from pypi
|
|
207
211
|
|
|
208
|
-
`pip install bertrend`
|
|
212
|
+
`uv pip install bertrend`
|
|
209
213
|
|
|
210
214
|
|
|
211
215
|
- Install using pip or poetry in the BERTrend home directory:
|
|
212
216
|
|
|
213
217
|
```bash
|
|
214
218
|
# Basic installation with core dependencies
|
|
215
|
-
pip install .
|
|
219
|
+
uv pip install .
|
|
216
220
|
|
|
217
221
|
# Installation with apps dependencies
|
|
218
|
-
pip install
|
|
222
|
+
uv pip install .[apps]
|
|
219
223
|
|
|
220
224
|
```
|
|
221
225
|
|
|
222
|
-
- (Use `pip install -e .` for a local installation)
|
|
226
|
+
- (Use `uv pip install -e .` for a local installation)
|
|
223
227
|
|
|
224
228
|
NB. Due to the number of dependencies, the installation may take some time on an empty environment.
|
|
225
229
|
|
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|

|
|
10
10
|

|
|
11
11
|
|
|
12
|
+
## News
|
|
13
|
+
2025-11-24: BERTrend has been integrated into the [Netminer 5](https://netminer.gitbook.io/netminer5/module-reference/text/bertopic/bertrend) data analysis tool !
|
|
14
|
+
|
|
15
|
+
## Overview
|
|
16
|
+
|
|
12
17
|

|
|
13
18
|
|
|
14
19
|
## Paper
|
|
@@ -89,11 +94,10 @@ Recommended steps:
|
|
|
89
94
|
- Misc: `CUDA_VISIBLE_DEVICES`
|
|
90
95
|
2. Use a virtual environment and install dependencies inside it:
|
|
91
96
|
```bash
|
|
92
|
-
|
|
97
|
+
uv venv --python 3.13
|
|
93
98
|
source .venv/bin/activate # Windows: .venv\\Scripts\\activate
|
|
94
|
-
pip install
|
|
95
|
-
pip install
|
|
96
|
-
pip install python-dotenv # ensures .env is auto-loaded
|
|
99
|
+
uv pip install . # or uv pip install .[apps]
|
|
100
|
+
uv pip install python-dotenv # ensures .env is auto-loaded
|
|
97
101
|
```
|
|
98
102
|
3. Notes
|
|
99
103
|
- If `python-dotenv` isn’t installed, `.env` won’t be auto-loaded; you can either install it or export variables via your shell/runner.
|
|
@@ -103,7 +107,7 @@ Recommended steps:
|
|
|
103
107
|
### Hardware and Software Requirements
|
|
104
108
|
|
|
105
109
|
- Recommended: at least one GPU with 16GB RAM for faster processing
|
|
106
|
-
- Python >= 3.
|
|
110
|
+
- Python >= 3.13 is required
|
|
107
111
|
|
|
108
112
|
### Docker Installation
|
|
109
113
|
|
|
@@ -113,28 +117,28 @@ For detailed instructions on using BERTrend with Docker, see the [Docker documen
|
|
|
113
117
|
|
|
114
118
|
### Package Installation
|
|
115
119
|
|
|
116
|
-
- (Recommended): create a new python environment using `
|
|
120
|
+
- (Recommended): create a new python environment using `uv`:
|
|
117
121
|
|
|
118
|
-
`
|
|
122
|
+
`uv venv --python 3.13`
|
|
119
123
|
|
|
120
124
|
|
|
121
125
|
- Installation from pypi
|
|
122
126
|
|
|
123
|
-
`pip install bertrend`
|
|
127
|
+
`uv pip install bertrend`
|
|
124
128
|
|
|
125
129
|
|
|
126
130
|
- Install using pip or poetry in the BERTrend home directory:
|
|
127
131
|
|
|
128
132
|
```bash
|
|
129
133
|
# Basic installation with core dependencies
|
|
130
|
-
pip install .
|
|
134
|
+
uv pip install .
|
|
131
135
|
|
|
132
136
|
# Installation with apps dependencies
|
|
133
|
-
pip install
|
|
137
|
+
uv pip install .[apps]
|
|
134
138
|
|
|
135
139
|
```
|
|
136
140
|
|
|
137
|
-
- (Use `pip install -e .` for a local installation)
|
|
141
|
+
- (Use `uv pip install -e .` for a local installation)
|
|
138
142
|
|
|
139
143
|
NB. Due to the number of dependencies, the installation may take some time on an empty environment.
|
|
140
144
|
|
|
@@ -257,9 +257,9 @@ class BERTopicModel:
|
|
|
257
257
|
if zeroshot_topic_list:
|
|
258
258
|
self.config["bertopic_model"]["zeroshot_topic_list"] = zeroshot_topic_list
|
|
259
259
|
if zeroshot_min_similarity is not None:
|
|
260
|
-
self.config["bertopic_model"][
|
|
261
|
-
|
|
262
|
-
|
|
260
|
+
self.config["bertopic_model"]["zeroshot_min_similarity"] = (
|
|
261
|
+
zeroshot_min_similarity
|
|
262
|
+
)
|
|
263
263
|
# Load and fit model
|
|
264
264
|
try:
|
|
265
265
|
logger.debug("\tInitializing BERTopic model")
|
|
@@ -287,7 +287,7 @@ class BERTrend:
|
|
|
287
287
|
|
|
288
288
|
for i, (period, group) in enumerate(non_empty_groups):
|
|
289
289
|
try:
|
|
290
|
-
logger.info(f"Training topic model {i+1}/{len(non_empty_groups)}...")
|
|
290
|
+
logger.info(f"Training topic model {i + 1}/{len(non_empty_groups)}...")
|
|
291
291
|
(
|
|
292
292
|
new_topic_model,
|
|
293
293
|
self.doc_groups[period],
|
|
@@ -55,7 +55,7 @@ FORMAT_ICONS = {
|
|
|
55
55
|
|
|
56
56
|
@st.dialog(translate("column_selection"))
|
|
57
57
|
def _select_alternative_columns(df: pd.DataFrame, message: str = ""):
|
|
58
|
-
st.warning(message, icon=WARNING_ICON),
|
|
58
|
+
(st.warning(message, icon=WARNING_ICON),)
|
|
59
59
|
if TEXT_COLUMN not in df.columns:
|
|
60
60
|
text_column = st.selectbox(
|
|
61
61
|
label=translate("text_column_selection"), options=df.columns
|
{bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/streamlit_components/clickable_df_component.py
RENAMED
|
@@ -8,6 +8,8 @@ from typing import Callable
|
|
|
8
8
|
import pandas as pd
|
|
9
9
|
import streamlit as st
|
|
10
10
|
|
|
11
|
+
from bertrend_apps.prospective_demo.i18n import translate
|
|
12
|
+
|
|
11
13
|
|
|
12
14
|
def clickable_df(
|
|
13
15
|
df: pd.DataFrame, clickable_buttons: list[tuple[str | Callable, Callable, str]]
|
|
@@ -18,7 +20,7 @@ def clickable_df(
|
|
|
18
20
|
cols = st.columns(len(df.columns) * [3] + len(clickable_buttons) * [1])
|
|
19
21
|
for i, c in enumerate(df.columns):
|
|
20
22
|
with cols[i]:
|
|
21
|
-
st.write(f"**{c}**")
|
|
23
|
+
st.write(f"**{translate('col_' + c, default=c)}**")
|
|
22
24
|
# Generate a unique identifier, this will be used to identify the keys in case multiple clickable_df are used
|
|
23
25
|
unique_id = zlib.crc32(" ".join(df.columns.tolist()).encode())
|
|
24
26
|
for index, row in df.iterrows():
|
{bertrend-0.3.22 → bertrend-0.3.24}/bertrend/demos/topic_analysis/demo_pages/explore_topics.py
RENAMED
|
@@ -226,7 +226,7 @@ def display_representative_documents(filtered_df: pd.DataFrame):
|
|
|
226
226
|
date = doc.timestamp.strftime("%A %d %b %Y %H:%M:%S")
|
|
227
227
|
snippet = doc.text[:200] + "..." if len(doc.text) > 150 else doc.text
|
|
228
228
|
|
|
229
|
-
content = f"""**{doc.title}**\n\n{date} | {translate(
|
|
229
|
+
content = f"""**{doc.title}**\n\n{date} | {translate("unknown_source") if website_name == translate("unknown_source") else website_name}\n\n{snippet}"""
|
|
230
230
|
|
|
231
231
|
if website_name != translate("unknown_source"):
|
|
232
232
|
st.link_button(content, doc.url)
|
|
@@ -108,7 +108,6 @@ def generate_newsletter(
|
|
|
108
108
|
|
|
109
109
|
# Iterate over topics
|
|
110
110
|
for i in tqdm(range(top_n_topics), desc="Processing topics..."):
|
|
111
|
-
|
|
112
111
|
topic_keywords = topics_info["Representation"].iloc[i]
|
|
113
112
|
|
|
114
113
|
sub_df = get_most_representative_docs(
|
|
@@ -180,7 +179,9 @@ def generate_newsletter(
|
|
|
180
179
|
article_summary = (
|
|
181
180
|
summaries[i]
|
|
182
181
|
if summary_mode == "document"
|
|
183
|
-
else doc.text
|
|
182
|
+
else doc.text
|
|
183
|
+
if summary_mode == "none"
|
|
184
|
+
else None
|
|
184
185
|
)
|
|
185
186
|
article_list.append(
|
|
186
187
|
Article(
|
|
@@ -8,17 +8,12 @@ import re
|
|
|
8
8
|
from enum import Enum
|
|
9
9
|
from typing import Type
|
|
10
10
|
|
|
11
|
-
from dotenv import load_dotenv
|
|
12
11
|
from openai import OpenAI, AzureOpenAI, Timeout, Stream
|
|
13
12
|
from loguru import logger
|
|
14
13
|
from openai.types.chat import ChatCompletion, ChatCompletionChunk
|
|
15
14
|
from pydantic import BaseModel
|
|
16
15
|
|
|
17
|
-
#
|
|
18
|
-
if load_dotenv(override=True):
|
|
19
|
-
logger.info("Loaded .env file")
|
|
20
|
-
else:
|
|
21
|
-
logger.warning("Failed to load .env file")
|
|
16
|
+
# Note: .env is loaded in bertrend/__init__.py which is imported before this module
|
|
22
17
|
|
|
23
18
|
MAX_ATTEMPTS = 3
|
|
24
19
|
TIMEOUT = 60.0
|
|
@@ -187,9 +187,7 @@ class TempTopic:
|
|
|
187
187
|
timestamps = documents["Timestamps"].unique()
|
|
188
188
|
|
|
189
189
|
topics_over_time = [] # Accumulates the final data for each timestamp
|
|
190
|
-
document_per_topic_list =
|
|
191
|
-
[]
|
|
192
|
-
) # Tracks documents associated with each topic at each timestamp
|
|
190
|
+
document_per_topic_list = [] # Tracks documents associated with each topic at each timestamp
|
|
193
191
|
|
|
194
192
|
previous_c_tf_idf = None
|
|
195
193
|
previous_topics = None
|
|
@@ -437,7 +435,7 @@ class TempTopic:
|
|
|
437
435
|
"""
|
|
438
436
|
|
|
439
437
|
with open(self.debug_file, "a", encoding="utf-8") as f:
|
|
440
|
-
f.write(f"{'#'*50}\n")
|
|
438
|
+
f.write(f"{'#' * 50}\n")
|
|
441
439
|
f.write(f"Failed match for Topic {topic_id} at Timestamp {timestamp}\n")
|
|
442
440
|
f.write(f"Phrase to match: '{phrase}'\n")
|
|
443
441
|
f.write(f"Best match: '{best_match}' with score {best_score}\n\n")
|
|
@@ -445,7 +443,7 @@ class TempTopic:
|
|
|
445
443
|
for idx, doc in enumerate(token_strings):
|
|
446
444
|
f.write(f"Document {idx}:\n")
|
|
447
445
|
f.write(" ".join(doc) + "\n\n")
|
|
448
|
-
f.write(f"{'#'*50}\n\n")
|
|
446
|
+
f.write(f"{'#' * 50}\n\n")
|
|
449
447
|
|
|
450
448
|
def _calculate_representation_embeddings(
|
|
451
449
|
self,
|
|
@@ -39,27 +39,28 @@ class SecureAPIClient:
|
|
|
39
39
|
def _get_access_token(self, scope: str = None):
|
|
40
40
|
"""Obtain an access token using the client credentials flow"""
|
|
41
41
|
token_url = f"{self.url}/token"
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
with (
|
|
43
|
+
requests.post(
|
|
44
|
+
token_url,
|
|
45
|
+
data={
|
|
46
|
+
"username": self.client_id, # Send client_id as username
|
|
47
|
+
"password": self.client_secret, # Send client_secret as password
|
|
48
|
+
"scope": scope, # Requesting specific scopes
|
|
49
|
+
},
|
|
50
|
+
verify=False, # verify=False to avoid problems of certificate not generated by a trusted CA
|
|
51
|
+
) as response
|
|
52
|
+
):
|
|
53
|
+
if response.status_code == status.HTTP_200_OK:
|
|
54
|
+
token_data = response.json()
|
|
55
|
+
access_token = token_data["access_token"]
|
|
56
|
+
expires_in = token_data.get(
|
|
57
|
+
"expires_in", 3600
|
|
58
|
+
) # Default to 1 hour if expires_in is not provided
|
|
51
59
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
# Set the token and its expiry time (current time + expires_in)
|
|
60
|
-
self.token = access_token
|
|
61
|
-
self.token_expiry = time.time() + expires_in
|
|
62
|
-
else:
|
|
63
|
-
raise Exception(
|
|
64
|
-
f"Failed to obtain token: {response.status_code} {response.text}"
|
|
65
|
-
)
|
|
60
|
+
# Set the token and its expiry time (current time + expires_in)
|
|
61
|
+
self.token = access_token
|
|
62
|
+
self.token_expiry = time.time() + expires_in
|
|
63
|
+
else:
|
|
64
|
+
raise Exception(
|
|
65
|
+
f"Failed to obtain token: {response.status_code} {response.text}"
|
|
66
|
+
)
|
|
@@ -43,33 +43,33 @@ class EmbeddingAPIClient(SecureAPIClient, Embeddings):
|
|
|
43
43
|
"""
|
|
44
44
|
Return currently loaded model name in Embedding API.
|
|
45
45
|
"""
|
|
46
|
-
|
|
46
|
+
with requests.get(
|
|
47
47
|
self.url + "/model_name",
|
|
48
48
|
verify=False,
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
) as response:
|
|
50
|
+
if response.status_code == 200:
|
|
51
|
+
model_name = response.json()
|
|
52
|
+
logger.debug(f"Model name: {model_name}")
|
|
53
|
+
return model_name
|
|
54
|
+
else:
|
|
55
|
+
logger.error(f"Error: {response.status_code}")
|
|
56
|
+
raise Exception(f"Error: {response.status_code}")
|
|
57
57
|
|
|
58
58
|
def get_num_workers(self) -> int:
|
|
59
59
|
"""
|
|
60
60
|
Return currently loaded number of workers in Embedding API.
|
|
61
61
|
"""
|
|
62
|
-
|
|
62
|
+
with requests.get(
|
|
63
63
|
self.url + "/num_workers",
|
|
64
64
|
verify=False,
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
65
|
+
) as response:
|
|
66
|
+
if response.status_code == 200:
|
|
67
|
+
num_workers = response.json()
|
|
68
|
+
logger.debug(f"Number of workers: {num_workers}")
|
|
69
|
+
return num_workers
|
|
70
|
+
else:
|
|
71
|
+
logger.error(f"Error: {response.status_code}")
|
|
72
|
+
raise Exception(f"Error: {response.status_code}")
|
|
73
73
|
|
|
74
74
|
def embed_query(
|
|
75
75
|
self, text: str | list[str], show_progress_bar: bool = False
|
|
@@ -78,36 +78,36 @@ class EmbeddingAPIClient(SecureAPIClient, Embeddings):
|
|
|
78
78
|
text = [text]
|
|
79
79
|
logger.debug(f"Calling EmbeddingAPI using model: {self.model_name}")
|
|
80
80
|
logger.debug(f"Computing embeddings...")
|
|
81
|
-
|
|
81
|
+
with requests.post(
|
|
82
82
|
self.url + "/encode",
|
|
83
83
|
data=json.dumps({"text": text, "show_progress_bar": show_progress_bar}),
|
|
84
84
|
verify=False,
|
|
85
85
|
headers=self._get_headers(),
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
) as response:
|
|
87
|
+
if response.status_code == 200:
|
|
88
|
+
embeddings = np.array(response.json()["embeddings"])
|
|
89
|
+
logger.debug(f"Computing embeddings done")
|
|
90
|
+
return embeddings.tolist()[0]
|
|
91
|
+
else:
|
|
92
|
+
logger.error(f"Error: {response.status_code}")
|
|
93
93
|
|
|
94
94
|
def embed_batch(
|
|
95
95
|
self, texts: list[str], show_progress_bar: bool = True
|
|
96
96
|
) -> list[list[float]]:
|
|
97
97
|
logger.debug(f"Computing embeddings...")
|
|
98
|
-
|
|
98
|
+
with requests.post(
|
|
99
99
|
self.url + "/encode",
|
|
100
100
|
data=json.dumps({"text": texts, "show_progress_bar": show_progress_bar}),
|
|
101
101
|
verify=False,
|
|
102
102
|
headers=self._get_headers(),
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
103
|
+
) as response:
|
|
104
|
+
if response.status_code == 200:
|
|
105
|
+
embeddings = np.array(response.json()["embeddings"])
|
|
106
|
+
logger.debug(f"Computing embeddings done for batch")
|
|
107
|
+
return embeddings.tolist()
|
|
108
|
+
else:
|
|
109
|
+
logger.error(f"Error: {response.status_code}")
|
|
110
|
+
return []
|
|
111
111
|
|
|
112
112
|
def embed_documents(
|
|
113
113
|
self,
|
|
@@ -133,7 +133,13 @@ class EmbeddingAPIClient(SecureAPIClient, Embeddings):
|
|
|
133
133
|
)
|
|
134
134
|
|
|
135
135
|
# Parallel request
|
|
136
|
-
|
|
136
|
+
#
|
|
137
|
+
# We explicitly use a *thread-based* backend here. Using the default
|
|
138
|
+
# (process-based) backend would require pickling ``self`` and the
|
|
139
|
+
# underlying SecureAPIClient state (e.g. auth/session objects), which
|
|
140
|
+
# is fragile and can easily break. Threads share the same context and
|
|
141
|
+
# avoid these issues while still allowing concurrent HTTP requests.
|
|
142
|
+
results = Parallel(n_jobs=MAX_N_JOBS, prefer="threads")(
|
|
137
143
|
delayed(self.embed_batch)(batch, show_progress_bar) for batch in batches
|
|
138
144
|
)
|
|
139
145
|
|
{bertrend-0.3.22 → bertrend-0.3.24}/bertrend/services/embedding_server/routers/authentication.py
RENAMED
|
@@ -31,7 +31,7 @@ async def login_for_access_token(
|
|
|
31
31
|
"/list_registered_clients", summary="List registered clients (requires admin scope)"
|
|
32
32
|
)
|
|
33
33
|
async def list_clients(
|
|
34
|
-
current_client: TokenData = Security(get_current_client, scopes=[ADMIN])
|
|
34
|
+
current_client: TokenData = Security(get_current_client, scopes=[ADMIN]),
|
|
35
35
|
):
|
|
36
36
|
return list_registered_clients()
|
|
37
37
|
|
|
@@ -4,16 +4,19 @@
|
|
|
4
4
|
# This file is part of BERTrend.
|
|
5
5
|
|
|
6
6
|
import os
|
|
7
|
-
import uvicorn
|
|
8
7
|
|
|
8
|
+
# Load the configuration BEFORE any other imports that might use CUDA
|
|
9
9
|
from bertrend.services.embedding_server.config.settings import get_config
|
|
10
10
|
|
|
11
|
-
# Load the configuration
|
|
12
11
|
CONFIG = get_config()
|
|
13
12
|
|
|
14
|
-
# Set the CUDA_VISIBLE_DEVICES environment variable
|
|
13
|
+
# Set the CUDA_VISIBLE_DEVICES environment variable BEFORE importing uvicorn
|
|
14
|
+
# This is critical because uvicorn will import the app module, which imports torch
|
|
15
|
+
# We override the value with the content of the config
|
|
15
16
|
os.environ["CUDA_VISIBLE_DEVICES"] = CONFIG.cuda_visible_devices
|
|
16
17
|
|
|
18
|
+
import uvicorn
|
|
19
|
+
|
|
17
20
|
# Start the FastAPI application
|
|
18
21
|
if __name__ == "__main__":
|
|
19
22
|
uvicorn.run(
|
|
@@ -17,13 +17,13 @@ if CONFIG.host == "0.0.0.0":
|
|
|
17
17
|
|
|
18
18
|
# Try to check health endpoint and handle any connection errors
|
|
19
19
|
try:
|
|
20
|
-
|
|
20
|
+
with requests.get(
|
|
21
21
|
f"https://{CONFIG.host}:{CONFIG.port}/health", timeout=5, verify=False
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
) as response:
|
|
23
|
+
if response.status_code == 200:
|
|
24
|
+
sys.exit(0)
|
|
25
|
+
else:
|
|
26
|
+
sys.exit(1)
|
|
27
27
|
|
|
28
28
|
# If an error occurs, exit with status code 1
|
|
29
29
|
except (requests.exceptions.RequestException, requests.exceptions.ConnectionError) as e:
|
|
@@ -79,7 +79,9 @@ class EmbeddingService(BaseEmbedder):
|
|
|
79
79
|
self.embedding_model_name = model_name
|
|
80
80
|
self.embedding_dtype = embedding_dtype
|
|
81
81
|
|
|
82
|
-
def embed(
|
|
82
|
+
def embed(
|
|
83
|
+
self, texts: list[str] | pd.Series, verbose: bool = False
|
|
84
|
+
) -> tuple[
|
|
83
85
|
np.ndarray,
|
|
84
86
|
list[list[str]] | None,
|
|
85
87
|
list[np.ndarray] | None,
|
|
@@ -267,14 +269,14 @@ class EmbeddingService(BaseEmbedder):
|
|
|
267
269
|
Exception
|
|
268
270
|
If the API request fails.
|
|
269
271
|
"""
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
272
|
+
with requests.get(self.url + "/model_name", verify=False) as response:
|
|
273
|
+
if response.status_code == 200:
|
|
274
|
+
model_name = response.json()
|
|
275
|
+
logger.debug(f"Remote model name: {model_name}")
|
|
276
|
+
return model_name
|
|
277
|
+
else:
|
|
278
|
+
logger.error(f"Error: {response.status_code}")
|
|
279
|
+
raise Exception(f"Error: {response.status_code}")
|
|
278
280
|
|
|
279
281
|
|
|
280
282
|
def _convert_to_numpy(obj, type=None):
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
import time
|
|
6
6
|
|
|
7
7
|
import requests
|
|
8
|
-
from fastapi import HTTPException
|
|
9
8
|
from loguru import logger
|
|
10
9
|
|
|
11
10
|
|
|
@@ -24,27 +23,27 @@ def http_request(
|
|
|
24
23
|
method: str = "GET",
|
|
25
24
|
headers: dict = None,
|
|
26
25
|
json_data: dict = None,
|
|
27
|
-
timeout: int =
|
|
26
|
+
timeout: int = 600, # 10 min
|
|
28
27
|
):
|
|
29
28
|
"""Execute an HTTP request (curl-like functionality)"""
|
|
30
29
|
logger.info(f"Executing HTTP {method} request to {url}")
|
|
31
30
|
try:
|
|
32
|
-
|
|
31
|
+
with requests.request(
|
|
33
32
|
method=method.upper(),
|
|
34
33
|
url=url,
|
|
35
34
|
headers=headers,
|
|
36
35
|
json=json_data,
|
|
37
36
|
timeout=timeout,
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
) as response:
|
|
38
|
+
if response.status_code != 200:
|
|
39
|
+
response.raise_for_status()
|
|
40
|
+
logger.info(
|
|
41
|
+
f"HTTP request completed with status code: {response.status_code}"
|
|
42
|
+
)
|
|
43
|
+
return f"Request to {url} completed with status {response.status_code}"
|
|
43
44
|
except Exception as e:
|
|
44
45
|
logger.error(f"HTTP request failed: {str(e)}")
|
|
45
|
-
raise
|
|
46
|
-
status_code=500, detail=f"Error executing request: {str(e)}"
|
|
47
|
-
)
|
|
46
|
+
raise RuntimeError(f"Error executing request: {str(e)}")
|
|
48
47
|
|
|
49
48
|
|
|
50
49
|
# Job function registry
|