Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/google/cloud/bigquery/routine/routine.py: 50%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

297 statements  

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.""" 

18 

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 } 

73 

74 def __init__(self, routine_ref, **kwargs) -> None: 

75 if isinstance(routine_ref, str): 

76 routine_ref = RoutineReference.from_string(routine_ref) 

77 

78 self._properties = {"routineReference": routine_ref.to_api_repr()} 

79 for property_name in kwargs: 

80 setattr(self, property_name, kwargs[property_name]) 

81 

82 @property 

83 def reference(self): 

84 """google.cloud.bigquery.routine.RoutineReference: Reference 

85 describing the ID of this routine. 

86 """ 

87 return RoutineReference.from_api_repr( 

88 self._properties[self._PROPERTY_TO_API_FIELD["reference"]] 

89 ) 

90 

91 @property 

92 def path(self): 

93 """str: URL path for the routine's APIs.""" 

94 return self.reference.path 

95 

96 @property 

97 def project(self): 

98 """str: ID of the project containing the routine.""" 

99 return self.reference.project 

100 

101 @property 

102 def dataset_id(self): 

103 """str: ID of dataset containing the routine.""" 

104 return self.reference.dataset_id 

105 

106 @property 

107 def routine_id(self): 

108 """str: The routine ID.""" 

109 return self.reference.routine_id 

110 

111 @property 

112 def etag(self): 

113 """str: ETag for the resource (:data:`None` until set from the 

114 server). 

115 

116 Read-only. 

117 """ 

118 return self._properties.get(self._PROPERTY_TO_API_FIELD["etag"]) 

119 

120 @property 

121 def type_(self): 

122 """str: The fine-grained type of the routine. 

123 

124 See: 

125 https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#RoutineType 

126 """ 

127 return self._properties.get(self._PROPERTY_TO_API_FIELD["type_"]) 

128 

129 @type_.setter 

130 def type_(self, value): 

131 self._properties[self._PROPERTY_TO_API_FIELD["type_"]] = value 

132 

133 @property 

134 def created(self): 

135 """Optional[datetime.datetime]: Datetime at which the routine was 

136 created (:data:`None` until set from the server). 

137 

138 Read-only. 

139 """ 

140 value = self._properties.get(self._PROPERTY_TO_API_FIELD["created"]) 

141 if value is not None and value != 0: 

142 # value will be in milliseconds. 

143 return google.cloud._helpers._datetime_from_microseconds( 

144 1000.0 * float(value) 

145 ) 

146 

147 @property 

148 def modified(self): 

149 """Optional[datetime.datetime]: Datetime at which the routine was 

150 last modified (:data:`None` until set from the server). 

151 

152 Read-only. 

153 """ 

154 value = self._properties.get(self._PROPERTY_TO_API_FIELD["modified"]) 

155 if value is not None and value != 0: 

156 # value will be in milliseconds. 

157 return google.cloud._helpers._datetime_from_microseconds( 

158 1000.0 * float(value) 

159 ) 

160 

161 @property 

162 def language(self): 

163 """Optional[str]: The language of the routine. 

164 

165 Defaults to ``SQL``. 

166 """ 

167 return self._properties.get(self._PROPERTY_TO_API_FIELD["language"]) 

168 

169 @language.setter 

170 def language(self, value): 

171 self._properties[self._PROPERTY_TO_API_FIELD["language"]] = value 

172 

173 @property 

174 def arguments(self): 

175 """List[google.cloud.bigquery.routine.RoutineArgument]: Input/output 

176 argument of a function or a stored procedure. 

177 

178 In-place modification is not supported. To set, replace the entire 

179 property value with the modified list of 

180 :class:`~google.cloud.bigquery.routine.RoutineArgument` objects. 

181 """ 

182 resources = self._properties.get(self._PROPERTY_TO_API_FIELD["arguments"], []) 

183 return [RoutineArgument.from_api_repr(resource) for resource in resources] 

184 

185 @arguments.setter 

186 def arguments(self, value): 

187 if not value: 

188 resource = [] 

189 else: 

190 resource = [argument.to_api_repr() for argument in value] 

191 self._properties[self._PROPERTY_TO_API_FIELD["arguments"]] = resource 

192 

193 @property 

194 def return_type(self): 

195 """google.cloud.bigquery.StandardSqlDataType: Return type of 

196 the routine. 

197 

198 If absent, the return type is inferred from 

199 :attr:`~google.cloud.bigquery.routine.Routine.body` at query time in 

200 each query that references this routine. If present, then the 

201 evaluated result will be cast to the specified returned type at query 

202 time. 

203 

204 See: 

205 https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#Routine.FIELDS.return_type 

206 """ 

