Skip to main content

🚄 pykorail

파이썬으로 KTX 표를 조회하고 예매합니다

코레일 스마트 예매(코레일톡) API 를 감싼 비공식 클라이언트

CI PyPI Python License

빠른 시작 · 할 수 있는 것 · API 레퍼런스 · 기여하기


빠른 시작

pip install pykorail
from datetime import datetime
from pykorail import Korail

with Korail.logged_in("me@example.com", "password") as korail:
    trains = korail.trains.search("서울", "부산", depart_after=datetime(2026, 4, 1, 9, 0))
    for train in trains:
        print(train)
[KTX 101]  04/01 09:00~12:30  서울~부산  특실 가능, 일반실 가능 (3시간 30분)
[KTX 103]  04/01 10:00~13:30  서울~부산  특실 매진, 일반실 가능 (3시간 30분)
[KTX 105]  04/01 11:00~14:35  서울~부산  특실 가능, 일반실 매진 (3시간 35분)

[!WARNING] 코레일과 아무 관련 없는 비공식 라이브러리입니다. 문서화되지 않은 앱 API 를 쓰기 때문에 코레일이 앱을 바꾸면 예고 없이 멈출 수 있습니다. 이용 약관과 관련 법령을 지키는 것은 사용자 책임이며, 과도한 자동 요청은 계정 제재로 이어질 수 있습니다.


할 수 있는 것

표 예매하고 결제하기

from pykorail import AdultPassenger, Card, ChildPassenger

trains = korail.trains.search(
    "서울",
    "부산",
    depart_after=datetime(2026, 4, 1, 9, 0),
    passengers=[AdultPassenger(2), ChildPassenger(1)],
)

reservation = korail.reservations.create(trains[0])
print(reservation)
# [KTX 101] … 119600원(3석), 구입기한 4월 1일 09:20

korail.reservations.pay(
    reservation,
    Card(number="1234567812345678", password="12", verify_number="900101", expire="2812"),
)
취소표 기다리기
import time
from pykorail import NoResultsError, PastDepartureError

departure = datetime(2026, 4, 1, 9, 0)

while True:
    try:
        trains = korail.trains.search("서울", "부산", depart_after=departure)
    except NoResultsError:
        time.sleep(30)  # 서버에 부담 주지 않게 넉넉히 쉬세요
        continue
    except PastDepartureError:
        break  # 열차가 이미 떠났습니다 — 무한정 돌지 않도록

    korail.reservations.create(trains[0])
    break
매진일 때 예약대기 걸기
trains = korail.trains.search("서울", "부산", include_waiting_list=True)
waitable = [t for t in trains if not t.has_seat() and t.has_waiting_list()]

reservation = korail.reservations.create(waitable[0])
assert reservation.is_waiting
내 예약·승차권 보기
for reservation in korail.reservations.all():
    print(reservation.train.dep_name, "→", reservation.train.arr_name, reservation.price)

for ticket in korail.tickets.all():
    print(ticket.ticket_no, ticket.car_no, ticket.seat_no)
    korail.tickets.refund(ticket)  # 환불
기기 프로파일 고정하기 — 여러 번 실행한다면

실행할 때마다 다른 기기인 척하면 오히려 부자연스럽습니다. 한 번 뽑아 id 를 저장해 두고 계속 쓰세요.

from pykorail.device import profile_by_id, random_profile

profile = profile_by_id(saved_id) or random_profile()
korail = Korail(device_profile=profile)

알아두면 좋은 것

역은 이름으로 "서울역" 이 아니라 "서울". 오타면 요청 전에 막고 비슷한 역을 알려줍니다.
시각은 항상 KST datetime(2026, 4, 1, 9) 는 서버가 어느 타임존이든 한국시간 오전 9시.
지난 시각은 거부 서버가 과거에도 빈 결과만 줘서 "떠난 열차"와 "열차 없음"이 구분되지 않습니다.
실패는 예외로 cancel() · pay() 는 성공 시 아무것도 반환하지 않습니다.
from pykorail import KorailError, SoldOutError

