import pandas as pd import sys import os import tableauserverclient as TSC from datetime import datetime, timedelta, timezone from tableauhyperapi import TableDefinition, SqlType, Nullability from dotenv import load_dotenv from pathlib import Path load_dotenv() sys.path.append(os.path.join(os.path.dirname(__file__), '../djagitit')) import tableau def safely_getenv(var): """Checks if environment variable is defined before returning it""" if not os.getenv(var): raise EnvironmentError(f'Environment variable {var} not defined!') return os.getenv(var) # Example data creation df = pd.DataFrame({ 'report_date': pd.to_datetime(['2022-01-01', '2022-01-02']), 'isrc': ['ABC123', 'DEF456'], 'country_code': ['US', 'UK'], 'num_streams': [100, 200], 'avg_stream_duration_seconds': [150.5, 200.75], 'is_local_track': [True, False], }) expected_hyperschema = [ TableDefinition.Column('report_date', SqlType.date(), Nullability.NULLABLE), TableDefinition.Column('isrc', SqlType.text(), Nullability.NULLABLE), TableDefinition.Column('country_code', SqlType.text(), Nullability.NULLABLE), TableDefinition.Column('num_streams', SqlType.big_int(), Nullability.NULLABLE), TableDefinition.Column('avg_stream_duration_seconds', SqlType.double(), Nullability.NULLABLE), TableDefinition.Column('is_local_track', SqlType.bool(), Nullability.NULLABLE), ] testfilepathobject = Path(safely_getenv('DATADIR')) / 'test' / 'test.hyper' testfilepath = testfilepathobject.resolve() infamous_id = 'e6d1af34-b15d-490f-a972-cbabcb8e7cf1' class TestTableau: @staticmethod def test_hyperschema(): # Generating hyperSchema for the DataFrame generated_hyperschema = tableau.generate_hyper_schema(df) # Extracting only column names and SQL types for comparison generated_columns = [(col.name, col.type) for col in generated_hyperschema] expected_columns = [(col.name, col.type) for col in expected_hyperschema] assert generated_columns == expected_columns @staticmethod def test_write_hyper(): tableau.write_hyper(df, testfilepath, expected_hyperschema) assert os.path.exists(testfilepath) @staticmethod def test_new_data_source(): global testdatasource_id testdatasource_id = tableau.new_datasource('int_mktng', infamous_id, testfilepath) @staticmethod def test_get_data_sources(): limit = datetime.now(timezone.utc) - timedelta(minutes=1) timefilter = limit.strftime('%Y-%m-%dT%H:%M:%SZ') req_option = TSC.RequestOptions(pagesize=1000) req_option.filter.add( TSC.Filter( TSC.RequestOptions.Field.UpdatedAt, TSC.RequestOptions.Operator.GreaterThan, timefilter ) ) result = tableau.get_datasource_ids('int_mktng', options=req_option) assert isinstance(result, dict), 'Failed, excpected dictionary' assert len(result) > 0, 'Failed, empty dict' print(testdatasource_id) print(result) assert testdatasource_id in result.values(), 'Failed, recently published data source not found' @staticmethod def test_get_projects(): result = tableau.get_project_ids('int_mktng') assert isinstance(result, dict), 'Failed, excpected dictionary' assert len(result) > 0, 'Failed, empty dict' assert infamous_id in result.values(), 'Failed, project Infamous not found' @staticmethod def test_publish_hyper(): tableau.publish_hyper(testfilepath, testdatasource_id, 'int_mktng') @staticmethod def test_delete_data_source(): tableau.delete_datasource(testdatasource_id, 'int_mktng', sure='Yes')