""" Upload API Routes - Загрузка файлов с OCR и S3 """ from fastapi import APIRouter, UploadFile, File, HTTPException from typing import List import httpx import uuid import os from ..config import settings from ..services.s3_service import s3_service import logging router = APIRouter(prefix="/api/v1/upload", tags=["Upload"]) logger = logging.getLogger(__name__) UPLOAD_DIR = "/tmp/erv_uploads" os.makedirs(UPLOAD_DIR, exist_ok=True) @router.post("/policy") async def upload_policy(file: UploadFile = File(...)): """ Загрузить скан полиса + OCR обработка Returns: - file_id: ID загруженного файла - ocr_text: распознанный текст - extracted_data: извлеченные данные (номер полиса, серия, даты) """ try: # Генерируем уникальный ID file_id = str(uuid.uuid4()) file_ext = file.filename.split('.')[-1] if '.' in file.filename else 'jpg' file_path = f"{UPLOAD_DIR}/{file_id}.{file_ext}" # Сохраняем файл with open(file_path, "wb") as f: content = await file.read() f.write(content) logger.info(f"📄 File saved: {file_path}") # Отправляем на OCR try: async with httpx.AsyncClient(timeout=60.0) as client: with open(file_path, "rb") as f: files = {"file": (file.filename, f, file.content_type)} response = await client.post( f"{settings.ocr_api_url}/process", files=files ) if response.status_code == 200: ocr_result = response.json() logger.info(f"✅ OCR completed for policy") # TODO: Извлечь номер полиса, серию, даты из OCR текста # Используем regex или AI для парсинга return { "success": True, "file_id": file_id, "ocr_text": ocr_result.get("text", ""), "extracted_data": { "policy_number": None, # TODO: парсинг "policy_series": None, "start_date": None, "end_date": None } } else: logger.error(f"OCR error: {response.status_code}") raise HTTPException(status_code=500, detail="OCR service error") except Exception as ocr_error: logger.error(f"OCR processing error: {ocr_error}") # Возвращаем без OCR return { "success": True, "file_id": file_id, "ocr_text": "", "extracted_data": {}, "message": "Файл загружен, но OCR не удалось выполнить" } except Exception as e: logger.error(f"File upload error: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.post("/passport") async def upload_passport(file: UploadFile = File(...)): """ Загрузить скан паспорта + OCR для ФИО Returns: - file_id: ID загруженного файла - ocr_text: распознанный текст - extracted_data: ФИО, дата рождения, серия/номер """ try: file_id = str(uuid.uuid4()) file_ext = file.filename.split('.')[-1] if '.' in file.filename else 'jpg' file_path = f"{UPLOAD_DIR}/{file_id}.{file_ext}" with open(file_path, "wb") as f: content = await file.read() f.write(content) logger.info(f"📄 Passport saved: {file_path}") # OCR обработка try: async with httpx.AsyncClient(timeout=60.0) as client: with open(file_path, "rb") as f: files = {"file": (file.filename, f, file.content_type)} response = await client.post( f"{settings.ocr_api_url}/process", files=files ) if response.status_code == 200: ocr_result = response.json() logger.info(f"✅ OCR completed for passport") # TODO: Извлечь ФИО через regex или AI return { "success": True, "file_id": file_id, "ocr_text": ocr_result.get("text", ""), "extracted_data": { "full_name": None, # TODO: парсинг "birth_date": None, "passport_series": None, "passport_number": None } } else: raise HTTPException(status_code=500, detail="OCR service error") except Exception as ocr_error: logger.error(f"OCR error: {ocr_error}") return { "success": True, "file_id": file_id, "ocr_text": "", "extracted_data": {}, "message": "Файл загружен, но OCR не удалось" } except Exception as e: logger.error(f"Passport upload error: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.post("/files") async def upload_files(files: List[UploadFile] = File(...), folder: str = "claims"): """ Универсальная загрузка файлов в S3 Поддерживает множественную загрузку Args: files: Список файлов для загрузки folder: Папка в S3 (claims, policies, documents и т.д.) Returns: List[dict]: Список загруженных файлов с URLs """ try: uploaded_files = [] for file in files: try: # Читаем содержимое файла content = await file.read() # Загружаем в S3 file_url = await s3_service.upload_file( file_content=content, filename=file.filename, content_type=file.content_type or 'application/octet-stream', folder=folder ) if file_url: uploaded_files.append({ "success": True, "filename": file.filename, "url": file_url, "size": len(content), "content_type": file.content_type }) else: uploaded_files.append({ "success": False, "filename": file.filename, "error": "S3 upload failed" }) except Exception as file_error: logger.error(f"Error uploading {file.filename}: {file_error}") uploaded_files.append({ "success": False, "filename": file.filename, "error": str(file_error) }) return { "success": True, "uploaded_count": len([f for f in uploaded_files if f.get("success")]), "total_count": len(files), "files": uploaded_files } except Exception as e: logger.error(f"Batch upload error: {e}") raise HTTPException(status_code=500, detail=str(e))