6
6
from pydantic import model_validator
7
7
from pydantic_settings import BaseSettings , SettingsConfigDict
8
8
9
- from backend .core .path_conf import BasePath
9
+ from backend .core .path_conf import BASE_PATH
10
10
11
11
12
12
class Settings (BaseSettings ):
13
- """Global Settings """
13
+ """全局配置 """
14
14
15
- model_config = SettingsConfigDict (env_file = f'{ BasePath } /.env' , env_file_encoding = 'utf-8' , extra = 'ignore' )
15
+ model_config = SettingsConfigDict (
16
+ env_file = f'{ BASE_PATH } /.env' , env_file_encoding = 'utf-8' , extra = 'ignore' , case_sensitive = True
17
+ )
16
18
17
- # Env Config
19
+ # 环境配置(从环境变量读取)
18
20
ENVIRONMENT : Literal ['dev' , 'pro' ]
19
21
20
- # Env Database Type
22
+ # 数据库配置(从环境变量读取)
21
23
DATABASE_TYPE : Literal ['mysql' , 'postgresql' ]
22
-
23
- # Env Database
24
24
DATABASE_HOST : str
25
25
DATABASE_PORT : int
26
26
DATABASE_USER : str
27
27
DATABASE_PASSWORD : str
28
28
29
- # Env Redis
29
+ # Redis 配置(从环境变量读取)
30
30
REDIS_HOST : str
31
31
REDIS_PORT : int
32
32
REDIS_PASSWORD : str
33
33
REDIS_DATABASE : int
34
34
35
- # Env Token
35
+ # Token 配置(从环境变量读取)
36
36
TOKEN_SECRET_KEY : str # 密钥 secrets.token_urlsafe(32)
37
37
38
- # Env Opera Log
38
+ # 操作日志加密密钥(从环境变量读取)
39
39
OPERA_LOG_ENCRYPT_SECRET_KEY : str # 密钥 os.urandom(32), 需使用 bytes.hex() 方法转换为 str
40
40
41
- # FastAPI
42
- FASTAPI_API_V1_PATH : str = '/api/v1'
43
- FASTAPI_TITLE : str = 'FastAPI'
44
- FASTAPI_VERSION : str = '0.0.1'
45
- FASTAPI_DESCRIPTION : str = 'FastAPI Best Architecture'
46
- FASTAPI_DOCS_URL : str = '/docs'
47
- FASTAPI_REDOC_URL : str = '/redoc'
48
- FASTAPI_OPENAPI_URL : str | None = '/openapi'
49
- FASTAPI_STATIC_FILES : bool = True
50
-
51
- # Upload
52
- UPLOAD_READ_SIZE : int = 1024 # 上传文件时分片读取大小
53
- UPLOAD_IMAGE_EXT_INCLUDE : list [str ] = ['jpg' , 'jpeg' , 'png' , 'gif' , 'webp' ]
54
- UPLOAD_IMAGE_SIZE_MAX : int = 1024 * 1024 * 5
55
- UPLOAD_VIDEO_EXT_INCLUDE : list [str ] = ['mp4' , 'mov' , 'avi' , 'flv' ]
56
- UPLOAD_VIDEO_SIZE_MAX : int = 1024 * 1024 * 20
57
-
58
- # Database
41
+ # 数据库配置(默认值)
59
42
DATABASE_ECHO : bool = False
60
43
DATABASE_POOL_ECHO : bool = False
61
44
DATABASE_SCHEMA : str = 'fba'
62
45
DATABASE_CHARSET : str = 'utf8mb4'
63
46
64
- # Redis
47
+ # Redis 配置(默认值)
65
48
REDIS_TIMEOUT : int = 5
66
49
67
- # Socketio
68
- WS_NO_AUTH_MARKER : str = 'internal'
69
-
70
- # Token
71
- TOKEN_ALGORITHM : str = 'HS256' # 算法
72
- TOKEN_EXPIRE_SECONDS : int = 60 * 60 * 24 * 1 # 过期时间,单位:秒
73
- TOKEN_REFRESH_EXPIRE_SECONDS : int = 60 * 60 * 24 * 7 # refresh token 过期时间,单位:秒
50
+ # Token 配置(默认值)
51
+ TOKEN_ALGORITHM : str = 'HS256'
52
+ TOKEN_EXPIRE_SECONDS : int = 60 * 60 * 24 # 1 天
53
+ TOKEN_REFRESH_EXPIRE_SECONDS : int = 60 * 60 * 24 * 7 # 7 天
74
54
TOKEN_REDIS_PREFIX : str = 'fba:token'
75
55
TOKEN_EXTRA_INFO_REDIS_PREFIX : str = 'fba:token_extra_info'
76
56
TOKEN_ONLINE_REDIS_PREFIX : str = 'fba:token_online'
77
57
TOKEN_REFRESH_REDIS_PREFIX : str = 'fba:refresh_token'
78
- TOKEN_REQUEST_PATH_EXCLUDE : list [str ] = [ # JWT / RBAC 白名单
79
- f' { FASTAPI_API_V1_PATH } /auth/login' ,
58
+ TOKEN_REQUEST_PATH_EXCLUDE : list [str ] = [ # JWT / RBAC 路由白名单
59
+ '/api/v1 /auth/login' ,
80
60
]
81
61
82
- # JWT
62
+ # JWT 配置(默认值)
83
63
JWT_USER_REDIS_PREFIX : str = 'fba:user'
84
- JWT_USER_REDIS_EXPIRE_SECONDS : int = 60 * 60 * 24 * 7
64
+ JWT_USER_REDIS_EXPIRE_SECONDS : int = 60 * 60 * 24 * 7 # 7 天
85
65
86
- # RBAC
66
+ # RBAC 配置(默认值)
87
67
RBAC_ROLE_MENU_MODE : bool = False
88
68
RBAC_ROLE_MENU_EXCLUDE : list [str ] = [
89
69
'sys:monitor:redis' ,
90
70
'sys:monitor:server' ,
91
71
]
92
72
93
- # Cookies
73
+ # Cookie 配置(默认值)
94
74
COOKIE_REFRESH_TOKEN_KEY : str = 'fba_refresh_token'
95
- COOKIE_REFRESH_TOKEN_EXPIRE_SECONDS : int = TOKEN_REFRESH_EXPIRE_SECONDS
75
+ COOKIE_REFRESH_TOKEN_EXPIRE_SECONDS : int = 60 * 60 * 24 * 7 # 7 天
76
+
77
+ # FastAPI 配置(默认值)
78
+ FASTAPI_API_V1_PATH : str = '/api/v1'
79
+ FASTAPI_TITLE : str = 'FastAPI'
80
+ FASTAPI_VERSION : str = '0.0.1'
81
+ FASTAPI_DESCRIPTION : str = 'FastAPI Best Architecture'
82
+ FASTAPI_DOCS_URL : str = '/docs'
83
+ FASTAPI_REDOC_URL : str = '/redoc'
84
+ FASTAPI_OPENAPI_URL : str | None = '/openapi'
85
+ FASTAPI_STATIC_FILES : bool = True
86
+
87
+ # Socketio 配置(默认值)
88
+ WS_NO_AUTH_MARKER : str = 'internal'
89
+
90
+ # 文件上传配置(默认值)
91
+ UPLOAD_READ_SIZE : int = 1024
92
+ UPLOAD_IMAGE_EXT_INCLUDE : list [str ] = ['jpg' , 'jpeg' , 'png' , 'gif' , 'webp' ]
93
+ UPLOAD_IMAGE_SIZE_MAX : int = 5 * 1024 * 1024 # 5 MB
94
+ UPLOAD_VIDEO_EXT_INCLUDE : list [str ] = ['mp4' , 'mov' , 'avi' , 'flv' ]
95
+ UPLOAD_VIDEO_SIZE_MAX : int = 20 * 1024 * 1024 # 20 MB
96
96
97
- # Log
97
+ # 日志配置(默认值)
98
98
LOG_CID_DEFAULT_VALUE : str = '-'
99
- LOG_CID_UUID_LENGTH : int = 32 # must <= 32
99
+ LOG_CID_UUID_LENGTH : int = 32 # 日志 correlation_id 长度,必须小于等于 32
100
100
LOG_STD_LEVEL : str = 'INFO'
101
101
LOG_ACCESS_FILE_LEVEL : str = 'INFO'
102
102
LOG_ERROR_FILE_LEVEL : str = 'ERROR'
@@ -111,51 +111,51 @@ class Settings(BaseSettings):
111
111
LOG_ACCESS_FILENAME : str = 'fba_access.log'
112
112
LOG_ERROR_FILENAME : str = 'fba_error.log'
113
113
114
- # Middleware
114
+ # 中间件配置(默认值)
115
115
MIDDLEWARE_CORS : bool = True
116
116
MIDDLEWARE_ACCESS : bool = True
117
117
118
- # Trace ID
118
+ # 追踪 ID 配置(默认值)
119
119
TRACE_ID_REQUEST_HEADER_KEY : str = 'X-Request-ID'
120
120
121
- # CORS
122
- CORS_ALLOWED_ORIGINS : list [str ] = [
121
+ # CORS 配置(默认值)
122
+ CORS_ALLOWED_ORIGINS : list [str ] = [ # 末尾不带斜杠
123
123
'http://127.0.0.1:8000' ,
124
- 'http://localhost:5173' , # 前端地址,末尾不要带 '/'
124
+ 'http://localhost:5173' ,
125
125
]
126
126
CORS_EXPOSE_HEADERS : list [str ] = [
127
- TRACE_ID_REQUEST_HEADER_KEY ,
127
+ 'X-Request-ID' ,
128
128
]
129
129
130
- # DateTime
130
+ # 时间配置(默认值)
131
131
DATETIME_TIMEZONE : str = 'Asia/Shanghai'
132
132
DATETIME_FORMAT : str = '%Y-%m-%d %H:%M:%S'
133
133
134
- # Request limiter
134
+ # 请求限制配置(默认值)
135
135
REQUEST_LIMITER_REDIS_PREFIX : str = 'fba:limiter'
136
136
137
- # Demo mode (Only GET, OPTIONS requests are allowed)
137
+ # 演示模式配置(默认值)
138
138
DEMO_MODE : bool = False
139
139
DEMO_MODE_EXCLUDE : set [tuple [str , str ]] = {
140
- ('POST' , f' { FASTAPI_API_V1_PATH } /auth/login' ),
141
- ('POST' , f' { FASTAPI_API_V1_PATH } /auth/logout' ),
142
- ('GET' , f' { FASTAPI_API_V1_PATH } /auth/captcha' ),
140
+ ('POST' , '/api/v1 /auth/login' ),
141
+ ('POST' , '/api/v1 /auth/logout' ),
142
+ ('GET' , '/api/v1 /auth/captcha' ),
143
143
}
144
144
145
- # Ip location
145
+ # IP 定位配置(默认值)
146
146
IP_LOCATION_PARSE : Literal ['online' , 'offline' , 'false' ] = 'offline'
147
147
IP_LOCATION_REDIS_PREFIX : str = 'fba:ip:location'
148
- IP_LOCATION_EXPIRE_SECONDS : int = 60 * 60 * 24 * 1 # 过期时间,单位:秒
148
+ IP_LOCATION_EXPIRE_SECONDS : int = 60 * 60 * 24 # 1 天
149
149
150
- # Opera log
150
+ # 操作日志配置(默认值)
151
151
OPERA_LOG_PATH_EXCLUDE : list [str ] = [
152
152
'/favicon.ico' ,
153
- FASTAPI_DOCS_URL ,
154
- FASTAPI_REDOC_URL ,
155
- FASTAPI_OPENAPI_URL ,
156
- f' { FASTAPI_API_V1_PATH } /auth/login/swagger' ,
157
- f' { FASTAPI_API_V1_PATH } /oauth2/github/callback' ,
158
- f' { FASTAPI_API_V1_PATH } /oauth2/linux-do/callback' ,
153
+ '/docs' ,
154
+ '/redoc' ,
155
+ '/openapi' ,
156
+ '/api/v1 /auth/login/swagger' ,
157
+ '/api/v1 /oauth2/github/callback' ,
158
+ '/api/v1 /oauth2/linux-do/callback' ,
159
159
]
160
160
OPERA_LOG_ENCRYPT_TYPE : int = 1 # 0: AES (性能损耗); 1: md5; 2: ItsDangerous; 3: 不加密, others: 替换为 ******
161
161
OPERA_LOG_ENCRYPT_KEY_INCLUDE : list [str ] = [ # 将加密接口入参参数对应的值
@@ -165,10 +165,8 @@ class Settings(BaseSettings):
165
165
'confirm_password' ,
166
166
]
167
167
168
- # Data permission
169
- DATA_PERMISSION_MODELS : dict [
170
- str , str
171
- ] = { # 允许进行数据过滤的 SQLA 模型,它必须以模块字符串的方式定义(它应该只用于前台数据,这里只是为了演示)
168
+ # 数据权限配置(默认值)
169
+ DATA_PERMISSION_MODELS : dict [str , str ] = { # 允许进行数据过滤的 SQLA 模型,它必须以模块字符串的方式定义
172
170
'Api' : 'backend.plugin.casbin.model.Api' ,
173
171
}
174
172
DATA_PERMISSION_COLUMN_EXCLUDE : list [str ] = [ # 排除允许进行数据过滤的 SQLA 模型列
@@ -178,24 +176,25 @@ class Settings(BaseSettings):
178
176
'updated_time' ,
179
177
]
180
178
181
- # Plugin
179
+ # 插件配置(默认值)
182
180
PLUGIN_PIP_CHINA : bool = True
183
181
PLUGIN_PIP_INDEX_URL : str = 'https://mirrors.aliyun.com/pypi/simple/'
184
182
185
183
@model_validator (mode = 'before' )
186
184
@classmethod
187
185
def check_env (cls , values : Any ) -> Any :
188
- if values ['ENVIRONMENT' ] == 'pro' :
186
+ """生产环境下禁用 OpenAPI 文档和静态文件服务"""
187
+ if values .get ('ENVIRONMENT' ) == 'pro' :
189
188
values ['FASTAPI_OPENAPI_URL' ] = None
190
189
values ['FASTAPI_STATIC_FILES' ] = False
191
190
return values
192
191
193
192
194
193
@lru_cache
195
194
def get_settings () -> Settings :
196
- """获取全局配置 """
195
+ """获取全局配置单例 """
197
196
return Settings ()
198
197
199
198
200
- # 创建配置实例
199
+ # 创建全局配置实例
201
200
settings = get_settings ()
0 commit comments