customeranalytics 0.1__py3-none-any.whl

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 (254) hide show
  1. customeranalytics/__init__.py +319 -0
  2. customeranalytics/configs.py +480 -0
  3. customeranalytics/data_storage_configurations/__init__.py +245 -0
  4. customeranalytics/data_storage_configurations/data_access.py +165 -0
  5. customeranalytics/data_storage_configurations/data_works_pipeline.py +207 -0
  6. customeranalytics/data_storage_configurations/es_create_index.py +544 -0
  7. customeranalytics/data_storage_configurations/logger.py +36 -0
  8. customeranalytics/data_storage_configurations/query_es.py +157 -0
  9. customeranalytics/data_storage_configurations/reports.py +684 -0
  10. customeranalytics/data_storage_configurations/schedule_data_integration.py +355 -0
  11. customeranalytics/docs/queries.yaml +245 -0
  12. customeranalytics/docs/web_configs.yaml +2 -0
  13. customeranalytics/exploratory_analysis/__init__.py +109 -0
  14. customeranalytics/exploratory_analysis/churn.py +232 -0
  15. customeranalytics/exploratory_analysis/cohorts.py +535 -0
  16. customeranalytics/exploratory_analysis/descriptive_statistics.py +470 -0
  17. customeranalytics/exploratory_analysis/funnels.py +407 -0
  18. customeranalytics/exploratory_analysis/product_analytics.py +340 -0
  19. customeranalytics/exploratory_analysis/promotion_analytics.py +299 -0
  20. customeranalytics/exploratory_analysis/rfm.py +202 -0
  21. customeranalytics/exploratory_analysis/sample_data/sample_data_avg_order_count_per_promo_per_cust.csv +99 -0
  22. customeranalytics/exploratory_analysis/sample_data/sample_data_chart_1_search.csv +2 -0
  23. customeranalytics/exploratory_analysis/sample_data/sample_data_chart_2_search.csv +46 -0
  24. customeranalytics/exploratory_analysis/sample_data/sample_data_chart_3_search.csv +2 -0
  25. customeranalytics/exploratory_analysis/sample_data/sample_data_chart_4_search.csv +2 -0
  26. customeranalytics/exploratory_analysis/sample_data/sample_data_churn.csv +2 -0
  27. customeranalytics/exploratory_analysis/sample_data/sample_data_churn_weekly.csv +10 -0
  28. customeranalytics/exploratory_analysis/sample_data/sample_data_client_feature_predicted.csv +1590 -0
  29. customeranalytics/exploratory_analysis/sample_data/sample_data_client_kpis.csv +7060 -0
  30. customeranalytics/exploratory_analysis/sample_data/sample_data_clvrfm_anomaly.csv +561 -0
  31. customeranalytics/exploratory_analysis/sample_data/sample_data_clvsegments_amount.csv +8 -0
  32. customeranalytics/exploratory_analysis/sample_data/sample_data_customer_journey.csv +18 -0
  33. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_clv.csv +103 -0
  34. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_cohort_downloads.csv +68 -0
  35. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_cohort_from_1_to_2.csv +66 -0
  36. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_cohort_from_2_to_3.csv +64 -0
  37. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_cohort_from_3_to_4.csv +55 -0
  38. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_dimension_values.csv +199 -0
  39. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_funnel.csv +36 -0
  40. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_funnel_downloads.csv +68 -0
  41. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_inorganic_ratio.csv +6070 -0
  42. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_orders.csv +57 -0
  43. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_organic_orders.csv +64 -0
  44. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_products_of_sales.csv +12574 -0
  45. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_promotion_discount.csv +64 -0
  46. customeranalytics/exploratory_analysis/sample_data/sample_data_daily_promotion_revenue.csv +6070 -0
  47. customeranalytics/exploratory_analysis/sample_data/sample_data_dcohort_anomaly.csv +6 -0
  48. customeranalytics/exploratory_analysis/sample_data/sample_data_dcohort_anomaly_2.csv +118 -0
  49. customeranalytics/exploratory_analysis/sample_data/sample_data_deliver.csv +47 -0
  50. customeranalytics/exploratory_analysis/sample_data/sample_data_deliver_kpis.csv +2 -0
  51. customeranalytics/exploratory_analysis/sample_data/sample_data_deliver_weekday_hour.csv +25 -0
  52. customeranalytics/exploratory_analysis/sample_data/sample_data_dfunnel_anomaly.csv +118 -0
  53. customeranalytics/exploratory_analysis/sample_data/sample_data_dimension_kpis.csv +199 -0
  54. customeranalytics/exploratory_analysis/sample_data/sample_data_dorders_anomaly.csv +85 -0
  55. customeranalytics/exploratory_analysis/sample_data/sample_data_frequency_clusters.csv +6 -0
  56. customeranalytics/exploratory_analysis/sample_data/sample_data_frequency_recency.csv +3740 -0
  57. customeranalytics/exploratory_analysis/sample_data/sample_data_hourly_funnel.csv +25 -0
  58. customeranalytics/exploratory_analysis/sample_data/sample_data_hourly_funnel_downloads.csv +25 -0
  59. customeranalytics/exploratory_analysis/sample_data/sample_data_hourly_inorganic_ratio.csv +2353 -0
  60. customeranalytics/exploratory_analysis/sample_data/sample_data_hourly_orders.csv +25 -0
  61. customeranalytics/exploratory_analysis/sample_data/sample_data_hourly_organic_orders.csv +2353 -0
  62. customeranalytics/exploratory_analysis/sample_data/sample_data_inorganic_orders_per_promotion_per_day.csv +6070 -0
  63. customeranalytics/exploratory_analysis/sample_data/sample_data_kpis.csv +2 -0
  64. customeranalytics/exploratory_analysis/sample_data/sample_data_monetary_clusters.csv +6 -0
  65. customeranalytics/exploratory_analysis/sample_data/sample_data_monetary_frequency.csv +3740 -0
  66. customeranalytics/exploratory_analysis/sample_data/sample_data_monthly_funnel.csv +5 -0
  67. customeranalytics/exploratory_analysis/sample_data/sample_data_monthly_funnel_downloads.csv +5 -0
  68. customeranalytics/exploratory_analysis/sample_data/sample_data_monthly_orders.csv +4 -0
  69. customeranalytics/exploratory_analysis/sample_data/sample_data_most_combined_products.csv +11 -0
  70. customeranalytics/exploratory_analysis/sample_data/sample_data_most_ordered_categories.csv +11 -0
  71. customeranalytics/exploratory_analysis/sample_data/sample_data_most_ordered_products.csv +11 -0
  72. customeranalytics/exploratory_analysis/sample_data/sample_data_order_and_payment_amount_differences.csv +91 -0
  73. customeranalytics/exploratory_analysis/sample_data/sample_data_prepare.csv +101 -0
  74. customeranalytics/exploratory_analysis/sample_data/sample_data_prepare_weekday_hour.csv +25 -0
  75. customeranalytics/exploratory_analysis/sample_data/sample_data_product_kpis.csv +201 -0
  76. customeranalytics/exploratory_analysis/sample_data/sample_data_product_usage_before_after_amount_accept.csv +11 -0
  77. customeranalytics/exploratory_analysis/sample_data/sample_data_product_usage_before_after_amount_reject.csv +7 -0
  78. customeranalytics/exploratory_analysis/sample_data/sample_data_product_usage_before_after_orders_accept.csv +11 -0
  79. customeranalytics/exploratory_analysis/sample_data/sample_data_product_usage_before_after_orders_reject.csv +11 -0
  80. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_comparison.csv +91 -0
  81. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_kpis.csv +99 -0
  82. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_number_of_customer.csv +99 -0
  83. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_usage_before_after_amount_accept.csv +81 -0
  84. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_usage_before_after_amount_reject.csv +11 -0
  85. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_usage_before_after_orders_accept.csv +55 -0
  86. customeranalytics/exploratory_analysis/sample_data/sample_data_promotion_usage_before_after_orders_reject.csv +37 -0
  87. customeranalytics/exploratory_analysis/sample_data/sample_data_purchase_amount_distribution.csv +22 -0
  88. customeranalytics/exploratory_analysis/sample_data/sample_data_recency_clusters.csv +6 -0
  89. customeranalytics/exploratory_analysis/sample_data/sample_data_recency_monetary.csv +3740 -0
  90. customeranalytics/exploratory_analysis/sample_data/sample_data_rfm.csv +2001 -0
  91. customeranalytics/exploratory_analysis/sample_data/sample_data_ride.csv +101 -0
  92. customeranalytics/exploratory_analysis/sample_data/sample_data_ride_weekday_hour.csv +25 -0
  93. customeranalytics/exploratory_analysis/sample_data/sample_data_segmentation.csv +11 -0
  94. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_daily_before_after_amount.csv +10 -0
  95. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_daily_before_after_orders.csv +9 -0
  96. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_monthly_before_after_amount.csv +10 -0
  97. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_monthly_before_after_orders.csv +11 -0
  98. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_weekly_before_after_amount.csv +10 -0
  99. customeranalytics/exploratory_analysis/sample_data/sample_data_segments_change_weekly_before_after_orders.csv +10 -0
  100. customeranalytics/exploratory_analysis/sample_data/sample_data_user_counts_per_order_seq.csv +47 -0
  101. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_average_order_per_user.csv +13 -0
  102. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_average_payment_amount.csv +13 -0
  103. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_average_session_per_user.csv +13 -0
  104. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_cohort_downloads.csv +13 -0
  105. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_cohort_from_1_to_2.csv +13 -0
  106. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_cohort_from_2_to_3.csv +13 -0
  107. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_cohort_from_3_to_4.csv +12 -0
  108. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_funnel.csv +25 -0
  109. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_funnel_downloads.csv +25 -0
  110. customeranalytics/exploratory_analysis/sample_data/sample_data_weekly_orders.csv +10 -0
  111. customeranalytics/ml_process/__init__.py +64 -0
  112. customeranalytics/ml_process/ab_test.py +615 -0
  113. customeranalytics/ml_process/anomaly_detection.py +456 -0
  114. customeranalytics/ml_process/clv_prediction.py +301 -0
  115. customeranalytics/ml_process/customer_segmentation.py +354 -0
  116. customeranalytics/ml_process/delivery_analytics.py +754 -0
  117. customeranalytics/utils.py +186 -0
  118. customeranalytics/web/app/__init__.py +37 -0
  119. customeranalytics/web/app/base/__init__.py +9 -0
  120. customeranalytics/web/app/base/forms.py +16 -0
  121. customeranalytics/web/app/base/models.py +43 -0
  122. customeranalytics/web/app/base/routes.py +126 -0
  123. customeranalytics/web/app/base/static/assets/css/app.css +20 -0
  124. customeranalytics/web/app/base/static/assets/fonts/Inter-Black.woff +0 -0
  125. customeranalytics/web/app/base/static/assets/fonts/Inter-Black.woff2 +0 -0
  126. customeranalytics/web/app/base/static/assets/fonts/Inter-BlackItalic.woff +0 -0
  127. customeranalytics/web/app/base/static/assets/fonts/Inter-BlackItalic.woff2 +0 -0
  128. customeranalytics/web/app/base/static/assets/fonts/Inter-Bold.woff +0 -0
  129. customeranalytics/web/app/base/static/assets/fonts/Inter-Bold.woff2 +0 -0
  130. customeranalytics/web/app/base/static/assets/fonts/Inter-BoldItalic.woff +0 -0
  131. customeranalytics/web/app/base/static/assets/fonts/Inter-BoldItalic.woff2 +0 -0
  132. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraBold.woff +0 -0
  133. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraBold.woff2 +0 -0
  134. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraBoldItalic.woff +0 -0
  135. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraBoldItalic.woff2 +0 -0
  136. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraLight-BETA.woff +0 -0
  137. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraLight-BETA.woff2 +0 -0
  138. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraLightItalic-BETA.woff +0 -0
  139. customeranalytics/web/app/base/static/assets/fonts/Inter-ExtraLightItalic-BETA.woff2 +0 -0
  140. customeranalytics/web/app/base/static/assets/fonts/Inter-Italic.woff +0 -0
  141. customeranalytics/web/app/base/static/assets/fonts/Inter-Italic.woff2 +0 -0
  142. customeranalytics/web/app/base/static/assets/fonts/Inter-Light-BETA.woff +0 -0
  143. customeranalytics/web/app/base/static/assets/fonts/Inter-Light-BETA.woff2 +0 -0
  144. customeranalytics/web/app/base/static/assets/fonts/Inter-LightItalic-BETA.woff +0 -0
  145. customeranalytics/web/app/base/static/assets/fonts/Inter-LightItalic-BETA.woff2 +0 -0
  146. customeranalytics/web/app/base/static/assets/fonts/Inter-Medium.woff +0 -0
  147. customeranalytics/web/app/base/static/assets/fonts/Inter-Medium.woff2 +0 -0
  148. customeranalytics/web/app/base/static/assets/fonts/Inter-MediumItalic.woff +0 -0
  149. customeranalytics/web/app/base/static/assets/fonts/Inter-MediumItalic.woff2 +0 -0
  150. customeranalytics/web/app/base/static/assets/fonts/Inter-Regular.woff +0 -0
  151. customeranalytics/web/app/base/static/assets/fonts/Inter-Regular.woff2 +0 -0
  152. customeranalytics/web/app/base/static/assets/fonts/Inter-SemiBold.woff +0 -0
  153. customeranalytics/web/app/base/static/assets/fonts/Inter-SemiBold.woff2 +0 -0
  154. customeranalytics/web/app/base/static/assets/fonts/Inter-SemiBoldItalic.woff +0 -0
  155. customeranalytics/web/app/base/static/assets/fonts/Inter-SemiBoldItalic.woff2 +0 -0
  156. customeranalytics/web/app/base/static/assets/fonts/Inter-Thin-BETA.woff +0 -0
  157. customeranalytics/web/app/base/static/assets/fonts/Inter-Thin-BETA.woff2 +0 -0
  158. customeranalytics/web/app/base/static/assets/fonts/Inter-ThinItalic-BETA.woff +0 -0
  159. customeranalytics/web/app/base/static/assets/fonts/Inter-ThinItalic-BETA.woff2 +0 -0
  160. customeranalytics/web/app/base/static/assets/fonts/Inter-italic.var.woff2 +0 -0
  161. customeranalytics/web/app/base/static/assets/fonts/Inter-upright.var.woff2 +0 -0
  162. customeranalytics/web/app/base/static/assets/fonts/Inter.var.woff2 +0 -0
  163. customeranalytics/web/app/base/static/assets/fonts/fa-brands-400.eot +0 -0
  164. customeranalytics/web/app/base/static/assets/fonts/fa-brands-400.svg +3570 -0
  165. customeranalytics/web/app/base/static/assets/fonts/fa-brands-400.ttf +0 -0
  166. customeranalytics/web/app/base/static/assets/fonts/fa-brands-400.woff +0 -0
  167. customeranalytics/web/app/base/static/assets/fonts/fa-brands-400.woff2 +0 -0
  168. customeranalytics/web/app/base/static/assets/fonts/fa-regular-400.eot +0 -0
  169. customeranalytics/web/app/base/static/assets/fonts/fa-regular-400.svg +801 -0
  170. customeranalytics/web/app/base/static/assets/fonts/fa-regular-400.ttf +0 -0
  171. customeranalytics/web/app/base/static/assets/fonts/fa-regular-400.woff +0 -0
  172. customeranalytics/web/app/base/static/assets/fonts/fa-regular-400.woff2 +0 -0
  173. customeranalytics/web/app/base/static/assets/fonts/fa-solid-900.eot +0 -0
  174. customeranalytics/web/app/base/static/assets/fonts/fa-solid-900.svg +5028 -0
  175. customeranalytics/web/app/base/static/assets/fonts/fa-solid-900.ttf +0 -0
  176. customeranalytics/web/app/base/static/assets/fonts/fa-solid-900.woff +0 -0
  177. customeranalytics/web/app/base/static/assets/fonts/fa-solid-900.woff2 +0 -0
  178. customeranalytics/web/app/base/static/assets/img/avatars/avatar-1.png +0 -0
  179. customeranalytics/web/app/base/static/assets/img/avatars/avatar-2.png +0 -0
  180. customeranalytics/web/app/base/static/assets/img/avatars/avatar-3.png +0 -0
  181. customeranalytics/web/app/base/static/assets/img/avatars/avatar-4.png +0 -0
  182. customeranalytics/web/app/base/static/assets/img/avatars/avatar-5.png +0 -0
  183. customeranalytics/web/app/base/static/assets/img/avatars/info.jpeg +0 -0
  184. customeranalytics/web/app/base/static/assets/img/icons/customanality.png +0 -0
  185. customeranalytics/web/app/base/static/assets/img/icons/icon-48x48.png +0 -0
  186. customeranalytics/web/app/base/static/assets/js/app.js +2 -0
  187. customeranalytics/web/app/base/static/assets/js/app.js.LICENSE +566 -0
  188. customeranalytics/web/app/base/static/assets/js/app.js.LICENSE.txt +556 -0
  189. customeranalytics/web/app/base/static/assets/js/modules/bootstrap.js +15 -0
  190. customeranalytics/web/app/base/static/assets/js/modules/chartjs.js +4 -0
  191. customeranalytics/web/app/base/static/assets/js/modules/feather.js +8 -0
  192. customeranalytics/web/app/base/static/assets/js/modules/flatpickr.js +4 -0
  193. customeranalytics/web/app/base/static/assets/js/modules/moment.js +4 -0
  194. customeranalytics/web/app/base/static/assets/js/modules/sidebar.js +23 -0
  195. customeranalytics/web/app/base/static/assets/js/modules/theme.js +16 -0
  196. customeranalytics/web/app/base/templates/accounts/login.html +81 -0
  197. customeranalytics/web/app/base/templates/accounts/register.html +80 -0
  198. customeranalytics/web/app/base/templates/includes/footer.html +28 -0
  199. customeranalytics/web/app/base/templates/includes/navigation.html +51 -0
  200. customeranalytics/web/app/base/templates/includes/scripts.html +3 -0
  201. customeranalytics/web/app/base/templates/includes/sidebar.html +146 -0
  202. customeranalytics/web/app/base/templates/layouts/base-fullscreen.html +36 -0
  203. customeranalytics/web/app/base/templates/layouts/base.html +84 -0
  204. customeranalytics/web/app/base/util.py +30 -0
  205. customeranalytics/web/app/home/__init__.py +9 -0
  206. customeranalytics/web/app/home/forms.py +1039 -0
  207. customeranalytics/web/app/home/models.py +438 -0
  208. customeranalytics/web/app/home/profiles.py +310 -0
  209. customeranalytics/web/app/home/routes.py +386 -0
  210. customeranalytics/web/app/home/search.py +288 -0
  211. customeranalytics/web/app/home/static/assets/img/avatars/avatar-1.png +0 -0
  212. customeranalytics/web/app/home/static/assets/img/avatars/avatar-2.png +0 -0
  213. customeranalytics/web/app/home/static/assets/img/avatars/avatar-3.png +0 -0
  214. customeranalytics/web/app/home/static/assets/img/avatars/avatar-4.png +0 -0
  215. customeranalytics/web/app/home/static/assets/img/avatars/avatar-5.png +0 -0
  216. customeranalytics/web/app/home/static/assets/img/icons/customanality.png +0 -0
  217. customeranalytics/web/app/home/static/assets/img/icons/icon-48x48.png +0 -0
  218. customeranalytics/web/app/home/templates/abtest-product.html +280 -0
  219. customeranalytics/web/app/home/templates/abtest-promotion.html +362 -0
  220. customeranalytics/web/app/home/templates/abtest-segments.html +298 -0
  221. customeranalytics/web/app/home/templates/add-data-delivery.html +184 -0
  222. customeranalytics/web/app/home/templates/add-data-product.html +177 -0
  223. customeranalytics/web/app/home/templates/add-data-purchase.html +392 -0
  224. customeranalytics/web/app/home/templates/anomaly.html +261 -0
  225. customeranalytics/web/app/home/templates/clv.html +211 -0
  226. customeranalytics/web/app/home/templates/cohorts.html +308 -0
  227. customeranalytics/web/app/home/templates/customer-segmentation.html +308 -0
  228. customeranalytics/web/app/home/templates/data-es.html +152 -0
  229. customeranalytics/web/app/home/templates/data-execute.html +397 -0
  230. customeranalytics/web/app/home/templates/delivery.html +404 -0
  231. customeranalytics/web/app/home/templates/funnel-customer.html +240 -0
  232. customeranalytics/web/app/home/templates/funnel-session.html +236 -0
  233. customeranalytics/web/app/home/templates/index.html +524 -0
  234. customeranalytics/web/app/home/templates/index2.html +515 -0
  235. customeranalytics/web/app/home/templates/page-403.html +46 -0
  236. customeranalytics/web/app/home/templates/page-404.html +45 -0
  237. customeranalytics/web/app/home/templates/page-500.html +45 -0
  238. customeranalytics/web/app/home/templates/pages-blank.html +33 -0
  239. customeranalytics/web/app/home/templates/pages-sign-in.html +67 -0
  240. customeranalytics/web/app/home/templates/pages-sign-up.html +61 -0
  241. customeranalytics/web/app/home/templates/product.html +203 -0
  242. customeranalytics/web/app/home/templates/profile.html +1009 -0
  243. customeranalytics/web/app/home/templates/rfm.html +254 -0
  244. customeranalytics/web/app/home/templates/search.html +167 -0
  245. customeranalytics/web/app/home/templates/settings.html +205 -0
  246. customeranalytics/web/app/home/templates/stats-desc.html +230 -0
  247. customeranalytics/web/app/home/templates/stats-purchase.html +221 -0
  248. customeranalytics/web/config.py +30 -0
  249. customeranalytics/web/db.sqlite3 +0 -0
  250. customeranalytics/web/run.py +30 -0
  251. customeranalytics-0.1.dist-info/METADATA +1102 -0
  252. customeranalytics-0.1.dist-info/RECORD +254 -0
  253. customeranalytics-0.1.dist-info/WHEEL +4 -0
  254. customeranalytics-0.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,438 @@