207 resource = self._properties.get(self._PROPERTY_TO_API_FIELD["return_type"]) 

208 if not resource: 

209 return resource 

210 

211 return StandardSqlDataType.from_api_repr(resource) 

212 

213 @return_type.setter 

214 def return_type(self, value: StandardSqlDataType): 

215 resource = None if not value else value.to_api_repr() 

216 self._properties[self._PROPERTY_TO_API_FIELD["return_type"]] = resource 

217 

218 @property 

219 def return_table_type(self) -> Union[StandardSqlTableType, Any, None]: 

220 """The return type of a Table Valued Function (TVF) routine. 

221 

222 .. versionadded:: 2.22.0 

223 """ 

224 resource = self._properties.get( 

225 self._PROPERTY_TO_API_FIELD["return_table_type"] 

226 ) 

227 if not resource: 

228 return resource 

229 

230 return StandardSqlTableType.from_api_repr(resource) 

231 

232 @return_table_type.setter 

233 def return_table_type(self, value: Optional[StandardSqlTableType]): 

234 if not value: 

235 resource = None 

236 else: 

237 resource = value.to_api_repr() 

238 

239 self._properties[self._PROPERTY_TO_API_FIELD["return_table_type"]] = resource 

240 

241 @property 

242 def imported_libraries(self): 

243 """List[str]: The path of the imported JavaScript libraries. 

244 

245 The :attr:`~google.cloud.bigquery.routine.Routine.language` must 

246 equal ``JAVACRIPT``. 

247 

248 Examples: 

249 Set the ``imported_libraries`` to a list of Google Cloud Storage 

250 URIs. 

251 

252 .. code-block:: python 

253 

254 routine = bigquery.Routine("proj.dataset.routine_id") 

255 routine.imported_libraries = [ 

256 "gs://cloud-samples-data/bigquery/udfs/max-value.js", 

257 ] 

258 """ 

259 return self._properties.get( 

260 self._PROPERTY_TO_API_FIELD["imported_libraries"], [] 

261 ) 

262 

263 @imported_libraries.setter 

264 def imported_libraries(self, value): 

265 if not value: 

266 resource = [] 

267 else: 

268 resource = value 

269 self._properties[self._PROPERTY_TO_API_FIELD["imported_libraries"]] = resource 

270 

271 @property 

272 def body(self): 

273 """str: The body of the routine.""" 

274 return self._properties.get(self._PROPERTY_TO_API_FIELD["body"]) 

275 

276 @body.setter 

277 def body(self, value): 

278 self._properties[self._PROPERTY_TO_API_FIELD["body"]] = value 

279 

280 @property 

281 def description(self): 

282 """Optional[str]: Description of the routine (defaults to 

283 :data:`None`). 

284 """ 

285 return self._properties.get(self._PROPERTY_TO_API_FIELD["description"]) 

286 

287 @description.setter 

288 def description(self, value): 

289 self._properties[self._PROPERTY_TO_API_FIELD["description"]] = value 

290 

291 @property 

292 def determinism_level(self): 

293 """Optional[str]: (experimental) The determinism level of the JavaScript UDF 

294 if defined. 

295 """ 

296 return self._properties.get(self._PROPERTY_TO_API_FIELD["determinism_level"]) 

297 

298 @determinism_level.setter 

299 def determinism_level(self, value): 

300 self._properties[self._PROPERTY_TO_API_FIELD["determinism_level"]] = value 

301 

302 @property 

303 def remote_function_options(self): 

304 """Optional[google.cloud.bigquery.routine.RemoteFunctionOptions]: 

305 Configures remote function options for a routine. 

306 

307 Raises: 

308 ValueError: 

309 If the value is not 

310 :class:`~google.cloud.bigquery.routine.RemoteFunctionOptions` or 

311 :data:`None`. 

312 """ 

313 prop = self._properties.get( 

314 self._PROPERTY_TO_API_FIELD["remote_function_options"] 

315 ) 

316 if prop is not None: 

317 return RemoteFunctionOptions.from_api_repr(prop) 

318 

319 @remote_function_options.setter 

320 def remote_function_options(self, value): 

321 api_repr = value 

322 if isinstance(value, RemoteFunctionOptions): 

323 api_repr = value.to_api_repr() 

324 elif value is not None: 

325 raise ValueError( 

326 "value must be google.cloud.bigquery.routine.RemoteFunctionOptions " 

327 "or None" 

328 ) 

329 self._properties[ 

330 self._PROPERTY_TO_API_FIELD["remote_function_options"] 

331 ] = api_repr 

