Skip to content

Commit

Permalink
fix(backend-services): use sync Twilio API call in executor (#568)
Browse files Browse the repository at this point in the history
  • Loading branch information
billguo99 authored May 23, 2023
1 parent 76f7244 commit bb02f6f
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 20 deletions.
57 changes: 40 additions & 17 deletions backend-services/src/auth_service/operations/twilio_2fa.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
from concurrent.futures import ThreadPoolExecutor

from fastapi import HTTPException
from twilio.rest import Client
Expand All @@ -11,33 +12,55 @@
)
from common.settings import AppSettings

executor = ThreadPoolExecutor()


def send_sms(client: Client, params: dict) -> str | None:
# Perform Twilio API calls here
verification = client.verify.v2.services(
params["service_sid"]
).verifications.create(to=params["phone_number"], channel="sms")
return verification.sid


def check_otp_verification(client: Client, params: dict) -> str | None:
# Perform Twilio API calls here
verification_check = client.verify.v2.services(
params["service_sid"]
).verification_checks.create(
verification_sid=params["verification_sid"], code=params["otp"]
)
return verification_check.status


async def send_otp_to_user(
settings: AppSettings, client: Client, params: SendOtp
) -> SendOtpResponse:
loop = asyncio.get_event_loop()
asyncio.set_event_loop(loop) # Set the Twilio client's event loop as the default

verification = await client.verify.v2.services(
settings.twilio_service_sid
).verifications.create_async(to=params.phone_number, channel="sms")

asyncio.set_event_loop(None) # Reset the default event loop

if verification.sid is None:
send_sms_params = {
"service_sid": settings.twilio_service_sid,
"phone_number": params.phone_number,
}
verification_sid = await loop.run_in_executor(
executor, send_sms, client, send_sms_params
)
if verification_sid is None:
raise HTTPException(500)
return SendOtpResponse(verification_sid=verification.sid)
return SendOtpResponse(verification_sid=verification_sid)


async def check_otp_verification_status(
settings: AppSettings, client: Client, params: CheckOtpStatus
) -> CheckOtpStatusResponse:
verification_check = await client.verify.v2.services(
settings.twilio_service_sid
).verification_checks.create_async(
verification_sid=params.verification_sid, code=params.otp
loop = asyncio.get_event_loop()
check_otp_params = {
"service_sid": settings.twilio_service_sid,
"verification_sid": params.verification_sid,
"otp": params.otp,
}
status = await loop.run_in_executor(
executor, check_otp_verification, client, check_otp_params
)

if verification_check.status is None:
if status is None:
raise HTTPException(500)
return CheckOtpStatusResponse(status=verification_check.status)
return CheckOtpStatusResponse(status=status)
3 changes: 0 additions & 3 deletions backend-services/src/web_asgi/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from fastapi.middleware.cors import CORSMiddleware
from motor.motor_asyncio import AsyncIOMotorClient
from odmantic import AIOEngine
from twilio.http.async_http_client import AsyncTwilioHttpClient
from twilio.rest import Client as TwilioClient

from auth_service.schema.actions import (
Expand Down Expand Up @@ -60,11 +59,9 @@
database=app_settings.wallet_db_name,
)

twilio_http_client = AsyncTwilioHttpClient()
twilio_client = TwilioClient(
app_settings.twilio_account_sid,
app_settings.twilio_auth_token,
http_client=twilio_http_client,
)

origins = [str(app_settings.primary_origin)]
Expand Down

0 comments on commit bb02f6f

Please sign in to comment.