"""Pydantic models for AgentForms API."""
from __future__ import annotations
from typing import Any, Literal, Optional
from pydantic import BaseModel, Field
class FieldDefinition(BaseModel):
"""Form field definition."""
name: str = Field(..., description="Snake-case field identifier")
label: str = Field(..., description="Human-readable display label")
type: Literal[
"text", "email", "tel", "textarea", "select", "number", "date", "hidden"
] = Field(..., description="Field type")
required: bool = Field(default=False)
options: Optional[list[str]] = Field(default=None, description="Options for select/radio")
placeholder: Optional[str] = None
default: Optional[str] = None
class Form(BaseModel):
"""Form representation."""
id: int
token: str
name: str
fields: list[FieldDefinition]
created_by: str = "agent"
embed_url: str = ""
submit_url: str = ""
created_at: Optional[str] = None
field_count: Optional[int] = None
metadata: Optional[dict[str, Any]] = None
@property
def public_url(self) -> str:
"""Public URL for humans to fill out the form."""
return f"https://agentforms.io/f/{self.token}"
@property
def share_url(self) -> str:
"""Short share link for messaging."""
return f"https://agentforms.io/{self.token}"
class Submission(BaseModel):
"""Form submission with parsed data."""
id: int
site_id: int
submitted_at: str
dynamic_data: dict[str, Any] = Field(default_factory=dict)
client_ip: Optional[str] = None
user_agent: Optional[str] = None
class ApiKey(BaseModel):
"""API key representation."""
id: int
key_prefix: str
name: str
permissions: Optional[dict[str, bool]] = None
created_at: Optional[str] = None
revoked: bool = False
class WebhookPayload(BaseModel):
"""Incoming webhook payload from AgentForms."""
event: str = "submission"
site_id: int
site_name: str
submission_id: int
submitted_at: str
fields: dict[str, str] = Field(default_factory=dict)
field_metadata: Optional[dict[str, Any]] = None