332 

333 @property 

334 def data_governance_type(self): 

335 """Optional[str]: If set to ``DATA_MASKING``, the function is validated 

336 and made available as a masking function. 

337 

338 Raises: 

339 ValueError: 

340 If the value is not :data:`string` or :data:`None`. 

341 """ 

342 return self._properties.get(self._PROPERTY_TO_API_FIELD["data_governance_type"]) 

343 

344 @data_governance_type.setter 

345 def data_governance_type(self, value): 

346 if value is not None and not isinstance(value, str): 

347 raise ValueError( 

348 "invalid data_governance_type, must be a string or `None`." 

349 ) 

350 self._properties[self._PROPERTY_TO_API_FIELD["data_governance_type"]] = value 

351 

352 @classmethod 

353 def from_api_repr(cls, resource: dict) -> "Routine": 

354 """Factory: construct a routine given its API representation. 

355 

356 Args: 

357 resource (Dict[str, object]): 

358 Resource, as returned from the API. 

359 

360 Returns: 

361 google.cloud.bigquery.routine.Routine: 

362 Python object, as parsed from ``resource``. 

363 """ 

364 ref = cls(RoutineReference.from_api_repr(resource["routineReference"])) 

365 ref._properties = resource 

366 return ref 

367 

368 def to_api_repr(self) -> dict: 

369 """Construct the API resource representation of this routine. 

370 

371 Returns: 

372 Dict[str, object]: Routine represented as an API resource. 

373 """ 

374 return self._properties 

375 

376 def _build_resource(self, filter_fields): 

377 """Generate a resource for ``update``.""" 

378 return _helpers._build_resource_from_properties(self, filter_fields) 

379 

380 def __repr__(self): 

381 return "Routine('{}.{}.{}')".format( 

382 self.project, self.dataset_id, self.routine_id 

383 ) 

384 

385 

386class RoutineArgument(object): 

387 """Input/output argument of a function or a stored procedure. 

388 

389 See: 

390 https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#argument 

391 

392 Args: 

393 ``**kwargs`` (Dict): 

394 Initial property values. 

395 """ 

396 

397 _PROPERTY_TO_API_FIELD = { 

398 "data_type": "dataType", 

399 "kind": "argumentKind", 

400 # Even though it's not necessary for field mapping to map when the 

401 # property name equals the resource name, we add these here so that we 

402 # have an exhaustive list of all properties. 

403 "name": "name", 

404 "mode": "mode", 

405 } 

406 

407 def __init__(self, **kwargs) -> None: 

408 self._properties: Dict[str, Any] = {} 

409 for property_name in kwargs: 

410 setattr(self, property_name, kwargs[property_name]) 

411 

412 @property 

413 def name(self): 

414 """Optional[str]: Name of this argument. 

415 

416 Can be absent for function return argument. 

417 """ 

418 return self._properties.get(self._PROPERTY_TO_API_FIELD["name"]) 

419 

420 @name.setter 

421 def name(self, value): 

422 self._properties[self._PROPERTY_TO_API_FIELD["name"]] = value 

423 

424 @property 

425 def kind(self): 

426 """Optional[str]: The kind of argument, for example ``FIXED_TYPE`` or 

427 ``ANY_TYPE``. 

428 

429 See: 

430 https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#Argument.FIELDS.argument_kind 

431 """ 

432 return self._properties.get(self._PROPERTY_TO_API_FIELD["kind"]) 

433 

434 @kind.setter 

435 def kind(self, value): 

436 self._properties[self._PROPERTY_TO_API_FIELD["kind"]] = value 

437 

438 @property 

439 def mode(self): 

440 """Optional[str]: The input/output mode of the argument.""" 

441 return self._properties.get(self._PROPERTY_TO_API_FIELD["mode"]) 

442 

443 @mode.setter 

444 def mode(self, value): 

445 self._properties[self._PROPERTY_TO_API_FIELD["mode"]] = value 

446 

447 @property 

448 def data_type(self): 

449 """Optional[google.cloud.bigquery.StandardSqlDataType]: Type 

450 of a variable, e.g., a function argument. 

451 

452 See: 

453 https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#Argument.FIELDS.data_type 

454 """ 

455 resource = self._properties.get(self._PROPERTY_TO_API_FIELD["data_type"]) 

456 if not resource: 

457 return resource 

458 

459 return StandardSqlDataType.from_api_repr(resource) 

460 

461 @data_type.setter 

462 def data_type(self, value): 

463 if value: 

464 resource = value.to_api_repr() 

465 else: 

466 resource = None 

