Skip to main content

概要

ipathelper は、JRA(日本中央競馬会)のインターネット投票サービス「I-PAT」および地方競馬の投票システムに対して、 ログイン・入出金・馬券購入・購入履歴取得などを Python から行うためのラッパーライブラリです。

  • 中央競馬・地方競馬・海外競馬・WIN5 に対応

  • Windows 32bit / 64bit 環境で動作

GitHub では Python 以外の利用例も公開しています。 詳細な関数仕様については 関数仕様書 を参照してください。

インストール方法

$ pip install ipathelper

動作環境

  • OS: Windows 10 以降(32bit / 64bit)

  • Python: 3.12 以上

共通仕様

戻り値

全関数(None を返すものを除く)は int をビットフラグとして返します。 複数のフラグが同時に立つ場合があります。判定には AND 演算を使用してください。

ret = bet(bet_data_list, 1, 0)

if (ret & 1) == 1:    # SUCCESS
    print("成功")
if (ret & 4) == 4:    # FAILED_CHUOU
    print("中央競馬で失敗")

戻り値ビットフラグ一覧:

定数名

ビット

意味

RETURN_SUCCESS

1

処理に成功

RETURN_UNSUCCESS

2

処理に失敗(パラメータ不正・残高不足等)

RETURN_FAILED_CHUOU

4

中央競馬での処理に失敗

RETURN_FAILED_CHIHOU

8

地方競馬での処理に失敗

RETURN_FAILED_COM_CHUOU

16

中央競馬との通信に失敗

RETURN_FAILED_COM_CHIHOU

32

地方競馬との通信に失敗

スレッドセーフ

全関数は内部で排他制御されています。複数スレッドからの同時呼び出しは安全ですが、 関数はブロッキング動作となります。

前提条件

bet ・ deposit ・ withdraw ・ get_purchase_data などの関数は、 事前に login() が成功している必要があります。 未ログイン状態での呼び出しは RETURN_UNSUCCESS を返します。

定数一覧

開催場(KAISAI)

中央競馬:

定数名

開催場

KAISAI_SAPPORO

札幌

KAISAI_HAKODATE

函館

KAISAI_FUKUSHIMA

福島

KAISAI_NIIGATA

新潟

KAISAI_TOKYO

東京

KAISAI_NAKAYAMA

中山

KAISAI_CHUKYO

中京

KAISAI_KYOTO

京都

KAISAI_HANSHIN

阪神

KAISAI_KOKURA

小倉

地方競馬:

定数名

開催場

KAISAI_SONODA

園田

KAISAI_HIMEJI

姫路

KAISAI_NAGOYA

名古屋

KAISAI_MONBETSU

門別

KAISAI_MORIOKA

盛岡

KAISAI_MIZUSAWA

水沢

KAISAI_URAWA

浦和

KAISAI_FUNABASHI

船橋

KAISAI_OI

大井

KAISAI_KAWASAKI

川崎

KAISAI_KASAMATSU

笠松

KAISAI_KANAZAWA

金沢

KAISAI_KOCHI

高知

KAISAI_SAGA

佐賀

海外競馬:

定数名

開催場

KAISAI_LONGCHAMP

ロンシャン(フランス)

KAISAI_SHATIN

シャティン(香港)

KAISAI_SANTAANITA

サンタアニタ(アメリカ)

KAISAI_DEAUVILLE

ドーヴィル(フランス)

KAISAI_CHURCHILLDOWNS

チャーチルダウンズ(アメリカ)

KAISAI_ABDULAZIZ

キングアブドゥルアジーズ(サウジアラビア)

式別(SHIKIBETSU)

定数名

式別

SHIKIBETSU_WIN

単勝

SHIKIBETSU_PLACE

複勝

SHIKIBETSU_BRACKETQUINELLA

枠連

SHIKIBETSU_QUINELLAPLACE

ワイド

SHIKIBETSU_QUINELLA

馬連

SHIKIBETSU_EXACTA

馬単

SHIKIBETSU_TRIO

三連複

SHIKIBETSU_TRIFECTA

三連単

方式(HOUSHIKI)

定数名

方式

HOUSHIKI_NORMAL

通常

HOUSHIKI_FORMATION

