feat: implement contact form submission endpoint with validation

This commit is contained in:
Backend IM Bot 2025-04-28 17:39:08 +00:00
parent f417477a20
commit 2e4a41227b
3 changed files with 39 additions and 23 deletions

View File

@ -1,31 +1,19 @@
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi import APIRouter, Depends, status
from sqlalchemy.orm import Session
from typing import Dict, Any
from core.database import get_db
from schemas.contact_form import ContactFormCreate
from helpers.contact_form_helpers import handle_contact_form_submission
router = APIRouter()
@router.post("/form", status_code=status.HTTP_201_CREATED)
async def submit_contact_form(
form_data: ContactFormCreate,
form_data: Dict[str, Any],
db: Session = Depends(get_db)
):
"""
Submit a contact form with name, email, and message.
All fields are required and email must be in valid format.
Endpoint to handle contact form submissions.
Requires name, email, and message fields.
Validates that all fields are provided and email is in valid format.
"""
try:
result = handle_contact_form_submission(
db=db,
form_data=form_data.dict()
)
return result
except HTTPException:
# Re-raise the HTTPException from the helper
raise
except Exception as e:
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"An error occurred while processing the form: {str(e)}"
)
return handle_contact_form_submission(db, form_data)

View File

@ -26,6 +26,7 @@ def create_contact_form(db: Session, contact_data: ContactFormCreate) -> Contact
def validate_contact_form_data(form_data: Dict[str, Any]) -> Dict[str, Union[bool, str]]:
"""
Validates contact form data, checking for required fields and email format.
Uses external email_validator package for robust email validation.
Args:
form_data (Dict[str, Any]): The form data to validate.
@ -36,16 +37,16 @@ def validate_contact_form_data(form_data: Dict[str, Any]) -> Dict[str, Union[boo
- 'error': Error message if validation fails, None otherwise
"""
# Check for required fields
if 'name' not in form_data or not form_data.get('name'):
if 'name' not in form_data or not form_data.get('name') or not form_data.get('name').strip():
return {'valid': False, 'error': 'Name is required'}
if 'email' not in form_data or not form_data.get('email'):
return {'valid': False, 'error': 'Email is required'}
if 'message' not in form_data or not form_data.get('message'):
if 'message' not in form_data or not form_data.get('message') or not form_data.get('message').strip():
return {'valid': False, 'error': 'Message is required'}
# Validate email format
# Validate email format using the external email_validator package
try:
validate_email(form_data['email'])
except EmailNotValidError as e:
@ -109,6 +110,8 @@ def handle_contact_form_submission(
) -> Dict[str, Any]:
"""
Processes a contact form submission with validation.
Performs specific validation for required fields (name, email, message)
and returns appropriate 400 error responses for missing or invalid fields.
Args:
db (Session): The database session.
@ -118,7 +121,7 @@ def handle_contact_form_submission(
Dict[str, Any]: Response data with status and message.
Raises:
HTTPException: If validation fails with a 400 status code.
HTTPException: If validation fails with a 400 status code and specific error message.
"""
# Validate form data
validation_result = validate_contact_form_data(form_data)

View File

@ -1,6 +1,7 @@
from pydantic import BaseModel, EmailStr, Field
from datetime import datetime
from uuid import UUID
from pydantic import validator
# Base schema for ContactForm, used for inheritance
class ContactFormBase(BaseModel):
@ -8,6 +9,18 @@ class ContactFormBase(BaseModel):
email: EmailStr = Field(..., description="Contact's email address")
message: str = Field(..., description="Contact message")
@validator('name')
def name_must_not_be_empty(cls, v):
if not v.strip():
raise ValueError('Name cannot be empty')
return v
@validator('message')
def message_must_not_be_empty(cls, v):
if not v.strip():
raise ValueError('Message cannot be empty')
return v
# Schema for creating a new ContactForm
class ContactFormCreate(ContactFormBase):
pass
@ -18,6 +31,18 @@ class ContactFormUpdate(BaseModel):
email: EmailStr = Field(..., description="Contact's email address")
message: str = Field(..., description="Contact message")
@validator('name')
def name_must_not_be_empty(cls, v):
if not v.strip():
raise ValueError('Name cannot be empty')
return v
@validator('message')
def message_must_not_be_empty(cls, v):
if not v.strip():
raise ValueError('Message cannot be empty')
return v
# Schema for representing a ContactForm in responses
class ContactFormSchema(ContactFormBase):
id: UUID