인공지능 개발자 수다(유튜브 바로가기) 자세히보기

Fastapi

[FastAPI] 공통 코드(Common Code) 작성 방법 (12)

Suda_777 2025. 2. 2. 22:35

목차

    반응형

     

     

    1. 공통 코드(Common Code)란?

    공통 코드반복되는 로직을 모듈화하여 여러 곳에서 재사용할 수 있도록 구성하는 것

     

     장점

    • 코드 중복 감소 → 동일한 로직을 여러 곳에서 사용 가능
    • 가독성 향상 → 핵심 로직만 남아 코드가 깔끔해짐
    • 유지보수 용이 → 하나의 파일에서 수정하면 모든 곳에 적용됨
    • 테스트 용이 → 공통 모듈을 독립적으로 테스트 가능

     


    2. 공통 코드 작성 방법

    공통 코드 디렉토리 구조

    • 보통 utils/ 디렉터리에 작성하며, 프로젝트 전반에서 사용
    my_fastapi_project/
    │── main.py
    │── routers/
    │── services/
    │── repositories/
    │── models/
    │── schemas/
    │── database.py
    │── utils/  # ✅ 공통 코드 디렉터리
    │   ├── hash.py       # 비밀번호 해싱 관련 공통 함수
    │   ├── exceptions.py  # 커스텀 예외 처리
    │   ├── dependencies.py  # 공통 의존성 관리
    │   ├── logging.py    # 로깅 설정
    │   ├── time_utils.py # 날짜, 시간 관련 함수

     

     

    utils/hash.py

    • 비밀번호 해싱 (예시)
    from passlib.context import CryptContext
    
    pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
    
    def hash_password(password: str) -> str:
        """비밀번호를 해싱하는 함수"""
        return pwd_context.hash(password)
    
    def verify_password(plain_password: str, hashed_password: str) -> bool:
        """입력된 비밀번호가 저장된 해시와 일치하는지 확인"""
        return pwd_context.verify(plain_password, hashed_password)

     

    📌  서비스에서 적용 예시

    from utils.hash import hash_password
    
    def register_user(db: Session, user: UserCreate):
        user.password = hash_password(user.password)  # 비밀번호 해싱
        return create_user(db, user)

     

     

    utils/exceptions.py

    • 공통 예외 처리 (Custom Exception) (예시)
    from fastapi import HTTPException
    
    class UserAlreadyExistsException(HTTPException):
        def __init__(self):
            super().__init__(status_code=400, detail="이미 존재하는 사용자입니다.")
    
    class UserNotFoundException(HTTPException):
        def __init__(self):
            super().__init__(status_code=404, detail="사용자를 찾을 수 없습니다.")

     

    📌  서비스에서 적용 예시

    from utils.exceptions import UserAlreadyExistsException, UserNotFoundException
    
    def register_user(db: Session, user: UserCreate):
        existing_user = get_user_by_email(db, user.email)
        if existing_user:
            raise UserAlreadyExistsException()  # 공통 예외 사용
    
        return create_user(db, user)
    
    def retrieve_user(db: Session, user_id: int):
        user = get_user_by_id(db, user_id)
        if not user:
            raise UserNotFoundException()  # 공통 예외 사용
        return user

     

     

    utils/dependencies.py

    • 공통 의존성 관리
    from fastapi import Depends
    from database import get_db
    from sqlalchemy.orm import Session
    
    def get_db_session(db: Session = Depends(get_db)):
        """SQLAlchemy 세션을 가져오는 공통 의존성"""
        return db

     

    📌  라우터에서 적용 예시

    • 데이터베이스 세션은 라우터에서 직접 받는 것이 좋음
    from fastapi import Depends
    from utils.dependencies import get_db_session
    from sqlalchemy.orm import Session
    
    @router.get("/")
    async def get_users(db: Session = Depends(get_db_session)):
        return list_users(db)

     

     

    utils/logging.py

    공통 로깅 설정

    import logging
    
    def get_logger(name: str):
        """FastAPI에서 사용할 로거 생성"""
        logger = logging.getLogger(name)
        logger.setLevel(logging.INFO)
        handler = logging.StreamHandler()
        formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
        handler.setFormatter(formatter)
        logger.addHandler(handler)
        return logger

     

    📌 적용 예시

    from utils.logging import get_logger
    
    logger = get_logger(__name__)
    
    def register_user(db: Session, user: UserCreate):
        logger.info(f"새로운 사용자 등록: {user.email}")  # 공통 로깅 사용
        return create_user(db, user)

     

     

    utils/time_utils.py

    • 날짜 & 시간 유틸리티
    from datetime import datetime, timedelta
    
    def get_current_time() -> str:
        """현재 시간을 ISO 포맷으로 반환"""
        return datetime.utcnow().isoformat()
    
    def add_days_to_now(days: int) -> str:
        """현재 시간에 특정 일수를 추가하여 반환"""
        return (datetime.utcnow() + timedelta(days=days)).isoformat()

     

    📌 적용 예시

    from utils.time_utils import get_current_time
    
    print(get_current_time())  # ✅ 공통 함수 사용
    반응형