フォーメーション

HOUSHIKI_BOX

ボックス

確定フラグ(DECISIONFLAG)

定数名

意味

DECISIONFLAG_DEFAULT

デフォルト

DECISIONFLAG_NORMAL

通常確定

DECISIONFLAG_DEADLINE

発売締切

DECISIONFLAG_CANCEL

キャンセル

DECISIONFLAG_FLATMATESCANCEL

仲間入力取消

DECISIONFLAG_HIT

的中

DECISIONFLAG_MISS

外れ

DECISIONFLAG_BACK

返還

DECISIONFLAG_PARTCANCEL

一部取消

DECISIONFLAG_INVALID

無効

DECISIONFLAG_SALECANCEL

発売取消

データ構造

ST_BET_DATA

get_bet_instance() で設定し、 bet() に渡す購入情報です。 フィールドを直接参照することで購入内容を確認できます。

betData = ST_BET_DATA()
get_bet_instance(KAISAI_TOKYO, 11, 2026, 4, 5,
                 HOUSHIKI_NORMAL, SHIKIBETSU_WIN, 100, "1", betData)

print(betData.TotalAmount)  # 合計購入金額(円)

フィールド名

型

説明

TotalAmount

int

合計購入金額(get_bet_instance が自動計算)

ST_BET_DATA_WIN5

get_bet_instance_win5() で設定し、 bet_win5() に渡す WIN5 専用の購入情報です。

ST_PURCHASE_DATA

get_purchase_data() が設定するルート構造体です。 使用後は必ず release_purchase_data() で解放してください。

フィールド名

型

説明

AvailableBetCount

int

残購入可能件数

Balance

int

現在残高(円)

DayPurchase

int

当日累計購入金額(円)

DayHaraimodosi

int

当日累計払戻金額(円)

TotalPurchase

int

合計購入金額(円)

TotalHaraimodosi

int

合計払戻金額(円)

TicketCount

int

馬券情報の件数

TicketData

array

馬券情報の配列(下記参照)

TicketData の各要素(ST_TICKET_DATA):

フィールド名

型

説明

DayFlag

int

購入日(1:当日 / 2:前日)

ReceiptNo

int

受付番号

Hour

int

購入時刻(時)

Minute

int

購入時刻(分)

Kingaku

int

購入金額(円)

Payout

int

払戻金額(円)

DetailCount

int

詳細情報の件数

DetailData

array

詳細情報の配列(下記参照)

DetailData の各要素(ST_TICKET_DATA_DETAIL):

フィールド名

型

説明

DecisionFlag

int

確定フラグ(DECISIONFLAG 定数)

Kaisai

int

開催場(KAISAI 定数)

RaceNo

int

レース番号

Method

int

方式(HOUSHIKI 定数)

Type

int

式別(SHIKIBETSU 定数)

Multi

int

マルチ購入フラグ(1: マルチあり)

関数リファレンス

login

I-PAT へログインします。中央競馬と地方競馬の両方へログインを試みます。

ret = login(inet_id, id, password, pars)

引数

型

説明

inet_id

str

I-NET ID

id

str

ログイン ID

password

str

パスワード

pars

str

P-ARS 番号

戻り値パターン:

状態

返るフラグ

両方成功

SUCCESS

中央のみ失敗

SUCCESS | FAILED_CHUOU

地方のみ失敗

SUCCESS | FAILED_CHIHOU

両方失敗

FAILED_CHUOU | FAILED_CHIHOU

既ログイン

UNSUCCESS

logout

I-PAT からログアウトします。自動入金設定もリセットされます。

ret = logout()  # -> int
  • ログアウト後、再度 login() を呼び出すまで他の関数は使用できません。

deposit

登録口座から I-PAT 残高へ入金します。

ret = deposit(amount, retry_count=10)

引数

型

説明

amount

int

入金額(円)。100円以上かつ100円単位。

retry_count

int

通信失敗時のリトライ回数。デフォルト: 10回。

withdraw

I-PAT 残高を登録口座へ全額出金します。

ret = withdraw(retry_count=10)

引数

型

説明

retry_count

int

通信失敗時のリトライ回数。デフォルト: 10回。

  • 出金額の指定は不要です。残高の全額が出金対象となります。

