satupeta-main/app/api/v1/routes/file_route.py

99 lines
3.4 KiB
Python
Raw Normal View History

2026-01-27 02:11:58 +00:00
from typing import Optional
from fastapi import (
APIRouter,
Depends,
File,
Form,
HTTPException,
Response,
UploadFile,
status,
)
from fastapi.responses import StreamingResponse
from app.api.dependencies.auth import get_current_active_user
from app.api.dependencies.factory import Factory
from app.core.data_types import UUID7Field
from app.core.params import CommonParams
from app.models import UserModel
from app.schemas.base import PaginatedResponse
from app.schemas.file_schema import FileSchema
from app.services import FileService
router = APIRouter()
@router.get("/files", response_model=PaginatedResponse[FileSchema], dependencies=[Depends(get_current_active_user)])
async def get_files(params: CommonParams = Depends(), service: FileService = Depends(Factory().get_file_service)):
filter = params.filter
sort = params.sort
search = params.search
group_by = params.group_by
limit = params.limit
offset = params.offset
files, total = await service.find_all(filter, sort, search, group_by, limit, offset)
return PaginatedResponse(
items=[FileSchema.model_validate(file) for file in files],
total=total,
limit=limit,
offset=offset,
has_more=total > (offset + limit),
)
@router.get("/files/{id}", response_model=FileSchema)
async def get_file(id: UUID7Field, service: FileService = Depends(Factory().get_file_service)):
file = await service.find_by_id(id)
return file
@router.post("/files", response_model=FileSchema, status_code=status.HTTP_201_CREATED)
async def upload_file(
file: UploadFile = File(...),
description: Optional[str] = Form(None),
current_user: UserModel = Depends(get_current_active_user),
service: FileService = Depends(Factory().get_file_service),
):
result = await service.upload_file(file=file, description=description, user_id=current_user.id)
return result
@router.get("/files/{file_id}", response_model=FileSchema, summary="Dapatkan metadata file")
async def get_file_info(file_id: UUID7Field, service: FileService = Depends(Factory().get_file_service)):
file = await service.find_by_id(file_id)
if not file:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="File tidak ditemukan")
return file
@router.get("/files/{file_id}/download", summary="Download file")
async def download_file(file_id: UUID7Field, service: FileService = Depends(Factory().get_file_service)):
file_content, object_info, file_model = await service.get_file_content(file_id)
async def iterfile():
try:
chunk = await file_content.content.read(8192)
while chunk:
yield chunk
chunk = await file_content.content.read(8192)
finally:
await file_content.release()
return StreamingResponse(
iterfile(),
media_type=file_model.content_type,
headers={"Content-Disposition": f'attachment; filename="{file_model.filename}"'},
)
@router.delete("/files/{file_id}", status_code=status.HTTP_204_NO_CONTENT, summary="Hapus file")
async def delete_file(
file_id: UUID7Field,
current_user: UserModel = Depends(get_current_active_user),
service: FileService = Depends(Factory().get_file_service),
):
await service.delete_file_with_content(file_id, str(current_user.id))
return Response(status_code=status.HTTP_204_NO_CONTENT)