Skip to content

Commit 2f0b384

Browse files
authored
Add Max Age to get_latest_result (#92)
1 parent 02ea964 commit 2f0b384

File tree

3 files changed

+40
-5
lines changed

3 files changed

+40
-5
lines changed

dune_client/api/extensions.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
Extended functionality for the ExecutionAPI
33
"""
44
from __future__ import annotations
5+
6+
import logging
57
import time
8+
69
from io import BytesIO
710
from typing import Union, Optional, Any
811

@@ -19,6 +22,9 @@
1922
)
2023
from dune_client.query import QueryBase, parse_query_object_or_id
2124
from dune_client.types import QueryParameter
25+
from dune_client.util import age_in_hours
26+
27+
THREE_MONTHS_IN_HOURS = 2191
2228

2329

2430
class ExtendedAPI(ExecutionAPI, QueryAPI):
@@ -76,13 +82,17 @@ def run_query_dataframe(
7682
data = self.run_query_csv(query, ping_frequency, performance).data
7783
return pandas.read_csv(data)
7884

79-
def get_latest_result(self, query: Union[QueryBase, str, int]) -> ResultsResponse:
85+
def get_latest_result(
86+
self,
87+
query: Union[QueryBase, str, int],
88+
max_age_hours: int = THREE_MONTHS_IN_HOURS,
89+
) -> ResultsResponse:
8090
"""
8191
GET the latest results for a query_id without re-executing the query
8292
(doesn't use execution credits)
8393
8494
:param query: :class:`Query` object OR query id as string or int
85-
95+
:param max_age_hours: re-executes the query if result is older than max_age_hours
8696
https://dune.com/docs/api/api-reference/get-results/latest-results
8797
"""
8898
params, query_id = parse_query_object_or_id(query)
@@ -91,7 +101,17 @@ def get_latest_result(self, query: Union[QueryBase, str, int]) -> ResultsRespons
91101
params=params,
92102
)
93103
try:
94-
return ResultsResponse.from_dict(response_json)
104+
results = ResultsResponse.from_dict(response_json)
105+
last_run = results.times.execution_ended_at
106+
if last_run and age_in_hours(last_run) > max_age_hours:
107+
# Query older than specified max age
108+
logging.info(
109+
f"results (from {last_run}) older than {max_age_hours} hours, re-running query"
110+
)
111+
results = self.run_query(
112+
query if isinstance(query, QueryBase) else QueryBase(query_id)
113+
)
114+
return results
95115
except KeyError as err:
96116
raise DuneError(response_json, "ResultsResponse", err) from err
97117

dune_client/util.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""Utility methods for package."""
2-
from datetime import datetime
2+
from datetime import datetime, timezone
33
from typing import Optional
44

55
import pkg_resources
@@ -20,3 +20,11 @@ def get_package_version(package_name: str) -> Optional[str]:
2020
return pkg_resources.get_distribution(package_name).version
2121
except pkg_resources.DistributionNotFound:
2222
return None
23+
24+
25+
def age_in_hours(timestamp: datetime) -> float:
26+
"""
27+
Returns the time (in hours) between now and `timestamp`
28+
"""
29+
result_age = datetime.now(timezone.utc) - timestamp
30+
return result_age.total_seconds() / (60 * 60)

tests/unit/test_utils.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import datetime
12
import unittest
2-
from dune_client.util import get_package_version
3+
from dune_client.util import get_package_version, age_in_hours
34

45

56
class TestUtils(unittest.TestCase):
@@ -11,3 +12,9 @@ def test_package_version_some(self):
1112
def test_package_version_none(self):
1213
# Can't self refer (this should only work when user has dune-client installed).
1314
self.assertIsNone(get_package_version("unittest"))
15+
16+
def test_age_in_hours(self):
17+
march_ten_eighty_five = datetime.datetime(
18+
1985, 3, 10, tzinfo=datetime.timezone.utc
19+
)
20+
self.assertGreaterEqual(age_in_hours(march_ten_eighty_five), 314159)

0 commit comments

Comments
 (0)