Skip to content

Код ревью - #1

Open
samsonovroma2011-cmd wants to merge 1 commit into
mainfrom
review
Open

samsonovroma2011-cmd wants to merge 1 commit into
mainfrom
review

Conversation

@samsonovroma2011-cmd

Copy link
Copy Markdown
Owner

Я проведу код ревью проекта https://github.com/theshohidul/FastAPI-Boilerplate

Comment thread app/core/db/base.py
from sqlalchemy.orm import as_declarative


@as_declarative()

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

не знакомый декоратор

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Советую изучить, что он делает и для чего

Comment on lines +10 to +47
def init_handlers(app_: FastAPI) -> None:

@app_.exception_handler(CustomException)
async def custom_exception_handler(request: Request, exc: CustomException):
return JSONResponse(
status_code=exc.status_code,
content={
"status": exc.status,
"status_type": exc.status_type,
"message": exc.message
},
)

@app_.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
reformatted_message = defaultdict(list)
field_string = ''
msg = ''

for pydantic_error in exc.errors():
loc, msg, error_type = pydantic_error["loc"], pydantic_error["msg"], pydantic_error["type"]

if error_type == "value_error.jsondecode":
return await custom_exception_handler(request=request, exc=BadRequestException())

filtered_loc = loc[1:] if loc[0] in ("body", "query", "path") and loc[1:] else loc
field_string = ".".join(filtered_loc)
reformatted_message[field_string].append(msg)

return JSONResponse(
status_code=UnprocessableEntity().status_code,
content={
"status": UnprocessableEntity.status,
"status_type": UnprocessableEntity.status_type,
"message": field_string.capitalize() + ' ' + msg,
"errors": reformatted_message
}
)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Слишком нагруженная функция

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Как бы сделал по другому. Интересно решение

Comment thread app/core/db/db.py
def __getattr__(self, name):
return getattr(self._session, name)

async def init(self):

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хорошо что используется асинхронность

Comment thread app/pyproject.toml
loguru = "^0.6.0"
cryptography = "^38.0.1"
bcrypt = "^4.0.0"
sqlalchemy = "^1.4.46"

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Используется старая версия sqlalchemy

@samsonovroma2011-cmd samsonovroma2011-cmd left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Мне показалось что в целом у проекта хорошая архитектура. Могу выделить в ней несколько плюсов: используется паттерн репозиторий, есть сервисный слой и виден очень сильный ООП подход.

Я понял этот проект на 50-60%.

Comment thread app/core/configs.py
Comment on lines +7 to +19
class Settings(BaseSettings):
ENV: str = "dev"
PROJECT_NAME: str = "Boilerplate"
PROJECT_TITLE: str = "FastAPI Boilerplate"
PROJECT_DESCRIPTION: str = "FastAPI Boilerplate"
PROJECT_VERSION: str = "1.0.0"

ENCODING: str = 'utf-8'

API_V1_PREFIX: str = "/api/v1"
JWT_ALGORITHM: str = "HS256"
JWT_ACCESS_SECRET_KEY: str = "MySuperSecret"
JWT_REFRESH_SECRET_KEY: str = "MySuperSecretRefresh"

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Секретные данные должны быть в в файле .env и от туда их должен брать класс с настройками

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да. Тут и нету секретных данных. Это шаблоны заглушки

@samsonovroma2011-cmd samsonovroma2011-cmd left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Мне показалось что в целом у проекта хорошая архитектура. Могу выделить в ней несколько плюсов: используется паттерн репозиторий, есть сервисный слой и виден очень сильный ООП подход.

Я понял этот проект на 50-60%.

@samsonovroma2011-cmd samsonovroma2011-cmd changed the title add code for review Код ревью Aug 6, 2026
Comment thread app/api/v1/user/models.py
Comment on lines +2 to +50

from sqlalchemy import Column, Integer, String, ForeignKey, Table, PrimaryKeyConstraint
from sqlalchemy.orm import declarative_base, relationship

from core.db.base import Base


user_roles_table = Table(
"user_roles",
Base.metadata,
Column("user_id", ForeignKey("users.id")),
Column("role_id", ForeignKey("roles.id")),
PrimaryKeyConstraint('user_id', 'role_id'),
)


class RoleModel(Base):
def __init__(self):
pass

__tablename__ = "roles"

id: int = Column(Integer, primary_key=True, autoincrement=True)
role: str = Column(String(255), nullable=False)
__mapper_args__ = {"eager_defaults": True}

users = relationship(
"UserModel", secondary=user_roles_table, back_populates="roles"
)


class UserModel(Base):
def __init__(self):
pass

__tablename__ = "users"

id: int = Column(Integer, primary_key=True, autoincrement=True)
name: str = Column(String(255), nullable=False)
email: str = Column(String(255), nullable=False, unique=True)
password: str = Column(String(255), nullable=False)
phone: str = Column(String(255), nullable=False)
__mapper_args__ = {"eager_defaults": True}

roles: List[RoleModel] = relationship(
"RoleModel",
secondary=user_roles_table,
back_populates="users",
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Смешивание подходов создание моделей. Декларативный и императивный подходы смешаны

Comment on lines +16 to +20
await self.db.rollback()

user_dict = user.dict()
role_name = user.role
del user_dict["role"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Для чего rollback до выполнение операции? Почему del? Советую изучить

Comment on lines +10 to +47
def init_handlers(app_: FastAPI) -> None:

@app_.exception_handler(CustomException)
async def custom_exception_handler(request: Request, exc: CustomException):
return JSONResponse(
status_code=exc.status_code,
content={
"status": exc.status,
"status_type": exc.status_type,
"message": exc.message
},
)

@app_.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
reformatted_message = defaultdict(list)
field_string = ''
msg = ''

for pydantic_error in exc.errors():
loc, msg, error_type = pydantic_error["loc"], pydantic_error["msg"], pydantic_error["type"]

if error_type == "value_error.jsondecode":
return await custom_exception_handler(request=request, exc=BadRequestException())

filtered_loc = loc[1:] if loc[0] in ("body", "query", "path") and loc[1:] else loc
field_string = ".".join(filtered_loc)
reformatted_message[field_string].append(msg)

return JSONResponse(
status_code=UnprocessableEntity().status_code,
content={
"status": UnprocessableEntity.status,
"status_type": UnprocessableEntity.status_type,
"message": field_string.capitalize() + ' ' + msg,
"errors": reformatted_message
}
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Как бы сделал по другому. Интересно решение

Comment thread app/core/configs.py
Comment on lines +7 to +19
class Settings(BaseSettings):
ENV: str = "dev"
PROJECT_NAME: str = "Boilerplate"
PROJECT_TITLE: str = "FastAPI Boilerplate"
PROJECT_DESCRIPTION: str = "FastAPI Boilerplate"
PROJECT_VERSION: str = "1.0.0"

ENCODING: str = 'utf-8'

API_V1_PREFIX: str = "/api/v1"
JWT_ALGORITHM: str = "HS256"
JWT_ACCESS_SECRET_KEY: str = "MySuperSecret"
JWT_REFRESH_SECRET_KEY: str = "MySuperSecretRefresh"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да. Тут и нету секретных данных. Это шаблоны заглушки

Comment thread app/core/db/base.py
from sqlalchemy.orm import as_declarative


@as_declarative()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Советую изучить, что он делает и для чего

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants