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

🎉 New Source: Zenloop #7380

Merged
merged 15 commits into from
Nov 22, 2021
Merged

Conversation

AlexanderBatoulis
Copy link
Contributor

@AlexanderBatoulis AlexanderBatoulis commented Oct 26, 2021

What

How

Added four streams for this source

  1. Surveys
  2. Answers
  3. Survey Groups
  4. Answers Survey Groups

Recommended reading order

  1. bootstrap.md
  2. spec.json
  3. Schemas under schemas/*.json
  4. source.py

Pre-merge Checklist

Expand the relevant checklist and delete the others.

Test Runs

unit test
zenloop_unit_test

integration test
zenloop_acceptance_test

New Connector

Community member or Airbyter

  • Community member? Grant edit access to maintainers (instructions)
  • Secrets in the connector's spec are annotated with airbyte_secret
  • Unit & integration tests added and passing. Community members, please provide proof of success locally e.g: screenshot or copy-paste unit, integration, and acceptance test output. To run acceptance tests for a Python connector, follow instructions in the README. For java connectors run ./gradlew :airbyte-integrations:connectors:<name>:integrationTest.
  • Code reviews completed
  • Documentation updated
    • Connector's README.md
    • Connector's bootstrap.md. See description and examples
    • docs/SUMMARY.md
    • docs/integrations/<source or destination>/<name>.md including changelog. See changelog example
    • docs/integrations/README.md
    • airbyte-integrations/builds.md
  • PR name follows PR naming conventions
  • Connector added to connector index like described here

Airbyter

If this is a community PR, the Airbyte engineer reviewing this PR is responsible for the below items.

  • Create a non-forked branch based on this PR and test the below items on it
  • Build is successful
  • Credentials added to Github CI. Instructions.
  • /test connector=connectors/<name> command is passing.
  • New Connector version released on Dockerhub by running the /publish command described here

@CLAassistant
Copy link

CLAassistant commented Oct 26, 2021

CLA assistant check
All committers have signed the CLA.

@github-actions github-actions bot added area/connectors Connector related issues area/documentation Improvements or additions to documentation labels Oct 26, 2021
@harshithmullapudi
Copy link
Contributor

Hey @AlexanderBatoulis thanks for the contribution. We will review this soon

@avaidyanatha avaidyanatha changed the title New Source: Zenloop 🎉 New Source: Zenloop Oct 28, 2021
@alafanechere
Copy link
Contributor

Hey @AlexanderBatoulis , could you please fill the checklist at the bottom of the PR's description so that we can check if it's ready for review? Thanks! 🙏

Comment on lines 18 to 22
# expect_records:
# path: "integration_tests/expected_records.txt"
# extra_fields: no
# exact_order: no
# extra_records: yes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you remove this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Member

@marcosmarxm marcosmarxm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @AlexanderBatoulis small comment also can you run ./gradlew format?

@AlexanderBatoulis
Copy link
Contributor Author

Thanks @AlexanderBatoulis small comment also can you run ./gradlew format?

done

@AlexanderBatoulis
Copy link
Contributor Author

Hey @AlexanderBatoulis , could you please fill the checklist at the bottom of the PR's description so that we can check if it's ready for review? Thanks! 🙏

done

@marcosmarxm
Copy link
Member

Hello @AlexanderBatoulis ! Sorry to not finished your contribution before the date stipulated in the contest. All contributions made before 15-November are eligible to receive the award. We're trying to review your contribution as soon as possible.

Copy link
Contributor

@alafanechere alafanechere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you very much @AlexanderBatoulis for this contribution, I have some minor questions and suggestions that you'll find in my review comments.
In addition, we configured a sandbox account for Zenloop and I'm afraid that the integration tests are not passing when we fill the public_hash_id field. The https://app.zenloop.com/settings/api page provides list of hash ids for surveys, but this value is reused to build requests to survey_groups endpoint in the AnswersSurveyGroup stream (survey_groups/{self.public_hash_id}/answers). It looks like the API expects a survey group id that is different from the public hash id provided in the config (which is expected to be a survey id and not a survey group id) and it leads to 404 error.
TLDR: integration tests did not pass when setting public_hash_id to a valid value in our config.

Could you also fix conflicts with master please? 🙏


class IncrementalZenloopStream(ZenloopStream, ABC):
# checkpoint stream reads after 100 records.
state_checkpoint_interval = 100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using state_checkpoint_interval combined with a stream_slice implementation leads to checkpointing at every 100 records of each slice, is it your original intent?

"cursor_field": expected_cursor_field,
"stream_state": {expected_cursor_field: "2021-10-20T03:30:30Z"},
}
expected_stream_slice = [None]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're not testing the behavior of stream_slices if public_hash_id is None

Comment on lines 44 to 77
def test_request_headers(patch_base_class, config):
stream = ZenloopStream(config["api_token"], config["date_from"], config["public_hash_id"])
inputs = {"stream_slice": None, "stream_state": None, "next_page_token": None}
expected_headers = {}
assert stream.request_headers(**inputs) == expected_headers


def test_http_method(patch_base_class, config):
stream = ZenloopStream(config["api_token"], config["date_from"], config["public_hash_id"])
expected_method = "GET"
assert stream.http_method == expected_method


@pytest.mark.parametrize(
("http_status", "should_retry"),
[
(HTTPStatus.OK, False),
(HTTPStatus.BAD_REQUEST, False),
(HTTPStatus.TOO_MANY_REQUESTS, True),
(HTTPStatus.INTERNAL_SERVER_ERROR, True),
],
)
def test_should_retry(patch_base_class, config, http_status, should_retry):
response_mock = MagicMock()
response_mock.status_code = http_status
stream = ZenloopStream(config["api_token"], config["date_from"], config["public_hash_id"])
assert stream.should_retry(response_mock) == should_retry


def test_backoff_time(patch_base_class, config):
response_mock = MagicMock()
stream = ZenloopStream(config["api_token"], config["date_from"], config["public_hash_id"])
expected_backoff_time = None
assert stream.backoff_time(response_mock) == expected_backoff_time
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These test might be redundant because you're not overriding these methods from the parent HttpStream class

expected_parsed_object = {"answers": [{"id": 123, "name": "John Doe"}]}
assert next(stream.parse_response(**inputs)) == expected_parsed_object


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could add tests for SurveyGroups and Surveys to increase coverage.

def test_check_connection(mocker, config):
source = SourceZenloop()
logger_mock = MagicMock()
assert source.check_connection(logger_mock, config) == (True, None)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is not passing, you might miss some mock because the real zenloop backend seems to be called... and moreover please test the behavior in case of error.

@alafanechere alafanechere removed the zzm label Nov 17, 2021
@AlexanderBatoulis
Copy link
Contributor Author

Thank you very much @AlexanderBatoulis for this contribution, I have some minor questions and suggestions that you'll find in my review comments. In addition, we configured a sandbox account for Zenloop and I'm afraid that the integration tests are not passing when we fill the public_hash_id field. The https://app.zenloop.com/settings/api page provides list of hash ids for surveys, but this value is reused to build requests to survey_groups endpoint in the AnswersSurveyGroup stream (survey_groups/{self.public_hash_id}/answers). It looks like the API expects a survey group id that is different from the public hash id provided in the config (which is expected to be a survey id and not a survey group id) and it leads to 404 error. TLDR: integration tests did not pass when setting public_hash_id to a valid value in our config.

Could you also fix conflicts with master please? 🙏

Hi @alafanechere,
Thank you very much for your thorough review! I resolved the not passing integration tests by adding another request parameter for survey_group_id.
Would be great if you could take another look and let me know if there is anything outstanding.

Kind regards,
Alex

@alafanechere
Copy link
Contributor

HI @AlexanderBatoulis , thanks for your modifications, I'll go for another review.

Copy link
Contributor

@alafanechere alafanechere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @AlexanderBatoulis , I tried to run the acceptance tests but they are failing. Could you please make sure the following command runs flawlessly?
./gradlew :airbyte-integrations:connectors:source-zenloop:integrationTest

@AlexanderBatoulis
Copy link
Contributor Author

Hi @alafanechere, this should run fine now - missed to update setup.py

Copy link
Contributor

@alafanechere alafanechere left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I'm happy with the change you've made and successfully ran the acceptance tests!
Ready to merge 👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/connectors Connector related issues area/documentation Improvements or additions to documentation bounty community connectors/source/zenloop
Projects
No open projects
Status: No status
Development

Successfully merging this pull request may close these issues.

7 participants