چرا فریمورک FastAPI بهترین گزینه برای توسعه وبسرویسهای پیامکی مدرن است؟
در سالهای اخیر، FastAPI به محبوبترین فریمورک پایتون برای ساخت میکروسرویسهای مدرن با کارایی بالا تبدیل شده است. معماری غیرهمزمان (Asynchronous) بر پایه asyncio و Starlette به FastAPI اجازه میدهد تا دهها هزار درخواست همزمان I/O-bound (مانند فراخوانی API ارسال پیامک) را بدون مسدود شدن حلقه رویداد (Event Loop) پردازش نماید.
هنگام ارسال کدهای تایید OTP یا کمپینهای پیامکی، اگر برنامه از کلاینتهای مسدودکننده سنتی نظیر requests استفاده کند، تاخیر شبکه موجب کندی کل سرور خواهد شد. در این راهنما، نحوه پیادهسازی سرویس پیامک با httpx و پیادهسازی اندپوینت Webhook دریافت گزارش وضعیت تحویل (DLR) در فری اس ام اس را بررسی میکنیم.
معماری کلاینت غیرهمزمان با httpx در FastAPI
با تعریف یک نشست کلاینت پایدار با استفاده از lifespan در FastAPI، میتوان کانکشنهای TCP را باز نگه داشت و تاخیر Handshake را به حداقل ممکن رساند.
from fastapi import FastAPI, HTTPException, status
from pydantic import BaseModel, Field
import httpx
from contextlib import asynccontextmanager
FREE_SMS_API_URL = "https://api.free-sms.ir/v1/otp/send"
API_KEY = "YOUR_FREE_SMS_API_KEY"
http_client: httpx.AsyncClient = None
@asynccontextmanager
async def lifespan(app: FastAPI):
global http_client
# ایجاد کانکشن پول پایدار برای ارتباطات وبسرویس
http_client = httpx.AsyncClient(timeout=5.0)
yield
await http_client.aclose()
app = FastAPI(title="Free SMS FastAPI Microservice", lifespan=lifespan)
class OTPRequest(BaseModel):
mobile: str = Field(..., pattern=r"^09[0-9]{9}$", example="09123456789")
code: str = Field(..., min_length=4, max_length=6, example="8492")
@app.post("/api/v1/auth/send-otp", status_code=status.HTTP_200_OK)
async def send_verification_otp(payload: OTPRequest):
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
payload_data = {
"mobile": payload.mobile,
"template_id": 104,
"parameters": {"code": payload.code}
}
try:
response = await http_client.post(FREE_SMS_API_URL, headers=headers, json=payload_data)
response.raise_for_status()
data = response.json()
return {"status": "success", "message_id": data.get("message_id")}
except httpx.HTTPStatusError as exc:
raise HTTPException(status_code=exc.response.status_code, detail="SMS Gateway Error")
except Exception as exc:
raise HTTPException(status_code=500, detail=str(exc))
پیادهسازی وبهوک وضعیت تحویل پیامک (Delivery Status Webhook)
هنگامی که پیامک به گوشی مخاطب میرسد، دیتاسنتر فری اس ام اس یک رویداد HTTP POST به آدرس وبهوک شما ارسال میکند. در FastAPI میتوانید این گزارش را بلافاصله دریافت و وضعیت را در دیتابیس (مانند PostgreSQL یا MongoDB) بهروزرسانی کنید:
from fastapi import Request
class WebhookDeliveryPayload(BaseModel):
message_id: int
status: str # e.g., 'delivered', 'failed', 'blacklisted'
delivered_at: str
@app.post("/api/v1/sms/webhook")
async def handle_delivery_report(payload: WebhookDeliveryPayload):
# لاگ یا آپدیت وضعیت پیامک در دیتابیس
print(f"Message {payload.message_id} status updated to: {payload.status}")
# پاسخ سریع 200 جهت تایید دریافت وبهوک
return {"received": True}
جدول مقایسه عملکرد معماری همگام (Sync) در برابر ناهمگام (Async)
| معیار بررسی عملکرد | کتابخانه requests (همگام / Blocking) | FastAPI + httpx (ناهمگام / Non-blocking) |
|---|---|---|
| تعداد ارسال در ثانیه در یک هسته CPU | حدود ۳۰ تا ۵۰ درخواست | بیش از ۲,۵۰۰ درخواست در ثانیه |
| اشغال حافظه RAM و مدیریت رشتهها | نیاز به Thread Pool حجیم | تکترد سبک بر پایه Co-routines |
| رفتار در صورت تاخیر شبکه مخابرات | قفل شدن تمام سرویس و خطای تایماوت | مدیریت مستقل بدون کوچکترین اثر بر سایر تسکها |
| پشتیبانی از کدهای پترن OTP | مستلزم تنظیمات دستی | پشتیبانی ذاتی با خط خدماتی زیر ۲ ثانیه |
X-Signature را با کلید مخفی خود با الگوریتم SHA256 تطبیق دهید تا از عدم جعل دادهها اطمینان حاصل شود.
سوالات متداول (FAQ)
چرا نباید از کتابخانه requests در FastAPI برای ارسال پیامک استفاده کرد؟+
چون کتابخانه requests همگام (blocking) است و زمان انتظار برای پاسخ وبسرویس پیامک، حلقه رویداد اصلی سرور FastAPI را قفل میکند و ظرفیت پذیرش همزمان کاربران را به شدت کاهش میدهد.
وبهوک تحویل (DLR) در فری اس ام اس چگونه کار میکند؟+
به محض تحویل پیامک به آنتن موبایل کاربر، سرور فری اس ام اس یک درخواست POST با فرمت JSON شامل شناسه پیامک و وضعیت تحویل به URL تعریفشده توسط شما ارسال مینماید.
آیا خط خدماتی اشتراکی در پایتون بدون سفته فعال میشود؟+
بله؛ خط خدماتی اشتراکی رایگان بلافاصله پس از ثبتنام در فری اس ام اس بدون سفته در اختیار شما قرار میگیرد و کدهای OTP را به بلکلیست میرساند.
سرعت ارسال پیامک با وبسرویس فری اس ام اس در پایتون چقدر است؟+
پاسخ HTTP وبسرویس پترن زیر ۱۰۰ میلیثانیه برگردانده شده و کد تایید ظرف کمتر از ۲ ثانیه بر روی تلفن همراه کاربر زنگ میخورد.