api-admim/app/s3/router_s3.py

171 lines
5.9 KiB
Python

# Importações de bibliotecas padrão
from typing import Annotated
# Importações de bibliotecas de terceiros
from fastapi import APIRouter, Depends, UploadFile, File, HTTPException
from starlette import status
# Importações do seu próprio projeto
from app.routers.dependencies import get_repository
from app.s3.RepositoryS3 import RepositoryS3
from app.rbac.permissions import verify_permissions
from app.database.models import RbacUser, S3Arquivo
from app.s3 import schema_s3
db_model = S3Arquivo
rota_prefix = "/api/s3/arquivos"
rota_tags = "S3 Arquivos"
repository_base = Annotated[
RepositoryS3[db_model],
Depends(get_repository(db_model, RepositoryS3)),
]
router = APIRouter(
prefix=rota_prefix,
tags=[rota_tags],
responses={404: {"description": "Not found"}},
)
@router.post("/upload", status_code=status.HTTP_200_OK, response_model=schema_s3.ArquivoRetorno)
async def upload_to_s3(
repository: repository_base,
file: UploadFile = File(...),
# repository: S3Repository[db_model] = Depends(get_repository_simple_table(S3Arquivo)),
user: RbacUser = Depends(verify_permissions([1, 2, 33, 401]))):
"""
Faz upload de uma imagem para o bucket restrito e registra no banco de dados.
"""
try:
# Chamar a função do repositório para realizar o upload e salvar no banco
resultado = await repository.upload_to_s3(
conteudo=file.file,
nome_original=file.filename,
tipo_conteudo=file.content_type,
inquilino=user.fk_inquilino_uuid
)
return resultado
except HTTPException as e:
raise e # Relevanta a exceção HTTP já tratada no repositório
except Exception as e:
raise HTTPException(status_code=500, detail=f"Erro inesperado: {str(e)}")
@router.post("/url/")
async def get_presigned_url(
request: schema_s3.FileNameRequest,
repository: repository_base,
user: RbacUser = Depends(verify_permissions([1, 2, 33, 401])), # Permissões necessárias
):
"""
Gera uma URL pré-assinada para download do arquivo, com o nome original configurado.
"""
try:
# Chamar a função do repositório para gerar a URL pré-assinada
presigned_url = await repository.get_presigned_url(
uuid=request.uuid,
inquilino=user.fk_inquilino_uuid
)
return {"url": presigned_url}
except HTTPException as e:
raise e # Relança exceções HTTP já tratadas no repositório
except Exception as e:
raise HTTPException(status_code=500, detail=f"Erro inesperado: {str(e)}")
@router.post("/url/simple/")
async def generate_presigned_url(
request: schema_s3.FileNameRequest,
repository: repository_base,
user: RbacUser = Depends(verify_permissions([1, 2, 33, 401])), # Permissões necessárias
):
"""
Gera uma URL pré-assinada para acessar o arquivo no MinIO (sem download automático).
"""
try:
# Chamar a função do repositório para gerar a URL pré-assinada
presigned_url = await repository.generate_presigned_url(
uuid=request.uuid,
inquilino=user.fk_inquilino_uuid # Passa diretamente o UUID do inquilino
)
return {"url": presigned_url}
except HTTPException as e:
raise e # Relança exceções HTTP já tratadas no repositório
except Exception as e:
raise HTTPException(status_code=500, detail=f"Erro inesperado: {str(e)}")
@router.post("/")
async def get_file(
request: schema_s3.FileNameRequest,
repository: repository_base,
user: RbacUser = Depends(verify_permissions([1, 2, 33, 401])), # Permissões necessárias
):
"""
Retorna uma imagem específica para download.
O usuário precisa estar autenticado para acessar.
"""
try:
# Chamar a função do repositório para obter a imagem como streaming
response = await repository.get_file(
uuid=request.uuid,
inquilino=user.fk_inquilino_uuid # Passa diretamente o UUID do inquilino
)
return response
except HTTPException as e:
raise e # Relança exceções HTTP já tratadas no repositório
except Exception as e:
raise HTTPException(status_code=500, detail=f"Erro inesperado: {str(e)}")
@router.post("/inline/")
async def get_file_inline(
request: schema_s3.FileNameRequest,
repository: repository_base,
user: RbacUser = Depends(verify_permissions([1, 2, 33, 401])), # Permissões necessárias
):
"""
Retorna uma imagem ou arquivo específico para exibição inline (sem download automático).
O usuário precisa estar autenticado para acessar.
"""
try:
# Chamar a função do repositório para obter o streaming da imagem
response = await repository.get_file_inline(
uuid=request.uuid,
inquilino=user.fk_inquilino_uuid # Passa diretamente o UUID do inquilino
)
return response
except HTTPException as e:
raise e # Relança exceções HTTP já tratadas no repositório
except Exception as e:
raise HTTPException(status_code=500, detail=f"Erro inesperado: {str(e)}")
@router.delete("/")
async def delete_file(
request: schema_s3.FileNameRequest,
repository: repository_base,
user: RbacUser = Depends(verify_permissions([1, 2, 33, 401])), # Permissões necessárias
):
"""
Exclui um arquivo do S3 e remove seu registro do banco de dados.
"""
try:
# Chamar a função do repositório para excluir o arquivo
result = await repository.delete_file_from_s3(
uuid=request.uuid,
inquilino=user.fk_inquilino_uuid # Passa diretamente o UUID do inquilino
)
return result
except HTTPException as e:
raise e # Relança exceções HTTP já tratadas no repositório
except Exception as e:
raise HTTPException(status_code=500, detail=f"Erro inesperado: {str(e)}")