2장. 개발 환경 준비
키를 코드에 적지 않는 까닭
거래처 출입증을 가게 벽에 붙여 두면 편합니다. 꺼낼 필요가 없으니까요. 그런데 손님도, 배달 기사도, 가게 사진을 찍은 사람도 그 출입증을 봅니다. 누군가 사진으로 출입증을 본떠 거래처에서 물건을 가져가면 청구서는 우리 가게로 옵니다. 그래서 출입증은 지갑에 넣어 둡니다. API 키를 코드에 그대로 적는 것이 벽에 붙이는 일이고, .env 파일에 따로 두는 것이 지갑에 넣는 일입니다.
왼쪽 파랑 상자는 키를 코드에 적었을 때, 오른쪽 보라 상자는 .env 에 두었을 때입니다. 코드 파일은 과제로 내고, 친구에게 보내고, 깃허브(GitHub, 코드를 올려 나누는 누리집)에 올리는 파일입니다. 키가 그 안에 있으면 파일이 가는 곳마다 키도 갑니다. 여기서 가게 벽이 코드 파일, 지갑이 .env, 지갑을 가게 밖으로 들고 나가지 않게 하는 규칙이 .gitignore 입니다. 비유와 다른 점은, 출입증은 떼어 내면 그만이지만 깃허브에 한 번 올린 키는 지워도 예전 기록에 남는다는 것입니다.
코드에 적으면 생기는 일
| 장면 | 생기는 일 |
|---|---|
| 과제 파일을 메일로 낸다 | 받는 사람이 키를 본다 |
| 깃허브에 올린다 | 누구나 검색으로 찾을 수 있다. 지워도 이전 기록에 남는다 |
| 화면 공유로 코드를 보여 준다 | 화면을 본 사람과 녹화본에 키가 남는다 |
| 키를 바꿔야 한다 | 키를 적은 파일을 모두 찾아 고쳐야 한다 |
짧은 예시
남에게 코드를 보내기 전에 키처럼 보이는 글자가 들어 있는지 찾아보는 작은 검사기입니다. re 는 regular expression(정규 표현식, 글자의 꼴을 기호로 적는 방법)을 쓰는 파이썬의 묶음입니다. 예시의 키는 0 을 늘어놓아 지어낸 시험용 글자입니다.
import re
# 검사할 코드 글. 둘째 줄에 키를 그대로 적은 나쁜 예가 있다
code = '''from openai import OpenAI
client = OpenAI(api_key="sk-test-0000000000000000")
print("안녕")'''
# "sk-" 로 시작하고 영문·숫자·빼기·밑줄이 16개 넘게 이어지는 꼴. {16,} = 16번 이상
pattern = re.compile(r"sk-[A-Za-z0-9_-]{16,}")
for no, line in enumerate(code.splitlines(), start=1):
# search: 줄 안 어디에든 그 꼴이 있으면 찾은 결과를, 없으면 None 을 돌려준다
if pattern.search(line):
print(f"{no}번째 줄에 키처럼 보이는 글자가 있습니다")2번째 줄에 키처럼 보이는 글자가 있습니다이 검사기는 "sk- 로 시작하는 긴 글자"라는 꼴만 봅니다. 키의 꼴이 바뀌면 놓칠 수 있으니 습관을 대신하지는 못합니다. 처음부터 코드에 적지 않는 것이 가장 확실합니다.
코드가 의미하는 것
이 코드는 가게 사진을 올리기 전에 벽에 출입증이 붙어 있지 않은지 훑어보는 일입니다. 키의 꼴을 정하고, 코드를 줄마다 나눠, 그 꼴이 있는 줄 번호를 찍습니다.
| 코드 | 하는 일 | 챗봇에서 뜻하는 것 |
|---|---|---|
re.compile(r"sk-[A-Za-z0-9_-]{16,}") | "sk- 뒤에 16글자 넘게 이어지는 글자"라는 꼴을 만든다 | 키처럼 생긴 글자를 찾는 그물입니다. 진짜 키인지는 모르고 생김새만 봅니다 |
code.splitlines() | 글을 줄마다 나눈다 | 어느 줄에 키가 있는지 알려 주려고 줄 단위로 봅니다 |
enumerate(..., start=1) | 줄마다 1부터 번호를 붙인다 | 편집기의 줄 번호와 같게 맞춰 고칠 곳을 바로 찾게 합니다 |
pattern.search(line) | 줄 안 어디든 그 꼴이 있는지 찾는다 | OpenAI(api_key="…") 처럼 줄 중간에 끼어 있는 키도 잡습니다 |
결과에서 읽을 것은 두 가지입니다.
- 2번째 줄만 걸렸습니다.
OpenAI(api_key=...)로 키를 코드에 직접 적은 줄입니다. 이 장의 실습은 이 자리를 비워 두고 환경 변수에서 키를 읽게 합니다. - 찾은 글자는 찍지 않습니다. 검사기는 줄 번호만 알리고 키 자체는 화면에 내지 않습니다. 키를 찾는 도구가 키를 퍼뜨리면 안 되기 때문입니다.