fact-checker-backend/app/api/fact_check.py
2024-12-11 17:39:10 +06:00

96 lines
No EOL
2.9 KiB
Python

from fastapi import APIRouter, HTTPException
import json
from datetime import datetime
from typing import Dict
from app.config import GOOGLE_API_KEY, GOOGLE_FACT_CHECK_BASE_URL
from app.models.fact_check_models import (
FactCheckResponse, FactCheckRequest, Claim, ErrorResponse
)
from app.websites.fact_checker_website import fetch_fact_checks, get_all_sources
fact_check_router = APIRouter()
class CustomJSONEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
return super().default(obj)
@fact_check_router.post(
"/check-facts",
response_model=FactCheckResponse,
responses={
400: {"model": ErrorResponse},
404: {"model": ErrorResponse},
500: {"model": ErrorResponse},
503: {"model": ErrorResponse}
}
)
async def check_facts(request: FactCheckRequest) -> FactCheckResponse:
"""
Check facts using multiple fact-checking sources
"""
all_results = []
# Validate configuration
if not GOOGLE_API_KEY or not GOOGLE_FACT_CHECK_BASE_URL:
raise HTTPException(
status_code=500,
detail=ErrorResponse(
detail="API configuration is missing",
error_code="CONFIGURATION_ERROR",
path="/check-facts"
).dict()
)
# Get all sources in priority order
all_sources = get_all_sources()
for source in all_sources:
try:
result = await fetch_fact_checks(
GOOGLE_API_KEY,
GOOGLE_FACT_CHECK_BASE_URL,
request.content,
source
)
if "claims" in result:
# Validate each claim through Pydantic
validated_claims = [
Claim(**claim).dict()
for claim in result["claims"]
]
all_results.extend(validated_claims)
except HTTPException:
raise
except Exception as e:
# Log the error but continue with other sources
print(f"Error processing {source.domain}: {str(e)}")
continue
if not all_results:
raise HTTPException(
status_code=404,
detail=ErrorResponse(
detail="No fact check results found",
error_code="NO_RESULTS_FOUND",
path="/check-facts"
).dict()
)
# Create the response using Pydantic model
response = FactCheckResponse(
query=request.content,
total_claims_found=len(all_results),
results=all_results,
summary={
"total_sources": len(set(claim.get("claimReview", [{}])[0].get("publisher", {}).get("site", "")
for claim in all_results if claim.get("claimReview"))),
"fact_checking_sites_queried": len(all_sources)
}
)
return response