3
0

oss.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. # -*- coding: utf-8 -*-
  2. """
  3. Created on 2024-02-26
  4. ---------
  5. @summary: oss附件服务
  6. ---------
  7. """
  8. from io import BytesIO
  9. import oss2
  10. import requests
  11. import feapder.setting as setting
  12. class AttachmentError(Exception):
  13. def __init__(self, *args, **kwargs):
  14. if 'code' not in kwargs and 'reason' not in kwargs:
  15. kwargs['code'] = 0
  16. kwargs['reason'] = '附件错误'
  17. if 'reason' in kwargs and kwargs['reason'] is None:
  18. kwargs['reason'] = '附件错误'
  19. for key, val in kwargs.items():
  20. setattr(self, key, val)
  21. super(AttachmentError, self).__init__(*args, kwargs)
  22. class OssClient(object):
  23. def __init__(self, domain: str):
  24. # 初始化函数,用于创建类的实例
  25. self.domain = domain
  26. def upload(self, args: dict) -> dict:
  27. reply = {"error_code": -1}
  28. try:
  29. files = {
  30. 'file': (args['object_name'], BytesIO(args['stream'])),
  31. }
  32. data = {
  33. 'bucket_id': args['bucket_id'],
  34. 'object_name': args['object_name'],
  35. 'gzip': args.get('gzip', False),
  36. }
  37. response = requests.post(
  38. f"{self.domain}/ossservice/upload",
  39. files=files,
  40. data=data,
  41. timeout=300,
  42. )
  43. if response.status_code == 200:
  44. reply.update(response.json())
  45. else:
  46. reply['error_msg'] = f"HTTP error: {response.status_code}"
  47. except Exception as e:
  48. reply['error_msg'] = str(e)
  49. return reply
  50. def download(self, args: dict):
  51. reply = {}
  52. try:
  53. data = {
  54. "bucket_id": args["bucket_id"],
  55. "object_name": args["object_name"]
  56. }
  57. url = f"{self.domain}/ossservice/download"
  58. response = requests.post(url, data=data, timeout=300)
  59. response.raise_for_status()
  60. reply["error_code"] = 0
  61. reply["error_msg"] = "下载成功"
  62. reply["data"] = response.content
  63. except Exception as e:
  64. reply["error_code"] = -1
  65. reply["error_msg"] = str(e)
  66. return reply
  67. def delete(self, args: dict):
  68. reply = {}
  69. try:
  70. data = {
  71. "bucket_id": args["bucket_id"],
  72. "object_name": args["object_name"]
  73. }
  74. url = f"{self.domain}/ossservice/delete"
  75. response = requests.post(url, data=data, timeout=10)
  76. response.raise_for_status()
  77. reply = response.json()
  78. reply["error_code"] = 0
  79. except Exception as e:
  80. reply["error_code"] = -1
  81. reply["error_msg"] = str(e)
  82. return reply
  83. class JyOssClient:
  84. def __init__(self, domain=None, mode=None):
  85. if domain is None:
  86. domain = setting.JY_OSS_URL
  87. if mode == "test":
  88. domain = setting.JY_OSS_URL_TEST
  89. self._oss_client = OssClient(domain=domain)
  90. def upload(self, bucket_id, object_name, stream, gzip=False, retries=3, err_show=True):
  91. """
  92. 上传附件
  93. :param str bucket_id: 文件名
  94. :param str object_name: 对象名称
  95. :param bytes stream: 文件流
  96. :param bool gzip: 是否压缩
  97. :param int retries: 上传最大重试次数
  98. :param bool err_show: 是否展示错误
  99. """
  100. args = {
  101. "bucket_id": bucket_id,
  102. "object_name": object_name,
  103. "gzip": gzip,
  104. "stream": stream
  105. }
  106. ret = {"error_msg": "附件上传错误", "error_code": -1}
  107. for _ in range(retries):
  108. ret = self._oss_client.upload(args)
  109. if ret["error_code"] == 0:
  110. return ret
  111. if err_show:
  112. raise AttachmentError(reason=ret.get("error_msg") or "附件上传错误")
  113. return ret
  114. def download(self, bucket_id, object_name, retries=3, err_show=False):
  115. """
  116. 下载附件
  117. :param str bucket_id: 文件名
  118. :param str object_name: 对象名称
  119. :param int retries: 下载最大重试次数
  120. :param bool err_show: 是否展示错误
  121. """
  122. args = {
  123. "bucket_id": bucket_id,
  124. "object_name": object_name,
  125. }
  126. ret = {"error_msg": "附件下载失败", "error_code": -1}
  127. for _ in range(retries):
  128. ret = self._oss_client.download(args)
  129. if ret["error_code"] == 0 or ret["error_code"] == -1:
  130. return ret
  131. if err_show:
  132. raise AttachmentError(reason=ret.get("error_msg") or "附件下载失败")
  133. return ret
  134. def delete(self, bucket_id, object_name, retries=3, err_show=False):
  135. """
  136. 删除附件
  137. :param str bucket_id: 文件名
  138. :param str object_name: 对象名称
  139. :param int retries: 删除最大重试次数
  140. :param bool err_show: 是否展示错误
  141. """
  142. args = {
  143. "bucket_id": bucket_id,
  144. "object_name": object_name,
  145. }
  146. ret = {"error_msg": "附件删除失败", "error_code": -1}
  147. for _ in range(retries):
  148. ret = self._oss_client.delete(args)
  149. if ret["error_code"] == 0:
  150. return ret
  151. if err_show:
  152. raise AttachmentError(reason=ret.get("error_msg") or "附件删除失败")
  153. return ret
  154. class OssBucketClient:
  155. def __init__(self):
  156. key_id = setting.ALI_BUCKET_CONFIG['key_id']
  157. key_secret = setting.ALI_BUCKET_CONFIG['key_secret']
  158. endpoint = setting.ALI_BUCKET_CONFIG['endpoint']
  159. bucket_name = setting.ALI_BUCKET_CONFIG['bucket_name']
  160. auth = oss2.Auth(key_id, key_secret)
  161. self._bucket = oss2.Bucket(auth, endpoint, bucket_name)
  162. def put_object_from_file(self, key, filename):
  163. """
  164. 上传一个本地文件到OSS的普通文件
  165. :param str key: 上传到OSS的文件名
  166. :param str filename: 本地文件名,需要有可读权限
  167. """
  168. self._bucket.put_object_from_file(key, filename)
  169. def put_object(self, key, data):
  170. """
  171. 流式上传oss
  172. :param str key: 上传到OSS的文件名
  173. :param data: 待上传的内容。
  174. :type data: bytes,str或file-like object
  175. """
  176. self._bucket.put_object(key, data)
  177. AliYunService = OssBucketClient