added image ai-moderation
This commit is contained in:
66
ai-moderation/app/routers/image_moderation_router.py
Normal file
66
ai-moderation/app/routers/image_moderation_router.py
Normal file
@@ -0,0 +1,66 @@
|
||||
from fastapi import APIRouter, UploadFile, File, Depends, HTTPException
|
||||
|
||||
from PIL import Image, UnidentifiedImageError
|
||||
|
||||
from app.services.image_moderation_service import ImageModerationService
|
||||
from app.core.dependencies import get_image_moderation_service
|
||||
from app.models.response.image_moderation_response import ImageModerationResponse
|
||||
|
||||
|
||||
router = APIRouter(
|
||||
prefix="/api/v1/moderation",
|
||||
tags=["Moderation"]
|
||||
)
|
||||
|
||||
MAX_SIZE = 5 * 1024 * 1024 # например, 5 МБ
|
||||
|
||||
ALLOWED_CONTENT_TYPES = (
|
||||
"image/jpeg",
|
||||
"image/png",
|
||||
"image/webp",
|
||||
)
|
||||
|
||||
|
||||
@router.post("/image", response_model=ImageModerationResponse)
|
||||
def moderate_image(
|
||||
file: UploadFile = File(...),
|
||||
service: ImageModerationService = Depends(get_image_moderation_service)
|
||||
):
|
||||
|
||||
# 1. Проверка content-type — самая дешёвая, делаем её первой
|
||||
if file.content_type not in ALLOWED_CONTENT_TYPES:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Unsupported image format"
|
||||
)
|
||||
|
||||
# 2. Проверка размера — читаем файл целиком
|
||||
contents = file.file.read()
|
||||
|
||||
if len(contents) > MAX_SIZE:
|
||||
raise HTTPException(
|
||||
status_code=413,
|
||||
detail="Image too large"
|
||||
)
|
||||
|
||||
file.file.seek(0) # обязательно вернуть указатель в начало!
|
||||
|
||||
# 3. Только теперь пытаемся открыть изображение
|
||||
try:
|
||||
image = Image.open(file.file)
|
||||
image = image.convert("RGB")
|
||||
except UnidentifiedImageError:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail="Invalid image"
|
||||
)
|
||||
|
||||
prediction = service.moderate(image)
|
||||
|
||||
return ImageModerationResponse(
|
||||
approved=prediction.approved,
|
||||
score=prediction.score,
|
||||
reason=prediction.reason,
|
||||
label=prediction.label,
|
||||
detected_labels=prediction.detected_labels
|
||||
)
|
||||
37
ai-moderation/app/routers/text_moderation_router.py
Normal file
37
ai-moderation/app/routers/text_moderation_router.py
Normal file
@@ -0,0 +1,37 @@
|
||||
from fastapi import APIRouter
|
||||
from typing import Annotated
|
||||
from fastapi import Depends
|
||||
|
||||
from app.models.dto.text_request import TextRequest
|
||||
from app.models.response.moderation_response import ModerationResponse
|
||||
from app.services.text_moderation_service import TextModerationService
|
||||
|
||||
|
||||
from app.core.dependencies import (
|
||||
get_text_moderation_service
|
||||
)
|
||||
|
||||
router = APIRouter(
|
||||
prefix="/api/v1/moderation",
|
||||
tags=["Moderation"]
|
||||
)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/text",
|
||||
response_model=ModerationResponse
|
||||
)
|
||||
def moderate_text(
|
||||
request: TextRequest,
|
||||
service: Annotated[
|
||||
TextModerationService,
|
||||
Depends(get_text_moderation_service)
|
||||
]
|
||||
):
|
||||
prediction = service.moderate(request.text)
|
||||
|
||||
return ModerationResponse(
|
||||
approved=prediction.approved,
|
||||
score=prediction.score,
|
||||
reason=prediction.reason
|
||||
)
|
||||
Reference in New Issue
Block a user