FastAPI — 타입이 곧 계약이다 · 환경변수의 오타가 운영 기본값이 되지 않게 · 实验
환경변수의 오타가 운영 기본값이 되지 않게
목표
엄격한 설정 파싱·비밀 제거·앱별 스냅샷을 테스트합니다.
왜 중요한가
문자열 false를 bool로 바꾸자 True가 됐다. 운영에서 디버그 응답이 켜졌고 상태 페이지에는 설정 딕셔너리 전체가 출력됐다. 환경변수는 문자열이므로 타입 선언만으로 안전한 값이 되지 않는다. 설정을 읽는 시점과 공개하는 범위도 애플리케이션 계약이다.
단계
1. /root/work/fa-config-lab/service.py에서 parse_bool(value)는 대소문자를 무시한 true 또는 false만 bool로 반환합니다. 공백이 붙거나 문자열이 아니면 ValueError입니다.
처음 한 번 준비하세요. 기존 파일은 덮어쓰지 않습니다.
mkdir -p /root/work/fa-config-labtest -e /root/work/fa-config-lab/service.py || cp /opt/fixtures/ten_labs/fa-config-lab/service.py /root/work/fa-config-lab/service.pycd /root/work/fa-config-lab2. /root/work/fa-config-lab/service.py에서 parse_port(value)는 ASCII 숫자만 있는 문자열을 int로 바꾸고 1~65535이면 반환합니다. 나머지는 ValueError입니다.
3. /root/work/fa-config-lab/service.py에서 parse_timeout(value)는 문자열을 float로 변환해 0보다 크고 30 이하인 유한 값만 반환합니다. 나머지는 ValueError입니다.
4. /root/work/fa-config-lab/service.py에서 required_token(env)는 TOKEN이 문자열이고 strip 후 비어 있지 않을 때 strip한 값을 반환합니다. 없거나 빈 값은 ValueError입니다.
5. /root/work/fa-config-lab/service.py에서 load_settings(env)는 service=env의 SERVICE 또는 누락 시 'api', debug=parse_bool(DEBUG 누락 시 'false'), port=parse_port(PORT 누락 시 '8000'), timeout=parse_timeout(TIMEOUT 누락 시 '5'), token=required_token인 딕셔너리입니다. 빈 SERVICE는 ValueError입니다.
6. /root/work/fa-config-lab/service.py에서 public_settings(settings)는 service와 debug만 가진 새 딕셔너리입니다. 원본은 수정하지 않습니다.
7. /root/work/fa-config-lab/service.py에서 snapshot(env)는 load_settings 결과를 반환합니다. 호출 후 env를 수정해도 반환된 설정은 바뀌지 않습니다.
8. /root/work/fa-config-lab/service.py에서 create_app(env)는 snapshot을 즉시 읽으며 잘못된 설정이면 ValueError로 앱 생성을 실패시킵니다. GET /info는 public_settings만 반환합니다. 다른 env로 만든 앱끼리 설정을 공유하지 않습니다.
참고
- 인터넷과 패키지 설치 없이 기존 lab-dev 환경에서 수행합니다.
- 각 단계는 45초 채점 예산 안에서 실행됩니다. 실제 sleep이나 네트워크 호출을 추가하지 마세요.
- 채점은 제출 모듈을 새로 불러오고 독립 입력과 임시 DB로 검사합니다. 예상값을 상수로 반환하는 대신 계약을 구현하세요.
- [FastAPI 공식 문서](https://fastapi.tiangolo.com/) · [pytest 공식 문서](https://docs.pytest.org/en/stable/) · [Python sqlite3](https://docs.python.org/3/library/sqlite3.html)
- 한계: 일반 딕셔너리로 환경을 주입하므로 실제 프로세스 전역 환경에 의존하지 않는다. 암호화된 비밀 저장소, 키 회전, 동적 재로딩까지 구현하는 예제는 아니다. 토큰 문자열은 학습용 입력이며 실제 운영 키를 실습 파드에 넣지 않는다.
8个步骤
- 불리언을 명시적으로 파싱한다
- 포트 범위를 검사한다
- 시간 제한을 유한 값으로 만든다
- 필수 비밀의 누락을 거절한다
- 누락에만 기본값을 적용한다
- 공개 설정에서 비밀을 제거한다
- 외부 변경과 설정을 분리한다
- 시작 실패와 공개 응답을 확인한다