Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc098cd0

Browse files
authored
feat: support authorized dataset entity (#1075)
* feat: support authorized dataset entity* cleanup* add test and cache the resource from from_api_repr in a _properties value* lint* update samples to use enums* update to_api_repr and add tests* refactor
1 parent44221f4 commitc098cd0

File tree

5 files changed

+92
-43
lines changed

5 files changed

+92
-43
lines changed

‎google/cloud/bigquery/dataset.py‎

Lines changed: 35 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -77,28 +77,29 @@ def _get_routine_reference(self, routine_id):
7777
classAccessEntry(object):
7878
"""Represents grant of an access role to an entity.
7979
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.
80+
An entry must have exactly one of the allowed
81+
:class:`google.cloud.bigquery.enums.EntityTypes`. Ifanything but ``view``,``routine``,
82+
or ``dataset``are set, a ``role``is also required. ``role`` is omitted for ``view``,
83+
``routine``, ``dataset``, because they are alwaysread-only.
8484
8585
See https://cloud.google.com/bigquery/docs/reference/rest/v2/datasets.
8686
8787
Args:
8888
role (str):
8989
Role granted to the entity. The following string values are
9090
supported: `'READER'`, `'WRITER'`, `'OWNER'`. It may also be
91-
:data:`None` if the ``entity_type`` is ``view``or ``routine``.
91+
:data:`None` if the ``entity_type`` is ``view``, ``routine``,or ``dataset``.
9292
9393
entity_type (str):
94-
Type of entity being granted the role. One of :attr:`ENTITY_TYPES`.
94+
Type of entity being granted the role. See
95+
:class:`google.cloud.bigquery.enums.EntityTypes` for supported types.
9596
9697
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 viewor routine from a different dataset to grant
101-
accessto in the following format for views::
98+
If the ``entity_type`` is not 'view', 'routine',or 'dataset', the
99+
``entity_id``is the ``str`` ID of the entity being granted the role. If
100+
the``entity_type`` is 'view' or 'routine', the ``entity_id`` is a ``dict``
101+
representing the view or routine from a different dataset to grant access
102+
to in the following format for views::
102103
103104
{
104105
'projectId': string,
@@ -114,11 +115,22 @@ class AccessEntry(object):
114115
'routineId': string
115116
}
116117
118+
If the ``entity_type`` is 'dataset', the ``entity_id`` is a ``dict`` that includes
119+
a 'dataset' field with a ``dict`` representing the dataset and a 'target_types'
120+
field with a ``str`` value of the dataset's resource type::
121+
122+
{
123+
'dataset': {
124+
'projectId': string,
125+
'datasetId': string,
126+
},
127+
'target_types: 'VIEWS'
128+
}
129+
117130
Raises:
118131
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.
132+
If a ``view``, ``routine``, or ``dataset`` has ``role`` set, or a non ``view``,
133+
non ``routine``, and non ``dataset`` **does not** have a ``role`` set.
122134
123135
Examples:
124136
>>> entry = AccessEntry('OWNER', 'userByEmail', 'user@example.com')
@@ -131,27 +143,9 @@ class AccessEntry(object):
131143
>>> entry = AccessEntry(None, 'view', view)
132144
"""
133145

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):
148-
ifentity_typenotinself.ENTITY_TYPES:
149-
message="Entity type %r not among: %s"% (
150-
entity_type,
151-
", ".join(self.ENTITY_TYPES),
152-
)
153-
raiseValueError(message)
154-
ifentity_typein ("view","routine"):
146+
def__init__(self,role=None,entity_type=None,entity_id=None):
147+
self._properties= {}
148+
ifentity_typein ("view","routine","dataset"):
155149
ifroleisnotNone:
156150
raiseValueError(
157151
"Role must be None for a %r. Received "
@@ -162,7 +156,6 @@ def __init__(self, role, entity_type, entity_id):
162156
raiseValueError(
163157
"Role must be set for entity ""type %r"% (entity_type,)
164158
)
165-
166159
self._role=role
167160
self._entity_type=entity_type
168161
self._entity_id=entity_id
@@ -214,7 +207,8 @@ def to_api_repr(self):
214207
Returns:
215208
Dict[str, object]: Access entry represented as an API resource
216209
"""
217-
resource= {self._entity_type:self._entity_id}
210+
resource=copy.deepcopy(self._properties)
211+
resource[self._entity_type]=self._entity_id
218212
ifself._roleisnotNone:
219213
resource["role"]=self._role
220214
returnresource
@@ -241,7 +235,10 @@ def from_api_repr(cls, resource: dict) -> "AccessEntry":
241235
entity_type,entity_id=entry.popitem()
242236
iflen(entry)!=0:
243237
raiseValueError("Entry has unexpected keys remaining.",entry)
244-
returncls(role,entity_type,entity_id)
238+
239+
config=cls(role,entity_type,entity_id)
240+
config._properties=copy.deepcopy(resource)
241+
returnconfig
245242

246243

247244
classDatasetReference(object):

‎google/cloud/bigquery/enums.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,19 @@ def _make_sql_scalars_enum():
232232
StandardSqlDataTypes=_make_sql_scalars_enum()
233233

234234

235+
classEntityTypes(str,enum.Enum):
236+
"""Enum of allowed entity type names in AccessEntry"""
237+
238+
USER_BY_EMAIL="userByEmail"
239+
GROUP_BY_EMAIL="groupByEmail"
240+
DOMAIN="domain"
241+
DATASET="dataset"
242+
SPECIAL_GROUP="specialGroup"
243+
VIEW="view"
244+
IAM_MEMBER="iamMember"
245+
ROUTINE="routine"
246+
247+
235248
# See also: https://cloud.google.com/bigquery/data-types#legacy_sql_data_types
236249
# and https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types
237250
classSqlTypeNames(str,enum.Enum):

‎samples/snippets/authorized_view_tutorial.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def run_authorized_view_tutorial(override_values={}):
2424
# Create a source dataset
2525
# [START bigquery_avt_create_source_dataset]
2626
fromgoogle.cloudimportbigquery
27+
fromgoogle.cloud.bigquery.enumsimportEntityTypes
2728

2829
client=bigquery.Client()
2930
source_dataset_id="github_source_data"
@@ -106,7 +107,7 @@ def run_authorized_view_tutorial(override_values={}):
106107
# analyst_group_email = 'data_analysts@example.com'
107108
access_entries=shared_dataset.access_entries
108109
access_entries.append(
109-
bigquery.AccessEntry("READER","groupByEmail",analyst_group_email)
110+
bigquery.AccessEntry("READER",EntityTypes.GROUP_BY_EMAIL,analyst_group_email)
110111
)
111112
shared_dataset.access_entries=access_entries
112113
shared_dataset=client.update_dataset(
@@ -118,7 +119,7 @@ def run_authorized_view_tutorial(override_values={}):
118119
# [START bigquery_avt_source_dataset_access]
119120
access_entries=source_dataset.access_entries
120121
access_entries.append(
121-
bigquery.AccessEntry(None,"view",view.reference.to_api_repr())
122+
bigquery.AccessEntry(None,EntityTypes.VIEW,view.reference.to_api_repr())
122123
)
123124
source_dataset.access_entries=access_entries
124125
source_dataset=client.update_dataset(

‎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):
2727
# of the entity, such as a view's table reference.
2828
entity_id="user-or-group-to-add@example.com"
2929

30+
fromgoogle.cloud.bigquery.enumsimportEntityTypes
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):
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:

‎tests/unit/test_dataset.py‎

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,28 @@ def test_to_api_repr_routine(self):
141141
exp_resource= {"routine":routine}
142142
self.assertEqual(resource,exp_resource)
143143

144+
deftest_to_api_repr_dataset(self):
145+
dataset= {
146+
"dataset": {"projectId":"my-project","datasetId":"my_dataset"},
147+
"target_types":"VIEWS",
148+
}
149+
entry=self._make_one(None,"dataset",dataset)
150+
resource=entry.to_api_repr()
151+
exp_resource= {"dataset":dataset}
152+
self.assertEqual(resource,exp_resource)
153+
154+
deftest_to_api_w_incorrect_role(self):
155+
dataset= {
156+
"dataset": {
157+
"projectId":"my-project",
158+
"datasetId":"my_dataset",
159+
"tableId":"my_table",
160+
},
161+
"target_type":"VIEW",
162+
}
163+
withself.assertRaises(ValueError):
164+
self._make_one("READER","dataset",dataset)
165+
144166
deftest_from_api_repr(self):
145167
resource= {"role":"OWNER","userByEmail":"salmon@example.com"}
146168
entry=self._get_target_class().from_api_repr(resource)
@@ -150,8 +172,22 @@ def test_from_api_repr(self):
150172

151173
deftest_from_api_repr_w_unknown_entity_type(self):
152174
resource= {"role":"READER","unknown":"UNKNOWN"}
153-
withself.assertRaises(ValueError):
154-
self._get_target_class().from_api_repr(resource)
175+
entry=self._get_target_class().from_api_repr(resource)
176+
self.assertEqual(entry.role,"READER")
177+
self.assertEqual(entry.entity_type,"unknown")
178+
self.assertEqual(entry.entity_id,"UNKNOWN")
179+
exp_resource=entry.to_api_repr()
180+
self.assertEqual(resource,exp_resource)
181+
182+
deftest_to_api_repr_w_extra_properties(self):
183+
resource= {
184+
"role":"READER",
185+
"userByEmail":"salmon@example.com",
186+
}
187+
entry=self._get_target_class().from_api_repr(resource)
188+
entry._properties["specialGroup"]=resource["specialGroup"]="projectReaders"
189+
exp_resource=entry.to_api_repr()
190+
self.assertEqual(resource,exp_resource)
155191

156192
deftest_from_api_repr_entries_w_extra_keys(self):
157193
resource= {

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp