dataops-testgen 2.2.0__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 (270) hide show
  1. dataops_testgen-2.2.0.dist-info/LICENSE +203 -0
  2. dataops_testgen-2.2.0.dist-info/METADATA +287 -0
  3. dataops_testgen-2.2.0.dist-info/NOTICE +5 -0
  4. dataops_testgen-2.2.0.dist-info/RECORD +270 -0
  5. dataops_testgen-2.2.0.dist-info/WHEEL +5 -0
  6. dataops_testgen-2.2.0.dist-info/entry_points.txt +2 -0
  7. dataops_testgen-2.2.0.dist-info/top_level.txt +1 -0
  8. testgen/__init__.py +0 -0
  9. testgen/__main__.py +770 -0
  10. testgen/commands/__init__.py +0 -0
  11. testgen/commands/queries/__init__.py +0 -0
  12. testgen/commands/queries/execute_cat_tests_query.py +95 -0
  13. testgen/commands/queries/execute_tests_query.py +160 -0
  14. testgen/commands/queries/generate_tests_query.py +94 -0
  15. testgen/commands/queries/profiling_query.py +366 -0
  16. testgen/commands/queries/test_parameter_validation_query.py +88 -0
  17. testgen/commands/run_execute_cat_tests.py +162 -0
  18. testgen/commands/run_execute_tests.py +168 -0
  19. testgen/commands/run_generate_tests.py +107 -0
  20. testgen/commands/run_get_entities.py +122 -0
  21. testgen/commands/run_launch_db_config.py +84 -0
  22. testgen/commands/run_observability_exporter.py +330 -0
  23. testgen/commands/run_profiling_bridge.py +495 -0
  24. testgen/commands/run_quick_start.py +168 -0
  25. testgen/commands/run_setup_profiling_tools.py +96 -0
  26. testgen/commands/run_test_definition.py +146 -0
  27. testgen/commands/run_test_parameter_validation.py +135 -0
  28. testgen/commands/run_upgrade_db_config.py +156 -0
  29. testgen/common/__init__.py +8 -0
  30. testgen/common/clean_sql.py +53 -0
  31. testgen/common/credentials.py +25 -0
  32. testgen/common/database/__init__.py +0 -0
  33. testgen/common/database/database_service.py +629 -0
  34. testgen/common/database/flavor/__init__.py +0 -0
  35. testgen/common/database/flavor/flavor_service.py +75 -0
  36. testgen/common/database/flavor/mssql_flavor_service.py +34 -0
  37. testgen/common/database/flavor/postgresql_flavor_service.py +5 -0
  38. testgen/common/database/flavor/redshift_flavor_service.py +22 -0
  39. testgen/common/database/flavor/snowflake_flavor_service.py +69 -0
  40. testgen/common/database/flavor/trino_flavor_service.py +21 -0
  41. testgen/common/date_service.py +68 -0
  42. testgen/common/display_service.py +85 -0
  43. testgen/common/docker_service.py +76 -0
  44. testgen/common/encrypt.py +55 -0
  45. testgen/common/get_pipeline_parms.py +57 -0
  46. testgen/common/logs.py +79 -0
  47. testgen/common/process_service.py +62 -0
  48. testgen/common/read_file.py +69 -0
  49. testgen/settings.py +440 -0
  50. testgen/template/dbsetup/010_create_base_schema.sql +2 -0
  51. testgen/template/dbsetup/020_create_standard_functions_sprocs.sql +179 -0
  52. testgen/template/dbsetup/030_initialize_new_schema_structure.sql +735 -0
  53. testgen/template/dbsetup/040_populate_new_schema_project.sql +59 -0
  54. testgen/template/dbsetup/050_populate_new_schema_metadata.sql +1517 -0
  55. testgen/template/dbsetup/060_create_standard_views.sql +248 -0
  56. testgen/template/dbsetup/070_create_default_users.sql +17 -0
  57. testgen/template/dbsetup/075_grant_role_rights.sql +43 -0
  58. testgen/template/dbsetup/080_set_current_revision.sql +5 -0
  59. testgen/template/dbupgrade/0100_incremental_upgrade.sql +5 -0
  60. testgen/template/dbupgrade/0101_incremental_upgrade.sql +15 -0
  61. testgen/template/dbupgrade/0102_incremental_upgrade.sql +4 -0
  62. testgen/template/dbupgrade/0103_incremental_upgrade.sql +22 -0
  63. testgen/template/dbupgrade/0104_incremental_upgrade.sql +44 -0
  64. testgen/template/dbupgrade/0105_incremental_upgrade.sql +1 -0
  65. testgen/template/dbupgrade/0106_incremental_upgrade.sql +5 -0
  66. testgen/template/dbupgrade/0107_incremental_upgrade.sql +3 -0
  67. testgen/template/dbupgrade_helpers/get_tg_revision.sql +2 -0
  68. testgen/template/exec_cat_tests/ex_cat_build_agg_table_tests.sql +116 -0
  69. testgen/template/exec_cat_tests/ex_cat_get_distinct_tables.sql +11 -0
  70. testgen/template/exec_cat_tests/ex_cat_results_parse.sql +69 -0
  71. testgen/template/exec_cat_tests/ex_cat_retrieve_agg_test_parms.sql +6 -0
  72. testgen/template/exec_cat_tests/ex_cat_test_query.sql +8 -0
  73. testgen/template/execution/ex_finalize_test_run_results.sql +37 -0
  74. testgen/template/execution/ex_get_tests_non_cat.sql +47 -0
  75. testgen/template/execution/ex_update_test_record_in_testrun_table.sql +27 -0
  76. testgen/template/execution/ex_write_test_record_to_testrun_table.sql +6 -0
  77. testgen/template/flavors/generic/exec_query_tests/ex_aggregate_match_no_drops_generic.sql +48 -0
  78. testgen/template/flavors/generic/exec_query_tests/ex_aggregate_match_num_incr_generic.sql +34 -0
  79. testgen/template/flavors/generic/exec_query_tests/ex_aggregate_match_percent_above_generic.sql +49 -0
  80. testgen/template/flavors/generic/exec_query_tests/ex_aggregate_match_percent_within_generic.sql +49 -0
  81. testgen/template/flavors/generic/exec_query_tests/ex_aggregate_match_same_generic.sql +49 -0
  82. testgen/template/flavors/generic/exec_query_tests/ex_custom_query_generic.sql +39 -0
  83. testgen/template/flavors/generic/exec_query_tests/ex_data_match_2way_generic.sql +58 -0
  84. testgen/template/flavors/generic/exec_query_tests/ex_data_match_generic.sql +44 -0
  85. testgen/template/flavors/generic/exec_query_tests/ex_prior_match_generic.sql +37 -0
  86. testgen/template/flavors/generic/exec_query_tests/ex_relative_entropy_generic.sql +53 -0
  87. testgen/template/flavors/generic/exec_query_tests/ex_window_match_no_drops_generic.sql +46 -0
  88. testgen/template/flavors/generic/exec_query_tests/ex_window_match_same_generic.sql +59 -0
  89. testgen/template/flavors/generic/profiling/contingency_counts.sql +3 -0
  90. testgen/template/flavors/generic/validate_tests/ex_get_project_column_list_generic.sql +3 -0
  91. testgen/template/flavors/mssql/exec_query_tests/ex_relative_entropy_mssql.sql +53 -0
  92. testgen/template/flavors/mssql/profiling/project_ddf_query_mssql.sql +35 -0
  93. testgen/template/flavors/mssql/profiling/project_profiling_query_mssql.yaml +246 -0
  94. testgen/template/flavors/mssql/profiling/project_secondary_profiling_query_mssql.sql +36 -0
  95. testgen/template/flavors/mssql/setup_profiling_tools/00_drop_existing_functions_mssql.sql +8 -0
  96. testgen/template/flavors/mssql/setup_profiling_tools/01_create_functions_mssql.sql +12 -0
  97. testgen/template/flavors/mssql/setup_profiling_tools/02_create_functions_mssql.sql +54 -0
  98. testgen/template/flavors/mssql/setup_profiling_tools/create_qc_schema_mssql.sql +4 -0
  99. testgen/template/flavors/mssql/setup_profiling_tools/grant_execute_privileges_mssql.sql +1 -0
  100. testgen/template/flavors/postgresql/exec_query_tests/ex_window_match_no_drops_postgresql.sql +46 -0
  101. testgen/template/flavors/postgresql/exec_query_tests/ex_window_match_same_postgresql.sql +59 -0
  102. testgen/template/flavors/postgresql/profiling/project_ddf_query_postgresql.sql +42 -0
  103. testgen/template/flavors/postgresql/profiling/project_profiling_query_postgresql.yaml +225 -0
  104. testgen/template/flavors/postgresql/profiling/project_secondary_profiling_query_postgresql.sql +28 -0
  105. testgen/template/flavors/postgresql/setup_profiling_tools/create_functions_postgresql.sql +157 -0
  106. testgen/template/flavors/postgresql/setup_profiling_tools/create_qc_schema_postgresql.sql +1 -0
  107. testgen/template/flavors/postgresql/setup_profiling_tools/grant_execute_privileges_postgresql.sql +2 -0
  108. testgen/template/flavors/redshift/profiling/project_ddf_query_redshift.sql +38 -0
  109. testgen/template/flavors/redshift/profiling/project_profiling_query_redshift.yaml +221 -0
  110. testgen/template/flavors/redshift/profiling/project_secondary_profiling_query_redshift.sql +29 -0
  111. testgen/template/flavors/redshift/setup_profiling_tools/create_functions_redshift.sql +115 -0
  112. testgen/template/flavors/redshift/setup_profiling_tools/create_qc_schema_redshift.sql +1 -0
  113. testgen/template/flavors/redshift/setup_profiling_tools/grant_execute_privileges_redshift.sql +2 -0
  114. testgen/template/flavors/snowflake/profiling/project_ddf_query_snowflake.sql +38 -0
  115. testgen/template/flavors/snowflake/profiling/project_profiling_query_snowflake.yaml +220 -0
  116. testgen/template/flavors/snowflake/profiling/project_secondary_profiling_query_snowflake.sql +29 -0
  117. testgen/template/flavors/snowflake/setup_profiling_tools/create_functions_snowflake.sql +69 -0
  118. testgen/template/flavors/snowflake/setup_profiling_tools/create_qc_schema_snowflake.sql +1 -0
  119. testgen/template/flavors/snowflake/setup_profiling_tools/grant_execute_privileges_snowflake.sql +6 -0
  120. testgen/template/flavors/trino/profiling/project_profiling_query_trino.yaml +219 -0
  121. testgen/template/flavors/trino/setup_profiling_tools/create_functions_trino.sql +92 -0
  122. testgen/template/flavors/trino/setup_profiling_tools/create_qc_schema_trino.sql +1 -0
  123. testgen/template/gen_funny_cat_tests/gen_test_constant.sql +104 -0
  124. testgen/template/gen_funny_cat_tests/gen_test_distinct_value_ct.sql +98 -0
  125. testgen/template/gen_funny_cat_tests/gen_test_row_ct.sql +57 -0
  126. testgen/template/gen_funny_cat_tests/gen_test_row_ct_pct.sql +59 -0
  127. testgen/template/generation/gen_delete_old_tests.sql +5 -0
  128. testgen/template/generation/gen_insert_test_suite.sql +5 -0
  129. testgen/template/generation/gen_retrieve_or_insert_test_suite.sql +58 -0
  130. testgen/template/generation/gen_standard_test_type_list.sql +13 -0
  131. testgen/template/generation/gen_standard_tests.sql +48 -0
  132. testgen/template/get_entities/get_connection.sql +21 -0
  133. testgen/template/get_entities/get_connections_list.sql +9 -0
  134. testgen/template/get_entities/get_latest.sql +4 -0
  135. testgen/template/get_entities/get_profile.sql +12 -0
  136. testgen/template/get_entities/get_profile_info.sql +17 -0
  137. testgen/template/get_entities/get_profile_list.sql +17 -0
  138. testgen/template/get_entities/get_profile_screen.sql +275 -0
  139. testgen/template/get_entities/get_project_list.sql +6 -0
  140. testgen/template/get_entities/get_table_group_list.sql +10 -0
  141. testgen/template/get_entities/get_test_generation_list.sql +18 -0
  142. testgen/template/get_entities/get_test_info.sql +41 -0
  143. testgen/template/get_entities/get_test_results_for_run_cli.sql +16 -0
  144. testgen/template/get_entities/get_test_run_list.sql +24 -0
  145. testgen/template/get_entities/get_test_suite.sql +13 -0
  146. testgen/template/get_entities/get_test_suite_list.sql +18 -0
  147. testgen/template/get_entities/list_test_types.sql +4 -0
  148. testgen/template/observability/get_event_data.sql +23 -0
  149. testgen/template/observability/get_test_results.sql +41 -0
  150. testgen/template/observability/update_test_results_exported_to_observability.sql +12 -0
  151. testgen/template/parms/parms_profiling.sql +34 -0
  152. testgen/template/parms/parms_test_execution.sql +13 -0
  153. testgen/template/parms/parms_test_gen.sql +23 -0
  154. testgen/template/profiling/contingency_columns.sql +7 -0
  155. testgen/template/profiling/datatype_suggestions.sql +56 -0
  156. testgen/template/profiling/functional_datatype.sql +523 -0
  157. testgen/template/profiling/functional_tabletype_stage.sql +48 -0
  158. testgen/template/profiling/functional_tabletype_update.sql +8 -0
  159. testgen/template/profiling/pii_flag.sql +133 -0
  160. testgen/template/profiling/profile_anomalies_screen_column.sql +22 -0
  161. testgen/template/profiling/profile_anomalies_screen_multi_column.sql +58 -0
  162. testgen/template/profiling/profile_anomalies_screen_table.sql +22 -0
  163. testgen/template/profiling/profile_anomalies_screen_table_dates.sql +30 -0
  164. testgen/template/profiling/profile_anomalies_screen_variants.sql +40 -0
  165. testgen/template/profiling/profile_anomaly_types_get.sql +3 -0
  166. testgen/template/profiling/project_get_table_sample_count.sql +22 -0
  167. testgen/template/profiling/project_profile_run_record_insert.sql +8 -0
  168. testgen/template/profiling/project_profile_run_record_update.sql +5 -0
  169. testgen/template/profiling/project_profile_run_record_update_status.sql +5 -0
  170. testgen/template/profiling/project_update_profile_results_to_estimates.sql +32 -0
  171. testgen/template/profiling/refresh_anomalies.sql +33 -0
  172. testgen/template/profiling/refresh_data_chars_from_profiling.sql +156 -0
  173. testgen/template/profiling/secondary_profiling_columns.sql +12 -0
  174. testgen/template/profiling/secondary_profiling_delete.sql +4 -0
  175. testgen/template/profiling/secondary_profiling_update.sql +18 -0
  176. testgen/template/quick_start/populate_target_data.sql +1077 -0
  177. testgen/template/quick_start/recreate_target_data_schema.sql +167 -0
  178. testgen/template/quick_start/update_target_data.sql +100 -0
  179. testgen/template/updates/create_tmp_test_definition.sql +19 -0
  180. testgen/template/updates/get_test_def_parms.sql +38 -0
  181. testgen/template/updates/populate_stg_test_definitions.sql +184 -0
  182. testgen/template/validate_tests/ex_disable_tests_test_definitions.sql +5 -0
  183. testgen/template/validate_tests/ex_flag_tests_test_definitions.sql +64 -0
  184. testgen/template/validate_tests/ex_get_project_column_list_generic.sql +3 -0
  185. testgen/template/validate_tests/ex_get_test_column_list_tg.sql +65 -0
  186. testgen/template/validate_tests/ex_write_test_val_errors.sql +22 -0
  187. testgen/ui/__init__.py +0 -0
  188. testgen/ui/app.py +98 -0
  189. testgen/ui/assets/dk_logo.svg +46 -0
  190. testgen/ui/assets/question_mark.png +0 -0
  191. testgen/ui/assets/scripts.js +68 -0
  192. testgen/ui/assets/style.css +140 -0
  193. testgen/ui/bootstrap.py +109 -0
  194. testgen/ui/components/__init__.py +0 -0
  195. testgen/ui/components/frontend/css/KFOlCnqEu92Fr1MmEU9fBBc4.woff2 +0 -0
  196. testgen/ui/components/frontend/css/KFOlCnqEu92Fr1MmEU9fChc4EsA.woff2 +0 -0
  197. testgen/ui/components/frontend/css/KFOmCnqEu92Fr1Mu4mxK.woff2 +0 -0
  198. testgen/ui/components/frontend/css/KFOmCnqEu92Fr1Mu7GxKOzY.woff2 +0 -0
  199. testgen/ui/components/frontend/css/material-symbols-rounded.css +24 -0
  200. testgen/ui/components/frontend/css/material-symbols-rounded.woff2 +0 -0
  201. testgen/ui/components/frontend/css/roboto-font-faces.css +35 -0
  202. testgen/ui/components/frontend/css/shared.css +36 -0
  203. testgen/ui/components/frontend/img/dk_logo.svg +46 -0
  204. testgen/ui/components/frontend/index.html +17 -0
  205. testgen/ui/components/frontend/js/components/breadcrumbs.js +86 -0
  206. testgen/ui/components/frontend/js/components/button.js +66 -0
  207. testgen/ui/components/frontend/js/components/location.js +62 -0
  208. testgen/ui/components/frontend/js/components/select.js +75 -0
  209. testgen/ui/components/frontend/js/components/sidebar.js +358 -0
  210. testgen/ui/components/frontend/js/main.js +99 -0
  211. testgen/ui/components/frontend/js/streamlit.js +19 -0
  212. testgen/ui/components/frontend/js/van.min.js +1 -0
  213. testgen/ui/components/utils/__init__.py +0 -0
  214. testgen/ui/components/utils/callbacks.py +51 -0
  215. testgen/ui/components/utils/component.py +13 -0
  216. testgen/ui/components/widgets/__init__.py +6 -0
  217. testgen/ui/components/widgets/breadcrumbs.py +32 -0
  218. testgen/ui/components/widgets/location.py +65 -0
  219. testgen/ui/components/widgets/modal.py +97 -0
  220. testgen/ui/components/widgets/sidebar.py +69 -0
  221. testgen/ui/navigation/__init__.py +0 -0
  222. testgen/ui/navigation/menu.py +42 -0
  223. testgen/ui/navigation/page.py +20 -0
  224. testgen/ui/navigation/router.py +63 -0
  225. testgen/ui/queries/__init__.py +0 -0
  226. testgen/ui/queries/authentication_queries.py +47 -0
  227. testgen/ui/queries/connection_queries.py +121 -0
  228. testgen/ui/queries/profiling_queries.py +148 -0
  229. testgen/ui/queries/project_queries.py +9 -0
  230. testgen/ui/queries/table_group_queries.py +186 -0
  231. testgen/ui/queries/test_definition_queries.py +270 -0
  232. testgen/ui/queries/test_run_queries.py +32 -0
  233. testgen/ui/queries/test_suite_queries.py +145 -0
  234. testgen/ui/scripts/__init__.py +0 -0
  235. testgen/ui/scripts/patch_streamlit.py +111 -0
  236. testgen/ui/services/__init__.py +0 -0
  237. testgen/ui/services/authentication_service.py +119 -0
  238. testgen/ui/services/connection_service.py +220 -0
  239. testgen/ui/services/database_service.py +282 -0
  240. testgen/ui/services/form_service.py +1008 -0
  241. testgen/ui/services/javascript_service.py +44 -0
  242. testgen/ui/services/query_service.py +316 -0
  243. testgen/ui/services/string_service.py +12 -0
  244. testgen/ui/services/table_group_service.py +130 -0
  245. testgen/ui/services/test_definition_service.py +117 -0
  246. testgen/ui/services/test_run_service.py +13 -0
  247. testgen/ui/services/test_suite_service.py +76 -0
  248. testgen/ui/services/toolbar_service.py +77 -0
  249. testgen/ui/session.py +46 -0
  250. testgen/ui/views/__init__.py +0 -0
  251. testgen/ui/views/app_log_modal.py +92 -0
  252. testgen/ui/views/connections.py +72 -0
  253. testgen/ui/views/connections_base.py +367 -0
  254. testgen/ui/views/login.py +40 -0
  255. testgen/ui/views/not_found.py +16 -0
  256. testgen/ui/views/overview.py +34 -0
  257. testgen/ui/views/profiling_anomalies.py +501 -0
  258. testgen/ui/views/profiling_details.py +335 -0
  259. testgen/ui/views/profiling_modal.py +40 -0
  260. testgen/ui/views/profiling_results.py +206 -0
  261. testgen/ui/views/profiling_summary.py +177 -0
  262. testgen/ui/views/project_settings.py +74 -0
  263. testgen/ui/views/table_groups.py +530 -0
  264. testgen/ui/views/test_definitions.py +1020 -0
  265. testgen/ui/views/test_results.py +908 -0
  266. testgen/ui/views/test_runs.py +195 -0
  267. testgen/ui/views/test_suites.py +545 -0
  268. testgen/utils/__init__.py +0 -0
  269. testgen/utils/plugins.py +17 -0
  270. testgen/utils/singleton.py +14 -0
