hkjc 0.3.22__tar.gz → 0.3.23__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hkjc
3
- Version: 0.3.22
3
+ Version: 0.3.23
4
4
  Summary: Library for scrapping HKJC data and perform basic analysis
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: beautifulsoup4>=4.14.2
@@ -12,5 +12,4 @@ Requires-Dist: numpy>=2.3.3
12
12
  Requires-Dist: polars>=1.33.1
13
13
  Requires-Dist: pyarrow>=21.0.0
14
14
  Requires-Dist: requests>=2.32.5
15
- Requires-Dist: scipy>=1.16.2
16
15
  Requires-Dist: tqdm>=4.67.1
@@ -1,4 +1,5 @@
1
1
  from flask import Flask, jsonify, render_template, request
2
+ from flask_caching import Cache
2
3
 
3
4
  import polars as pl
4
5
  import numpy as np
@@ -26,7 +27,13 @@ def arr_to_dict(arr: np.ndarray, dtype=float):
26
27
 
27
28
 
28
29
  app = Flask(__name__)
29
-
30
+ config = {
31
+ "CACHE_TYPE": "RedisCache",
32
+ "CACHE_REDIS_HOST": "localhost",
33
+ "CACHE_REDIS_PORT": "6379"
34
+ }
35
+ app.config.from_mapping(config)
36
+ cache = Cache(app)
30
37
 
31
38
  @app.route("/")
32
39
  def disp_race_info():
@@ -73,6 +80,7 @@ going_dict = {'TURF': turf_going_dict, 'ALL WEATHER TRACK': aw_going_dict}
73
80
 
74
81
 
75
82
  @app.route("/horse_info/<horse_no>", methods=['GET'])
83
+ @cache.cached(timeout=7200, query_string=True)
76
84
  def disp_horse_info(horse_no):
77
85
  # read optional filters
78
86
  dist = request.args.get('dist', type=int)
@@ -87,16 +95,18 @@ def disp_horse_info(horse_no):
87
95
  going = None
88
96
 
89
97
  df = get_horse_data(horse_no)
90
- if dist is not None:
91
- df = df.filter(pl.col('Dist') == dist)
92
- if track and track.upper() == 'TURF':
93
- df = df.filter(pl.col('Track') == 'Turf')
94
- elif track and track.upper() == 'ALL WEATHER TRACK':
95
- df = df.filter(pl.col('Track') == 'AWT')
96
- if going is not None:
97
- df = df.filter(pl.col('G') == going)
98
98
 
99
- return render_template('horse-info.html', df=df)
99
+ if df.height > 0:
100
+ if dist is not None:
101
+ df = df.filter(pl.col('Dist') == dist)
102
+ if track and track.upper() == 'TURF':
103
+ df = df.filter(pl.col('Track') == 'Turf')
104
+ elif track and track.upper() == 'ALL WEATHER TRACK':
105
+ df = df.filter(pl.col('Track') == 'AWT')
106
+ if going is not None:
107
+ df = df.filter(pl.col('G') == going)
108
+
109
+ return render_template('horse-info.html', df=df.head(5))
100
110
 
101
111
 
102
112
  @app.route('/live_odds/<race_no>')
@@ -114,4 +124,10 @@ def disp_live_odds(race_no=1):
114
124
  def disp_speedmap(race_no=1):
115
125
  return speedmap(int(race_no))
116
126
 
117
- # TODO: trades
127
+ # TODO: trades API
128
+
129
+ # TODO: Single QP trade calculation: ?banker= & cover= , , , => return ev win-prob avgodds
130
+
131
+ # TODO: Recommend QP trade given banker ?exclude= , , , &maxC= => return list of pareto trades, cover, ev, win-prob, avgodds
132
+
133
+ # TODO: Recommend Place only trade ?exclude= , , , &maxC => return list of pareto trades, cover, ev, win-prob, avgodds