sanic-api 0.2.9__py3-none-any.whl → 0.3.0__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.
Files changed (45) hide show
  1. sanic_api/__init__.py +2 -20
  2. sanic_api/api/__init__.py +17 -2
  3. sanic_api/api/model.py +0 -46
  4. sanic_api/api/request.py +157 -0
  5. sanic_api/api/response.py +34 -0
  6. sanic_api/app.py +306 -0
  7. sanic_api/config/__init__.py +1 -1
  8. sanic_api/config/setting.py +69 -14
  9. sanic_api/logger/__init__.py +0 -1
  10. sanic_api/logger/config.py +74 -52
  11. sanic_api/logger/extension.py +130 -0
  12. sanic_api/openapi/__init__.py +0 -7
  13. sanic_api/utils/__init__.py +0 -0
  14. sanic_api/{enum.py → utils/enum.py} +1 -31
  15. sanic_api-0.3.0.dist-info/METADATA +160 -0
  16. sanic_api-0.3.0.dist-info/RECORD +19 -0
  17. {sanic_api-0.2.9.dist-info → sanic_api-0.3.0.dist-info}/WHEEL +1 -1
  18. example/__main__.py +0 -19
  19. example/api/__init__.py +0 -1
  20. example/api/t1/__init__.py +0 -2
  21. example/api/t1/t1_1.py +0 -22
  22. example/api/t1/t1_2.py +0 -9
  23. example/api/t2/__init__.py +0 -1
  24. example/api/t2/t2.py +0 -9
  25. example/api/t2/t3/__init__.py +0 -1
  26. example/api/t2/t3/t3.py +0 -9
  27. example/api/user.py +0 -89
  28. example/api/validator.py +0 -97
  29. example/app.py +0 -62
  30. example/settings.py +0 -10
  31. sanic_api/api/api.py +0 -177
  32. sanic_api/api/exception.py +0 -46
  33. sanic_api/api/extend.py +0 -25
  34. sanic_api/api/handle_exception.py +0 -61
  35. sanic_api/api/validators.py +0 -76
  36. sanic_api/config/sanic.py +0 -19
  37. sanic_api/config/sanic_api.py +0 -11
  38. sanic_api/logger/extend.py +0 -71
  39. sanic_api/logger/sanic_http.py +0 -68
  40. sanic_api/openapi/openapi.py +0 -102
  41. sanic_api/utils.py +0 -112
  42. sanic_api-0.2.9.dist-info/METADATA +0 -96
  43. sanic_api-0.2.9.dist-info/RECORD +0 -38
  44. /example/__init__.py → /sanic_api/openapi/extension.py +0 -0
  45. {sanic_api-0.2.9.dist-info → sanic_api-0.3.0.dist-info}/licenses/LICENSE.txt +0 -0
sanic_api/__init__.py CHANGED
@@ -1,21 +1,3 @@
1
- from sanic import Sanic
2
- from sanic_ext import Extend
1
+ from sanic_api.logger.extension import LoggerExtend
3
2
 