set_auto_deposit_flag

馬券購入前の残高不足時に自動で入金を行う機能を設定します。 有効化すると bet() / bet_win5() 実行時に残高不足が検出された場合、自動的に入金してから購入を行います。

ret = set_auto_deposit_flag(enable, deposit_value=1000, confirm_timeout=10000)

引数

型

説明

enable

bool

True で有効化、False で無効化

deposit_value

int

自動入金額(円)。デフォルト: 1,000円

confirm_timeout

int

入金反映確認タイムアウト(ms)。デフォルト: 10秒

  • logout() を呼び出すと設定はリセットされます。

get_bet_instance

買い目文字列を解析し、 bet() に渡す``ST_BET_DATA`` を構築します。

betData = ST_BET_DATA()
ret = get_bet_instance(place, race_no, year, month, day,
                       houshiki, shikibetsu, kingaku, kaime, betData)

引数

型

説明

place

int

開催場(KAISAI 定数)

race_no

int

レース番号

year

int

開催年(西暦 4桁)

month

int

開催月(1〜12)

day

int

開催日(1〜31)

houshiki

int

方式(HOUSHIKI 定数)

shikibetsu

int

式別(SHIKIBETSU 定数)

kingaku

int

1点あたりの購入金額(円、100円単位)

kaime

str

買い目文字列(書式は後述)

betData

[out] ST_BET_DATA インスタンス

成功すると betData.TotalAmount に合計購入金額が格納されます。

買い目文字列の書式

  • 列の区切り: - (ハイフン)

  • 同一列内の複数馬番の区切り: , (カンマ)

単勝 1番               -> "1"
馬連 通常 1-5          -> "1-5"
馬単 通常 3-7          -> "3-7"
三連複 通常 2-5-8      -> "2-5-8"
三連単 通常 1-3-5      -> "1-3-5"

馬連 フォーメーション 1・2番 vs 3・4・5番                  -> "1,2-3,4,5"
三連複 フォーメーション 軸1番/相手A2・3番/相手B4・5・6番    -> "1-2,3-4,5,6"
三連単 フォーメーション 1着1番/2着2・3番/3着4・5番          -> "1-2,3-4,5"

馬連 ボックス 1・2・3・4番(6点)  -> "1,2,3,4"
三連単 ボックス 1・2・3番(6点)   -> "1,2,3"

bet

get_bet_instance() で構築した ST_BET_DATA の配列を一括購入します。 開催場に応じて中央・地方・海外に自動で振り分けられます。

betDataList = (ST_BET_DATA * n)()
betDataList[0] = betData
ret = bet(betDataList, n, wait_ms=500)

引数

型

説明

betDataList

ST_BET_DATA の配列((ST_BET_DATA * n)() で作成)

n

int

配列の要素数

wait_ms

int

購入リクエスト間隔(ms)。デフォルト: 500ms

get_bet_instance_win5

WIN5 の買い目文字列を解析し、 bet_win5() に渡す``ST_BET_DATA_WIN5`` を構築します。

betDataWin5 = ST_BET_DATA_WIN5()
ret = get_bet_instance_win5(kingaku, year, month, day, kaime, betDataWin5)

引数

型

説明

kingaku

int

1組み合わせあたりの購入金額(円、100円単位)

year

int

開催年(西暦 4桁)

month

int

開催月(1〜12)

day

int

開催日(1〜31)

kaime

str

5レース分の買い目(- でレース区切り)

betDataWin5

[out] ST_BET_DATA_WIN5 インスタンス

WIN5 の買い目文字列は必ず 5レース分 を``-`` で区切って指定してください。

各レース1頭ずつ              -> "1-2-3-4-5"
一部のレースで複数頭指定     -> "1,2-3-4,5-6-7,8"

bet_win5

get_bet_instance_win5() で構築した ST_BET_DATA_WIN5 を使って WIN5 を購入します。

ret = bet_win5(betDataWin5, wait_ms=500)

引数

型

説明

betDataWin5

ST_BET_DATA_WIN5 インスタンス

wait_ms

int

購入リクエスト間隔(ms)。デフォルト: 500ms

get_purchase_data

