lesscode-flask 0.1.77__tar.gz → 0.1.79__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/PKG-INFO +1 -1
  2. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/__init__.py +1 -1
  3. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/log/access_log_handler.py +4 -1
  4. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/oss/__init__.py +39 -16
  5. lesscode_flask-0.1.79/lesscode_flask/utils/oss/aliyun_oss.py +202 -0
  6. lesscode_flask-0.1.79/lesscode_flask/utils/oss/minio_oss.py +254 -0
  7. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask.egg-info/PKG-INFO +1 -1
  8. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask.egg-info/SOURCES.txt +2 -0
  9. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/README.md +0 -0
  10. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/app.py +0 -0
  11. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/db/__init__.py +0 -0
  12. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/db/datasource.py +0 -0
  13. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/db/executor.py +0 -0
  14. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/export_data/__init__.py +0 -0
  15. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/export_data/data_download_handler.py +0 -0
  16. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/model/access_log.py +0 -0
  17. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/model/base_model.py +0 -0
  18. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/model/parameterized_query.py +0 -0
  19. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/model/resource_param_template.py +0 -0
  20. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/model/response_result.py +0 -0
  21. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/model/user.py +0 -0
  22. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/service/access_log_service.py +0 -0
  23. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/service/base_service.py +0 -0
  24. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/service/resource_param_template_service.py +0 -0
  25. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/setting/__init__.py +0 -0
  26. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/setup/__init__.py +0 -0
  27. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/signals.py +0 -0
  28. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/static/swagger.py +0 -0
  29. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/decorator/__init__.py +0 -0
  30. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/decorator/cache.py +0 -0
  31. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/decorator/swagger.py +0 -0
  32. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/dify_utils.py +0 -0
  33. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/file/file_exporter.py +0 -0
  34. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/file/file_utils.py +0 -0
  35. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/helpers.py +0 -0
  36. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/json/NotSortJSONProvider.py +0 -0
  37. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/oss/ks3_oss.py +0 -0
  38. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/redis/redis_helper.py +0 -0
  39. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/request/request.py +0 -0
  40. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/swagger/swagger_template.py +0 -0
  41. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/swagger/swagger_util.py +0 -0
  42. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/task/__init__.py +0 -0
  43. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/task/task_helper.py +0 -0
  44. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/thread/thread_utils.py +0 -0
  45. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/wsgi.py +0 -0
  46. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask.egg-info/dependency_links.txt +0 -0
  47. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask.egg-info/requires.txt +0 -0
  48. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask.egg-info/top_level.txt +0 -0
  49. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/query_runner/__init__.py +0 -0
  50. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/query_runner/clickhouse.py +0 -0
  51. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/query_runner/elasticsearch.py +0 -0
  52. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/query_runner/kingbase.py +0 -0
  53. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/query_runner/mysql.py +0 -0
  54. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/query_runner/pg.py +0 -0
  55. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/settings/__init__.py +0 -0
  56. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/settings/helpers.py +0 -0
  57. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/utils/__init__.py +0 -0
  58. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/utils/requests_session.py +0 -0
  59. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/setup.cfg +0 -0
  60. {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lesscode-flask
3
- Version: 0.1.77
3
+ Version: 0.1.79
4
4
  Summary: lesscode-flask 是基于flask的web开发脚手架项目,该项目初衷为简化开发过程,让研发人员更加关注业务。
5
5
  Home-page: https://lesscode-flask
6
6
  Author: Chao.yy
@@ -1,4 +1,4 @@
1
- __version__ = '0.1.77'
1
+ __version__ = '0.1.79'
2
2
 
3
3
  import functools
4
4
  import logging
@@ -54,7 +54,10 @@ class AccessLogHandler(Handler):
54
54
  except Exception as e:
55
55
  pass
56
56
  location: str = iputil.get_region(client_ip)
57
- current_user = flask_login.current_user
57
+ if hasattr(request, "user"):
58
+ current_user = getattr(request, "user")
59
+ else:
60
+ current_user = flask_login.current_user
58
61
  access_log = AccessLog(request_id=request_id, display_name=current_user.display_name,
59
62
  obj_id=current_user.id, type=current_user.type, client_id=client_id,
60
63
  resource_id=resource_id, location=location,sub=current_user.sub,
@@ -2,7 +2,9 @@ import os
2
2
  from io import BytesIO
3
3
 
4
4
  from lesscode_flask.utils.helpers import app_config
5
+ from lesscode_flask.utils.oss.aliyun_oss import AliYunOss
5
6
  from lesscode_flask.utils.oss.ks3_oss import Ks3Oss
7
+ from lesscode_flask.utils.oss.minio_oss import MinioOss
6
8
 
7
9
 
8
10
  class CommonOss:
@@ -12,7 +14,7 @@ class CommonOss:
12
14
  Args:
13
15
  storage_type (str): 存储类型,目前支持ks3和file
14
16
  data_type (str): 数据类型,目前支持stream和file_path
15
- storage_config (dict): 存储配置,目前支持ks3和file,file_name
17
+ storage_config (dict): 存储配置,目前支持ks3和file,file_name,aliyun,minio
16
18
  """
17
19
  _storage_config = app_config.get("STORAGE_CONFIG", {}).get(config_key, {}) or dict()
18
20
  self.storage_type = storage_type if storage_type else _storage_config.get("storage_type", "")
@@ -20,25 +22,37 @@ class CommonOss:
20
22
  self.storage_config = kwargs.get("storage_config", {}) if kwargs.get("storage_config",
21
23
  {}) else _storage_config.get(
22
24
  "storage_config", {})
25
+ self.bucket_name = kwargs.get("bucket_name") or self.storage_config.pop("bucket_name", "")
23
26
 
24
- def _save(self, key, io_stream: BytesIO = None, file_path: str = None):
27
+ def _save(self, key, io_stream: BytesIO = None, file_path: str = None, bucket_name: str = None):
25
28
  file_url_obj = dict()
26
29
  if self.storage_type == "ks3":
27
30
  if self.data_type == "stream":
28
31
  storage_config = self.storage_config or dict()
29
- ks3 = Ks3Oss(**storage_config)
30
- url = ks3.save(key=key, string_data=io_stream.getvalue(), content_type="string", policy="public-read")
32
+ ks3 = Ks3Oss(bucket_name=self.bucket_name, **storage_config)
33
+ url = ks3.save(key=key, string_data=io_stream.getvalue(), content_type="string", policy="public-read",
34
+ bucket_name=bucket_name or self.bucket_name)
31
35
  file_url_obj = {"key": key, "url": url}
32
36
  elif self.data_type == "file_path":
33
37
  storage_config = self.storage_config or dict()
34
- ks3 = Ks3Oss(**storage_config)
38
+ ks3 = Ks3Oss(bucket_name=self.bucket_name, **storage_config)
35
39
  url = ks3.save(key=key, filename=file_path, content_type="filename", policy="public-read")
36
40
  file_url_obj = {"key": key, "url": url}
41
+ elif self.storage_type == "aliyun":
42
+ storage_config = self.storage_config or dict()
43
+ aliyun = AliYunOss(bucket_name=self.bucket_name, **storage_config)
44
+ url = aliyun.save(key=key, content_type="string", data=io_stream.getvalue(),
45
+ bucket_name=bucket_name or self.bucket_name)
46
+ file_url_obj = {"key": key, "url": url}
47
+ elif self.storage_type == "minio":
48
+ storage_config = self.storage_config or dict()
49
+ minio = MinioOss(**storage_config)
50
+ url = minio.save(key=key, content_type="string", data=io_stream.getvalue(),
51
+ bucket_name=bucket_name or self.bucket_name)
52
+ file_url_obj = {"key": key, "url": url}
37
53
  elif self.storage_type == "file":
38
54
  storage_path = ""
39
- storage_dir = self.storage_config.get("storage_dir", "")
40
- if not storage_dir:
41
- storage_dir = app_config.get("STORAGE_DIR")
55
+ storage_dir = self.storage_config.get("STORAGE_DIR", "")
42
56
  if not storage_dir:
43
57
  raise Exception("storage_dir is empty")
44
58
  if self.data_type == "stream":
@@ -73,6 +87,7 @@ class CommonOss:
73
87
  """
74
88
  file_url_list = []
75
89
  files = kwargs.get("files", [])
90
+ bucket_name = kwargs.get("bucket_name", self.bucket_name)
76
91
  if not files:
77
92
  raise Exception("files is empty")
78
93
  if self.data_type == "stream":
@@ -86,7 +101,7 @@ class CommonOss:
86
101
  _steam = f.get("stream")
87
102
  stream = _steam.stream.read()
88
103
  file_stream = BytesIO(stream)
89
- file_url_obj = self._save(key=key, io_stream=file_stream)
104
+ file_url_obj = self._save(key=key, io_stream=file_stream, bucket_name=bucket_name)
90
105
  file_url_list.append(file_url_obj)
91
106
 
92
107
  elif self.data_type == "file_path":
@@ -103,25 +118,32 @@ class CommonOss:
103
118
  else:
104
119
  key = f.get("key", "")
105
120
  _file_path = f.get("file_path")
106
- file_url_obj = self._save(key=key, file_path=_file_path)
121
+ file_url_obj = self._save(key=key, file_path=_file_path, bucket_name=bucket_name)
107
122
  file_url_list.append(file_url_obj)
108
123
  return file_url_list
109
124
 
110
- def download(self, key):
125
+ def download(self, key, bucket_name=None):
111
126
  """下载文件,返回文件流
112
127
  Args:
113
128
  key (str): 上面接口返回的文件key
114
129
  Returns:
115
130
  file_stream: 文件流
131
+ :param bucket_name:
116
132
  """
117
133
  if self.storage_type == "ks3":
118
134
  storage_config = self.storage_config or dict()
119
- ks3 = Ks3Oss(**storage_config)
120
- return ks3.get_file(key)
135
+ ks3 = Ks3Oss(bucket_name=self.bucket_name, **storage_config)
136
+ return ks3.get_file(key=key, bucket_name=bucket_name or self.bucket_name)
137
+ elif self.storage_type == "aliyun":
138
+ storage_config = self.storage_config or dict()
139
+ aliyun = AliYunOss(bucket_name=self.bucket_name, **storage_config)
140
+ return aliyun.get_file(key=key, bucket_name=bucket_name or self.bucket_name)
141
+ elif self.storage_type == "minio":
142
+ storage_config = self.storage_config or dict()
143
+ minio = MinioOss(**storage_config)
144
+ return minio.get_file(bucket_name=bucket_name or self.bucket_name, key=key)
121
145
  if self.storage_type == "file":
122
- storage_dir = self.storage_config.get("storage_dir", "")
123
- if not storage_dir:
124
- storage_dir = app_config.get("STORAGE_DIR")
146
+ storage_dir = self.storage_config.get("STORAGE_DIR", "")
125
147
  if "\\" in key:
126
148
  key_list = key.split("\\")
127
149
  elif "/" in key:
@@ -134,3 +156,4 @@ class CommonOss:
134
156
  file_path = os.path.join(file_path, k)
135
157
  with open(file_path, 'rb') as f:
136
158
  return f.read()
159
+ return None
@@ -0,0 +1,202 @@
1
+ import importlib
2
+ import os
3
+ from typing import List
4
+
5
+ from tornado.options import options
6
+
7
+
8
+ class AliYunOss:
9
+ def __init__(self, **kwargs):
10
+ try:
11
+ oss2 = importlib.import_module("oss2")
12
+ except ImportError:
13
+ raise Exception(f"oss2 is not exist,run:pip install oss2")
14
+ bucket_name = kwargs.pop("bucket_name", "") if kwargs.get("bucket_name") else options.aliyun_connect_config.get(
15
+ "bucket_name")
16
+ auth_config = {
17
+ "access_key_id": kwargs.pop("access_key_id", "") if kwargs.get(
18
+ "access_key_id") else options.aliyun_connect_config.get("access_key_id"),
19
+ "access_key_secret": kwargs.pop("access_key_secret", "") if kwargs.get(
20
+ "access_key_secret") else options.aliyun_connect_config.get("access_key_secret")
21
+ }
22
+ self.auth = oss2.Auth(**auth_config)
23
+ self.endpoint = kwargs.pop("endpoint", "") if kwargs.get("endpoint") else options.aliyun_connect_config.get(
24
+ "endpoint")
25
+ config = {
26
+ "auth": self.auth,
27
+ "endpoint": self.endpoint,
28
+ "session": kwargs.pop("session", None),
29
+ "connect_timeout": kwargs.pop("connect_timeout", None),
30
+ "app_name": kwargs.pop("connect_timeout", ''),
31
+ "proxies": kwargs.pop("proxies", None),
32
+ "region": kwargs.pop("region", None),
33
+ "cloudbox_id": kwargs.pop("cloudbox_id", None),
34
+ "is_path_style": kwargs.pop("is_path_style", False)
35
+ }
36
+ self.client = oss2.Service(**config)
37
+ if bucket_name is not None:
38
+ self.instance = oss2.Bucket(auth=self.auth, endpoint=self.endpoint, bucket_name=bucket_name)
39
+ else:
40
+ self.instance = None
41
+
42
+ def get_bucket_instance(self, bucket_name=None):
43
+ try:
44
+ oss2 = importlib.import_module("oss2")
45
+ except ImportError:
46
+ raise Exception(f"oss2 is not exist,run:pip install oss2")
47
+ if bucket_name:
48
+ self.instance = oss2.Bucket(auth=self.auth, endpoint=self.endpoint, bucket_name=bucket_name)
49
+ return self.instance
50
+
51
+ def create_bucket(self, bucket_name, **kwargs):
52
+ if not self.instance:
53
+ self.instance = self.get_bucket_instance(bucket_name)
54
+ bucket = self.instance.create_bucket(**kwargs)
55
+ return bucket
56
+
57
+ def list_buckets(self, **kwargs):
58
+ try:
59
+ oss2 = importlib.import_module("oss2")
60
+ except ImportError:
61
+ raise Exception(f"oss2 is not exist,run:pip install oss2")
62
+ return [b.name for b in oss2.BucketIterator(self.client, **kwargs)]
63
+
64
+ def delete_bucket(self, bucket_name):
65
+ if not self.instance:
66
+ self.instance = self.get_bucket_instance(bucket_name)
67
+ return self.instance.delete_bucket()
68
+
69
+ def save(self, key, content_type, data, bucket_name="", region="oss-cn-hangzhou", domain="aliyuncs.com",
70
+ protocol="https", **kwargs):
71
+ if bucket_name:
72
+ self.instance = self.get_bucket_instance(bucket_name)
73
+ if content_type == "filename":
74
+ self.instance.put_object_from_file(key=key, filename=data, **kwargs)
75
+ elif content_type == "network":
76
+ self.instance.put_object(key=key, data=data, **kwargs)
77
+ else:
78
+ self.instance.put_object(key=key, data=data, **kwargs)
79
+ return f'{protocol}://{self.instance.name}.{region}.{domain}/{key}'
80
+
81
+ def get_url(self, key, bucket_name="", region="oss-cn-hangzhou", domain="aliyuncs.com", protocol="https"):
82
+ if bucket_name:
83
+ self.instance = self.get_bucket_instance(bucket_name)
84
+ return f'{protocol}://{self.instance.name}.{region}.{domain}/{key}'
85
+
86
+ def get_file(self, key, bucket_name="", file_path=None, **kwargs):
87
+ if bucket_name:
88
+ self.instance = self.get_bucket_instance(bucket_name)
89
+ if file_path:
90
+ self.instance.get_object_to_file(key=key, filename=file_path, **kwargs)
91
+ else:
92
+ return self.instance.get_object(key=key, **kwargs)
93
+
94
+ def get_key(self, key, bucket_name="", **kwargs):
95
+ if bucket_name:
96
+ self.instance = self.get_bucket_instance(bucket_name)
97
+ k = self.instance.head_object(key, **kwargs)
98
+ return k
99
+
100
+ def delete_file(self, key, bucket_name=None, **kwargs):
101
+ if bucket_name:
102
+ self.instance = self.get_bucket_instance(bucket_name)
103
+ res = self.instance.delete_object(key, **kwargs)
104
+ return res
105
+
106
+ def list_file(self, bucket_name, **kwargs):
107
+ try:
108
+ oss2 = importlib.import_module("oss2")
109
+ except ImportError:
110
+ raise Exception(f"oss2 is not exist,run:pip install oss2")
111
+ if bucket_name:
112
+ self.instance = oss2.Bucket(auth=self.auth, endpoint=self.endpoint, bucket_name=bucket_name)
113
+ files = [k.key for k in oss2.ObjectIterator(self.instance, **kwargs)]
114
+ return files
115
+
116
+ def get_bucket_referer(self, bucket_name=None):
117
+ if bucket_name:
118
+ self.instance = self.get_bucket_instance(bucket_name)
119
+ acl = self.instance.get_bucket_referer()
120
+ return acl
121
+
122
+ def set_bucket_referer(self, bucket_name=None, **kwargs):
123
+ try:
124
+ oss2 = importlib.import_module("oss2")
125
+ models = importlib.import_module("oss2.models")
126
+ except ImportError:
127
+ raise Exception(f"oss2 is not exist,run:pip install oss2")
128
+ if bucket_name:
129
+ self.instance = oss2.Bucket(auth=self.auth, endpoint=self.endpoint, bucket_name=bucket_name)
130
+ return self.instance.put_bucket_referer(models.BucketReferer(**kwargs))
131
+
132
+ def get_bucket_cors(self, bucket_name=None):
133
+ if bucket_name:
134
+ self.instance = self.get_bucket_instance(bucket_name)
135
+ cors = self.instance.get_bucket_cors()
136
+ return cors
137
+
138
+ def set_bucket_cors(self, cors: List[dict], bucket_name=None):
139
+ try:
140
+ oss2 = importlib.import_module("oss2")
141
+ models = importlib.import_module("oss2.models")
142
+ except ImportError:
143
+ raise Exception(f"oss2 is not exist,run:pip install oss2")
144
+ if bucket_name:
145
+ self.instance = oss2.Bucket(auth=self.auth, endpoint=self.endpoint, bucket_name=bucket_name)
146
+ rules = [models.CorsRule(**_) for _ in cors]
147
+ return self.instance.put_bucket_cors(rules)
148
+
149
+ def delete_bucket_cors(self, bucket_name=None):
150
+ if bucket_name:
151
+ self.instance = self.get_bucket_instance(bucket_name)
152
+ return self.instance.delete_bucket_cors()
153
+
154
+ def multipart_upload(self, key, file_path, preferred_size, bucket_name=None, **kwargs):
155
+ try:
156
+ oss2 = importlib.import_module("oss2")
157
+ models = importlib.import_module("oss2.models")
158
+ except ImportError:
159
+ raise Exception(f"oss2 is not exist,run:pip install oss2")
160
+ if bucket_name:
161
+ self.instance = oss2.Bucket(auth=self.auth, endpoint=self.endpoint, bucket_name=bucket_name)
162
+ total_size = os.path.getsize(file_path)
163
+ part_size = oss2.determine_part_size(total_size, preferred_size=preferred_size)
164
+ upload_id = self.instance.init_multipart_upload(key).upload_id
165
+ parts = []
166
+ with open(file_path, 'rb') as f:
167
+ part_number = 1
168
+ offset = 0
169
+ while offset < total_size:
170
+ num_to_upload = min(part_size, total_size - offset)
171
+ result = self.instance.upload_part(key, upload_id, part_number,
172
+ oss2.SizedFileAdapter(f, num_to_upload))
173
+ parts.append(models.PartInfo(part_number, result.etag))
174
+
175
+ offset += num_to_upload
176
+ part_number += 1
177
+ ret = self.instance.complete_multipart_upload(key, upload_id, parts, **kwargs)
178
+ return {"result": ret, "upload_id": upload_id}
179
+
180
+ def list_multipart_uploads(self, key, upload_id, bucket_name=None, **kwargs):
181
+ try:
182
+ oss2 = importlib.import_module("oss2")
183
+ except ImportError:
184
+ raise Exception(f"oss2 is not exist,run:pip install oss2")
185
+ if bucket_name:
186
+ self.instance = oss2.Bucket(auth=self.auth, endpoint=self.endpoint, bucket_name=bucket_name)
187
+ return oss2.PartIterator(self.instance, key, upload_id, **kwargs)
188
+
189
+ def get_sign_url(self, key, expires, bucket_name=None, headers=None, params=None, slash_safe=False):
190
+ if bucket_name:
191
+ self.instance = self.get_bucket_instance(bucket_name)
192
+ url = self.instance.sign_url('GET', key, expires, slash_safe=slash_safe, headers=headers, params=params)
193
+ return url
194
+
195
+ def modify_object(self, bucket_name=None, **kwargs):
196
+ if bucket_name:
197
+ self.instance = self.get_bucket_instance(bucket_name)
198
+ source_bucket_name = bucket_name if bucket_name else self.instance.name
199
+ return self.instance.copy_object(source_bucket_name=source_bucket_name, **kwargs)
200
+
201
+ def get_regions(self, regions):
202
+ return self.client.describe_regions(regions=regions)
@@ -0,0 +1,254 @@
1
+ import importlib
2
+ import logging
3
+ import os
4
+
5
+ from datetime import timedelta
6
+ from io import BytesIO
7
+
8
+
9
+ class MinioOss:
10
+ client = None
11
+ policy = '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":["*"]},"Action":["s3:GetBucketLocation","s3:ListBucket"],"Resource":["arn:aws:s3:::%s"]},{"Effect":"Allow","Principal":{"AWS":["*"]},"Action":["s3:GetObject"],"Resource":["arn:aws:s3:::%s/*"]}]}'
12
+
13
+ def __new__(cls, *args, **kwargs):
14
+ if not cls.client:
15
+ cls.client = object.__new__(cls)
16
+ return cls.client
17
+
18
+ def __init__(self, service, access_key, secret_key, secure=False):
19
+ try:
20
+ minio = importlib.import_module("minio")
21
+ except ImportError as e:
22
+ raise Exception(f"minio is not exist,run:pip install minio")
23
+ self.service = service
24
+ self.client = minio.Minio(service, access_key=access_key, secret_key=secret_key, secure=secure)
25
+
26
+ def exists_bucket(self, bucket_name):
27
+ """
28
+ 判断桶是否存在
29
+ :param bucket_name: 桶名称
30
+ :return:
31
+ """
32
+ return self.client.bucket_exists(bucket_name=bucket_name)
33
+
34
+ def create_bucket(self, bucket_name: str, is_policy: bool = True):
35
+ """
36
+ 创建桶 + 赋予策略
37
+ :param bucket_name: 桶名
38
+ :param is_policy: 策略
39
+ :return:
40
+ """
41
+ if self.exists_bucket(bucket_name=bucket_name):
42
+ return False
43
+ else:
44
+ self.client.make_bucket(bucket_name=bucket_name)
45
+ if is_policy:
46
+ policy = self.policy % (bucket_name, bucket_name)
47
+ self.client.set_bucket_policy(bucket_name=bucket_name, policy=policy)
48
+ return True
49
+
50
+ def get_bucket_list(self):
51
+ """
52
+ 列出存储桶
53
+ :return:
54
+ """
55
+ buckets = self.client.list_buckets()
56
+ bucket_list = []
57
+ for bucket in buckets:
58
+ bucket_list.append(
59
+ {"bucket_name": bucket.name, "create_time": bucket.creation_date}
60
+ )
61
+ return bucket_list
62
+
63
+ def remove_bucket(self, bucket_name):
64
+ """
65
+ 删除桶
66
+ :param bucket_name:
67
+ :return:
68
+ """
69
+ try:
70
+ minio_error = importlib.import_module("minio.error")
71
+ except ImportError as e:
72
+ raise Exception(f"minio is not exist,run:pip install minio")
73
+ try:
74
+ self.client.remove_bucket(bucket_name=bucket_name)
75
+ except minio_error.S3Error as e:
76
+ logging.error(f"[error]:{e}")
77
+ return False
78
+ return True
79
+
80
+ def bucket_list_files(self, bucket_name, prefix):
81
+ """
82
+ 列出存储桶中所有对象
83
+ :param bucket_name: 同名
84
+ :param prefix: 前缀
85
+ :return:
86
+ """
87
+ try:
88
+ minio_error = importlib.import_module("minio.error")
89
+ except ImportError as e:
90
+ raise Exception(f"minio is not exist,run:pip install minio")
91
+ try:
92
+ files_list = self.client.list_objects(bucket_name=bucket_name, prefix=prefix, recursive=True)
93
+ return files_list
94
+ except minio_error.S3Error as e:
95
+ logging.error(f"[error]:{e}")
96
+ return None
97
+
98
+ def bucket_policy(self, bucket_name):
99
+ """
100
+ 列出桶存储策略
101
+ :param bucket_name:
102
+ :return:
103
+ """
104
+ try:
105
+ minio_error = importlib.import_module("minio.error")
106
+ except ImportError as e:
107
+ raise Exception(f"minio is not exist,run:pip install minio")
108
+ try:
109
+ policy = self.client.get_bucket_policy(bucket_name)
110
+ except minio_error.S3Error as e:
111
+ logging.error(f"[error]:{e}")
112
+ return None
113
+ return policy
114
+
115
+ def download_file(self, bucket_name, file, file_path, stream=1024 * 32):
116
+ """
117
+ 从bucket 下载文件 + 写入指定文件
118
+ :return:
119
+ """
120
+ try:
121
+ minio_error = importlib.import_module("minio.error")
122
+ except ImportError as e:
123
+ raise Exception(f"minio is not exist,run:pip install minio")
124
+ try:
125
+ data = self.client.get_object(bucket_name, file)
126
+ with open(file_path, "wb") as fp:
127
+ for d in data.stream(stream):
128
+ fp.write(d)
129
+ except minio_error.S3Error as e:
130
+ logging.error(f"[error]:{e}")
131
+
132
+ def get_file(self, bucket_name, key):
133
+ data = self.client.get_object(bucket_name, object_name=key)
134
+ return data
135
+
136
+ def fget_file(self, bucket_name, file, file_path):
137
+ """
138
+ 下载保存文件保存本地
139
+ :param bucket_name:
140
+ :param file:
141
+ :param file_path:
142
+ :return:
143
+ """
144
+ self.client.fget_object(bucket_name, file, file_path)
145
+
146
+ def copy_file(self, bucket_name, file, file_path):
147
+ """
148
+ 拷贝文件(最大支持5GB)
149
+ :param bucket_name:
150
+ :param file:
151
+ :param file_path:
152
+ :return:
153
+ """
154
+ self.client.copy_object(bucket_name, file, file_path)
155
+
156
+ def upload_file(self, bucket_name, file, file_path, content_type):
157
+ """
158
+ 上传文件 + 写入
159
+ :param bucket_name: 桶名
160
+ :param file: 文件名
161
+ :param file_path: 本地文件路径
162
+ :param content_type: 文件类型
163
+ :return:
164
+ """
165
+ try:
166
+ minio_error = importlib.import_module("minio.error")
167
+ except ImportError as e:
168
+ raise Exception(f"minio is not exist,run:pip install minio")
169
+ try:
170
+ with open(file_path, "rb") as file_data:
171
+ file_stat = os.stat(file_path)
172
+ self.client.put_object(bucket_name, file, file_data, file_stat.st_size, content_type=content_type)
173
+ except minio_error.S3Error as e:
174
+ logging.error(f"[error]:{e}")
175
+
176
+ def save(self, key, bucket_name, data, content_type="string", **kwargs):
177
+ ret = None
178
+ if content_type == "string":
179
+ ret = self.client.put_object(bucket_name=bucket_name, object_name=key, data=BytesIO(data), length=len(data),
180
+ **kwargs)
181
+ elif content_type == "filename":
182
+ with open(data, "rb") as f:
183
+ data = f.read()
184
+ ret = self.client.put_object(bucket_name=bucket_name, object_name=key, data=BytesIO(data), length=len(data),
185
+ **kwargs)
186
+ if ret:
187
+ if ret.status == 200:
188
+ return self.client.presigned_get_object(bucket_name=bucket_name, key=key, expires=3600)
189
+ else:
190
+ return False
191
+ else:
192
+ return False
193
+
194
+ def fput_file(self, bucket_name, file, file_path):
195
+ """
196
+ 上传文件
197
+ :param bucket_name: 桶名
198
+ :param file: 文件名
199
+ :param file_path: 本地文件路径
200
+ :return:
201
+ """
202
+ try:
203
+ minio_error = importlib.import_module("minio.error")
204
+ except ImportError as e:
205
+ raise Exception(f"minio is not exist,run:pip install minio")
206
+ try:
207
+ self.client.fput_object(bucket_name, file, file_path)
208
+ except minio_error.S3Error as e:
209
+ logging.error(f"[error]:{e}")
210
+
211
+ def stat_object(self, bucket_name, file):
212
+ """
213
+ 获取文件元数据
214
+ :param bucket_name:
215
+ :param file:
216
+ :return:
217
+ """
218
+ try:
219
+ minio_error = importlib.import_module("minio.error")
220
+ except ImportError as e:
221
+ raise Exception(f"minio is not exist,run:pip install minio")
222
+ try:
223
+ data = self.client.stat_object(bucket_name, file)
224
+ return data
225
+ except minio_error.S3Error as e:
226
+ logging.error(f"[error]:{e}")
227
+ return None
228
+
229
+ def remove_file(self, bucket_name, file):
230
+ """
231
+ 移除单个文件
232
+ :return:
233
+ """
234
+ self.client.remove_object(bucket_name, file)
235
+
236
+ def remove_files(self, bucket_name, file_list):
237
+ """
238
+ 删除多个文件
239
+ :return:
240
+ """
241
+ try:
242
+ deleteobjects = importlib.import_module("minio.deleteobjects")
243
+ except ImportError as e:
244
+ raise Exception(f"minio is not exist,run:pip install minio")
245
+ delete_object_list = [deleteobjects.DeleteObject(file) for file in file_list]
246
+ for del_err in self.client.remove_objects(bucket_name, delete_object_list):
247
+ logging.error(del_err)
248
+
249
+ def presigned_get_file(self, bucket_name, file, days=7):
250
+ """
251
+ 生成一个http GET操作 签证URL
252
+ :return:
253
+ """
254
+ return self.client.presigned_get_object(bucket_name, file, expires=timedelta(days=days))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lesscode-flask
3
- Version: 0.1.77
3
+ Version: 0.1.79
4
4
  Summary: lesscode-flask 是基于flask的web开发脚手架项目,该项目初衷为简化开发过程,让研发人员更加关注业务。
5
5
  Home-page: https://lesscode-flask
6
6
  Author: Chao.yy
@@ -36,7 +36,9 @@ lesscode_flask/utils/file/file_exporter.py
36
36
  lesscode_flask/utils/file/file_utils.py
37
37
  lesscode_flask/utils/json/NotSortJSONProvider.py
38
38
  lesscode_flask/utils/oss/__init__.py
39
+ lesscode_flask/utils/oss/aliyun_oss.py
39
40
  lesscode_flask/utils/oss/ks3_oss.py
41
+ lesscode_flask/utils/oss/minio_oss.py
40
42
  lesscode_flask/utils/redis/redis_helper.py
41
43
  lesscode_flask/utils/request/request.py
42
44
  lesscode_flask/utils/swagger/swagger_template.py