4
- from sanic_api import api, openapi
5
-
6
- from .api import ApiExtend
7
- from .logger import LoggerExtend
8
-
9
-
10
- def init_api(app: Sanic):
11
- """
12
- 初始化API
13
- Args:
14
- app: Sanic的APP
15
-
16
- Returns:
17
-
18
- """
19
- Extend.register(LoggerExtend)
20
- Extend.register(ApiExtend)
21
- openapi.init(app)
3
+ __version__ = "0.3.0"
sanic_api/api/__init__.py CHANGED
@@ -1,2 +1,17 @@
1
- from .api import API
2
- from .extend import ApiExtend
1
+ from sanic_api.api.request import Request
2
+ from sanic_api.api.response import BaseResp, BaseRespTml, TempModel
3
+
4
+ """
5
+ class BaseResponseModel(BaseModel):
6
+ "直接返回str、int、float、bool等类型"
7
+ ...
8
+
9
+ class JsonResponseModel(BaseModel):
10
+ "返回JSON的Pydantic结构"
11
+ ...
12
+
13
+ class ListResponseModel(BaseModel):
14
+ "返回JSON的Pydantic结构的列表"
15
+ ...
16
+
17
+ """
sanic_api/api/model.py CHANGED
@@ -1,46 +0,0 @@
1
- from typing import Optional, Union
2
-
3
- from pydantic.fields import ModelPrivateAttr
4
- from pydantic.main import BaseModel
5
- from pydantic_core.core_schema import ModelField
6
-
7
-
8
- class ResponseModel(BaseModel):
9
- """
10
- 响应基础模型
11
- """
12
-
13
- def __new__(cls, *args, **kwargs):
14
- for _field, value in cls.model_fields.items():
15
- if not isinstance(value, ModelField):
16
- continue
17
- value.required = False
18
-
19
- return super().__new__(cls, *args, **kwargs)
20
-
21
-
22
- class ListRespModel(ResponseModel):
23
- """
24
- 列表格式的响应基础模型
25
- """
26
-
27
- _data_list: Optional[Union[ModelPrivateAttr, list]] = ModelPrivateAttr(default_factory=list)
28
-
29
- def add_data(self):
30
- """
31
- 当前模型下数据添加到列表中
32
- Returns:
33
-
34
- """
35
- data = self.dict()
36
- self._data_list.append(data)
37
- for attr in data.keys():
38
- self.__setattr__(attr, None)
39
-
40
- def to_list(self):
41
- """
42
- 返回列表响应数据
43
- Returns:
44
-
45
- """
46
- return self._data_list
@@ -0,0 +1,157 @@
1
+ import inspect
2
+ from collections.abc import Collection
3
+ from typing import get_origin
4
+
5
+ from pydantic import BaseModel
6
+ from sanic import Request as SanicRequest
7
+ from sanic_ext.extensions.openapi.builders import OperationStore
8
+
9
+
10
+ class Request(SanicRequest):
11
+ """
12
+ 自定义的请求类
13
+ 加入便于接口参数获取校验的方法
14
+ """
15
+
16
+ json_data: BaseModel
17
+ form_data: BaseModel
18
+ query_data: BaseModel
19
+
20
+ _request_type: type["Request"] | None
21
+ _json_data_type: type[BaseModel] | None
22
+ _form_data_type: type[BaseModel] | None
23
+ _query_data_type: type[BaseModel] | None
24
+
25
+ def __init__(self, *args, **kwargs):
26
+ super().__init__(*args, **kwargs)
27
+
28
+ async def receive_body(self):
29
+ """
30
+ 接收请求体
31
+ 在这里进行参数校验注入的所有操作
32
+ Returns:
33
+
34
+ """
35
+ await super().receive_body()
36
+ self._get_data_type()
37
+ self._load_data()
38
+ self._set_openapi()
39
+
40
+ def _get_type(self, name: str, base_type: type):
41
+ """
42
+ 获取指定属性的类型
43
+ Args:
44
+ name: 属性名字
45
+ base_type: 所属的基本类型
46
+
47
+ Returns:
48
+ 对于参数返回BaseModel或None
49
+ 对于情求类型返回Request或None
50
+ """
51
+
52
+ route_handler_arg_spec = inspect.getfullargspec(self.route.handler)
53
+ arg_type = route_handler_arg_spec.annotations.get(name)
54
+ is_name = name in route_handler_arg_spec.args
55
+ is_type = arg_type and issubclass(arg_type, base_type) and arg_type not in (Request, SanicRequest)
56
+ if is_name and is_type:
57
+ return arg_type
58
+ return None
59
+
60
+ def _get_data_type(self):
61
+ """
62
+ 获取json_data、form_data、query_data、request的类型
63
+ 如果定义了request就从request上面获取上述类型
64
+ Returns:
65
+
66
+ """
67
+
68
+ # 从函数参数注解上面获取类型
69
+ self._json_data_type = self._get_type("json_data", BaseModel)
70
+ self._form_data_type = self._get_type("form_data", BaseModel)
71
+ self._query_data_type = self._get_type("query_data", BaseModel)
72
+ self._request_type = self._get_type("request", Request)
73
+
74
+ # 没有json_data参数 但是有自定义的request类就从request类上面获取json_data类型
75
+ if self._request_type and not self._json_data_type:
76
+ self._json_data_type = self._request_type.__annotations__.get("json_data")
77
+
78
+ # 没有form_data参数 但是有自定义的request类就从request类上面获取form_data类型
79
+ if self._request_type and not self._form_data_type:
80
+ self._form_data_type = self._request_type.__annotations__.get("form_data")
81
+
82
+ # 没有query_data参数 但是有自定义的request类就从request类上面获取query_data类型
83
+ if self._request_type and not self._query_data_type:
84
+ self._query_data_type = self._request_type.__annotations__.get("query_data")
85
+
86
+ # noinspection PyBroadException
87
+ def _load_data(self):
88
+ """
89
+ 加载json_data、form_data、query_data数据
90
+ 同时做参数校验及参数的注入
91
+ Returns:
92
+
93
+ """
94
+ route_handler_arg_spec = inspect.getfullargspec(self.route.handler)
95
+
96
+ def _set_arg(name, value):
97
+ arg_type = route_handler_arg_spec.annotations.get(name)
98
+ if name in route_handler_arg_spec.args and issubclass(arg_type, BaseModel):
99
+ self.match_info.update({name: value})
100
+
101
+ def _proc_param_data(data: dict, data_type: BaseModel | None):
102
+ for k, v in data.items():
103
+ if isinstance(v, list) and len(v) == 1:
104
+ field = data_type.model_fields.get(k)
105
+ if not field:
106
+ continue
107
+ arg_type = field.annotation
108
+ arg_type = get_origin(arg_type) or arg_type
109
+ is_list = issubclass(arg_type, Collection) and arg_type is not str
110
+ if not is_list:
111
+ data[k] = v[0]
112
+ return data
113
+
114
+ try:
115
+ json_data = self.json
116
+ except Exception:
117
+ json_data = None
118
+ if json_data and self._json_data_type:
119
+ self.json_data = self._json_data_type(**json_data)
120
+ _set_arg("json_data", self.json_data)
121
+
122
+ # 由于form和query的参数的key是可以重复的,所以默认类型是类似dict[str, list]的
123
+ # 这里做了个处理,如果key的数量是1个则直接转为dict[str, dict]
124
+ try:
125
+ form_data = self.form
126
+ except Exception:
127
+ form_data = None
128
+ if form_data and self._form_data_type:
129
+ form_data = _proc_param_data(form_data, self._form_data_type)
130
+ self.form_data = self._form_data_type(**form_data)
131
+ _set_arg("form_data", self.form_data)
132
+
133
+ try:
134
+ query_data = self.args
135
+ except Exception:
136
+ query_data = None
137
+ if query_data and self._query_data_type:
138
+ query_data = _proc_param_data(query_data, self._query_data_type)
139
+ self.query_data = self._query_data_type(**query_data)
140
+ _set_arg("query_data", self.query_data)
141
+
142
+ def _set_openapi(self):
143
+ """
144
+ 注入 OpenAPI 信息
145
+ """
146
+
147
+ func = self.route.handler
148
+
149
+ # 设置接口的概括和描述
150
+ api_doc = self._request_type.__doc__ if self._request_type else func.__doc__
151
+
152
+ if api_doc:
153
+ api_doc = api_doc.strip()
154
+ summary = api_doc.split("\n")[0]
155
+ description = "\n".join(api_doc.split("\n")[1:])
156
+
157
+ OperationStore()[func].describe(summary=summary, description=description)
@@ -0,0 +1,34 @@
1
+ from typing import Any, ClassVar
2
+
3
+ from pydantic import BaseModel, Field, PrivateAttr
4
+ from sanic.compat import Header
5
+ from sanic.response import JSONResponse
6
+
7
+
8
+ class TempModel(BaseModel):
9
+ _data_field: str = PrivateAttr(default="data")
10
+ data: Any = Field(default=None, title="数据")
11
+ code: str = Field(default_factory=str, title="业务状态码")
12
+ msg: str = Field(default_factory=str, title="消息")
13
+
14
+ def get_data_field_name(self) -> str:
15
+ return self._data_field
16
+
17
+
18
+ class BaseResp(BaseModel):
19
+ temp_data: ClassVar = Ellipsis
20
+
21
+ def resp(self, status: int = 200, headers: Header | dict[str, str] | None = None) -> JSONResponse:
22
+ data = self.model_dump(mode="json")
23
+ return JSONResponse(data, status=status, headers=headers)
24
+
25
+
26
+ class BaseRespTml(BaseModel):
27
+ temp_data: TempModel | None = Field(default_factory=TempModel)
28
+
29
+ def resp(self, status: int = 200, headers: Header | dict[str, str] | None = None) -> JSONResponse:
30
+ tmp_data_field_name = self.temp_data.get_data_field_name()
31
+ self_data = self.model_dump(mode="json", exclude={"temp_data"})
32
+ setattr(self.temp_data, tmp_data_field_name, self_data)
33
+ tml_data = self.temp_data.model_dump(mode="json")
34
+ return JSONResponse(tml_data, status=status, headers=headers)
sanic_api/app.py ADDED
@@ -0,0 +1,306 @@
1
+ import sentry_sdk
2
+ from sanic import Sanic, text
3
+ from sanic.log import logger
4
+ from sanic.worker.loader import AppLoader
5
+ from sanic_ext import Extend
6
+ from sentry_sdk.integrations.asyncio import AsyncioIntegration
7
+
8
+ from sanic_api import LoggerExtend
9
+ from sanic_api.api import Request
10
+ from sanic_api.config import DefaultSettings, RunModeEnum
11
+
12
+
13
+ class BaseApp:
14
+ name: str = "sanic-server"
15
+ settings: DefaultSettings
16
+
17
+ def __init__(self, settings: DefaultSettings):
18
+ self.settings = settings
19
+
20
+ @classmethod
21
+ def run(cls, settings: DefaultSettings = None):
22
+ """
23
+ 运行服务
24
+ Args:
25
+ settings: 设置,为空就使用默认设置
26
+
27
+ Returns:
28
+
29
+ """
30
+ if not cls.name:
31
+ raise ValueError("请设置服务名称!")
32
+
33
+ settings = settings or DefaultSettings()
34
+ self = cls(settings)
35
+ loader = AppLoader(factory=self._create_app)
36
+ app = loader.load()
37
+
38
+ # 服务配置
39
+ # 开发模式下workers指定为1,自动重载根据配置决定,默认关闭,跨域设置为允许所有跨域
40
+ # 生产模式下使用fast模型,自动指定最多的workers,自定重载强制关闭,跨域使用配置中的跨域列表
41
+ # 默认启用sanic_ext里面的后台日志记录器
42
+ motd_display = {"envornment": settings.envornment}
43
+ config = {"access_log": settings.access_log, "motd_display": motd_display}
44
+ if settings.mode == RunModeEnum.DEBNUG:
45
+ config.update({"auto_reload": settings.auto_reload, "workers": 1, "debug": True})
46
+ else:
47
+ config.update({"fast": True, "auto_reload": False})
48
+
49
+ app.prepare(settings.host, settings.port, **config)
50
+ Sanic.serve(primary=app, app_loader=loader)
51
+
52
+ def _create_app(self):
53
+ """
54
+ 创建app的内部工厂方法
55
+ Returns:
56
+
57
+ """
58
+ app = Sanic(self.name, configure_logging=False, request_class=Request)
59
+
60
+ self._setup_logger(app)
61
+ self._setup_config(app)
62
+ self._setup_openai(app)
63
+
64
+ app.main_process_stop(self._main_process_stop)
65
+ app.main_process_start(self._main_process_start)
66
+ app.before_server_start(self._before_server_start)
67
+ app.before_server_stop(self._before_server_stop)
68
+ app.after_server_start(self._after_server_start)
69
+ app.after_server_stop(self._after_server_stop)
70
+ return app
71
+
72
+ async def _main_process_start(self, app: Sanic):
73
+ """
74
+ 主进程启动的内部方法
75
+ Args:
76
+ app:
77
+
78
+ Returns:
79
+
80
+ """
81
+ logger.info("主进程启动")
82
+ await self.main_process_start(app)
83
+
84
+ async def _main_process_stop(self, app: Sanic):
85
+ """
86
+ 主进程停止的内部方法
87
+ Args:
88
+ app:
89
+
90
+ Returns:
91
+
92
+ """
93
+ logger.info("主进程停止")
94
+ await self.main_process_stop(app)
95
+
96
+ async def _before_server_start(self, app: Sanic):
97
+ """
98
+ 工作进程启动之前的内部方法。
99
+ 设置路由写在这里是因为sanic_ext是会在before_server_start阶段对路由设置_cors属性
100
+ Args:
101
+ app:
102
+
103
+ Returns:
104
+
105
+ """
106
+ logger.info(f"工作进程 {app.m.pid} 即将启动")
107
+
108
+ await self._setup_route(app)
109
+ await self.before_server_start(app)
110
+
111
+ async def _before_server_stop(self, app: Sanic):
112
+ """
113
+ 服务停止之前的内部方法
114
+ Args:
115
+ app:
116
+
117
+ Returns:
118
+
119
+ """
120
+ logger.info(f"工作进程 {app.m.pid} 即将停止")
121
+ await self.before_server_stop(app)
122
+
123
+ async def _after_server_start(self, app: Sanic):
124
+ """
125
+ 服务启动之后的内部方法
126
+ Args:
127
+ app:
128
+
129
+ Returns:
130
+
131
+ """
132
+ logger.info(f"工作进程 {app.m.pid} 启动完毕")
133
+ await self.after_server_start(app)
134
+
135
+ async def _after_server_stop(self, app: Sanic):
136
+ """
137
+ 服务停止之后的内部方法
138
+ Args:
139
+ app:
140
+
141
+ Returns:
142
+
143
+ """
144
+ logger.info(f"工作进程 {app.m.pid} 停止")
145
+ await self.after_server_stop(app)
146
+
147
+ def _setup_config(self, app: Sanic):
148
+ """
149
+ 设置配置
150
+ Args:
151
+ app: Sanic App
152
+
153
+ Returns:
154
+
155
+ """
156
+ app.config.LOGGING = True
157
+ self._setup_cors(app)
158
+
159
+ def _setup_openai(self, app: Sanic): ...
160
+
161
+ def _setup_cors(self, app: Sanic):
162
+ """
163
+ 设置跨域: 开发模式下允许所有跨域,生产模式下使用配置中的跨域列表
164
+ Args:
165
+ app: Sanic App
166
+
167
+ Returns:
168
+
169
+ """
170
+ cors = ",".join(self.settings.cors.origins)
171
+ if self.settings.mode == RunModeEnum.DEBNUG:
172
+ app.config.CORS_SEND_WILDCARD = True
173
+ app.config.CORS_SUPPORTS_CREDENTIALS = self.settings.cors.supports_credentials
174
+ app.config.CORS_ORIGINS = cors or "*"
175
+ else:
176
+ app.config.CORS_ORIGINS = cors
177
+
178
+ async def _setup_route(self, app: Sanic):
179
+ """
180
+ 设置路由和蓝图的内部方法,自动设置一个ping的路由
181
+ Args:
182
+ app: Sanic App
183
+
184
+ Returns:
185
+
186
+ """
187
+ app.add_route(self._ping, "ping", methods=["GET", "POST"])
188
+ await self.setup_route(app)
189
+
190
+ def _setup_logger(self, app: Sanic):
191
+ """
192
+ 设置日志
193
+ Args:
194
+ app: Sanic App
195
+
196
+ Returns:
197
+
198
+ """
199
+ log_config = self.settings.logger
200
+ log_ext = LoggerExtend(
201
+ app,
202
+ log_file=log_config.file,
203
+ rotation=log_config.rotation,
204
+ retention=log_config.retention,
205
+ compression=log_config.compression,
206
+ loki_url=log_config.loki_url,
207
+ loki_labels={"Application": self.name, "Envornment": self.settings.envornment},
208
+ )
209
+ Extend.register(log_ext)
210
+
211
+ def _setup_sentry(self, _app: Sanic):
212
+ """
213
+ 如果存在sentryURL配置,则自动设置sentry哨兵
214
+ Args:
215
+ _app: Sanic App
216
+
217
+ Returns:
218
+
219
+ """
220
+ if self.settings.sentry_dsn is None:
221
+ return
222
+
223
+ sentry_sdk.init(
224
+ dsn=str(self.settings.sentry_dsn),
225
+ # Set traces_sample_rate to 1.0 to capture 100%
226
+ # of transactions for tracing.
227
+ traces_sample_rate=1.0,
228
+ # Set profiles_sample_rate to 1.0 to profile 100%
229
+ # of sampled transactions.
230
+ # We recommend adjusting this value in production.
231
+ profiles_sample_rate=1.0,
232
+ integrations=[AsyncioIntegration()],
233
+ )
234
+
235
+ async def _ping(self, _request):
236
+ return text("ok")
237
+
238
+ async def main_process_start(self, app: Sanic):
239
+ """
240
+ 主进程启动的方法
241
+ Args:
242
+ app: Sanic App
243
+
244
+ Returns:
245
+
246
+ """
247
+
248
+ async def main_process_stop(self, app: Sanic):
249
+ """
250
+ 主进程停止的方法
251
+ Args:
252
+ app: Sanic App
253
+
254
+ Returns:
255
+
256
+ """
257
+
258
+ async def before_server_start(self, app: Sanic):
259
+ """
260
+ 工作进程启动之前的方法。
261
+ Args:
262
+ app: Sanic App
263
+
264
+ Returns:
265
+
266
+ """
267
+
268
+ async def before_server_stop(self, app: Sanic):
269
+ """
270
+ 工作进程停止之前的方法。
271
+ Args:
272
+ app: Sanic App
273
+
274
+ Returns:
275
+
276
+ """
277
+
278
+ async def after_server_start(self, app: Sanic):
279
+ """
280
+ 工作进程启动之后的方法。
281
+ Args:
282
+ app: Sanic App
283
+
284
+ Returns:
285
+
286
+ """
287
+
288
+ async def after_server_stop(self, app: Sanic):
289
+ """
290
+ 工作进程停止之后的方法。
291
+ Args:
292
+ app: Sanic App
293
+
294
+ Returns:
295
+
296
+ """
297
+
298
+ async def setup_route(self, app: Sanic):
299
+ """
300
+ 继承此方法去设置蓝图及路由
301
+ Args:
302
+ app: Sanic App
303
+
304
+ Returns:
305
+
306
+ """
@@ -1 +1 @@
1
- from .setting import DefaultSettings
1
+ from sanic_api.config.setting import DefaultSettings, RunModeEnum, SettingsBase
@@ -1,12 +1,57 @@
1
- from hs_config import ConfigBase
2
- from pydantic import Field
1
+ from hs_config import SettingsBase
2
+ from pydantic import BaseModel, Field, FilePath, HttpUrl, NewPath
3
3
 
