@@ -77,28 +77,29 @@ def _get_routine_reference(self, routine_id):
77
77
class AccessEntry (object ):
78
78
"""Represents grant of an access role to an entity.
79
79
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`. If anything but ``view``, ``routine``,
82
+ or ``dataset `` are set, a ``role `` is also required. ``role`` is omitted for ``view``,
83
+ ``routine``, ``dataset``, because they are always read-only.
84
84
85
85
See https://cloud.google.com/bigquery/docs/reference/rest/v2/datasets.
86
86
87
87
Args:
88
88
role (str):
89
89
Role granted to the entity. The following string values are
90
90
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 ``.
92
92
93
93
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.
95
96
96
97
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::
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::
102
103
103
104
{
104
105
'projectId': string,
@@ -114,11 +115,22 @@ class AccessEntry(object):
114
115
'routineId': string
115
116
}
116
117
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
+
117
130
Raises:
118
131
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.
122
134
123
135
Examples:
124
136
>>> entry = AccessEntry('OWNER', 'userByEmail', '[email protected] ')
@@ -131,27 +143,9 @@ class AccessEntry(object):
131
143
>>> entry = AccessEntry(None, 'view', view)
132
144
"""
133
145
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
- 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" ):
146
+ def __init__ (self , role = None , entity_type = None , entity_id = None ):
147
+ self ._properties = {}
148
+ if entity_type in ("view" , "routine" , "dataset" ):
155
149
if role is not None :
156
150
raise ValueError (
157
151
"Role must be None for a %r. Received "
@@ -162,7 +156,6 @@ def __init__(self, role, entity_type, entity_id):
162
156
raise ValueError (
163
157
"Role must be set for entity " "type %r" % (entity_type ,)
164
158
)
165
-
166
159
self ._role = role
167
160
self ._entity_type = entity_type
168
161
self ._entity_id = entity_id
@@ -214,7 +207,8 @@ def to_api_repr(self):
214
207
Returns:
215
208
Dict[str, object]: Access entry represented as an API resource
216
209
"""
217
- resource = {self ._entity_type : self ._entity_id }
210
+ resource = copy .deepcopy (self ._properties )
211
+ resource [self ._entity_type ] = self ._entity_id
218
212
if self ._role is not None :
219
213
resource ["role" ] = self ._role
220
214
return resource
@@ -241,7 +235,10 @@ def from_api_repr(cls, resource: dict) -> "AccessEntry":
241
235
entity_type , entity_id = entry .popitem ()
242
236
if len (entry ) != 0 :
243
237
raise ValueError ("Entry has unexpected keys remaining." , entry )
244
- return cls (role , entity_type , entity_id )
238
+
239
+ config = cls (role , entity_type , entity_id )
240
+ config ._properties = copy .deepcopy (resource )
241
+ return config
245
242
246
243
247
244
class DatasetReference (object ):
0 commit comments