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.
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/PKG-INFO +1 -1
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/__init__.py +1 -1
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/log/access_log_handler.py +4 -1
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/oss/__init__.py +39 -16
- lesscode_flask-0.1.79/lesscode_flask/utils/oss/aliyun_oss.py +202 -0
- lesscode_flask-0.1.79/lesscode_flask/utils/oss/minio_oss.py +254 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask.egg-info/PKG-INFO +1 -1
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask.egg-info/SOURCES.txt +2 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/README.md +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/app.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/db/__init__.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/db/datasource.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/db/executor.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/export_data/__init__.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/export_data/data_download_handler.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/model/access_log.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/model/base_model.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/model/parameterized_query.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/model/resource_param_template.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/model/response_result.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/model/user.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/service/access_log_service.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/service/base_service.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/service/resource_param_template_service.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/setting/__init__.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/setup/__init__.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/signals.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/static/swagger.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/decorator/__init__.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/decorator/cache.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/decorator/swagger.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/dify_utils.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/file/file_exporter.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/file/file_utils.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/helpers.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/json/NotSortJSONProvider.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/oss/ks3_oss.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/redis/redis_helper.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/request/request.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/swagger/swagger_template.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/swagger/swagger_util.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/task/__init__.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/task/task_helper.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/thread/thread_utils.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/wsgi.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask.egg-info/dependency_links.txt +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask.egg-info/requires.txt +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask.egg-info/top_level.txt +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/query_runner/__init__.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/query_runner/clickhouse.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/query_runner/elasticsearch.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/query_runner/kingbase.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/query_runner/mysql.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/query_runner/pg.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/settings/__init__.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/settings/helpers.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/utils/__init__.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/redash/utils/requests_session.py +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/setup.cfg +0 -0
- {lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/setup.py +0 -0
|
@@ -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
|
-
|
|
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("
|
|
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("
|
|
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))
|
|
@@ -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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/export_data/data_download_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/model/resource_param_template.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/service/access_log_service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/json/NotSortJSONProvider.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/swagger/swagger_template.py
RENAMED
|
File without changes
|
{lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask/utils/swagger/swagger_util.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lesscode-flask-0.1.77 → lesscode_flask-0.1.79}/lesscode_flask.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|