当日・前日の馬券購入履歴(残高・累計金額・購入済み馬券一覧)を取得します。

purchaseData = ST_PURCHASE_DATA()
ret = get_purchase_data(purchaseData)
if (ret & 1) == 1:
    print(f"残高: {purchaseData.Balance} 円")
    for i in range(purchaseData.TicketCount):
        ticket = purchaseData.TicketData[i]
        print(f"受付No.{ticket.ReceiptNo} {ticket.Hour:02d}:{ticket.Minute:02d} {ticket.Kingaku}円")

get_odds

指定レース・式別のオッズを取得します(中央競馬・地方競馬に対応)。 単勝・複勝は基本オッズ、枠連〜三連単は全通りのオッズ表を取得します。

oddsData = ST_ODDS_DATA()
ret = get_odds(place, race_no, shikibetsu, oddsData)

引数

型

説明

place

int

開催場(KAISAI 定数)

race_no

int

レース番号

shikibetsu

int

式別(SHIKIBETSU 定数)

oddsData

[out] ST_ODDS_DATA インスタンス

  • ネイティブ側のメモリは関数内部で自動解放されます。利用者側での解放は不要です。

  • オッズは 10 倍の整数(Odds)で格納されます。実際の倍率は Odds / 10.0。

  • 複勝・ワイドは下限を Odds、上限を OddsHigh に格納します。

  • Status が 1(発売中止)/2(オッズ未取得)の場合、Odds / OddsHigh は 0 です。

  • 海外開催・当日非開催の場合は UNSUCCESS を返します。

oddsData.OddsDetail の各要素(ST_ODDS_DETAIL):

フィールド名

説明

Type

式別(SHIKIBETSU 定数)

Horse1 / Horse2 / Horse3

馬番/枠番(単複は1頭、馬連・ワイド・馬単・枠連は2頭、三連系は3頭)

Status

0:通常 1:発売中止 2:オッズ未取得

Odds / OddsHigh

オッズ×10(複勝・ワイドは下限/上限)

oddsData = ST_ODDS_DATA()
ret = get_odds(KAISAI_TOKYO, 11, SHIKIBETSU_QUINELLA, oddsData)
if (ret & 1) == 1:
    print(f"オッズ更新時刻: {oddsData.OddsTime} / 明細数: {oddsData.DetailCount}")
    for d in oddsData.OddsDetail:
        kaime = str(d.Horse1)
        if d.Horse2:
            kaime += "-" + str(d.Horse2)
        if d.Horse3:
            kaime += "-" + str(d.Horse3)
        odds = f"{d.Odds / 10.0:.1f}" if d.Status == 0 else "-"
        print(f"  {kaime} : {odds}")

get_race_card

指定レースの出馬表(出走馬一覧)を取得します(中央競馬・地方競馬に対応)。 各出走馬の枠番・馬番・馬名・性齢・馬体重・騎手・斤量・調教師・単勝人気・単勝/複勝オッズを取得します。

raceCard = ST_RACECARD_DATA()
ret = get_race_card(place, race_no, raceCard)
  • ネイティブ側のメモリは関数内部で自動解放されます。利用者側での解放は不要です。

  • raceCard.EntryData の各要素は ST_ENTRY_DETAIL です。

  • 馬名・騎手名・調教師名などの文字列フィールドは UTF-8 の bytes です。利用時は .decode('utf-8') してください。

  • 斤量・オッズは 10 倍の整数で格納されます。実際の値は / 10.0。

raceCard.EntryData の各要素(ST_ENTRY_DETAIL):

フィールド名

説明

Wakuban / Umaban

枠番 / 馬番

HorseName / Sex / Age

馬名(bytes) / 性別(bytes) / 年齢

WeightStatus / Weight / WeightDiffCode / WeightDiff

馬体重の状態(0:通常 1:未発表 2:出走取消 3:計量不能) / 重量(kg) / 増減符号 / 増減量

Apprentice

見習騎手コード(0:なし 1〜5:減量 9:女性騎手2kg減)

JockeyName / Burden / TrainerName

騎手名(bytes) / 斤量×10 / 調教師名(bytes)

WinPopular

単勝人気(0:データなし)

WinOddsStatus / WinOdds

