Skip to content

Commit 6dfac39

Browse files
[core] feat: improve handling empty response from API
* Add __bool__ method to GarfApiResponse to check whether there is any data * If API returns no response, return an empty report * Ensure that when empty and non-empty reports are added only non-empty report is returned
1 parent 0c9f7cd commit 6dfac39

File tree

6 files changed

+30
-1
lines changed

6 files changed

+30
-1
lines changed

libs/core/garf_core/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@
2626
'ApiReportFetcher',
2727
]
2828

29-
__version__ = '0.3.0'
29+
__version__ = '0.3.1'

libs/core/garf_core/api_clients.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ class GarfApiResponse(pydantic.BaseModel):
3939

4040
results: list[ApiResponseRow]
4141

42+
def __bool__(self) -> bool:
43+
return bool(self.results)
44+
4245

4346
class GarfApiError(exceptions.GarfError):
4447
"""API specific exception."""

libs/core/garf_core/report.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,10 @@ def __add__(self, other: GarfReport) -> GarfReport:
403403
"""
404404
if not isinstance(other, self.__class__):
405405
raise GarfReportError('Add operation is supported only for GarfReport')
406+
if not other:
407+
return self
408+
if not self:
409+
return other
406410
if self.column_names != other.column_names:
407411
raise GarfReportError('column_names should be the same in GarfReport')
408412
return GarfReport(
@@ -635,6 +639,9 @@ def __eq__(self, other):
635639
def __repr__(self):
636640
return f'GarfRow(\n{self.to_dict()}\n)'
637641

642+
def __bool__(self) -> bool:
643+
return bool(self.data)
644+
638645

639646
class GarfReportError(exceptions.GarfError):
640647
"""Base exception for Garf reports."""

libs/core/garf_core/report_fetcher.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ def fetch(
148148
return builtin_report(self, **kwargs)
149149

150150
response = self.api_client.get_response(query, **kwargs)
151+
if not response:
152+
return report.GarfReport(query_specification=query)
153+
151154
parsed_response = self.parser(query).parse_response(response)
152155
return report.GarfReport(
153156
results=parsed_response,

libs/core/tests/unit/test_report.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,12 @@ def test_add_two_empty_reports(self, empty_report):
144144
added_report = empty_report + empty_report
145145
assert len(added_report) == 0
146146

147+
def test_add_empty_report_to_non_emptry_report_returns_non_empty_report(
148+
self, multi_column_report, empty_report
149+
):
150+
added_report = empty_report + multi_column_report + empty_report
151+
assert added_report == multi_column_report
152+
147153
def test_add_two_reports(self, multi_column_report):
148154
added_report = multi_column_report + multi_column_report
149155
assert len(added_report) == len(multi_column_report.results) * 2

libs/core/tests/unit/test_report_fetcher.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,16 @@ def test_fetch_returns_correct_report_for_dict_parser(
5151

5252
assert test_report == expected_report
5353

54+
def test_fetch_returns_empty_report_for_empty_api_response(self):
55+
test_api_client = api_clients.FakeApiClient(results=[])
56+
fetcher = report_fetcher.ApiReportFetcher(
57+
api_client=test_api_client, parser=parsers.DictParser
58+
)
59+
query = 'SELECT column.name, other_column FROM test'
60+
test_report = fetcher.fetch(query)
61+
62+
assert not test_report
63+
5464
def test_fetch_builtin_query_returns_correct_builtin_report(
5565
self, test_dict_report_fetcher
5666
):

0 commit comments

Comments
 (0)