Skip to content

Commit

Permalink
[low code connectors] fix bug where headers were not passed to cursor…
Browse files Browse the repository at this point in the history
… interpolation (airbytehq#15347)

* fix bug where headers were not passed to cursor interpolation

* add headers to error handler predicate
  • Loading branch information
brianjlai authored Aug 8, 2022
1 parent d4abf61 commit 054cbbe
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def matches(self, response: requests.Response) -> Optional[ResponseAction]:
return None

def _response_matches_predicate(self, response: requests.Response) -> bool:
return self.predicate and self.predicate.eval(None, response=response.json())
return self.predicate and self.predicate.eval(None, response=response.json(), headers=response.headers)

def _response_contains_error_message(self, response: requests.Response) -> bool:
if not self.error_message_contains:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,17 @@ def __post_init__(self, options: Mapping[str, Any]):

def next_page_token(self, response: requests.Response, last_records: List[Mapping[str, Any]]) -> Optional[Any]:
decoded_response = self.decoder.decode(response)

# The default way that link is presented in requests.Response is a string of various links (last, next, etc). This
# is not indexable or useful for parsing the cursor, so we replace it with the link dictionary from response.links
headers = response.headers
headers["link"] = response.links

if self.stop_condition:
should_stop = self.stop_condition.eval(self.config, response=decoded_response, headers=headers, last_records=last_records)
if should_stop:
return None
token = self.cursor_value.eval(config=self.config, last_records=last_records, response=decoded_response)
token = self.cursor_value.eval(config=self.config, last_records=last_records, response=decoded_response, headers=headers)
return token if token else None

def reset(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,15 @@
ResponseStatus.retry(10),
None,
),
(
"test_200_fail_with_predicate_from_header",
HTTPStatus.OK,
HttpResponseFilter(action=ResponseAction.FAIL, predicate="{{ headers['fail'] }}", options={}),
None,
{"fail": True},
response_status.FAIL,
None,
),
],
)
def test_default_error_handler(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,15 @@
("test_token_from_response", "{{ response._metadata.content }}", None, "content_value"),
("test_token_from_options", "{{ options.key }}", None, "value"),
("test_token_not_found", "{{ response.invalid_key }}", None, None),
("test_static_token_with_stop_condition_false", "token", InterpolatedBoolean(condition="{{False}}", options={}), "token"),
("test_static_token_with_stop_condition_true", "token", InterpolatedBoolean(condition="{{True}}", options={}), None),
("test_static_token_with_stop_condition_false", "token", InterpolatedBoolean("{{False}}", options={}), "token"),
("test_static_token_with_stop_condition_true", "token", InterpolatedBoolean("{{True}}", options={}), None),
("test_token_from_header", "{{ headers.next }}", InterpolatedBoolean("{{ not headers.has_more }}", options={}), "ready_to_go"),
(
"test_token_from_response_header_links",
"{{ headers.link.next.url }}",
InterpolatedBoolean("{{ not headers.link.next.url }}", options={}),
"https://adventure.io/api/v1/records?page=2&per_page=100",
),
],
)
def test_cursor_pagination_strategy(test_name, template_string, stop_condition, expected_token):
Expand All @@ -33,7 +40,8 @@ def test_cursor_pagination_strategy(test_name, template_string, stop_condition,
)

response = requests.Response()
response.headers = {"has_more": True}
link_str = '<https://adventure.io/api/v1/records?page=2&per_page=100>; rel="next"'
response.headers = {"has_more": True, "next": "ready_to_go", "link": link_str}
response_body = {"_metadata": {"content": "content_value"}, "accounts": [], "end": 99, "total": 200, "characters": {}}
response._content = json.dumps(response_body).encode("utf-8")
last_records = [{"id": 0, "more_records": True}, {"id": 1, "more_records": True}]
Expand Down

0 comments on commit 054cbbe

Please sign in to comment.