bkflow-sdk 0.0.28__py2.py3-none-any.whl

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.
bkflow/client/core.py ADDED
@@ -0,0 +1,253 @@
1
+ """
2
+ Tencent is pleased to support the open source community by making 蓝鲸智云 - PaaS平台 (BlueKing - PaaS System) available.
3
+ Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved.
4
+ Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+ http://opensource.org/licenses/MIT
7
+ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8
+ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9
+ specific language governing permissions and limitations under the License.
10
+ """
11
+
12
+ import json
13
+ import logging
14
+
15
+ import requests
16
+ from django.conf import settings
17
+
18
+ from bkflow.client.apis.bkflow import CollectionsBKFlow
19
+ from bkflow.common.exceptions import APIException
20
+
21
+ logger = logging.getLogger(__name__)
22
+
23
+ __all__ = [
24
+ "get_client_by_request",
25
+ "get_client_by_user",
26
+ ]
27
+
28
+ HEADER_BK_AUTHORIZATION = "X-Bkapi-Authorization"
29
+ DEFAULT_STAGE = getattr(settings, "BK_APIGW_STAGE_NAME", "prod")
30
+ AVAILABLE_COLLECTIONS = {
31
+ "bkflow": CollectionsBKFlow,
32
+ }
33
+
34
+
35
+ class BaseAPIClient:
36
+ """Base client class for api"""
37
+
38
+ def __init__(
39
+ self,
40
+ app_code=None,
41
+ app_secret=None,
42
+ headers=None,
43
+ common_args=None,
44
+ stage="prod",
45
+ timeout=None,
46
+ bk_apigw_ver="v3",
47
+ ):
48
+ """
49
+ :param str app_code: App code to use
50
+ :param str app_secret: App secret to use
51
+ :param dict headers: headers be sent to api
52
+ :param dict common_args: Args that will apply to every request
53
+ :param str stage: Stage for api gateway
54
+ :param int timeout: timeout for request
55
+ """
56
+
57
+ self.app_code = app_code or settings.APP_CODE
58
+ self.app_secret = app_secret or settings.SECRET_KEY
59
+ self.headers = headers or {}
60
+ self.common_args = common_args or {}
61
+ self.stage = stage
62
+ self.bk_apigw_ver = bk_apigw_ver
63
+ self.timeout = timeout
64
+ self._cached_collections = {}
65
+ self._log_warning()
66
+ self.available_collections = AVAILABLE_COLLECTIONS
67
+
68
+ def _log_warning(self):
69
+ _, _, api_name = __package__.partition(".")
70
+ logger.warning(
71
+ "%s is no longer maintained, recommend to use bkapi.%s as a replacement",
72
+ __package__,
73
+ api_name,
74
+ )
75
+
76
+ def merge_params_data_with_common_args(self, method, params, data):
77
+ """Add common args to params every request"""
78
+ common_args = dict(app_code=self.app_code, **self.common_args)
79
+ if method in ["GET", "HEAD"]:
80
+ _params = common_args.copy()
81
+ _params.update(params or {})
82
+ params = _params
83
+ elif method in ["POST", "PUT", "PATCH", "DELETE"]:
84
+ _data = common_args.copy()
85
+ _data.update(data or {})
86
+ data = json.dumps(_data)
87
+ return params, data
88
+
89
+ def __getattr__(self, key):
90
+ if key not in self.available_collections:
91
+ return getattr(super(), key)
92
+
93
+ if key not in self._cached_collections:
94
+ collection = self.available_collections[key]
95
+ self._cached_collections[key] = collection(self)
96
+ return self._cached_collections[key]
97
+
98
+ def request(self, method, url, params=None, data=None, path_params=None, **kwargs):
99
+ # Merge custom headers with instance headers
100
+ headers = self.headers.copy()
101
+ if "headers" in kwargs:
102
+ headers.update(kwargs.pop("headers"))
103
+ return requests.request(method, url, headers=headers, params=params, json=data, timeout=self.timeout, **kwargs)
104
+
105
+
106
+ class RedirectAPIClient(BaseAPIClient):
107
+ """用于根据View的request配置重定向请求."""
108
+
109
+ def redirect(self, request):
110
+ pass
111
+
112
+
113
+ class RequestAPIClient(BaseAPIClient):
114
+ def request(self, *args, **kwargs):
115
+ # update headers
116
+ headers = kwargs.pop("headers", {})
117
+ headers.update(self.headers)
118
+ method = kwargs.get("method", "GET")
119
+ if method.upper() in ["POST", "PUT", "PATCH", "DELETE"]:
120
+ headers["Content-Type"] = "application/json"
121
+ return self._request(headers=headers, *args, **kwargs)
122
+
123
+ def _request(self, method, url, params=None, data=None, **kwargs):
124
+ """Send request direct"""
125
+ params, data = self.merge_params_data_with_common_args(method, params, data)
126
+ logger.info("Calling %s %s with params=%s, data=%s", method, url, params, data)
127
+ return requests.request(method, url, params=params, json=data, timeout=self.timeout, **kwargs)
128
+
129
+
130
+ def get_client_by_request(request, stage=DEFAULT_STAGE, common_args=None, headers=None):
131
+ """
132
+ 根据当前请求返回一个client
133
+ :param request: 一个django request实例
134
+ :param stage: 请求环境,默认为prod
135
+ :param common_args: 公共请求参数
136
+ :param headers: 头部信息
137
+ :returns: 一个初始化好的APIClint对象
138
+ """
139
+ headers = headers or {}
140
+
141
+ is_authenticated = request.user.is_authenticated
142
+ if callable(is_authenticated):
143
+ is_authenticated = is_authenticated()
144
+ if is_authenticated:
145
+ headers.update(
146
+ {
147
+ HEADER_BK_AUTHORIZATION: json.dumps(
148
+ {
149
+ "bk_ticket": request.COOKIES.get("bk_ticket", ""),
150
+ "bk_app_code": settings.APP_CODE,
151
+ "bk_app_secret": settings.SECRET_KEY,
152
+ }
153
+ )
154
+ }
155
+ )
156
+ else:
157
+ raise APIException("用户未通过验证")
158
+
159
+ return RedirectAPIClient(
160
+ app_code=settings.APP_CODE,
161
+ app_secret=settings.SECRET_KEY,
162
+ headers=headers,
163
+ common_args=common_args,
164
+ stage=stage,
165
+ )
166
+
167
+
168
+ def get_client_by_user(user, stage=DEFAULT_STAGE, common_args=None, headers=None):
169
+ """
170
+ 根据user实例返回一个client
171
+ :param user: 用户
172
+ :param stage: 请求环境,默认为prod
173
+ :param common_args: 公共请求参数
174
+ :param common_args: 公共请求参数
175
+ :param headers: 头部信息
176
+ :returns: 一个初始化好的APIClint对象
177
+ """
178
+ headers = headers or {}
179
+ common_args = common_args or {}
180
+ if hasattr(user, "username"):
181
+ user = user.username
182
+ try:
183
+ from bkoauth import get_access_token_by_user
184
+
185
+ access_token = get_access_token_by_user(user)
186
+ headers.update(
187
+ {
188
+ HEADER_BK_AUTHORIZATION: json.dumps({"access_token": access_token.access_token}),
189
+ }
190
+ )
191
+ except Exception as e:
192
+ logger.warning("get_access_token_by_user error %s, using header authorization", str(e))
193
+ headers.update(
194
+ {
195
+ HEADER_BK_AUTHORIZATION: json.dumps(
196
+ {"bk_username": user, "bk_app_code": settings.APP_CODE, "bk_app_secret": settings.SECRET_KEY}
197
+ )
198
+ }
199
+ )
200
+
201
+ return RedirectAPIClient(
202
+ app_code=settings.APP_CODE,
203
+ app_secret=settings.SECRET_KEY,
204
+ headers=headers,
205
+ common_args=common_args,
206
+ stage=stage,
207
+ )
208
+
209
+
210
+ def get_redirect_client_with_auth(request, **kwargs):
211
+ """
212
+ 根据当前请求返回一个带有认证信息的client
213
+ :param request: 一个django request实例
214
+ :returns: 一个初始化好的APIClint对象
215
+ """
216
+ bk_ticket = request.COOKIES.get("bk_ticket", None)
217
+ bk_token = request.COOKIES.get("bk_token", None)
218
+ if not bk_ticket and not bk_token:
219
+ raise APIException("用户未通过验证")
220
+ headers = {
221
+ HEADER_BK_AUTHORIZATION: json.dumps(
222
+ {
223
+ "bk_app_code": settings.APP_CODE,
224
+ "bk_app_secret": settings.SECRET_KEY,
225
+ "bk_ticket": bk_ticket,
226
+ "bk_token": bk_token,
227
+ }
228
+ )
229
+ }
230
+
231
+ return RedirectAPIClient(
232
+ app_code=settings.APP_CODE, app_secret=settings.SECRET_KEY, headers=headers, common_args={}, stage=DEFAULT_STAGE
233
+ )
234
+
235
+
236
+ def get_redirect_client(request):
237
+ """
238
+ 根据当前请求返回一个client
239
+ :param request: 一个django request实例
240
+ :returns: 一个初始化好的APIClint对象
241
+ """
242
+ headers = {
243
+ HEADER_BK_AUTHORIZATION: json.dumps(
244
+ {
245
+ "bk_app_code": settings.APP_CODE,
246
+ "bk_app_secret": settings.SECRET_KEY,
247
+ }
248
+ )
249
+ }
250
+
251
+ return RedirectAPIClient(
252
+ app_code=settings.APP_CODE, app_secret=settings.SECRET_KEY, headers=headers, common_args={}, stage=DEFAULT_STAGE
253
+ )
@@ -0,0 +1,10 @@
1
+ """
2
+ Tencent is pleased to support the open source community by making 蓝鲸智云 - PaaS平台 (BlueKing - PaaS System) available.
3
+ Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved.
4
+ Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+ http://opensource.org/licenses/MIT
7
+ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8
+ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9
+ specific language governing permissions and limitations under the License.
10
+ """
@@ -0,0 +1,107 @@
1
+ """
2
+ Tencent is pleased to support the open source community by making 蓝鲸智云 - PaaS平台 (BlueKing - PaaS System) available.
3
+ Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved.
4
+ Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+ http://opensource.org/licenses/MIT
7
+ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8
+ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9
+ specific language governing permissions and limitations under the License.
10
+ """
11
+ from functools import wraps
12
+
13
+ from django.core.handlers.wsgi import WSGIRequest
14
+ from django.utils.translation import gettext_lazy as _
15
+ from rest_framework import serializers
16
+ from rest_framework.request import Request
17
+
18
+ from bkflow.common.exceptions import ValidationError
19
+ from bkflow.common.validator import custom_params_valid
20
+ from bkflow.config.default import REQUEST_TOKEN_HEADER_KEY
21
+
22
+
23
+ def token_inject(view_func):
24
+ """
25
+ token注入
26
+ :param view_func: 被装饰的view函数
27
+ """
28
+
29
+ def wrapper(*args, **kwargs):
30
+ request = args[1]
31
+ if not hasattr(request, "token"):
32
+ token = request.META.get(REQUEST_TOKEN_HEADER_KEY, "")
33
+
34
+ if not token:
35
+ raise ValidationError(
36
+ _("当前接口需要token,请在请求头中添加${REQUEST_TOKEN_HEADER_KEY}").format(
37
+ REQUEST_TOKEN_HEADER_KEY=REQUEST_TOKEN_HEADER_KEY
38
+ )
39
+ )
40
+
41
+ setattr(request, "token", token)
42
+
43
+ return view_func(*args, **kwargs)
44
+
45
+ return wraps(view_func)(wrapper)
46
+
47
+
48
+ def params_valid(serializer: serializers.Serializer, add_params: bool = True):
49
+ """参数校验装饰器
50
+
51
+ :param serializer: serializer类
52
+ :param add_params: 是否将校验后的参数添加到request.cleaned_params中
53
+ :return: 参数校验装饰器
54
+ """
55
+
56
+ def decorator(view_func):
57
+ @wraps(view_func)
58
+ def wrapper(*args, **kwargs):
59
+ # 获得Django的request对象
60
+ _request = kwargs.get("request")
61
+
62
+ if not _request:
63
+ for arg in args:
64
+ if isinstance(arg, (Request, WSGIRequest)):
65
+ _request = arg
66
+ break
67
+
68
+ if not _request:
69
+ raise ValidationError(_("该装饰器只允许用于Django的View函数(包括普通View函数和Class-base的View函数)"))
70
+
71
+ # 校验request中的参数
72
+ params = {}
73
+ if _request.method in ["GET"]:
74
+ if isinstance(_request, Request):
75
+ params = _request.query_params
76
+ else:
77
+ params = _request.GET
78
+ elif _request.META.get("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest":
79
+ if isinstance(_request, Request):
80
+ params = _request.data
81
+ else:
82
+ params = _request.json()
83
+ else:
84
+ if isinstance(_request, Request):
85
+ params = _request.data
86
+ else:
87
+ params = _request.POST
88
+
89
+ cleaned_params = custom_params_valid(serializer=serializer, params=params)
90
+ _request.cleaned_params = cleaned_params
91
+
92
+ # 执行实际的View逻辑
93
+ params_add = False
94
+ try:
95
+ # 语法糖,使用这个decorator的话可直接从view中获得参数的字典
96
+ if "params" not in kwargs and add_params:
97
+ kwargs["params"] = cleaned_params
98
+ params_add = True
99
+ except TypeError:
100
+ if params_add:
101
+ del kwargs["params"]
102
+ resp = view_func(*args, **kwargs)
103
+ return resp
104
+
105
+ return wrapper
106
+
107
+ return decorator
@@ -0,0 +1,46 @@
1
+ """
2
+ Tencent is pleased to support the open source community by making 蓝鲸智云 - PaaS平台 (BlueKing - PaaS System) available.
3
+ Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved.
4
+ Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+ http://opensource.org/licenses/MIT
7
+ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8
+ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9
+ specific language governing permissions and limitations under the License.
10
+ """
11
+
12
+
13
+ class BkflowSDKException(Exception):
14
+ CODE = None
15
+ MESSAGE = None
16
+ STATUS_CODE = 500
17
+
18
+ def __init__(self, message="", errors=""):
19
+ if message:
20
+ self.MESSAGE = message
21
+ if self.MESSAGE and errors:
22
+ self.message = f"{self.MESSAGE}: {errors}"
23
+ elif self.MESSAGE:
24
+ self.message = self.MESSAGE
25
+ else:
26
+ self.message = f"{errors}"
27
+
28
+ def __str__(self):
29
+ return self.message
30
+
31
+
32
+ class APIException(BkflowSDKException):
33
+ """Exception for API"""
34
+
35
+ def __init__(self, errors, resp=None, url=""):
36
+ self.url = url
37
+ self.error_message = errors
38
+ self.resp = resp
39
+
40
+ if self.resp is not None:
41
+ errors = "%s, resp=%s" % (errors, self.resp.text)
42
+ super(APIException, self).__init__(errors)
43
+
44
+
45
+ class ValidationError(BkflowSDKException):
46
+ pass
@@ -0,0 +1,96 @@
1
+ """
2
+ Tencent is pleased to support the open source community by making 蓝鲸智云 - PaaS平台 (BlueKing - PaaS System) available.
3
+ Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved.
4
+ Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+ http://opensource.org/licenses/MIT
7
+ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8
+ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9
+ specific language governing permissions and limitations under the License.
10
+ """
11
+ import json
12
+
13
+ from django.utils.translation import gettext_lazy as _
14
+ from rest_framework import serializers
15
+
16
+ from bkflow.common.exceptions import ValidationError
17
+
18
+
19
+ def format_serializer_errors(errors: dict, fields: dict, params: dict, prefix: str = " "):
20
+ """格式化序列化器错误信息
21
+
22
+ :param errors: 错误信息
23
+ :param fields: 序列化器字段
24
+ :param params: 参数
25
+ :return: 格式化后的错误信息
26
+ """
27
+ message = _("参数校验失败:{wrap}").format(wrap="\n") if prefix == " " else "\n"
28
+ for key, field_errors in list(errors.items()):
29
+ sub_message = ""
30
+ label = key
31
+ if key not in fields:
32
+ sub_message = json.dumps(field_errors, ensure_ascii=False)
33
+ else:
34
+ field = fields[key]
35
+ label = field.label or field.field_name
36
+ if (
37
+ hasattr(field, "child")
38
+ and isinstance(field_errors, list)
39
+ and len(field_errors) > 0
40
+ and not isinstance(field_errors[0], str)
41
+ ):
42
+ for index, sub_errors in enumerate(field_errors):
43
+ if sub_errors:
44
+ sub_format = format_serializer_errors(
45
+ sub_errors, field.child.fields, params, prefix=prefix + " "
46
+ )
47
+ # return sub_format
48
+ sub_message += _("{wrap}{prefix}第{index}项:").format(
49
+ wrap="\n",
50
+ prefix=prefix + " ",
51
+ index=index + 1,
52
+ )
53
+ sub_message += sub_format
54
+ else:
55
+ if isinstance(field_errors, dict):
56
+ if hasattr(field, "child"):
57
+ sub_foramt = format_serializer_errors(
58
+ field_errors, field.child.fields, params, prefix=prefix + " "
59
+ )
60
+ else:
61
+ sub_foramt = format_serializer_errors(field_errors, field.fields, params, prefix=prefix + " ")
62
+ sub_message += sub_foramt
63
+ elif isinstance(field_errors, list):
64
+ for index in range(len(field_errors)):
65
+ field_errors[index] = field_errors[index].format(**{key: params.get(key, "")})
66
+ sub_message += "{index}.{error}".format(index=index + 1, error=field_errors[index])
67
+ sub_message += "\n"
68
+ # 对使用 Validate() 时 label == "non_field_errors" 的特殊情况做处理
69
+ if label == "non_field_errors":
70
+ message += f"{prefix} {sub_message}"
71
+ else:
72
+ message += f"{prefix}{label}: {sub_message}"
73
+ return message
74
+
75
+
76
+ def custom_params_valid(serializer: serializers.Serializer, params: dict, many: bool = False):
77
+ """校验参数
78
+
79
+ :param serializer: 校验器
80
+ :param params: 原始参数
81
+ :param many: 是否为多个参数
82
+ :return: 校验通过的参数
83
+ """
84
+ _serializer = serializer(data=params, many=many)
85
+ try:
86
+ _serializer.is_valid(raise_exception=True)
87
+ except serializers.ValidationError as e: # pylint: disable=broad-except # noqa
88
+ try:
89
+ message = format_serializer_errors(_serializer.errors, _serializer.fields, params)
90
+ except Exception as e: # pylint: disable=broad-except
91
+ if isinstance(e.message, str):
92
+ message = e.message
93
+ else:
94
+ message = _("参数校验失败,详情请查看返回的errors")
95
+ raise ValidationError(message=message, errors=_serializer.errors)
96
+ return list(_serializer.validated_data) if many else dict(_serializer.validated_data)
bkflow/common/views.py ADDED
@@ -0,0 +1,50 @@
1
+ """
2
+ Tencent is pleased to support the open source community by making 蓝鲸智云 - PaaS平台 (BlueKing - PaaS System) available.
3
+ Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved.
4
+ Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+ http://opensource.org/licenses/MIT
7
+ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8
+ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9
+ specific language governing permissions and limitations under the License.
10
+ """
11
+ import urllib
12
+
13
+ from django.conf import settings
14
+ from rest_framework import status
15
+ from rest_framework.renderers import JSONRenderer
16
+ from rest_framework.response import Response
17
+ from rest_framework.viewsets import GenericViewSet
18
+
19
+ from bkflow.config.default import BK_TOKEN_EXPIRED_CODE
20
+
21
+
22
+ class SimpleGenericViewSet(GenericViewSet):
23
+ """
24
+ 最基础的视图函数,不支持model, view_set 的 创建,查看,更新,删除方法,只支持用户自定义的action
25
+ """
26
+
27
+ renderer_classes = [JSONRenderer]
28
+ EXEMPT_STATUS_CODES = {status.HTTP_204_NO_CONTENT}
29
+ RESPONSE_WRAPPER = None
30
+
31
+ def default_response_wrapper(self, data):
32
+ return {"result": True, "data": data, "code": "0", "message": ""}
33
+
34
+ def finalize_response(self, request, response, *args, **kwargs):
35
+
36
+ if isinstance(response, Response):
37
+ res_data = {
38
+ "result": response.data.get("result"),
39
+ "code": response.data.get("code"),
40
+ "data": response.data.get("data"),
41
+ "message": response.data.get("message"),
42
+ }
43
+ if response.data.get("count"):
44
+ res_data["count"] = response.data.get("count")
45
+ response.data = res_data
46
+ if str(response.data.get("code")) == BK_TOKEN_EXPIRED_CODE:
47
+ response.status_code = 401
48
+ curl = urllib.parse.quote(request.build_absolute_uri())
49
+ res_data["data"] = {"login_url": f"{getattr(settings,'BKPAAS_LOGIN_URL','')}?curl={curl}"}
50
+ return super(SimpleGenericViewSet, self).finalize_response(request, response, *args, **kwargs)
@@ -0,0 +1,10 @@
1
+ """
2
+ Tencent is pleased to support the open source community by making 蓝鲸智云 - PaaS平台 (BlueKing - PaaS System) available.
3
+ Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved.
4
+ Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+ http://opensource.org/licenses/MIT
7
+ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8
+ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9
+ specific language governing permissions and limitations under the License.
10
+ """
@@ -0,0 +1,61 @@
1
+ """
2
+ Tencent is pleased to support the open source community by making 蓝鲸智云 - PaaS平台 (BlueKing - PaaS System) available.
3
+ Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved.
4
+ Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+ http://opensource.org/licenses/MIT
7
+ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8
+ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9
+ specific language governing permissions and limitations under the License.
10
+ """
11
+ from django.conf import settings
12
+
13
+ BKFLOW_SDK_APIGW_HOST = getattr(settings, "BKFLOW_SDK_APIGW_HOST", "")
14
+ DEFAULT_SETTINGS = {
15
+ "BKFLOW_SDK_APIGW_HOST": BKFLOW_SDK_APIGW_HOST,
16
+ "BKFLOW_SDK_DEFAULT_SPACE_ID": "",
17
+ "common_key1": "common_value2",
18
+ "interface": {"interface_key1": "interface_value1"},
19
+ }
20
+ REQUEST_TOKEN_HEADER_KEY = "HTTP_BKFLOW_TOKEN"
21
+ API_TOKEN_HEADER_KEY = "BKFLOW-TOKEN"
22
+ BK_TOKEN_EXPIRED_CODE = "1640001"
23
+
24
+
25
+ class BkflowSDKSettings:
26
+ SETTING_PREFIX = "BKFLOW_SDK"
27
+ NESTING_SEPARATOR = "_"
28
+
29
+ def __init__(self, default_settings=None):
30
+ self.project_settings = self.get_flatten_settings(getattr(settings, self.SETTING_PREFIX, {}))
31
+ self.default_settings = self.get_flatten_settings(default_settings or DEFAULT_SETTINGS)
32
+
33
+ def __getattr__(self, key):
34
+ if key not in self.project_settings and key not in self.default_settings:
35
+ raise AttributeError
36
+
37
+ value = self.project_settings.get(key) or self.default_settings.get(key)
38
+ if value is not None:
39
+ setattr(self, key, value)
40
+ return value
41
+
42
+ def get_flatten_settings(self, inputted_settings: dict, cur_prefix: str = ""):
43
+ def get_cur_key(cur_key):
44
+ return f"{cur_prefix}{self.NESTING_SEPARATOR}{cur_key}" if cur_prefix else cur_key
45
+
46
+ flatten_settings = {}
47
+ for key, value in inputted_settings.items():
48
+ if isinstance(value, dict):
49
+ flatten_sub_settings = self.get_flatten_settings(value, key)
50
+ flatten_settings.update(
51
+ {
52
+ get_cur_key(flatten_key): flatten_value
53
+ for flatten_key, flatten_value in flatten_sub_settings.items()
54
+ }
55
+ )
56
+ else:
57
+ flatten_settings[get_cur_key(key)] = value
58
+ return flatten_settings
59
+
60
+
61
+ bkflow_sdk_settings = BkflowSDKSettings(DEFAULT_SETTINGS)
@@ -0,0 +1,10 @@
1
+ """
2
+ Tencent is pleased to support the open source community by making 蓝鲸智云 - PaaS平台 (BlueKing - PaaS System) available.
3
+ Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved.
4
+ Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+ http://opensource.org/licenses/MIT
7
+ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8
+ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9
+ specific language governing permissions and limitations under the License.
10
+ """
@@ -0,0 +1,18 @@
1
+ """
2
+ Tencent is pleased to support the open source community by making 蓝鲸智云 - PaaS平台 (BlueKing - PaaS System) available.
3
+ Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved.
4
+ Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+ http://opensource.org/licenses/MIT
7
+ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
8
+ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
9
+ specific language governing permissions and limitations under the License.
10
+ """
11
+ from django.apps import AppConfig
12
+
13
+
14
+ class BkflowInterfaceConfig(AppConfig):
15
+ name = "bkflow.interface"
16
+
17
+ def ready(self):
18
+ pass