Skip to content

Commit 41178e5

Browse files
committed
WPS fixes
1 parent e2842f4 commit 41178e5

25 files changed

+687
-598
lines changed

backend/app/alembic/versions/9c0a54914c78_add_max_length_for_string_varchar_.py

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@
99
import sqlalchemy as sa
1010
from alembic import op
1111

12+
# Constants
13+
STRING_FIELD_LENGTH = 255
14+
USER_TABLE = "user"
15+
ITEM_TABLE = "item"
16+
1217
# revision identifiers, used by Alembic.
1318
revision = "9c0a54914c78"
1419
down_revision = "e2412789c190"
@@ -20,37 +25,37 @@ def upgrade() -> None:
2025
"""Upgrade database schema."""
2126
# Adjust the length of the email field in the User table
2227
op.alter_column(
23-
"user",
28+
USER_TABLE,
2429
"email",
2530
existing_type=sa.String(),
26-
type_=sa.String(length=255),
31+
type_=sa.String(length=STRING_FIELD_LENGTH),
2732
existing_nullable=False,
2833
)
2934

3035
# Adjust the length of the full_name field in the User table
3136
op.alter_column(
32-
"user",
37+
USER_TABLE,
3338
"full_name",
3439
existing_type=sa.String(),
35-
type_=sa.String(length=255),
40+
type_=sa.String(length=STRING_FIELD_LENGTH),
3641
existing_nullable=True,
3742
)
3843

3944
# Adjust the length of the title field in the Item table
4045
op.alter_column(
41-
"item",
46+
ITEM_TABLE,
4247
"title",
4348
existing_type=sa.String(),
44-
type_=sa.String(length=255),
49+
type_=sa.String(length=STRING_FIELD_LENGTH),
4550
existing_nullable=False,
4651
)
4752

4853
# Adjust the length of the description field in the Item table
4954
op.alter_column(
50-
"item",
55+
ITEM_TABLE,
5156
"description",
5257
existing_type=sa.String(),
53-
type_=sa.String(length=255),
58+
type_=sa.String(length=STRING_FIELD_LENGTH),
5459
existing_nullable=True,
5560
)
5661

@@ -59,36 +64,36 @@ def downgrade() -> None:
5964
"""Downgrade database schema."""
6065
# Revert the length of the email field in the User table
6166
op.alter_column(
62-
"user",
67+
USER_TABLE,
6368
"email",
64-
existing_type=sa.String(length=255),
69+
existing_type=sa.String(length=STRING_FIELD_LENGTH),
6570
type_=sa.String(),
6671
existing_nullable=False,
6772
)
6873

6974
# Revert the length of the full_name field in the User table
7075
op.alter_column(
71-
"user",
76+
USER_TABLE,
7277
"full_name",
73-
existing_type=sa.String(length=255),
78+
existing_type=sa.String(length=STRING_FIELD_LENGTH),
7479
type_=sa.String(),
7580
existing_nullable=True,
7681
)
7782

7883
# Revert the length of the title field in the Item table
7984
op.alter_column(
80-
"item",
85+
ITEM_TABLE,
8186
"title",
82-
existing_type=sa.String(length=255),
87+
existing_type=sa.String(length=STRING_FIELD_LENGTH),
8388
type_=sa.String(),
8489
existing_nullable=False,
8590
)
8691

8792
# Revert the length of the description field in the Item table
8893
op.alter_column(
89-
"item",
94+
ITEM_TABLE,
9095
"description",
91-
existing_type=sa.String(length=255),
96+
existing_type=sa.String(length=STRING_FIELD_LENGTH),
9297
type_=sa.String(),
9398
existing_nullable=True,
9499
)

backend/app/api/deps.py

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,45 +10,56 @@
1010
from pydantic import ValidationError
1111
from sqlmodel import Session
1212

13+
from app import constants
1314
from app.core import security
14-
from app.core.config import settings
15-
from app.core.db import engine
15+
from app.core import config, db
1616
from app.models import TokenPayload, User
1717

