Skip to content

Commit b9e4ac3

Browse files
authored
Add environment variable management and fix Pydantic validation error (#15)
* Use env to manage important configurations and distinguish environments * fix Pydantic validation error caused by None value in links field of Page class * Production environment no longer exposes API docs * Extract TOKEN_URL to conf
1 parent 8dc6081 commit b9e4ac3

File tree

5 files changed

+52
-20
lines changed

5 files changed

+52
-20
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ git clone https://github.com/wu-clan/fastapi_best_architecture.git
3333

3434
2. Create a database `fba`, choose utf8mb4 encode
3535
3. Install and start Redis
36-
4. View `backend/app/core/conf.py`, update database configuration information
36+
4. Copy .env.example to .env and view `backend/app/core/conf.py`, update database configuration information
3737
5. Perform a database migration [alembic](https://alembic.sqlalchemy.org/en/latest/tutorial.html)
3838
```shell
3939
cd backend/app/

backend/app/.env.example

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# env: test、dev、pro
2+
ENVIRONMENT='pro'
3+
# mysql
4+
DB_HOST='127.0.0.1'
5+
DB_PORT=3306
6+
DB_USER='root'
7+
DB_PASSWORD=''
8+
# redis
9+
REDIS_HOST='127.0.0.1'
10+
REDIS_PORT=6379
11+
REDIS_PASSWORD=''
12+
REDIS_DATABASE=0
13+
# APScheduler
14+
APS_REDIS_HOST='127.0.0.1'
15+
APS_REDIS_PORT=6379
16+
APS_REDIS_PASSWORD=''
17+
# token
18+
TOKEN_SECRET_KEY='1VkVF75nsNABBjK_7-qz7GtzNy3AMvktc9TCPwKczCk'
19+
# email
20+
EMAIL_USER='[email protected]'
21+
EMAIL_PASSWORD=''

backend/app/api/jwt.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
pwd_context = CryptContext(schemes=['bcrypt'], deprecated='auto')
2020

21-
oauth2_schema = OAuth2PasswordBearer(tokenUrl='/v1/users/login')
21+
oauth2_schema = OAuth2PasswordBearer(tokenUrl=settings.TOKEN_URL)
2222

2323

2424
def get_hash_password(password: str) -> str:

backend/app/common/pagination.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from __future__ import annotations
44

55
import math
6-
from typing import TypeVar, Generic, Sequence, Dict
6+
from typing import TypeVar, Generic, Sequence, Dict, Union
77

88
from fastapi import Query
99
from fastapi_pagination.bases import AbstractPage, AbstractParams, RawParams
@@ -35,7 +35,7 @@ class Page(AbstractPage[T], Generic[T]):
3535
page: int # 第n页
3636
size: int # 每页数量
3737
total_pages: int # 总页数
38-
links: Dict[str, str] # 跳转链接
38+
links: Dict[str, Union[str, None]] # 跳转链接
3939

4040
__params_type__ = Params # 使用自定义的Params
4141

backend/app/core/conf.py

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,25 @@
33
from functools import lru_cache
44
from typing import Optional
55

6-
from pydantic import BaseSettings
6+
from pydantic import BaseSettings, root_validator
77

88

99
class Settings(BaseSettings):
10+
ENVIRONMENT: str
1011
# FastAPI
1112
TITLE: str = 'FastAPI'
1213
VERSION: str = 'v0.0.1'
1314
DESCRIPTION: str = "FastAPI Best Architecture"
1415
DOCS_URL: Optional[str] = '/v1/docs'
15-
REDOCS_URL: Optional[str] = None
16+
REDOCS_URL: Optional[str] = '/v1/redocs'
1617
OPENAPI_URL: Optional[str] = '/v1/openapi'
1718

19+
@root_validator
20+
def validator_api_url(cls, values):
21+
if values['ENVIRONMENT'] == 'pro':
22+
values['OPENAPI_URL'] = None
23+
return values
24+
1825
# Uvicorn
1926
UVICORN_HOST: str = '127.0.0.1'
2027
UVICORN_PORT: int = 8000
@@ -25,24 +32,24 @@ class Settings(BaseSettings):
2532

2633
# MySQL
2734
DB_ECHO: bool = False
28-
DB_HOST: str = '127.0.0.1'
29-
DB_PORT: int = 3306
30-
DB_USER: str = 'root'
31-
DB_PASSWORD: str = '123456'
35+
DB_HOST: str
36+
DB_PORT: int
37+
DB_USER: str
38+
DB_PASSWORD: str
3239
DB_DATABASE: str = 'fba'
3340
DB_CHARSET: str = 'utf8mb4'
3441

3542
# Redis
36-
REDIS_HOST: str = '127.0.0.1'
37-
REDIS_PORT: int = 6379
38-
REDIS_PASSWORD: str = ''
39-
REDIS_DATABASE: int = 0
43+
REDIS_HOST: str
44+
REDIS_PORT: int
45+
REDIS_PASSWORD: str
46+
REDIS_DATABASE: int
4047
REDIS_TIMEOUT: int = 5
4148

4249
# APScheduler DB
43-
APS_REDIS_HOST: str = '127.0.0.1'
44-
APS_REDIS_PORT: int = 6379
45-
APS_REDIS_PASSWORD: str = ''
50+
APS_REDIS_HOST: str
51+
APS_REDIS_PORT: int
52+
APS_REDIS_PASSWORD: str
4653
APS_REDIS_DATABASE: int = 1
4754
APS_REDIS_TIMEOUT: int = 10
4855

@@ -53,15 +60,16 @@ class Settings(BaseSettings):
5360

5461
# Token
5562
TOKEN_ALGORITHM: str = 'HS256' # 算法
56-
TOKEN_SECRET_KEY: str = '1VkVF75nsNABBjK_7-qz7GtzNy3AMvktc9TCPwKczCk' # 密钥 secrets.token_urlsafe(32))
63+
TOKEN_SECRET_KEY: str # 密钥 secrets.token_urlsafe(32))
5764
TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 1 # token 时效 60 * 24 * 1 = 1 天
65+
TOKEN_URL: str = '/v1/users/login'
5866

5967
# Email
6068
EMAIL_DESCRIPTION: str = 'fastapi_sqlalchemy_mysql' # 默认发件说明
6169
EMAIL_SERVER: str = 'smtp.qq.com'
6270
EMAIL_PORT: int = 465
63-
EMAIL_USER: str = '[email protected]'
64-
EMAIL_PASSWORD: str = '' # 授权密码,非邮箱密码
71+
EMAIL_USER: str
72+
EMAIL_PASSWORD: str # 授权密码,非邮箱密码
6573
EMAIL_SSL: bool = True # 是否使用ssl
6674

6775
# 邮箱登录验证码过期时间
@@ -75,6 +83,9 @@ class Settings(BaseSettings):
7583
MIDDLEWARE_GZIP: bool = True
7684
MIDDLEWARE_ACCESS: bool = False
7785

86+
class Config:
87+
env_file = '.env'
88+
7889

7990
@lru_cache
8091
def get_settings():

0 commit comments

Comments
 (0)