-
Notifications
You must be signed in to change notification settings - Fork 441
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Make ListObject.auto_paging_iter()
implement AsyncIterator
#1247
Make ListObject.auto_paging_iter()
implement AsyncIterator
#1247
Conversation
Do we want this to succeed? If the user wanted to use all async methods, this seems like something they could easily miss and unintentionally introduce synchronous calls. |
I think ideally, no. But the only way to get this to fail is via an approach like https://github.com/stripe/stripe-python/compare/richardm-async-list-object?expand=1 which has a lot of downsides, basically you have to have 2 separate versions of ListObject (which is kind of at odds with the design decision we've made not to have mirror versions of resources), and you also have to flow a So instead of that, for users who want to make sure that they've eliminated all synchronous requests, I propose a bigger hammer
this unfortunately won't help the typechecker find synchronous method calls but it could cause runtime errors when they run tests. |
Ahh, I didn't parse the follow-up about So if I'm understanding correctly: # No migration, all synchronous calls
print(", ".join([cus.id for cus in stripe.Customer.list().auto_paging_iter()]))
# 1 asynchronous call (through `list_async` method) + synchronous pagination calls
print(", ".join([cus.id for cus in (await stripe.Customer.list_async()).auto_paging_iter()]))
# 1 synchronous call (through the `list` method) + asynchronous pagination calls
print(", ".join([cus.id async for cus in stripe.Customer.list().auto_paging_iter()]))
# Correct migration, all asynchronous calls
print(", ".join([cus.id async for cus in (await stripe.Customer.list_async()).auto_paging_iter()])) Overall, I do think this change would give a better experience! |
61844dd
to
163adc4
Compare
Ok @anniel-stripe, since the last time you reviewed:
|
Summary
This PR gets rid of
.auto_paging_iter_async()
and makes.auto_paging_iter()
capable of asynchronous iteration.Not included: the analog for SearchResult. Want feedback on this approach before I apply it everywhere.
Motivation
We got some feedback from internal users that it error-prone figuring out how to migrate sync code that used
.auto_paging_iter
, e.g.There are 3 things you have to change, and so 2^3 - 2 = 6 ways to incorrectly/partially migrate this (minus one for the correct migration, minus one for making no change at all). Here are 3:
I experimented a little bit with introducing ListObjectAsync and SearchResultAsync, this added a lot of complexity and would have resulted in
This PR, on the other hand, makes it so that it is not a mistake to use
async for
along with.auto_paging_iter()
. So it reduces the possible ways to migrate incorrectly to 2^2 - 2 = 2.As a follow-up, we could consider adding (and recommending) an option like
stripe.default_http_client = stripe.HTTPXClient(disable_sync=True)
that would cause these to begin throwing exceptions if the user wanted.