1
+ import sys, os, inspect, logging
2
+ currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
3
+ parentdir = os.path.dirname(currentdir)
4
+ sys.path.insert(0, parentdir)
5
+
6
+ from sqlalchemy import create_engine, MetaData
7
+ from os.path import abspath, join
8
+
9
+ try: from utils import read_yaml, current_date_to_day, abspath_for_sample_data, sqlite_string_converter
10
+ except: from customeranalytics.utils import read_yaml, current_date_to_day, abspath_for_sample_data, sqlite_string_converter
11
+
12
+ try: from configs import query_path, default_es_port, default_es_host, default_message, schedule_columns
13
+ except: from customeranalytics.configs import query_path, default_es_port, default_es_host, default_message, schedule_columns
14
+
15
+
16
+ import pandas as pd
17
+ from datetime import datetime
18
+ from flask_login import current_user
19
+
20
+ try: from data_storage_configurations import connection_check, create_index, check_elasticsearch
21
+ except: from customeranalytics.data_storage_configurations import connection_check, create_index, check_elasticsearch
22
+
23
+ try: from exploratory_analysis import ea_configs
24
+ except: from customeranalytics.exploratory_analysis import ea_configs
25
+
26
+ try: from ml_process import ml_configs
27
+ except: from customeranalytics.ml_process import ml_configs
28
+
29
+
30
+ engine = create_engine('sqlite://///' + join(abspath_for_sample_data(), "web", 'db.sqlite3'),
31
+ connect_args={'check_same_thread': False})
32
+ metadata = MetaData()
33
+ con = engine.connect()
34
+
35
+
36
+ class RouterRequest:
37
+ def __init__(self):
38
+ self.return_values = {}
39
+ self.sqlite_queries = read_yaml(query_path, "queries.yaml")
40
+ self.tables = pd.read_sql(self.sqlite_queries['tables'], con)
41
+ self.table = None
42
+ self.active_connections = False
43
+ self.hold_connection = False
44
+ self.recent_connection = False
45
+ self.message = default_message
46
+ self.success_data_execute = """ Data Storage Process is initialized!
47
+ This process mainly involves fetching data
48
+ from the data sources and storing them into the ElasticSearch indexes.
49
+ This will take a while. Data Storage Process is triggered for
50
+ """
51
+ self.info_logs_for_chat = lambda info: {'user': 'info',
52
+ 'date': str(current_date_to_day())[0:19],
53
+ 'user_logo': 'info.jpeg',
54
+ 'chat_type': 'info', 'chart': '',
55
+ 'general_message': info, 'message': ''}
56
+
57
+ def insert_query(self, table, columns, values):
58
+ values = [values[col] for col in columns]
59
+ _query = "INSERT INTO " + table + " "
60
+ _query += " (" + ", ".join(columns) + ") "
61
+ _query += " VALUES (" + ", ".join([" '{}' ".format(v) for v in values]) + ") "
62
+ _query = _query.replace("\\", "")
63
+ return _query
64
+
65
+ def update_query(self, table, condition, columns, values):
66
+ values = [(col, values[col]) for col in columns if values.get(col, None) is not None]
67
+ _query = "UPDATE " + table
68
+ _query += " SET " + ", ".join([i[0] + " = '" + i[1] + "'" for i in values])
69
+ _query +=" WHERE " + condition
70
+ _query = _query.replace("\\", "")
71
+ return _query
72
+
73
+ def delete_query(self, table, condition):
74
+ _query = "DELETE FROM " + table
75
+ _query += " WHERE " + condition
76
+ _query = _query.replace("\\", "")
77
+ return _query
78
+
79
+ def check_for_table_exits(self, table):
80
+ """
81
+ checking sqlite if table is created before. If it not, table is created.
82
+ :params table: checking table name in sqlite
83
+ """
84
+ if table not in list(self.tables['name']):
85
+ con.execute(self.sqlite_queries[table])
86
+
87
+ def logs_update(self, logs):
88
+ """
89
+ logs table in sqlite table is updated.
90
+ chats table in sqlite table is updated.
91
+ """
92
+ try: self.check_for_table_exits(table='logs')
93
+ except Exception as e: logging.error(e)
94
+
95
+ try: self.check_for_table_exits(table='chat')
96
+ except Exception as e: print(e)
97
+
98
+ try:
99
+ logs['login_user'] = current_user
100
+ logs['log_time'] = str(current_date_to_day())[0:19]
101
+ con.execute(self.insert_query(table='logs', columns=self.sqlite_queries['columns']['logs'][1:], values=logs))
102
+ except Exception as e: logging.error(e)
103
+
104
+ try: con.execute(self.insert_query(table='chat', columns=self.sqlite_queries['columns']['chat'][1:],
105
+ values=self.info_logs_for_chat(logs['info'])))
106
+ except Exception as e: print(e)
107
+
108
+ def assign_color_for_es_tag(self, data):
109
+ _unique_es_tags = list(data['tag'].unique())
110
+ data = pd.merge(data, pd.DataFrame(zip(_unique_es_tags, self.colors[0:len(_unique_es_tags)])).rename(
111
+ columns={0: "tag", 1: "color"}), on='tag', how='left')
112
+ return data
113
+
114
+ def collect_data_from_table(self, table, query_str=None):
115
+ data = pd.DataFrame()
116
+ try:
117
+ data = pd.read_sql("SELECT * FROM " + table, con)
118
+ if query_str is not None:
119
+ data = data.query(query_str)
120
+ except Exception as e: logging.error(e)
121
+ return data
122
+
123
+ def get_intersect_columns_with_request(self, requests, table):
124
+ return list(set(list(requests.keys())) & set(self.sqlite_queries['columns'][table][1:]))
125
+
126
+ def check_for_data_source_connection(self, requests, columns):
127
+ try:
128
+ return connection_check(request={col: requests[col] for col in columns},
129
+ index=requests['data_type'],
130
+ type=requests['data_type'])
131
+ except Exception as e: logging.error(e)
132
+
133
+ def check_for_both_sessions_and_customers_data_source(self, data_connection):
134
+ if data_connection['orders_data_source_tag'] not in ['None', None] and \
135
+ data_connection['downloads_data_source_tag'] not in ['None', None]:
136
+ return True
137
+ else: return False
138
+
139
+ def check_for_product_data_source(self, data_connection):
140
+ if data_connection['products_data_source_tag'] not in ['None', None]:
141
+ return True
142
+ else: return False
143
+
144
+ def check_for_insert_columns(self, columns, requests, table):
145
+ try:
146
+ for col in self.sqlite_queries['columns'][table][1:]:
147
+ if col not in columns:
148
+ requests[col] = None
149
+ except Exception as e: logging.error(e)
150
+ return requests
151
+
152
+ def check_for_session_and_customer_product_connect(self):
153
+ data_connection = self.collect_data_from_table(table='data_connection')
154
+ sessions, customers, products, deliveries = False, False, False, False
155
+ if len(data_connection) != 0:
156
+ data_connection = data_connection.to_dict('records')[-1]
157
+ sessions = True if data_connection['orders_data_source_tag'] != 'None' else False
158
+ customers = True if data_connection['downloads_data_source_tag'] != 'None' else False
159
+ products = True if data_connection['products_data_source_tag'] != 'None' else False
160
+ deliveries = True if data_connection['deliveries_data_source_tag'] != 'None' else False
161
+ return {'sessions': str(sessions), 'customers': str(customers),
162
+ 'products': str(products), 'deliveries': str(deliveries)}
163
+
164
+ def values_for_manage_data(self, template):
165
+ es_connection = self.collect_data_from_table(table='es_connection')
166
+ if len(es_connection) != 0:
167
+ if template in ['add-data-purchase_2', 'add-data-product_2']:
168
+ self.message['es_connection'] = es_connection.to_dict('records')[-1]
169
+ else:
170
+ self.message['es_connection'] = es_connection.to_dict('records')
171
+ # self.message['s_c_p_connection_check'] = "_".join(
172
+ # [str(i) for i in self.check_for_session_and_customer_product_connect()])
173
+ self.message['s_c_p_connection_check'] = self.check_for_session_and_customer_product_connect()
174
+
175
+ def values_for_schedule_data(self):
176
+ try:
177
+ data_connection = self.collect_data_from_table(table='data_connection')
178
+ except Exception as e:
179
+ logging.error(e)
180
+ prev_schedule = self.collect_data_from_table(table='schedule_data')
181
+ if len(prev_schedule) != 0:
182
+ self.message['schedule_check'] = True
183
+ actions = self.collect_data_from_table(table='actions')
184
+ if len(actions) != 0:
185
+ actions = actions.groupby("data_type").agg(
186
+ {"action_name": lambda x: ", ".join(list(x))}).reset_index().fillna('....')
187
+ try:
188
+ es_connection = self.collect_data_from_table(table='es_connection')
189
+ if len(es_connection) != 0:
190
+ self.message['es_connection'] = es_connection.to_dict('records')[-1]
191
+ else:
192
+ self.message['es_connection'] = '....'
193
+ except Exception as e: logging.error(e)
194
+
195
+ try:
196
+ logs = self.collect_data_from_table(table='logs')
197
+ if len(logs) != 0:
198
+ logs['color'] = logs['color'].apply(lambda x: 'color:' + x + ';')
199
+ self.message['logs'] = logs.to_dict('records')[-min(len(logs), 20):]
200
+ else:
201
+ self.message['logs'] = '....'
202
+ except Exception as e: logging.error(e)
203
+
204
+ if len(data_connection) != 0:
205
+ if self.check_for_both_sessions_and_customers_data_source(data_connection.to_dict('records')[-1]):
206
+ self.message['connect_accept'] = True
207
+ for dt in ['orders', 'downloads', 'products', 'deliveries']:
208
+ data_connection[dt + '_data_query_path'] = sqlite_string_converter(
209
+ list(data_connection[dt + '_data_query_path'])[0], back_to_normal=True)
210
+ data_connection = pd.concat([data_connection, prev_schedule], axis=1)
211
+ data_connection = pd.concat([data_connection,
212
+ actions.query("data_type == 'orders'").drop('data_type', axis=1).rename(
213
+ columns={"action_name": "ses_actions"}).reset_index()], axis=1).fillna('....')
214
+ data_connection = pd.concat([data_connection,
215
+ actions.query("data_type == 'downloads'").drop('data_type', axis=1).rename(
216
+ columns={"action_name": "d_actions"}).reset_index()], axis=1).fillna('....')
217
+
218
+ schedule = data_connection.to_dict('records')[-1]
219
+ self.message['schedule'] = {i: '....' for i in list(schedule.keys()) + ['ses_actions', 'd_actions'] +
220
+ self.sqlite_queries['columns']['schedule_data'][1:]}
221
+ for i in schedule:
222
+ if schedule[i] not in [None, 'None']:
223
+ self.message['schedule'][i] = schedule[i]
224
+ self.message['schedule'] = [self.message['schedule']]
225
+ if self.check_for_product_data_source(data_connection.to_dict('records')[-1]):
226
+ self.message['has_product_data_source'] = True
227
+
228
+ def update_data_query_path_for_insert(self, requests):
229
+ _data_type = requests['data_type']
230
+ requests[_data_type + '_data_query_path'] = sqlite_string_converter(requests[_data_type + '_data_query_path'])
231
+ return requests
232
+
233
+ def update_data_connection_table(self, requests, columns):
234
+ data_connections = self.collect_data_from_table(table='data_connection')
235
+ requests = self.update_data_query_path_for_insert(requests)
236
+ if len(data_connections) == 0:
237
+ for col in self.sqlite_queries['columns']['data_connection'][1:]:
238
+ if col not in list(requests.keys()):
239
+ requests[col] = None
240
+ try:
241
+ con.execute(self.insert_query(table='data_connection',
242
+ columns=self.sqlite_queries['columns']['data_connection'][1:],
243
+ values=requests))
244
+ except Exception as e: logging.error(e)
245
+ else:
246
+ data_connections = data_connections.to_dict('records')[-1]
247
+ try:
248
+ con.execute(self.update_query(table='data_connection',
249
+ condition=" id = " + str(data_connections['id']),
250
+ columns=columns, values=requests))
251
+ except Exception as e: logging.error(e)
252
+
253
+ def update_data_columns_match_table(self, requests, columns):
254
+ try:
255
+ self.check_for_table_exits(table='data_columns_integration')
256
+ data_columns_integration = self.collect_data_from_table(table='data_columns_integration', query_str=" id == 1")
257
+ if len(data_columns_integration) == 0:
258
+ requests = self.check_for_insert_columns(columns, requests, 'data_columns_integration')
259
+ try:
260
+ con.execute(self.insert_query(table='data_columns_integration',
261
+ columns=self.sqlite_queries['columns']['data_columns_integration'][1:],
262
+ values=requests))
263
+ except Exception as e: logging.error(e)
264
+ else:
265
+ try:
266
+ con.execute(self.update_query(table='data_columns_integration',
267
+ condition=" id = 1 ",
268
+ columns=columns, values=requests))
269
+ except Exception as e: logging.error(e)
270
+ except Exception as e: logging.error(e)
271
+
272
+ def remove_data_type_action(self, requests):
273
+ prev_actions = self.collect_data_from_table(table='actions')
274
+ if len(prev_actions) != 0:
275
+ prev_actions_data_type = prev_actions[prev_actions['data_type'] == requests['data_type']]
276
+ if len(prev_actions_data_type) != 0:
277
+ for a in prev_actions_data_type.to_dict('records'):
278
+ con.execute(self.delete_query(table='actions',
279
+ condition=" id = " + str(a['id'])))
280
+
281
+ def update_actions_table(self, requests):
282
+ if requests['data_type'] not in ['products', 'deliveries']:
283
+ self.remove_data_type_action(requests)
284
+ self.check_for_table_exits(table='actions')
285
+ if requests.get('actions', None) is not None:
286
+ actions = []
287
+ if requests['actions'] != '':
288
+ for i in [i.replace(" ", "") for i in requests['actions'].split(",")]:
289
+ counter = 0
290
+ for c in i:
291
+ if c == ' ':
292
+ counter += 1
293
+ else:
294
+ break
295
+ _action = i[counter:]
296
+ actions.append(_action)
297
+ con.execute(self.insert_query(table='actions',
298
+ columns=self.sqlite_queries['columns']['actions'][1:],
299
+ values={"action_name": _action, "data_type": requests['data_type']}))
300
+ requests['actions'] = ",".join(actions)
301
+ else:
302
+ self.remove_data_type_action(requests)
303
+
304
+ def update_schedule_table(self, requests):
305
+ try:
306
+ self.check_for_table_exits(table='schedule_data')
307
+ prev_schedule = self.collect_data_from_table(table='schedule_data').to_dict('records')
308
+ if len(prev_schedule) != 0:
309
+ self.logs_update(logs={"page": "data-execute", "info": "Previous job " + " is removed.", "color": "red"})
310
+ con.execute(self.delete_query(table='schedule_data', condition=" id = 1"))
311
+ columns = self.get_intersect_columns_with_request(requests, 'schedule_data')
312
+ requests = self.check_for_insert_columns(columns, requests, 'schedule_data')
313
+ requests['max_date_of_order_data'] = str(current_date_to_day())[0:19]
314
+ con.execute(self.insert_query(table='schedule_data',
315
+ columns=self.sqlite_queries['columns']['schedule_data'][1:],
316
+ values=requests))
317
+ self.logs_update(logs={"page": "data-execute",
318
+ "info": self.success_data_execute + " ".join(requests['time_period'].split("_")),
319
+ "color": "green"})
320
+ except Exception as e:
321
+ logging.error(e)
322
+ return requests['tag']
323
+
324
+ def update_data_query_path_on_schedule(self, request):
325
+ keys = list(request.keys())
326
+ data_source_query_path = [i for i in ['orders', 'downloads', 'products', 'deliveries'] if i + '_data_query_path' in keys]
327
+ con.execute(self.update_query(table='data_columns_integration',
328
+ condition=" id = 1 ",
329
+ columns=data_source_query_path,
330
+ values={data_source_query_path: request[data_source_query_path[0]]}))
331
+
332
+ def update_message_and_tables(self):
333
+ self.tables = pd.read_sql(self.sqlite_queries['tables'], con)
334
+ self.message = default_message
335
+
336
+ def manage_data_integration(self, requests):
337
+ if requests.get('connect', None) is not None:
338
+ self.check_for_table_exits(table='es_connection')
339
+ requests['port'] = str(default_es_port) if requests['port'] is None else requests['port']
340
+ requests['host'] = str(default_es_host) if requests['host'] is None else requests['host']
341
+ status, self.message['es_connection_check'] = check_elasticsearch(port=requests['port'],
342
+ host=requests['host'],
343
+ directory=requests['directory'])
344
+ if status:
345
+ try:
346
+ con.execute(self.insert_query(table='es_connection',
347
+ columns=self.sqlite_queries['columns']['es_connection'][1:],
348
+ values=requests))
349
+ except Exception as e:
350
+ logging.error(e)
351
+
352
+ if requests.get('delete', None) is not None:
353
+ try:
354
+ con.execute("DROP table es_connection")
355
+ except Exception as e:
356
+ logging.error(e)
357
+
358
+ def data_connections(self, requests):
359
+ # for orders index choose ElasticSearch Connection from es_connection table (only status == 'on')
360
+ if requests.get('connect', None) is not None:
361
+ self.check_for_table_exits(table='data_connection')
362
+ self.check_for_table_exits(table='data_columns_integration')
363
+ _columns = self.get_intersect_columns_with_request(requests, 'data_connection')
364
+ _columns_2 = self.get_intersect_columns_with_request(requests, 'data_columns_integration')
365
+ conn_status, self.message['data_source_con_check'], data, data_columns = self.check_for_data_source_connection(requests, _columns)
366
+
367
+ # connection update
368
+ if conn_status:
369
+ self.update_actions_table(requests)
370
+ self.update_data_connection_table(requests, _columns)
371
+ self.update_data_columns_match_table(requests, _columns_2)
372
+
373
+ def data_execute(self, requests):
374
+ if requests.get('schedule', None) is not None:
375
+ es_tag = self.update_schedule_table(requests)
376
+ create_index(tag=es_tag, ea_configs=ea_configs, ml_configs=ml_configs)
377
+ if requests.get('edit', None) is not None:
378
+ self.update_data_query_path_on_schedule(requests)
379
+ if requests.get('delete', None) is not None:
380
+ try:
381
+ con.execute("DELETE FROM schedule_data")
382
+ except Exception as e:
383
+ logging.error(e)
384
+
385
+ def check_for_request(self, _r):
386
+ _r_updated = {}
387
+ try:
388
+ for i in _r:
389
+ _r_updated[i] = _r[i]
390
+ if _r_updated[i] == 'True':
391
+ _r_updated[i] = True
392
+ if _r_updated[i] == 'None':
393
+ _r_updated[i] = None
394
+ if i == 'connect':
395
+ if _r_updated[i] not in [True, 'True']:
396
+ _r_updated['data_type'] = _r[i]
397
+ _r_updated['connect'] = True
398
+
399
+ if i == 'schedule':
400
+ _r_updated['es_tag'] = _r[i]
401
+ _r_updated['schedule'] = True
402
+
403
+ except Exception as e:
404
+ logging.error(e)
405
+ return _r_updated
406
+
407
+ def execute_request(self, req, template):
408
+ if req != {}:
409
+ if template == 'data-es':
410
+ self.manage_data_integration(self.check_for_request(req))
411
+ if template in ['add-data-purchase', 'add-data-product', 'add-data-delivery']:
412
+ self.data_connections(self.check_for_request(req))
413
+ if template == 'data-execute':
414
+ self.data_execute(self.check_for_request(req))
415
+
416
+ def fetch_results(self, template, requests):
417
+ if requests == {}:
418
+ self.update_message_and_tables()
419
+ else:
420
+ if 'delete' in list(requests.keys()):
421
+ self.update_message_and_tables()
422
+
423
+ if template in ['add-data-purchase', 'add-data-product', 'add-data-delivery']:
424
+ self.values_for_manage_data(template)
425
+ if template == 'data-es':
426
+ try:
427
+ es_connection = self.collect_data_from_table(table='es_connection')
428
+ if len(es_connection) != 0:
429
+ self.message['es_connection'] = es_connection.to_dict('records')[-1]
430
+ else:
431
+ self.message['es_connection'] = '....'
432
+ except Exception as e:
433
+ logging.error(e)
434
+ if template == 'data-execute':
435
+ self.values_for_schedule_data()
436
+
437
+
438
+