139139
140140import re
141141import ast
142+ import copy
142143import functools
143144import sys
144145import time
155156import six
156157
157158from google .api_core import client_info
159+ from google .api_core import client_options
158160from google .api_core .exceptions import NotFound
159161import google .auth
160162from google .cloud import bigquery
@@ -178,11 +180,13 @@ def __init__(self):
178180self ._project = None
179181self ._connection = None
180182self ._default_query_job_config = bigquery .QueryJobConfig ()
183+ self ._bigquery_client_options = client_options .ClientOptions ()
184+ self ._bqstorage_client_options = client_options .ClientOptions ()
181185
182186@property
183187def credentials (self ):
184188"""google.auth.credentials.Credentials: Credentials to use for queries
185- performed through IPython magics
189+ performed through IPython magics.
186190
187191 Note:
188192 These credentials do not need to be explicitly defined if you are
@@ -217,7 +221,7 @@ def credentials(self, value):
217221@property
218222def project (self ):
219223"""str: Default project to use for queries performed through IPython
220- magics
224+ magics.
221225
222226 Note:
223227 The project does not need to be explicitly defined if you have an
@@ -239,6 +243,54 @@ def project(self):
239243def project (self ,value ):
240244self ._project = value
241245
246+ @property
247+ def bigquery_client_options (self ):
248+ """google.api_core.client_options.ClientOptions: client options to be
249+ used through IPython magics.
250+
251+ Note::
252+ The client options do not need to be explicitly defined if no
253+ special network connections are required. Normally you would be
254+ using the https://bigquery.googleapis.com/ end point.
255+
256+ Example:
257+ Manually setting the endpoint:
258+
259+ >>> from google.cloud.bigquery import magics
260+ >>> client_options = {}
261+ >>> client_options['api_endpoint'] = "https://some.special.url"
262+ >>> magics.context.bigquery_client_options = client_options
263+ """
264+ return self ._bigquery_client_options
265+
266+ @bigquery_client_options .setter
267+ def bigquery_client_options (self ,value ):
268+ self ._bigquery_client_options = value
269+
270+ @property
271+ def bqstorage_client_options (self ):
272+ """google.api_core.client_options.ClientOptions: client options to be
273+ used through IPython magics for the storage client.
274+
275+ Note::
276+ The client options do not need to be explicitly defined if no
277+ special network connections are required. Normally you would be
278+ using the https://bigquerystorage.googleapis.com/ end point.
279+
280+ Example:
281+ Manually setting the endpoint:
282+
283+ >>> from google.cloud.bigquery import magics
284+ >>> client_options = {}
285+ >>> client_options['api_endpoint'] = "https://some.special.url"
286+ >>> magics.context.bqstorage_client_options = client_options
287+ """
288+ return self ._bqstorage_client_options
289+
290+ @bqstorage_client_options .setter
291+ def bqstorage_client_options (self ,value ):
292+ self ._bqstorage_client_options = value
293+
242294@property
243295def default_query_job_config (self ):
244296"""google.cloud.bigquery.job.QueryJobConfig: Default job
@@ -410,6 +462,24 @@ def _create_dataset_if_necessary(client, dataset_id):
410462"Standard SQL if this argument is not used."
411463 ),
412464)
465+ @magic_arguments .argument (
466+ "--bigquery_api_endpoint" ,
467+ type = str ,
468+ default = None ,
469+ help = (
470+ "The desired API endpoint, e.g., bigquery.googlepis.com. Defaults to this "
471+ "option's value in the context bigquery_client_options."
472+ ),
473+ )
474+ @magic_arguments .argument (
475+ "--bqstorage_api_endpoint" ,
476+ type = str ,
477+ default = None ,
478+ help = (
479+ "The desired API endpoint, e.g., bigquerystorage.googlepis.com. Defaults to "
480+ "this option's value in the context bqstorage_client_options."
481+ ),
482+ )
413483@magic_arguments .argument (
414484"--use_bqstorage_api" ,
415485action = "store_true" ,
@@ -511,15 +581,34 @@ def _cell_magic(line, query):
511581params = _helpers .to_query_parameters (ast .literal_eval (params_option_value ))
512582
513583project = args .project or context .project
584+
585+ bigquery_client_options = copy .deepcopy (context .bigquery_client_options )
586+ if args .bigquery_api_endpoint :
587+ if isinstance (bigquery_client_options ,dict ):
588+ bigquery_client_options ["api_endpoint" ]= args .bigquery_api_endpoint
589+ else :
590+ bigquery_client_options .api_endpoint = args .bigquery_api_endpoint
591+
514592client = bigquery .Client (
515593project = project ,
516594credentials = context .credentials ,
517595default_query_job_config = context .default_query_job_config ,
518596client_info = client_info .ClientInfo (user_agent = IPYTHON_USER_AGENT ),
597+ client_options = bigquery_client_options ,
519598 )
520599if context ._connection :
521600client ._connection = context ._connection
522- bqstorage_client = _make_bqstorage_client (use_bqstorage_api ,context .credentials )
601+
602+ bqstorage_client_options = copy .deepcopy (context .bqstorage_client_options )
603+ if args .bqstorage_api_endpoint :
604+ if isinstance (bqstorage_client_options ,dict ):
605+ bqstorage_client_options ["api_endpoint" ]= args .bqstorage_api_endpoint
606+ else :
607+ bqstorage_client_options .api_endpoint = args .bqstorage_api_endpoint
608+
609+ bqstorage_client = _make_bqstorage_client (
610+ use_bqstorage_api ,context .credentials ,bqstorage_client_options ,
611+ )
523612
524613close_transports = functools .partial (_close_transports ,client ,bqstorage_client )
525614
@@ -632,7 +721,7 @@ def _split_args_line(line):
632721return params_option_value ,rest_of_args
633722
634723
635- def _make_bqstorage_client (use_bqstorage_api ,credentials ):
724+ def _make_bqstorage_client (use_bqstorage_api ,credentials , client_options ):
636725if not use_bqstorage_api :
637726return None
638727
@@ -658,6 +747,7 @@ def _make_bqstorage_client(use_bqstorage_api, credentials):
658747return bigquery_storage .BigQueryReadClient (
659748credentials = credentials ,
660749client_info = gapic_client_info .ClientInfo (user_agent = IPYTHON_USER_AGENT ),
750+ client_options = client_options ,
661751 )
662752
663753