try:
    korail.reservations.create(train)
except SoldOutError:
    ...  # 매진 — 다음 열차로
except KorailError as exc:
    print(exc.msg, exc.code)  # 코레일이 준 메시지와 코드

문서

📖 API 레퍼런스 전체 메서드 · 모델 · 옵션 · 예외
🤝 기여 가이드 개발 환경, 테스트 규칙, PR 절차
🏛 아키텍처 규약 계층 구조, 외부 API 불변식
🤖 에이전트 설정 Codex · Claude Code · Pi · Cursor · OpenCode
🔐 보안 정책 · 행동 강령

자주 묻는 것

로그인이 안 됩니다

설치할 때 경고가 떴다면 curl_cffi 대신 requests 로 돌고 있을 수 있습니다. 코레일은 TLS 지문을 보기 때문에 이때 로그인이 거부될 수 있습니다. pip install curl_cffi 로 해결되는 경우가 대부분입니다.

휴대폰 번호로 로그인한다면 하이픈을 넣어야 합니다 (010-1234-5678). 빠뜨리면 회원번호로 조회돼 엉뚱하게 실패합니다.

Windows 에서 설치가 안 됩니다

curl_cffi 의 libcurl DLL 로드가 실패하는 환경이 있습니다. pip install "pykorail[fallback]" 로 requests 폴백을 함께 설치하세요. 다만 위에 적은 이유로 로그인이 막힐 수 있습니다.

SRT 도 되나요?

아니요. SRT(수서고속철도)는 다른 회사의 다른 시스템입니다.

어제까지 되던 게 오늘 안 됩니다

코레일이 서버를 바꿨을 수 있습니다. API 변경 이슈 로 알려주시면 대응하겠습니다. 가장 도움이 되는 기여입니다.

예매가 확실히 되나요?

이 라이브러리는 앱과 같은 요청을 보낼 뿐이고, 좌석 배정은 코레일 서버가 합니다. 명절 예매처럼 경쟁이 심한 상황에서 성공을 보장하지 않습니다.


개발

파이썬 3.10 이상 (3.10 – 3.14 에서 테스트합니다).

uv sync --all-extras
uv run ruff format && uv run ruff check && uv run ty check && uv run pytest

네 개를 전부 통과해야 합니다. 커버리지 하한 90%, 현재 96%.

기여를 환영합니다 — CONTRIBUTING.md 부터 보세요. 새 엔드포인트는 공식 코레일톡+ APK 를 디컴파일해 경로와 폼 필드를 확인한 뒤에만 추가합니다.

릴리스

버전의 유일한 출처는 git 태그입니다. 파일을 손으로 고칠 필요가 없습니다.

git tag v0.2.0 && git push origin v0.2.0

태그를 밀면 전 버전 게이트 → 보안 스캔 → 빌드 → PyPI 업로드 → 릴리스 노트 생성이 자동으로 돕니다.


MIT License · 코레일과 무관한 비공식 프로젝트

Release files for pykorail 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pykorail 0.1.1
File Size Uploaded
pykorail-0.1.1.tar.gz 78.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pykorail 0.1.1
File Interpreter ABI Platform
pykorail-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 139.2 kB

Release files / pykorail-0.1.1.tar.gz

Download URL pykorail-0.1.1.tar.gz
Size 78.3 kB
Tags Source
SHA-256 checksum
How to use checksums
610f7278a8ac9a2a231d3da85a37de152f72539160f7ed39a05efad321429be4
BLAKE2b-256 checksum
How to use checksums
323ab70e4f823bbdc69342f630550f0e3bef53641f48c0d72c0c67656e74e1cb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release files / pykorail-0.1.1-py3-none-any.whl

Download URL pykorail-0.1.1-py3-none-any.whl
Size 60.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c4448717466d724d8201f64d4d69cf4e586a5a3990ac4f6f2bca4ebb9f5c854e
BLAKE2b-256 checksum
How to use checksums
46e15664c7390a9f9e8913c6b2196dbf1d5763cca42e66cdeb337fbd90147bc1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.2

2 release files

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page