単勝オッズの状態(0:通常 1:発売中止 2:未取得) / オッズ×10

PlaceOddsStatus / PlaceOddsLow / PlaceOddsHigh

複勝オッズの状態 / 下限×10 / 上限×10

raceCard = ST_RACECARD_DATA()
ret = get_race_card(KAISAI_TOKYO, 11, raceCard)
if (ret & 1) == 1:
    print(f"オッズ更新時刻: {raceCard.OddsTime} / 出走頭数: {raceCard.EntryCount}")
    for e in raceCard.EntryData:
        name = e.HorseName.decode('utf-8')
        sex = e.Sex.decode('utf-8')
        jockey = e.JockeyName.decode('utf-8')
        win = f"{e.WinOdds / 10.0:.1f}" if e.WinOddsStatus == 0 else "-"
        print(f"  {e.Umaban:2d}番 {name} {sex}{e.Age} "
              f"斤量{e.Burden / 10.0:.1f} 騎手:{jockey} 単勝:{win} 人気:{e.WinPopular}")

get_notice

現在有効なお知らせを取得します(中央競馬・地方競馬に対応)。 強制表示お知らせ本文(Message)に加え、お知らせ一覧(ItemData)を全件取得します。

notice = ST_NOTICE_DATA()
ret = get_notice(notice)
  • ネイティブ側のメモリは関数内部で自動解放されます。利用者側での解放は不要です。

  • notice.ItemData の各要素は ST_NOTICE_ITEM です。

  • Title / Date / Url などの文字列フィールドは UTF-8 の bytes です。利用時は .decode('utf-8') してください。

  • お知らせが無い場合は Message が空文字・ItemCount が 0 で成功します。

  • Message は HTML を含むことがあり、2048 バイトで打ち切られます(Title は 512 バイト、Url は 1024 バイト)。 古い版の DLL では打ち切り位置が文字の途中になることがあり、.decode('utf-8') が UnicodeDecodeError になる場合があります。最新版へ更新するか、 .decode('utf-8', errors='replace') で安全に読み取ってください。

notice.ItemData の各要素(ST_NOTICE_ITEM):

フィールド名

説明

Title / Date

タイトル(bytes) / 日付テキスト(bytes)

Url / Icon / Color

リンクURL(bytes) / アイコン(bytes) / 日付表示色(bytes)

notice = ST_NOTICE_DATA()
ret = get_notice(notice)
if (ret & 1) == 1:
    if notice.Message:
        print(f"強制表示: {notice.Message}")
    print(f"お知らせ {notice.ItemCount} 件")
    for item in notice.ItemData:
        title = item.Title.decode('utf-8')
        date = item.Date.decode('utf-8')
        url = item.Url.decode('utf-8')
        print(f"  [{date}] {title}  {url}")

使用例

基本フロー(ログイン〜単勝購入〜ログアウト)

from ipathelper import *

def main():
    try:
        # ログイン
        ret = login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')
        if (ret & 1) != 1:
            print("ログインに失敗しました。")
            return

        # 購入情報の構築(東京 11R、単勝、1番、100円)
        betData = ST_BET_DATA()
        ret = get_bet_instance(
            KAISAI_TOKYO, 11,
            2026, 4, 5,
            HOUSHIKI_NORMAL, SHIKIBETSU_WIN,
            100, "1",
            betData
        )
        if (ret & 1) != 1:
            print("購入情報の構築に失敗しました。")
            return

        print(f"合計購入金額: {betData.TotalAmount} 円")

        # 馬券購入
        betDataList = (ST_BET_DATA * 1)()
        betDataList[0] = betData
        ret = bet(betDataList, 1)
        if (ret & 1) != 1:
            print("馬券購入に失敗しました。")
            return

        print("購入成功")

    finally:
        logout()

if __name__ == '__main__':
    main()

複数買い目の一括購入

from ipathelper import *

