API для работы с файлами, индексация файлов и результатов распощнавания
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File as FastAPIFile, status
|
||||
from fastapi.responses import FileResponse
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List
|
||||
import os
|
||||
import uuid
|
||||
import aiofiles
|
||||
|
||||
from apiApp.database import get_db
|
||||
from apiApp.schemas import (
|
||||
AudioCreate,
|
||||
AudioResponse,
|
||||
AudioListResponse,
|
||||
MessageResponse
|
||||
)
|
||||
from apiApp.services import AudioCRUD
|
||||
from apiApp.config import UPLOAD_FOLDER, ALLOWED_AUDIO_EXTENSIONS, MAX_UPLOAD_SIZE
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.post("/upload", response_model=AudioResponse, status_code=status.HTTP_201_CREATED)
|
||||
async def upload_audio_file(
|
||||
file: UploadFile = FastAPIFile(...),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Загрузка аудиофайла на сервер
|
||||
"""
|
||||
# Проверка расширения файла
|
||||
file_ext = os.path.splitext(file.filename)[1].lower()
|
||||
if file_ext not in ALLOWED_AUDIO_EXTENSIONS:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
detail=f"File extension not allowed. Allowed: {', '.join(ALLOWED_AUDIO_EXTENSIONS)}"
|
||||
)
|
||||
|
||||
# Чтение содержимого файла
|
||||
content = await file.read()
|
||||
|
||||
# Проверка размера файла
|
||||
if len(content) > MAX_UPLOAD_SIZE:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
|
||||
detail=f"File too large. Maximum size: {MAX_UPLOAD_SIZE / (1024*1024)}MB"
|
||||
)
|
||||
|
||||
# Сохранение файла
|
||||
file_path = UPLOAD_FOLDER / f"{uuid.uuid4()}{file_ext}"
|
||||
|
||||
try:
|
||||
async with aiofiles.open(file_path, 'wb') as f:
|
||||
await f.write(content)
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Error saving file: {str(e)}"
|
||||
)
|
||||
|
||||
# Создание записи в БД
|
||||
try:
|
||||
audio_data = AudioCreate(filename=file.filename)
|
||||
audio = AudioCRUD.create(
|
||||
db=db,
|
||||
audio_data=audio_data,
|
||||
file_path=str(file_path),
|
||||
file_size=len(content)
|
||||
)
|
||||
return audio
|
||||
except Exception as e:
|
||||
# Удаление файла при ошибке записи в БД
|
||||
if os.path.exists(file_path):
|
||||
os.remove(file_path)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Error creating database record: {str(e)}"
|
||||
)
|
||||
|
||||
|
||||
@router.get("/audio/list", response_model=AudioListResponse)
|
||||
async def list_audio_files(
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Получить список всех аудиофайлов
|
||||
"""
|
||||
audios = AudioCRUD.get_all(db)
|
||||
return AudioListResponse(
|
||||
audios=audios[skip:skip+limit],
|
||||
count=len(audios)
|
||||
)
|
||||
|
||||
|
||||
@router.get("/audio/{audio_id}", response_model=AudioResponse)
|
||||
async def get_audio(
|
||||
audio_id: uuid.UUID,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Получить информацию о аудиофайле по ID
|
||||
"""
|
||||
audio = AudioCRUD.get_by_id(db, audio_id)
|
||||
if not audio:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Audio not found"
|
||||
)
|
||||
return audio
|
||||
|
||||
|
||||
@router.get("/audio/file/{audio_id}")
|
||||
async def download_audio_file(
|
||||
audio_id: uuid.UUID,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Скачать аудиофайл по ID
|
||||
"""
|
||||
audio = AudioCRUD.get_by_id(db, audio_id)
|
||||
if not audio:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Audio not found"
|
||||
)
|
||||
|
||||
if not audio.file_path or not os.path.exists(audio.file_path):
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Audio file not found on disk"
|
||||
)
|
||||
|
||||
return FileResponse(
|
||||
path=audio.file_path,
|
||||
filename=audio.filename,
|
||||
media_type='audio/mpeg'
|
||||
)
|
||||
|
||||
|
||||
@router.delete("/audio/delete/{audio_id}", response_model=AudioResponse)
|
||||
async def delete_audio(
|
||||
audio_id: uuid.UUID,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Удалить аудиофайл
|
||||
"""
|
||||
audio = AudioCRUD.delete(db, audio_id)
|
||||
if not audio:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
detail="Audio not found"
|
||||
)
|
||||
return audio
|
||||
Reference in New Issue
Block a user