Skip to content

Commit

Permalink
Merge pull request #262 from ASFHyP3/configurable-costs
Browse files Browse the repository at this point in the history
Configurable job costs
  • Loading branch information
jtherrmann authored Feb 28, 2024
2 parents 47bc6a0 + f6a5c2d commit fa03655
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [PEP 440](https://www.python.org/dev/peps/pep-0440/)
and uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [6.1.0]

### Added
* `HyP3.costs` method to retrieve the job cost lookup table, following the addition of the `/costs` API endpoint in HyP3 v6.2.0
* `Batch.total_credit_cost` method to calculate the total credit cost for a batch of jobs

## [6.0.0]
This release accommodates changes to the HyP3 API schema introduced in HyP3 v6.0.0

Expand Down
9 changes: 9 additions & 0 deletions src/hyp3_sdk/hyp3.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,3 +505,12 @@ def check_quota(self) -> Union[float, int, None]:
warn('This method is deprecated and will be removed in a future release.\n'
'Please use `HyP3.check_credits` instead.', DeprecationWarning, stacklevel=2)
return self.check_credits()

def costs(self) -> dict:
"""
Returns:
Table of job costs
"""
response = self.session.get(urljoin(self.url, '/costs'))
_raise_for_hyp3_status(response)
return response.json()
3 changes: 3 additions & 0 deletions src/hyp3_sdk/jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,6 @@ def filter_jobs(
filtered_jobs.append(job)

return Batch(filtered_jobs)

def total_credit_cost(self):
return sum(job.credit_cost for job in self.jobs if job.credit_cost is not None)
10 changes: 10 additions & 0 deletions tests/test_hyp3.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,3 +437,13 @@ def test_check_credits():
responses.add(responses.GET, urljoin(api.url, '/user'), json=api_response)

assert math.isclose(api.check_credits(), 25.)


@responses.activate
def test_costs():
api_response = {'foo': 5}
with patch('hyp3_sdk.util.get_authenticated_session', mock_get_authenticated_session):
api = HyP3()
responses.add(responses.GET, urljoin(api.url, '/costs'), json=api_response)

assert api.costs() == {'foo': 5}
63 changes: 63 additions & 0 deletions tests/test_jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,3 +440,66 @@ def test_batch_filter_jobs():
assert job.status_code == batch.jobs[ii].status_code
if job.succeeded():
assert job.expired() == batch.jobs[ii].expired()


def test_batch_total_credit_cost():
batch = Batch()
assert batch.total_credit_cost() == 0

batch = Batch([
Job.from_dict({
'job_type': 'foo',
'job_id': 'foo',
'request_time': '2024-01-01T00:00:00Z',
'status_code': 'foo',
'user_id': 'foo',
}),
])
assert batch.total_credit_cost() == 0

batch = Batch([
Job.from_dict({
'job_type': 'foo',
'job_id': 'foo',
'request_time': '2024-01-01T00:00:00Z',
'status_code': 'foo',
'user_id': 'foo',
'credit_cost': 4
}),
Job.from_dict({
'job_type': 'foo',
'job_id': 'foo',
'request_time': '2024-01-01T00:00:00Z',
'status_code': 'foo',
'user_id': 'foo',
}),
])
assert batch.total_credit_cost() == 4

batch = Batch([
Job.from_dict({
'job_type': 'foo',
'job_id': 'foo',
'request_time': '2024-01-01T00:00:00Z',
'status_code': 'foo',
'user_id': 'foo',
'credit_cost': 1
}),
Job.from_dict({
'job_type': 'foo',
'job_id': 'foo',
'request_time': '2024-01-01T00:00:00Z',
'status_code': 'foo',
'user_id': 'foo',
'credit_cost': 2
}),
Job.from_dict({
'job_type': 'foo',
'job_id': 'foo',
'request_time': '2024-01-01T00:00:00Z',
'status_code': 'foo',
'user_id': 'foo',
'credit_cost': 5
}),
])
assert batch.total_credit_cost() == 8

0 comments on commit fa03655

Please sign in to comment.