bertrend 0.3.12__tar.gz → 0.3.13__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.
Files changed (209) hide show
  1. {bertrend-0.3.12 → bertrend-0.3.13}/PKG-INFO +2 -1
  2. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/llm_utils/newsletter_model.py +8 -7
  3. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/llm_utils/newsletter_outlook_template.html +25 -9
  4. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/llm_utils/newsletter_template.html +20 -5
  5. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_newsletter_model.py +4 -23
  6. bertrend-0.3.13/bertrend_apps/common/mail_utils.py +131 -0
  7. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/__init__.py +1 -0
  8. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/app.py +26 -0
  9. bertrend-0.3.13/bertrend_apps/prospective_demo/data_model.py +19 -0
  10. bertrend-0.3.13/bertrend_apps/prospective_demo/detailed_report_template.html +438 -0
  11. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/i18n_translations.py +4 -11
  12. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/models_info.py +11 -17
  13. bertrend-0.3.13/bertrend_apps/prospective_demo/report_generation.py +325 -0
  14. {bertrend-0.3.12 → bertrend-0.3.13}/pyproject.toml +2 -1
  15. bertrend-0.3.12/bertrend_apps/common/mail_utils.py +0 -91
  16. bertrend-0.3.12/bertrend_apps/prospective_demo/report_generation.py +0 -215
  17. bertrend-0.3.12/bertrend_apps/prospective_demo/report_template.html +0 -148
  18. bertrend-0.3.12/bertrend_apps/prospective_demo/report_utils.py +0 -132
  19. {bertrend-0.3.12 → bertrend-0.3.13}/AUTHORS.txt +0 -0
  20. {bertrend-0.3.12 → bertrend-0.3.13}/LICENSE.md +0 -0
  21. {bertrend-0.3.12 → bertrend-0.3.13}/README.md +0 -0
  22. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/BERTopicModel.py +0 -0
  23. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/BERTrend.py +0 -0
  24. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/__init__.py +0 -0
  25. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/config/bertopic_default_config.toml +0 -0
  26. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/config/bertrend_default_config.toml +0 -0
  27. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/config/parameters.py +0 -0
  28. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/config/services_default_config.toml +0 -0
  29. {bertrend-0.3.12/bertrend_apps/newsletters → bertrend-0.3.13/bertrend/demos}/__init__.py +0 -0
  30. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/demos_utils/__init__.py +0 -0
  31. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/demos_utils/data_loading_component.py +0 -0
  32. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/demos_utils/embed_documents_component.py +0 -0
  33. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/demos_utils/i18n.py +0 -0
  34. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/demos_utils/i18n_translations.py +0 -0
  35. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/demos_utils/icons.py +0 -0
  36. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/demos_utils/parameters_component.py +0 -0
  37. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/demos_utils/state_utils.py +0 -0
  38. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/start_summarizer_app.sh +0 -0
  39. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/start_topic_analysis_app.sh +0 -0
  40. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/start_weak_signals_app.sh +0 -0
  41. {bertrend-0.3.12/bertrend_apps/exploration/curebot → bertrend-0.3.13/bertrend/demos/summarization}/__init__.py +0 -0
  42. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/summarization/summarizer_app.py +0 -0
  43. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/topic_analysis/.streamlit/config.toml +0 -0
  44. {bertrend-0.3.12/bertrend_apps/exploration → bertrend-0.3.13/bertrend/demos/topic_analysis}/__init__.py +0 -0
  45. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/topic_analysis/app.py +0 -0
  46. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/topic_analysis/app_utils.py +0 -0
  47. {bertrend-0.3.12/bertrend_apps/common → bertrend-0.3.13/bertrend/demos/topic_analysis/demo_pages}/__init__.py +0 -0
  48. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/topic_analysis/demo_pages/explore_topics.py +0 -0
  49. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/topic_analysis/demo_pages/newsletters_generation.py +0 -0
  50. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/topic_analysis/demo_pages/temporal_visualizations.py +0 -0
  51. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/topic_analysis/demo_pages/topic_visualizations.py +0 -0
  52. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/topic_analysis/demo_pages/training_page.py +0 -0
  53. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/topic_analysis/i18n_translations.py +0 -0
  54. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/weak_signals/.streamlit/config.toml +0 -0
  55. {bertrend-0.3.12/bertrend_apps → bertrend-0.3.13/bertrend/demos/weak_signals}/__init__.py +0 -0
  56. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/weak_signals/app.py +0 -0
  57. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/weak_signals/i18n_translations.py +0 -0
  58. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/demos/weak_signals/visualizations_utils.py +0 -0
  59. {bertrend-0.3.12/bertrend/trend_analysis → bertrend-0.3.13/bertrend/llm_utils}/__init__.py +0 -0
  60. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/llm_utils/newsletter.css +0 -0
  61. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/llm_utils/newsletter_features.py +0 -0
  62. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/llm_utils/openai_client.py +0 -0
  63. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/llm_utils/prompts.py +0 -0
  64. {bertrend-0.3.12/bertrend/topic_analysis → bertrend-0.3.13/bertrend/metrics}/__init__.py +0 -0
  65. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/metrics/temporal_metrics_embedding.py +0 -0
  66. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/metrics/topic_metrics.py +0 -0
  67. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/resources/common_ngrams.json +0 -0
  68. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/resources/stopwords-en.json +0 -0
  69. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/resources/stopwords-fr.json +0 -0
  70. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/resources/stopwords-rte.json +0 -0
  71. {bertrend-0.3.12/bertrend/tests → bertrend-0.3.13/bertrend/services}/__init__.py +0 -0
  72. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/authentication.py +0 -0
  73. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_client.py +0 -0
  74. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_server/README.md +0 -0
  75. {bertrend-0.3.12/bertrend/services/summary → bertrend-0.3.13/bertrend/services/embedding_server}/__init__.py +0 -0
  76. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_server/bertrend_client_registry.json +0 -0
  77. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_server/config/default_config.toml +0 -0
  78. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_server/config/settings.py +0 -0
  79. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_server/main.py +0 -0
  80. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_server/models.py +0 -0
  81. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_server/routers/__init__.py +0 -0
  82. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_server/routers/authentication.py +0 -0
  83. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_server/routers/embeddings.py +0 -0
  84. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_server/routers/info.py +0 -0
  85. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_server/security.py +0 -0
  86. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_server/start.py +0 -0
  87. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_server/status.py +0 -0
  88. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_server/stop.py +0 -0
  89. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/embedding_service.py +0 -0
  90. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/summarizer.py +0 -0
  91. {bertrend-0.3.12/bertrend/services/embedding_server → bertrend-0.3.13/bertrend/services/summary}/__init__.py +0 -0
  92. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/summary/abstractive_summarizer.py +0 -0
  93. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/summary/chatgpt_summarizer.py +0 -0
  94. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/summary/extractive_summarizer.py +0 -0
  95. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/summary/lexrank.py +0 -0
  96. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/services/summary/prompts.py +0 -0
  97. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/README_integration_tests.md +0 -0
  98. {bertrend-0.3.12/bertrend/services → bertrend-0.3.13/bertrend/tests}/__init__.py +0 -0
  99. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/conftest.py +0 -0
  100. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_abstractive_summarizer.py +0 -0
  101. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_bertrend.py +0 -0
  102. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_cache_utils.py +0 -0
  103. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_chatgpt_summarizer.py +0 -0
  104. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_config_utils.py +0 -0
  105. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_data_loading.py +0 -0
  106. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_data_structure.py +0 -0
  107. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_embedding_client.py +0 -0
  108. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_extractive_summarizer.py +0 -0
  109. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_installation.py +0 -0
  110. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_integration.py +0 -0
  111. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_newsletter_features.py +0 -0
  112. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_openai_client.py +0 -0
  113. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_representative_docs.py +0 -0
  114. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_summarizer.py +0 -0
  115. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_temporal_metrics_embedding.py +0 -0
  116. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_topic_description.py +0 -0
  117. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_topic_metrics.py +0 -0
  118. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_topic_model.py +0 -0
  119. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_trend_analysis_data_structure.py +0 -0
  120. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_trend_analysis_prompts.py +0 -0
  121. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_trend_analysis_visualizations.py +0 -0
  122. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_trend_analysis_weak_signals.py +0 -0
  123. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_utils_init.py +0 -0
  124. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/tests/test_visualizations.py +0 -0
  125. {bertrend-0.3.12/bertrend/metrics → bertrend-0.3.13/bertrend/topic_analysis}/__init__.py +0 -0
  126. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/topic_analysis/data_structure.py +0 -0
  127. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/topic_analysis/prompts.py +0 -0
  128. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/topic_analysis/representative_docs.py +0 -0
  129. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/topic_analysis/topic_description.py +0 -0
  130. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/topic_analysis/visualizations.py +0 -0
  131. {bertrend-0.3.12/bertrend/llm_utils → bertrend-0.3.13/bertrend/trend_analysis}/__init__.py +0 -0
  132. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/trend_analysis/data_structure.py +0 -0
  133. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/trend_analysis/prompts.py +0 -0
  134. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/trend_analysis/signal_llm_template_en.html +0 -0
  135. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/trend_analysis/signal_llm_template_fr.html +0 -0
  136. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/trend_analysis/visualizations.py +0 -0
  137. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/trend_analysis/weak_signals.py +0 -0
  138. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/utils/__init__.py +0 -0
  139. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/utils/cache_utils.py +0 -0
  140. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/utils/config_utils.py +0 -0
  141. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend/utils/data_loading.py +0 -0
  142. {bertrend-0.3.12/bertrend/demos/weak_signals → bertrend-0.3.13/bertrend_apps}/__init__.py +0 -0
  143. {bertrend-0.3.12/bertrend/demos/topic_analysis/demo_pages → bertrend-0.3.13/bertrend_apps/common}/__init__.py +0 -0
  144. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/common/crontab_utils.py +0 -0
  145. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/config/feeds/arxiv_feed.toml +0 -0
  146. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/config/feeds/decarbonation_feed.toml +0 -0
  147. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/config/feeds/llm_en_feed.toml +0 -0
  148. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/config/feeds/llm_feed.toml +0 -0
  149. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/config/feeds/nlp_feed.toml +0 -0
  150. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/config/feeds/rte_feed.toml +0 -0
  151. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/config/gmail_credentials.json +0 -0
  152. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/config/newsletters/arxiv_newsletter_from_last.toml +0 -0
  153. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/config/newsletters/decarbonation_newsletter_from_last.toml +0 -0
  154. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/config/newsletters/decarbonation_newsletter_from_scratch.toml +0 -0
  155. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/config/newsletters/llm_en_newsletter_from_last.toml +0 -0
  156. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/config/newsletters/llm_newsletter_from_last.toml +0 -0
  157. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/config/newsletters/nlp_newsletter_from_last.toml +0 -0
  158. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/config/newsletters/rte_newsletter_from_last.toml +0 -0
  159. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/config/newsletters/rte_newsletter_from_scratch.toml +0 -0
  160. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/data_provider/__init__.py +0 -0
  161. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/data_provider/__main__.py +0 -0
  162. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/data_provider/arxiv_provider.py +0 -0
  163. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/data_provider/atom_feed_provider.py +0 -0
  164. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/data_provider/bing_news_provider.py +0 -0
  165. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/data_provider/data_provider.py +0 -0
  166. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/data_provider/google_news_provider.py +0 -0
  167. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/data_provider/newscatcher_provider.py +0 -0
  168. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/data_provider/utils.py +0 -0
  169. {bertrend-0.3.12/bertrend/demos/topic_analysis → bertrend-0.3.13/bertrend_apps/exploration}/__init__.py +0 -0
  170. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/curebot/.streamlit/config.toml +0 -0
  171. {bertrend-0.3.12/bertrend/demos/summarization → bertrend-0.3.13/bertrend_apps/exploration/curebot}/__init__.py +0 -0
  172. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/curebot/app.py +0 -0
  173. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/curebot/app_utils.py +0 -0
  174. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/curebot/config.toml +0 -0
  175. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/curebot/import_extraction_article.ipynb +0 -0
  176. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/curebot/prompts.py +0 -0
  177. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/curebot/start_newsletter_generator.sh +0 -0
  178. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/curebot/tabs/tab1.py +0 -0
  179. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/curebot/tabs/tab2.py +0 -0
  180. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/curebot/tabs/tab3.py +0 -0
  181. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/dataviz/Main_page.py +0 -0
  182. {bertrend-0.3.12/bertrend_apps/exploration/geolocalization/spacy → bertrend-0.3.13/bertrend_apps/exploration/dataviz}/__init__.py +0 -0
  183. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/dataviz/pages/1_Data_feeds.py +0 -0
  184. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/geolocalization/__init__.py +0 -0
  185. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/geolocalization/entity_utils.py +0 -0
  186. {bertrend-0.3.12/bertrend_apps/exploration/dataviz → bertrend-0.3.13/bertrend_apps/exploration/geolocalization/spacy}/__init__.py +0 -0
  187. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/geolocalization/spacy/common_factory.py +0 -0
  188. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/geolocalization/spacy/dbpedia.py +0 -0
  189. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/geolocalization/spacy/nlp.config +0 -0
  190. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/exploration/geolocalization/spacy/utils.py +0 -0
  191. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/install_feeds_and_newsletters.py +0 -0
  192. {bertrend-0.3.12/bertrend/demos → bertrend-0.3.13/bertrend_apps/newsletters}/__init__.py +0 -0
  193. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/newsletters/__main__.py +0 -0
  194. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/.streamlit/config.toml +0 -0
  195. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/.streamlit/secrets.toml +0 -0
  196. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/authentication.py +0 -0
  197. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/dashboard_analysis.py +0 -0
  198. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/dashboard_common.py +0 -0
  199. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/dashboard_signals.py +0 -0
  200. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/feeds_common.py +0 -0
  201. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/feeds_config.py +0 -0
  202. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/feeds_data.py +0 -0
  203. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/llm_utils.py +0 -0
  204. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/perf_utils.py +0 -0
  205. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/process_new_data.py +0 -0
  206. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/start_demo.sh +0 -0
  207. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/prospective_demo/streamlit_utils.py +0 -0
  208. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/start_apps.sh +0 -0
  209. {bertrend-0.3.12 → bertrend-0.3.13}/bertrend_apps/stop_apps.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bertrend
