Skip to content

Commit 08a9bcc

Browse files
authored
Merge pull request #1088 from googleapis/sync-v3
chore: sync v3 with main branch
2 parents 7e3721e + 011f160 commit 08a9bcc

File tree

13 files changed

+140
-87
lines changed

13 files changed

+140
-87
lines changed

google/cloud/bigquery/dataset.py

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from __future__ import absolute_import
1818

1919
import copy
20+
from typing import Dict, Any
2021

2122
import google.cloud._helpers # type: ignore
2223

@@ -77,28 +78,29 @@ def _get_routine_reference(self, routine_id):
7778
class AccessEntry(object):
7879
"""Represents grant of an access role to an entity.
7980
80-
An entry must have exactly one of the allowed :attr:`ENTITY_TYPES`. If
81-
anything but ``view`` or ``routine`` are set, a ``role`` is also required.
82-
``role`` is omitted for ``view`` and ``routine``, because they are always
83-
read-only.
81+
An entry must have exactly one of the allowed
82+
:class:`google.cloud.bigquery.enums.EntityTypes`. If anything but ``view``, ``routine``,
83+
or ``dataset`` are set, a ``role`` is also required. ``role`` is omitted for ``view``,
84+
``routine``, ``dataset``, because they are always read-only.
8485
8586
See https://cloud.google.com/bigquery/docs/reference/rest/v2/datasets.
8687
8788
Args:
8889
role (str):
8990
Role granted to the entity. The following string values are
9091
supported: `'READER'`, `'WRITER'`, `'OWNER'`. It may also be
91-
:data:`None` if the ``entity_type`` is ``view`` or ``routine``.
92+
:data:`None` if the ``entity_type`` is ``view``, ``routine``, or ``dataset``.
9293
9394
entity_type (str):
94-
Type of entity being granted the role. One of :attr:`ENTITY_TYPES`.
95+
Type of entity being granted the role. See
96+
:class:`google.cloud.bigquery.enums.EntityTypes` for supported types.
9597
9698
entity_id (Union[str, Dict[str, str]]):
97-
If the ``entity_type`` is not 'view' or 'routine', the ``entity_id``
98-
is the ``str`` ID of the entity being granted the role. If the
99-
``entity_type`` is 'view' or 'routine', the ``entity_id`` is a ``dict``
100-
representing the view or routine from a different dataset to grant
101-
access to in the following format for views::
99+
If the ``entity_type`` is not 'view', 'routine', or 'dataset', the
100+
``entity_id`` is the ``str`` ID of the entity being granted the role. If
101+
the ``entity_type`` is 'view' or 'routine', the ``entity_id`` is a ``dict``
102+
representing the view or routine from a different dataset to grant access
103+
to in the following format for views::
102104
103105
{
104106
'projectId': string,
@@ -114,11 +116,22 @@ class AccessEntry(object):
114116
'routineId': string
115117
}
116118
119+
If the ``entity_type`` is 'dataset', the ``entity_id`` is a ``dict`` that includes
120+
a 'dataset' field with a ``dict`` representing the dataset and a 'target_types'
121+
field with a ``str`` value of the dataset's resource type::
122+
123+
{
124+
'dataset': {
125+
'projectId': string,
126+
'datasetId': string,
127+
},
128+
'target_types: 'VIEWS'
129+
}
130+
117131
Raises:
118132
ValueError:
119-
If the ``entity_type`` is not among :attr:`ENTITY_TYPES`, or if a
120-
``view`` or a ``routine`` has ``role`` set, or a non ``view`` and
121-
non ``routine`` **does not** have a ``role`` set.
133+
If a ``view``, ``routine``, or ``dataset`` has ``role`` set, or a non ``view``,
134+
non ``routine``, and non ``dataset`` **does not** have a ``role`` set.
122135
123136
Examples:
124137
>>> entry = AccessEntry('OWNER', 'userByEmail', 'user@example.com')
@@ -131,27 +144,9 @@ class AccessEntry(object):
131144
>>> entry = AccessEntry(None, 'view', view)
132145
"""
133146

