Spaces:
Running
Running
| from fastapi import FastAPI, File, UploadFile, Body | |
| from fastapi.responses import RedirectResponse | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from PIL import Image | |
| import io | |
| import numpy as np | |
| from structure import ImagePredictionResponse, TextPredictionRequest, TextPredictionResponse, PredictionEntry | |
| from textPreprocess import predict_text | |
| from imagePreprocess import CNNPredict, CLIPPredict | |
| import tensorflow as tf | |
| origins=[ | |
| "http://localhost:5173", | |
| "http://localhost", | |
| "https://authentica-ai.vercel.app", | |
| ] | |
| app = FastAPI( | |
| title="Authentica API", | |
| description=( | |
| "Simple demo API for image and text prediction. " | |
| "Upload an image to `/predict/image` or POST text to `/predict/text`." | |
| ), | |
| version="0.1.0", | |
| ) | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=origins, | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| async def root(): | |
| # Redirect to the automatic Swagger UI provided by FastAPI | |
| return RedirectResponse(url="/docs") | |
| async def predict(image: UploadFile = File(...)): | |
| """Accept an image upload and return a prediction using loaded model.""" | |
| image_data = await image.read() | |
| pil_img = Image.open(io.BytesIO(image_data)).convert("RGB") | |
| predictions=[] | |
| cnnPred = CNNPredict(pil_img) | |
| if isinstance(cnnPred, str): | |
| # An error occurred during CNN prediction | |
| print("CNN preprocessing error:", cnnPred) | |
| predictions.append(PredictionEntry(model="CNN", error=cnnPred, predicted_class=-1, confidence=0.0)) | |
| else: | |
| cnn_class = 1 if cnnPred >= 0.5 else 0 | |
| cnn_conf = cnnPred if cnnPred >= 0.5 else 1 - cnnPred | |
| predictions.append( PredictionEntry(model="CNN", predicted_class=cnn_class, confidence=round(float(cnn_conf), 4))) | |
| clipPred = CLIPPredict(pil_img) | |
| if isinstance(clipPred, str): | |
| # An error occurred during CLIP prediction | |
| print("CLIP error:", clipPred) | |
| predictions.append(PredictionEntry(model="CLIP", error=clipPred, predicted_class=-1, confidence=0.0)) | |
| else: | |
| clip_class = 1 if clipPred > 0.5 else 0 | |
| clip_conf = clipPred if clipPred >= 0.5 else 1 - clipPred | |
| predictions.append( PredictionEntry(model="CLIP", predicted_class=clip_class, confidence=round(float(clip_conf), 4))) | |
| #print(f"CNN Prediction (AI prob): {cnnPred:.4f}") | |
| #print(f"ResNet Prediction (AI prob): {resnetPred:.4f}") | |
| #print(f"CLIP Prediction (AI prob): {clipPred:.4f}") | |
| #Predicted classes 1 is Real, 0 is AI | |
| return ImagePredictionResponse(predictions=predictions) | |
| async def predict_text_endpoint(payload: TextPredictionRequest = Body(...)): | |
| """Accept a text string and return a prediction of whether it's human or AI-generated.""" | |
| try: | |
| # Use the text prediction function from textPreprocess.py | |
| result = predict_text(payload.text) | |
| return TextPredictionResponse( | |
| predicted_class=result["predicted_class"], | |
| confidence_ai=result["confidence_ai"], | |
| confidence_human=result["confidence_human"] | |
| ) | |
| except Exception as e: | |
| # Return a fallback response in case of error | |
| print(f"Error in text prediction: {e}") | |
| return TextPredictionResponse(predicted_class="Human", confidence_ai=-100.0, confidence_human=-100.0) |