Skip to content

Commit 095a115

Browse files
committed
[Add] User 생성 API 추가
- 새로운 도메인 User와 관련된 기능 추가 - schema, crud, router 코드 생성 - main.py에 user router 연결 - 사용자 정보 중복 상황을 다루기 위한 유효성 검사 반영 - 비밀번호 암호화를 위한 passlib 사용 - passlib와 bcrypt 간의 버전 문제가 있는 듯 하다. - pyca/bcrypt#684 - 이메일 정보 포맷 확인을 위한 Pydantic 확장 - pip install pydantic[email]
1 parent 654d6d5 commit 095a115

File tree

5 files changed

+76
-2
lines changed

5 files changed

+76
-2
lines changed

domain/user/user_crud.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from sqlalchemy.orm import Session
2+
from passlib.context import CryptContext
3+
4+
from domain.user.user_schema import UserCreate
5+
from models import User
6+
7+
8+
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
9+
10+
def create_user(db: Session, user_create: UserCreate):
11+
db_user = User(
12+
username=user_create.username,
13+
password=pwd_context.hash(user_create.password1),
14+
email=user_create.email
15+
)
16+
17+
db.add(db_user)
18+
19+
db.commit()
20+
21+
def get_existing_user(db: Session, user_create: UserCreate):
22+
return db.query(User).filter(
23+
(User.username == user_create.username) | (User.email == user_create.email)
24+
).first()

domain/user/user_router.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from fastapi import APIRouter, Depends, HTTPException
2+
from sqlalchemy.orm import Session
3+
from starlette import status
4+
5+
from database import get_db
6+
from domain.user import user_crud, user_schema
7+
8+
9+
router = APIRouter(
10+
prefix="/api/user",
11+
)
12+
13+
@router.post("/create", status_code=status.HTTP_204_NO_CONTENT)
14+
def user_create(_user_create: user_schema.UserCreate, db: Session = Depends(get_db)):
15+
user = user_crud.get_existing_user(db, user_create=_user_create)
16+
if user:
17+
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="ALREADY_EXIST_USER")
18+
user_crud.create_user(db=db, user_create=_user_create)

domain/user/user_schema.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from pydantic import BaseModel, field_validator, EmailStr
2+
from pydantic_core.core_schema import FieldValidationInfo
3+
4+
5+
class UserCreate(BaseModel):
6+
username: str
7+
password1: str
8+
password2: str
9+
email: EmailStr
10+
11+
@field_validator("username","password1", "password2", "email")
12+
def not_empty(cls, v):
13+
if not v or not v.strip():
14+
raise ValueError("NOT_ALLOW_EMPTY_VALUE")
15+
return v
16+
17+
@field_validator("password2")
18+
def passwords_match(cls, v, info: FieldValidationInfo):
19+
if "password1" in info.data and v != info.data["password1"]:
20+
raise ValueError("PASSWORD_NOT_MATCH")
21+
return v

main.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from domain.question import question_router
44
from domain.answer import answer_router
5+
from domain.user import user_router
56

67

78
app = FastAPI()
@@ -12,4 +13,5 @@ def health_check():
1213
return {"STATUS" : "WORKING_WELL..."}
1314

1415
app.include_router(question_router.router)
15-
app.include_router(answer_router.router)
16+
app.include_router(answer_router.router)
17+
app.include_router(user_router.router)

models.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,13 @@ class Answer(Base):
2020
content= Column(Text, nullable=False)
2121
create_date = Column(DateTime, nullable=False)
2222
question_id = Column(Integer, ForeignKey("question.id"))
23-
question = relationship("Question", backref="answers")
23+
question = relationship("Question", backref="answers")
24+
25+
26+
class User(Base):
27+
__tablename__= "user"
28+
29+
id = Column(Integer, primary_key=True)
30+
username = Column(String, nullable=False, unique=True)
31+
password = Column(String, nullable=False)
32+
email = Column(String, nullable=False, unique=True)

0 commit comments

Comments
 (0)