lesscode-flask 0.0.65__tar.gz → 0.0.67__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 (55) hide show
  1. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/PKG-INFO +1 -12
  2. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/__init__.py +1 -1
  3. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/app.py +14 -6
  4. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/db/__init__.py +7 -2
  5. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/log/access_log_handler.py +15 -9
  6. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/model/parameterized_query.py +25 -7
  7. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/model/user.py +7 -2
  8. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/service/base_service.py +15 -11
  9. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/setup/__init__.py +22 -12
  10. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/utils/decorator/cache.py +1 -1
  11. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/wsgi.py +23 -8
  12. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask.egg-info/PKG-INFO +1 -12
  13. lesscode-flask-0.0.67/lesscode_flask.egg-info/requires.txt +1 -0
  14. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/redash/query_runner/__init__.py +14 -2
  15. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/redash/query_runner/clickhouse.py +8 -3
  16. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/redash/query_runner/elasticsearch.py +5 -1
  17. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/redash/settings/__init__.py +11 -5
  18. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/redash/utils/requests_session.py +8 -1
  19. lesscode-flask-0.0.65/lesscode_flask.egg-info/requires.txt +0 -12
  20. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/README.md +0 -0
  21. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/db/datasource.py +0 -0
  22. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/db/executor.py +0 -0
  23. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/model/access_log.py +0 -0
  24. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/model/auth_client.py +0 -0
  25. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/model/auth_permission.py +0 -0
  26. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/model/base_model.py +0 -0
  27. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/model/response_result.py +0 -0
  28. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/service/access_log_service.py +0 -0
  29. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/service/auth_client_service.py +0 -0
  30. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/service/auth_permission_service.py +0 -0
  31. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/service/authentication_service.py +0 -0
  32. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/setting/__init__.py +0 -0
  33. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/utils/__init__.py +0 -0
  34. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/utils/decorator/__init__.py +0 -0
  35. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/utils/decorator/swagger.py +0 -0
  36. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/utils/file/file_exporter.py +0 -0
  37. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/utils/helpers.py +0 -0
  38. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/utils/json/NotSortJSONProvider.py +0 -0
  39. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/utils/oss/__init__.py +0 -0
  40. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/utils/oss/ks3_oss.py +0 -0
  41. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/utils/redis/redis_helper.py +0 -0
  42. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/utils/request/request.py +0 -0
  43. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/utils/swagger/swagger_template.py +0 -0
  44. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/utils/swagger/swagger_util.py +0 -0
  45. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask/utils/thread/thread_utils.py +0 -0
  46. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask.egg-info/SOURCES.txt +0 -0
  47. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask.egg-info/dependency_links.txt +0 -0
  48. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/lesscode_flask.egg-info/top_level.txt +0 -0
  49. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/redash/query_runner/kingbase.py +0 -0
  50. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/redash/query_runner/mysql.py +0 -0
  51. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/redash/query_runner/pg.py +0 -0
  52. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/redash/settings/helpers.py +0 -0
  53. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/redash/utils/__init__.py +0 -0
  54. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/setup.cfg +0 -0
  55. {lesscode-flask-0.0.65 → lesscode-flask-0.0.67}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lesscode-flask
3
- Version: 0.0.65
3
+ Version: 0.0.67
4
4
  Summary: lesscode-flask 是基于flask的web开发脚手架项目,该项目初衷为简化开发过程,让研发人员更加关注业务。
5
5
  Home-page: https://lesscode-flask
6
6
  Author: Chao.yy
@@ -11,17 +11,6 @@ Classifier: Operating System :: OS Independent
11
11
  Requires-Python: >=3.9
12
12
  Description-Content-Type: text/markdown
13
13
  Requires-Dist: Flask==3.0.3
14
- Requires-Dist: Flask-Login==0.6.3
15
- Requires-Dist: redis==5.1.1
16
- Requires-Dist: flask-swagger-ui==4.11.1
17
- Requires-Dist: pystache==0.6.5
18
- Requires-Dist: python-dateutil==2.9.0.post0
19
- Requires-Dist: funcy==2.0
20
- Requires-Dist: Flask-SQLAlchemy==3.1.1
21
- Requires-Dist: sqlparse==0.5.1
22
- Requires-Dist: requests==2.32.3
23
- Requires-Dist: gunicorn==23.0.0
24
- Requires-Dist: gevent==24.10.2
25
14
 