1818
reusable_oauth2 = OAuth2PasswordBearer(
19-
tokenUrl=f"{settings.API_V1_STR}/login/access-token",
19+
tokenUrl=f"{config.settings.API_V1_STR}/login/access-token",
2020
)
2121

2222

2323
def get_db() -> Generator[Session]:
2424
"""Get database session."""
25-
with Session(engine) as session:
25+
with Session(db.engine) as session:
2626
yield session
2727

2828

2929
SessionDep = Annotated[Session, Depends(get_db)]
3030
TokenDep = Annotated[str, Depends(reusable_oauth2)]
3131

3232

33-
def get_current_user(session: SessionDep, token: TokenDep) -> User:
34-
"""Get current user from JWT token."""
33+
def _validate_token(token: str) -> TokenPayload:
34+
"""Validate JWT token and return payload."""
3535
try:
3636
payload = jwt.decode(
3737
token,
38-
settings.SECRET_KEY,
38+
config.settings.SECRET_KEY,
3939
algorithms=[security.ALGORITHM],
4040
)
41-
token_data = TokenPayload(**payload)
42-
except (InvalidTokenError, ValidationError):
41+
except InvalidTokenError:
4342
raise HTTPException(
4443
status_code=status.HTTP_403_FORBIDDEN,
4544
detail="Could not validate credentials",
4645
) from None
46+
try:
47+
return TokenPayload(**payload)
48+
except ValidationError:
49+
raise HTTPException(
50+
status_code=status.HTTP_403_FORBIDDEN,
51+
detail="Could not validate credentials",
52+
) from None
53+
54+
55+
def get_current_user(session: SessionDep, token: TokenDep) -> User:
56+
"""Get current user from JWT token."""
57+
token_data = _validate_token(token)
4758
user = session.get(User, token_data.sub)
4859
if not user:
49-
raise HTTPException(status_code=404, detail="User not found")
60+
raise HTTPException(status_code=constants.NOT_FOUND_CODE, detail="User not found")
5061
if not user.is_active:
51-
raise HTTPException(status_code=400, detail="Inactive user")
62+
raise HTTPException(status_code=constants.BAD_REQUEST_CODE, detail="Inactive user")
5263
return user
5364

5465

@@ -59,7 +70,7 @@ def get_current_active_superuser(current_user: CurrentUser) -> User:
5970
"""Get current active superuser."""
6071
if not current_user.is_superuser:
6172
raise HTTPException(
62-
status_code=403,
73+
status_code=constants.FORBIDDEN_CODE,
6374
detail="The user doesn't have enough privileges",
6475
)
6576
return current_user

backend/app/api/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
from fastapi import APIRouter
44

5-
from app.api.routes import items, login, private, users, utils
5+
from app.api.routes import items, login, misc, private, users
66
from app.core.config import settings
77

88
api_router = APIRouter()
99
api_router.include_router(login.router)
1010
api_router.include_router(users.router)
11-
api_router.include_router(utils.router)
11+
api_router.include_router(misc.router)
1212
api_router.include_router(items.router)
1313

1414

backend/app/api/routes/items.py

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from sqlmodel import func, select
88

99
from app.api.deps import CurrentUser, SessionDep
10+
from app.constants import BAD_REQUEST_CODE, NOT_FOUND_CODE
1011
from app.models import Item, ItemCreate, ItemPublic, ItemsPublic, ItemUpdate, Message
1112