def main():
    try:
        ret = login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')
        if (ret & 1) != 1:
            return

        bet_list = [
            # (開催場, R, 年, 月, 日, 方式, 式別, 金額, 買い目)
            (KAISAI_TOKYO,    11, 2026, 4, 5, HOUSHIKI_NORMAL,    SHIKIBETSU_WIN,      100, "3"),
            (KAISAI_HANSHIN,  10, 2026, 4, 5, HOUSHIKI_BOX,       SHIKIBETSU_QUINELLA, 200, "1,3,5,7"),
            (KAISAI_NAKAYAMA,  9, 2026, 4, 5, HOUSHIKI_FORMATION, SHIKIBETSU_TRIFECTA, 100, "1-2,3-4,5"),
            # 地方競馬も同じ配列に混在させることができる
            (KAISAI_OI,        8, 2026, 4, 5, HOUSHIKI_NORMAL,    SHIKIBETSU_EXACTA,   100, "5-8"),
        ]

        n = len(bet_list)
        betDataList = (ST_BET_DATA * n)()

        for i, (place, r, y, m, d, houshiki, shikibetsu, kingaku, kaime) in enumerate(bet_list):
            tmp = ST_BET_DATA()
            ret = get_bet_instance(place, r, y, m, d, houshiki, shikibetsu, kingaku, kaime, tmp)
            if (ret & 1) != 1:
                print(f"[{i}] 購入情報の構築に失敗しました。")
                return
            betDataList[i] = tmp

        # 4件を一括購入(中央・地方は自動振り分け)
        ret = bet(betDataList, n)
        if (ret & 1) == 1:
            print("全件購入成功")
        if (ret & 4) == 4:
            print("中央競馬の一部または全部が失敗")
        if (ret & 8) == 8:
            print("地方競馬の一部または全部が失敗")

    finally:
        logout()

if __name__ == '__main__':
    main()

WIN5 の購入

from ipathelper import *

def main():
    try:
        ret = login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')
        if (ret & 1) != 1:
            return

        betDataWin5 = ST_BET_DATA_WIN5()

        # レース1: 1・2番 / レース2: 3番 / レース3: 4・5番 / レース4: 6番 / レース5: 7・8番
        # -> 2x1x2x1x2 = 8通り、計 800円
        ret = get_bet_instance_win5(100, 2026, 4, 5, "1,2-3-4,5-6-7,8", betDataWin5)
        if (ret & 1) != 1:
            print("WIN5 購入情報の構築に失敗しました。")
            return

        ret = bet_win5(betDataWin5)
        if (ret & 1) == 1:
            print("WIN5 購入成功")
        else:
            print("WIN5 購入失敗")

    finally:
        logout()

if __name__ == '__main__':
    main()

入金・出金

from ipathelper import *

def main():
    try:
        ret = login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')
        if (ret & 1) != 1:
            return

        # 入金(2,000円)
        ret = deposit(2000)
        if (ret & 1) == 1:
            print("入金成功")

        # 入金(ネットワーク不安定時に最大 3 回だけリトライ)
        ret = deposit(1000, retry_count=3)
        if (ret & 1) != 1:
            print("3回試みても入金できませんでした。")

        # 全額出金
        ret = withdraw()
        if (ret & 1) == 1:
            print("出金成功")

    finally:
        logout()

if __name__ == '__main__':
    main()

自動入金を有効にして購入

from ipathelper import *

def main():
    try:
        ret = login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')
        if (ret & 1) != 1:
            return

        # 残高不足時に 3,000円 自動入金、反映確認タイムアウト 15秒
        set_auto_deposit_flag(True, deposit_value=3000, confirm_timeout=15000)

        betData = ST_BET_DATA()
        ret = get_bet_instance(
            KAISAI_TOKYO, 11, 2026, 4, 5,
            HOUSHIKI_FORMATION, SHIKIBETSU_TRIFECTA,
            100, "1-2,3,4-5,6,7", betData
        )
        if (ret & 1) != 1:
            return

        betDataList = (ST_BET_DATA * 1)()
        betDataList[0] = betData

        # 残高不足なら自動的に 3,000円 入金してから購入
        ret = bet(betDataList, 1)
        if (ret & 1) == 1:
            print("購入成功")
        else:
            print("購入失敗(残高不足またはタイムアウト)")

    finally:
        logout()

if __name__ == '__main__':
    main()

購入履歴の取得

from ipathelper import *

