Repository: googleapis/python-bigquery

Issue:
Ability to specify a location for the BigQuery magics %%bigquery requests
When using the BigQuery magics command, I am unable to specify a location where the query will be executed.  When we look at the Cloud Console, we find that we can go into query settings > Advanced  and set the location type (after unchecking "Automatic location selection").  By naming a region/multi region we can explicitly declare where the query should run.

Prior to now (2024-01) the ability to specify where the query should execute was likely not that interesting ... however, now we have the concept of Cross Region Dataset replication.  This allows me to define a dataset and specify a named region where my dataset will be asynchronously replicated to.  Effectively, I now have the dataset existing in MULTIPLE regions and, in that case, it makes sense to specify where I want my query to run.

I reviewed the magics code and *believe* the change would be relatively simple.  Looking at the code I find

```
client = bigqueryClient(...)
```

and then reviewing [here](https://cloud.google.com/python/docs/reference/bigquery/latest/google.cloud.bigquery.client.Client) ... I see that location is a parameter of the Client() constructor.  I get the feel that adding location as a parameter to Bigquery magics would not be too onerous.

I could imagine:
```
%%bigquery --location us-east1
SELECT * FROM X.Y;
```


Discussion:
Thanks for the feature request! I agree this shouldn't be too difficult to implement. I'd like it to also be added to Context as a global option as well.

Resolving patch:
diff --git a/google/cloud/bigquery/magics/magics.py b/google/cloud/bigquery/magics/magics.py
--- a/google/cloud/bigquery/magics/magics.py
+++ b/google/cloud/bigquery/magics/magics.py
@@ -508,6 +508,15 @@ def _create_dataset_if_necessary(client, dataset_id):
         "Defaults to use tqdm_notebook. Install the ``tqdm`` package to use this feature."
     ),
 )
+@magic_arguments.argument(
+    "--location",
+    type=str,
+    default=None,
+    help=(
+        "Set the location to execute query."
+        "Defaults to location set in query setting in console."
+    ),
+)
 def _cell_magic(line, query):
     """Underlying function for bigquery cell magic
 
@@ -551,6 +560,7 @@ def _cell_magic(line, query):
             category=DeprecationWarning,
         )
     use_bqstorage_api = not args.use_rest_api
+    location = args.location
 
     params = []
     if params_option_value:
@@ -579,6 +589,7 @@ def _cell_magic(line, query):
         default_query_job_config=context.default_query_job_config,
         client_info=client_info.ClientInfo(user_agent=IPYTHON_USER_AGENT),
         client_options=bigquery_client_options,
+        location=location,
     )
     if context._connection:
         client._connection = context._connection


Test patch:
diff --git a/tests/unit/test_magics.py b/tests/unit/test_magics.py
--- a/tests/unit/test_magics.py
+++ b/tests/unit/test_magics.py
@@ -2053,3 +2053,21 @@ def test_bigquery_magic_create_dataset_fails():
         )
 
     assert close_transports.called
+
+
+@pytest.mark.usefixtures("ipython_interactive")
+def test_bigquery_magic_with_location():
+    ip = IPython.get_ipython()
+    ip.extension_manager.load_extension("google.cloud.bigquery")
+    magics.context.credentials = mock.create_autospec(
+        google.auth.credentials.Credentials, instance=True
+    )
+
+    run_query_patch = mock.patch(
+        "google.cloud.bigquery.magics.magics._run_query", autospec=True
+    )
+    with run_query_patch as run_query_mock:
+        ip.run_cell_magic("bigquery", "--location=us-east1", "SELECT 17 AS num")
+
+        client_options_used = run_query_mock.call_args_list[0][0][0]
+        assert client_options_used.location == "us-east1"