467 self._properties[self._PROPERTY_TO_API_FIELD["data_type"]] = resource 

468 

469 @classmethod 

470 def from_api_repr(cls, resource: dict) -> "RoutineArgument": 

471 """Factory: construct a routine argument given its API representation. 

472 

473 Args: 

474 resource (Dict[str, object]): Resource, as returned from the API. 

475 

476 Returns: 

477 google.cloud.bigquery.routine.RoutineArgument: 

478 Python object, as parsed from ``resource``. 

479 """ 

480 ref = cls() 

481 ref._properties = resource 

482 return ref 

483 

484 def to_api_repr(self) -> dict: 

485 """Construct the API resource representation of this routine argument. 

486 

487 Returns: 

488 Dict[str, object]: Routine argument represented as an API resource. 

489 """ 

490 return self._properties 

491 

492 def __eq__(self, other): 

493 if not isinstance(other, RoutineArgument): 

494 return NotImplemented 

495 return self._properties == other._properties 

496 

497 def __ne__(self, other): 

498 return not self == other 

499 

500 def __repr__(self): 

501 all_properties = [ 

502 "{}={}".format(property_name, repr(getattr(self, property_name))) 

503 for property_name in sorted(self._PROPERTY_TO_API_FIELD) 

504 ] 

505 return "RoutineArgument({})".format(", ".join(all_properties)) 

506 

507 

508class RoutineReference(object): 

509 """A pointer to a routine. 

510 

511 See: 

512 https://cloud.google.com/bigquery/docs/reference/rest/v2/routines#routinereference 

513 """ 

514 

515 def __init__(self): 

516 self._properties = {} 

517 

518 @property 

519 def project(self): 

520 """str: ID of the project containing the routine.""" 

521 return self._properties.get("projectId", "") 

522 

523 @property 

524 def dataset_id(self): 

525 """str: ID of dataset containing the routine.""" 

526 return self._properties.get("datasetId", "") 

527 

528 @property 

529 def routine_id(self): 

530 """str: The routine ID.""" 

531 return self._properties.get("routineId", "") 

532 

533 @property 

534 def path(self): 

535 """str: URL path for the routine's APIs.""" 

536 return "/projects/%s/datasets/%s/routines/%s" % ( 

537 self.project, 

538 self.dataset_id, 

539 self.routine_id, 

540 ) 

541 

542 @classmethod 

543 def from_api_repr(cls, resource: dict) -> "RoutineReference": 

544 """Factory: construct a routine reference given its API representation. 

545 

546 Args: 

547 resource (Dict[str, object]): 

548 Routine reference representation returned from the API. 

549 

550 Returns: 

551 google.cloud.bigquery.routine.RoutineReference: 

552 Routine reference parsed from ``resource``. 

553 """ 

554 ref = cls() 

555 ref._properties = resource 

556 return ref 

557 

558 @classmethod 

559 def from_string( 

560 cls, routine_id: str, default_project: Optional[str] = None 

561 ) -> "RoutineReference": 

562 """Factory: construct a routine reference from routine ID string. 

563 

564 Args: 

565 routine_id (str): 

566 A routine ID in standard SQL format. If ``default_project`` 

567 is not specified, this must included a project ID, dataset 

568 ID, and routine ID, each separated by ``.``. 

569 default_project (Optional[str]): 

570 The project ID to use when ``routine_id`` does not 

571 include a project ID. 

572 

573 Returns: 

574 google.cloud.bigquery.routine.RoutineReference: 

575 Routine reference parsed from ``routine_id``. 

576 

577 Raises: 

578 ValueError: 

579 If ``routine_id`` is not a fully-qualified routine ID in 

580 standard SQL format. 

581 """ 

582 proj, dset, routine = _helpers._parse_3_part_id( 

583 routine_id, default_project=default_project, property_name="routine_id" 

584 ) 

585 return cls.from_api_repr( 

586 {"projectId": proj, "datasetId": dset, "routineId": routine} 

587 ) 

588 

589 def to_api_repr(self) -> dict: 

590 """Construct the API resource representation of this routine reference. 

591 

592 Returns: 

593 Dict[str, object]: Routine reference represented as an API resource. 

594 """ 

595 return self._properties 

596 

597 def __eq__(self, other): 

598 """Two RoutineReferences are equal if they point to the same routine.""" 

599 if not isinstance(other, RoutineReference): 

600 return NotImplemented 

601 return str(self) == str(other) 

602 

603 def __hash__(self): 

604 return hash(str(self)) 

605 

606 def __ne__(self, other): 

607 return not self == other 

608 

609 def __repr__(self): 

