Skip to content

Commit 1c2482b

Browse files
committed
lint
1 parent 43228b6 commit 1c2482b

File tree

5 files changed

+44
-38
lines changed

5 files changed

+44
-38
lines changed

backend/app/schemas/user.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@
22
Pydantic schemas for user-related data validation and serialization.
33
Handles user CRUD and response models for the API.
44
"""
5+
56
from enum import Enum
6-
from uuid import UUID
77
from typing import Optional
8+
from uuid import UUID
89

910
from pydantic import BaseModel, ConfigDict, EmailStr, Field, field_validator
1011

1112
# TODO:
1213
# confirm complexity rules for fields (such as password)
1314

15+
1416
class SignUpMethod(str, Enum):
1517
"""Authentication methods supported for user signup"""
18+
1619
PASSWORD = "PASSWORD"
1720
GOOGLE = "GOOGLE"
1821

@@ -21,6 +24,7 @@ class UserRole(str, Enum):
2124
"""
2225
Enum for possible user roles.
2326
"""
27+
2428
PARTICIPANT = "participant"
2529
VOLUNTEER = "volunteer"
2630
ADMIN = "admin"
@@ -35,6 +39,7 @@ class UserBase(BaseModel):
3539
"""
3640
Base schema for user model with common attributes shared across schemas.
3741
"""
42+
3843
first_name: str = Field(..., min_length=1, max_length=50)
3944
last_name: str = Field(..., min_length=1, max_length=50)
4045
email: EmailStr
@@ -45,32 +50,34 @@ class UserCreateRequest(UserBase):
4550
"""
4651
Request schema for user creation with conditional password validation
4752
"""
53+
4854
password: Optional[str] = Field(None, min_length=8)
4955
auth_id: Optional[str] = Field(None)
5056
signup_method: SignUpMethod = Field(default=SignUpMethod.PASSWORD)
5157

5258
@field_validator("password")
5359
def validate_password(cls, password: Optional[str], info):
54-
signup_method = info.data.get('signup_method')
55-
60+
signup_method = info.data.get("signup_method")
61+
5662
if signup_method == SignUpMethod.PASSWORD and not password:
5763
raise ValueError("Password is required for password signup")
58-
64+
5965
if password:
6066
if not any(char.isdigit() for char in password):
6167
raise ValueError("Password must contain at least one digit")
6268
if not any(char.isupper() for char in password):
6369
raise ValueError("Password must contain at least one uppercase letter")
6470
if not any(char.islower() for char in password):
6571
raise ValueError("Password must contain at least one lowercase letter")
66-
72+
6773
return password
6874

6975

7076
class UserCreateResponse(BaseModel):
7177
"""
7278
Response schema for user creation, maps directly from ORM User object.
7379
"""
80+
7481
id: UUID
7582
first_name: str
7683
last_name: str

backend/app/server.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
from fastapi import FastAPI
77

88
from app.routes import email
9-
load_dotenv()
109

11-
from . import models
12-
from .routes import user
13-
from .utilities.firebase_init import initialize_firebase
10+
load_dotenv()
1411

12+
# we need to load env variables before initialization code runs
13+
from . import models # noqa: E402
14+
from .routes import user # noqa: E402
15+
from .utilities.firebase_init import initialize_firebase # noqa: E402
1516

1617
log = logging.getLogger("uvicorn")
1718

backend/app/services/implementations/user_service.py

+13-22
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import logging
2-
from typing import Optional
32

43
import firebase_admin.auth
54
from fastapi import HTTPException
65
from sqlalchemy.orm import Session
76

87
from app.models import User
9-
from app.schemas.user import SignUpMethod, UserCreateRequest, UserCreateResponse, UserRole
8+
from app.schemas.user import (
9+
SignUpMethod,
10+
UserCreateRequest,
11+
UserCreateResponse,
12+
UserRole,
13+
)
1014
from app.services.interfaces.user_service import IUserService
1115

1216

@@ -15,16 +19,12 @@ def __init__(self, db: Session):
1519
self.db = db
1620
self.logger = logging.getLogger(__name__)
1721

18-
async def create_user(
19-
self,
20-
user: UserCreateRequest
21-
) -> UserCreateResponse:
22+
async def create_user(self, user: UserCreateRequest) -> UserCreateResponse:
2223
firebase_user = None
2324
try:
2425
if user.signup_method == SignUpMethod.PASSWORD:
2526
firebase_user = firebase_admin.auth.create_user(
26-
email=user.email,
27-
password=user.password
27+
email=user.email, password=user.password
2828
)
2929
## TO DO: SSO functionality depends a lot on frontend implementation,
3030
## so we may need to update this when we have a better idea of what
@@ -55,15 +55,9 @@ async def create_user(
5555
self.logger.error(f"Firebase error: {str(firebase_error)}")
5656

5757
if isinstance(firebase_error, firebase_admin.auth.EmailAlreadyExistsError):
58-
raise HTTPException(
59-
status_code=409,
60-
detail="Email already exists"
61-
)
58+
raise HTTPException(status_code=409, detail="Email already exists")
6259

63-
raise HTTPException(
64-
status_code=400,
65-
detail=str(firebase_error)
66-
)
60+
raise HTTPException(status_code=400, detail=str(firebase_error))
6761

6862
except Exception as e:
6963
# Clean up Firebase user if a database exception occurs
@@ -72,19 +66,16 @@ async def create_user(
7266
firebase_admin.auth.delete_user(firebase_user.uid)
7367
except firebase_admin.auth.AuthError as firebase_error:
7468
self.logger.error(
75-
"Failed to delete Firebase user after database insertion failed. "
69+
"Failed to delete Firebase user after database insertion failed"
7670
f"Firebase UID: {firebase_user.uid}. "
7771
f"Error: {str(firebase_error)}"
7872
)
7973

8074
# Rollback database changes
8175
self.db.rollback()
8276
self.logger.error(f"Error creating user: {str(e)}")
83-
84-
raise HTTPException(
85-
status_code=500,
86-
detail=str(e)
87-
)
77+
78+
raise HTTPException(status_code=500, detail=str(e))
8879

8980
def delete_user_by_email(self, email: str):
9081
pass

backend/app/utilities/db_utils.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
from dotenv import load_dotenv
21
import os
32

4-
load_dotenv()
5-
3+
from dotenv import load_dotenv
64
from sqlalchemy import create_engine
75
from sqlalchemy.orm import Session, sessionmaker
86

7+
load_dotenv()
8+
99
DATABASE_URL = os.getenv("POSTGRES_DATABASE_URL")
1010
engine = create_engine(DATABASE_URL)
1111
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
1212

13+
1314
# explanation for using yield to get local db session:
1415
# https://stackoverflow.com/questions/64763770/why-we-use-yield-to-get-sessionlocal-in-fastapi-with-sqlalchemy
1516
def get_db() -> Session:

backend/tests/unit/test_user.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
from app.models import Role
66
from app.models.Base import Base
77
from app.models.User import User
8-
from app.schemas.user import SignUpMethod, UserCreateRequest, UserCreateResponse, UserRole
8+
from app.schemas.user import (
9+
SignUpMethod,
10+
UserCreateRequest,
11+
UserCreateResponse,
12+
UserRole,
13+
)
914
from app.services.implementations.user_service import UserService
1015

1116
# Test DB Configuration
@@ -102,7 +107,7 @@ async def test_create_user_service(mock_firebase_auth, db_session):
102107
103108
password="TestPass@123",
104109
role=UserRole.PARTICIPANT,
105-
signup_method=SignUpMethod.PASSWORD
110+
signup_method=SignUpMethod.PASSWORD,
106111
)
107112

108113
# Act
@@ -127,6 +132,7 @@ async def test_create_user_service(mock_firebase_auth, db_session):
127132
db_session.rollback() # Rollback on error
128133
raise
129134

135+
130136
@pytest.mark.asyncio
131137
async def test_create_user_with_google(mock_firebase_auth, db_session):
132138
"""Test user creation flow with Google authentication"""
@@ -138,7 +144,7 @@ async def test_create_user_with_google(mock_firebase_auth, db_session):
138144
last_name="User",
139145
140146
role=UserRole.PARTICIPANT,
141-
signup_method=SignUpMethod.GOOGLE
147+
signup_method=SignUpMethod.GOOGLE,
142148
)
143149

144150
# Act
@@ -161,4 +167,4 @@ async def test_create_user_with_google(mock_firebase_auth, db_session):
161167
db_session.commit() # Commit successful test
162168
except Exception:
163169
db_session.rollback() # Rollback on error
164-
raise
170+
raise

0 commit comments

Comments
 (0)