[파이썬 Projects]/<파이썬 웹개발>

[파이썬] AI 활용 웹 서비스 개발 기록 : 6 scheme_files 설명

기록자_Recordian 2025. 6. 27. 15:22
728x90
반응형
이전 내용
 

[파이썬] AI 활용 웹 서비스 개발 기록 : 5 models_dir 설명

이전 내용 [파이썬] AI 활용 웹 서비스 개발 기록 : 4 frontend 설명이전 내용 [파이썬] AI 활용 웹 서비스 개발 기록 : 3 emails 설명이전 내용 [파이썬] AI 활용 웹 서비스 개발 기록 : 2 controllers 설명이전

puppy-foot-it.tistory.com


전체 디렉터리 구조

 

- 기술 스택

  • FastAPI (비동기 REST API)
  • SQLAlchemy (ORM)
  • Pydantic (입력값 검증)
  • PostgreSQL (RDBMS)
  • 로깅 시스템 (logger): logging 모듈 기반 로그 기록
  • 비밀번호 해싱: Passlib (bcrypt)
  • 이메일 처리: SMTP + 커스텀 EmailService
  • 유효성 검사: re 정규표현식, 수동 로직
  • 백그라운드 작업: BackgroundTasks
  • 세션 처리: FastAPI session middleware
  • 세션 상태 관리: st.session_state
  • API 키 관리: dotenv (.env), st.secrets

- 구현 의도

  • 단순한 CRUD API를 넘어서 실서비스에서 필요한 유효성 검사, 예외 처리, 중복 방지 등 실제 운영 환경에서 중요한 요소들을 고려해 설계.
  • 실무에서 바로 사용 가능한 사용자 인증 API를 처음부터 끝까지 설계 및 개발
  • DB 설계, 암호화, 유효성 검사, 예외처리, 이메일 전송 등 실무 요구 사항 반영
  • 보안 및 사용자 경험을 모두 고려한 구조라는 점에서 팀 프로젝트 혹은 SaaS 백엔드 개발에 바로 투입 가능

디렉터리 구조 5: scheme_files

 

- 아이, 사용자, 컨텐츠 관련 클래스

- pydantic을 사용한 아이, 사용자, 컨텐츠 관련 데이터 검증 코드 구현


◆ babies_schemes.py

- Baby(아이) 관련 API 요청 및 응답 데이터의 구조를 정의하고, 유효성 검증

- FastAPI와 연동하여 요청 데이터 검증 및 문서화 (swagger에 자동 적용됨)

 

[주요 기능]

모델 이름 목적 주요 필드 설명
CreateBaby 아이 생성 요청 시 사용 user_id, baby_name, baby_gender, baby_bday 입력값 검증 및 예시 설정 포함
BabyResponse 아이 조회 응답 시 사용 id, user_id, baby_name API 응답 모델로 사용
DeleteBaby 아이 삭제 요청 시 사용 user_id, baby_name 삭제를 위한 최소 정보 전달 구조

 

[고도화 아이디어]

아이디어 내용 기대 효과
날짜 유효성 baby_bday에 미래/과거 여부 체크 사용자 입력 오류 방지
응답 모델 보완 baby_gender, baby_bday도 BabyResponse에 포함 프론트엔드에 더 많은 정보 제공
권한 체크 로직 추가 DeleteBaby에 auth_token 등 추가 고려 보안 강화
설명/예시 확장 각 필드에 설명(Field(..., description="...")) 추가 API 문서(예: Swagger) 가독성 향상

◆ stories_schemes.py

- 동화 생성 및 응답 관련 Pydantic 모델

- 동화 생성, 저장, 응답 및 콘텐츠 생성 요청에 대한 데이터 구조 정의

- FastAPI 서버에서 사용자 요청의 유효성 검증 및 응답 구조 통일

 

[주요 기능 및 역할]

클래스 이름 용도 주요 필드 설명
StoryResponse 동화 조회 응답용 id, theme, voice, content, image, bw_image, created_at 등 DB에서 가져온 Story를 프론트로 전달할 때 사용
StoryRequest 동화 생성 요청 name, theme 동화 제목 및 테마 기반 생성 요청
SaveStoryRequest 동화 저장 요청 user_id, theme, voice, content, image, bw_image 동화를 DB에 저장하기 위한 요청
TTSRequest 음성 생성 요청 text, voice, speed 텍스트를 TTS로 변환하는 요청
ImageRequest 이미지 생성 요청 text 동화 내용을 기반으로 이미지 생성 요청
MusicRequest 음악 검색 요청 theme 테마에 맞는 자장가 음악 검색
VideoRequest 영상 검색 요청 theme 테마에 맞는 유튜브 영상 검색

 

[고도화 아이디어]

아이디어 내용 기대 효과
Field로 문서화 강화 각 필드에 Field(..., description=..., example=...) 추가 Swagger 문서 가독성 향상
Enum 클래스 사용 theme, voice, gender 등에 Enum 사용 허용값 명시로 안정성 강화

 


◆ users_schemes.py

- 사용자 회원가입, 로그인, 비밀번호 변경, 사용자 정보 조회 요청에 사용되는 데이터 검증 및 직렬화 모델 정의

