on
키움 REST API로 나만의 주식툴 만들기 1편: 접근 토큰(Access Token) 자동 발급 및 관리
안녕하세요! 이번 포스팅부터는 파이썬(Python)과 키움증권 REST API를 활용하여 저만의 맞춤형 주식 분석 툴을 만들어가는 과정을 연재합니다. 그 첫걸음으로, API 통신의 핵심이자 가장 먼저 해결해야 할 접근 토큰(Access Token) 자동 발급 및 관리 모듈을 만들어 보겠습니다.
우리가 궁극적으로 만들게 될 프로그램은 주식 차트, 보조지표, 외국인/기관 수급, 그리고 실시간 웹 검색을 결합한 AI 챗봇까지 포함된 통합 주식 대시보드입니다. 매번 수동으로 토큰을 발급받는 것은 번거로우므로, 파이썬 스크립트를 통해 자동으로 토큰을 발급받고 영리하게 관리하는 get_token.py를 작성해 보겠습니다.
들어가며
깃허브 블로그를 만든지 벌써 4년이나 시간이 흘렀습니다. 연구실 생활로 바쁘다 보니 매번 간헐적으로 글을 썼다 지웠다를 반복했었는데요. 과거에 작성했던 글들을 봐준 분들이 꽤 있었는데 블로그를 정리할 때마다 과거의 포스팅에서 부족한 점들도 많이 보이고 결과적으로 마무리를 짓지 못한 글들도 많아 아쉬움이 많이 남네요 😭😭
이번에는 마음을 먹고 복잡하게 꼬여 있던 HTML과 CSS 코드들을 고치고 테마를 엎은 건 아니지만 사소한 디자인도 많이 고쳤습니다. 앞으로는 주식, 기술과 관련된 글이나 제 전공인 ASIC 설계와 관련된 글들을 블로그에 남겨 보려고 합니다. 사실 대부분의 블로그 게시글은 제가 아니라 AI가 대신 작성하겠지만요 😅😅
사설은 이 정도로 끝내도록 하겠습니다! 앞으로 몇 편의 시리즈를 통해 최종적으로 우리가 완성할 차트툴의 실행화면은 Figure 1과 같습니다. KOSPI/KODAQ 지수, 개별 종목의 차트 및 기관/개인/외국인의 기간별 누적 순매수 및 외국인 지분율(%) 등을 구할 것이고, 크롬 드라이버를 통해 개별 종목의 실적, 컨센서스 등을 파악하고 마켓맵을 연동하도록 할 것입니다. 또한, Openrouter의 API 키를 발급받아 Free 모델의 성능을 극복하기 위하여 Dukdukgo의 검색결과를 이용하고, 사용자와의 대화내용을 db화 하는 방법을 탐색할 것입니다.
차트 엔진을 가속하기 위해선 C++를 기반으로 하는 Qt같은 툴을 이용하여 설계하는 것이 더 바람직하지만 저는 스윙 매매를 위해 이 툴을 제작하고 있기 때문에 구현이 간단하고 AI를 적극 활용하여 바이브 코딩만으로도 쉽게 구현 가능한 Pyside6를 바탕으로 UI를 구현하였습니다. 이 시리즈를 통해 기본적인 차트툴의 뼈대를 완성하고, 각자 원하는 매매전략을 더함으로써 나만의 차트툴을 만들어 보도록 합시다 🔥🔥
1. 사전 준비: 환경 변수(.env) 설정
키움증권 REST API 포털의 절차에 따라서 계좌를 개설하고, App Key와 Secret Key를 발급해 주세요. 2개의 텍스트 파일을 다운받을 수 있게 되는데 이 키들은 외부에 유출되면 안 되는 중요한 정보이므로, 코드 내부에 직접 적지 않고 .env 파일에 저장하여 불러오는 방식을 사용하겠습니다.
프로젝트 폴더 최상단에 .env 파일을 만들고 아래와 같이 입력해 줍니다. 텍스트 파일의 내용을 그대로 복사해서 붙여 넣으면 됩니다.
KIWOOM_APP_KEY=여러분의_앱_키를_입력하세요
KIWOOM_SECRET_KEY=여러분의_시크릿_키를_입력하세요
KIWOOM_ACCESS_TOKEN=
KIWOOM_TOKEN_EXPIRED=
KIWOOM_ACCESS_TOKEN과 KIWOOM_TOKEN_EXPIRED는 앞으로 파이썬 코드가 알아서 채워 넣을 공간입니다. 이를 위해 python-dotenv 라이브러리가 필요하니 설치해 줍니다.
pip install python-dotenv requests
2. .env 파일을 업데이트하는 헬퍼 함수 만들기
발급받은 토큰을 매번 메모리에만 들고 있으면, 프로그램을 껐다 켤 때마다 새로 토큰을 발급받아야 합니다. 이를 방지하기 위해 발급된 토큰을 .env 파일에 덮어써서 영구적으로 보관해 주는 함수를 먼저 작성합니다.
import os
def update_env_file(key, value):
"""
.env 파일의 특정 키 값을 업데이트하는 함수
"""
env_path = '.env'
# 1. 파일이 없으면 새로 생성
if not os.path.exists(env_path):
with open(env_path, 'w', encoding='utf-8') as file:
file.write(f'{key}={value}\n')
return
# 2. 기존 파일 읽기
with open(env_path, 'r', encoding='utf-8') as file:
lines = file.readlines()
# 3. 해당 키를 찾아 업데이트
updated = False
for i, line in enumerate(lines):
if line.startswith(f'{key}='):
lines[i] = f'{key}={value}\n'
updated = True
break
# 4. 키가 없었다면 마지막줄에 추가
if not updated:
lines.append(f'{key}={value}\n')
# 5. 파일에 쓰기
with open(env_path, 'w', encoding='utf-8') as file:
lines = [line if line.endswith('\n') else line + '\n' for line in lines]
file.writelines(lines)
이 함수를 이용하면 파이썬 코드 내에서 update_env_file('KIWOOM_ACCESS_TOKEN', '토큰값') 형태로 간편하게 .env 파일을 조작할 수 있습니다.
3. 스마트한 토큰 재사용 로직
기본적으로 국내 주식의 경우 초당 5회의 API 호출이 가능합니다. 그런데, 모든 API는 토큰을 전제로 하기 때문에 API 호출을 하기 위해서 토큰을 계속해서 발급 받으면 호출 횟수가 상당히 제한될 수밖에 없습니다. 키움증권의 접근 토큰은 발급 후 24시간 동안 유효하므로 기존에 발급받은 토큰이 아직 유효하다면 그대로 재사용하는 로직이 효율적입니다.
get_access_token 함수의 앞부분에 이 로직을 작성해 줍니다.
import requests
import json
from datetime import datetime, timedelta
from dotenv import load_dotenv
def get_access_token():
# .env 파일 로드
load_dotenv(override=True)
existing_token = os.getenv('KIWOOM_ACCESS_TOKEN')
token_expired = os.getenv('KIWOOM_TOKEN_EXPIRED')
# 토큰이 존재하고 만료 기한이 남았다면 API 호출 생략 (스마트 캐싱)
if existing_token and token_expired:
try:
expire_time = datetime.strptime(token_expired.strip(), '%Y-%m-%d %H:%M:%S')
if datetime.now() < expire_time:
print(f"✅ 유효한 기존 접근 토큰이 존재합니다. (만료 일시: {expire_time})")
return existing_token
except Exception:
pass # 파싱에 실패하면 안전하게 새로 발급 진행
print("🔄 유효한 토큰이 없어 새로 발급을 요청합니다...")
4. 키움 API 서버로 발급 요청하기
이제 기존 토큰이 만료되었거나 없을 때, 실제로 키움 서버에 통신하여 새로운 토큰을 발급받는 메인 통신부입니다.
# (위 코드에 이어서 작성)
# 실전투자 API URL
url = '[https://api.kiwoom.com/oauth2/token](https://api.kiwoom.com/oauth2/token)'
# 환경변수에서 키 가져오기
app_key = os.getenv('KIWOOM_APP_KEY')
secret_key = os.getenv('KIWOOM_SECRET_KEY')
# 요청 데이터(Body) 및 헤더(Header) 설정
data = {
'grant_type': 'client_credentials',
'appkey': app_key,
'secretkey': secret_key,
}
headers = {
'Content-Type': 'application/json;charset=UTF-8',
}
# POST 요청 보내기
response = requests.post(url, headers=headers, json=data)
result = response.json()
# 토큰 발급 성공 여부 체크
if result.get('return_code') == 0:
token = result.get('token')
print('\n✅ 토큰 발급 성공!')
# 유효기간(24시간)을 고려하여 넉넉히 23시간 후로 만료 시각 지정
expire_dt = datetime.now() + timedelta(hours=23)
expire_str = expire_dt.strftime('%Y-%m-%d %H:%M:%S')
# .env 파일에 토큰 및 만료 시간 업데이트
update_env_file('KIWOOM_ACCESS_TOKEN', token)
update_env_file('KIWOOM_TOKEN_EXPIRED', expire_str)
print(f'📝 .env 파일 업데이트 완료! (만료 일시: {expire_str})\n')
return token
else:
print(f'\n❌ 토큰 발급 실패: {result.get("return_msg")}')
return None
if __name__ == '__main__':
get_access_token()
여기서 포인트는 서버에서 제시하는 24시간을 꽉 채우지 않고, 혹시 모를 오차를 위해 23시간(timedelta(hours=23)) 후를 만료 시각으로 설정하여 .env에 저장한다는 점입니다. 이를 통해 서비스 중간에 토큰이 만료되어 API 통신이 끊기는 불상사를 예방할 수 있습니다. 이건 실시간으로 계속해서 매매를 수행해야 하는 프로그램을 위한 예방책입니다.
python get_token.py
✅ 토큰 발급 성공!, 📝 .env 파일 업데이트 완료!를 보게 되면 성공적으로 토큰 발행이 수행된 것입니다. 한 번 더 실행하게 되면, ✅ 유효한 기존 접근 토큰이 존재합니다. 문구를 보게 될 것입니다.
마무리
이렇게 해서 키움 REST API 통신의 가장 기본이 되는 인증 모듈(get_token.py)을 완성했습니다. 한 번 발급받은 토큰은 .env 파일에 기록해 두고 23시간 동안 영리하게 재사용하므로, 앞으로 개발할 차트나 챗봇 스크립트 어디서든 get_access_token() 함수만 호출하면 걱정 없이 최신의 토큰을 불러올 수 있습니다.
다음 2편에서는 방금 만든 토큰을 이용해 코스피/코스닥 전 종목 리스트를 받아오는 방법에 대해 알아보겠습니다.
궁금한 점이 있다면 언제든 아래 댓글로 남겨주세요!