1213
router = APIRouter(prefix="/items", tags=["items"])
@@ -24,7 +25,7 @@ def read_items(
2425
count_statement = select(func.count()).select_from(Item)
2526
count = session.exec(count_statement).one()
2627
statement = select(Item).offset(skip).limit(limit)
27-
items = session.exec(statement).all()
28+
item_list = session.exec(statement).all()
2829
else:
2930
count_statement = (
3031
select(func.count())
@@ -38,22 +39,22 @@ def read_items(
3839
.offset(skip)
3940
.limit(limit)
4041
)
41-
items = session.exec(statement).all()
42+
item_list = session.exec(statement).all()
4243

43-
return ItemsPublic(data=items, count=count)
44+
return ItemsPublic(item_data=item_list, count=count)
4445

4546

4647
@router.get("/{item_id}")
4748
def read_item(
4849
session: SessionDep, current_user: CurrentUser, item_id: uuid.UUID,
4950
) -> ItemPublic:
5051
"""Get item by ID."""
51-
item = session.get(Item, item_id)
52-
if not item:
53-
raise HTTPException(status_code=404, detail="Item not found")
54-
if not current_user.is_superuser and (item.owner_id != current_user.id):
55-
raise HTTPException(status_code=400, detail="Not enough permissions")
56-
return ItemPublic.model_validate(item)
52+
db_item = session.get(Item, item_id)
53+
if not db_item:
54+
raise HTTPException(status_code=NOT_FOUND_CODE, detail="Item not found")
55+
if not current_user.is_superuser and (db_item.owner_id != current_user.id):
56+
raise HTTPException(status_code=BAD_REQUEST_CODE, detail="Not enough permissions")
57+
return ItemPublic.model_validate(db_item)
5758

5859

5960
@router.post("/")
@@ -64,11 +65,11 @@ def create_item(
6465
item_in: ItemCreate,
6566
) -> ItemPublic:
6667
"""Create new item."""
67-
item = Item.model_validate(item_in, update={"owner_id": current_user.id})
68-
session.add(item)
68+
db_item = Item.model_validate(item_in, update={"owner_id": current_user.id})
69+
session.add(db_item)
6970
session.commit()
70-
session.refresh(item)
71-
return ItemPublic.model_validate(item)
71+
session.refresh(db_item)
72+
return ItemPublic.model_validate(db_item)
7273

7374

7475
@router.put("/{item_id}")
@@ -80,17 +81,17 @@ def update_item(
8081
item_in: ItemUpdate,
8182
) -> ItemPublic:
8283
"""Update an item."""
83-
item = session.get(Item, item_id)
84-
if not item:
85-
raise HTTPException(status_code=404, detail="Item not found")
86-
if not current_user.is_superuser and (item.owner_id != current_user.id):
87-
raise HTTPException(status_code=400, detail="Not enough permissions")
84+
db_item = session.get(Item, item_id)
85+
if not db_item:
86+
raise HTTPException(status_code=NOT_FOUND_CODE, detail="Item not found")
87+
if not current_user.is_superuser and (db_item.owner_id != current_user.id):
88+
raise HTTPException(status_code=BAD_REQUEST_CODE, detail="Not enough permissions")
8889
update_dict = item_in.model_dump(exclude_unset=True)
89-
item.sqlmodel_update(update_dict)
90-
session.add(item)
90+
db_item.sqlmodel_update(update_dict)
91+
session.add(db_item)
9192
session.commit()
92-
session.refresh(item)
93-
return ItemPublic.model_validate(item)
93+
session.refresh(db_item)
94+
return ItemPublic.model_validate(db_item)
9495

9596

9697
@router.delete("/{item_id}")
@@ -100,11 +101,11 @@ def delete_item(
100101
item_id: uuid.UUID,
101102
) -> Message:
102103
"""Delete an item."""
103-
item = session.get(Item, item_id)
104-
if not item:
105-
raise HTTPException(status_code=404, detail="Item not found")
106-
if not current_user.is_superuser and (item.owner_id != current_user.id):
107-
raise HTTPException(status_code=400, detail="Not enough permissions")
108-
session.delete(item)
104+
db_item = session.get(Item, item_id)
105+
if not db_item:
106+
raise HTTPException(status_code=NOT_FOUND_CODE, detail="Item not found")
107+
if not current_user.is_superuser and (db_item.owner_id != current_user.id):
108+
raise HTTPException(status_code=BAD_REQUEST_CODE, detail="Not enough permissions")
109+
session.delete(db_item)
109110
session.commit()
110111
return Message(message="Item deleted successfully")

backend/app/api/routes/login.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99

1010
from app import crud
1111
from app.api.deps import CurrentUser, SessionDep, get_current_active_superuser
12+
from app.constants import BAD_REQUEST_CODE, NOT_FOUND_CODE
1213
from app.core import security
1314
from app.core.config import settings
14-
from app.core.security import get_password_hash
1515
from app.models import Message, NewPassword, Token, UserPublic
16-
from app.utils import (
16+
from app.email_utils import (
1717
generate_password_reset_token,
1818
generate_reset_password_email,
1919
send_email,
@@ -35,9 +35,9 @@ def login_access_token(
3535
password=form_data.password,
3636
)
3737
if not user:
38-
raise HTTPException(status_code=400, detail="Incorrect email or password")
38+
raise HTTPException(status_code=BAD_REQUEST_CODE, detail="Incorrect email or password")
3939
if not user.is_active:
40-
raise HTTPException(status_code=400, detail="Inactive user")
40+
raise HTTPException(status_code=BAD_REQUEST_CODE, detail="Inactive user")
4141
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
4242
return Token(
4343
access_token=security.create_access_token(
@@ -60,7 +60,7 @@ def recover_password(email: str, session: SessionDep) -> Message:
6060

6161
if not user:
6262
raise HTTPException(
63-
status_code=404,
63+
status_code=NOT_FOUND_CODE,
6464
detail="The user with this email does not exist in the system.",
6565
)
6666
password_reset_token = generate_password_reset_token(email=email)
@@ -82,16 +82,16 @@ def reset_password(session: SessionDep, body: NewPassword) -> Message:
8282
"""Reset password."""
8383
email = verify_password_reset_token(token=body.token)
8484
if not email:
85-
raise HTTPException(status_code=400, detail="Invalid token")
85+
raise HTTPException(status_code=BAD_REQUEST_CODE, detail="Invalid token")
8686
user = crud.get_user_by_email(session=session, email=email)
8787
if not user:
8888
raise HTTPException(
89-
status_code=404,
89+
status_code=NOT_FOUND_CODE,
9090
detail="The user with this email does not exist in the system.",
9191
)
9292
if not user.is_active:
93-
raise HTTPException(status_code=400, detail="Inactive user")
94-
hashed_password = get_password_hash(password=body.new_password)
93+
raise HTTPException(status_code=BAD_REQUEST_CODE, detail="Inactive user")
94+
hashed_password = security.get_password_hash(password=body.new_password)
9595
user.hashed_password = hashed_password
9696
session.add(user)
9797
session.commit()
@@ -109,7 +109,7 @@ def recover_password_html_content(email: str, session: SessionDep) -> HTMLRespon
109109

110110
if not user:
111111
raise HTTPException(
112-
status_code=404,
112+
status_code=NOT_FOUND_CODE,
113113
detail="The user with this username does not exist in the system.",
114114
)
115115
password_reset_token = generate_password_reset_token(email=email)

backend/app/api/routes/utils.py renamed to backend/app/api/routes/misc.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@
44
from pydantic.networks import EmailStr
55

66
from app.api.deps import get_current_active_superuser
7+
from app.constants import CREATED_CODE
78
from app.models import Message
8-
from app.utils import generate_test_email, send_email
9+
from app.email_utils import generate_test_email, send_email
910

1011
router = APIRouter(prefix="/utils", tags=["utils"])
1112

1213

1314
@router.post(
1415
"/test-email/",
1516
dependencies=[Depends(get_current_active_superuser)],
16-
status_code=201,
17+
status_code=CREATED_CODE,
1718
)
1819
def test_email(email_to: EmailStr) -> Message:
1920
"""Test emails."""

0 commit comments

Comments
 (0)