Files
sms-api-wrapper/sms/models.py
chelsea db5bde0a70 first commit
Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-04 04:39:53 +00:00

76 lines
2.2 KiB
Python

"""Pydantic models for voip.ms SMS/MMS request and response payloads."""
from __future__ import annotations
from typing import Literal
from pydantic import BaseModel, Field
class SendResult(BaseModel):
"""Result of a successful sendSMS / sendMMS call."""
id: int = Field(..., description="The new SMS/MMS id assigned by voip.ms.")
class SmsRecord(BaseModel):
"""A single SMS row as returned by getSMS.
voip.ms returns a flat object per message; only the commonly-used fields
are typed. Extra fields are ignored so the model stays forward-compatible.
"""
id: str | int
date: str | None = None
type: str | None = Field(None, description="e.g. '1' received / '0' sent")
did: str | None = None
contact: str | None = None
message: str | None = None
model_config = {"extra": "ignore"}
class MmsRecord(BaseModel):
"""A single MMS row as returned by getMMS."""
id: str | int
date: str | None = None
type: str | None = None
did: str | None = None
contact: str | None = None
message: str | None = None
media: str | None = Field(None, description="Comma-separated media file list, if present.")
model_config = {"extra": "ignore"}
class MediaResult(BaseModel):
"""Media attachments for one MMS, from getMediaMMS."""
id: str | int
date: str | None = None
media: list[str] = Field(default_factory=list, description="Up to 3 media URLs/slots.")
class DeleteResult(BaseModel):
"""Result of deleteSMS / deleteMMS."""
status: Literal["success"] = "success"
# --- Request bodies for the FastAPI routes ---------------------------------
class SendSmsRequest(BaseModel):
did: str = Field(..., description="Sender DID (10 digits, or +1... for e164).")
dst: str = Field(..., description="Destination number.")
message: str = Field(..., max_length=160)
class SendMmsRequest(BaseModel):
did: str
dst: str
message: str = Field(..., max_length=2048)
media1: str | None = Field(None, description="URL to a media file.")
media2: str | None = Field(None, description="Base64-encoded image (data:image/...;base64,...).")
media3: str | None = Field(None, description="Reserved; usually empty.")