- Pydantic, EmailStr, BaseModel 상속 구조

 

[주요 클래스 기능]

클래스 이름 역할 및 목적 특징
UserCreate 회원가입 요청 시 입력 데이터 검증 이메일 형식 검증 포함, 비밀번호 확인 필드 존재
UserLogin 로그인 요청 시 데이터 검증 최소한의 필수 필드 포함 (username, password)
UserUpdate 비밀번호 변경 시 데이터 검증 기존 비밀번호와 새 비밀번호 필드 존재
UserResponse 사용자 정보 응답용 모델 DB에서 조회한 사용자 정보 반환용, Config: from_attributes=True 사용
UserIdRequest 사용자 ID 기반 요청 처리용 삭제/조회 요청 시 유용

 

[고도화 아이디어]

아이디어 내용 기대 효과
Field() 사용 Field(..., description="설명", example="test@example.com") 형태로 문서화 Swagger 문서 자동화 및 가독성 향상
검증 로직 클래스화 @validator()를 활용해 password == password_confirm 검사 API 요청 단에서 에러 사전 방지

▶ 비밀번호 검증 로직의 경우, 현재 users_controller.py 파일에 회원가입 라우터에 구현되어 있으나,

이를 users_chemes.py의 클래스 내에 구현하는 것이 유지보수에 더 용이할 것으로 보임.

 

★ 참고: users_controller.py의 회원가입 관련 로직

# 회원가입
@router.post("/signup")
async def signup(signup_data: UserCreate, background_tasks: BackgroundTasks, db:Session=Depends(get_db)):
    logger.info(f"회원 가입 요청: 사용자 이름 {signup_data.username}, 이메일: {signup_data.email}")

    # ID 규칙 확인
    if not re.fullmatch(r"[a-z0-9]+", signup_data.username):
        logger.warning("회원 가입 실패: 사용자 규칙 위반")
        raise HTTPException(status_code=400, detail="사용자 이름은 영어 소문자와 숫자로만 구성되어야 합니다.")
    
    # 비밀번호 규칙 확인
    if not password_regex.match(signup_data.password):
        logger.warning("회원 가입 실패: 비밀번호 규칙 위반")
        raise HTTPException(status_code=400, detail="비밀번호는 최소 10자 이상이며, 대문자, 소문자, 숫자 및 특수문자가 포함돼야 합니다.")
    
    # 비밀번호 확인 일치 검사
    if signup_data.password != signup_data.password_confirm:
        logger.warning("비밀번호가 일치하지 않습니다.")
        raise HTTPException(status_code=400, detail="비밀번호가 서로 일치하지 않습니다.")
    
    # username 중복 확인
    existing_user = db.query(User).filter(User.username == signup_data.username).first()
    if existing_user:
        logger.warning(f"회원 가입 실패: 이미 존재하는 사용자 이름 - {signup_data.username}")
        raise HTTPException(status_code=400, detail="이미 존재하는 사용자 이름입니다.")
    
    # nickname 중복 확인
    existing_nick = db.query(User).filter(User.nickname == signup_data.nickname).first()
    if existing_nick:
        logger.warning(f"회원 가입 실패: 이미 존재하는 닉네임 - {signup_data.nickname}")
        raise HTTPException(status_code=400, detail="이미 존재하는 닉네임입니다.")

    # 모든 조건 만족 시
    hashed_password = get_password_hash(signup_data.password) # 비밀번호 해시
    # 기본 role_id 설정 (예: 일반 사용자)
    DEFAULT_ROLE_ID = 1
    new_user = User(username=signup_data.username,
                    nickname=signup_data.nickname,
                    email = signup_data.email, 
                    hashed_password=hashed_password,
                    role_id=DEFAULT_ROLE_ID
                    )
    db.add(new_user)
    logger.info(f"{new_user.username} 사용자가 데이터베이스에 추가 되었습니다.")

    try:
        db.commit()
        logger.info("데이터베이스에 새로운 사용자가 추가되었습니다.")
    except Exception as e:
        db.rollback() # 에러 발생 시 롤백
        logger.error(f"회원 가입 오류: {e}") # 에러 내용 출력
        raise HTTPException(status_code=500, detail="회원 가입 실패. 다시 시도해 주세요")
    db.refresh(new_user)

    # 백그라운드 작업 등록
    background_tasks.add_task(send_welcome_email, new_user.email)
    logger.info(f"회원 가입 후 사용자 {new_user.username}에게 환영 이메일 발송")

    return {"message": "회원가입을 성공하였습니다. 이메일을 확인해 주세요."}

다음 내용

 

[파이썬] AI 활용 웹 서비스 개발 기록 : 7 main / ai_server

이전 내용 [파이썬] AI 활용 웹 서비스 개발 기록 : 6 scheme_files이전 내용 [파이썬] AI 활용 웹 서비스 개발 기록 : 5 models_dir 설명이전 내용 [파이썬] AI 활용 웹 서비스 개발 기록 : 4 frontend 설명이전

puppy-foot-it.tistory.com

728x90
반응형