dj-stripe / dj-stripe

dj-stripe automatically syncs your Stripe Data to your local database as pre-implemented Django Models allowing you to use the Django ORM, in your code, to work with the data making it easier and faster.
https://dj-stripe.dev
MIT License
1.65k stars 487 forks source link

Asyncio support #1872

Open Andrew-Chen-Wang opened 1 year ago

Andrew-Chen-Wang commented 1 year ago

Hi, thanks for this great library! My team is migrating a lot of our code to async. Looking to see if you had any design decisions when it comes to adopting asyncio and would like to start a discussion.

I've gone through a bunch of libraries (non Django related), and -- to me -- for Django, an approach is to separate the views and urls.py of a library into a separate folder and have users include the urls.py from an asyncio folder.

For each synchronous db call, all the model methods would need an a prefixed version. The bad thing about this approach is lots of repeated code, and even abstracting the views in some way can become a slight mess.

An approach I liked a lot was redis-py's Command mixins, but that might not be possible in this case? Thoughts?

Of course the other problem is stripe-python is not async either, but we can wrap those calls into asgiref.sync

jleclanche commented 1 year ago

I don't really know what can be done here tbh. Like you said, stripe-python is not async, and django's async code is just super repeated, so I don't think we're a good candidate to go async until all that can happen without literally duplicating the entire library.

However, keep in mind dj-stripe is just models and webhook handlers. Those don't have to live in an async thread. You can directly access the models and use django's async functions as you like there. You can also have the webhook handling in a separate, fully synchronous instance.

bufke commented 4 months ago

Now that stripe-python supports async, would you accept pull requests adding async methods where appropriate? Anything using the stripe API would benefit. Models would not, outside of consistency, as Django ORM does not utilize async DB drivers right now. IMO making external http calls is a good priority for async code as the response times are considerable. And Django supports async views just fine.

If so, would you consider

1) My preference would be to use only async code with "a" function prefixes like Django. Then use async_to_sync for sync fallbacks for backwards compatibility. This method results in less code. The sync performance penalty is minimum compared to the wait of of the network request. 2) Duplicate code. Colors of function and whatnot. Perhaps use some mixins to reduce repeats as suggested.

jleclanche commented 4 months ago

Great to hear stripe-python now supports async. Let's get 3.0 out of the door first, but I'm open to a decent design for it.