콘텐츠로 이동

빠른 시작

전부 읽기입니다. 무엇도 만들지 않고 돈이 움직이지 않습니다.

from srt_mobile_api import PassengerCounts, SrtClient, TrainSearchQuery

client = SrtClient()
client.login("you@example.com", "password")   # 이메일·휴대폰번호·회원번호 중 하나

query = TrainSearchQuery(
    departure_station_code="0551",            # 수서
    arrival_station_code="0015",              # 동대구
    departure_date="20260809",                # YYYYMMDD
    departure_time="060000",                  # HHMMSS — 이 시각부터 검색
    passengers=PassengerCounts(adult=1),
)
for train in client.search_trains(query).trains:
    print(train.train_no, train.departure_time,
          train.general_seat_availability_name)          # 예: "예약가능"

for reservation in client.get_reservations().reservations:   # 없으면 빈 리스트
    print(reservation.pnr_no)

client.close()

역 코드는 srt_mobile_api.stations 에 있습니다. SrtClient() 는 설정 없이 동작합니다. SrtConfig 는 타임아웃·User-Agent·기기키용이며 app.srail.or.kr 와 NetFunnel 원점(nf.letskorail.com) 외의 주소는 거부합니다.

기기키 기본값은 ANDROID_ID 모양의 자리채움 값입니다. 실기기 값을 쓰려면 SRT_DEVICE_KEY 로 넘기고, 값은 adb shell settings get secure android_id 로 읽으면 됩니다. 안드로이드 8부터 이 값은 앱 서명키별로 갈리므로 adb shell 이 보는 것과 SRT 앱이 보는 것은 다릅니다 — 여기서 중요한 건 진짜냐가 아니라 실행 간에 안정적이냐입니다.

타입이 좁혀진 파라미터

셋은 export 된 Literal 별칭이라 오타가 타입 오류가 됩니다. 응답에서 읽어 온 코드는 좁히지 않고 str 그대로 둡니다.

별칭
SrtSeatAttrCode "015", "021", "028"
SrtTrainGroupCode "300", "900", "109"
MutationCategory reserve, cancel, payment, refund, coupon
korail-mobile-api 와 같이 쓸 때 `TrainSearchQuery`, `DiscountCoupon`, `MutationCategory` 는 두 패키지가 각자 export 하는데 호환되지 않습니다. `passengers` 는 여기가 `PassengerCounts`, KORAIL 이 `int` 이고, `departure_time` 기본값도 `"060000"` 대 `"000000"` 으로 다릅니다. 잘못 import 해도 타입 검사는 통과하고 요청만 틀리게 만들어집니다. 둘 다 쓴다면 `srt_mobile_api.TrainSearchQuery` 처럼 패키지를 붙이세요.

무엇을 할 수 있나

전부 SrtClient 의 메서드이고, 각 docstring 이 근거(APK 파일·행 번호 또는 실 응답)를 답니다.

읽기 — 동의가 필요 없습니다

메서드 하는 일
login / logout / clear_session / close 앱과 같은 순서의 로그인, 세션 종료, 로컬 상태 폐기, 연결 종료
search_trains / search_group_trains / search_transfer_trains / search_public_discount_trains 직통·단체(10명 이상)·환승·공공할인 조회
iter_train_search_pages(query, group=False, max_pages=10) 조회의 지연 페이지네이션. 커서가 끊기면 멈춥니다
get_timetable / get_fare / get_seat_page / get_seat_grid 정차역, 좌석 등급별 운임(여정 한 다리), 남은 호차, 좌석배치도
get_reservations / get_ticket_list / get_discount_coupons / get_public_discounts 예약 목록(타입이 붙은 유일한 읽기), 승차권 페이지, 보유 쿠폰, 승인받은 공공할인 자격
get_typed_notice_list / get_notice_list / get_main / get_station_selector 공지(파싱본·원본)와 앱이 밟는 페이지·팝업 선택 화면들

키워드로 넘겨야 하고, 기본 dry_run=True 에서는 MutationPreview 만 돌려줍니다. 아래 안전 모델 절을 먼저 읽어야 합니다.

메서드 하는 일
reserve(train, consent=...) 개인예약. 미결제 홀드와 PNR. 선택 인자로 standby=True(예약대기 jobId=1102), round_trip=True(왕복 rtnDv=1), designated_seats=(좌석지정 jobId=1103), seat_attr_code=
reserve_transfer(itinerary, ...) 환승. 요청 하나에 두 여정
cancel(hold_or_pnr, ...) 미결제 홀드 해제. 맨 PNR 로 취소할 때만 journey_count 를 직접 줍니다
pay_with_card(reservation, card, ...) 신용카드 결제. 동의 외에 카드 종류 주장이 하나 더 필요합니다
get_refund_ticket_info(pnr)refund(ticket_info, ...) 환불. 앞은 읽기, 뒤가 상태변경입니다
register_discount_coupon(number, password, ...) 쿠폰 등록. 미리보기까지만 됩니다

맞지 않는 조합(예약대기를 제공하지 않는 행, 인원과 다른 좌석 수, 코레일 전용역이 낀 왕복)은 전송 전에 ValueError 로 막습니다.