Skip to content

Commit e7e52d2

Browse files
committed
ITN fixes
An assortment of fixes following the last period to make the API more stable. We also remove prematurer deduplication so that we can now identify when validators are submitting too many values. For the HTMX endpoint we also handle a case where location data cannot be retrieved initially meaning we attempted to process a dict when were were receiving a string.
1 parent af51ecf commit e7e52d2

File tree

4 files changed

+38
-13
lines changed

4 files changed

+38
-13
lines changed

api.env

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ export KUPO_PORT=
55
export DB_USER=
66
export DB_PASS=
77
export DB_DATABASE=
8+
export DB_URL=
9+
export DB_PORT=

src/itn_api/api.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# pylint: disable=W0621
1313

1414
import argparse
15+
import decimal
1516
import importlib
1617
import logging
1718
import os
@@ -83,8 +84,8 @@ def _get_database_connection() -> mariadb.Connection:
8384
connection = mariadb.connect(
8485
user=os.environ["DB_USER"],
8586
password=os.environ["DB_PASS"],
86-
host="127.0.0.1",
87-
port=3306,
87+
host=os.environ.get("DB_URL", "0.0.0.0"),
88+
port=int(os.environ.get("DB_PORT", 3306)),
8889
database=os.environ["DB_DATABASE"],
8990
autocommit=True,
9091
)
@@ -185,7 +186,7 @@ async def get_participants_counts_day_csv(
185186
logger.info("generating participant csv: get db data")
186187
report = await reports.get_participants_counts_date_range(app, date_start, date_end)
187188
logger.info("data retrieved for participant csv: creating count csv")
188-
csv_report = reports.generate_participant_count_csv(report)
189+
csv_report = await reports.generate_participant_count_csv(report)
189190
return csv_report
190191

191192

@@ -289,6 +290,10 @@ async def get_online_collectors() -> str:
289290
participant_count_24h_feed_average[address] = 0
290291
participant_count_1h_feed_average[address] = 0
291292
participant_count_1m_feed_average = 0
293+
except decimal.InvalidOperation:
294+
participant_count_24h_feed_average[address] = 0
295+
participant_count_1h_feed_average[address] = 0
296+
participant_count_1m_feed_average[address] = 0
292297

293298
htmx = htm_helpers.participants_count_table(
294299
participants_count_total,

src/itn_api/htm_helpers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ def locations_table(locations):
133133
seen = []
134134
rows = ""
135135
idx = 0
136+
if not locations:
137+
return "problem gathering collectors, please try again shortly"
136138
for addr, locale in locations.items():
137139
idx += 1
138140
region = locale["region"]
@@ -152,7 +154,6 @@ def locations_table(locations):
152154
<td nowrap>&nbsp;{idx}&nbsp;</td>
153155
</tr>
154156
""".strip()
155-
156157
return f"{head}\n{rows}\n{country_count}</table>\n"
157158

158159

src/itn_api/reports.py

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ def _get_addr_minute_feed_dicts(data: list, addresses: list):
158158
for item in data:
159159
if item[0] != addr:
160160
continue
161+
# SPLIT MINUTES OUT HERE FOR EVENTUAL DEDUPE...
162+
# SPLIT MINUTES OUT HERE FOR EVENTUAL DEDUPE...
163+
# SPLIT MINUTES OUT HERE FOR EVENTUAL DEDUPE...
161164
minutes = str(item[1]).rsplit(":", 1)[0].strip()
162165
feed = item[2].strip()
163166
addr_minute_values = helpers.update_dict(
@@ -195,9 +198,11 @@ def _process_json_report(
195198
days_in_range = minutes_in_range / helpers.MINUTES_DAY
196199
counts = {}
197200
for addr, value in addr_minute_values.items():
198-
total_mins = len(set(value))
201+
total_mins = len(value)
199202
average_mins = total_mins / len(set(feeds))
200203
license_name, stake = _get_license_and_stake(address_data, addr)
204+
feeds_sorted = addr_feed_values[addr]
205+
feeds_sorted.sort()
201206
counts[addr] = {
202207
"license": license_name,
203208
"stake": stake,
@@ -206,8 +211,7 @@ def _process_json_report(
206211
"total_mins_in_date_range": minutes_in_range,
207212
"number_of_feeds_collected": len(set(addr_feed_values[addr])),
208213
"feeds_count": [
209-
f"{key}: {value}"
210-
for key, value in Counter(addr_feed_values[addr]).items()
214+
f"{key}: {value}" for key, value in Counter(feeds_sorted).items()
211215
],
212216
}
213217
report = {}
@@ -222,19 +226,29 @@ def _process_json_report(
222226

223227

224228
@helpers.timeit
225-
def get_participants_counts_date_range(
229+
async def get_participants_counts_date_range(
226230
app: FastAPI, date_start: str, date_end: str
227231
) -> dict:
228232
"""Return participants report by date range."""
233+
229234
data = _get_participant_data_by_date_range(app, date_start, date_end)
230235
feeds, addresses = _get_unique_feeds(data)
231236
logger.info("no feeds: '%s'", len(feeds))
232237
logger.info("no addresses: '%s'", len(feeds))
233238
addr_minute_values, addr_feed_values = _get_addr_minute_feed_dicts(data, addresses)
234-
addr_minute_values = helpers.dedupe_dicts(addr_minute_values)
239+
240+
# Remove dedupe for now, and look at all minute values we receive
241+
# to perform a full count.
242+
#
243+
# `addr_minute_values`` is a dict ordered by stake key, with a list
244+
# of feed+minutes for the era of participation as the value.
245+
#
246+
# addr_minute_values = helpers.dedupe_dicts(addr_minute_values)
247+
235248
logger.info("retrieving data from kupo")
236249
address_data = _get_basic_addr_data(app.state.kupo_url, app.state.kupo_port)
237250
logger.info("processing json report")
251+
238252
report = _process_json_report(
239253
address_data, date_start, date_end, addr_minute_values, addr_feed_values, feeds
240254
)
@@ -260,7 +274,7 @@ def _get_participant_data_by_date_range(
260274
return res
261275

262276

263-
def generate_participant_count_csv(report: dict) -> str:
277+
async def generate_participant_count_csv(report: dict) -> str:
264278
"""Convert JSON data into a CSV for ease of use."""
265279

266280
max_possible = report.get("max_possible_data_points")
@@ -283,8 +297,11 @@ def generate_participant_count_csv(report: dict) -> str:
283297
value,
284298
stake_addr,
285299
)
286-
continue
287-
stake = humanize.intcomma(int(value.get("stake", 0))).replace(",", "")
300+
license_no = "deregistered"
301+
try:
302+
stake = humanize.intcomma(int(value.get("stake", 0))).replace(",", "")
303+
except TypeError:
304+
stake = 0
288305
total_data_points = value.get("total_data_points", 0)
289306
average_per_feed = value.get("average_mins_collecting_per_feed", 0)
290307
total_collected = value.get("number_of_feeds_collected", 0)
@@ -387,7 +404,7 @@ async def get_locations_stake_key(app: FastAPI) -> list:
387404
"""
388405
)
389406
except mariadb.Error:
390-
return "zero collectors online"
407+
return {}
391408

392409
res = list(cursor)
393410
cursor.close()

0 commit comments

Comments
 (0)