3
- Version: 0.3.12
3
+ Version: 0.3.13
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
  Keywords: topics,BERTopic,transformers,weak signals,LLM
@@ -59,6 +59,7 @@ Requires-Dist: sentencepiece (>=0.2.0)
59
59
  Requires-Dist: starlette (>=0.46.2)
60
60
  Requires-Dist: streamlit (>=1.46)
61
61
  Requires-Dist: streamlit-code-editor (>=0.1.22)
62
+ Requires-Dist: streamlit-tags
62
63
  Requires-Dist: supervisor (>=4.2.5)
63
64
  Requires-Dist: thefuzz (>=0.22.1)
64
65
  Requires-Dist: tiktoken (>=0.8.0)
@@ -2,8 +2,8 @@
2
2
  # See AUTHORS.txt
3
3
  # SPDX-License-Identifier: MPL-2.0
4
4
  # This file is part of BERTrend.
5
+ from typing import Optional
5
6
 
6
- from typing import List
7
7
  from pydantic import BaseModel
8
8
  from datetime import date
9
9
 
@@ -16,7 +16,7 @@ class Article(BaseModel):
16
16
  """Article model."""
17
17
 
18
18
  title: str
19
- date: date
19
+ date: Optional[date]
20
20
  summary: str | None = None
21
21
  source: str | None = None
