twilio / twilio-python

A Python module for communicating with the Twilio API and generating TwiML.
MIT License
1.84k stars 703 forks source link

`client.messages.create_async` hanging in FastAPI #731

Open mike-guaranteed opened 10 months ago

mike-guaranteed commented 10 months ago

Issue Summary

A summary of the issue and the environment in which it occurs. If suitable, include the steps required to reproduce the bug. Please feel free to include screenshots, screencasts, or code examples.

Steps to Reproduce

  1. Create a FastAPI app
  2. Create an async route that creates a Client with an AsyncTwilioHttpClient
  3. call await client.messages.create_async()
  4. The future never resolves

Code Snippet

from fastapi import FastAPI

app = FastAPI()

@app.post("/test")
async def test():
    account_sid = os.getenv('TWILIO_ACCOUNT_SID')
    auth_token = os.getenv('TWILIO_AUTH_TOKEN')
    messaging_service_sid = os.getenv('TWILIO_MESSAGING_SERVICE_SID')

    client = Client(account_sid, auth_token, http_client=AsyncTwilioHttpClient())
    message = await client.messages.create_async(    ### never resolves
        messaging_service_sid=messaging_service_sid,
        body='message_content',
        # from_=twilio_number,
        to=phone_number,
    )

If I run create_async like this it works:

async def main():
    account_sid = os.getenv('TWILIO_ACCOUNT_SID')
    auth_token = os.getenv('TWILIO_AUTH_TOKEN')
    messaging_service_sid = os.getenv('TWILIO_MESSAGING_SERVICE_SID')

    client = Client(account_sid, auth_token, http_client=AsyncTwilioHttpClient())
    message = await client.messages.create_async(
        messaging_service_sid=messaging_service_sid,
        body='message_content',
        # from_=twilio_number,
        to=phone_number,
    )

asyncio.run(main())

I have also tried using the regular HTTP client in a non-async path definition, but that also hangs.

Exception/Log

# paste exception/log here

None, the future never resolves

Technical details:

mike-guaranteed commented 10 months ago

I looked into it a bit more, and it seems we were using uvloop in uvicorn because it was available. If I switch uvicorn to useasyncio it still doesn't work. If I use hypercorn with the standard config (asyncio) this code functions fine. If I use hypercorn with uvloop this code does not work. Since it appears the twilio library is not compatible with uvloop, which is fine with us, I can't quite figure out why it won't work in uvicorn with the asyncio event loop, has this behavior been seen before? Our version of uvicorn is 0.23.2.

tiwarishubham635 commented 5 months ago

Hi @mike-guaranteed! I would require more context regarding how you are using uvicorn. We can look into this. Thanks!