Skip to content
This repository was archived by the owner on Sep 5, 2023. It is now read-only.

Commit 66772fa

Browse files
feat: add context manager support in client (#119)
- [ ] Regenerate this pull request now. chore: fix docstring for first attribute of protos committer: @busunkim96 PiperOrigin-RevId: 401271153 Source-Link: googleapis/googleapis@787f8c9 Source-Link: https://github.com/googleapis/googleapis-gen/commit/81decffe9fc72396a8153e756d1d67a6eecfd620 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiODFkZWNmZmU5ZmM3MjM5NmE4MTUzZTc1NmQxZDY3YTZlZWNmZDYyMCJ9
1 parent ce5219c commit 66772fa

File tree

8 files changed

+100
-5
lines changed

8 files changed

+100
-5
lines changed

google/cloud/functions_v1/services/cloud_functions_service/async_client.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,12 @@ async def test_iam_permissions(
10941094
# Done; return the response.
10951095
return response
10961096

1097+
async def __aenter__(self):
1098+
return self
1099+
1100+
async def __aexit__(self, exc_type, exc, tb):
1101+
await self.transport.close()
1102+
10971103

10981104
try:
10991105
DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(

google/cloud/functions_v1/services/cloud_functions_service/client.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -356,10 +356,7 @@ def __init__(
356356
client_cert_source_for_mtls=client_cert_source_func,
357357
quota_project_id=client_options.quota_project_id,
358358
client_info=client_info,
359-
always_use_jwt_access=(
360-
Transport == type(self).get_transport_class("grpc")
361-
or Transport == type(self).get_transport_class("grpc_asyncio")
362-
),
359+
always_use_jwt_access=True,
363360
)
364361

365362
def list_functions(
@@ -1240,6 +1237,19 @@ def test_iam_permissions(
12401237
# Done; return the response.
12411238
return response
12421239

1240+
def __enter__(self):
1241+
return self
1242+
1243+
def __exit__(self, type, value, traceback):
1244+
"""Releases underlying transport's resources.
1245+
1246+
.. warning::
1247+
ONLY use as a context manager if the transport is NOT shared
1248+
with other clients! Exiting the with block will CLOSE the transport
1249+
and may cause errors in other clients!
1250+
"""
1251+
self.transport.close()
1252+
12431253

12441254
try:
12451255
DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(

google/cloud/functions_v1/services/cloud_functions_service/transports/base.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,15 @@ def _prep_wrapped_messages(self, client_info):
243243
),
244244
}
245245

246+
def close(self):
247+
"""Closes resources associated with the transport.
248+
249+
.. warning::
250+
Only call this method if the transport is NOT shared
251+
with other clients - this may cause errors in other clients!
252+
"""
253+
raise NotImplementedError()
254+
246255
@property
247256
def operations_client(self) -> operations_v1.OperationsClient:
248257
"""Return the client designed to process long-running operations."""

google/cloud/functions_v1/services/cloud_functions_service/transports/grpc.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,5 +586,8 @@ def test_iam_permissions(
586586
)
587587
return self._stubs["test_iam_permissions"]
588588

589+
def close(self):
590+
self.grpc_channel.close()
591+
589592

590593
__all__ = ("CloudFunctionsServiceGrpcTransport",)

google/cloud/functions_v1/services/cloud_functions_service/transports/grpc_asyncio.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,5 +603,8 @@ def test_iam_permissions(
603603
)
604604
return self._stubs["test_iam_permissions"]
605605

606+
def close(self):
607+
return self.grpc_channel.close()
608+
606609

607610
__all__ = ("CloudFunctionsServiceGrpcAsyncIOTransport",)

google/cloud/functions_v1/types/functions.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,13 +363,15 @@ class Retry(proto.Message):
363363
failed execution will be retried up to 7 days with an
364364
exponential backoff (capped at 10 seconds).
365365
Retried execution is charged as any other execution.
366-
"""
366+
367+
"""
367368

368369
retry = proto.Field(proto.MESSAGE, number=1, oneof="action", message=Retry,)
369370

370371

371372
class CreateFunctionRequest(proto.Message):
372373
r"""Request for the ``CreateFunction`` method.
374+
373375
Attributes:
374376
location (str):
375377
Required. The project and location in which the function
@@ -385,6 +387,7 @@ class CreateFunctionRequest(proto.Message):
385387

386388
class UpdateFunctionRequest(proto.Message):
387389
r"""Request for the ``UpdateFunction`` method.
390+
388391
Attributes:
389392
function (google.cloud.functions_v1.types.CloudFunction):
390393
Required. New version of the function.
@@ -401,6 +404,7 @@ class UpdateFunctionRequest(proto.Message):
401404

402405
class GetFunctionRequest(proto.Message):
403406
r"""Request for the ``GetFunction`` method.
407+
404408
Attributes:
405409
name (str):
406410
Required. The name of the function which
@@ -412,6 +416,7 @@ class GetFunctionRequest(proto.Message):
412416

413417
class ListFunctionsRequest(proto.Message):
414418
r"""Request for the ``ListFunctions`` method.
419+
415420
Attributes:
416421
parent (str):
417422
The project and location from which the function should be
@@ -438,6 +443,7 @@ class ListFunctionsRequest(proto.Message):
438443

439444
class ListFunctionsResponse(proto.Message):
440445
r"""Response for the ``ListFunctions`` method.
446+
441447
Attributes:
442448
functions (Sequence[google.cloud.functions_v1.types.CloudFunction]):
443449
The functions that match the request.
@@ -463,6 +469,7 @@ def raw_page(self):
463469

464470
class DeleteFunctionRequest(proto.Message):
465471
r"""Request for the ``DeleteFunction`` method.
472+
466473
Attributes:
467474
name (str):
468475
Required. The name of the function which
@@ -474,6 +481,7 @@ class DeleteFunctionRequest(proto.Message):
474481

475482
class CallFunctionRequest(proto.Message):
476483
r"""Request for the ``CallFunction`` method.
484+
477485
Attributes:
478486
name (str):
479487
Required. The name of the function to be
@@ -488,6 +496,7 @@ class CallFunctionRequest(proto.Message):
488496

489497
class CallFunctionResponse(proto.Message):
490498
r"""Response of ``CallFunction`` method.
499+
491500
Attributes:
492501
execution_id (str):
493502
Execution id of function invocation.
@@ -508,6 +517,7 @@ class CallFunctionResponse(proto.Message):
508517

509518
class GenerateUploadUrlRequest(proto.Message):
510519
r"""Request of ``GenerateSourceUploadUrl`` method.
520+
511521
Attributes:
512522
parent (str):
513523
The project and location in which the Google Cloud Storage
@@ -520,6 +530,7 @@ class GenerateUploadUrlRequest(proto.Message):
520530

521531
class GenerateUploadUrlResponse(proto.Message):
522532
r"""Response of ``GenerateSourceUploadUrl`` method.
533+
523534
Attributes:
524535
upload_url (str):
525536
The generated Google Cloud Storage signed URL
@@ -533,6 +544,7 @@ class GenerateUploadUrlResponse(proto.Message):
533544

534545
class GenerateDownloadUrlRequest(proto.Message):
535546
r"""Request of ``GenerateDownloadUrl`` method.
547+
536548
Attributes:
537549
name (str):
538550
The name of function for which source code
@@ -549,6 +561,7 @@ class GenerateDownloadUrlRequest(proto.Message):
549561

550562
class GenerateDownloadUrlResponse(proto.Message):
551563
r"""Response of ``GenerateDownloadUrl`` method.
564+
552565
Attributes:
553566
download_url (str):
554567
The generated Google Cloud Storage signed URL

google/cloud/functions_v1/types/operations.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class OperationType(proto.Enum):
3535

3636
class OperationMetadataV1(proto.Message):
3737
r"""Metadata describing an [Operation][google.longrunning.Operation]
38+
3839
Attributes:
3940
target (str):
4041
Target of the operation - for example

tests/unit/gapic/functions_v1/test_cloud_functions_service.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from google.api_core import grpc_helpers_async
3333
from google.api_core import operation_async # type: ignore
3434
from google.api_core import operations_v1
35+
from google.api_core import path_template
3536
from google.auth import credentials as ga_credentials
3637
from google.auth.exceptions import MutualTLSChannelError
3738
from google.cloud.functions_v1.services.cloud_functions_service import (
@@ -2847,6 +2848,9 @@ def test_cloud_functions_service_base_transport():
28472848
with pytest.raises(NotImplementedError):
28482849
getattr(transport, method)(request=object())
28492850

2851+
with pytest.raises(NotImplementedError):
2852+
transport.close()
2853+
28502854
# Additionally, the LRO client (a property) should
28512855
# also raise NotImplementedError
28522856
with pytest.raises(NotImplementedError):
@@ -3366,3 +3370,49 @@ def test_client_withDEFAULT_CLIENT_INFO():
33663370
credentials=ga_credentials.AnonymousCredentials(), client_info=client_info,
33673371
)
33683372
prep.assert_called_once_with(client_info)
3373+
3374+
3375+
@pytest.mark.asyncio
3376+
async def test_transport_close_async():
3377+
client = CloudFunctionsServiceAsyncClient(
3378+
credentials=ga_credentials.AnonymousCredentials(), transport="grpc_asyncio",
3379+
)
3380+
with mock.patch.object(
3381+
type(getattr(client.transport, "grpc_channel")), "close"
3382+
) as close:
3383+
async with client:
3384+
close.assert_not_called()
3385+
close.assert_called_once()
3386+
3387+
3388+
def test_transport_close():
3389+
transports = {
3390+
"grpc": "_grpc_channel",
3391+
}
3392+
3393+
for transport, close_name in transports.items():
3394+
client = CloudFunctionsServiceClient(
3395+
credentials=ga_credentials.AnonymousCredentials(), transport=transport
3396+
)
3397+
with mock.patch.object(
3398+
type(getattr(client.transport, close_name)), "close"
3399+
) as close:
3400+
with client:
3401+
close.assert_not_called()
3402+
close.assert_called_once()
3403+
3404+
3405+
def test_client_ctx():
3406+
transports = [
3407+
"grpc",
3408+
]
3409+
for transport in transports:
3410+
client = CloudFunctionsServiceClient(
3411+
credentials=ga_credentials.AnonymousCredentials(), transport=transport
3412+
)
3413+
# Test client calls underlying transport.
3414+
with mock.patch.object(type(client.transport), "close") as close:
3415+
close.assert_not_called()
3416+
with client:
3417+
pass
3418+
close.assert_called()

0 commit comments

Comments
 (0)