def main():
    try:
        ret = login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')
        if (ret & 1) != 1:
            return

        purchaseData = ST_PURCHASE_DATA()
        ret = get_purchase_data(purchaseData)

        if (ret & 1) == 1:
            print(f"残高          : {purchaseData.Balance} 円")
            print(f"残購入可能数  : {purchaseData.AvailableBetCount} 件")
            print(f"当日購入金額  : {purchaseData.DayPurchase} 円")
            print(f"当日払戻金額  : {purchaseData.DayHaraimodosi} 円")
            print(f"累計購入金額  : {purchaseData.TotalPurchase} 円")
            print(f"累計払戻金額  : {purchaseData.TotalHaraimodosi} 円")
            print(f"馬券件数      : {purchaseData.TicketCount} 件")
            print("--------------------------------")

            for i in range(purchaseData.TicketCount):
                ticket = purchaseData.TicketData[i]
                day_label = "当日" if ticket.DayFlag == 1 else "前日"
                print(f"[受付No.{ticket.ReceiptNo:02d}] "
                      f"{day_label} "
                      f"{ticket.Hour:02d}:{ticket.Minute:02d}購入 "
                      f"{ticket.Kingaku}円 "
                      f"(払戻: {ticket.Payout}円) "
                      f"詳細{ticket.DetailCount}点")

                for j in range(ticket.DetailCount):
                    detail = ticket.DetailData[j]
                    status_map = {
                        DECISIONFLAG_HIT:      "的中",
                        DECISIONFLAG_MISS:     "外れ",
                        DECISIONFLAG_BACK:     "返還",
                        DECISIONFLAG_CANCEL:   "取消",
                        DECISIONFLAG_NORMAL:   "確定",
                        DECISIONFLAG_DEADLINE: "締切",
                    }
                    status = status_map.get(detail.DecisionFlag, "不明")
                    multi  = "[マルチ]" if detail.Multi else ""
                    print(f"  詳細[{j}]: {status} {multi} "
                          f"R{detail.RaceNo} 方式:{detail.Method} 式別:{detail.Type}")

        # メモリ解放は get_purchase_data 内部で自動実行される

    finally:
        logout()

if __name__ == '__main__':
    main()

エラーハンドリング

from ipathelper import *

# 戻り値のビットフラグを一括確認するユーティリティ関数
def print_return_value(func_name: str, ret: int):
    flags = []
    if (ret &  1): flags.append("SUCCESS")
    if (ret &  2): flags.append("UNSUCCESS")
    if (ret &  4): flags.append("FAILED_CHUOU")
    if (ret &  8): flags.append("FAILED_CHIHOU")
    if (ret & 16): flags.append("FAILED_COM_CHUOU")
    if (ret & 32): flags.append("FAILED_COM_CHIHOU")
    print(f"[{func_name}] {' | '.join(flags)}")

def main():
    try:
        ret = login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')
        print_return_value("login", ret)

        if (ret & 1) != 1:
            print("ログインに失敗しました。処理を中止します。")
            return

        # 中央・地方のログイン状態を個別確認
        if (ret & 4) == 4:
            print("警告: 中央競馬ログイン失敗。中央競馬の馬券は購入できません。")
        if (ret & 8) == 8:
            print("警告: 地方競馬ログイン失敗。地方競馬の馬券は購入できません。")

        betData = ST_BET_DATA()
        ret = get_bet_instance(KAISAI_TOKYO, 11, 2026, 4, 5,
                               HOUSHIKI_NORMAL, SHIKIBETSU_WIN, 100, "5", betData)
        print_return_value("get_bet_instance", ret)

        if (ret & 1) == 1:
            betDataList = (ST_BET_DATA * 1)()
            betDataList[0] = betData
            ret = bet(betDataList, 1)
            print_return_value("bet", ret)

            # 通信エラー時は再ログインを試みる
            if (ret & 1) != 1 and (ret & 16) == 16:
                print("通信エラー。再ログインを試みます。")
                logout()
                login('INET-ID', 'LOGIN-ID', 'PASSWORD', 'PARS')

    finally:
        logout()

if __name__ == '__main__':
    main()

対応金融機関