26
15
  # lesscode-flask
27
16
 
@@ -1,4 +1,4 @@
1
- __version__ = '0.0.65'
1
+ __version__ = '0.0.67'
2
2
 
3
3
  import functools
4
4
  import logging
@@ -6,9 +6,11 @@ import sys
6
6
  import time
7
7
  import traceback
8
8
  import typing as t
9
- from flask import Flask, typing as ft, abort, Response
9
+ from importlib import import_module
10
+
11
+ # from flask import Flask, typing as ft, Response
10
12
  from flask.globals import request_ctx, request
11
- from flask_login import current_user
13
+ # from flask_login import current_user
12
14
  from lesscode_utils.json_utils import JSONEncoder
13
15
  from werkzeug.middleware.proxy_fix import ProxyFix
14
16
 
@@ -52,6 +54,10 @@ class Lesscoder(Flask):
52
54
 
53
55
  def preprocess_request(self) -> ft.ResponseReturnValue | None:
54
56
  if self.config.get("AUTHORIZATION_ENABLE"): # 启动 AUTHORIZATION_ENABLE 才进行权限验证
57
+ try:
58
+ flask_login = import_module("flask_login")
59
+ except ImportError as e:
60
+ raise Exception(f"flask_login is not exist,run:pip install Flask-Login==0.6.3")
55
61
  # 获取当前请求的url
56
62
  url = request.path
57
63
  # 获取URL 对应的id 与访问权限
@@ -62,13 +68,13 @@ class Lesscoder(Flask):
62
68
  access = app_config.get("AUTH_DEFAULT_ACCESS", "0")
63
69
  # '访问权限2:需要权限 1:需要登录 0:游客',
64
70
  if str(access) == "1": # 需要登录
65
- if current_user.is_anonymous_user:
71
+ if flask_login.current_user.is_anonymous_user:
66
72
  # abort(403, "需要登录")
67
73
  ResponseResult.fail("请登录后访问", status_code="403")
68
74
  elif str(access) == "2": # 需要权限
69
- if current_user.is_anonymous_user:
75
+ if flask_login.current_user.is_anonymous_user:
70
76
  ResponseResult.fail("请登录后访问", status_code="403")
71
- if not current_user.has_permission(id):
77
+ if not flask_login.current_user.has_permission(id):
72
78
  ResponseResult.fail("请获取授权后访问", status_code="403")
73
79
  return super(Lesscoder, self).preprocess_request()
74
80
 
@@ -86,7 +92,8 @@ class Lesscoder(Flask):
86
92
  # # 计算请求耗时
87
93
  # duration = time.time() - start_time
88
94
  # 100 为自定义 'ACCESS' 的日志级别标识
89
- logging.log(100,"访问日志", {"request_id": request_id,"start_time":start_time, "end_time": time.time(),"status_code":response.status_code})
95
+ logging.log(100, "访问日志", {"request_id": request_id, "start_time": start_time, "end_time": time.time(),
96
+ "status_code": response.status_code})
90
97
  return response
91
98
 
92
99
  def dispatch_request(self) -> ft.ResponseReturnValue:
@@ -140,6 +147,7 @@ class Lesscoder(Flask):
140
147
  setup_resource_register(self)
141
148
  for blueprint_name, blueprint in blueprint_map.items():
142
149
  self.register_blueprint(blueprint)
150
+
143
151
  @staticmethod
144
152
  def handle_exception(e):
145
153
  traceback.print_exc() # 打印堆栈信息
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ from importlib import import_module
2
3
 
3
4
  from lesscode_flask.db.executor import QueryExecutor, QueryExecutionError
4
5
  from lesscode_flask.model.parameterized_query import ParameterizedQuery
