@@ -267,6 +267,8 @@ def __init__(
267
267
auth_redirect_uri = None ,
268
268
client_id = None ,
269
269
client_secret = None ,
270
+ user_agent = None ,
271
+ rfc9110_delimiter = False ,
270
272
):
271
273
global context
272
274
from google .api_core .exceptions import ClientError , GoogleAPIError
@@ -284,6 +286,8 @@ def __init__(
284
286
self .auth_redirect_uri = auth_redirect_uri
285
287
self .client_id = client_id
286
288
self .client_secret = client_secret
289
+ self .user_agent = user_agent
290
+ self .rfc9110_delimiter = rfc9110_delimiter
287
291
288
292
default_project = None
289
293
@@ -337,11 +341,15 @@ def log_elapsed_seconds(self, prefix="Elapsed", postfix="s.", overlong=6):
337
341
338
342
def get_client (self ):
339
343
import google .api_core .client_info
340
- import pandas
341
344
342
345
bigquery = FEATURES .bigquery_try_import ()
346
+
347
+ user_agent = create_user_agent (
348
+ user_agent = self .user_agent , rfc9110_delimiter = self .rfc9110_delimiter
349
+ )
350
+
343
351
client_info = google .api_core .client_info .ClientInfo (
344
- user_agent = "pandas-{}" . format ( pandas . __version__ )
352
+ user_agent = user_agent ,
345
353
)
346
354
return bigquery .Client (
347
355
project = self .project_id ,
@@ -961,6 +969,8 @@ def to_gbq(
961
969
auth_redirect_uri = None ,
962
970
client_id = None ,
963
971
client_secret = None ,
972
+ user_agent = None ,
973
+ rfc9110_delimiter = False ,
964
974
):
965
975
"""Write a DataFrame to a Google BigQuery table.
966
976
@@ -1072,6 +1082,13 @@ def to_gbq(
1072
1082
client_secret : str
1073
1083
The Client Secret associated with the Client ID for the Google Cloud Project
1074
1084
the user is attempting to connect to.
1085
+ user_agent : str
1086
+ Custom user agent string used as a prefix to the pandas version.
1087
+ rfc9110_delimiter : bool
1088
+ Sets user agent delimiter to a hyphen or a slash.
1089
+ Default is False, meaning a hyphen will be used.
1090
+
1091
+ .. versionadded:: 0.23.3
1075
1092
"""
1076
1093
1077
1094
_test_google_api_imports ()
@@ -1130,6 +1147,8 @@ def to_gbq(
1130
1147
auth_redirect_uri = auth_redirect_uri ,
1131
1148
client_id = client_id ,
1132
1149
client_secret = client_secret ,
1150
+ user_agent = user_agent ,
1151
+ rfc9110_delimiter = rfc9110_delimiter ,
1133
1152
)
1134
1153
bqclient = connector .client
1135
1154
@@ -1409,3 +1428,59 @@ def create(self, dataset_id):
1409
1428
self .client .create_dataset (dataset )
1410
1429
except self .http_error as ex :
1411
1430
self .process_http_error (ex )
1431
+
1432
+
1433
+ def create_user_agent (
1434
+ user_agent : Optional [str ] = None , rfc9110_delimiter : bool = False
1435
+ ) -> str :
1436
+ """Creates a user agent string.
1437
+
1438
+ The legacy format of our the user agent string was: `product-x.y.z` (where x,
1439
+ y, and z are the major, minor, and micro version numbers).
1440
+
1441
+ Users are able to prepend this string with their own user agent identifier
1442
+ to render something similar to `<my_user_agent> pandas-x.y.z`.
1443
+
1444
+ The legacy format used a hyphen to separate the product from the product
1445
+ version which differs slightly from the format recommended by RFC9110, which is:
1446
+ `product/x.y.z`. To produce a user agent more in line with the RFC, set
1447
+ rfc9110_delimiter to True. This setting does not depend on whether a
1448
+ user_agent is also supplied.
1449
+
1450
+ Reference:
1451
+ https://www.rfc-editor.org/info/rfc9110
1452
+
1453
+ Args:
1454
+ user_agent (Optional[str]): User agent string.
1455
+
1456
+ rfc9110_delimiter (Optional[bool]): Sets delimiter to a hyphen or a slash.
1457
+ Default is False, meaning a hyphen will be used.
1458
+
1459
+ Returns (str):
1460
+ Customized user agent string.
1461
+
1462
+ Deprecation Warning:
1463
+ In a future major release, the default delimiter will be changed to
1464
+ a `/` in accordance with RFC9110.
1465
+ """
1466
+ import pandas as pd
1467
+
1468
+ if rfc9110_delimiter :
1469
+ delimiter = "/"
1470
+ else :
1471
+ warnings .warn (
1472
+ "In a future major release, the default delimiter will be "
1473
+ "changed to a `/` in accordance with RFC9110." ,
1474
+ PendingDeprecationWarning ,
1475
+ stacklevel = 2 ,
1476
+ )
1477
+ delimiter = "-"
1478
+
1479
+ identity = f"pandas{ delimiter } { pd .__version__ } "
1480
+
1481
+ if user_agent is None :
1482
+ user_agent = identity
1483
+ else :
1484
+ user_agent = f"{ user_agent } { identity } "
1485
+
1486
+ return user_agent
0 commit comments