22
22
  url: str | None = None
@@ -26,9 +26,9 @@ class Topic(BaseModel):
26
26
  """Topic model."""
27
27
 
28
28
  title: str
29
- hashtags: List[str]
29
+ hashtags: list[str] | None = None
30
30
  summary: str | None = None
31
- articles: List[Article]
31
+ articles: list[Article]
32
32
  topic_type: str = (
33
33
  STRONG_TOPIC_TYPE # Default value "strong", can be "weak" or "noise"
34
34
  )
@@ -38,7 +38,8 @@ class Newsletter(BaseModel):
38
38
  """Newsletter model."""
39
39
 
40
40
  title: str
41
- period_start_date: date
42
- period_end_date: date
43
- topics: List[Topic]
41
+ reference_period: date = None # has the precedence over the two other dates
42
+ period_start_date: date = None
43
+ period_end_date: date = None
44
+ topics: list[Topic]
44
45
  debug_info: dict | None = None
@@ -58,13 +58,21 @@
58
58
  <tr>
59
59
  <td>
60
60
  <h1 style="font-size: 32px; color: #333; margin: 0 0 10px 0; font-family: Arial, sans-serif;">{{ newsletter.title }}</h1>
61
- <p style="font-size: 18px; color: #555; margin: 0 0 30px 0; font-family: Arial, sans-serif;">
62
- {% if language == 'en' %}
63
- Period: {{ newsletter.period_start_date }} to {{ newsletter.period_end_date }}
64
- {% else %}
65
- Période : {{ newsletter.period_start_date }} au {{ newsletter.period_end_date }}
66
- {% endif %}
67
- </p>
61
+ <p style="font-size: 18px; color: #555; margin: 0 0 30px 0; font-family: Arial, sans-serif;">
62
+ {% if newsletter.reference_period %}
63
+ {% if language == 'en' %}
64
+ Period: {{ newsletter.reference_period }}
65
+ {% else %}
66
+ Période : {{ newsletter.reference_period }}
67
+ {% endif %}
68
+ {% elif newsletter.period_start_date and newsletter.period_end_date %}
69
+ {% if language == 'en' %}
70
+ Period: {{ newsletter.period_start_date }} to {{ newsletter.period_end_date }}
71
+ {% else %}
72
+ Période : {{ newsletter.period_start_date }} au {{ newsletter.period_end_date }}
73
+ {% endif %}
74
+ {% endif %}
75
+ </p>
68
76
  </td>
