mirror of
https://github.com/fastapi-practices/fastapi-best-architecture.git
synced 2026-09-21 13:12:24 +00:00
update the ruff rules and format the code
This commit is contained in:
@@ -11,7 +11,7 @@ from sqlalchemy.ext.asyncio import AsyncEngine
|
||||
|
||||
sys.path.append('../../')
|
||||
|
||||
from backend.app.core import path_conf # noqa
|
||||
from backend.app.core import path_conf # noqa: E402
|
||||
|
||||
if not os.path.exists(path_conf.Versions):
|
||||
os.makedirs(path_conf.Versions)
|
||||
@@ -26,12 +26,12 @@ fileConfig(config.config_file_name)
|
||||
|
||||
# add your model's MetaData object here
|
||||
# for 'autogenerate' support
|
||||
from backend.app.models import MappedBase # noqa
|
||||
from backend.app.models import MappedBase # noqa: E402
|
||||
|
||||
target_metadata = MappedBase.metadata
|
||||
|
||||
# other values from the config, defined by the needs of env.py,
|
||||
from backend.app.database.db_mysql import SQLALCHEMY_DATABASE_URL # noqa
|
||||
from backend.app.database.db_mysql import SQLALCHEMY_DATABASE_URL # noqa: E402
|
||||
|
||||
config.set_main_option('sqlalchemy.url', SQLALCHEMY_DATABASE_URL)
|
||||
|
||||
@@ -48,12 +48,12 @@ def run_migrations_offline():
|
||||
script output.
|
||||
|
||||
"""
|
||||
url = config.get_main_option("sqlalchemy.url")
|
||||
url = config.get_main_option('sqlalchemy.url')
|
||||
context.configure(
|
||||
url=url,
|
||||
target_metadata=target_metadata,
|
||||
literal_binds=True,
|
||||
dialect_opts={"paramstyle": "named"},
|
||||
dialect_opts={'paramstyle': 'named'},
|
||||
)
|
||||
|
||||
with context.begin_transaction():
|
||||
@@ -77,7 +77,7 @@ async def run_migrations_online():
|
||||
connectable = AsyncEngine(
|
||||
engine_from_config(
|
||||
config.get_section(config.config_ini_section),
|
||||
prefix="sqlalchemy.",
|
||||
prefix='sqlalchemy.',
|
||||
poolclass=pool.NullPool,
|
||||
future=True,
|
||||
)
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import Any, Union
|
||||
|
||||
from fastapi import Depends
|
||||
from fastapi.security import OAuth2PasswordBearer
|
||||
from jose import jwt # noqa
|
||||
from jose import jwt
|
||||
from passlib.context import CryptContext
|
||||
from pydantic import ValidationError
|
||||
from typing_extensions import Annotated
|
||||
@@ -54,7 +54,7 @@ def create_access_token(data: Union[int, Any], expires_delta: Union[timedelta, N
|
||||
expires = datetime.utcnow() + expires_delta
|
||||
else:
|
||||
expires = datetime.utcnow() + timedelta(settings.TOKEN_EXPIRE_MINUTES)
|
||||
to_encode = {"exp": expires, "sub": str(data)}
|
||||
to_encode = {'exp': expires, 'sub': str(data)}
|
||||
encoded_jwt = jwt.encode(to_encode, settings.TOKEN_SECRET_KEY, settings.TOKEN_ALGORITHM)
|
||||
return encoded_jwt
|
||||
|
||||
|
||||
@@ -24,17 +24,17 @@ async def task_demo_get():
|
||||
for job in scheduler.get_jobs():
|
||||
tasks.append(
|
||||
{
|
||||
"id": job.id,
|
||||
"func_name": job.func_ref,
|
||||
"trigger": str(job.trigger),
|
||||
"executor": job.executor,
|
||||
'id': job.id,
|
||||
'func_name': job.func_ref,
|
||||
'trigger': str(job.trigger),
|
||||
'executor': job.executor,
|
||||
# "args": str(job.args),
|
||||
# "kwargs": job.kwargs,
|
||||
"name": job.name,
|
||||
"misfire_grace_time": job.misfire_grace_time,
|
||||
"coalesce": job.coalesce,
|
||||
"max_instances": job.max_instances,
|
||||
"next_run_time": job.next_run_time,
|
||||
'name': job.name,
|
||||
'misfire_grace_time': job.misfire_grace_time,
|
||||
'coalesce': job.coalesce,
|
||||
'max_instances': job.max_instances,
|
||||
'next_run_time': job.next_run_time,
|
||||
}
|
||||
)
|
||||
return {'msg': 'success', 'data': tasks}
|
||||
|
||||
@@ -27,7 +27,7 @@ def _get_exception_code(status_code):
|
||||
"""
|
||||
try:
|
||||
STATUS_PHRASES[status_code]
|
||||
except Exception: # noqa
|
||||
except Exception:
|
||||
code = 400
|
||||
else:
|
||||
code = status_code
|
||||
@@ -36,7 +36,7 @@ def _get_exception_code(status_code):
|
||||
|
||||
def register_exception(app: FastAPI):
|
||||
@app.exception_handler(HTTPException)
|
||||
def http_exception_handler(request: Request, exc: HTTPException): # noqa
|
||||
def http_exception_handler(request: Request, exc: HTTPException):
|
||||
"""
|
||||
全局HTTP异常处理
|
||||
|
||||
@@ -51,7 +51,7 @@ def register_exception(app: FastAPI):
|
||||
)
|
||||
|
||||
@app.exception_handler(Exception)
|
||||
def all_exception_handler(request: Request, exc): # noqa
|
||||
def all_exception_handler(request: Request, exc):
|
||||
"""
|
||||
全局异常处理
|
||||
|
||||
|
||||
@@ -17,16 +17,16 @@ class Logger:
|
||||
os.mkdir(path_conf.LogPath)
|
||||
|
||||
# 日志文件
|
||||
log_file = os.path.join(path_conf.LogPath, "FastBlog.log")
|
||||
log_file = os.path.join(path_conf.LogPath, 'FastBlog.log')
|
||||
|
||||
# loguru日志
|
||||
# more: https://github.com/Delgan/loguru#ready-to-use-out-of-the-box-without-boilerplate
|
||||
logger.add(
|
||||
log_file,
|
||||
encoding='utf-8',
|
||||
level="DEBUG",
|
||||
level='DEBUG',
|
||||
rotation='00:00', # 每天 0 点创建一个新日志文件
|
||||
retention="7 days", # 定时自动清理文件
|
||||
retention='7 days', # 定时自动清理文件
|
||||
enqueue=True, # 异步安全
|
||||
backtrace=True, # 错误跟踪
|
||||
diagnose=True,
|
||||
|
||||
@@ -10,7 +10,7 @@ from fastapi_pagination.bases import AbstractPage, AbstractParams, RawParams
|
||||
from fastapi_pagination.links.bases import create_links
|
||||
from pydantic import BaseModel
|
||||
|
||||
T = TypeVar("T")
|
||||
T = TypeVar('T')
|
||||
|
||||
"""
|
||||
重写分页库:fastapi-pagination
|
||||
@@ -19,8 +19,8 @@ T = TypeVar("T")
|
||||
|
||||
|
||||
class Params(BaseModel, AbstractParams):
|
||||
page: int = Query(1, ge=1, description="Page number")
|
||||
size: int = Query(20, gt=0, le=100, description="Page size") # 默认 20 条记录
|
||||
page: int = Query(1, ge=1, description='Page number')
|
||||
size: int = Query(20, gt=0, le=100, description='Page size') # 默认 20 条记录
|
||||
|
||||
def to_raw_params(self) -> RawParams:
|
||||
return RawParams(
|
||||
@@ -51,10 +51,10 @@ class Page(AbstractPage[T], Generic[T]):
|
||||
total_pages = math.ceil(total / params.size)
|
||||
links = create_links(
|
||||
**{
|
||||
"first": {"page": 1, "size": f"{size}"},
|
||||
"last": {"page": f"{math.ceil(total / params.size)}", "size": f"{size}"} if total > 0 else None,
|
||||
"next": {"page": f"{page + 1}", "size": f"{size}"} if (page + 1) <= total_pages else None,
|
||||
"prev": {"page": f"{page - 1}", "size": f"{size}"} if (page - 1) >= 1 else None,
|
||||
'first': {'page': 1, 'size': f'{size}'},
|
||||
'last': {'page': f'{math.ceil(total / params.size)}', 'size': f'{size}'} if total > 0 else None,
|
||||
'next': {'page': f'{page + 1}', 'size': f'{size}'} if (page + 1) <= total_pages else None,
|
||||
'prev': {'page': f'{page - 1}', 'size': f'{size}'} if (page - 1) >= 1 else None,
|
||||
}
|
||||
).dict()
|
||||
|
||||
|
||||
@@ -28,10 +28,10 @@ class RedisCli(Redis):
|
||||
try:
|
||||
await self.ping()
|
||||
except TimeoutError:
|
||||
log.error("❌ 数据库 redis 连接超时")
|
||||
log.error('❌ 数据库 redis 连接超时')
|
||||
sys.exit()
|
||||
except AuthenticationError:
|
||||
log.error("❌ 数据库 redis 连接认证失败")
|
||||
log.error('❌ 数据库 redis 连接认证失败')
|
||||
sys.exit()
|
||||
except Exception as e:
|
||||
log.error('❌ 数据库 redis 连接异常 {}', e)
|
||||
|
||||
@@ -21,13 +21,13 @@ class ResponseModel(BaseModel):
|
||||
data: Optional[Any] = None
|
||||
|
||||
class Config:
|
||||
json_encoders = {datetime: lambda x: x.strftime("%Y-%m-%d %H:%M:%S")}
|
||||
json_encoders = {datetime: lambda x: x.strftime('%Y-%m-%d %H:%M:%S')}
|
||||
|
||||
|
||||
class ResponseBase:
|
||||
@staticmethod
|
||||
def __encode_json(data: Any):
|
||||
return jsonable_encoder(data, custom_encoder={datetime: lambda x: x.strftime("%Y-%m-%d %H:%M:%S")})
|
||||
return jsonable_encoder(data, custom_encoder={datetime: lambda x: x.strftime('%Y-%m-%d %H:%M:%S')})
|
||||
|
||||
@staticmethod
|
||||
@validate_arguments
|
||||
|
||||
@@ -25,19 +25,19 @@ def _scheduler_conf() -> dict:
|
||||
|
||||
end_conf = {
|
||||
# 配置存储器
|
||||
"jobstores": {'default': RedisJobStore(**redis_conf)},
|
||||
'jobstores': {'default': RedisJobStore(**redis_conf)},
|
||||
# 配置执行器
|
||||
"executors": {
|
||||
'executors': {
|
||||
'default': AsyncIOExecutor(),
|
||||
},
|
||||
# 创建task时的默认参数
|
||||
"job_defaults": {
|
||||
'job_defaults': {
|
||||
'coalesce': settings.APS_COALESCE,
|
||||
'max_instances': settings.APS_MAX_INSTANCES,
|
||||
"misfire_grace_time": settings.APS_MISFIRE_GRACE_TIME,
|
||||
'misfire_grace_time': settings.APS_MISFIRE_GRACE_TIME,
|
||||
},
|
||||
# 时区
|
||||
"timezone": str(tzlocal.get_localzone()),
|
||||
'timezone': str(tzlocal.get_localzone()),
|
||||
}
|
||||
|
||||
return end_conf
|
||||
|
||||
@@ -38,7 +38,7 @@ class Settings(BaseSettings):
|
||||
# FastAPI
|
||||
TITLE: str = 'FastAPI'
|
||||
VERSION: str = '0.0.1'
|
||||
DESCRIPTION: str = "FastAPI Best Architecture"
|
||||
DESCRIPTION: str = 'FastAPI Best Architecture'
|
||||
DOCS_URL: Optional[str] = '/v1/docs'
|
||||
REDOCS_URL: Optional[str] = '/v1/redocs'
|
||||
OPENAPI_URL: Optional[str] = '/v1/openapi'
|
||||
|
||||
@@ -79,9 +79,9 @@ def register_static_file(app: FastAPI):
|
||||
import os
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
if not os.path.exists("./static"):
|
||||
os.mkdir("./static")
|
||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||
if not os.path.exists('./static'):
|
||||
os.mkdir('./static')
|
||||
app.mount('/static', StaticFiles(directory='static'), name='static')
|
||||
|
||||
|
||||
def register_middleware(app: FastAPI):
|
||||
@@ -89,10 +89,10 @@ def register_middleware(app: FastAPI):
|
||||
if settings.MIDDLEWARE_CORS:
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=["*"],
|
||||
allow_origins=['*'],
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
allow_methods=['*'],
|
||||
allow_headers=['*'],
|
||||
)
|
||||
# Gzip
|
||||
if settings.MIDDLEWARE_GZIP:
|
||||
|
||||
@@ -8,9 +8,9 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from backend.app.database.base_class import MappedBase
|
||||
|
||||
ModelType = TypeVar("ModelType", bound=MappedBase)
|
||||
CreateSchemaType = TypeVar("CreateSchemaType", bound=BaseModel)
|
||||
UpdateSchemaType = TypeVar("UpdateSchemaType", bound=BaseModel)
|
||||
ModelType = TypeVar('ModelType', bound=MappedBase)
|
||||
CreateSchemaType = TypeVar('CreateSchemaType', bound=BaseModel)
|
||||
UpdateSchemaType = TypeVar('UpdateSchemaType', bound=BaseModel)
|
||||
|
||||
|
||||
class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
|
||||
|
||||
@@ -40,7 +40,7 @@ class MappedBase(DeclarativeBase):
|
||||
"""
|
||||
|
||||
@declared_attr.directive
|
||||
def __tablename__(cls) -> str: # noqa
|
||||
def __tablename__(cls) -> str:
|
||||
return cls.__name__.lower()
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ class InitData:
|
||||
)
|
||||
async with async_db_session.begin() as db:
|
||||
db.add(user_obj)
|
||||
log.info(f"普通用户创建成功,账号:{username},密码:{password}")
|
||||
log.info(f'普通用户创建成功,账号:{username},密码:{password}')
|
||||
|
||||
async def fake_no_active_user(self):
|
||||
"""自动创建锁定普通用户"""
|
||||
@@ -72,7 +72,7 @@ class InitData:
|
||||
)
|
||||
async with async_db_session.begin() as db:
|
||||
db.add(user_obj)
|
||||
log.info(f"普通锁定用户创建成功,账号:{username},密码:{password}")
|
||||
log.info(f'普通锁定用户创建成功,账号:{username},密码:{password}')
|
||||
|
||||
async def fake_superuser(self):
|
||||
"""自动创建管理员用户"""
|
||||
@@ -87,7 +87,7 @@ class InitData:
|
||||
)
|
||||
async with async_db_session.begin() as db:
|
||||
db.add(user_obj)
|
||||
log.info(f"管理员用户创建成功,账号:{username},密码:{password}")
|
||||
log.info(f'管理员用户创建成功,账号:{username},密码:{password}')
|
||||
|
||||
async def fake_no_active_superuser(self):
|
||||
"""自动创建锁定管理员用户"""
|
||||
@@ -103,7 +103,7 @@ class InitData:
|
||||
)
|
||||
async with async_db_session.begin() as db:
|
||||
db.add(user_obj)
|
||||
log.info(f"管理员锁定用户创建成功,账号:{username},密码:{password}")
|
||||
log.info(f'管理员锁定用户创建成功,账号:{username},密码:{password}')
|
||||
|
||||
async def init_data(self):
|
||||
"""自动创建数据"""
|
||||
|
||||
@@ -17,5 +17,5 @@ class AccessMiddleware(BaseHTTPMiddleware):
|
||||
start_time = datetime.now()
|
||||
response = await call_next(request)
|
||||
end_time = datetime.now()
|
||||
log.info(f"{response.status_code} {request.client.host} {request.method} {request.url} {end_time - start_time}")
|
||||
log.info(f'{response.status_code} {request.client.host} {request.method} {request.url} {end_time - start_time}')
|
||||
return response
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
# 导入所有模型,并将 Base 放在最前面, 以便 Base 拥有它们
|
||||
# imported by Alembic
|
||||
"""
|
||||
from backend.app.database.base_class import MappedBase # noqa
|
||||
from backend.app.database.base_class import MappedBase
|
||||
from backend.app.models.user import User
|
||||
|
||||
@@ -40,4 +40,4 @@ def is_mobile(text: str) -> bool:
|
||||
:param text:
|
||||
:return:
|
||||
"""
|
||||
return match_string(r"^1[3-9]\d{9}$", text)
|
||||
return match_string(r'^1[3-9]\d{9}$', text)
|
||||
|
||||
Reference in New Issue
Block a user