- Notifications
You must be signed in to change notification settings - Fork90
feat: implement async client for LROs#707
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
feat: implement async client for LROs#707
Uh oh!
There was an error while loading.Please reload this page.
Conversation
conventional-commit-lint-gcfbot commentedSep 24, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
🤖 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
tocb2eab0
Compare787f0ba
to35d88d7
Compare5ea5e27
to4d75cca
Compare5e6c365
to74e9bb8
Compare4f3671c
to2af34aa
Compare5564d01
tof448498
Comparegoogle/api_core/operations_v1/abstract_operations_async_client.py OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
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 | | AbstractOperationsAsyncClientListOperationsPagerBase ^ ^ | | | | | ListOperationsPager # sync | | ListOperationsAsyncPager
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
google/api_core/operations_v1/abstract_operations_async_client.py OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
google/api_core/operations_v1/abstract_operations_async_client.py OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
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 thetransport
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 indeedREST
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 OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
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 acompression
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 acompression
parameter since it's aREST
only client. We have a separate client forgRPC
.
Uh oh!
There was an error while loading.Please reload this page.
@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. |
vchudnov-g left a comment• edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
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 (egTransport orClient ) | |||
SyncFoo | AsyncFoo | ||
gRPCSyncFoo | RestSyncFoo | gRPCAsyncFoo | RestAsyncFoo |
Given historical naming and wanting to keep backward-compatibility, maybe we want something like this?:
BaseFoo (egBaseTransport orBaseClient ) | |||
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.
Uh oh!
There was an error while loading.Please reload this page.
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 thetransport
is not an async rest transport (ours or user-defined)? Might be worth filing a follow-up issue.
043785e
intoasync-rest-lro-support-in-coreUh oh!
There was an error while loading.Please reload this page.
* 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-processorSeehttps://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 <omairnaveed@ymail.com>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 <omairnaveed@ymail.com>Co-authored-by: ohmayr <omairn@google.com>* 🦉 Updates from OwlBot post-processorSeehttps://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md---------Co-authored-by: Anthonios Partheniou <partheniou@google.com>Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
Uh oh!
There was an error while loading.Please reload this page.
Towards b/362946071
This PR depends on#700 and#701