69
77
  </tr>
70
78
  </table>
@@ -123,7 +131,9 @@
123
131
 
124
132
  <!-- Date and Source -->
125
133
  <div style="font-size: 10px; color: #666; margin-bottom: 8px; font-family: Arial, sans-serif;">
134
+ {% if article.date %}
126
135
  <span style="font-weight: bold;">{{ article.date }}</span>
136
+ {% endif %}
127
137
  {% if article.source %}
128
138
  <span style="margin: 0 5px;">|</span>
129
139
  <span style="font-style: italic;">
@@ -150,6 +160,10 @@
150
160
  </tr>
151
161
  </table>
152
162
  {% endfor %}
163
+
164
+ {% block detailed_topic_analysis scoped %}
165
+ <!-- Placeholder for detailed analysis -->
166
+ {% endblock %}
153
167
  </td>
154
168
  </tr>
155
169
  </table>
@@ -174,6 +188,8 @@
174
188
  </td>
175
189
  </tr>
176
190
  </table>
177
- </body>
178
191
 
179
- </html>
192
+ </body>
193
+
194
+ </html>
195
+
@@ -27,10 +27,18 @@
27
27
  <header>
28
28
  <h1>{{ newsletter.title }}</h1>
29
29
  <p class="period">
30
- {% if language == 'en' %}
31
- Period: {{ newsletter.period_start_date }} to {{ newsletter.period_end_date }}
32
- {% else %}
33
- Période : {{ newsletter.period_start_date }} au {{ newsletter.period_end_date }}
30
+ {% if newsletter.reference_period %}
31
+ {% if language == 'en' %}
32
+ Period: {{ newsletter.reference_period }}
33
+ {% else %}
34
+ Période : {{ newsletter.reference_period }}
35
+ {% endif %}
36
+ {% elif newsletter.period_start_date and newsletter.period_end_date %}
37
+ {% if language == 'en' %}
38
+ Period: {{ newsletter.period_start_date }} to {{ newsletter.period_end_date }}
39
+ {% else %}
40
+ Période : {{ newsletter.period_start_date }} au {{ newsletter.period_end_date }}
41
+ {% endif %}
34
42
  {% endif %}
