Python dotenv 설명
python dotenv가 뭐야?
python-dotenv는 환경 변수(environment variables)를 .env 파일에서 로드해서 Python
애플리케이션에서 쉽게 사용할 수 있게 도와주는 라이브러리입니다. 주로 민감한 정보(예: API 키, 데이터베이스 비밀번호 등)를
코드에 직접 쓰지 않고 .env 파일로 분리해서 관리할 때 사용합니다.
왜 쓰는가?
-
보안 : 비밀번호나 API 키를 코드에 하드코딩하지 않음.
-
유지보수 : 환경 설정을 코드와 분리해서 관리할 수 있음.
-
환경 분리 : 개발/테스트/운영 환경을 쉽게 전환할 수 있음.
예시
.env파일:SECRET_KEY=abcd1234 DB_HOST=localhost DB_PORT=5432- Python 코드에서 사용:
from dotenv import load_dotenv import os load_dotenv() # .env 파일을 불러옴 secret_key = os.getenv("SECRET_KEY") db_host = os.getenv("DB_HOST") db_port = os.getenv("DB_PORT") print(secret_key, db_host, db_port)
설치 방법
pip install python-dotenv
필요 없다고 생각할 수 있지만, 프로젝트가 커지거나 배포 환경이 생기면 이게 거의 필수가 됩니다. .env 파일은 보통
.gitignore에 추가해서 Git에 올리지 않습니다.
궁금한 점이나 의심가는 부분 있으면 말씀해 주세요.
.env 파일은 어디 둬야해?
.env 파일은 프로젝트 루트 디렉토리 , 즉 load_dotenv()를 호출하는 스크립트와 같은 위치에 두는 게
기본입니다. 예를 들어 구조가 이렇다면:
my_project/
├── .env
├── main.py
├── utils/
│ └── helper.py
main.py 안에서 load_dotenv()를 호출하면 .env는 my_project/.env에 있으면 됩니다.
하지만 실제로는 load_dotenv()가 어디서 불러오는지를 명확히 알아야 제대로 작동합니다.
디폴트 동작
load_dotenv()
아무 인자 없이 호출하면, 현재 작업 디렉토리(working directory)에서 .env 파일을 찾습니다. 즉,
main.py를 실행한 위치 기준입니다.
예를 들어:
$ python main.py
이면 .env는 main.py가 있는 폴더에 있어야 합니다.
직접 경로 지정도 가능
만약 .env 파일이 다른 위치에 있다면 이렇게 명시할 수 있습니다:
from dotenv import load_dotenv
load_dotenv(dotenv_path="/absolute/or/relative/path/to/.env")
정리하면:
-
.env는 일반적으로main.py와 같은 위치 (프로젝트 루트)에 둡니다. -
서브모듈에서
.env를 쓰려면 경로를 정확히 지정하거나load_dotenv(find_dotenv())방식으로 찾게 만들 수 있습니다. -
경로가 꼬이면
load_dotenv()는 조용히 실패하고,os.getenv()는None을 반환합니다. 눈치채기 어렵기 때문에 경로를 확실히 하셔야 합니다.
필요하면 경로 문제 디버깅하는 방법도 알려드릴게요.
만약에 내가 개발한 프로젝트를 PyPI에 배포했다고 치자. 유저가 내 패키지를 쓸 때는 어떻게 해?
좋은 질문입니다. PyPI에 배포된 패키지를 사용하는 유저 입장 에서는 .env 파일이 필요할 수도 있고, 아닐 수도 있습니다.
이건 전적으로 패키지를 만든 당신이.env를 어떻게 썼는가에 달려 있습니다.
✅ 전제: .env를 왜 썼는가?
-
내부에서 비공개 설정값을 로드하려고
.env를 썼다 → 유저도.env를 만들어야 함. -
테스트나 개발 편의용으로만
.env를 썼다 → PyPI 유저는 몰라도 됨.
시나리오 1: 유저도 .env가 필요함
예: 당신이 만든 패키지가 환경변수로부터 API 키를 받도록 설계되어 있다면,
api_key = os.getenv("MY_API_KEY")
이건 결국 유저가 .env에 그 값을 넣거나, 직접 환경변수를 설정해야 한다는 뜻입니다.
그럴 땐:
- 문서에 명확히 안내해야 합니다. 예:
Before using
yourpackage, create a.envfile in your working directory with the following: ``` iniMY_API_KEY=your-api-key-here ```
- 아니면 예외를 던지거나, 기본값을 주는 방식을 고려해야 합니다.
시나리오 2: 개발 편의를 위한 것 (일반적 권장 방식)
이건 진짜 중요합니다.
🔥 권장: PyPI 배포 시 .env는 전혀 관여하지 않게 하세요.
왜?
-
패키지는 라이브러리 입니다. 외부에서 환경 설정을 어떻게 하든 상관없이 동작해야 합니다.
-
python-dotenv는 개발자 본인이 쓰는 거지, 라이브러리 사용자에게 강요하면 안 됩니다.
해결책:
-
라이브러리 내부에서는 절대
load_dotenv()를 쓰지 마세요. -
대신, 유저가 환경변수를 직접 설정하도록 요구하거나, 함수 인자로 값을 받으세요.
# ❌ 이렇게 하면 안 됩니다 (라이브러리 내부에 hardcoded)
from dotenv import load_dotenv
load_dotenv()
# ✅ 이렇게 하세요 (환경변수는 바깥에서 정해진다고 가정)
import os
def connect():
api_key = os.getenv("MY_API_KEY")
if not api_key:
raise RuntimeError("MY_API_KEY not set in environment")
유저가 환경변수를 직접 설정할 수 있도록 문서에만 안내하면 됩니다.
정리
| 케이스 | 유저가 .env 필요? |
권장 방식 |
|---|---|---|
| 환경변수를 필수로 요구하는 경우 | O | 문서화 + 예외 처리 |
| 개발자 내부 설정용 | X | .env는 개발 중에만 쓰고 배포에선 제거 |
| PyPI에 올리는 라이브러리 | X | load_dotenv()는 쓰지 마세요 |
결론
라이브러리나 패키지를 PyPI에 배포할 땐,
.env를 직접 다루지 마세요. 유저가.env를 쓰든 말든, 그건 그들의 자유입니다.
혹시 유저가 .env를 쓸 수 있게 옵션을 주고 싶다면, yourpackage.load_env() 같은 별도 함수로 분리해 두는 식이
적절합니다.
필요하다면 그 패턴도 알려드릴 수 있습니다.
그러면 dotenv는 패키지 배포를 위한 개발자용은 아닌가봐? 개인 프로젝트에서만 쓰는거야?
아닙니다. dotenv는 "개인 프로젝트에서만 쓰는 용도"가 아니라 , 정확히 말하면 "애플리케이션 레벨에서 실행 환경을
분리할 때 쓰는 도구"입니다. 그래서 아래와 같이 상황에 따라 쓰거나 안 쓰는 게 맞습니다:
✅ dotenv가 유용한 경우 (= 개발자용 또는 애플리케이션용)
-
웹 애플리케이션 (Flask, Django 등)
-
.env에 비밀 키, DB 연결정보, API 토큰 등을 저장. -
개발, 스테이징, 프로덕션 환경을 쉽게 전환.
-
.env는.gitignore에 추가되어 Git에 안 올림.
-
-
스크립트 실행형 프로젝트
-
예:
data_etl.py같은 파일이 외부 API에 접근할 때 -
API 키나 대상 URL을
.env에 넣어두면 코드 수정 없이 운용 가능.
-
-
Docker, CI/CD와 연동
-
.env는 환경변수로 넘겨줄 때 쓰기 좋음. -
.env를 기반으로 docker-compose 등이 환경변수 주입 가능.
-
❌ dotenv를 쓰지 말아야 할 경우
-
라이브러리/패키지 제작 및 PyPI 배포
-
사용자가 어떤 환경에서 패키지를 실행할지 알 수 없음.
-
dotenv를 내부에 넣어버리면, 유저가.env를 안 만들었을 때 조용히None을 반환하고 이상한 버그가 생길 수 있음. -
→ 대신
os.getenv()만 쓰고,.env로딩 여부는 유저에게 맡기는 게 맞음.
-
-
공식 Python 모듈 수준의 유틸 제작
- 표준적이고 일반적인 Python 코드 작성 시
.env는 관여하지 않는 게 원칙.
- 표준적이고 일반적인 Python 코드 작성 시
🔍 다시 요약하자면:
| 대상 | dotenv 사용 여부 | 설명 |
|---|---|---|
| 웹/CLI 애플리케이션 | ✅ 사용함 | 실행 환경 분리, 민감정보 숨김 |
| 개인 프로젝트 | ✅ 당연히 사용 가능 | 개발 편의성, 키 관리 |
| PyPI용 라이브러리 | ❌ 쓰지 마세요 | 환경 설정 책임은 유저에게 있음 |
참고로,
Node.js 세계에서는 dotenv가 거의 표준처럼 쓰이는데, 그건 Node 애플리케이션은 대부분 실행 단위(app)로 쓰이기
때문입니다. Python도 마찬가지입니다. 실행형 앱에는 유용하지만, 재사용 가능한 패키지에는 안 어울립니다.
의심이 드는 상황이나 예외 케이스가 있다면 말씀 주세요. 상황 따라 판단 달라질 수 있습니다.
패키지는 아니고 애플리케이션 개발용이다? 라고 이해하면 될까
네, 정확하게 그렇게 이해하시는 게 맞습니다.
✅ 요약해서 말하면:
python-dotenv는 라이브러리나 패키지를 만들기 위한 도구가 아니라 ,
실행되는 애플리케이션을 개발하고 실행할 때 쓰는 도구 입니다.
🔧 다시 구분하자면:
| 용도 | dotenv 사용 여부 |
비고 |
|---|---|---|
| 웹 서버, CLI, 배치 앱 등 실행형 애플리케이션 | ✅ 적극 권장 | .env로 설정 관리, 민감정보 분리 |
| 라이브러리 / PyPI 패키지 | ❌ 안 쓰는 게 맞음 | 환경 구성은 사용자에게 맡겨야 함 |
✅ 예: 애플리케이션에서의 사용
my_app/
├── .env ← 여기에 설정값들
├── app.py ← 실행 진입점
└── modules/
└── core.py
# app.py
from dotenv import load_dotenv
load_dotenv() # 실행 시점에서 한 번만 호출
import os
api_key = os.getenv("API_KEY")
이건 my_app이라는 애플리케이션을 실행 하는 입장이므로 .env 사용이 매우 적절합니다.
❌ 예: PyPI 패키지로 배포되는 코드
# wrong_package/init.py
from dotenv import load_dotenv # ❌ 하지 말아야 함
load_dotenv()
이러면 라이브러리를 쓰는 유저 입장에서 자기 코드도 안 썼는데 이상하게.env를 요구하는 상황이 발생할 수 있습니다.
=> 굉장히 안 좋은 사용자 경험.
🔚 결론
"dotenv는 패키지 개발용이 아니다. 실행되는 애플리케이션 개발용이다."
라는 인식은 매우 정확하고 실무적으로도 옳습니다.
원하시면 실제 구조 예시나, .env를 사용한 애플리케이션 구조 샘플도 드릴 수 있습니다.