1# -*- coding: utf-8 -*-
2#
3# Copyright 2019 Google LLC
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# https://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""Define resources for the BigQuery Routines API."""
18import typing
19from typing import Any, Dict, Optional, Union
20
21import google.cloud._helpers # type: ignore
22from google.cloud.bigquery import _helpers
23from google.cloud.bigquery.standard_sql import StandardSqlDataType
24from google.cloud.bigquery.standard_sql import StandardSqlTableType
25
26
27class RoutineType:
28 """The fine-grained type of the routine.
29
30 https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#routinetype
31
32 .. versionadded:: 2.22.0
33 """
34
35 ROUTINE_TYPE_UNSPECIFIED = "ROUTINE_TYPE_UNSPECIFIED"
36 SCALAR_FUNCTION = "SCALAR_FUNCTION"
37 PROCEDURE = "PROCEDURE"
38 TABLE_VALUED_FUNCTION = "TABLE_VALUED_FUNCTION"
39
40
41class Routine(object):
42 """Resource representing a user-defined routine.
43
44 See
45 https://cloud.google.com/bigquery/docs/reference/rest/v2/routines
46
47 Args:
48 routine_ref (Union[str, google.cloud.bigquery.routine.RoutineReference]):
49 A pointer to a routine. If ``routine_ref`` is a string, it must
50 included a project ID, dataset ID, and routine ID, each separated
51 by ``.``.
52 ``**kwargs`` (Dict):
53 Initial property values.
54 """
55
56 _PROPERTY_TO_API_FIELD = {
57 "arguments": "arguments",
58 "body": "definitionBody",
59 "created": "creationTime",
60 "etag": "etag",
61 "imported_libraries": "importedLibraries",
62 "language": "language",
63 "modified": "lastModifiedTime",
64 "reference": "routineReference",
65 "return_type": "returnType",
66 "return_table_type": "returnTableType",
67 "type_": "routineType",
68 "description": "description",
69 "determinism_level": "determinismLevel",
70 "remote_function_options": "remoteFunctionOptions",
71 "data_governance_type": "dataGovernanceType",
72 "external_runtime_options": "externalRuntimeOptions",
73 }
74
75 def __init__(self, routine_ref, **kwargs) -> None:
76 if isinstance(routine_ref, str):
77 routine_ref = RoutineReference.from_string(routine_ref)
78
79 self._properties = {"routineReference": routine_ref.to_api_repr()}
80 for property_name in kwargs:
81 setattr(self, property_name, kwargs[property_name])
82
83 @property
84 def reference(self):
85 """google.cloud.bigquery.routine.RoutineReference: Reference
86 describing the ID of this routine.
87 """
88 return RoutineReference.from_api_repr(
89 self._properties[self._PROPERTY_TO_API_FIELD["reference"]]
90 )
91
92 @property
93 def path(self):
94 """str: URL path for the routine's APIs."""
95 return self.reference.path
96
97 @property
98 def project(self):
99 """str: ID of the project containing the routine."""
100 return self.reference.project
101
102 @property
103 def dataset_id(self):
104 """str: ID of dataset containing the routine."""
105 return self.reference.dataset_id
106
107 @property
108 def routine_id(self):
109 """str: The routine ID."""
110 return self.reference.routine_id
111
112 @property
113 def etag(self):
114 """str: ETag for the resource (:data:`None` until set from the
115 server).
116
117 Read-only.
118 """
119 return self._properties.get(self._PROPERTY_TO_API_FIELD["etag"])
120
121 @property
122 def type_(self):
123 """str: The fine-grained type of the routine.
124
125 See:
126 https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#RoutineType
127 """
128 return self._properties.get(self._PROPERTY_TO_API_FIELD["type_"])
129
130 @type_.setter
131 def type_(self, value):
132 self._properties[self._PROPERTY_TO_API_FIELD["type_"]] = value
133
134 @property
135 def created(self):
136 """Optional[datetime.datetime]: Datetime at which the routine was
137 created (:data:`None` until set from the server).
138
139 Read-only.
140 """
141 value = self._properties.get(self._PROPERTY_TO_API_FIELD["created"])
142 if value is not None and value != 0:
143 # value will be in milliseconds.
144 return google.cloud._helpers._datetime_from_microseconds(
145 1000.0 * float(value)
146 )
147
148 @property
149 def modified(self):
150 """Optional[datetime.datetime]: Datetime at which the routine was
151 last modified (:data:`None` until set from the server).
152
153 Read-only.
154 """
155 value = self._properties.get(self._PROPERTY_TO_API_FIELD["modified"])
156 if value is not None and value != 0:
157 # value will be in milliseconds.
158 return google.cloud._helpers._datetime_from_microseconds(
159 1000.0 * float(value)
160 )
161
162 @property
163 def language(self):
164 """Optional[str]: The language of the routine.
165
166 Defaults to ``SQL``.
167 """
168 return self._properties.get(self._PROPERTY_TO_API_FIELD["language"])
169
170 @language.setter
171 def language(self, value):
172 self._properties[self._PROPERTY_TO_API_FIELD["language"]] = value
173
174 @property
175 def arguments(self):
176 """List[google.cloud.bigquery.routine.RoutineArgument]: Input/output
177 argument of a function or a stored procedure.
178
179 In-place modification is not supported. To set, replace the entire
180 property value with the modified list of
181 :class:`~google.cloud.bigquery.routine.RoutineArgument` objects.
182 """
183 resources = self._properties.get(self._PROPERTY_TO_API_FIELD["arguments"], [])
184 return [RoutineArgument.from_api_repr(resource) for resource in resources]
185
186 @arguments.setter
187 def arguments(self, value):
188 if not value:
189 resource = []
190 else:
191 resource = [argument.to_api_repr() for argument in value]
192 self._properties[self._PROPERTY_TO_API_FIELD["arguments"]] = resource
193
194 @property
195 def return_type(self):
196 """google.cloud.bigquery.StandardSqlDataType: Return type of
197 the routine.
198
199 If absent, the return type is inferred from
200 :attr:`~google.cloud.bigquery.routine.Routine.body` at query time in
201 each query that references this routine. If present, then the
202 evaluated result will be cast to the specified returned type at query
203 time.
204
205 See:
206 https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#Routine.FIELDS.return_type
207 """
208 resource = self._properties.get(self._PROPERTY_TO_API_FIELD["return_type"])
209 if not resource:
210 return resource
211
212 return StandardSqlDataType.from_api_repr(resource)
213
214 @return_type.setter
215 def return_type(self, value: StandardSqlDataType):
216 resource = None if not value else value.to_api_repr()
217 self._properties[self._PROPERTY_TO_API_FIELD["return_type"]] = resource
218
219 @property
220 def return_table_type(self) -> Union[StandardSqlTableType, Any, None]:
221 """The return type of a Table Valued Function (TVF) routine.
222
223 .. versionadded:: 2.22.0
224 """
225 resource = self._properties.get(
226 self._PROPERTY_TO_API_FIELD["return_table_type"]
227 )
228 if not resource:
229 return resource
230
231 return StandardSqlTableType.from_api_repr(resource)
232
233 @return_table_type.setter
234 def return_table_type(self, value: Optional[StandardSqlTableType]):
235 if not value:
236 resource = None
237 else:
238 resource = value.to_api_repr()
239
240 self._properties[self._PROPERTY_TO_API_FIELD["return_table_type"]] = resource
241
242 @property
243 def imported_libraries(self):
244 """List[str]: The path of the imported JavaScript libraries.
245
246 The :attr:`~google.cloud.bigquery.routine.Routine.language` must
247 equal ``JAVACRIPT``.
248
249 Examples:
250 Set the ``imported_libraries`` to a list of Google Cloud Storage
251 URIs.
252
253 .. code-block:: python
254
255 routine = bigquery.Routine("proj.dataset.routine_id")
256 routine.imported_libraries = [
257 "gs://cloud-samples-data/bigquery/udfs/max-value.js",
258 ]
259 """
260 return self._properties.get(
261 self._PROPERTY_TO_API_FIELD["imported_libraries"], []
262 )
263
264 @imported_libraries.setter
265 def imported_libraries(self, value):
266 if not value:
267 resource = []
268 else:
269 resource = value
270 self._properties[self._PROPERTY_TO_API_FIELD["imported_libraries"]] = resource
271
272 @property
273 def body(self):
274 """str: The body of the routine."""
275 return self._properties.get(self._PROPERTY_TO_API_FIELD["body"])
276
277 @body.setter
278 def body(self, value):
279 self._properties[self._PROPERTY_TO_API_FIELD["body"]] = value
280
281 @property
282 def description(self):
283 """Optional[str]: Description of the routine (defaults to
284 :data:`None`).
285 """
286 return self._properties.get(self._PROPERTY_TO_API_FIELD["description"])
287
288 @description.setter
289 def description(self, value):
290 self._properties[self._PROPERTY_TO_API_FIELD["description"]] = value
291
292 @property
293 def determinism_level(self):
294 """Optional[str]: (experimental) The determinism level of the JavaScript UDF
295 if defined.
296 """
297 return self._properties.get(self._PROPERTY_TO_API_FIELD["determinism_level"])
298
299 @determinism_level.setter
300 def determinism_level(self, value):
301 self._properties[self._PROPERTY_TO_API_FIELD["determinism_level"]] = value
302
303 @property
304 def remote_function_options(self):
305 """Optional[google.cloud.bigquery.routine.RemoteFunctionOptions]:
306 Configures remote function options for a routine.
307
308 Raises:
309 ValueError:
310 If the value is not
311 :class:`~google.cloud.bigquery.routine.RemoteFunctionOptions` or
312 :data:`None`.
313 """
314 prop = self._properties.get(
315 self._PROPERTY_TO_API_FIELD["remote_function_options"]
316 )
317 if prop is not None:
318 return RemoteFunctionOptions.from_api_repr(prop)
319
320 @remote_function_options.setter
321 def remote_function_options(self, value):
322 api_repr = value
323 if isinstance(value, RemoteFunctionOptions):
324 api_repr = value.to_api_repr()
325 elif value is not None:
326 raise ValueError(
327 "value must be google.cloud.bigquery.routine.RemoteFunctionOptions "
328 "or None"
329 )
330 self._properties[
331 self._PROPERTY_TO_API_FIELD["remote_function_options"]
332 ] = api_repr
333
334 @property
335 def data_governance_type(self):
336 """Optional[str]: If set to ``DATA_MASKING``, the function is validated
337 and made available as a masking function.
338
339 Raises:
340 ValueError:
341 If the value is not :data:`string` or :data:`None`.
342 """
343 return self._properties.get(self._PROPERTY_TO_API_FIELD["data_governance_type"])
344
345 @data_governance_type.setter
346 def data_governance_type(self, value):
347 if value is not None and not isinstance(value, str):
348 raise ValueError(
349 "invalid data_governance_type, must be a string or `None`."
350 )
351 self._properties[self._PROPERTY_TO_API_FIELD["data_governance_type"]] = value
352
353 @property
354 def external_runtime_options(self):
355 """Optional[google.cloud.bigquery.routine.ExternalRuntimeOptions]:
356 Configures the external runtime options for a routine.
357
358 Raises:
359 ValueError:
360 If the value is not
361 :class:`~google.cloud.bigquery.routine.ExternalRuntimeOptions` or
362 :data:`None`.
363 """
364 prop = self._properties.get(
365 self._PROPERTY_TO_API_FIELD["external_runtime_options"]
366 )
367 if prop is not None:
368 return ExternalRuntimeOptions.from_api_repr(prop)
369
370 @external_runtime_options.setter
371 def external_runtime_options(self, value):
372 api_repr = value
373 if isinstance(value, ExternalRuntimeOptions):
374 api_repr = value.to_api_repr()
375 elif value is not None:
376 raise ValueError(
377 "value must be google.cloud.bigquery.routine.ExternalRuntimeOptions "
378 "or None"
379 )
380 self._properties[
381 self._PROPERTY_TO_API_FIELD["external_runtime_options"]
382 ] = api_repr
383
384 @classmethod
385 def from_api_repr(cls, resource: dict) -> "Routine":
386 """Factory: construct a routine given its API representation.
387
388 Args:
389 resource (Dict[str, object]):
390 Resource, as returned from the API.
391
392 Returns:
393 google.cloud.bigquery.routine.Routine:
394 Python object, as parsed from ``resource``.
395 """
396 ref = cls(RoutineReference.from_api_repr(resource["routineReference"]))
397 ref._properties = resource
398 return ref
399
400 def to_api_repr(self) -> dict:
401 """Construct the API resource representation of this routine.
402
403 Returns:
404 Dict[str, object]: Routine represented as an API resource.
405 """
406 return self._properties
407
408 def _build_resource(self, filter_fields):
409 """Generate a resource for ``update``."""
410 return _helpers._build_resource_from_properties(self, filter_fields)
411
412 def __repr__(self):
413 return "Routine('{}.{}.{}')".format(
414 self.project, self.dataset_id, self.routine_id
415 )
416
417
418class RoutineArgument(object):
419 """Input/output argument of a function or a stored procedure.
420
421 See:
422 https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#argument
423
424 Args:
425 ``**kwargs`` (Dict):
426 Initial property values.
427 """
428
429 _PROPERTY_TO_API_FIELD = {
430 "data_type": "dataType",
431 "kind": "argumentKind",
432 # Even though it's not necessary for field mapping to map when the
433 # property name equals the resource name, we add these here so that we
434 # have an exhaustive list of all properties.
435 "name": "name",
436 "mode": "mode",
437 }
438
439 def __init__(self, **kwargs) -> None:
440 self._properties: Dict[str, Any] = {}
441 for property_name in kwargs:
442 setattr(self, property_name, kwargs[property_name])
443
444 @property
445 def name(self):
446 """Optional[str]: Name of this argument.
447
448 Can be absent for function return argument.
449 """
450 return self._properties.get(self._PROPERTY_TO_API_FIELD["name"])
451
452 @name.setter
453 def name(self, value):
454 self._properties[self._PROPERTY_TO_API_FIELD["name"]] = value
455
456 @property
457 def kind(self):
458 """Optional[str]: The kind of argument, for example ``FIXED_TYPE`` or
459 ``ANY_TYPE``.
460
461 See:
462 https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#Argument.FIELDS.argument_kind
463 """
464 return self._properties.get(self._PROPERTY_TO_API_FIELD["kind"])
465
466 @kind.setter
467 def kind(self, value):
468 self._properties[self._PROPERTY_TO_API_FIELD["kind"]] = value
469
470 @property
471 def mode(self):
472 """Optional[str]: The input/output mode of the argument."""
473 return self._properties.get(self._PROPERTY_TO_API_FIELD["mode"])
474
475 @mode.setter
476 def mode(self, value):
477 self._properties[self._PROPERTY_TO_API_FIELD["mode"]] = value
478
479 @property
480 def data_type(self):
481 """Optional[google.cloud.bigquery.StandardSqlDataType]: Type
482 of a variable, e.g., a function argument.
483
484 See:
485 https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#Argument.FIELDS.data_type
486 """
487 resource = self._properties.get(self._PROPERTY_TO_API_FIELD["data_type"])
488 if not resource:
489 return resource
490
491 return StandardSqlDataType.from_api_repr(resource)
492
493 @data_type.setter
494 def data_type(self, value):
495 if value:
496 resource = value.to_api_repr()
497 else:
498 resource = None
499 self._properties[self._PROPERTY_TO_API_FIELD["data_type"]] = resource
500
501 @classmethod
502 def from_api_repr(cls, resource: dict) -> "RoutineArgument":
503 """Factory: construct a routine argument given its API representation.
504
505 Args:
506 resource (Dict[str, object]): Resource, as returned from the API.
507
508 Returns:
509 google.cloud.bigquery.routine.RoutineArgument:
510 Python object, as parsed from ``resource``.
511 """
512 ref = cls()
513 ref._properties = resource
514 return ref
515
516 def to_api_repr(self) -> dict:
517 """Construct the API resource representation of this routine argument.
518
519 Returns:
520 Dict[str, object]: Routine argument represented as an API resource.
521 """
522 return self._properties
523
524 def __eq__(self, other):
525 if not isinstance(other, RoutineArgument):
526 return NotImplemented
527 return self._properties == other._properties
528
529 def __ne__(self, other):
530 return not self == other
531
532 def __repr__(self):
533 all_properties = [
534 "{}={}".format(property_name, repr(getattr(self, property_name)))
535 for property_name in sorted(self._PROPERTY_TO_API_FIELD)
536 ]
537 return "RoutineArgument({})".format(", ".join(all_properties))
538
539
540class RoutineReference(object):
541 """A pointer to a routine.
542
543 See:
544 https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#routinereference
545 """
546
547 def __init__(self):
548 self._properties = {}
549
550 @property
551 def project(self):
552 """str: ID of the project containing the routine."""
553 return self._properties.get("projectId", "")
554
555 @property
556 def dataset_id(self):
557 """str: ID of dataset containing the routine."""
558 return self._properties.get("datasetId", "")
559
560 @property
561 def routine_id(self):
562 """str: The routine ID."""
563 return self._properties.get("routineId", "")
564
565 @property
566 def path(self):
567 """str: URL path for the routine's APIs."""
568 return "/projects/%s/datasets/%s/routines/%s" % (
569 self.project,
570 self.dataset_id,
571 self.routine_id,
572 )
573
574 @classmethod
575 def from_api_repr(cls, resource: dict) -> "RoutineReference":
576 """Factory: construct a routine reference given its API representation.
577
578 Args:
579 resource (Dict[str, object]):
580 Routine reference representation returned from the API.
581
582 Returns:
583 google.cloud.bigquery.routine.RoutineReference:
584 Routine reference parsed from ``resource``.
585 """
586 ref = cls()
587 ref._properties = resource
588 return ref
589
590 @classmethod
591 def from_string(
592 cls, routine_id: str, default_project: Optional[str] = None
593 ) -> "RoutineReference":
594 """Factory: construct a routine reference from routine ID string.
595
596 Args:
597 routine_id (str):
598 A routine ID in standard SQL format. If ``default_project``
599 is not specified, this must included a project ID, dataset
600 ID, and routine ID, each separated by ``.``.
601 default_project (Optional[str]):
602 The project ID to use when ``routine_id`` does not
603 include a project ID.
604
605 Returns:
606 google.cloud.bigquery.routine.RoutineReference:
607 Routine reference parsed from ``routine_id``.
608
609 Raises:
610 ValueError:
611 If ``routine_id`` is not a fully-qualified routine ID in
612 standard SQL format.
613 """
614 proj, dset, routine = _helpers._parse_3_part_id(
615 routine_id, default_project=default_project, property_name="routine_id"
616 )
617 return cls.from_api_repr(
618 {"projectId": proj, "datasetId": dset, "routineId": routine}
619 )
620
621 def to_api_repr(self) -> dict:
622 """Construct the API resource representation of this routine reference.
623
624 Returns:
625 Dict[str, object]: Routine reference represented as an API resource.
626 """
627 return self._properties
628
629 def __eq__(self, other):
630 """Two RoutineReferences are equal if they point to the same routine."""
631 if not isinstance(other, RoutineReference):
632 return NotImplemented
633 return str(self) == str(other)
634
635 def __hash__(self):
636 return hash(str(self))
637
638 def __ne__(self, other):
639 return not self == other
640
641 def __repr__(self):
642 return "RoutineReference.from_string('{}')".format(str(self))
643
644 def __str__(self):
645 """String representation of the reference.
646
647 This is a fully-qualified ID, including the project ID and dataset ID.
648 """
649 return "{}.{}.{}".format(self.project, self.dataset_id, self.routine_id)
650
651
652class RemoteFunctionOptions(object):
653 """Configuration options for controlling remote BigQuery functions."""
654
655 _PROPERTY_TO_API_FIELD = {
656 "endpoint": "endpoint",
657 "connection": "connection",
658 "max_batching_rows": "maxBatchingRows",
659 "user_defined_context": "userDefinedContext",
660 }
661
662 def __init__(
663 self,
664 endpoint=None,
665 connection=None,
666 max_batching_rows=None,
667 user_defined_context=None,
668 _properties=None,
669 ) -> None:
670 if _properties is None:
671 _properties = {}
672 self._properties = _properties
673
674 if endpoint is not None:
675 self.endpoint = endpoint
676 if connection is not None:
677 self.connection = connection
678 if max_batching_rows is not None:
679 self.max_batching_rows = max_batching_rows
680 if user_defined_context is not None:
681 self.user_defined_context = user_defined_context
682
683 @property
684 def connection(self):
685 """string: Fully qualified name of the user-provided connection object which holds the authentication information to send requests to the remote service.
686
687 Format is "projects/{projectId}/locations/{locationId}/connections/{connectionId}"
688 """
689 return _helpers._str_or_none(self._properties.get("connection"))
690
691 @connection.setter
692 def connection(self, value):
693 self._properties["connection"] = _helpers._str_or_none(value)
694
695 @property
696 def endpoint(self):
697 """string: Endpoint of the user-provided remote service
698
699 Example: "https://us-east1-my_gcf_project.cloudfunctions.net/remote_add"
700 """
701 return _helpers._str_or_none(self._properties.get("endpoint"))
702
703 @endpoint.setter
704 def endpoint(self, value):
705 self._properties["endpoint"] = _helpers._str_or_none(value)
706
707 @property
708 def max_batching_rows(self):
709 """int64: Max number of rows in each batch sent to the remote service.
710
711 If absent or if 0, BigQuery dynamically decides the number of rows in a batch.
712 """
713 return _helpers._int_or_none(self._properties.get("maxBatchingRows"))
714
715 @max_batching_rows.setter
716 def max_batching_rows(self, value):
717 self._properties["maxBatchingRows"] = _helpers._str_or_none(value)
718
719 @property
720 def user_defined_context(self):
721 """Dict[str, str]: User-defined context as a set of key/value pairs,
722 which will be sent as function invocation context together with
723 batched arguments in the requests to the remote service. The total
724 number of bytes of keys and values must be less than 8KB.
725 """
726 return self._properties.get("userDefinedContext")
727
728 @user_defined_context.setter
729 def user_defined_context(self, value):
730 if not isinstance(value, dict):
731 raise ValueError("value must be dictionary")
732 self._properties["userDefinedContext"] = value
733
734 @classmethod
735 def from_api_repr(cls, resource: dict) -> "RemoteFunctionOptions":
736 """Factory: construct remote function options given its API representation.
737
738 Args:
739 resource (Dict[str, object]): Resource, as returned from the API.
740
741 Returns:
742 google.cloud.bigquery.routine.RemoteFunctionOptions:
743 Python object, as parsed from ``resource``.
744 """
745 ref = cls()
746 ref._properties = resource
747 return ref
748
749 def to_api_repr(self) -> dict:
750 """Construct the API resource representation of this RemoteFunctionOptions.
751
752 Returns:
753 Dict[str, object]: Remote function options represented as an API resource.
754 """
755 return self._properties
756
757 def __eq__(self, other):
758 if not isinstance(other, RemoteFunctionOptions):
759 return NotImplemented
760 return self._properties == other._properties
761
762 def __ne__(self, other):
763 return not self == other
764
765 def __repr__(self):
766 all_properties = [
767 "{}={}".format(property_name, repr(getattr(self, property_name)))
768 for property_name in sorted(self._PROPERTY_TO_API_FIELD)
769 ]
770 return "RemoteFunctionOptions({})".format(", ".join(all_properties))
771
772
773class ExternalRuntimeOptions(object):
774 """Options for the runtime of the external system.
775
776 Args:
777 container_memory (str):
778 Optional. Amount of memory provisioned for a Python UDF container
779 instance. Format: {number}{unit} where unit is one of "M", "G", "Mi"
780 and "Gi" (e.g. 1G, 512Mi). If not specified, the default value is
781 512Mi. For more information, see `Configure container limits for
782 Python UDFs <https://cloud.google.com/bigquery/docs/user-defined-functions-python#configure-container-limits>`_
783 container_cpu (int):
784 Optional. Amount of CPU provisioned for a Python UDF container
785 instance. For more information, see `Configure container limits
786 for Python UDFs <https://cloud.google.com/bigquery/docs/user-defined-functions-python#configure-container-limits>`_
787 runtime_connection (str):
788 Optional. Fully qualified name of the connection whose service account
789 will be used to execute the code in the container. Format:
790 "projects/{projectId}/locations/{locationId}/connections/{connectionId}"
791 max_batching_rows (int):
792 Optional. Maximum number of rows in each batch sent to the external
793 runtime. If absent or if 0, BigQuery dynamically decides the number of
794 rows in a batch.
795 runtime_version (str):
796 Optional. Language runtime version. Example: python-3.11.
797 """
798
799 _PROPERTY_TO_API_FIELD = {
800 "container_memory": "containerMemory",
801 "container_cpu": "containerCpu",
802 "runtime_connection": "runtimeConnection",
803 "max_batching_rows": "maxBatchingRows",
804 "runtime_version": "runtimeVersion",
805 }
806
807 def __init__(
808 self,
809 container_memory: Optional[str] = None,
810 container_cpu: Optional[int] = None,
811 runtime_connection: Optional[str] = None,
812 max_batching_rows: Optional[int] = None,
813 runtime_version: Optional[str] = None,
814 _properties: Optional[Dict] = None,
815 ) -> None:
816 if _properties is None:
817 _properties = {}
818 self._properties = _properties
819
820 if container_memory is not None:
821 self.container_memory = container_memory
822 if container_cpu is not None:
823 self.container_cpu = container_cpu
824 if runtime_connection is not None:
825 self.runtime_connection = runtime_connection
826 if max_batching_rows is not None:
827 self.max_batching_rows = max_batching_rows
828 if runtime_version is not None:
829 self.runtime_version = runtime_version
830
831 @property
832 def container_memory(self) -> Optional[str]:
833 """Optional. Amount of memory provisioned for a Python UDF container instance."""
834 return _helpers._str_or_none(self._properties.get("containerMemory"))
835
836 @container_memory.setter
837 def container_memory(self, value: Optional[str]):
838 if value is not None and not isinstance(value, str):
839 raise ValueError("container_memory must be a string or None.")
840 self._properties["containerMemory"] = value
841
842 @property
843 def container_cpu(self) -> Optional[int]:
844 """Optional. Amount of CPU provisioned for a Python UDF container instance."""
845 return _helpers._int_or_none(self._properties.get("containerCpu"))
846
847 @container_cpu.setter
848 def container_cpu(self, value: Optional[int]):
849 if value is not None and not isinstance(value, int):
850 raise ValueError("container_cpu must be an integer or None.")
851 self._properties["containerCpu"] = value
852
853 @property
854 def runtime_connection(self) -> Optional[str]:
855 """Optional. Fully qualified name of the connection."""
856 return _helpers._str_or_none(self._properties.get("runtimeConnection"))
857
858 @runtime_connection.setter
859 def runtime_connection(self, value: Optional[str]):
860 if value is not None and not isinstance(value, str):
861 raise ValueError("runtime_connection must be a string or None.")
862 self._properties["runtimeConnection"] = value
863
864 @property
865 def max_batching_rows(self) -> Optional[int]:
866 """Optional. Maximum number of rows in each batch sent to the external runtime."""
867 return typing.cast(
868 int, _helpers._int_or_none(self._properties.get("maxBatchingRows"))
869 )
870
871 @max_batching_rows.setter
872 def max_batching_rows(self, value: Optional[int]):
873 if value is not None and not isinstance(value, int):
874 raise ValueError("max_batching_rows must be an integer or None.")
875 self._properties["maxBatchingRows"] = _helpers._str_or_none(value)
876
877 @property
878 def runtime_version(self) -> Optional[str]:
879 """Optional. Language runtime version."""
880 return _helpers._str_or_none(self._properties.get("runtimeVersion"))
881
882 @runtime_version.setter
883 def runtime_version(self, value: Optional[str]):
884 if value is not None and not isinstance(value, str):
885 raise ValueError("runtime_version must be a string or None.")
886 self._properties["runtimeVersion"] = value
887
888 @classmethod
889 def from_api_repr(cls, resource: dict) -> "ExternalRuntimeOptions":
890 """Factory: construct external runtime options given its API representation.
891 Args:
892 resource (Dict[str, object]): Resource, as returned from the API.
893 Returns:
894 google.cloud.bigquery.routine.ExternalRuntimeOptions:
895 Python object, as parsed from ``resource``.
896 """
897 ref = cls()
898 ref._properties = resource
899 return ref
900
901 def to_api_repr(self) -> dict:
902 """Construct the API resource representation of this ExternalRuntimeOptions.
903 Returns:
904 Dict[str, object]: External runtime options represented as an API resource.
905 """
906 return self._properties
907
908 def __eq__(self, other):
909 if not isinstance(other, ExternalRuntimeOptions):
910 return NotImplemented
911 return self._properties == other._properties
912
913 def __ne__(self, other):
914 return not self == other
915
916 def __repr__(self):
917 all_properties = [
918 "{}={}".format(property_name, repr(getattr(self, property_name)))
919 for property_name in sorted(self._PROPERTY_TO_API_FIELD)
920 ]
921 return "ExternalRuntimeOptions({})".format(", ".join(all_properties))