35
43
  </p>
36
44
  </header>
@@ -61,7 +69,9 @@
61
69
  {% endif %}
62
70
  <!-- Date and Source Inline -->
63
71
  <div class="timestamp">
64
- <div class="date">{{ article.date }}</div>
72
+ {% if article.date %}
73
+ <div class="date">{{ article.date }}</div>
74
+ {% endif %}
65
75
  {% if article.source %}
66
76
  <span class="separator">|</span>
67
77
  <div class="source">
@@ -87,6 +97,11 @@
87
97
  </div>
88
98
  {% endfor %}
89
99
  </div>
100
+
101
+ <!-- Placeholder for additional info -->
102
+ {% block detailed_topic_analysis with topic=topic %}
103
+ {% endblock %}
104
+
90
105
  </section>
91
106
  {% endfor %}
92
107
  </main>
@@ -127,11 +127,6 @@ class TestTopic:
127
127
  Topic(hashtags=["#test"], articles=articles)
128
128
  assert "title" in str(exc_info.value)
129
129
 
130
- # Missing hashtags
131
- with pytest.raises(ValidationError) as exc_info:
132
- Topic(title="Test Topic", articles=articles)
133
- assert "hashtags" in str(exc_info.value)
134
-
135
130
  # Missing articles
136
131
  with pytest.raises(ValidationError) as exc_info:
