Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion fastapi-twilio/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
./venv
./__pycache__
./__pycache__
.env
3 changes: 3 additions & 0 deletions fastapi-twilio/.gitignore copy
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
./venv
./__pycache__
.env
12 changes: 6 additions & 6 deletions fastapi-twilio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ Make API Calls using Hoppscotch, Postman or cURL command. Keploy with capture th
1. Replace the place holder below i.e. `YOUR_REGISTERED_PERSONAL_PHONE_NUMBER` with your registered personal phone number that you linked with Twilio.

```bash
curl --location 'http://127.0.0.1:8000/send-sms/' \
--header 'Content-Type: application/json' \
--data-raw '{
curl -X 'http://127.0.0.1:8000/send-sms/' \
-H 'Content-Type: application/json' \
-d '{
"Body": "Test",
"To": "<OUR_REGISTERED_PERSONAL_PHONE_NUMBER>"
}'
Expand All @@ -49,9 +49,9 @@ curl --location 'http://127.0.0.1:8000/send-sms/' \
2. Replace the place holder below i.e. `SOME_WRONG_PHONE_NUMBER` with any wrong phone number and make the request.

```bash
curl --location 'http://127.0.0.1:8000/send-sms/' \
--header 'Content-Type: application/json' \
--data-raw '{
curl -X 'http://127.0.0.1:8000/send-sms/' \
-H 'Content-Type: application/json' \
-d '{
"Body": "Test, testtt, testttttttssss :)",
"To": "<SOME_WRONG_PHONE_NUMBER>",
}'
Expand Down
90 changes: 62 additions & 28 deletions fastapi-twilio/main.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,79 @@
from fastapi import FastAPI
import requests
from dotenv import load_dotenv
from pydantic import BaseModel
from fastapi import FastAPI, Form, Response
from contextlib import asynccontextmanager
import logging
import os
import asyncio
import httpx
from dotenv import load_dotenv
from pydantic import BaseModel, Field
from twilio.twiml.messaging_response import MessagingResponse
from fastapi.responses import JSONResponse

# Load environment variables from a .env file
load_dotenv()

# Setup logging
logging.basicConfig(level=logging.INFO)


# Pydantic model for request validation
class Message(BaseModel):
Body: str
To: str
Body: str = Field(..., min_length=1, max_length=160)
To: str = Field(..., pattern=r"^\+\d{10,15}$")





# Lifespan handler (replaces @app.on_event("startup"))
@asynccontextmanager
async def lifespan(app: FastAPI):
logging.info("Starting FastAPI app...")
yield
logging.info("Shutting down gracefully...")

app = FastAPI()

@app.post('/send-sms/')
def send_sms(data: Message):

app = FastAPI(lifespan=lifespan)




@app.post("/send-sms/")
async def send_sms(data: Message):

twilio_account_sid = os.getenv('TWILIO_ACCOUNT_SID')
twilio_auth_token = os.getenv('TWILIO_AUTH_TOKEN')
twilio_phone_number = os.getenv('TWILIO_NUMBER')

url = f'https://api.twilio.com/2010-04-01/Accounts/{twilio_account_sid}/Messages.json'
if not all([twilio_account_sid, twilio_auth_token, twilio_phone_number]):
logging.error("Missing Twilio environment variables.")
return JSONResponse(status_code=500, content={"message": "Twilio credentials are not set properly."})

url = f"https://api.twilio.com/2010-04-01/Accounts/{twilio_account_sid}/Messages.json"
payload = {
'Body': data.Body,
'From': twilio_phone_number,
'To': data.To
}

try:
response = requests.post(url=url, data=payload, auth=(twilio_account_sid, twilio_auth_token))
if response.status_code == 201:
return {"message": "SMS sent successfully!"}
else:
return {"message": "Failed to send SMS. Please check the provided phone number."}
except Exception as e:
return {"message": str(e)}

# Graceful shutdown
@app.on_event("shutdown")
async def shutdown_event():
print("Shutting down gracefully...")
# Perform any additional cleanup here if needed
# For example, closing database connections or other resources

async with httpx.AsyncClient() as client:
try:
response = await client.post(
url=url,
data=payload,
auth=(twilio_account_sid, twilio_auth_token)
)
if response.status_code in [200, 201]:
return {"message": "SMS sent successfully!"}
else:
logging.error(f"Twilio error: {response.status_code} - {response.text}")
return JSONResponse(status_code=response.status_code, content={
"message": "Failed to send SMS",
"details": response.text
})
except httpx.RequestError as e:
logging.error(f"HTTPX error: {e}")
return JSONResponse(status_code=500, content={"message": f"An error occurred: {str(e)}"})

@app.get("/")
async def health_check():
return {"status": "ok"}
2 changes: 2 additions & 0 deletions fastapi-twilio/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ PyYAML==6.0
rich==13.3.1
six==1.16.0
ssh-import-id==5.10
httpx
pydantic
5 changes: 5 additions & 0 deletions fastapi-twilio/run_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!bin/bash

curl -X POST "http://localhost:8000/send-sms/" \
-H 'Content-Type: application/json' \
-d '{"Body": "Keploy test!", "To": "+919999999999"}'