Skip to content

Commit 60128a5

Browse files
tswastchalmerlowe
andauthored
feat: use bigquery-magics package for the %%bigquery magic (#1965)
* feat: use `bigquery-magics` package for the `%%bigquery` magic * ignore types on bigquery-magics package * Update samples/magics/noxfile_config.py Co-authored-by: Chalmer Lowe <[email protected]> --------- Co-authored-by: Chalmer Lowe <[email protected]>
1 parent a958732 commit 60128a5

File tree

12 files changed

+262
-186
lines changed

12 files changed

+262
-186
lines changed

google/cloud/bigquery/__init__.py

+18-4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
- :class:`~google.cloud.bigquery.table.Table` represents a single "relation".
2828
"""
2929

30+
import warnings
3031

3132
from google.cloud.bigquery import version as bigquery_version
3233

@@ -114,6 +115,11 @@
114115
from google.cloud.bigquery.table import TimePartitioning
115116
from google.cloud.bigquery.encryption_configuration import EncryptionConfiguration
116117

118+
try:
119+
import bigquery_magics # type: ignore
120+
except ImportError:
121+
bigquery_magics = None
122+
117123
__all__ = [
118124
"__version__",
119125
"Client",
@@ -214,8 +220,16 @@
214220

215221
def load_ipython_extension(ipython):
216222
"""Called by IPython when this module is loaded as an IPython extension."""
217-
from google.cloud.bigquery.magics.magics import _cell_magic
218-
219-
ipython.register_magic_function(
220-
_cell_magic, magic_kind="cell", magic_name="bigquery"
223+
warnings.warn(
224+
"%load_ext google.cloud.bigquery is deprecated. Install bigquery-magics package and use `%load_ext bigquery_magics`, instead.",
225+
category=FutureWarning,
221226
)
227+
228+
if bigquery_magics is not None:
229+
bigquery_magics.load_ipython_extension(ipython)
230+
else:
231+
from google.cloud.bigquery.magics.magics import _cell_magic
232+
233+
ipython.register_magic_function(
234+
_cell_magic, magic_kind="cell", magic_name="bigquery"
235+
)

google/cloud/bigquery/magics/magics.py

+17-64
Original file line numberDiff line numberDiff line change
@@ -14,70 +14,11 @@
1414

1515
"""IPython Magics
1616
17-
.. function:: %%bigquery
18-
19-
IPython cell magic to run a query and display the result as a DataFrame
20-
21-
.. code-block:: python
22-
23-
%%bigquery [<destination_var>] [--project <project>] [--use_legacy_sql]
24-
[--verbose] [--params <params>]
25-
<query>
26-
27-
Parameters:
28-
29-
* ``<destination_var>`` (Optional[line argument]):
30-
variable to store the query results. The results are not displayed if
31-
this parameter is used. If an error occurs during the query execution,
32-
the corresponding ``QueryJob`` instance (if available) is stored in
33-
the variable instead.
34-
* ``--destination_table`` (Optional[line argument]):
35-
A dataset and table to store the query results. If table does not exists,
36-
it will be created. If table already exists, its data will be overwritten.
37-
Variable should be in a format <dataset_id>.<table_id>.
38-
* ``--no_query_cache`` (Optional[line argument]):
39-
Do not use cached query results.
40-
* ``--project <project>`` (Optional[line argument]):
41-
Project to use for running the query. Defaults to the context
42-
:attr:`~google.cloud.bigquery.magics.Context.project`.
43-
* ``--use_bqstorage_api`` (Optional[line argument]):
44-
[Deprecated] Not used anymore, as BigQuery Storage API is used by default.
45-
* ``--use_rest_api`` (Optional[line argument]):
46-
Use the BigQuery REST API instead of the Storage API.
47-
* ``--use_legacy_sql`` (Optional[line argument]):
48-
Runs the query using Legacy SQL syntax. Defaults to Standard SQL if
49-
this argument not used.
50-
* ``--verbose`` (Optional[line argument]):
51-
If this flag is used, information including the query job ID and the
52-
amount of time for the query to complete will not be cleared after the
53-
query is finished. By default, this information will be displayed but
54-
will be cleared after the query is finished.
55-
* ``--params <params>`` (Optional[line argument]):
56-
If present, the argument following the ``--params`` flag must be
57-
either:
58-
59-
* :class:`str` - A JSON string representation of a dictionary in the
60-
format ``{"param_name": "param_value"}`` (ex. ``{"num": 17}``). Use
61-
of the parameter in the query should be indicated with
62-
``@param_name``. See ``In[5]`` in the Examples section below.
63-
64-
* :class:`dict` reference - A reference to a ``dict`` in the format
65-
``{"param_name": "param_value"}``, where the value types must be JSON
66-
serializable. The variable reference is indicated by a ``$`` before
67-
the variable name (ex. ``$my_dict_var``). See ``In[6]`` and ``In[7]``
68-
in the Examples section below.
69-
70-
* ``<query>`` (required, cell argument):
71-
SQL query to run. If the query does not contain any whitespace (aside
72-
from leading and trailing whitespace), it is assumed to represent a
73-
fully-qualified table ID, and the latter's data will be fetched.
17+
Install ``bigquery-magics`` and call ``%load_ext bigquery_magics`` to use the
18+
``%%bigquery`` cell magic.
7419
75-
Returns:
76-
A :class:`pandas.DataFrame` with the query results.
77-
78-
.. note::
79-
All queries run using this magic will run using the context
80-
:attr:`~google.cloud.bigquery.magics.Context.credentials`.
20+
See the `BigQuery Magics reference documentation
21+
<https://googleapis.dev/python/bigquery-magics/latest/>`_.
8122
"""
8223

8324
from __future__ import print_function
@@ -109,6 +50,11 @@
10950
from google.cloud.bigquery.dbapi import _helpers
11051
from google.cloud.bigquery.magics import line_arg_parser as lap
11152

53+
try:
54+
import bigquery_magics # type: ignore
55+
except ImportError:
56+
bigquery_magics = None
57+
11258

11359
IPYTHON_USER_AGENT = "ipython-{}".format(IPython.__version__)
11460

@@ -280,7 +226,14 @@ def progress_bar_type(self, value):
280226
self._progress_bar_type = value
281227

282228

283-
context = Context()
229+
# If bigquery_magics is available, we load that extension rather than this one.
230+
# Ensure google.cloud.bigquery.magics.context setters are on the correct magics
231+
# implementation in case the user has installed the package but hasn't updated
232+
# their code.
233+
if bigquery_magics is not None:
234+
context = bigquery_magics.context
235+
else:
236+
context = Context()
284237

285238

286239
def _handle_error(error, destination_var=None):

samples/magics/noxfile_config.py

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Default TEST_CONFIG_OVERRIDE for python repos.
16+
17+
# You can copy this file into your directory, then it will be inported from
18+
# the noxfile.py.
19+
20+
# The source of truth:
21+
# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/noxfile_config.py
22+
23+
TEST_CONFIG_OVERRIDE = {
24+
# You can opt out from the test for specific Python versions.
25+
"ignored_versions": [
26+
"2.7",
27+
],
28+
# An envvar key for determining the project id to use. Change it
29+
# to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a
30+
# build specific Cloud project. You can also use your own string
31+
# to use your own Cloud project.
32+
"gcloud_project_env": "GOOGLE_CLOUD_PROJECT",
33+
# "gcloud_project_env": "BUILD_SPECIFIC_GCLOUD_PROJECT",
34+
# A dictionary you want to inject into your test. Don't put any
35+
# secrets here. These values will override predefined values.
36+
"envs": {},
37+
}

samples/magics/query.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
def query() -> "pandas.DataFrame":
2626
ip = IPython.get_ipython()
27-
ip.extension_manager.load_extension("google.cloud.bigquery")
27+
ip.extension_manager.load_extension("bigquery_magics")
2828

2929
sample = """
3030
# [START bigquery_jupyter_query]

samples/magics/query_params_scalars.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424

2525
def query_with_parameters() -> "pandas.DataFrame":
2626
ip = IPython.get_ipython()
27-
ip.extension_manager.load_extension("google.cloud.bigquery")
27+
ip.extension_manager.load_extension("bigquery_magics")
2828

2929
sample = """
3030
# [START bigquery_jupyter_query_params_scalars]

samples/magics/requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
bigquery_magics==0.1.0
12
db-dtypes==1.2.0
23
google.cloud.bigquery==3.25.0
34
google-cloud-bigquery-storage==2.25.0

samples/notebooks/jupyter_tutorial_test.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def _strip_region_tags(sample_text: str) -> str:
6060
def test_jupyter_tutorial(ipython: "TerminalInteractiveShell") -> None:
6161
matplotlib.use("agg")
6262
ip = IPython.get_ipython()
63-
ip.extension_manager.load_extension("google.cloud.bigquery")
63+
ip.extension_manager.load_extension("bigquery_magics")
6464

6565
sample = """
6666
# [START bigquery_jupyter_magic_gender_by_year]

samples/notebooks/requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
bigquery-magics==0.1.0
12
db-dtypes==1.2.0
23
google-cloud-bigquery==3.25.0
34
google-cloud-bigquery-storage==2.25.0

setup.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,7 @@
6666
],
6767
"geopandas": ["geopandas>=0.9.0, <1.0dev", "Shapely>=1.8.4, <3.0.0dev"],
6868
"ipython": [
69-
"ipython>=7.23.1,!=8.1.0",
70-
"ipykernel>=6.0.0",
69+
"bigquery-magics >= 0.1.0",
7170
],
7271
"tqdm": ["tqdm >= 4.7.4, <5.0.0dev"],
7372
"opentelemetry": [

testing/constraints-3.7.txt

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#
66
# e.g., if setup.py has "foo >= 1.14.0, < 2.0.0dev",
77
# Then this file should have foo==1.14.0
8+
bigquery-magics==0.1.0
89
db-dtypes==0.3.0
910
geopandas==0.9.0
1011
google-api-core==2.11.1

tests/system/test_magics.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,10 @@ def test_bigquery_magic(ipython_interactive):
5050
current_process = psutil.Process()
5151
conn_count_start = len(current_process.connections())
5252

53-
ip.extension_manager.load_extension("google.cloud.bigquery")
53+
# Deprecated, but should still work in google-cloud-bigquery 3.x.
54+
with pytest.warns(FutureWarning, match="bigquery_magics"):
55+
ip.extension_manager.load_extension("google.cloud.bigquery")
56+
5457
sql = """
5558
SELECT
5659
CONCAT(

0 commit comments

Comments
 (0)