137
132
  Topic(title="Test Topic", hashtags=["#test"])
@@ -246,30 +241,13 @@ class TestNewsletter:
246
241
  # Missing title
247
242
  with pytest.raises(ValidationError) as exc_info:
248
243
  Newsletter(
244
+ reference_period=date(2024, 1, 31),
249
245
  period_start_date=date(2024, 1, 1),
250
246
  period_end_date=date(2024, 1, 31),
251
247
  topics=topics,
252
248
  )
253
249
  assert "title" in str(exc_info.value)
254
250
 
255
- # Missing period_start_date
256
- with pytest.raises(ValidationError) as exc_info:
257
- Newsletter(
258
- title="Test Newsletter",
259
- period_end_date=date(2024, 1, 31),
260
- topics=topics,
261
- )
262
- assert "period_start_date" in str(exc_info.value)
263
-
264
- # Missing period_end_date
265
- with pytest.raises(ValidationError) as exc_info:
266
- Newsletter(
267
- title="Test Newsletter",
268
- period_start_date=date(2024, 1, 1),
269
- topics=topics,
270
- )
271
- assert "period_end_date" in str(exc_info.value)
272
-
273
251
  # Missing topics
274
252
  with pytest.raises(ValidationError) as exc_info:
275
253
  Newsletter(
@@ -399,6 +377,7 @@ class TestIntegration:
399
377
  title="Test Newsletter",
400
378
  period_start_date=date(2024, 1, 1),
401
379
  period_end_date=date(2024, 1, 31),
380
+ reference_period=date(2024, 1, 31),
402
381
  topics=[topic],
403
382
  )
404
383
 
@@ -409,6 +388,7 @@ class TestIntegration:
409
388
  assert data["title"] == "Test Newsletter"
410
389
  assert data["period_start_date"] == date(2024, 1, 1)
411
390
  assert data["period_end_date"] == date(2024, 1, 31)
391
+ assert data["reference_period"] == date(2024, 1, 31)
412
392
  assert len(data["topics"]) == 1
413
393
  assert data["topics"][0]["title"] == "Test Topic"
414
394
  assert len(data["topics"][0]["articles"]) == 1
@@ -420,4 +400,5 @@ class TestIntegration:
420
400
  assert newsletter_from_dict.title == newsletter.title