134-
ENTITY_TYPES = frozenset(
135-
[
136-
"userByEmail",
137-
"groupByEmail",
138-
"domain",
139-
"specialGroup",
140-
"view",
141-
"iamMember",
142-
"routine",
143-
]
144-
)
145-
"""Allowed entity types."""
146-
147-
def __init__(self, role, entity_type, entity_id) -> None:
148-
if entity_type not in self.ENTITY_TYPES:
149-
message = "Entity type %r not among: %s" % (
150-
entity_type,
151-
", ".join(self.ENTITY_TYPES),
152-
)
153-
raise ValueError(message)
154-
if entity_type in ("view", "routine"):
147+
def __init__(self, role=None, entity_type=None, entity_id=None) -> None:
148+
self._properties: Dict[str, Any] = {}
149+
if entity_type in ("view", "routine", "dataset"):
155150
if role is not None:
156151
raise ValueError(
157152
"Role must be None for a %r. Received "
@@ -162,7 +157,6 @@ def __init__(self, role, entity_type, entity_id) -> None:
162157
raise ValueError(
163158
"Role must be set for entity " "type %r" % (entity_type,)
164159
)
165-
166160
self._role = role
167161
self._entity_type = entity_type
168162
self._entity_id = entity_id
@@ -214,7 +208,8 @@ def to_api_repr(self):
214208
Returns:
215209
Dict[str, object]: Access entry represented as an API resource
216210
"""
217-
resource = {self._entity_type: self._entity_id}
211+
resource = copy.deepcopy(self._properties)
212+
resource[self._entity_type] = self._entity_id
218213
if self._role is not None:
219214
resource["role"] = self._role
220215
return resource
@@ -241,7 +236,10 @@ def from_api_repr(cls, resource: dict) -> "AccessEntry":
241236
entity_type, entity_id = entry.popitem()
242237
if len(entry) != 0:
243238
raise ValueError("Entry has unexpected keys remaining.", entry)
244-
return cls(role, entity_type, entity_id)
239+
240+
config = cls(role, entity_type, entity_id)
241+
config._properties = copy.deepcopy(resource)
242+
return config
245243

246244

247245
class DatasetReference(object):

google/cloud/bigquery/enums.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,19 @@ def _generate_next_value_(name, start, count, last_values):
236236
STRUCT = enum.auto()
237237

238238

239+
class EntityTypes(str, enum.Enum):
240+
"""Enum of allowed entity type names in AccessEntry"""
241+
242+
USER_BY_EMAIL = "userByEmail"
243+
GROUP_BY_EMAIL = "groupByEmail"
244+
DOMAIN = "domain"
245+
DATASET = "dataset"
246+
SPECIAL_GROUP = "specialGroup"
247+
VIEW = "view"
248+
IAM_MEMBER = "iamMember"
249+
ROUTINE = "routine"
250+
251+
239252
# See also: https://cloud.google.com/bigquery/data-types#legacy_sql_data_types
240253
# and https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types
241254
class SqlTypeNames(str, enum.Enum):

samples/geography/requirements.txt

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,51 @@
11
attrs==21.2.0
22
cachetools==4.2.4
3-
certifi==2021.5.30
4-
cffi==1.14.6
5-
charset-normalizer==2.0.6
6-
click==8.0.1
3+
certifi==2021.10.8
4+
cffi==1.15.0
5+
charset-normalizer==2.0.9
6+
click==8.0.3
77
click-plugins==1.1.1
88
cligj==0.7.2
99
dataclasses==0.6; python_version < '3.7'
1010
db-dtypes==0.3.0
1111
Fiona==1.8.20
1212
geojson==2.5.0
13-
geopandas==0.9.0
14-
google-api-core==2.0.1
15-
google-auth==2.2.1
16-
google-cloud-bigquery==2.27.1
17-
google-cloud-bigquery-storage==2.9.0
18-
google-cloud-core==2.0.0
19-
google-crc32c==1.2.0
20-
google-resumable-media==2.0.3
21-
googleapis-common-protos==1.53.0
22-
grpcio==1.41.0
23-
idna==3.2
24-
importlib-metadata==4.8.1
25-
libcst==0.3.21
13+
geopandas==0.9.0; python_version < '3.7'
14+
geopandas==0.10.2; python_version >= '3.7'
15+
google-api-core==2.3.0
16+
google-auth==2.3.3
17+
google-cloud-bigquery==2.31.0
18+
google-cloud-bigquery-storage==2.10.1
19+
google-cloud-core==2.2.1
20+
google-crc32c==1.3.0
21+
google-resumable-media==2.1.0
22+
googleapis-common-protos==1.54.0
23+
grpcio==1.42.0
24+
idna==3.3
25+
importlib-metadata==4.8.2
26+
libcst==0.3.23
2627
munch==2.5.0
2728
mypy-extensions==0.4.3
28-
packaging==21.0
29+
packaging==21.3
2930
pandas==1.1.5; python_version < '3.7'
3031
pandas==1.3.4; python_version >= '3.7'
31-
proto-plus==1.19.2
32-
protobuf==3.18.0
33-
pyarrow==6.0.0
32+
proto-plus==1.19.8
33+
protobuf==3.19.1
34+
pyarrow==6.0.1
3435
pyasn1==0.4.8
3536
pyasn1-modules==0.2.8
36-
pycparser==2.20
37-
pyparsing==2.4.7
37+
pycparser==2.21
38+
pyparsing==3.0.6
3839
pyproj==3.0.1; python_version < "3.7"
3940
pyproj==3.1.0; python_version > "3.6"
4041
python-dateutil==2.8.2
41-
pytz==2021.1
42-
PyYAML==5.4.1
42+
pytz==2021.3
43+
PyYAML==6.0
4344
requests==2.26.0
44-
rsa==4.7.2
45+
rsa==4.8
4546
Shapely==1.8.0
4647
six==1.16.0
47-
typing-extensions==3.10.0.2
48+
typing-extensions==4.0.1
4849
typing-inspect==0.7.1
4950
urllib3==1.26.7
5051
zipp==3.6.0
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
google-cloud-testutils==1.1.0
1+
google-cloud-testutils==1.3.1
22
pytest==6.2.5
33
mock==4.0.3

samples/magics/requirements.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
db-dtypes==0.3.0
2-
google-cloud-bigquery-storage==2.9.0
1+
db-dtypes==0.3.1
2+
google-cloud-bigquery-storage==2.10.1
33
google-auth-oauthlib==0.4.6
4-
grpcio==1.41.0
4+
grpcio==1.42.0
55
ipython==7.16.1; python_version < '3.7'
66
ipython==7.29.0; python_version >= '3.7'
77
matplotlib==3.3.4; python_version < '3.7'
88
matplotlib==3.5.0rc1; python_version >= '3.7'
99
pandas==1.1.5; python_version < '3.7'
1010
pandas==1.3.4; python_version >= '3.7'
11-
pyarrow==6.0.0
12-
pytz==2021.1
11+
pyarrow==6.0.1
12+
pytz==2021.3
1313
typing-extensions==3.10.0.2

samples/snippets/authorized_view_tutorial.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def run_authorized_view_tutorial(
3131
# Create a source dataset
3232
# [START bigquery_avt_create_source_dataset]
3333
from google.cloud import bigquery
34+
from google.cloud.bigquery.enums import EntityTypes
3435

3536
client = bigquery.Client()
3637
source_dataset_id = "github_source_data"
@@ -113,7 +114,7 @@ def run_authorized_view_tutorial(
113114
# analyst_group_email = 'data_analysts@example.com'
114115
access_entries = shared_dataset.access_entries
115116
access_entries.append(
116-
bigquery.AccessEntry("READER", "groupByEmail", analyst_group_email)
117+
bigquery.AccessEntry("READER", EntityTypes.GROUP_BY_EMAIL, analyst_group_email)
117118
)
118119
shared_dataset.access_entries = access_entries
119120
shared_dataset = client.update_dataset(
@@ -125,7 +126,7 @@ def run_authorized_view_tutorial(
125126
# [START bigquery_avt_source_dataset_access]
126127
access_entries = source_dataset.access_entries
127128
access_entries.append(
128-
bigquery.AccessEntry(None, "view", view.reference.to_api_repr())
129+
bigquery.AccessEntry(None, EntityTypes.VIEW, view.reference.to_api_repr())
129130
)
130131
source_dataset.access_entries = access_entries
131132
source_dataset = client.update_dataset(
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
google-cloud-testutils==1.1.0
1+
google-cloud-testutils==1.3.1
22
pytest==6.2.5
33
mock==4.0.3

samples/snippets/requirements.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
db-dtypes==0.3.0
2-
google-cloud-bigquery-storage==2.9.0
1+
db-dtypes==0.3.1
2+
google-cloud-bigquery-storage==2.10.1
33
google-auth-oauthlib==0.4.6
4-
grpcio==1.41.0
4+
grpcio==1.42.0
55
ipython==7.16.1; python_version < '3.7'
66
ipython==7.29.0; python_version >= '3.7'
77
matplotlib==3.3.4; python_version < '3.7'
88
matplotlib==3.4.1; python_version >= '3.7'
99
pandas==1.1.5; python_version < '3.7'
1010
pandas==1.3.4; python_version >= '3.7'
11-
pyarrow==6.0.0
12-
pytz==2021.1
11+
pyarrow==6.0.1
12+
pytz==2021.3
1313
typing-extensions==3.10.0.2

samples/snippets/update_dataset_access.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ def update_dataset_access(dataset_id: str, entity_id: str) -> None:
2727
# of the entity, such as a view's table reference.
2828
entity_id = "user-or-group-to-add@example.com"
2929

30+
from google.cloud.bigquery.enums import EntityTypes
31+
3032
# TODO(developer): Set entity_type to the type of entity you are granting access to.
3133
# Common types include:
3234
#
@@ -37,7 +39,7 @@ def update_dataset_access(dataset_id: str, entity_id: str) -> None:
3739
#
3840
# For a complete reference, see the REST API reference documentation:
3941
# https://cloud.google.com/bigquery/docs/reference/rest/v2/datasets#Dataset.FIELDS.access
40-
entity_type = "groupByEmail"
42+
entity_type = EntityTypes.GROUP_BY_EMAIL
4143

4244
# TODO(developer): Set role to a one of the "Basic roles for datasets"
4345
# described here:

samples/tests/test_copy_table.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414

1515
import typing
1616

17+
import pytest
18+
1719
from .. import copy_table
1820

1921
if typing.TYPE_CHECKING:
20-
import pytest
2122
from google.cloud import bigquery
2223

2324

@@ -27,6 +28,7 @@ def test_copy_table(
2728
random_table_id: str,
2829
client: "bigquery.Client",
2930
) -> None:
31+
pytest.skip("b/210907595: copy fails for shakespeare table")
3032

3133
copy_table.copy_table(table_with_data_id, random_table_id)
3234
out, err = capsys.readouterr()

0 commit comments

Comments
 (0)