update to python3.10 (#29)

This commit is contained in:
dylan
2023-05-03 17:10:55 +08:00
committed by GitHub
parent 4e6284eafe
commit 64f2a13e37
14 changed files with 46 additions and 44 deletions

View File

@ -18,10 +18,10 @@ repos:
rev: 23.3.0
hooks:
- id: black
language_version: python3.8
language_version: python3.10
args:
- '--skip-string-normalization'
- '--line-length'
- '120'
- '--target-version'
- 'py38'
- 'py310'

View File

@ -9,11 +9,14 @@ select = [
"PGH004",
"PLE1142",
"RUF100",
"I002",
"F404",
"TCH",
"UP007"
]
ignore = ["F401"]
line-length = 120
format = "grouped"
target-version = "py38"
target-version = "py310"
cache-dir = "./.ruff_cache"
[flake8-pytest-style]
@ -34,3 +37,8 @@ ignore-variadic-names = true
[isort]
lines-between-types = 1
order-by-type = true
[per-file-ignores]
"backend/app/api/v1/*.py" = ["TCH"]
"backend/app/models/*.py" = ["TCH003"]
"backend/app/**/__init__.py" = ["F401"]

View File

@ -5,6 +5,8 @@ This is a base project of the FastAPI framework.
Its purpose is to allow you to develop your project directly with it
as your base project
Support python3.10 and above
## Skill
- [x] FastAPI

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from datetime import datetime, timedelta
from typing import Any, Union
from typing import Any
from fastapi import Depends
from fastapi.security import OAuth2PasswordBearer
@ -42,7 +42,7 @@ def password_verify(plain_password: str, hashed_password: str) -> bool:
return pwd_context.verify(plain_password, hashed_password)
def create_access_token(data: Union[int, Any], expires_delta: Union[timedelta, None] = None) -> str:
def create_access_token(data: int | Any, expires_delta: timedelta | None = None) -> str:
"""
Generate encryption token

View File

@ -3,7 +3,7 @@
from __future__ import annotations
import math
from typing import TypeVar, Generic, Sequence, Dict, Union
from typing import TypeVar, Generic, Sequence, Dict
from fastapi import Query
from fastapi_pagination.bases import AbstractPage, AbstractParams, RawParams
@ -35,7 +35,7 @@ class Page(AbstractPage[T], Generic[T]):
page: int # 第n页
size: int # 每页数量
total_pages: int # 总页数
links: Dict[str, Union[str, None]] # 跳转链接
links: Dict[str, str | None] # 跳转链接
__params_type__ = Params # 使用自定义的Params

View File

@ -1,12 +1,12 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from datetime import datetime
from typing import Optional, Any, Union, Set, Dict
from typing import Any, Union, Set, Dict
from fastapi.encoders import jsonable_encoder
from pydantic import validate_arguments, BaseModel
_JsonEncoder = Union[Set[Union[int, str]], Dict[Union[int, str], Any]]
_JsonEncoder = Union[Set[int | str], Dict[int | str, Any]]
__all__ = ['ResponseModel', 'response_base']
@ -18,7 +18,7 @@ class ResponseModel(BaseModel):
code: int = 200
msg: str = 'Success'
data: Optional[Any] = None
data: Any | None = None
class Config:
json_encoders = {datetime: lambda x: x.strftime('%Y-%m-%d %H:%M:%S')}
@ -31,9 +31,7 @@ class ResponseBase:
@staticmethod
@validate_arguments
def success(
*, code: int = 200, msg: str = 'Success', data: Optional[Any] = None, exclude: Optional[_JsonEncoder] = None
):
def success(*, code: int = 200, msg: str = 'Success', data: Any | None = None, exclude: _JsonEncoder | None = None):
"""
请求成功返回通用方法
@ -48,13 +46,13 @@ class ResponseBase:
@staticmethod
@validate_arguments
def fail(*, code: int = 400, msg: str = 'Bad Request', data: Any = None, exclude: Optional[_JsonEncoder] = None):
def fail(*, code: int = 400, msg: str = 'Bad Request', data: Any = None, exclude: _JsonEncoder | None = None):
data = data if data is None else ResponseBase.__encode_json(data)
return ResponseModel(code=code, msg=msg, data=data).dict(exclude={'data': exclude})
@staticmethod
@validate_arguments
def response_200(*, msg: str = 'Success', data: Optional[Any] = None, exclude: Optional[_JsonEncoder] = None):
def response_200(*, msg: str = 'Success', data: Any | None = None, exclude: _JsonEncoder | None = None):
data = data if data is None else ResponseBase.__encode_json(data)
return ResponseModel(code=200, msg=msg, data=data).dict(exclude={'data': exclude})

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from functools import lru_cache
from typing import Optional
from pydantic import BaseSettings, root_validator
@ -35,9 +34,9 @@ class Settings(BaseSettings):
TITLE: str = 'FastAPI'
VERSION: str = '0.0.1'
DESCRIPTION: str = 'FastAPI Best Architecture'
DOCS_URL: Optional[str] = '/v1/docs'
REDOCS_URL: Optional[str] = '/v1/redocs'
OPENAPI_URL: Optional[str] = '/v1/openapi'
DOCS_URL: str | None = '/v1/docs'
REDOCS_URL: str | None = '/v1/redocs'
OPENAPI_URL: str | None = '/v1/openapi'
@root_validator
def validator_api_url(cls, values):

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Any, Dict, Generic, Type, TypeVar, Union, Optional, NoReturn
from typing import Any, Dict, Generic, Type, TypeVar, NoReturn
from pydantic import BaseModel
from sqlalchemy import select, update, delete
@ -17,7 +17,7 @@ class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
def __init__(self, model: Type[ModelType]):
self.model = model
async def get(self, db: AsyncSession, pk: int) -> Optional[ModelType]:
async def get(self, db: AsyncSession, pk: int) -> ModelType | None:
"""
通过主键 id 获取一条数据
@ -28,7 +28,7 @@ class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
model = await db.execute(select(self.model).where(self.model.id == pk))
return model.scalars().first()
async def create(self, db: AsyncSession, obj_in: CreateSchemaType, user_id: Optional[int] = None) -> NoReturn:
async def create(self, db: AsyncSession, obj_in: CreateSchemaType, user_id: int | None = None) -> NoReturn:
"""
新增一条数据
@ -44,7 +44,7 @@ class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
db.add(db_obj)
async def update(
self, db: AsyncSession, pk: int, obj_in: Union[UpdateSchemaType, Dict[str, Any]], user_id: Optional[int] = None
self, db: AsyncSession, pk: int, obj_in: UpdateSchemaType | Dict[str, Any], user_id: int | None = None
) -> int:
"""
通过主键 id 更新一条数据

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Optional, NoReturn
from typing import NoReturn
from sqlalchemy import func, select, update, desc
from sqlalchemy.ext.asyncio import AsyncSession
@ -13,10 +13,10 @@ from backend.app.schemas.user import CreateUser, UpdateUser, Avatar
class CRUDUser(CRUDBase[User, CreateUser, UpdateUser]):
async def get_user_by_id(self, db: AsyncSession, user_id: int) -> Optional[User]:
async def get_user_by_id(self, db: AsyncSession, user_id: int) -> User | None:
return await self.get(db, user_id)
async def get_user_by_username(self, db: AsyncSession, username: str) -> Optional[User]:
async def get_user_by_username(self, db: AsyncSession, username: str) -> User | None:
user = await db.execute(select(self.model).where(self.model.username == username))
return user.scalars().first()

View File

@ -2,7 +2,6 @@
# -*- coding: utf-8 -*-
import uuid
from datetime import datetime
from typing import Optional
from sqlalchemy import func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, declared_attr, MappedAsDataclass
@ -24,9 +23,9 @@ class _BaseMixin(MappedAsDataclass):
"""
create_user: Mapped[int] = mapped_column(sort_order=9999, comment='创建者')
update_user: Mapped[Optional[int]] = mapped_column(init=False, default=None, sort_order=9999, comment='修改者')
update_user: Mapped[int | None] = mapped_column(init=False, default=None, sort_order=9999, comment='修改者')
created_time: Mapped[datetime] = mapped_column(init=False, default=func.now(), sort_order=9999, comment='创建时间')
updated_time: Mapped[Optional[datetime]] = mapped_column(
updated_time: Mapped[datetime | None] = mapped_column(
init=False, onupdate=func.now(), sort_order=9999, comment='更新时间'
)

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from datetime import datetime
from typing import Optional
from sqlalchemy import func, String
from sqlalchemy.orm import Mapped, mapped_column
@ -21,7 +20,7 @@ class User(DataClassBase):
email: Mapped[str] = mapped_column(String(50), unique=True, index=True, comment='邮箱')
is_superuser: Mapped[bool] = mapped_column(default=False, comment='超级权限')
is_active: Mapped[bool] = mapped_column(default=True, comment='用户账号状态')
avatar: Mapped[Optional[str]] = mapped_column(String(255), default=None, comment='头像')
mobile_number: Mapped[Optional[str]] = mapped_column(String(11), default=None, comment='手机号')
avatar: Mapped[str | None] = mapped_column(String(255), default=None, comment='头像')
mobile_number: Mapped[str | None] = mapped_column(String(11), default=None, comment='手机号')
time_joined: Mapped[datetime] = mapped_column(init=False, default=func.now(), comment='注册时间')
last_login: Mapped[Optional[datetime]] = mapped_column(init=False, onupdate=func.now(), comment='上次登录')
last_login: Mapped[datetime | None] = mapped_column(init=False, onupdate=func.now(), comment='上次登录')

View File

@ -1,6 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Optional
from pydantic import BaseModel
@ -10,4 +9,4 @@ class Token(BaseModel):
msg: str = 'Success'
access_token: str
token_type: str = 'Bearer'
is_superuser: Optional[bool] = None
is_superuser: bool | None = None

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import datetime
from typing import Optional
from pydantic import BaseModel, Field, HttpUrl
@ -18,7 +17,7 @@ class CreateUser(Auth):
class UpdateUser(BaseModel):
username: str
email: str
mobile_number: Optional[str] = None
mobile_number: str | None = None
class Avatar(BaseModel):
@ -28,9 +27,9 @@ class Avatar(BaseModel):
class GetUserInfo(UpdateUser):
id: int
uid: str
avatar: Optional[str] = None
avatar: str | None = None
time_joined: datetime.datetime = None
last_login: Optional[datetime.datetime] = None
last_login: datetime.datetime | None = None
is_superuser: bool
is_active: bool

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from functools import lru_cache
from typing import Optional
from pydantic import BaseSettings
@ -11,9 +10,9 @@ class Settings(BaseSettings):
TITLE: str = 'FastAPI'
VERSION: str = 'v0.0.1'
DESCRIPTION: str = 'FastAPI Best Architecture'
DOCS_URL: Optional[str] = '/v1/docs'
REDOCS_URL: Optional[str] = None
OPENAPI_URL: Optional[str] = '/v1/openapi'
DOCS_URL: str | None = '/v1/docs'
REDOCS_URL: str | None = None
OPENAPI_URL: str | None = '/v1/openapi'
# Static Server
STATIC_FILES: bool = False