421
401
  assert newsletter_from_dict.period_start_date == newsletter.period_start_date
422
402
  assert newsletter_from_dict.period_end_date == newsletter.period_end_date
403
+ assert newsletter_from_dict.reference_period == newsletter.reference_period
423
404
  assert len(newsletter_from_dict.topics) == len(newsletter.topics)
@@ -0,0 +1,131 @@
1
+ # Copyright (c) 2024, 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 base64
7
+ import os
8
+ from email.message import EmailMessage
9
+ from email.utils import COMMASPACE
10
+ import mimetypes
11
+ from pathlib import Path
12
+
13
+ # Gmail API utils
14
+ from google.auth.transport.requests import Request
15
+ from google.oauth2.credentials import Credentials
16
+ from google_auth_oauthlib.flow import InstalledAppFlow
17
+ from googleapiclient.discovery import build
18
+ from googleapiclient.errors import HttpError
19
+ from loguru import logger
20
+
21
+ from bertrend import BASE_PATH
22
+
23
+ SCOPES = ["https://mail.google.com/"] # full access to mail API
24
+ FROM = "wattelse.ai@gmail.com"
25
+ TOKEN_PATH = BASE_PATH / "gmail_token.json"
26
+ DEFAULT_GMAIL_CREDENTIALS_PATH = (
27
+ Path(__file__).parent.parent / "config" / "gmail_credentials.json"
28
+ )
29
+
30
+ # Ensures to write with +rw for both user and groups
31
+ os.umask(0o002)
32
+
33
+
34
+ def get_credentials(
35
+ credentials_path: Path = DEFAULT_GMAIL_CREDENTIALS_PATH,
36
+ ) -> Credentials:
37
+ """Returns credentials for the user"""
38
+ creds = None
39
+ # The file token.json stores the user's access and refresh tokens, and is
40
+ # created automatically when the authorization flow completes for the first
41
+ # time.
42
+ logger.debug(f"Gmail credentials path: {credentials_path}")
43
+ logger.debug(f"Gmail token path: {TOKEN_PATH}")
44
+ if TOKEN_PATH.exists():
45
+ creds = Credentials.from_authorized_user_file(TOKEN_PATH, SCOPES)
46
+ # If there are no (valid) credentials available, let the user log in.
47
+ if not creds or not creds.valid:
48
+ if creds and creds.expired and creds.refresh_token:
49
+ creds.refresh(Request())
50
+ else:
51
+ flow = InstalledAppFlow.from_client_secrets_file(credentials_path, SCOPES)
52
+ creds = flow.run_local_server(port=0)
53
+ # Save the credentials for the next run
54
+ with open(TOKEN_PATH, "w") as token:
55
+ token.write(creds.to_json())
56
+ return creds
57
+
58
+
59
+ def send_email(
60
+ credentials,
61
+ subject: str,
62
+ recipients: list[str],
63
+ content: str | Path,
64
+ content_type: str = "html",
65
+ file_name: str = None,
66
+ ) -> None:
67
+ """
68
+ Send an e-mail with Gmail API.
69
+
70
+ If *content* is a valid path it is attached as a file (with an optional filename),
71
+ otherwise it is used as the message body.
72
+ """
73
+ try:
74
+ service = build("gmail", "v1", credentials=credentials)
75
+
76
+ msg = EmailMessage()
77
+ msg["Subject"] = subject
78
+ msg["From"] = FROM
79
+ msg["To"] = COMMASPACE.join(recipients)
80
+
81
+ # ------------------------------------------------------------------ #
82
+ # 1. Attach a file if *content* points to an existing file #
83
+ # ------------------------------------------------------------------ #
84
+ if isinstance(content, (str, Path)) and Path(content).is_file():
85
+ file_path = Path(content)
86
+
87
+ # Body text so the message is not “empty”
88
+ msg.set_content(
89
+ f"Please find {file_path.name} attached.",
90
+ subtype="plain",
91
+ )
92
+
93
+ mime_type, _ = mimetypes.guess_type(file_path)
94
+ mime_type = mime_type or "application/octet-stream"
95
+ maintype, subtype = mime_type.split("/", 1)
96
+
97
+ with file_path.open("rb") as fp:
98
+ msg.add_attachment(
99
+ fp.read(),
100
+ maintype=maintype,
101
+ subtype=subtype,
102
+ filename=file_path.name if not file_name else file_name,
103
+ )
104
+
105
+ # ------------------------------------------------------------------ #
106
+ # 2. Otherwise use *content* as the body #
107
+ # ------------------------------------------------------------------ #
108
+ else:
109
+ subtype = (
110
+ "plain"
111
+ if content_type.lower() in {"md", "text", "txt"}
112
+ else content_type
113
+ )
114
+ msg.set_content(content, subtype=subtype)
115
+
116
+ # ------------------------------------------------------------------ #
117
+ # 3. Send through Gmail API #
118
+ # ------------------------------------------------------------------ #
119
+ raw_message = base64.urlsafe_b64encode(msg.as_bytes()).decode()
120
+ service.users().messages().send(
121
+ userId="me", body={"raw": raw_message}
122
+ ).execute()
123
+
124
+ logger.debug("E-mail successfully sent.")
125
+
126
+ except HttpError as err:
127
+ logger.error("Gmail API error: %s", err)
128
+ except FileNotFoundError:
129
+ logger.error("File not found: %s", content)
130
+ except Exception as err:
131
+ logger.exception("Unexpected error: %s", err)
@@ -34,6 +34,7 @@ DEFAULT_ANALYSIS_CFG = {
34
34
  "granularity": DEFAULT_GRANULARITY,
35
35
  "window_size": DEFAULT_WINDOW_SIZE,
36
36
  "language": "French",
37
+ "split_by_paragraph": True,
37
38
  },