4
- from sanic_api.config.sanic import SanicConfig
5
- from sanic_api.config.sanic_api import SanicApiConfig
6
- from sanic_api.enum import RunModeEnum
4
+ from sanic_api.utils.enum import EnumBase, EnumField
7
5
 
8
6
 
9
- class DefaultSettings(ConfigBase):
7
+ class RunModeEnum(EnumBase):
8
+ """
9
+ 运行模式
10
+ """
11
+
12
+ DEBNUG = EnumField("debug", desc="开发模式")
13
+ PRODUCTION = EnumField("prod", desc="生产模式")
14
+
15
+
16
+ class LoggerSettings(BaseModel):
17
+ """
18
+ 日志配置类
19
+ """
20
+
21
+ # 日志文件路径
22
+ file: FilePath | NewPath | None = Field(default=None)
23
+
24
+ # 自动轮转条件。就是保留几天的日志。
25
+ # 具体查看loguru文档:https://loguru.readthedocs.io/en/stable/api/logger.html#file
26
+ rotation: str | None = Field(default=None)
27
+
28
+ # 日志文件保留条件。就是保留多大的日志。
29
+ # 具体查看loguru文档:https://loguru.readthedocs.io/en/stable/api/logger.html#file
30
+ retention: str | None = Field(default=None)
31
+
32
+ # 日志文件的压缩格式。zip、gz、tar等。
33
+ # 体查看loguru文档:https://loguru.readthedocs.io/en/stable/api/logger.html#file
34
+ compression: str | None = Field(default=None)
35
+
36
+ # loji的地址。如果存在,则会把日志推送给logki
37
+ loki_url: HttpUrl | None = Field(default=None)
38
+
39
+
40
+ class CrosSettings(BaseModel):
41
+ """
42
+ 跨域设置
43
+ """
44
+
45
+ # 地址、地址列表、*
46
+ # 当 credentials等于 'include' 时,origins必须是具体是地址不能是 “*”
47
+ origins: list[str] | None = Field(default_factory=list)
48
+
49
+ # 支持凭证。
50
+ # 当前端启用了withCredentials 后端需要设置这个值为True
51
+ supports_credentials: bool = Field(default=False)
52
+
53
+
54
+ class DefaultSettings(SettingsBase):
10
55
  """
11
56
  配置类
12
57
  """
