aliyun.py 6.8 KB

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