38
39
  "analysis_config": {
39
40
  "topic_evolution": True,
@@ -2,6 +2,7 @@
2
2
  # See AUTHORS.txt
3
3
  # SPDX-License-Identifier: MPL-2.0
4
4
  # This file is part of BERTrend.
5
+ from importlib.metadata import version
5
6
 
6
7
  import torch
7
8
 
@@ -43,6 +44,29 @@ AUTHENTIFICATION = True
43
44
  # AUTHENTIFICATION = False
44
45
 
45
46
 
47
+ def display_version_number():
48
+ # Display version at the bottom (using st.markdown and CSS for fixed footer)
49
+ footer = f"""
50
+ <style>
51
+ .footer {{
52
+ position: fixed;
53
+ right: 10px;
54
+ bottom: 10px;
55
+ color: #666;
56
+ font-size: 0.8em;
57
+ opacity: 0.6;
58
+ user-select: none;
59
+ pointer-events: none;
60
+ background: none;
61
+ }}
62
+ </style>
63
+ <div class="footer">
64
+ Version: {version('bertrend')}
65
+ </div>
66
+ """
67
+ st.markdown(footer, unsafe_allow_html=True)
68
+
69
+
46
70
  def main():
47
71
  """Main page"""
48
72
  set_internationalization_language("fr")
@@ -54,6 +78,8 @@ def main():
54
78
  page_icon=":part_alternation_mark:",
55
79
  )
56
80
 
81
+ display_version_number()
82
+
57
83
  st.title(":part_alternation_mark: " + page_title)
58
84
 
59
85
  if AUTHENTIFICATION:
@@ -0,0 +1,19 @@
1
+ # Copyright (c) 2024, 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
+ from bertrend.llm_utils.newsletter_model import Topic, Newsletter
6
+ from bertrend.trend_analysis.data_structure import SignalAnalysis, TopicSummaryList
7
+
8
+
9
+ class TopicOverTime(Topic):
10
+ """Topic model."""
11
+
12
+ topic_evolution: TopicSummaryList | None = None
13
+ topic_analysis: SignalAnalysis | None = None
14
+
15
+
16
+ class DetailedNewsletter(Newsletter):
17
+ """Newsletter model with detailed information about topic evolution over time."""
18
+
19
+ topics: list[TopicOverTime]