idconvert/backend/routers/upload.py

56 lines
1.9 KiB
Python

from fastapi import APIRouter, Depends, UploadFile, File
from fastapi.responses import Response
from typing import Optional
from models.scan import ScanReport
from models.conversion import ConversionRequest, ConversionResult
from services.scan_service import ScanService
from services.conversion_service import ConversionService, get_conversion_result
from dependencies import (
get_scan_service,
get_conversion_service,
get_optional_user,
get_admin_token,
)
router = APIRouter(prefix='/api', tags=['upload'])
@router.post('/scan', response_model=ScanReport)
async def scan_file(
file: UploadFile = File(...),
service: ScanService = Depends(get_scan_service),
):
"""Validate and scan an idconvert_export.json. Costs no credits."""
return await service.scan(file)
@router.post('/convert', response_model=ConversionResult)
async def convert_file(
body: ConversionRequest,
service: ConversionService = Depends(get_conversion_service),
user: Optional[dict] = Depends(get_optional_user),
admin_token: str = Depends(get_admin_token),
):
"""Convert the cached scan to DOCX.
Deducts 1 credit if the user is authenticated via Bearer token.
Works without auth for local development (no credit deduction).
"""
return await service.convert(body.session_id, body.filename, user, admin_token)
@router.get('/download/{session_id}')
async def download_file(session_id: str):
"""Fallback download endpoint when MinIO is not configured."""
result = get_conversion_result(session_id)
if not result:
from fastapi import HTTPException
raise HTTPException(404, 'File not found or session expired')
docx_bytes, filename = result
return Response(
content=docx_bytes,
media_type='application/vnd.openxmlformats-officedocument.wordprocessingml.document',
headers={'Content-Disposition': f'attachment; filename="{filename}"'},
)