| from fastapi import APIRouter, HTTPException |
|
|
| from app.config import get_settings |
| from app.core.errors import VendorError |
| from app.schemas.requests import FollowSchemaRequest |
| from app.services.factory import AIServiceFactory |
| from app.utils.logger import exception_to_str, setup_logger |
|
|
| logger = setup_logger(__name__) |
| settings = get_settings() |
|
|
|
|
| async def handle_follow(request: FollowSchemaRequest): |
|
|
| request.max_attempts = max(request.max_attempts, 1) |
| request.max_attempts = min(request.max_attempts, 5) |
|
|
| for attempt in range(1, request.max_attempts + 1): |
| try: |
| logger.info(f"Attempt: {attempt}") |
| if request.ai_model in settings.OPENAI_MODELS: |
| ai_vendor = "openai" |
| elif request.ai_model in settings.ANTHROPIC_MODELS: |
| ai_vendor = "anthropic" |
| else: |
| raise ValueError( |
| f"Invalid AI model: {request.ai_model}, only support {settings.SUPPORTED_MODELS}" |
| ) |
| service = AIServiceFactory.get_service(ai_vendor) |
| json_attributes = await service.follow_schema_with_validation( |
| request.data_schema, request.data |
| ) |
| break |
| except ValueError as e: |
| if attempt == request.max_attempts: |
| raise HTTPException( |
| status_code=400, |
| detail=exception_to_str(e), |
| headers={"attempt": attempt}, |
| ) |
| except VendorError as e: |
| if attempt == request.max_attempts: |
| raise HTTPException( |
| status_code=500, |
| detail=exception_to_str(e), |
| headers={"attempt": attempt}, |
| ) |
| except Exception as e: |
| if attempt == request.max_attempts: |
| raise HTTPException( |
| status_code=500, |
| detail="Internal server error", |
| headers={"attempt": attempt}, |
| ) |
|
|
| return json_attributes, attempt |
|
|