seaweedfs_service.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import requests
  2. from fastapi import UploadFile
  3. from app.core.biz_exception import NotFoundError, PermissionDeniedError, BizLogicError
  4. from app.core.logger import logger
  5. class SeaweedFSService:
  6. MASTER_URL = "http://127.0.0.1:9333" # 你的 SeaweedFS master 地址
  7. @classmethod
  8. def upload(cls, file: UploadFile):
  9. """上传文件到 SeaweedFS"""
  10. try:
  11. # 1️⃣ 获取可上传的 volume 地址
  12. assign_resp = requests.get(f"{cls.MASTER_URL}/dir/assign", timeout=5)
  13. assign_data = assign_resp.json()
  14. fid = assign_data["fid"]
  15. public_url = assign_data["publicUrl"]
  16. # 2️⃣ 上传文件数据
  17. upload_url = f"http://{public_url}/{fid}"
  18. download_url = f"http://45.137.220.138:8888/api/resource/download_file?fid={fid}"
  19. files = {"file": (file.filename, file.file, file.content_type)}
  20. upload_resp = requests.post(upload_url, files=files, timeout=10)
  21. if upload_resp.status_code == 201:
  22. return {"fid": fid, "url": download_url}
  23. else:
  24. raise BizLogicError(f"file upload error: {upload_resp.text}")
  25. except Exception as e:
  26. raise BizLogicError(f"file upload exception: {e}")
  27. @classmethod
  28. def get(cls, fid: str):
  29. """根据 fid 读取文件"""
  30. try:
  31. resp = requests.get(f"{cls.MASTER_URL}/dir/lookup?volumeId={fid.split(',')[0]}", timeout=5)
  32. data = resp.json()
  33. if not data.get("locations"):
  34. return None
  35. public_url = data["locations"][0]["publicUrl"]
  36. file_url = f"http://{public_url}/{fid}"
  37. file_resp = requests.get(file_url, timeout=10)
  38. if file_resp.status_code == 200:
  39. return file_resp.content, file_resp.headers.get("Content-Type", "application/octet-stream")
  40. else:
  41. return None
  42. except Exception as e:
  43. logger.exception(f"SeaweedFS 读取异常, 原因={e}")
  44. return None
  45. @classmethod
  46. def delete(cls, fid: str):
  47. """删除文件"""
  48. try:
  49. resp = requests.get(f"{cls.MASTER_URL}/dir/lookup?volumeId={fid.split(',')[0]}", timeout=5)
  50. data = resp.json()
  51. if not data.get("locations"):
  52. return False
  53. public_url = data["locations"][0]["publicUrl"]
  54. delete_url = f"http://{public_url}/{fid}"
  55. del_resp = requests.delete(delete_url, timeout=10)
  56. return del_resp.status_code == 202
  57. except Exception as e:
  58. logger.exception(f"SeaweedFS 删除异常, 原因={e}")
  59. return False