File size: 3,285 Bytes
32398f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c5addcf
 
32398f2
 
 
 
 
 
 
 
 
 
 
 
f7b5aa2
32398f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c5addcf
32398f2
c5addcf
32398f2
 
 
c5addcf
32398f2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import logging
from fastapi import FastAPI, UploadFile, File, HTTPException, status
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from inference import predict_with_confidence, device

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
    handlers=[
        logging.StreamHandler()
    ]
)
logger = logging.getLogger("deep-detect-api")

# Initialize FastAPI App
app = FastAPI(
    title="Deep-Detect API",
    description="Production-grade API for AI vs Real Image Detection using a custom CNN.",
    version="1.0.0"
)

# Enable CORS middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # Adjust for production
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.api_route("/", methods=["GET", "HEAD"], tags=["General"])
async def root():
    """
    Health check and system information endpoint.
    """
    return {
        "status": "healthy",
        "api_name": "Deep-Detect Image Classification Service",
        "model_architecture": "Custom CNN Standalone (PyTorch)",
        "device_running": str(device),
        "endpoints": {
            "health_check": "/",
            "inference": "/predict"
        }
    }


@app.post("/predict", tags=["Inference"])
async def predict_image(file: UploadFile = File(...)):
    """
    Accepts an uploaded image file, preprocesses it, runs it through
    the custom CNN, and returns whether it is Deep-Fake ('ai') or 'real'.
    """
    logger.info(f"Received prediction request. File: {file.filename}")

    # Validate file extension
    content_type = file.content_type or ""
    if not (content_type.startswith("image/") or file.filename.lower().endswith((".png", ".jpg", ".jpeg"))):
        logger.warning(f"Rejected invalid file format: {file.filename} (Content-Type: {content_type})")
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Uploaded file must be a valid JPEG or PNG image."
        )

    try:
        # Read image bytes
        image_bytes = await file.read()
        if len(image_bytes) == 0:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Uploaded file is empty."
            )

        # Run inference
        label, confidence = predict_with_confidence(image_bytes)
        logger.info(f"Prediction successful for {file.filename} -> Result: {label} (Confidence: {confidence:.2f}%)")

        return {
            "prediction": label,
            "confidence": round(confidence, 2),
            "status": "success"
        }

    except Exception as e:
        logger.error(f"Inference pipeline error: {str(e)}", exc_info=True)
        return JSONResponse(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            content={
                "status": "error",
                "message": "Internal error processing the image. Ensure the image is not corrupted.",
                "details": str(e)
            }
        )


if __name__ == "__main__":
    import uvicorn
    logger.info("Starting Deep-Detect backend server...")
    uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=False)