From c6dd8b3a84e123d6cdc97f2eadde5a25f2db027b Mon Sep 17 00:00:00 2001 From: Ashley Xu Date: Thu, 14 Dec 2023 00:09:26 +0000 Subject: [PATCH 1/3] feat: add module/class level api tracking --- bigframes/core/log_adapter.py | 8 +++++--- tests/unit/session/test_io_bigquery.py | 16 ++++++++-------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/bigframes/core/log_adapter.py b/bigframes/core/log_adapter.py index b790d19562..ad9a8d85ff 100644 --- a/bigframes/core/log_adapter.py +++ b/bigframes/core/log_adapter.py @@ -25,19 +25,21 @@ def class_logger(decorated_cls): """Decorator that adds logging functionality to each method of the class.""" for attr_name, attr_value in decorated_cls.__dict__.items(): if callable(attr_value): - setattr(decorated_cls, attr_name, method_logger(attr_value)) + setattr(decorated_cls, attr_name, method_logger(attr_value, decorated_cls)) return decorated_cls -def method_logger(method): +def method_logger(method, decorated_cls): """Decorator that adds logging functionality to a method.""" @functools.wraps(method) def wrapper(*args, **kwargs): + class_name = decorated_cls.__name__ # Access decorated class name api_method_name = str(method.__name__) + full_method_name = f"{class_name}.{api_method_name}" # Track regular and "dunder" methods if api_method_name.startswith("__") or not api_method_name.startswith("_"): - add_api_method(api_method_name) + add_api_method(full_method_name) return method(*args, **kwargs) return wrapper diff --git a/tests/unit/session/test_io_bigquery.py b/tests/unit/session/test_io_bigquery.py index 3f3bfbe7d3..92d3851f28 100644 --- a/tests/unit/session/test_io_bigquery.py +++ b/tests/unit/session/test_io_bigquery.py @@ -76,11 +76,11 @@ def test_create_job_configs_labels_log_adaptor_call_method_under_length_limit(): expected_dict = { "bigframes-api": "read_pandas", "source": "bigquery-dataframes-temp", - "recent-bigframes-api-0": "__init__", - "recent-bigframes-api-1": "max", - "recent-bigframes-api-2": "__init__", - "recent-bigframes-api-3": "head", - "recent-bigframes-api-4": "__init__", + "recent-bigframes-api-0": "Series.__init__", + "recent-bigframes-api-1": "DataFrame.max", + "recent-bigframes-api-2": "DataFrame.__init__", + "recent-bigframes-api-3": "DataFrame.head", + "recent-bigframes-api-4": "DataFrame.__init__", } assert labels is not None assert len(labels) == 7 @@ -100,7 +100,7 @@ def test_create_job_configs_labels_length_limit_met_and_labels_is_none(): ) assert labels is not None assert len(labels) == 64 - assert "head" in labels.values() + assert "DataFrame.head" in labels.values() def test_create_job_configs_labels_length_limit_met(): @@ -125,8 +125,8 @@ def test_create_job_configs_labels_length_limit_met(): ) assert labels is not None assert len(labels) == 64 - assert "max" in labels.values() - assert "head" not in labels.values() + assert "DataFrame.max" in labels.values() + assert "DataFrame.head" not in labels.values() assert "bigframes-api" in labels.keys() assert "source" in labels.keys() From 219dfb28007589ce26c19436c78dee89ebe6c282 Mon Sep 17 00:00:00 2001 From: Ashley Xu Date: Thu, 14 Dec 2023 00:13:43 +0000 Subject: [PATCH 2/3] fix the failing unit test --- tests/unit/core/test_log_adapter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/core/test_log_adapter.py b/tests/unit/core/test_log_adapter.py index 376b7f2075..d9f7df92a7 100644 --- a/tests/unit/core/test_log_adapter.py +++ b/tests/unit/core/test_log_adapter.py @@ -40,8 +40,8 @@ def test_method_logging(test_instance): # Check if the methods were added to the _api_methods list api_methods = log_adapter.get_and_reset_api_methods() assert api_methods is not None - assert "method1" in api_methods - assert "method2" in api_methods + assert "TestClass.method1" in api_methods + assert "TestClass.method2" in api_methods def test_add_api_method_limit(test_instance): From 89c771c235b8547426122a4932cece4de0717cb9 Mon Sep 17 00:00:00 2001 From: Ashley Xu Date: Thu, 14 Dec 2023 02:24:28 +0000 Subject: [PATCH 3/3] fix: follow the labels requirement --- bigframes/core/log_adapter.py | 2 +- tests/unit/core/test_log_adapter.py | 4 ++-- tests/unit/session/test_io_bigquery.py | 16 ++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/bigframes/core/log_adapter.py b/bigframes/core/log_adapter.py index ad9a8d85ff..556851fa1b 100644 --- a/bigframes/core/log_adapter.py +++ b/bigframes/core/log_adapter.py @@ -36,7 +36,7 @@ def method_logger(method, decorated_cls): def wrapper(*args, **kwargs): class_name = decorated_cls.__name__ # Access decorated class name api_method_name = str(method.__name__) - full_method_name = f"{class_name}.{api_method_name}" + full_method_name = f"{class_name.lower()}-{api_method_name}" # Track regular and "dunder" methods if api_method_name.startswith("__") or not api_method_name.startswith("_"): add_api_method(full_method_name) diff --git a/tests/unit/core/test_log_adapter.py b/tests/unit/core/test_log_adapter.py index d9f7df92a7..7033369dd5 100644 --- a/tests/unit/core/test_log_adapter.py +++ b/tests/unit/core/test_log_adapter.py @@ -40,8 +40,8 @@ def test_method_logging(test_instance): # Check if the methods were added to the _api_methods list api_methods = log_adapter.get_and_reset_api_methods() assert api_methods is not None - assert "TestClass.method1" in api_methods - assert "TestClass.method2" in api_methods + assert "testclass-method1" in api_methods + assert "testclass-method2" in api_methods def test_add_api_method_limit(test_instance): diff --git a/tests/unit/session/test_io_bigquery.py b/tests/unit/session/test_io_bigquery.py index 92d3851f28..96bb7bf67f 100644 --- a/tests/unit/session/test_io_bigquery.py +++ b/tests/unit/session/test_io_bigquery.py @@ -76,11 +76,11 @@ def test_create_job_configs_labels_log_adaptor_call_method_under_length_limit(): expected_dict = { "bigframes-api": "read_pandas", "source": "bigquery-dataframes-temp", - "recent-bigframes-api-0": "Series.__init__", - "recent-bigframes-api-1": "DataFrame.max", - "recent-bigframes-api-2": "DataFrame.__init__", - "recent-bigframes-api-3": "DataFrame.head", - "recent-bigframes-api-4": "DataFrame.__init__", + "recent-bigframes-api-0": "series-__init__", + "recent-bigframes-api-1": "dataframe-max", + "recent-bigframes-api-2": "dataframe-__init__", + "recent-bigframes-api-3": "dataframe-head", + "recent-bigframes-api-4": "dataframe-__init__", } assert labels is not None assert len(labels) == 7 @@ -100,7 +100,7 @@ def test_create_job_configs_labels_length_limit_met_and_labels_is_none(): ) assert labels is not None assert len(labels) == 64 - assert "DataFrame.head" in labels.values() + assert "dataframe-head" in labels.values() def test_create_job_configs_labels_length_limit_met(): @@ -125,8 +125,8 @@ def test_create_job_configs_labels_length_limit_met(): ) assert labels is not None assert len(labels) == 64 - assert "DataFrame.max" in labels.values() - assert "DataFrame.head" not in labels.values() + assert "dataframe-max" in labels.values() + assert "dataframe-head" not in labels.values() assert "bigframes-api" in labels.keys() assert "source" in labels.keys()