入出金に使用できる金融機関は以下の通りです。

  • PayPay 銀行

  • 楽天銀行

  • 三井住友銀行

  • 三菱 UFJ 銀行

  • 住信 SBI ネット銀行

  • ゆうちょ銀行

  • りそな銀行

  • 埼玉りそな銀行

  • au じぶん銀行

開発者向け: リリース手順

リポジトリ構成

ipathelper/
├── deploy_prd.bat      ... PyPI へ公開する入口
├── deploy_dev.bat      ... TestPyPI へ公開する入口
├── deploy_common.bat   ... バージョン更新・ビルド・公開の本体
├── publish.py          ... ~/.pypirc から認証情報を読み uv publish を実行する
├── pyproject.toml      ... [project] の version を deploy_common.bat が自動更新する
└── ipathelper/
    ├── __init__.py     ... DLL の読み込み・解放
    ├── ipathelper.py   ... 各 API のラッパー
    ├── x64/IpatHelper.dll
    └── x86/IpatHelper.dll

事前準備

uv をインストールし、~/.pypirc に [pypi] / [testpypi] セクションを用意します。

[pypi]
repository = https://upload.pypi.org/legacy/
username = __token__
password = pypi-xxxxxxxx

[testpypi]
repository = https://test.pypi.org/legacy/
username = __token__
password = pypi-xxxxxxxx

ネイティブ DLL を更新する場合は、ビルドした 32bit / 64bit の IpatHelper.dll を ipathelper/x86/ と ipathelper/x64/ へ配置してください。

公開

> deploy_dev.bat      :: TestPyPI へ公開
> deploy_prd.bat      :: PyPI へ公開

いずれも次の順に処理されます。

  1. pyproject.toml の [project] セクションから version を読み取り、パッチ番号を +1 して書き戻す

  2. dist を削除して uv build

  3. publish.py 経由で uv publish

公開せずにバージョン計算とビルドだけを確認したい場合は /dryrun を付けます。 このときバージョン番号は書き換わりません。

> deploy_prd.bat /dryrun

バッチ編集時の注意

deploy_common.bat は pyproject.toml を 1 行ずつ読み直して書き戻すため、 次の点を崩さないでください。

  • バッチ本文は ASCII のみ・改行は CRLF にする。 先頭でコンソールのコードページを UTF-8(65001)へ切り替えているため、 バッチ内に非 ASCII 文字があるとコードページ次第で構文エラーになります。

  • コードページの切り替えは必須です。pyproject.toml は UTF-8 で日本語(description)を 含むため、CP932 のまま読み書きすると再エンコードされて文字化けします。

  • 行の出力は echo(!line! の形(遅延展開)を使う。 requires-python = ">=3.12" の > がリダイレクトとして解釈されるのを防いでいます。

  • 読み込みは findstr /n "^" で行番号を付けてから除去する。 for /f は空行を読み飛ばすため、そのままでは TOML の空行が失われます。

Metadata

Release files for ipathelper 2.0.23

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

Source distribution (sdist)

Source distribution for ipathelper 2.0.23
File Size Uploaded Provenance Actions
ipathelper-2.0.23.tar.gz 693.5 kB Without provenance Details for ipathelper-2.0.23.tar.gz

Built distribution (wheel)

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

Total release size: 1.4 MB

Release files / ipathelper-2.0.23.tar.gz

Download URL ipathelper-2.0.23.tar.gz
Size 693.5 kB
Tags Source
SHA-256 checksum
How to use checksums
c86716c9d468c59081ff313e7f258f1382f422a19e7ae8f090efc7e4502b7ca3
BLAKE2b-256 checksum
How to use checksums
a92b467c76bc382aee8a4f140ec782f73e7515bef994fb9d0c7fdfd1bf51b9ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.6.2

Release files / ipathelper-2.0.23-py3-none-any.whl

Download URL ipathelper-2.0.23-py3-none-any.whl
Size 686.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b3f8f392fbabe6288dec459de5fc8c0bdf2fb3d905ebfa4b788b12767c2e6d2f
BLAKE2b-256 checksum
How to use checksums
635715b140a44cf5ca7e16a4e668cef47b98f6b51d88d1dea7646abe2a774a54
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.6.2

Security for ipathelper 2.0.23

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

2.0.23 This release

2 release files No provenance

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