@@ -0,0 +1,76 @@
1
+ import streamlit as st
2
+
3
+ import testgen.ui.queries.test_suite_queries as test_suite_queries
4
+ import testgen.ui.services.test_definition_service as test_definition_service
5
+
6
+
7
+ def get_by_table_group(project_code, table_group_id):
8
+ schema = st.session_state["dbschema"]
9
+ return test_suite_queries.get_by_table_group(schema, project_code, table_group_id)
10
+
11
+
12
+ def edit(test_suite):
13
+ schema = st.session_state["dbschema"]
14
+ test_suite_queries.edit(schema, test_suite)
15
+
16
+
17
+ def add(test_suite):
18
+ schema = st.session_state["dbschema"]
19
+ test_suite_queries.add(schema, test_suite)
20
+
21
+
22
+ def cascade_delete(test_suite_names, dry_run=False):
23
+ if not test_suite_names:
24
+ return True
25
+ schema = st.session_state["dbschema"]
26
+ can_be_deleted = not has_test_suite_dependencies(schema, test_suite_names)
27
+ if not dry_run:
28
+ test_definition_service.cascade_delete(test_suite_names)
29
+ test_suite_queries.cascade_delete(schema, test_suite_names)
30
+ return can_be_deleted
31
+
32
+
33
+ def has_test_suite_dependencies(schema, test_suite_names):
34
+ if not test_suite_names:
35
+ return False
36
+ return not test_suite_queries.get_test_suite_dependencies(schema, test_suite_names).empty
37
+
38
+
39
+ def are_test_suites_in_use(test_suite_names):
40
+ if not test_suite_names:
41
+ return False
42
+ schema = st.session_state["dbschema"]
43
+ usage_result = test_suite_queries.get_test_suite_usage(schema, test_suite_names)
44
+ return not usage_result.empty
45
+
46
+
47
+ def get_test_suite_refresh_warning(table_groups_id, test_suite_name):
48
+ if not test_suite_name:
49
+ return False
50
+ schema = st.session_state["dbschema"]
51
+ row_result = test_suite_queries.get_test_suite_refresh_check(schema, table_groups_id, test_suite_name)
52
+
53
+ test_ct = None
54
+ unlocked_test_ct = None
55
+ unlocked_edits_ct = None
56
+ if row_result:
57
+ test_ct = row_result["test_ct"]
58
+ unlocked_test_ct = row_result["unlocked_test_ct"]
59
+ unlocked_edits_ct = row_result["unlocked_edits_ct"]
60
+
61
+ return test_ct, unlocked_test_ct, unlocked_edits_ct
62
+
63
+
64
+ def get_generation_set_choices():
65
+ schema = st.session_state["dbschema"]
66
+ dfSets = test_suite_queries.get_generation_sets(schema)
67
+ if dfSets.empty:
68
+ return None
69
+ else:
70
+ return dfSets["generation_set"].to_list()
71
+
72
+
73
+ def lock_edited_tests(test_suite_name):
74
+ schema = st.session_state["dbschema"]
75
+ tests_locked = test_suite_queries.lock_edited_tests(schema, test_suite_name)
76
+ return tests_locked
@@ -0,0 +1,77 @@
1
+ from time import sleep
2
+
3
+ import streamlit as st
4
+
5
+
6
+ class ToolBar:
7
+ slot_count = 5
8
+ toolbar_prompt = None
9
+ action_prompt = None
10
+ help_link = "https://docs.datakitchen.io/article/dataops-testgen-help/dataops-testgen-help"
11
+
12
+ long_slots = None
13
+ short_slots = None
14
+ button_slots = None
15
+ status_bar = None
16
+ action_container = None
17
+
18
+ def __init__(self, long_slot_count=5, short_slot_count=0, button_slot_count=0, prompt=None, multiline=False):
19
+ self.toolbar_prompt = prompt
20
+
21
+ lst_slots_line2 = []
22
+ slots_line2 = None
23
+
24
+ # Initialize Toolbar Slots for widgets at right size ratio
25
+ lst_slots_line1 = [10] * long_slot_count
26
+ if multiline:
27
+ lst_slots_line2 = [7] * short_slot_count
28
+ lst_slots_line2 += [2] * button_slot_count
29
+ else:
30
+ lst_slots_line1 += [7] * short_slot_count
31
+ lst_slots_line1 += [2] * button_slot_count
32
+
33
+ slots_line1 = st.columns(lst_slots_line1)
34
+ if multiline:
35
+ slots_line2 = st.columns(lst_slots_line2)
36
+
37
+ if long_slot_count > 0:
38
+ self.long_slots = slots_line1[:long_slot_count]
39
+ if multiline:
40
+ if short_slot_count > 0:
41
+ self.short_slots = slots_line2[0:short_slot_count]
42
+ if button_slot_count > 0:
43
+ self.button_slots = slots_line2[-1 * button_slot_count :]
44
+ else:
45
+ if short_slot_count > 0:
46
+ self.short_slots = slots_line1[long_slot_count : long_slot_count + short_slot_count]
47
+ if button_slot_count > 0:
48
+ self.button_slots = slots_line1[-1 * button_slot_count :]
49
+
50
+ # Add vertical space to short slots
51
+ for i in range(short_slot_count):
52
+ self.short_slots[i].markdown("</p>&nbsp;</br>", unsafe_allow_html=True)
53
+
54
+ # Add vertical space to button slots
55
+ for i in range(button_slot_count):
56
+ self.button_slots[i].markdown("</p>&nbsp;</br>", unsafe_allow_html=True)
57
+
58
+ self.status_bar = st.empty()
59
+ self.set_prompt()
60
+
61
+ def set_prompt(self, str_new_prompt=None):
62
+ str_prompt = self.toolbar_prompt if str_new_prompt is None else str_new_prompt
63
+ if str_prompt:
64
+ self.toolbar_prompt = str_prompt
65
+ self.status_bar.markdown(f":green[**{str_prompt}**]")
66
+ else:
67
+ self.status_bar.empty()
68
+
69
+ def show_status(self, str_message, str_type):
70
+ if str_type == "success":
71
+ self.status_bar.success(str_message, icon="✅")
72
+ elif str_type == "error":
73
+ self.status_bar.error(str_message, icon="❌")
74
+ elif str_type == "info":
75
+ self.status_bar.info(str_message, icon="💡")
76
+ sleep(2)
77
+ self.set_prompt()
testgen/ui/session.py ADDED
@@ -0,0 +1,46 @@
1
+ import typing
2
+
3
+ from streamlit import session_state
4
+ from streamlit.runtime.state import SessionStateProxy
5
+
6
+ from testgen.utils.singleton import Singleton
7
+
8
+
9
+ class TestgenSession(Singleton):
10
+ renders: int
11
+ current_page: str
12
+ current_page_args: dict
13
+
14
+ dbschema: str
15
+
16
+ name: str
17
+ username: str
18
+ authentication_status: bool
19
+ auth_role: typing.Literal["admin", "edit", "read"]
20
+ logging_out: bool
21
+
22
+ project: str
23
+ add_project: bool
24
+
25
+ sb_latest_rel: str
26
+ sb_schema_rev: str
27
+
28
+ def __init__(self, state: SessionStateProxy) -> None:
29
+ super().__setattr__("_state", state)
30
+
31
+ def __getattr__(self, key: str) -> typing.Any:
32
+ state = object.__getattribute__(self, "_state")
33
+ if key not in state:
34
+ return None
35
+ return state[key]
36
+
37
+ def __setattr__(self, key: str, value: typing.Any) -> None:
38
+ object.__getattribute__(self, "_state")[key] = value
39
+
40
+ def __delattr__(self, key: str) -> None:
41
+ state = object.__getattribute__(self, "_state")
42
+ if key in state:
43
+ del state[key]
44
+
45
+
46
+ session = TestgenSession(session_state)
File without changes
@@ -0,0 +1,92 @@
1
+ import logging
2
+ import os
3
+ import re
4
+ from datetime import date, datetime
5
+
6
+ import streamlit as st
7
+
8
+ import testgen.common.logs as logs
9
+ import testgen.ui.services.form_service as fm
10
+ from testgen.common import display_service
11
+ from testgen.ui.components import widgets as testgen
12
+
13
+ LOG = logging.getLogger("testgen")
14
+
15
+
16
+ # Read the log file
17
+ @st.cache_data
18
+ def _read_log(file_path):
19
+ try:
20
+ with open(file_path) as file:
21
+ log_data = file.readlines()
22
+ return log_data # NOQA TRY300
23
+
24
+ except Exception:
25
+ st.warning(f"Log file is unavailable: {file_path}")
26
+ LOG.debug(f"Log viewer can't read log file {file_path}")
27
+
28
+
29
+ # Function to filter log data by date
30
+ def _filter_by_date(log_data, start_date, end_date):
31
+ filtered_data = []
32
+ for line in log_data:
33
+ # Assuming the log line starts with a date in the format 'YYYY-MM-DD'
34
+ match = re.match(r"^(\d{4}-\d{2}-\d{2})", line)
35
+ if match:
36
+ log_date = datetime.strptime(match.group(1), "%Y-%m-%d")
37
+ if start_date <= log_date <= end_date:
38
+ filtered_data.append(line)
39
+ return filtered_data
40
+
41
+
42
+ # Function to search text in log data
43
+ def _search_text(log_data, search_query):
44
+ return [line for line in log_data if search_query in line]
45
+
46
+
47
+ def view_log_file(button_container):
48
+ log_file_modal = testgen.Modal(title=None, key="dk-view-log-modal", max_width=1100)
49
+
50
+ with button_container:
51
+ if st.button(
52
+ "Troubleshooting →", help="Open and review TestGen Log files", use_container_width=True
53
+ ):
54
+ log_file_modal.open()
55
+
56
+ if log_file_modal.is_open():
57
+ with log_file_modal.container():
58
+ fm.render_modal_header("TestGen App Log", None, "Review/Troubleshoot daily log files")
59
+
60
+ _, file_out_path = display_service.get_in_out_paths()
61
+
62
+ col1, col2, col3 = st.columns([33, 33, 33])
63
+ log_date = col1.date_input("Log Date", value=datetime.today())
64
+
65
+ log_file_location = logs.get_log_full_path()
66
+
67
+ if log_date != date.today():
68
+ log_file_location += log_date.strftime(".%Y-%m-%d")
69
+
70
+ log_file_name = os.path.basename(log_file_location)
71
+
72
+ log_data = _read_log(log_file_location)
73
+
74
+ search_query = col2.text_input("Filter by Text")
75
+ if search_query:
76
+ show_data = _search_text(log_data, search_query)
77
+ else:
78
+ show_data = log_data
79
+
80
+ # Refresh button
81
+ col3.write(" \n ")
82
+ if col3.button("Refresh"):
83
+ # Clear cache to refresh the log data
84
+ st.cache_data.clear()
85
+
86
+ if log_data:
87
+ st.markdown(f"**Log File:** {log_file_name}")
88
+ # TOO SLOW: st.code(body=''.join(show_data), language="log", line_numbers=True)
89
+ st.text_area("Log Data", value="".join(show_data), height=400)
90
+
91
+ # Download button
92
+ st.download_button("Download", data="".join(show_data), file_name=log_file_name)
@@ -0,0 +1,72 @@
1
+ import logging
2
+ import typing
3
+
4
+ import streamlit as st
5
+
6
+ import testgen.ui.services.form_service as fm
7
+ import testgen.ui.services.toolbar_service as tb
8
+ from testgen.ui.components import widgets as testgen
9
+ from testgen.ui.navigation.menu import MenuItem
10
+ from testgen.ui.navigation.page import Page
11
+ from testgen.ui.services import connection_service
12
+ from testgen.ui.session import session
13
+ from testgen.ui.views.connections_base import show_connection, show_create_qc_schema_modal
14
+
15
+ LOG = logging.getLogger("testgen")
16
+
17
+
18
+ class ConnectionsPage(Page):
19
+ path = "connections"
20
+ can_activate: typing.ClassVar = [
21
+ lambda: session.authentication_status or "login",
22
+ ]
23
+ menu_item = MenuItem(icon="database", label="Data Configuration", order=3)
24
+
25
+ def render(self) -> None:
26
+ fm.render_page_header(
27
+ "Connection",
28
+ "https://docs.datakitchen.io/article/dataops-testgen-help/connect-your-database",
29
+ lst_breadcrumbs=[
30
+ {"label": "Overview", "path": "overview"},
31
+ {"label": "Connection", "path": None},
32
+ ],
33
+ )
34
+
35
+ project_code = session.project
36
+ dataframe = connection_service.get_connections(project_code)
37
+ connection = dataframe.iloc[0]
38
+
39
+ tool_bar = tb.ToolBar(long_slot_count=6, short_slot_count=0, button_slot_count=0, prompt=None)
40
+
41
+ enable_table_groups = connection["project_host"] and connection["project_db"] and connection["project_qc_schema"]
42
+
43
+ form_container = st.expander("", expanded=True)
44
+ with form_container:
45
+ connection_modal = None
46
+ mode = "edit"
47
+ show_connection(connection_modal, connection, mode, project_code, show_header=False)
48
+
49
+ if tool_bar.long_slots[-1].button(
50
+ f":{'gray' if not enable_table_groups else 'green'}[Table Groups →]",
51
+ help="Create or edit Table Groups for the Connection",
52
+ use_container_width=True,
53
+ ):
54
+ st.session_state["connection"] = connection.to_dict()
55
+
56
+ session.current_page = "connections/table-groups"
57
+ session.current_page_args = {"connection_id": connection["connection_id"]}
58
+ st.experimental_rerun()
59
+
60
+ create_qc_schema_modal = testgen.Modal(title=None, key="dk-create-qc-schema-modal", max_width=1100)
61
+
62
+ _, col2 = st.columns([70, 30])
63
+
64
+ if col2.button(
65
+ "Configure QC Utility Schema",
66
+ help="Creates the required Utility schema and related functions in the target database",
67
+ use_container_width=True,
68
+ ):
69
+ create_qc_schema_modal.open()
70
+
71
+ if create_qc_schema_modal.is_open():
72
+ show_create_qc_schema_modal(create_qc_schema_modal, connection)