-
Notifications
You must be signed in to change notification settings - Fork 714
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
IMPROVEMENT: Support for asynchronous sending #296
Comments
Hello @Jakobovski, Thanks for taking the time to not only add the request, but for the additional details! And thanks for the kind words as well! We will add this to our backlog. For it to rise in importance, we would require additional votes or a pull request. With Best Regards, Elmer |
This is something I wouldn't expect in a library, but rather something that should be implemented in the project that uses the library. The de facto solution with Python is to write an asynchronous task to do the heavy lifting using Celery. |
Hi @jussih, Would you mind creating documentation that demonstrates how this can be done? You would add your PR here and we would give you hacktoberfest credit at "difficulty: medium" for that. If not, no worries. We appreciate your feedback in any case :) With Best Regards, Elmer |
Celery is a great tool for async or parallel processing. But if one is using Python 3.5+, the built-in SendGrid v3 Mail Send - Async Example
|
I've been doing something like this for a while, but resorted to updating the http-client library instead of making any changes to this library. You can take a look at https://github.com/tr11/python-http-client, which uses aiohttp instead of the requests library to do the heavy lifting. |
Do you mind adding that example to this repo's USE_CASES.md? That's awesome @tr11! Do you mind making a PR for hacktoberfest on that library to demonstrate your example? You would create a USE_CASES.md based on the format of the one found in this repo. With Best Regards, Elmer |
I have a PR open - #363 that adds this example to the USE_CASES.md file. If there are any other changes I need to make beyond contained in the change log, please let me know. Thanks! |
@LiYChristopher are you sure your code actually works? Client post will block scheduler, or I'm missing something?
|
Hello. sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
url, data = sg.prepare_send(message)
response = await your_async_method_for_send(url, data)
response = sg.process_response(response) because we have many different libs (for me it's Tornado) to make an async request we should provide an easy way to integration with any of it. |
If this is still on the table, I'd love to take it on as a Hacktoberfest project two years later following the idea of @stalkerg here. Would the method name I think |
This has been open for a while, and nobody has mentioned it, but you can run blocking network requests in parallel through the default executor. It's not an obvious solution (mentioned only in a corner of the asyncio documentation and referring to a method that doesn't directly refer to being run in a background thread, but the example code demonstrates it), and it's not perfect (because it's not actually using async IO, but executing parallel through threads behind the scenes) but this will work when run from within any async function, and will be properly parallelized without blocking or exposing thread safety issues: mail = {
# Mail body here
}
loop = asyncio.get_running_loop() # or get_event_loop if you need to use Python 3.6
response = await loop.run_in_executor(
None,
functools.partial(
api_client.client.mail.send.post,
request_body=mail)) Like I said, not the most ideal, but for my uses, it allows backgrounding parallel IO to keep my application responsive and snappy. The previous answer posted by @LiYChristopher will not work. Each request will still fully block the scheduler. I only mention it because it has a handful of positive reactions despite not functioning the way it looks like it does. edit: I should mention that this is thread-safe in respect to asyncio, but it does involve threads running in parallel, so if sendgrid's API client is not thread-safe for any reason, this will actually be vulnerable to thread safety issues. I don't think this will be the case in cPython due to the GIL, but I can't assert that for certain. I have had exactly one 503 error from SendGrid while interacting in this way, but I don't think it's related to this parallelism and I haven't been able to replicate it. |
@Taywee, after all, I started to communicate with REST API directly it's much easier than fighting with the library in the async environment. |
@stalkerg |
I prefer @stalkerg's solution, mainly because there are several popular async libs and it would be great to better support them all. Then we can add usage examples in the most popular async libs in the docs. Thank you to everyone on this thread (and linked threads) for the thoughtful conversation. And thank you @Taywee for the PR and explanations with sample code! This issue has been added to our internal backlog to be prioritized. Pull requests and +1s on the issue summary will help it move up the backlog. |
@thinkingserious this also should fix this issue #409 ;) |
Interesting, this approach even formalized! |
Since there aren't any working code examples posted above, I figured I'd share what I just cooked up: import aiohttp
from sendgrid import SendGridAPIClient
async def send_async(client, message):
if not isinstance(message, dict):
message = message.get()
async with aiohttp.ClientSession() as session:
async with session.post(f"{client.host}/v3/mail/send",
headers=client._default_headers,
json=message) as resp:
resp.raise_for_status()
return await resp.text()
SendGridAPIClient.send_async = send_async Later, I call with: |
Thanks for the great API and product!
It would be awesome if there was support for asynchronous api calls.
Use Case:
When charging a user's credit card over my REST API I need to call the stripe API ( a few times), then call sendgrid API to send user confirmation message, then call sendgrid again to notify my sales team of a new sale. This takes a bit of time to wait for all the responses and causes my API it be rather slow.
Cheers.
The text was updated successfully, but these errors were encountered: