Skip to content

Commit 0d7d59c

Browse files
authored
fix: disambiguate google-cloud-bigquery to_dataframe usage from pandas-gbq in ua. (#18369)
For internal issue b/540939659 and a follow-up to #18364 🦕
1 parent 9a1fb24 commit 0d7d59c

4 files changed

Lines changed: 290 additions & 38 deletions

File tree

packages/google-cloud-bigquery/google/cloud/bigquery/client.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@
7878
job,
7979
)
8080
from google.cloud.bigquery import exceptions as bq_exceptions
81+
from google.cloud.bigquery import (
82+
version as bq_version,
83+
)
8184
from google.cloud.bigquery._helpers import (
8285
_DEFAULT_HOST,
8386
_DEFAULT_HOST_TEMPLATE,
@@ -148,7 +151,7 @@
148151
_RESUMABLE_URL_TEMPLATE = _BASE_UPLOAD_TEMPLATE + "resumable"
149152
_GENERIC_CONTENT_TYPE = "*/*"
150153
_READ_LESS_THAN_SIZE = (
151-
"Size {:d} was specified but the file-like object only had " "{:d} bytes remaining."
154+
"Size {:d} was specified but the file-like object only had {:d} bytes remaining."
152155
)
153156
_NEED_TABLE_ARGUMENT = (
154157
"The table argument should be a table ID string, Table, or TableReference"
@@ -641,9 +644,16 @@ def _ensure_bqstorage_client(
641644
pandas_gbq = None # type: ignore
642645

643646
if pandas_gbq is None:
644-
user_agent = "pandas-gbq/0.0.0"
647+
# Even if pandas-gbq isn't installed, attribute all
648+
# to_dataframe/to_arrow usage the same as we do the recommended
649+
# (pandas-gbq) code paths.
650+
pandas_user_agent = "pandas-gbq/0.0.0"
645651
else:
646-
user_agent = f"pandas-gbq/{pandas_gbq.__version__}"
652+
pandas_user_agent = f"pandas-gbq/{pandas_gbq.__version__}"
653+
654+
# Track the google-cloud-bigquery version as "legacy" because this code
655+
# path is intended to be migrated to pandas-gbq itself.
656+
user_agent = f"legacy-gcb/{bq_version.__version__} {pandas_user_agent}"
647657

648658
if client_info is None:
649659
amended_client_info = google.api_core.gapic_v1.client_info.ClientInfo(

packages/google-cloud-bigquery/noxfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
from __future__ import absolute_import
1616

1717
import contextlib
18+
from functools import wraps
1819
import os
1920
import pathlib
2021
import re
2122
import shutil
2223
import time
23-
from functools import wraps
2424
from typing import Generator
2525

2626
import nox

packages/google-cloud-bigquery/tests/unit/test_client.py

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
import google.cloud.bigquery.table
5555
from google.api_core import client_info
5656
from google.cloud import bigquery
57-
from google.cloud.bigquery import ParquetOptions, exceptions
57+
from google.cloud.bigquery import ParquetOptions, exceptions, version
5858
from google.cloud.bigquery.dataset import Dataset, DatasetReference
5959
from google.cloud.bigquery.enums import DatasetView, TimestampPrecision, UpdateMode
6060
from google.cloud.bigquery.retry import DEFAULT_TIMEOUT
@@ -840,6 +840,9 @@ def test_ensure_bqstorage_client_creating_new_instance(self):
840840
self.assertIs(kwargs["client_options"], mock.sentinel.client_options)
841841
self.assertIn("test-agent", kwargs["client_info"].user_agent)
842842
self.assertIn("pandas-gbq", kwargs["client_info"].user_agent)
843+
self.assertIn(
844+
f"legacy-gcb/{version.__version__}", kwargs["client_info"].user_agent
845+
)
843846

844847
def test_ensure_bqstorage_client_pandas_gbq_installed(self):
845848
bigquery_storage = pytest.importorskip("google.cloud.bigquery_storage")
@@ -857,15 +860,17 @@ def test_ensure_bqstorage_client_pandas_gbq_installed(self):
857860
mock_pandas = mock.Mock()
858861
mock_pandas.__version__ = "0.13.0"
859862

860-
with mock.patch(
861-
"google.cloud.bigquery_storage.BigQueryReadClient", mock_client
862-
), mock.patch.dict(sys.modules, {"pandas_gbq": mock_pandas}):
863+
with (
864+
mock.patch("google.cloud.bigquery_storage.BigQueryReadClient", mock_client),
865+
mock.patch.dict(sys.modules, {"pandas_gbq": mock_pandas}),
866+
):
863867
client._ensure_bqstorage_client(client_info=client_info)
864868

865869
mock_client.assert_called_once()
866870
_, kwargs = mock_client.call_args
867871
self.assertEqual(
868-
kwargs["client_info"].user_agent, "app-agent pandas-gbq/0.13.0"
872+
kwargs["client_info"].user_agent,
873+
f"app-agent legacy-gcb/{version.__version__} pandas-gbq/0.13.0",
869874
)
870875

871876
def test_ensure_bqstorage_client_pandas_gbq_not_installed(self):
@@ -881,14 +886,18 @@ def test_ensure_bqstorage_client_pandas_gbq_not_installed(self):
881886
user_agent="app-agent"
882887
)
883888

884-
with mock.patch(
885-
"google.cloud.bigquery_storage.BigQueryReadClient", mock_client
886-
), mock.patch.dict(sys.modules, {"pandas_gbq": None}):
889+
with (
890+
mock.patch("google.cloud.bigquery_storage.BigQueryReadClient", mock_client),
891+
mock.patch.dict(sys.modules, {"pandas_gbq": None}),
892+
):
887893
client._ensure_bqstorage_client(client_info=client_info)
888894

889895
mock_client.assert_called_once()
890896
_, kwargs = mock_client.call_args
891-
self.assertEqual(kwargs["client_info"].user_agent, "app-agent pandas-gbq/0.0.0")
897+
self.assertEqual(
898+
kwargs["client_info"].user_agent,
899+
f"app-agent legacy-gcb/{version.__version__} pandas-gbq/0.0.0",
900+
)
892901

893902
def test_ensure_bqstorage_client_client_info_none(self):
894903
bigquery_storage = pytest.importorskip("google.cloud.bigquery_storage")
@@ -898,14 +907,18 @@ def test_ensure_bqstorage_client_client_info_none(self):
898907
creds = _make_credentials()
899908
client = self._make_one(project=self.PROJECT, credentials=creds)
900909

901-
with mock.patch(
902-
"google.cloud.bigquery_storage.BigQueryReadClient", mock_client
903-
), mock.patch.dict(sys.modules, {"pandas_gbq": None}):
910+
with (
911+
mock.patch("google.cloud.bigquery_storage.BigQueryReadClient", mock_client),
912+
mock.patch.dict(sys.modules, {"pandas_gbq": None}),
913+
):
904914
client._ensure_bqstorage_client(client_info=None)
905915

906916
mock_client.assert_called_once()
907917
_, kwargs = mock_client.call_args
908-
self.assertEqual(kwargs["client_info"].user_agent, "pandas-gbq/0.0.0")
918+
self.assertEqual(
919+
kwargs["client_info"].user_agent,
920+
f"legacy-gcb/{version.__version__} pandas-gbq/0.0.0",
921+
)
909922

910923
def test_ensure_bqstorage_client_client_info_user_agent_none(self):
911924
bigquery_storage = pytest.importorskip("google.cloud.bigquery_storage")
@@ -919,14 +932,18 @@ def test_ensure_bqstorage_client_client_info_user_agent_none(self):
919932

920933
client_info = google.api_core.gapic_v1.client_info.ClientInfo(user_agent=None)
921934

922-
with mock.patch(
923-
"google.cloud.bigquery_storage.BigQueryReadClient", mock_client
924-
), mock.patch.dict(sys.modules, {"pandas_gbq": None}):
935+
with (
936+
mock.patch("google.cloud.bigquery_storage.BigQueryReadClient", mock_client),
937+
mock.patch.dict(sys.modules, {"pandas_gbq": None}),
938+
):
925939
client._ensure_bqstorage_client(client_info=client_info)
926940

927941
mock_client.assert_called_once()
928942
_, kwargs = mock_client.call_args
929-
self.assertEqual(kwargs["client_info"].user_agent, "pandas-gbq/0.0.0")
943+
self.assertEqual(
944+
kwargs["client_info"].user_agent,
945+
f"legacy-gcb/{version.__version__} pandas-gbq/0.0.0",
946+
)
930947

931948
def test_ensure_bqstorage_client_missing_dependency(self):
932949
creds = _make_credentials()
@@ -9157,9 +9174,10 @@ def test_load_table_from_dataframe_w_partial_schema_extra_types(self):
91579174
SchemaField("unknown_col", "BYTES"),
91589175
)
91599176
job_config = job.LoadJobConfig(schema=schema)
9160-
with load_patch as load_table_from_file, pytest.raises(
9161-
ValueError
9162-
) as exc_context:
9177+
with (
9178+
load_patch as load_table_from_file,
9179+
pytest.raises(ValueError) as exc_context,
9180+
):
91639181
client.load_table_from_dataframe(
91649182
dataframe, self.TABLE_REF, job_config=job_config, location=self.LOCATION
91659183
)
@@ -9429,9 +9447,13 @@ def test_load_table_from_dataframe_emits_pending_deprecation_warning(self):
94299447
get_table_patch = mock.patch(
94309448
"google.cloud.bigquery.client.Client.get_table", autospec=True
94319449
)
9432-
with load_patch, get_table_patch, pytest.warns(
9433-
PendingDeprecationWarning,
9434-
match="Loading DataFrames via google-cloud-bigquery is deprecated",
9450+
with (
9451+
load_patch,
9452+
get_table_patch,
9453+
pytest.warns(
9454+
PendingDeprecationWarning,
9455+
match="Loading DataFrames via google-cloud-bigquery is deprecated",
9456+
),
94359457
):
94369458
client.load_table_from_dataframe(dataframe, self.TABLE_REF)
94379459

@@ -9853,7 +9875,7 @@ def test_load_table_from_json_unicode_emoji_data_case(self):
98539875

98549876
client = self._make_client()
98559877

9856-
emoji = "\U0001F3E6"
9878+
emoji = "\U0001f3e6"
98579879
json_row = {"emoji": emoji}
98589880
json_rows = [json_row]
98599881

0 commit comments

Comments
 (0)