260 lines
8.9 KiB
Python
260 lines
8.9 KiB
Python
"""Pydantic models for component logic requests and responses."""
|
|
|
|
from typing import Dict, Any, List, Optional
|
|
from pydantic import BaseModel, EmailStr, validator
|
|
import re
|
|
|
|
# AI Research Models
|
|
|
|
class UserInfoRequest(BaseModel):
|
|
"""Request model for user information validation."""
|
|
full_name: str
|
|
email: str
|
|
company: str
|
|
role: str
|
|
|
|
@validator('full_name')
|
|
def validate_full_name(cls, v):
|
|
if not v or len(v.strip()) < 2:
|
|
raise ValueError('Full name must be at least 2 characters long')
|
|
return v.strip()
|
|
|
|
@validator('email')
|
|
def validate_email(cls, v):
|
|
# Basic email validation
|
|
email_pattern = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')
|
|
if not email_pattern.match(v):
|
|
raise ValueError('Invalid email format')
|
|
return v.lower()
|
|
|
|
@validator('company')
|
|
def validate_company(cls, v):
|
|
if not v or len(v.strip()) < 1:
|
|
raise ValueError('Company name is required')
|
|
return v.strip()
|
|
|
|
@validator('role')
|
|
def validate_role(cls, v):
|
|
valid_roles = ["Content Creator", "Marketing Manager", "Business Owner", "Other"]
|
|
if v not in valid_roles:
|
|
raise ValueError(f'Role must be one of: {", ".join(valid_roles)}')
|
|
return v
|
|
|
|
class ResearchPreferencesRequest(BaseModel):
|
|
"""Request model for research preferences configuration."""
|
|
research_depth: str
|
|
content_types: List[str]
|
|
auto_research: bool
|
|
factual_content: bool = True # Default to True
|
|
|
|
@validator('research_depth')
|
|
def validate_research_depth(cls, v):
|
|
valid_depths = ["Basic", "Standard", "Deep", "Comprehensive"]
|
|
if v not in valid_depths:
|
|
raise ValueError(f'Research depth must be one of: {", ".join(valid_depths)}')
|
|
return v
|
|
|
|
@validator('content_types')
|
|
def validate_content_types(cls, v):
|
|
valid_types = ["Blog Posts", "Social Media", "Technical Articles", "News", "Academic Papers"]
|
|
if not v:
|
|
raise ValueError('At least one content type must be selected')
|
|
for content_type in v:
|
|
if content_type not in valid_types:
|
|
raise ValueError(f'Invalid content type: {content_type}')
|
|
return v
|
|
|
|
class ResearchRequest(BaseModel):
|
|
"""Request model for research processing."""
|
|
topic: str
|
|
preferences: ResearchPreferencesRequest
|
|
|
|
@validator('topic')
|
|
def validate_topic(cls, v):
|
|
if not v or len(v.strip()) < 3:
|
|
raise ValueError('Topic must be at least 3 characters long')
|
|
return v.strip()
|
|
|
|
class UserInfoResponse(BaseModel):
|
|
"""Response model for user information validation."""
|
|
valid: bool
|
|
user_info: Optional[Dict[str, Any]] = None
|
|
errors: List[str] = []
|
|
|
|
class ResearchPreferencesResponse(BaseModel):
|
|
"""Response model for research preferences configuration."""
|
|
valid: bool
|
|
preferences: Optional[Dict[str, Any]] = None
|
|
errors: List[str] = []
|
|
|
|
class ResearchResponse(BaseModel):
|
|
"""Response model for research processing."""
|
|
success: bool
|
|
topic: str
|
|
results: Optional[Dict[str, Any]] = None
|
|
error: Optional[str] = None
|
|
|
|
# Personalization Models
|
|
|
|
class ContentStyleRequest(BaseModel):
|
|
"""Request model for content style configuration."""
|
|
writing_style: str
|
|
tone: str
|
|
content_length: str
|
|
|
|
@validator('writing_style')
|
|
def validate_writing_style(cls, v):
|
|
valid_styles = ["Professional", "Casual", "Technical", "Conversational", "Academic"]
|
|
if v not in valid_styles:
|
|
raise ValueError(f'Writing style must be one of: {", ".join(valid_styles)}')
|
|
return v
|
|
|
|
@validator('tone')
|
|
def validate_tone(cls, v):
|
|
valid_tones = ["Formal", "Semi-Formal", "Neutral", "Friendly", "Humorous"]
|
|
if v not in valid_tones:
|
|
raise ValueError(f'Tone must be one of: {", ".join(valid_tones)}')
|
|
return v
|
|
|
|
@validator('content_length')
|
|
def validate_content_length(cls, v):
|
|
valid_lengths = ["Concise", "Standard", "Detailed", "Comprehensive"]
|
|
if v not in valid_lengths:
|
|
raise ValueError(f'Content length must be one of: {", ".join(valid_lengths)}')
|
|
return v
|
|
|
|
class BrandVoiceRequest(BaseModel):
|
|
"""Request model for brand voice configuration."""
|
|
personality_traits: List[str]
|
|
voice_description: Optional[str] = None
|
|
keywords: Optional[str] = None
|
|
|
|
@validator('personality_traits')
|
|
def validate_personality_traits(cls, v):
|
|
valid_traits = ["Professional", "Innovative", "Friendly", "Trustworthy", "Creative", "Expert"]
|
|
if not v:
|
|
raise ValueError('At least one personality trait must be selected')
|
|
for trait in v:
|
|
if trait not in valid_traits:
|
|
raise ValueError(f'Invalid personality trait: {trait}')
|
|
return v
|
|
|
|
@validator('voice_description')
|
|
def validate_voice_description(cls, v):
|
|
if v and len(v.strip()) < 10:
|
|
raise ValueError('Voice description must be at least 10 characters long')
|
|
return v.strip() if v else None
|
|
|
|
class AdvancedSettingsRequest(BaseModel):
|
|
"""Request model for advanced content generation settings."""
|
|
seo_optimization: bool
|
|
readability_level: str
|
|
content_structure: List[str]
|
|
|
|
@validator('readability_level')
|
|
def validate_readability_level(cls, v):
|
|
valid_levels = ["Simple", "Standard", "Advanced", "Expert"]
|
|
if v not in valid_levels:
|
|
raise ValueError(f'Readability level must be one of: {", ".join(valid_levels)}')
|
|
return v
|
|
|
|
@validator('content_structure')
|
|
def validate_content_structure(cls, v):
|
|
valid_structures = ["Introduction", "Key Points", "Examples", "Conclusion", "Call-to-Action"]
|
|
if not v:
|
|
raise ValueError('At least one content structure element must be selected')
|
|
for structure in v:
|
|
if structure not in valid_structures:
|
|
raise ValueError(f'Invalid content structure: {structure}')
|
|
return v
|
|
|
|
class PersonalizationSettingsRequest(BaseModel):
|
|
"""Request model for complete personalization settings."""
|
|
content_style: ContentStyleRequest
|
|
brand_voice: BrandVoiceRequest
|
|
advanced_settings: AdvancedSettingsRequest
|
|
|
|
class ContentStyleResponse(BaseModel):
|
|
"""Response model for content style validation."""
|
|
valid: bool
|
|
style_config: Optional[Dict[str, Any]] = None
|
|
errors: List[str] = []
|
|
|
|
class BrandVoiceResponse(BaseModel):
|
|
"""Response model for brand voice configuration."""
|
|
valid: bool
|
|
brand_config: Optional[Dict[str, Any]] = None
|
|
errors: List[str] = []
|
|
|
|
class PersonalizationSettingsResponse(BaseModel):
|
|
"""Response model for complete personalization settings."""
|
|
valid: bool
|
|
settings: Optional[Dict[str, Any]] = None
|
|
errors: List[str] = []
|
|
|
|
# Research Utilities Models
|
|
|
|
class ResearchTopicRequest(BaseModel):
|
|
"""Request model for topic research."""
|
|
topic: str
|
|
api_keys: Dict[str, str]
|
|
|
|
@validator('topic')
|
|
def validate_topic(cls, v):
|
|
if not v or len(v.strip()) < 3:
|
|
raise ValueError('Topic must be at least 3 characters long')
|
|
return v.strip()
|
|
|
|
class ResearchResultResponse(BaseModel):
|
|
"""Response model for research results."""
|
|
success: bool
|
|
topic: str
|
|
data: Optional[Dict[str, Any]] = None
|
|
error: Optional[str] = None
|
|
metadata: Optional[Dict[str, Any]] = None
|
|
|
|
# Style Detection Models
|
|
class StyleAnalysisRequest(BaseModel):
|
|
"""Request model for style analysis."""
|
|
content: Dict[str, Any]
|
|
analysis_type: str = "comprehensive" # comprehensive, patterns, guidelines
|
|
|
|
class StyleAnalysisResponse(BaseModel):
|
|
"""Response model for style analysis."""
|
|
success: bool
|
|
analysis: Optional[Dict[str, Any]] = None
|
|
patterns: Optional[Dict[str, Any]] = None
|
|
guidelines: Optional[Dict[str, Any]] = None
|
|
error: Optional[str] = None
|
|
timestamp: str
|
|
|
|
class WebCrawlRequest(BaseModel):
|
|
"""Request model for web crawling."""
|
|
url: Optional[str] = None
|
|
text_sample: Optional[str] = None
|
|
|
|
class WebCrawlResponse(BaseModel):
|
|
"""Response model for web crawling."""
|
|
success: bool
|
|
content: Optional[Dict[str, Any]] = None
|
|
metrics: Optional[Dict[str, Any]] = None
|
|
error: Optional[str] = None
|
|
timestamp: str
|
|
|
|
class StyleDetectionRequest(BaseModel):
|
|
"""Request model for complete style detection workflow."""
|
|
url: Optional[str] = None
|
|
text_sample: Optional[str] = None
|
|
include_patterns: bool = True
|
|
include_guidelines: bool = True
|
|
|
|
class StyleDetectionResponse(BaseModel):
|
|
"""Response model for complete style detection workflow."""
|
|
success: bool
|
|
crawl_result: Optional[Dict[str, Any]] = None
|
|
style_analysis: Optional[Dict[str, Any]] = None
|
|
style_patterns: Optional[Dict[str, Any]] = None
|
|
style_guidelines: Optional[Dict[str, Any]] = None
|
|
error: Optional[str] = None
|
|
warning: Optional[str] = None
|
|
timestamp: str |