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.
- dataops_testgen-2.2.0.dist-info/LICENSE +203 -0
- dataops_testgen-2.2.0.dist-info/METADATA +287 -0
- dataops_testgen-2.2.0.dist-info/NOTICE +5 -0
- dataops_testgen-2.2.0.dist-info/RECORD +270 -0
- dataops_testgen-2.2.0.dist-info/WHEEL +5 -0
- dataops_testgen-2.2.0.dist-info/entry_points.txt +2 -0
- dataops_testgen-2.2.0.dist-info/top_level.txt +1 -0
- testgen/__init__.py +0 -0
- testgen/__main__.py +770 -0
- testgen/commands/__init__.py +0 -0
- testgen/commands/queries/__init__.py +0 -0
- testgen/commands/queries/execute_cat_tests_query.py +95 -0
- testgen/commands/queries/execute_tests_query.py +160 -0
- testgen/commands/queries/generate_tests_query.py +94 -0
- testgen/commands/queries/profiling_query.py +366 -0
- testgen/commands/queries/test_parameter_validation_query.py +88 -0
- testgen/commands/run_execute_cat_tests.py +162 -0
- testgen/commands/run_execute_tests.py +168 -0
- testgen/commands/run_generate_tests.py +107 -0
- testgen/commands/run_get_entities.py +122 -0
- testgen/commands/run_launch_db_config.py +84 -0
- testgen/commands/run_observability_exporter.py +330 -0
- testgen/commands/run_profiling_bridge.py +495 -0
- testgen/commands/run_quick_start.py +168 -0
- testgen/commands/run_setup_profiling_tools.py +96 -0
- testgen/commands/run_test_definition.py +146 -0
- testgen/commands/run_test_parameter_validation.py +135 -0
- testgen/commands/run_upgrade_db_config.py +156 -0
- testgen/common/__init__.py +8 -0
- testgen/common/clean_sql.py +53 -0
- testgen/common/credentials.py +25 -0
- testgen/common/database/__init__.py +0 -0
- testgen/common/database/database_service.py +629 -0
- testgen/common/database/flavor/__init__.py +0 -0
- testgen/common/database/flavor/flavor_service.py +75 -0
- testgen/common/database/flavor/mssql_flavor_service.py +34 -0
- testgen/common/database/flavor/postgresql_flavor_service.py +5 -0
- testgen/common/database/flavor/redshift_flavor_service.py +22 -0
- testgen/common/database/flavor/snowflake_flavor_service.py +69 -0
- testgen/common/database/flavor/trino_flavor_service.py +21 -0
- testgen/common/date_service.py +68 -0
- testgen/common/display_service.py +85 -0
- testgen/common/docker_service.py +76 -0
- testgen/common/encrypt.py +55 -0
- testgen/common/get_pipeline_parms.py +57 -0
- testgen/common/logs.py +79 -0
- testgen/common/process_service.py +62 -0
- testgen/common/read_file.py +69 -0
- testgen/settings.py +440 -0
- testgen/template/dbsetup/010_create_base_schema.sql +2 -0
- testgen/template/dbsetup/020_create_standard_functions_sprocs.sql +179 -0
- testgen/template/dbsetup/030_initialize_new_schema_structure.sql +735 -0
- testgen/template/dbsetup/040_populate_new_schema_project.sql +59 -0
- testgen/template/dbsetup/050_populate_new_schema_metadata.sql +1517 -0
- testgen/template/dbsetup/060_create_standard_views.sql +248 -0
- testgen/template/dbsetup/070_create_default_users.sql +17 -0
- testgen/template/dbsetup/075_grant_role_rights.sql +43 -0
- testgen/template/dbsetup/080_set_current_revision.sql +5 -0
- testgen/template/dbupgrade/0100_incremental_upgrade.sql +5 -0
- testgen/template/dbupgrade/0101_incremental_upgrade.sql +15 -0
- testgen/template/dbupgrade/0102_incremental_upgrade.sql +4 -0
- testgen/template/dbupgrade/0103_incremental_upgrade.sql +22 -0
- testgen/template/dbupgrade/0104_incremental_upgrade.sql +44 -0
- testgen/template/dbupgrade/0105_incremental_upgrade.sql +1 -0
- testgen/template/dbupgrade/0106_incremental_upgrade.sql +5 -0
- testgen/template/dbupgrade/0107_incremental_upgrade.sql +3 -0
- testgen/template/dbupgrade_helpers/get_tg_revision.sql +2 -0
- testgen/template/exec_cat_tests/ex_cat_build_agg_table_tests.sql +116 -0
- testgen/template/exec_cat_tests/ex_cat_get_distinct_tables.sql +11 -0
- testgen/template/exec_cat_tests/ex_cat_results_parse.sql +69 -0
- testgen/template/exec_cat_tests/ex_cat_retrieve_agg_test_parms.sql +6 -0
- testgen/template/exec_cat_tests/ex_cat_test_query.sql +8 -0
- testgen/template/execution/ex_finalize_test_run_results.sql +37 -0
- testgen/template/execution/ex_get_tests_non_cat.sql +47 -0
- testgen/template/execution/ex_update_test_record_in_testrun_table.sql +27 -0
- testgen/template/execution/ex_write_test_record_to_testrun_table.sql +6 -0
- testgen/template/flavors/generic/exec_query_tests/ex_aggregate_match_no_drops_generic.sql +48 -0
- testgen/template/flavors/generic/exec_query_tests/ex_aggregate_match_num_incr_generic.sql +34 -0
- testgen/template/flavors/generic/exec_query_tests/ex_aggregate_match_percent_above_generic.sql +49 -0
- testgen/template/flavors/generic/exec_query_tests/ex_aggregate_match_percent_within_generic.sql +49 -0
- testgen/template/flavors/generic/exec_query_tests/ex_aggregate_match_same_generic.sql +49 -0
- testgen/template/flavors/generic/exec_query_tests/ex_custom_query_generic.sql +39 -0
- testgen/template/flavors/generic/exec_query_tests/ex_data_match_2way_generic.sql +58 -0
- testgen/template/flavors/generic/exec_query_tests/ex_data_match_generic.sql +44 -0
- testgen/template/flavors/generic/exec_query_tests/ex_prior_match_generic.sql +37 -0
- testgen/template/flavors/generic/exec_query_tests/ex_relative_entropy_generic.sql +53 -0
- testgen/template/flavors/generic/exec_query_tests/ex_window_match_no_drops_generic.sql +46 -0
- testgen/template/flavors/generic/exec_query_tests/ex_window_match_same_generic.sql +59 -0
- testgen/template/flavors/generic/profiling/contingency_counts.sql +3 -0
- testgen/template/flavors/generic/validate_tests/ex_get_project_column_list_generic.sql +3 -0
- testgen/template/flavors/mssql/exec_query_tests/ex_relative_entropy_mssql.sql +53 -0
- testgen/template/flavors/mssql/profiling/project_ddf_query_mssql.sql +35 -0
- testgen/template/flavors/mssql/profiling/project_profiling_query_mssql.yaml +246 -0
- testgen/template/flavors/mssql/profiling/project_secondary_profiling_query_mssql.sql +36 -0
- testgen/template/flavors/mssql/setup_profiling_tools/00_drop_existing_functions_mssql.sql +8 -0
- testgen/template/flavors/mssql/setup_profiling_tools/01_create_functions_mssql.sql +12 -0
- testgen/template/flavors/mssql/setup_profiling_tools/02_create_functions_mssql.sql +54 -0
- testgen/template/flavors/mssql/setup_profiling_tools/create_qc_schema_mssql.sql +4 -0
- testgen/template/flavors/mssql/setup_profiling_tools/grant_execute_privileges_mssql.sql +1 -0
- testgen/template/flavors/postgresql/exec_query_tests/ex_window_match_no_drops_postgresql.sql +46 -0
- testgen/template/flavors/postgresql/exec_query_tests/ex_window_match_same_postgresql.sql +59 -0
- testgen/template/flavors/postgresql/profiling/project_ddf_query_postgresql.sql +42 -0
- testgen/template/flavors/postgresql/profiling/project_profiling_query_postgresql.yaml +225 -0
- testgen/template/flavors/postgresql/profiling/project_secondary_profiling_query_postgresql.sql +28 -0
- testgen/template/flavors/postgresql/setup_profiling_tools/create_functions_postgresql.sql +157 -0
- testgen/template/flavors/postgresql/setup_profiling_tools/create_qc_schema_postgresql.sql +1 -0
- testgen/template/flavors/postgresql/setup_profiling_tools/grant_execute_privileges_postgresql.sql +2 -0
- testgen/template/flavors/redshift/profiling/project_ddf_query_redshift.sql +38 -0
- testgen/template/flavors/redshift/profiling/project_profiling_query_redshift.yaml +221 -0
- testgen/template/flavors/redshift/profiling/project_secondary_profiling_query_redshift.sql +29 -0
- testgen/template/flavors/redshift/setup_profiling_tools/create_functions_redshift.sql +115 -0
- testgen/template/flavors/redshift/setup_profiling_tools/create_qc_schema_redshift.sql +1 -0
- testgen/template/flavors/redshift/setup_profiling_tools/grant_execute_privileges_redshift.sql +2 -0
- testgen/template/flavors/snowflake/profiling/project_ddf_query_snowflake.sql +38 -0
- testgen/template/flavors/snowflake/profiling/project_profiling_query_snowflake.yaml +220 -0
- testgen/template/flavors/snowflake/profiling/project_secondary_profiling_query_snowflake.sql +29 -0
- testgen/template/flavors/snowflake/setup_profiling_tools/create_functions_snowflake.sql +69 -0
- testgen/template/flavors/snowflake/setup_profiling_tools/create_qc_schema_snowflake.sql +1 -0
- testgen/template/flavors/snowflake/setup_profiling_tools/grant_execute_privileges_snowflake.sql +6 -0
- testgen/template/flavors/trino/profiling/project_profiling_query_trino.yaml +219 -0
- testgen/template/flavors/trino/setup_profiling_tools/create_functions_trino.sql +92 -0
- testgen/template/flavors/trino/setup_profiling_tools/create_qc_schema_trino.sql +1 -0
- testgen/template/gen_funny_cat_tests/gen_test_constant.sql +104 -0
- testgen/template/gen_funny_cat_tests/gen_test_distinct_value_ct.sql +98 -0
- testgen/template/gen_funny_cat_tests/gen_test_row_ct.sql +57 -0
- testgen/template/gen_funny_cat_tests/gen_test_row_ct_pct.sql +59 -0
- testgen/template/generation/gen_delete_old_tests.sql +5 -0
- testgen/template/generation/gen_insert_test_suite.sql +5 -0
- testgen/template/generation/gen_retrieve_or_insert_test_suite.sql +58 -0
- testgen/template/generation/gen_standard_test_type_list.sql +13 -0
- testgen/template/generation/gen_standard_tests.sql +48 -0
- testgen/template/get_entities/get_connection.sql +21 -0
- testgen/template/get_entities/get_connections_list.sql +9 -0
- testgen/template/get_entities/get_latest.sql +4 -0
- testgen/template/get_entities/get_profile.sql +12 -0
- testgen/template/get_entities/get_profile_info.sql +17 -0
- testgen/template/get_entities/get_profile_list.sql +17 -0
- testgen/template/get_entities/get_profile_screen.sql +275 -0
- testgen/template/get_entities/get_project_list.sql +6 -0
- testgen/template/get_entities/get_table_group_list.sql +10 -0
- testgen/template/get_entities/get_test_generation_list.sql +18 -0
- testgen/template/get_entities/get_test_info.sql +41 -0
- testgen/template/get_entities/get_test_results_for_run_cli.sql +16 -0
- testgen/template/get_entities/get_test_run_list.sql +24 -0
- testgen/template/get_entities/get_test_suite.sql +13 -0
- testgen/template/get_entities/get_test_suite_list.sql +18 -0
- testgen/template/get_entities/list_test_types.sql +4 -0
- testgen/template/observability/get_event_data.sql +23 -0
- testgen/template/observability/get_test_results.sql +41 -0
- testgen/template/observability/update_test_results_exported_to_observability.sql +12 -0
- testgen/template/parms/parms_profiling.sql +34 -0
- testgen/template/parms/parms_test_execution.sql +13 -0
- testgen/template/parms/parms_test_gen.sql +23 -0
- testgen/template/profiling/contingency_columns.sql +7 -0
- testgen/template/profiling/datatype_suggestions.sql +56 -0
- testgen/template/profiling/functional_datatype.sql +523 -0
- testgen/template/profiling/functional_tabletype_stage.sql +48 -0
- testgen/template/profiling/functional_tabletype_update.sql +8 -0
- testgen/template/profiling/pii_flag.sql +133 -0
- testgen/template/profiling/profile_anomalies_screen_column.sql +22 -0
- testgen/template/profiling/profile_anomalies_screen_multi_column.sql +58 -0
- testgen/template/profiling/profile_anomalies_screen_table.sql +22 -0
- testgen/template/profiling/profile_anomalies_screen_table_dates.sql +30 -0
- testgen/template/profiling/profile_anomalies_screen_variants.sql +40 -0
- testgen/template/profiling/profile_anomaly_types_get.sql +3 -0
- testgen/template/profiling/project_get_table_sample_count.sql +22 -0
- testgen/template/profiling/project_profile_run_record_insert.sql +8 -0
- testgen/template/profiling/project_profile_run_record_update.sql +5 -0
- testgen/template/profiling/project_profile_run_record_update_status.sql +5 -0
- testgen/template/profiling/project_update_profile_results_to_estimates.sql +32 -0
- testgen/template/profiling/refresh_anomalies.sql +33 -0
- testgen/template/profiling/refresh_data_chars_from_profiling.sql +156 -0
- testgen/template/profiling/secondary_profiling_columns.sql +12 -0
- testgen/template/profiling/secondary_profiling_delete.sql +4 -0
- testgen/template/profiling/secondary_profiling_update.sql +18 -0
- testgen/template/quick_start/populate_target_data.sql +1077 -0
- testgen/template/quick_start/recreate_target_data_schema.sql +167 -0
- testgen/template/quick_start/update_target_data.sql +100 -0
- testgen/template/updates/create_tmp_test_definition.sql +19 -0
- testgen/template/updates/get_test_def_parms.sql +38 -0
- testgen/template/updates/populate_stg_test_definitions.sql +184 -0
- testgen/template/validate_tests/ex_disable_tests_test_definitions.sql +5 -0
- testgen/template/validate_tests/ex_flag_tests_test_definitions.sql +64 -0
- testgen/template/validate_tests/ex_get_project_column_list_generic.sql +3 -0
- testgen/template/validate_tests/ex_get_test_column_list_tg.sql +65 -0
- testgen/template/validate_tests/ex_write_test_val_errors.sql +22 -0
- testgen/ui/__init__.py +0 -0
- testgen/ui/app.py +98 -0
- testgen/ui/assets/dk_logo.svg +46 -0
- testgen/ui/assets/question_mark.png +0 -0
- testgen/ui/assets/scripts.js +68 -0
- testgen/ui/assets/style.css +140 -0
- testgen/ui/bootstrap.py +109 -0
- testgen/ui/components/__init__.py +0 -0
- testgen/ui/components/frontend/css/KFOlCnqEu92Fr1MmEU9fBBc4.woff2 +0 -0
- testgen/ui/components/frontend/css/KFOlCnqEu92Fr1MmEU9fChc4EsA.woff2 +0 -0
- testgen/ui/components/frontend/css/KFOmCnqEu92Fr1Mu4mxK.woff2 +0 -0
- testgen/ui/components/frontend/css/KFOmCnqEu92Fr1Mu7GxKOzY.woff2 +0 -0
- testgen/ui/components/frontend/css/material-symbols-rounded.css +24 -0
- testgen/ui/components/frontend/css/material-symbols-rounded.woff2 +0 -0
- testgen/ui/components/frontend/css/roboto-font-faces.css +35 -0
- testgen/ui/components/frontend/css/shared.css +36 -0
- testgen/ui/components/frontend/img/dk_logo.svg +46 -0
- testgen/ui/components/frontend/index.html +17 -0
- testgen/ui/components/frontend/js/components/breadcrumbs.js +86 -0
- testgen/ui/components/frontend/js/components/button.js +66 -0
- testgen/ui/components/frontend/js/components/location.js +62 -0
- testgen/ui/components/frontend/js/components/select.js +75 -0
- testgen/ui/components/frontend/js/components/sidebar.js +358 -0
- testgen/ui/components/frontend/js/main.js +99 -0
- testgen/ui/components/frontend/js/streamlit.js +19 -0
- testgen/ui/components/frontend/js/van.min.js +1 -0
- testgen/ui/components/utils/__init__.py +0 -0
- testgen/ui/components/utils/callbacks.py +51 -0
- testgen/ui/components/utils/component.py +13 -0
- testgen/ui/components/widgets/__init__.py +6 -0
- testgen/ui/components/widgets/breadcrumbs.py +32 -0
- testgen/ui/components/widgets/location.py +65 -0
- testgen/ui/components/widgets/modal.py +97 -0
- testgen/ui/components/widgets/sidebar.py +69 -0
- testgen/ui/navigation/__init__.py +0 -0
- testgen/ui/navigation/menu.py +42 -0
- testgen/ui/navigation/page.py +20 -0
- testgen/ui/navigation/router.py +63 -0
- testgen/ui/queries/__init__.py +0 -0
- testgen/ui/queries/authentication_queries.py +47 -0
- testgen/ui/queries/connection_queries.py +121 -0
- testgen/ui/queries/profiling_queries.py +148 -0
- testgen/ui/queries/project_queries.py +9 -0
- testgen/ui/queries/table_group_queries.py +186 -0
- testgen/ui/queries/test_definition_queries.py +270 -0
- testgen/ui/queries/test_run_queries.py +32 -0
- testgen/ui/queries/test_suite_queries.py +145 -0
- testgen/ui/scripts/__init__.py +0 -0
- testgen/ui/scripts/patch_streamlit.py +111 -0
- testgen/ui/services/__init__.py +0 -0
- testgen/ui/services/authentication_service.py +119 -0
- testgen/ui/services/connection_service.py +220 -0
- testgen/ui/services/database_service.py +282 -0
- testgen/ui/services/form_service.py +1008 -0
- testgen/ui/services/javascript_service.py +44 -0
- testgen/ui/services/query_service.py +316 -0
- testgen/ui/services/string_service.py +12 -0
- testgen/ui/services/table_group_service.py +130 -0
- testgen/ui/services/test_definition_service.py +117 -0
- testgen/ui/services/test_run_service.py +13 -0
- testgen/ui/services/test_suite_service.py +76 -0
- testgen/ui/services/toolbar_service.py +77 -0
- testgen/ui/session.py +46 -0
- testgen/ui/views/__init__.py +0 -0
- testgen/ui/views/app_log_modal.py +92 -0
- testgen/ui/views/connections.py +72 -0
- testgen/ui/views/connections_base.py +367 -0
- testgen/ui/views/login.py +40 -0
- testgen/ui/views/not_found.py +16 -0
- testgen/ui/views/overview.py +34 -0
- testgen/ui/views/profiling_anomalies.py +501 -0
- testgen/ui/views/profiling_details.py +335 -0
- testgen/ui/views/profiling_modal.py +40 -0
- testgen/ui/views/profiling_results.py +206 -0
- testgen/ui/views/profiling_summary.py +177 -0
- testgen/ui/views/project_settings.py +74 -0
- testgen/ui/views/table_groups.py +530 -0
- testgen/ui/views/test_definitions.py +1020 -0
- testgen/ui/views/test_results.py +908 -0
- testgen/ui/views/test_runs.py +195 -0
- testgen/ui/views/test_suites.py +545 -0
- testgen/utils/__init__.py +0 -0
- testgen/utils/plugins.py +17 -0
- 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> </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> </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)
|