610 return "RoutineReference.from_string('{}')".format(str(self)) 

611 

612 def __str__(self): 

613 """String representation of the reference. 

614 

615 This is a fully-qualified ID, including the project ID and dataset ID. 

616 """ 

617 return "{}.{}.{}".format(self.project, self.dataset_id, self.routine_id) 

618 

619 

620class RemoteFunctionOptions(object): 

621 """Configuration options for controlling remote BigQuery functions.""" 

622 

623 _PROPERTY_TO_API_FIELD = { 

624 "endpoint": "endpoint", 

625 "connection": "connection", 

626 "max_batching_rows": "maxBatchingRows", 

627 "user_defined_context": "userDefinedContext", 

628 } 

629 

630 def __init__( 

631 self, 

632 endpoint=None, 

633 connection=None, 

634 max_batching_rows=None, 

635 user_defined_context=None, 

636 _properties=None, 

637 ) -> None: 

638 if _properties is None: 

639 _properties = {} 

640 self._properties = _properties 

641 

642 if endpoint is not None: 

643 self.endpoint = endpoint 

644 if connection is not None: 

645 self.connection = connection 

646 if max_batching_rows is not None: 

647 self.max_batching_rows = max_batching_rows 

648 if user_defined_context is not None: 

649 self.user_defined_context = user_defined_context 

650 

651 @property 

652 def connection(self): 

653 """string: Fully qualified name of the user-provided connection object which holds the authentication information to send requests to the remote service. 

654 

655 Format is "projects/{projectId}/locations/{locationId}/connections/{connectionId}" 

656 """ 

657 return _helpers._str_or_none(self._properties.get("connection")) 

658 

659 @connection.setter 

660 def connection(self, value): 

661 self._properties["connection"] = _helpers._str_or_none(value) 

662 

663 @property 

664 def endpoint(self): 

665 """string: Endpoint of the user-provided remote service 

666 

667 Example: "https://us-east1-my_gcf_project.cloudfunctions.net/remote_add" 

668 """ 

669 return _helpers._str_or_none(self._properties.get("endpoint")) 

670 

671 @endpoint.setter 

672 def endpoint(self, value): 

673 self._properties["endpoint"] = _helpers._str_or_none(value) 

674 

675 @property 

676 def max_batching_rows(self): 

677 """int64: Max number of rows in each batch sent to the remote service. 

678 

679 If absent or if 0, BigQuery dynamically decides the number of rows in a batch. 

680 """ 

681 return _helpers._int_or_none(self._properties.get("maxBatchingRows")) 

682 

683 @max_batching_rows.setter 

684 def max_batching_rows(self, value): 

685 self._properties["maxBatchingRows"] = _helpers._str_or_none(value) 

686 

687 @property 

688 def user_defined_context(self): 

689 """Dict[str, str]: User-defined context as a set of key/value pairs, 

690 which will be sent as function invocation context together with 

691 batched arguments in the requests to the remote service. The total 

692 number of bytes of keys and values must be less than 8KB. 

693 """ 

694 return self._properties.get("userDefinedContext") 

695 

696 @user_defined_context.setter 

697 def user_defined_context(self, value): 

698 if not isinstance(value, dict): 

699 raise ValueError("value must be dictionary") 

700 self._properties["userDefinedContext"] = value 

701 

702 @classmethod 

703 def from_api_repr(cls, resource: dict) -> "RemoteFunctionOptions": 

704 """Factory: construct remote function options given its API representation. 

705 

706 Args: 

707 resource (Dict[str, object]): Resource, as returned from the API. 

708 

709 Returns: 

710 google.cloud.bigquery.routine.RemoteFunctionOptions: 

711 Python object, as parsed from ``resource``. 

712 """ 

713 ref = cls() 

714 ref._properties = resource 

715 return ref 

716 

717 def to_api_repr(self) -> dict: 

718 """Construct the API resource representation of this RemoteFunctionOptions. 

719 

720 Returns: 

721 Dict[str, object]: Remote function options represented as an API resource. 

722 """ 

723 return self._properties 

724 

725 def __eq__(self, other): 

726 if not isinstance(other, RemoteFunctionOptions): 

727 return NotImplemented 

728 return self._properties == other._properties 

729 

730 def __ne__(self, other): 

731 return not self == other 

732 

733 def __repr__(self): 

734 all_properties = [ 

735 "{}={}".format(property_name, repr(getattr(self, property_name))) 

736 for property_name in sorted(self._PROPERTY_TO_API_FIELD) 

737 ] 

738 return "RemoteFunctionOptions({})".format(", ".join(all_properties))