Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Max Age to get_latest_result #92

Merged
merged 3 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions dune_client/api/extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
Extended functionality for the ExecutionAPI
"""
from __future__ import annotations

import logging
import time

from io import BytesIO
from typing import Union, Optional, Any

Expand All @@ -19,6 +22,9 @@
)
from dune_client.query import QueryBase, parse_query_object_or_id
from dune_client.types import QueryParameter
from dune_client.util import age_in_hours

THREE_MONTHS_IN_HOURS = 2191


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

def get_latest_result(self, query: Union[QueryBase, str, int]) -> ResultsResponse:
def get_latest_result(
self,
query: Union[QueryBase, str, int],
max_age_hours: int = THREE_MONTHS_IN_HOURS,
) -> ResultsResponse:
"""
GET the latest results for a query_id without re-executing the query
(doesn't use execution credits)

:param query: :class:`Query` object OR query id as string or int

:param max_age_hours: re-executes the query if result is older than max_age_hours
https://dune.com/docs/api/api-reference/get-results/latest-results
"""
params, query_id = parse_query_object_or_id(query)
Expand All @@ -91,7 +101,17 @@ def get_latest_result(self, query: Union[QueryBase, str, int]) -> ResultsRespons
params=params,
)
try:
return ResultsResponse.from_dict(response_json)
results = ResultsResponse.from_dict(response_json)
last_run = results.times.execution_ended_at
if last_run and age_in_hours(last_run) > max_age_hours:
# Query older than specified max age
logging.info(
f"results (from {last_run}) older than {max_age_hours} hours, re-running query"
)
results = self.run_query(
query if isinstance(query, QueryBase) else QueryBase(query_id)
)
return results
except KeyError as err:
raise DuneError(response_json, "ResultsResponse", err) from err

Expand Down
10 changes: 9 additions & 1 deletion dune_client/util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Utility methods for package."""
from datetime import datetime
from datetime import datetime, timezone
from typing import Optional

import pkg_resources
Expand All @@ -20,3 +20,11 @@ def get_package_version(package_name: str) -> Optional[str]:
return pkg_resources.get_distribution(package_name).version
except pkg_resources.DistributionNotFound:
return None


def age_in_hours(timestamp: datetime) -> float:
"""
Returns the time (in hours) between now and `timestamp`
"""
result_age = datetime.now(timezone.utc) - timestamp
return result_age.total_seconds() / (60 * 60)
9 changes: 8 additions & 1 deletion tests/unit/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import datetime
import unittest
from dune_client.util import get_package_version
from dune_client.util import get_package_version, age_in_hours


class TestUtils(unittest.TestCase):
Expand All @@ -11,3 +12,9 @@ def test_package_version_some(self):
def test_package_version_none(self):
# Can't self refer (this should only work when user has dune-client installed).
self.assertIsNone(get_package_version("unittest"))

def test_age_in_hours(self):
march_ten_eighty_five = datetime.datetime(
1985, 3, 10, tzinfo=datetime.timezone.utc
)
self.assertGreaterEqual(age_in_hours(march_ten_eighty_five), 314159)