2026년 7월 21일 화요일

# .env



# .env

* **.env.example**: 프로젝트에 필요한 환경변수의 이름(Key)만 복사해 둔 템플릿 파일입니다. (`git`에 공유됨)
* ~~**.env**~~: 실제 로컬에서 사용할 비밀번호나 API 키(Value)를 채워 넣는 진짜 파일입니다. (`git`에 절대 올리지 않음)

```bash
#.gitignore
.env

#.env
DATABASE_URL=sqlite:///./test.db
GOOGLE_SHEET_ID=your_sheet_id_here
SECRET_KEY=super-secret-key-1234
DEBUG_MODE=True

#.env.example
DATABASE_URL=your_database_url_here
GOOGLE_SHEET_ID=your_sheet_id_here
SECRET_KEY=your_jwt_secret_key_here
DEBUG_MODE=True
```

* **.env.example** 파일을 사용하여 로컬 개발 환경에 .env 파일을 만들어 사용.
새로운 환경변수를 추가했다면, 다른 팀원들을 위해 .env.example 파일에도 변수명(Key)을 함께 업데이트해 주는 것이 좋습니다.

* 프로덕션에선 환경 변수 를 받아서 처리한다.

```python
# config.py
# 현재 컴퓨터의 OS 환경변수(ENV_MODE)를 보고 어떤 설정을 켤지 런타임에 결정합니다.

from pydantic_settings import BaseSettings, SettingsConfigDict

class BaseConfig(BaseSettings):
  """모든 환경이 공유하는 공통 설정실"""

  # 💡 [핵심] ENV_MODE 자체를 Pydantic 변수로 등록합니다.
  # OS 환경변수에 ENV_MODE가 있으면 가져오고, 없으면 "local"이 기본값이 됩니다.
  ENV_MODE: str = "local"

  PROJECT_NAME: str = "My FastAPI App"
  GOOGLE_SHEET_ID: str = ""

  # ⭕ 에러가 났던 secret_key를 대문자로 클래스에 선언해 줍니다!
  SECRET_KEY: str = "super-secret-default-key"

  # 💡 [핵심 추가] 디버그 모드 스위치를 추가합니다. 기본값은 안전하게 False로 둡니다.
  DEBUG_MODE: bool = False

  LOG_DIR: str = "logs"
  LOG_FILE_NAME: str = "access.log"


class LocalConfig(BaseConfig):
  """내 컴퓨터(로컬)에서만 사용할 설정값"""

  DATABASE_URL: str = "sqlite:///./local.db"  # 로컬은 가벼운 SQLite 사용

  # 내 컴퓨터에서는 .env 파일을 읽도록 지정
  model_config = SettingsConfigDict(env_file=".env", extra="ignore", env_file_encoding="utf-8")


class ProdConfig(BaseConfig):
  """🔥 실제 AWS ECS 운영 서버에서 사용할 설정값"""

  DATABASE_URL: str = ""  # 실제 운영 DB 주소 (AWS가 환경변수로 주입해줄 것임)

  # AWS 서버에서는 .env 파일 없이 오직 OS 환경변수만 읽도록 강제
  model_config = SettingsConfigDict(env_file=None, extra="ignore", env_file_encoding="utf-8")


# -------------------------------------------------------------
# 👑 [최종 개선] 수동 os.environ을 완전히 걷어낸 진입점 함수
# -------------------------------------------------------------
def get_settings():
  # ① 일단 기본 설정 베이스를 0.001초만에 임시 가동합니다.
  # 이때 Pydantic이 OS 환경변수를 지가 알아서 긁어와 BaseConfig의 ENV_MODE에 채워 넣습니다!
  base = BaseConfig()

  # ② 수동 os.environ.get 대신, Pydantic이 안전하게 검증해준 진짜 변수값을 읽어 분기합니다.
  if base.ENV_MODE == "prod":
    return ProdConfig()
  return LocalConfig()


settings = get_settings()
```



database.py

import os from contextlib import contextmanager # contextmanager 임포트 from typing import Generator from dotenv...