@@ -15,16 +60,26 @@ class DefaultSettings(ConfigBase):
15
60
  host: str = Field(default="127.0.0.1")
16
61
 
17
62
  # 端口
18
- port: int = Field(default=5798)
63
+ port: int = Field(default=6969)
19
64
 
20
65
  # 运行模式
21
- mode: RunModeEnum = Field(default=RunModeEnum.DEV)
66
+ mode: RunModeEnum = Field(default=RunModeEnum.DEBNUG)
67
+
68
+ # 运行环境,仅作为环境标识。
69
+ # 尽量不要使用这个字段去做逻辑判断。请使用mode去进行判断,因为测试环境、预发布环境、生产环境都应属于生产模式模式
70
+ envornment: str = Field(default="dev")
71
+
72
+ # 自动重载。生产模式强制关闭
73
+ auto_reload: bool = Field(default=False)
74
+
75
+ # 访问日志开关
76
+ access_log: bool = Field(default=True)
22
77
 
23
- # 工作进程的数量
24
- workers: int = Field(default=1)
78
+ # 跨域设置
79
+ cors: CrosSettings = Field(default_factory=CrosSettings)
25
80
 
26
- # sanic 自身的配置
27
- sanic: SanicConfig = Field(default_factory=SanicConfig)
81
+ # 哨兵连接dsn,如果存在则会把错误信息推送给哨兵
82
+ sentry_dsn: HttpUrl | None = Field(default=None)
28
83
 
29
- # sanic_api 扩展自身需要的配置
30
- sanic_api: SanicApiConfig = Field(default_factory=SanicApiConfig)
84
+ # 日志配置
85
+ logger: LoggerSettings = Field(default_factory=LoggerSettings)
@@ -1 +0,0 @@
1
- from .extend import LoggerExtend