-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: implement async client for LROs #707
feat: implement async client for LROs #707
Conversation
🤖 I detect that the PR title and the commit message differ and there's only one commit. To use the PR title for the commit history, you can use Github's automerge feature with squashing, or use -- conventional-commit-lint bot |
1492985
to
cb2eab0
Compare
787f0ba
to
35d88d7
Compare
5ea5e27
to
4d75cca
Compare
5e6c365
to
74e9bb8
Compare
4f3671c
to
2af34aa
Compare
5564d01
to
f448498
Compare
google/api_core/operations_v1/abstract_operations_async_client.py
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have some initial comments. I'll continue next week.
The main thing I want to work out in my head is the class hierarchy, and how it pertains to {sync, async} × {grpc, rest}.
What I've worked out so far is this class hierarchy, but I don't see where gRPC fits in. I need to think about this more, and it might be worth a discussion:
# do any of these include gRPC?
AbstractOperationsBaseClient o---- OperationsRestTransport
^ ^ o---- OperationsRestAsyncTransport
| |
| |
| AbstractOperationsClient # sync
|
|
AbstractOperationsAsyncClient
ListOperationsPagerBase
^ ^
| |
| |
| ListOperationsPager # sync
|
|
ListOperationsAsyncPager
google/api_core/operations_v1/abstract_operations_base_client.py
Outdated
Show resolved
Hide resolved
google/api_core/operations_v1/abstract_operations_async_client.py
Outdated
Show resolved
Hide resolved
google/api_core/operations_v1/abstract_operations_async_client.py
Outdated
Show resolved
Hide resolved
super().__init__( | ||
credentials=credentials, # type: ignore | ||
# NOTE: If a transport is not provided, we force the client to use the async | ||
# REST transport, as it should. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
Why should it? This abstract operations class does not say it's REST-specific, so why couldn't we go with gRPC async? We should see default to one of the ones that are supported (have the right dependencies); if both gRPC and REST are possible, sure, we could have a policy as to which one we choose for the default. As per my other comment, if the plan is to do this as we clean up this code, etc., let's add a TODO with link to a tracking issue that includes setting the right default.
-
Regardless, I would remove the final clause:
# REST transport, as it should. | |
# REST transport. |
- Also, update the class doc above so instead if "If set to None, a transport is chosen automatically", it says "If set to None, this defaults to 'rest_asyncio'".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need a TODO to add the right default. This is an async REST client so we're setting the right default value i.e. rest_asyncio
.
What we may instead want to do is update the name / docstring of the class to make it clear that this is specific to async REST.
In future, we may want to spend some time to investigate if we can combine different transport and client class for gRPC and REST that we maintain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if this is an async rest client, why do we have a transport parameter at all? What do we do if the transport
is not an async rest transport (ours or user-defined)? Might be worth filing a follow-up issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Users can still configure an instance of an async transport class but I agree that it is a bit weird. Can add a note about it in the issue that i file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filed: #726
try: | ||
from google.auth.aio import credentials as ga_credentials # type: ignore | ||
except ImportError as e: # pragma: NO COVER | ||
raise ImportError( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name of the file and the name of the class do not make it clear that this is REST-specific. So async should work if at least one of { (REST dependencies), (gRPC dependencies) } are available. So it seems to me we should check for both sets of dependencies being absent before we error.
That, at least, when we get to the steady state of having everything implemented and cleaned up. If that's the reason we're not doing that now, let's add a TODO with a link to a tracking issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. The name doesn't specify it but it is indeed REST
specific. I agree that it's confusing. The name used here is consistent to what we have for the sync REST client / transport. We can have a discussion on what we want to name our async client / transport.
Updating the sync client name would be a breaking change.
google/api_core/operations_v1/abstract_operations_async_client.py
Outdated
Show resolved
Hide resolved
page_token: Optional[str] = None, | ||
timeout: Optional[float] = None, | ||
metadata: Sequence[Tuple[str, str]] = (), | ||
) -> pagers.ListOperationsAsyncPager: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AbstractOperationsClient
has a compression
parameter. Since This abstract class is, I assume, also applicable to gRPC, we should accept that parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AbstractOperationsClient
shouldn't have a compression
parameter since it's a REST
only client. We have a separate client for gRPC
.
@vchudnov-g I've addressed all of your comments. The only thing that's left and is causing a bit of confusion is the name of client/transport class. Let's discuss this, address it accordingly, and get this over the line since I believe it's not a big change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, let's have a clearer naming convention for files and classes. We want to cover {sync, async} × {REST, gRPC}.
In the ideal world, we would have prefixes for each of those two dimensions:
Foo (eg Transport or Client ) | |||
SyncFoo | AsyncFoo | ||
gRPCSyncFoo | RestSyncFoo | gRPCAsyncFoo | RestAsyncFoo |
Given historical naming and wanting to keep backward-compatibility, maybe we want something like this?:
BaseFoo (eg BaseTransport or BaseClient ) | |||
BaseSyncFoo | BaseAsyncFoo | ||
Foo | RestSyncFoo | AsyncFoo | RestAsyncFoo |
Let's discuss the right names.....
Also, we should consider that we could have the "ideal" names in their own logical namespace, and assign the legacy names in the legacy namespace, e.e.:
transports.Foo = transports.ideal.gRPCSyncFoo
transports.AsyncFoo = transports.ideal.gRPCAsyncFoo
We'd have to figure out what name to use; it obviously wouldn't literally be "ideal".
Luckily, we can do this now or later, so we have options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the discussion on the class hierarchy now and how we want it to evolve. Googlers, see b/372066378
super().__init__( | ||
credentials=credentials, # type: ignore | ||
# NOTE: If a transport is not provided, we force the client to use the async | ||
# REST transport, as it should. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if this is an async rest client, why do we have a transport parameter at all? What do we do if the transport
is not an async rest transport (ours or user-defined)? Might be worth filing a follow-up issue.
* feat: implement `OperationsRestAsyncTransport` to support long running operations (#700) * feat: Add OperationsRestAsyncTransport to support long running operations * update TODO comment * update TODO comment * address feedback * address feedback * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * fix mypy and lint issues * minor fix * add no cover * fix no cover tag * link coverage issue * silence coverage issue * fix statement name error * address PR feedback * address PR feedback * address PR comments --------- Co-authored-by: ohmayr <[email protected]> Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com> * feat: implement async client for LROs (#707) * feat: implement `AbstractOperationsAsyncClient` to support long running operations * remove coverage guards * address presubmit failures * fix coverage for cancel operation * tests cleanup * fix incorrect tests * file bugs * add auth import * address PR comments * address PR comments * fix unit tests and address more comments * disable retry parameter * add retry parameter * address PR comments --------- Co-authored-by: ohmayr <[email protected]> Co-authored-by: ohmayr <[email protected]> * 🦉 Updates from OwlBot post-processor See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --------- Co-authored-by: Anthonios Partheniou <[email protected]> Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
Towards b/362946071
This PR depends on #700 and #701