HR-ATS-Portal/backend/s3/views.py

80 lines
2.8 KiB
Python

"""S3 storage service — upload / delete / health over the plugins S3 class."""
from fastapi import HTTPException,UploadFile
from s3.plugins import S3,S3ServiceError,assert_pdf
from s3.serializers import serialize_delete,serialize_health,serialize_upload
class S3Storage:
"""No DB session — pure object storage against the configured bucket."""
def __init__(self):
self.s3=S3()
def _map(self,exc:S3ServiceError):
raise HTTPException(status_code=exc.status_code,detail=exc.message)
async def health_check(self):
try:
return serialize_health(self.s3.head_bucket())
except S3ServiceError as e:
self._map(e)
async def upload_for_record(self,file:UploadFile,source,record_id,owner_id):
"""PDF gate → PutObject under {source}/{record_id}/{owner_id}/{name}.pdf."""
if file is None:
raise HTTPException(status_code=422,detail="file is required")
filename=(file.filename or "").strip() or "resume.pdf"
try:
assert_pdf(filename,file.content_type)
except S3ServiceError as e:
self._map(e)
body=await file.read()
if not body:
raise HTTPException(status_code=422,detail="file is empty")
try:
result=self.s3.upload_for_record(
body,
filename,
source=source,
record_id=record_id,
owner_id=owner_id,
content_type=file.content_type,
)
return serialize_upload(result)
except S3ServiceError as e:
self._map(e)
async def upload_bytes_for_record(self,body,filename,source,record_id,owner_id,content_type=None):
try:
assert_pdf(filename or "resume.pdf",content_type)
result=self.s3.upload_for_record(
body,
filename or "resume.pdf",
source=source,
record_id=record_id,
owner_id=owner_id,
content_type=content_type,
)
return serialize_upload(result)
except S3ServiceError as e:
self._map(e)
async def delete_file(self,key):
if not key or not str(key).strip():
raise HTTPException(status_code=422,detail="key is required")
try:
return serialize_delete(self.s3.delete_object(str(key).strip()))
except S3ServiceError as e:
self._map(e)
async def object_url(self,key):
if not key or not str(key).strip():
raise HTTPException(status_code=422,detail="key is required")
try:
url=self.s3.permanent_object_url(str(key).strip())
return {"key":str(key).strip(),"url":url}
except S3ServiceError as e:
self._map(e)