@@ -33,10 +34,14 @@ def execute_query(
33
34
  return e
34
35
 
35
36
 
36
- from flask_sqlalchemy import SQLAlchemy
37
+ # from flask_sqlalchemy import SQLAlchemy
38
+ try:
39
+ flask_sqlalchemy = import_module("flask_sqlalchemy")
40
+ except ImportError as e:
41
+ raise Exception(f"flask_sqlalchemy is not exist,run:pip install Flask-SQLAlchemy==3.1.1")
37
42
 
38
43
 
39
- class LessCodeSQLAlchemy(SQLAlchemy):
44
+ class LessCodeSQLAlchemy(flask_sqlalchemy.SQLAlchemy):
40
45
  pass
41
46
  # def apply_driver_hacks(self, app, info, options):
42
47
  # options.update(json_serializer=json_dumps)
@@ -1,11 +1,12 @@
1
+ # from flask_login import current_user
2
+ import threading
3
+ from importlib import import_module
1
4
  from logging import Handler
2
5
 
3
6
  from flask import request, copy_current_request_context
4
- from flask_login import current_user
5
- import threading
6
- from lesscode_flask.model.access_log import AccessLog
7
- from lesscode_flask.model.user import AnonymousUser, ApiUser, User
8
7
 
8
+ from lesscode_flask.model.access_log import AccessLog
9
+ from lesscode_flask.model.user import AnonymousUser, ApiUser
9
10
  from lesscode_flask.service.access_log_service import AccessLogService
10
11
  from lesscode_flask.utils.helpers import app_config
11
12
  from lesscode_flask.utils.redis.redis_helper import RedisHelper
@@ -50,19 +51,24 @@ class AccessLogHandler(Handler):
50
51
  resource_label = url_info.get("label", "-")
51
52
  except Exception as e:
52
53
  pass
54
+ try:
55
+ flask_login = import_module("flask_login")
56
+ except ImportError as e:
57
+ raise Exception(f"flask_login is not exist,run:pip install Flask-Login==0.6.3")
53
58
  '请求类型0:用户请求,1:API用户,2:匿名用户',
54
- if isinstance(current_user, AnonymousUser):
59
+ if isinstance(flask_login.current_user, AnonymousUser):
55
60
  type = 2
56
- elif isinstance(current_user, ApiUser):
61
+ elif isinstance(flask_login.current_user, ApiUser):
57
62
  type = 1
58
63
  else:
59
64
  type = 0
60
65
 
61
- access_log = AccessLog(request_id=request_id, display_name=current_user.display_name,
62
- obj_id=current_user.id, type=type,
66
+ access_log = AccessLog(request_id=request_id, display_name=flask_login.current_user.display_name,
67
+ obj_id=flask_login.current_user.id, type=type,
63
68
  resource_id=resource_id,
64
69
  resource_label=resource_label, url=url, referrer=referrer, client_ip=client_ip,
65
- user_agent=user_agent_string,start_time=start_time, end_time=end_time, duration = end_time-start_time,status_code =status_code,
70
+ user_agent=user_agent_string, start_time=start_time, end_time=end_time,
71
+ duration=end_time - start_time, status_code=status_code,
66
72
  params=params)
67
73
 
68
74
  @copy_current_request_context
@@ -1,14 +1,16 @@
1
1
  import re
2
2
  from functools import partial
3
+ from importlib import import_module
3
4
  from numbers import Number
4
5
 
5
- import pystache
6
- from dateutil.parser import parse
7
- from funcy import distinct
8
-
9
6
  from lesscode_flask.utils.helpers import mustache_render
10
7
 
11
8
 
9
+ # import pystache
10
+ # from dateutil.parser import parse
11
+ # from funcy import distinct
12
+
13
+
12
14
  def _pluck_name_and_value(default_column, row):
13
15
  row = {k.lower(): v for k, v in row.items()}
14
16
  name_column = "name" if "name" in row.keys() else default_column.lower()
@@ -30,7 +32,7 @@ def _pluck_name_and_value(default_column, row):
30
32
 
31
33
 
32
34
  def dropdown_values(query_id, org):
33
- data = [] # load_result(query_id, org)
35
+ data = [] # load_result(query_id, org)
34
36
  first_column = data["columns"][0]["name"]
35
37
  pluck = partial(_pluck_name_and_value, first_column)
36
38
  return list(map(pluck, data["rows"]))
@@ -53,6 +55,14 @@ def join_parameter_list_values(parameters, schema):
53
55
 
54
56
  def _collect_key_names(nodes):
55
57
  keys = []
58
+ try:
59
+ pystache = import_module("pystache")
60
+ except ImportError:
61
+ raise Exception(f"pystache is not exist,run:pip install pystache==0.6.5")
62
+ try:
63
+ funcy = import_module("funcy")
64
+ except ImportError:
65
+ raise Exception(f"pystache is not exist,run:pip install pystache==0.6.5")
56
66
  for node in nodes._parse_tree:
57
67
  if isinstance(node, pystache.parser._EscapeNode):
58
68
  keys.append(node.key)
@@ -60,10 +70,14 @@ def _collect_key_names(nodes):
60
70
  keys.append(node.key)
61
71
  keys.extend(_collect_key_names(node.parsed))
62
72
 
63
- return distinct(keys)
73
+ return funcy.distinct(keys)
64
74
 
65
75
 
66
76
  def _collect_query_parameters(query):
77
+ try:
78
+ pystache = import_module("pystache")
79
+ except ImportError:
80
+ raise Exception(f"pystache is not exist,run:pip install pystache==0.6.5")
67
81
  nodes = pystache.parse(query)
68
82
  keys = _collect_key_names(nodes)
69
83
  return keys
@@ -100,7 +114,11 @@ def _is_regex_pattern(value, regex):
100
114
 
101
115
 
102
116
  def _is_date(string):
103
- parse(string)
117
+ try:
118
+ dateutil_parser = import_module("dateutil.parser")
119
+ except ImportError:
120
+ raise Exception(f"python-dateutil is not exist,run:pip install python-dateutil==2.9.0.post0")
121
+ dateutil_parser.parse(string)
104
122
  return True
105
123
 
106
124
 
@@ -1,6 +1,11 @@
1
1
  from functools import reduce
2
+ from importlib import import_module
2
3
 
3
- from flask_login import AnonymousUserMixin, UserMixin
4
+ # from flask_login import AnonymousUserMixin, UserMixin
5
+ try:
6
+ flask_login = import_module("flask_login")
7
+ except ImportError as e:
8
+ raise Exception(f"flask_login is not exist,run:pip install Flask-Login==0.6.3")
4
9
 
5
10
 
6
11
  class PermissionsCheckMixin:
@@ -17,7 +22,7 @@ class PermissionsCheckMixin:
17
22
  return has_permissions
18
23
 
19
24
 
20
- class User(UserMixin, PermissionsCheckMixin):
25
+ class User(flask_login.UserMixin, PermissionsCheckMixin):
21
26
  """
22
27
  在线用户对象类
23
28
  """
@@ -1,7 +1,11 @@
1
1
  import logging
2
+ from importlib import import_module
2
3
 
3
- from flask_login import current_user
4
-
4
+ # from flask_login import current_user
5
+ try:
6
+ flask_login = import_module("flask_login")
7
+ except ImportError as e:
8
+ raise Exception(f"flask_login is not exist,run:pip install Flask-Login==0.6.3")
5
9
  from lesscode_flask.db import db
6
10
  from lesscode_flask.model.base_model import BaseModel
7
11
  from lesscode_flask.utils.helpers import result_to_dict, parameter_validation, format_page_index
@@ -28,9 +32,9 @@ class BaseService:
28
32
  # current_user = None
29
33
  try:
30
34
  if hasattr(item, "create_user_id"):
31
- item.create_user_id = current_user.id
35
+ item.create_user_id = flask_login.current_user.id
32
36
  if hasattr(item, "create_user_name"):
33
- item.create_user_name = current_user.display_name
37
+ item.create_user_name = flask_login.current_user.display_name
34
38
  except Exception as e:
35
39
  if hasattr(item, "create_user_id"):
36
40
  item.create_user_id = "AnonymousUserId"
@@ -49,9 +53,9 @@ class BaseService:
49
53
  for item in items:
50
54
  try:
51
55
  if hasattr(item, "create_user_id"):
52
- item.create_user_id = current_user.id
56
+ item.create_user_id = flask_login.current_user.id
53
57
  if hasattr(item, "create_user_name"):
54
- item.create_user_name = current_user.display_name
58
+ item.create_user_name = flask_login.current_user.display_name
55
59
  except Exception as e:
56
60
  if hasattr(item, "create_user_id"):
57
61
  item.create_user_id = "AnonymousUserId"
@@ -69,9 +73,9 @@ class BaseService:
69
73
 
70
74
  try:
71
75
  if hasattr(self.model, "modify_user_id"):
72
- item["modify_user_id"] = current_user.id
76
+ item["modify_user_id"] = flask_login.current_user.id
73
77
  if hasattr(self.model, "modify_user_name"):
74
- item["modify_user_name"] = current_user.display_name
78
+ item["modify_user_name"] = flask_login.current_user.display_name
75
79
  except Exception as e:
76
80
  if hasattr(item, "modify_user_id"):
77
81
  item.create_user_id = "AnonymousUserId"
@@ -81,13 +85,13 @@ class BaseService:
81
85
  db.session.commit()
82
86
  return id
83
87
 
84
- def update_items(self, filters: list , item: dict):
88
+ def update_items(self, filters: list, item: dict):
85
89
 
86
90
  try:
87
91
  if hasattr(self.model, "modify_user_id"):
88
- item["modify_user_id"] = current_user.id
92
+ item["modify_user_id"] = flask_login.current_user.id
89
93
  if hasattr(self.model, "modify_user_name"):
90
- item["modify_user_name"] = current_user.display_name
94
+ item["modify_user_name"] = flask_login.current_user.display_name
91
95
  except Exception as e:
92
96
  if hasattr(item, "modify_user_id"):
93
97
  item.create_user_id = "AnonymousUserId"
@@ -1,26 +1,24 @@
1
- import importlib
2
1
  import inspect
3
-
4
2
  import uuid
5
-
6
3
  from datetime import datetime
7
-
4
+ from importlib import import_module
8
5
  from logging.handlers import TimedRotatingFileHandler
9
6
 
10
- import redis
11
7
  from flask import current_app
12
- from flask_login import LoginManager
13
- from flask_swagger_ui import get_swaggerui_blueprint
14
8
 
15
9
  from lesscode_flask.db import db
16
10
  from lesscode_flask.log.access_log_handler import AccessLogHandler
17
- from lesscode_flask.model.user import AnonymousUser, User
11
+ from lesscode_flask.model.user import AnonymousUser
18
12
  from lesscode_flask.service.authentication_service import get_token_user, get_api_user, get_gateway_user
19
13
  from lesscode_flask.utils.swagger.swagger_template import split_doc
20
14
  from lesscode_flask.utils.swagger.swagger_util import generate_openapi_spec, replace_symbol, get_params_type, \
21
15
  get_sample_data
22
16
 
23
17
 
18
+ # from flask_login import LoginManager
19
+ # from flask_swagger_ui import get_swaggerui_blueprint
20
+
21
+
24
22
  def setup_logging(app):
25
23
  """
26
24
  初始化日志配置
@@ -93,7 +91,7 @@ def setup_blueprint(app, path=None, pkg_name="handlers", blueprint_map={}):
93
91
  elif os.path.isfile(full_file) and handler_name.lower().endswith("handler.py"):
94
92
  # 文件,并且为handler结尾,认为是请求处理器,完成动态装载
95
93
  module_path = "{}.{}".format(pkg_name, handler_name.replace(".py", ""))
96
- module = importlib.import_module(module_path) # __import__(module_path)
94
+ module = import_module(module_path) # __import__(module_path)
97
95
  for name, obj in inspect.getmembers(module):
98
96
  # 找到Blueprint 的属性进行注册
99
97
  if isinstance(obj, Blueprint):
@@ -129,7 +127,11 @@ def setup_sql_alchemy(app):
129
127
 
130
128
 
131
129
  def setup_login_manager(app):
132
- login_manager = LoginManager(app)
130
+ try:
131
+ flask_login = import_module("flask_login")
132
+ except ImportError as e:
133
+ raise Exception(f"flask_login is not exist,run:pip install Flask-Login==0.6.3")
134
+ login_manager = flask_login.LoginManager(app)
133
135
  setattr(app, "login_manager", login_manager)
134
136
 
135
137
  @login_manager.request_loader
@@ -163,7 +165,11 @@ def setup_swagger(app):
163
165
  # API_URL = 'http://127.0.0.1:5001/static/swagger.json' # Swagger 规范的路径(本地 JSON 文件)
164
166
  API_URL = app.config.get("SWAGGER_API_URL", "") # 接口
165
167
  # 创建 Swagger UI 蓝图
166
- swagger_ui_blueprint = get_swaggerui_blueprint(
168
+ try:
169
+ flask_swagger_ui = import_module("flask_swagger_ui")
170
+ except ImportError as e:
171
+ raise Exception(f"flask_swagger_ui is not exist,run:pip install flask-swagger-ui==4.11.1")
172
+ swagger_ui_blueprint = flask_swagger_ui.get_swaggerui_blueprint(
167
173
  SWAGGER_URL, # Swagger UI 访问路径
168
174
  app.config.get("OUTSIDE_SCREEN_IP") + API_URL, # Swagger 文件路径
169
175
  config={ # Swagger UI 配置参数
@@ -187,6 +193,10 @@ def setup_redis(app):
187
193
 
188
194
  for r in redis_conn_list:
189
195
  if r.get("type") == "redis":
196
+ try:
197
+ redis = import_module("redis")
198
+ except ImportError:
199
+ raise Exception(f"redis is not exist,run:pip install redis==5.1.1")
190
200
  conn = redis.Redis(host=r.get("host"), port=r.get("port"), db=r.get("db"), password=r.get("password"),
191
201
  decode_responses=True)
192
202
  if not hasattr(current_app, "redis_conn_dict"):
@@ -361,7 +371,7 @@ def setup_resource_register(app):
361
371
  description=inter_desc, param_list=param_list))
362
372
  resource_list.append(resource)
363
373
  try:
364
- httpx = importlib.import_module("httpx")
374
+ httpx = import_module("httpx")
365
375
  except ImportError as e:
366
376
  raise Exception(f"httpx is not exist,run:pip install httpx==0.24.1")
367
377
  with httpx.Client(**{"timeout": None}) as session:
@@ -125,7 +125,7 @@ def insert_cache(data, ex, cache_key, conn_name=None):
125
125
  try:
126
126
  json_utils = import_module("lesscode_utils.json_utils")
127
127
  except ImportError:
128
- raise Exception(f"pymysql is not exist,run:pip install lesscode_utils==0.0.22")
128
+ raise Exception(f"lesscode_utils is not exist,run:pip install lesscode_utils==0.0.61")
129
129
  RedisHelper(conn_name).sync_set(cache_key, json_utils.JSONEncoder().encode(data), ex=ex)
130
130
  except:
131
131
  logging.error(traceback.format_exc())
@@ -1,15 +1,26 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # 解决MonkeyPatchWarning
3
3
  import os
4
+ from importlib import import_module
4
5
 
5
- from gevent import monkey # 导入补丁模块
6
+ # from gevent import monkey # 导入补丁模块
6
7
 
7
- monkey.patch_all() # 创建补丁
8
- from funcy import iteritems
9
- from gunicorn.app.base import BaseApplication
8
+ # 创建补丁
9
+ # from funcy import iteritems
10
+ try:
11
+ gunicorn_app_base = import_module("gunicorn.app.base")
12
+ except ImportError as e:
13
+ raise Exception(f"gunicorn is not exist,run:pip install gunicorn==23.0.0")
10
14
 
15
+ try:
16
+ gevent = import_module("gevent")
17
+ except ImportError as e:
18
+ raise Exception(f"gevent is not exist,run:pip install gevent==24.10.2")
11
19
 
12
- class Application(BaseApplication):
20
+ gevent.monkey.patch_all()
21
+
22
+
23
+ class Application(gunicorn_app_base.BaseApplication):
13
24
  def __init__(self, app):
14
25
  self.app = app
15
26
  cpu_count = os.cpu_count()
@@ -17,7 +28,7 @@ class Application(BaseApplication):
17
28
  cpu_count = 5
18
29
  options = {
19
30
  'bind': f"0.0.0.0:{app.config.get('PORT', 5002)}", # 绑定地址和端口
20
- 'workers': cpu_count*2+1, # 指定 workers 数量
31
+ 'workers': cpu_count * 2 + 1, # 指定 workers 数量
21
32
  'accesslog': "-", # 输出到标准输出,取消gunicorn接管日志输出
22
33
  'worker_class': 'gevent', # worker 运行方式
23
34
  'timeout': 300
@@ -28,9 +39,13 @@ class Application(BaseApplication):
28
39
  # self.logger = logging # 自定义一直输出,如果项目中已经使用了其他的日志框架,而不想让gunicorn接管日志输出,需要将日志框架的对象指定给这里
29
40
 
30
41
  def load_config(self):
31
- config = {key: value for key, value in iteritems(self.options)
42
+ try:
43
+ funcy = import_module("funcy")
44
+ except ImportError:
45
+ raise Exception(f"pystache is not exist,run:pip install pystache==0.6.5")
46
+ config = {key: value for key, value in funcy.iteritems(self.options)
32
47
  if key in self.cfg.settings and value is not None}
33
- for key, value in iteritems(config):
48
+ for key, value in funcy.iteritems(config):
34
49
  self.cfg.set(key.lower(), value)
35
50
 
36
51
  def load(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lesscode-flask
3
- Version: 0.0.65
3
+ Version: 0.0.67
4
4
  Summary: lesscode-flask 是基于flask的web开发脚手架项目,该项目初衷为简化开发过程,让研发人员更加关注业务。
5
5
  Home-page: https://lesscode-flask
6
6
  Author: Chao.yy
@@ -11,17 +11,6 @@ Classifier: Operating System :: OS Independent
11
11
  Requires-Python: >=3.9
12
12
  Description-Content-Type: text/markdown
13
13
  Requires-Dist: Flask==3.0.3
14
- Requires-Dist: Flask-Login==0.6.3
15
- Requires-Dist: redis==5.1.1
16
- Requires-Dist: flask-swagger-ui==4.11.1
17
- Requires-Dist: pystache==0.6.5
18
- Requires-Dist: python-dateutil==2.9.0.post0
19
- Requires-Dist: funcy==2.0
20
- Requires-Dist: Flask-SQLAlchemy==3.1.1
21
- Requires-Dist: sqlparse==0.5.1
22
- Requires-Dist: requests==2.32.3
23
- Requires-Dist: gunicorn==23.0.0
24
- Requires-Dist: gevent==24.10.2
25
14
 
26
15
  # lesscode-flask
27
16
 
@@ -0,0 +1 @@
1
+ Flask==3.0.3
@@ -2,12 +2,24 @@ import logging
2
2
  from collections import defaultdict
3
3
  from contextlib import ExitStack
4
4
  from functools import wraps
5
+ from importlib import import_module
5
6
 
6
- import sqlparse
7
+ # import sqlparse
7
8
  from dateutil import parser
9
+
8
10
  # from rq.timeouts import JobTimeoutException
9
11
  # from sshtunnel import open_tunnel
10
12
 
13
+ try:
14
+ sqlparse = import_module("sqlparse")
15
+ except ImportError as e:
16
+ raise Exception(f"sqlparse is not exist,run:pip install sqlparse==0.5.1")
17
+
18
+ try:
19
+ sshtunnel = import_module("sshtunnel")
20
+ except ImportError as e:
21
+ raise Exception(f"sshtunnel is not exist,run:pip install sshtunnel==0.4.0")
22
+
11
23
  from redash import settings, utils
12
24
  from redash.utils.requests_session import (
13
25
  # UnacceptableAddressException,
@@ -503,7 +515,7 @@ def with_ssh_tunnel(query_runner, details):
503
515
  "ssh_username": details["ssh_username"],
504
516
  **settings.dynamic_settings.ssh_tunnel_auth(),
505
517
  }
506
- server = stack.enter_context(open_tunnel(bastion_address, remote_bind_address=remote_address, **auth))
518
+ server = stack.enter_context(sshtunnel.open_tunnel(bastion_address, remote_bind_address=remote_address, **auth))
507
519
  except Exception as error:
508
520
  raise type(error)("SSH tunnel: {}".format(str(error)))
509
521
 
@@ -1,11 +1,12 @@
1
1
  import logging
2
2
  import re
3
+ from importlib import import_module
3
4
  from urllib.parse import urlparse
4
5
 
5
- import requests
6
-
7
6
  from redash.query_runner import *
8
- from redash.utils import json_dumps, json_loads
7
+ from redash.utils import json_loads
8
+
9
+ # import requests
9
10
 
10
11
  logger = logging.getLogger(__name__)
11
12
 
@@ -89,6 +90,10 @@ class ClickHouse(BaseSQLQueryRunner):
89
90
 
90
91
  def _send_query(self, data, stream=False):
91
92
  url = self.configuration.get("url", "http://127.0.0.1:8123")
93
+ try:
94
+ requests = import_module("requests")
95
+ except ImportError as e:
96
+ raise Exception(f"requests is not exist,run:pip install requests==2.32.3")
92
97
  try:
93
98
  verify = self.configuration.get("verify", True)
94
99
  r = requests.post(
@@ -3,8 +3,12 @@ import sys
3
3
  import urllib.request
4
4
  import urllib.parse
5
5
  import urllib.error
6
+ from importlib import import_module
6
7
 
7
- import requests
8
+ try:
9
+ requests = import_module("requests")
10
+ except ImportError as e:
11
+ raise Exception(f"requests is not exist,run:pip install requests==2.32.3")
8
12
  from requests.auth import HTTPBasicAuth
9
13
 
10
14
  from redash.query_runner import *
@@ -1,14 +1,15 @@
1
1
  import os
2
+ from importlib import import_module
2
3
 
3
4
  from redash.settings.helpers import parse_boolean, array_from_string
4
- from funcy import distinct, remove
5
+
6
+ # from funcy import distinct, remove
5
7
 
6
8
  # Whether api calls using the json query runner will block private addresses
7
9
  ENFORCE_PRIVATE_ADDRESS_BLOCK = parse_boolean(os.environ.get("REDASH_ENFORCE_PRIVATE_IP_BLOCK", "true"))
8
10
  # requests
9
11
  REQUESTS_ALLOW_REDIRECTS = parse_boolean(os.environ.get("REDASH_REQUESTS_ALLOW_REDIRECTS", "false"))
10
12
 
11
-
12
13
  # Query Runners
13
14
  default_query_runners = [
14
15
  # "redash.query_runner.athena",
@@ -84,7 +85,12 @@ enabled_query_runners = array_from_string(
84
85
  additional_query_runners = array_from_string(os.environ.get("REDASH_ADDITIONAL_QUERY_RUNNERS", ""))
85
86
  disabled_query_runners = array_from_string(os.environ.get("REDASH_DISABLED_QUERY_RUNNERS", ""))
86
87
 
87
- QUERY_RUNNERS = remove(
88
+ try:
89
+ funcy = import_module("funcy")
90
+ except ImportError as e:
91
+ raise Exception(f"funcy is not exist,run:pip install funcy==2.0")
92
+
93
+ QUERY_RUNNERS = funcy.remove(
88
94
  set(disabled_query_runners),
89
- distinct(enabled_query_runners + additional_query_runners),
90
- )
95
+ funcy.distinct(enabled_query_runners + additional_query_runners),
96
+ )
@@ -1,11 +1,18 @@
1
1
  # from advocate.exceptions import UnacceptableAddressException # noqa: F401
2
+ from importlib import import_module
2
3
 
3
4
  from redash import settings
4
5
 
5
6
  # if settings.ENFORCE_PRIVATE_ADDRESS_BLOCK:
6
7
  # import advocate as requests_or_advocate
7
8
  # else:
8
- import requests as requests_or_advocate
9
+
10
+ # import requests as requests_or_advocate
11
+
12
+ try:
13
+ requests_or_advocate = import_module("requests")
14
+ except ImportError as e:
15
+ raise Exception(f"requests is not exist,run:pip install requests==2.32.3")
9
16
 
10
17
 
11
18
  class ConfiguredSession(requests_or_advocate.Session):
@@ -1,12 +0,0 @@
1
- Flask==3.0.3
2
- Flask-Login==0.6.3
3
- redis==5.1.1
4
- flask-swagger-ui==4.11.1
5
- pystache==0.6.5
6
- python-dateutil==2.9.0.post0
7
- funcy==2.0
8
- Flask-SQLAlchemy==3.1.1
9
- sqlparse==0.5.1
10
- requests==2.32.3
11
- gunicorn==23.0.0
12
- gevent==24.10.2