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

[Low Code CDK] configurable oauth request payload #13993

Merged
merged 16 commits into from
Jul 8, 2022

Conversation

brianjlai
Copy link
Contributor

@brianjlai brianjlai commented Jun 22, 2022

What

Adds the ability to configure additional fields thats can go into the request body made when refreshing tokens as part of the oauth flow.

How

Uses the existing Oauth2Authenticator class and adds an additional config field called refresh_request_body which is a mapping of fields to values that will go into the outbound request. In the event of a conflict between oauth language names like client_id or refresh_token we will defer to the existing value instead of the override.

Recommended reading order

  1. requests_native_auth/oauth.python
  2. factory.py

🚨 User Impact 🚨

Are there any breaking changes? What is the end result perceived by the user? If yes, please merge this PR with the 🚨🚨 emoji so changelog authors can further highlight this if needed.

Pre-merge Checklist

Expand the relevant checklist and delete the others.

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/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

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
  • If new credentials are required for use in CI, add them to GSM. Instructions.
  • /test connector=connectors/<name> command is passing
  • New Connector version released on Dockerhub by running the /publish command described here
  • After the connector is published, connector added to connector index as described here
  • Seed specs have been re-generated by building the platform and committing the changes to the seed spec files, as described here
Updating a connector

Community member or Airbyter

  • 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
    • Changelog updated in docs/integrations/<source or destination>/<name>.md including changelog. See changelog example
  • PR name follows PR naming conventions

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
  • If new credentials are required for use in CI, add them to GSM. Instructions.
  • /test connector=connectors/<name> command is passing
  • New Connector version released on Dockerhub and connector version bumped by running the /publish command described here
Connector Generator
  • Issue acceptance criteria met
  • PR name follows PR naming conventions
  • If adding a new generator, add it to the list of scaffold modules being tested
  • The generator test modules (all connectors with -scaffold in their name) have been updated with the latest scaffold by running ./gradlew :airbyte-integrations:connector-templates:generator:testScaffoldTemplates then checking in your changes
  • Documentation which references the generator is updated as needed

Tests

Unit

Put your unit tests output here.

Integration

Put your integration tests output here.

Acceptance

Put your acceptance tests output here.

@github-actions github-actions bot added the CDK Connector Development Kit label Jun 22, 2022
@@ -27,13 +27,15 @@ def __init__(
refresh_token: str,
scopes: List[str] = None,
refresh_access_token_headers: Mapping[str, Any] = None,
refresh_request_body: Mapping[str, Any] = None,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

/auth/oauth.py is marked as deprecated so I wasn't sure if I needed to update this flow. Other recent PRs update both files so I did the same.

@@ -52,6 +53,8 @@ def _create_subcomponent(self, v, kwargs, config):
v["options"] = self._merge_dicts(kwargs.get("options", dict()), v.get("options", dict()))

return self.create_component(v, config)()
elif isinstance(v, dict):
return InterpolatedMapping(v).eval(config=config, kwargs=kwargs)
Copy link
Contributor Author

@brianjlai brianjlai Jun 23, 2022

Choose a reason for hiding this comment

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

The existing code only supports interpolating new class components, but does not currently support standalone dictionary interpolation. Since we first check if there is a class_name, for component mappings, we'll skip over and just return the uninterpolated map. For example, this wouldn't work:

authenticator:
  refresh_request_body:
    grant_type: "refresh_token"
    client_secret: "{{ config['client_secret'] }}"
    redirect_uri: "{{ config['redirect_uri'] }}

One caveat with this code is that the standalone dictionary doesn't support options at this level because we don't merge existing and current level options. We could potentially add in something like: self._merge_dicts(kwargs.get("options", dict()), v.get("options", dict())), but I think we'd want to discourage nesting options into the standalone dictionary. It's just confusing from a DX standpoint.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

on second thought, this introduces kind of a concerning side effect to our component generation. For most of our existing components, we interpolate at run time, this change to the factory forces it at parse/instantiation time for all components, which we don't want...

I think this all comes about since we're reusing the existing Oauth2Authenticator shared by declarative and normal integrations. I'd have to shove an interpolator and configs/kwargs/options into the class for get_refresh_request_body() to interpolate like I'd expect it to. I'll think on this a little bit more.

Copy link
Contributor

Choose a reason for hiding this comment

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

@brianjlai would it make sense for the factory to create an InterpolatedMapping instead of a standard map when there is no class_name so we can always do interpolation?

@brianjlai brianjlai requested a review from girarda June 23, 2022 00:01
@brianjlai brianjlai marked this pull request as ready for review June 23, 2022 00:04
@brianjlai brianjlai requested a review from a team as a code owner July 1, 2022 04:20
from requests.auth import AuthBase


class Oauth2Authenticator(AuthBase):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

as per some offline discussion, we're now going to have a separate declarative oauth authenticator. Its annoying that we have a declarative oauth authenticator that looks roughly similar to the existing CDK one. But at least this can support runtime interpolation w/o shoe horning it into the existing implementation.

}


class TestOauth2Authenticator:
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a rough copy of the existing unit tests to ensure we retain the same feature set, but w/ a few extra test variations that rely on inputs that require interpolation.

@brianjlai brianjlai changed the title configurable oauth request payload [Low Code CDK] configurable oauth request payload Jul 1, 2022
Copy link
Contributor

@girarda girarda left a comment

Choose a reason for hiding this comment

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

lgtm but worth running tests for a few connectors using the existing authenticator

@brianjlai
Copy link
Contributor Author

100% since this affects the existing connector workflow a little bit

from airbyte_cdk.sources.streams.http.requests_native_auth.abstract_oauth import AbstractOauth2Authenticator


class DeclarativeOauth2Authenticator(AbstractOauth2Authenticator):
Copy link
Contributor

Choose a reason for hiding this comment

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

should we move this to the declarative package so the inter-module dependencies only go in one direction?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good point. i didn't really consider that, but I think it makes sense to keep interpolation out of existing cdk code as much as possible. will move this

@brianjlai
Copy link
Contributor Author

brianjlai commented Jul 7, 2022

/test connector=connectors/source-hubspot

🕑 connectors/source-hubspot https://github.com/airbytehq/airbyte/actions/runs/2627238463
✅ connectors/source-hubspot https://github.com/airbytehq/airbyte/actions/runs/2627238463
Python tests coverage:

Name                                                 Stmts   Miss  Cover
------------------------------------------------------------------------
source_acceptance_test/utils/__init__.py                 6      0   100%
source_acceptance_test/tests/__init__.py                 4      0   100%
source_acceptance_test/__init__.py                       2      0   100%
source_acceptance_test/tests/test_full_refresh.py       52      2    96%
source_acceptance_test/utils/asserts.py                 37      2    95%
source_acceptance_test/config.py                        77      6    92%
source_acceptance_test/utils/json_schema_helper.py     105     13    88%
source_acceptance_test/tests/test_incremental.py       121     25    79%
source_acceptance_test/utils/common.py                  80     17    79%
source_acceptance_test/tests/test_core.py              294    106    64%
source_acceptance_test/utils/compare.py                 62     23    63%
source_acceptance_test/base.py                          10      4    60%
source_acceptance_test/utils/connector_runner.py       110     48    56%
------------------------------------------------------------------------
TOTAL                                                  960    246    74%
Name                         Stmts   Miss  Cover
------------------------------------------------
source_hubspot/errors.py         6      0   100%
source_hubspot/__init__.py       2      0   100%
source_hubspot/helpers.py       70      3    96%
source_hubspot/streams.py      764     65    91%
source_hubspot/source.py        97     21    78%
------------------------------------------------
TOTAL                          939     89    91%

Build Passed

Test summary info:

All Passed

@brianjlai
Copy link
Contributor Author

brianjlai commented Jul 7, 2022

/test connector=connectors/source-slack

🕑 connectors/source-slack https://github.com/airbytehq/airbyte/actions/runs/2627246241

@brianjlai
Copy link
Contributor Author

brianjlai commented Jul 7, 2022

/test connector=connectors/source-linnworks

🕑 connectors/source-linnworks https://github.com/airbytehq/airbyte/actions/runs/2627246265
❌ connectors/source-linnworks https://github.com/airbytehq/airbyte/actions/runs/2627246265
🐛 https://gradle.com/s/6aeiqjfzyi3ds

Build Failed

Test summary info:

=========================== short test summary info ============================
FAILED test_core.py::TestBasicRead::test_read[inputs0] - docker.errors.Contai...
FAILED test_full_refresh.py::TestFullRefresh::test_sequential_reads[inputs0]
FAILED test_incremental.py::TestIncremental::test_two_sequential_reads[inputs0]
FAILED test_incremental.py::TestIncremental::test_read_sequential_slices[inputs0]
FAILED test_incremental.py::TestIncremental::test_state_with_abnormally_large_values[inputs0]
======================== 5 failed, 19 passed in 22.95s =========================

@brianjlai
Copy link
Contributor Author

brianjlai commented Jul 7, 2022

/test connector=connectors/source-square

🕑 connectors/source-square https://github.com/airbytehq/airbyte/actions/runs/2627342423
❌ connectors/source-square https://github.com/airbytehq/airbyte/actions/runs/2627342423
🐛 https://gradle.com/s/aob2aeuaywkhy

Build Failed

Test summary info:

=========================== short test summary info ============================
FAILED test_core.py::TestSpec::test_oneof_usage[inputs0] - AssertionError: Th...
FAILED test_core.py::TestBasicRead::test_read[inputs0] - AssertionError: All ...
=================== 2 failed, 31 passed in 69.46s (0:01:09) ====================

@brianjlai
Copy link
Contributor Author

brianjlai commented Jul 7, 2022

/test connector=connectors/source-strava

🕑 connectors/source-strava https://github.com/airbytehq/airbyte/actions/runs/2627343218
❌ connectors/source-strava https://github.com/airbytehq/airbyte/actions/runs/2627343218
🐛

@brianjlai
Copy link
Contributor Author

brianjlai commented Jul 7, 2022

/test connector=connectors/source-github

🕑 connectors/source-github https://github.com/airbytehq/airbyte/actions/runs/2632580902
✅ connectors/source-github https://github.com/airbytehq/airbyte/actions/runs/2632580902
Python tests coverage:

Name                                                 Stmts   Miss  Cover
------------------------------------------------------------------------
source_acceptance_test/utils/__init__.py                 6      0   100%
source_acceptance_test/tests/__init__.py                 4      0   100%
source_acceptance_test/__init__.py                       2      0   100%
source_acceptance_test/tests/test_full_refresh.py       52      2    96%
source_acceptance_test/utils/asserts.py                 37      2    95%
source_acceptance_test/config.py                        77      6    92%
source_acceptance_test/utils/json_schema_helper.py     105     13    88%
source_acceptance_test/tests/test_incremental.py       121     25    79%
source_acceptance_test/utils/common.py                  80     17    79%
source_acceptance_test/tests/test_core.py              294    106    64%
source_acceptance_test/utils/compare.py                 62     23    63%
source_acceptance_test/base.py                          10      4    60%
source_acceptance_test/utils/connector_runner.py       110     48    56%
------------------------------------------------------------------------
TOTAL                                                  960    246    74%
Name                             Stmts   Miss  Cover
----------------------------------------------------
source_github/utils.py               6      0   100%
source_github/github_schema.py    8807      0   100%
source_github/__init__.py            2      0   100%
source_github/graphql.py            47      1    98%
source_github/streams.py           667     36    95%
source_github/source.py             92     27    71%
----------------------------------------------------
TOTAL                             9621     64    99%

Build Passed

Test summary info:

All Passed

@brianjlai
Copy link
Contributor Author

brianjlai commented Jul 7, 2022

/test connector=connectors/source-salesforce

🕑 connectors/source-salesforce https://github.com/airbytehq/airbyte/actions/runs/2632586979
✅ connectors/source-salesforce https://github.com/airbytehq/airbyte/actions/runs/2632586979
Python tests coverage:

Name                                                 Stmts   Miss  Cover
------------------------------------------------------------------------
source_acceptance_test/utils/__init__.py                 6      0   100%
source_acceptance_test/tests/__init__.py                 4      0   100%
source_acceptance_test/__init__.py                       2      0   100%
source_acceptance_test/tests/test_full_refresh.py       52      2    96%
source_acceptance_test/utils/asserts.py                 37      2    95%
source_acceptance_test/config.py                        77      6    92%
source_acceptance_test/utils/json_schema_helper.py     105     13    88%
source_acceptance_test/tests/test_incremental.py       121     25    79%
source_acceptance_test/utils/common.py                  80     17    79%
source_acceptance_test/tests/test_core.py              294    106    64%
source_acceptance_test/utils/compare.py                 62     23    63%
source_acceptance_test/base.py                          10      4    60%
source_acceptance_test/utils/connector_runner.py       110     48    56%
------------------------------------------------------------------------
TOTAL                                                  960    246    74%
Name                                 Stmts   Miss  Cover
--------------------------------------------------------
source_salesforce/__init__.py            2      0   100%
source_salesforce/exceptions.py          8      1    88%
source_salesforce/api.py               150     19    87%
source_salesforce/streams.py           307     67    78%
source_salesforce/rate_limiting.py      22      6    73%
source_salesforce/source.py             77     33    57%
source_salesforce/utils.py               8      7    12%
--------------------------------------------------------
TOTAL                                  574    133    77%
Name                                 Stmts   Miss  Cover
--------------------------------------------------------
source_salesforce/utils.py               8      0   100%
source_salesforce/__init__.py            2      0   100%
source_salesforce/source.py             77      6    92%
source_salesforce/api.py               150     14    91%
source_salesforce/exceptions.py          8      1    88%
source_salesforce/rate_limiting.py      22      3    86%
source_salesforce/streams.py           307     43    86%
--------------------------------------------------------
TOTAL                                  574     67    88%

Build Passed

Test summary info:

All Passed

@brianjlai
Copy link
Contributor Author

brianjlai commented Jul 7, 2022

/test connector=connectors/source-stripe

🕑 connectors/source-stripe https://github.com/airbytehq/airbyte/actions/runs/2632590668
✅ connectors/source-stripe https://github.com/airbytehq/airbyte/actions/runs/2632590668
Python tests coverage:

Name                                                 Stmts   Miss  Cover
------------------------------------------------------------------------
source_acceptance_test/utils/__init__.py                 6      0   100%
source_acceptance_test/tests/__init__.py                 4      0   100%
source_acceptance_test/__init__.py                       2      0   100%
source_acceptance_test/tests/test_full_refresh.py       52      2    96%
source_acceptance_test/utils/asserts.py                 37      2    95%
source_acceptance_test/config.py                        77      6    92%
source_acceptance_test/utils/json_schema_helper.py     105     13    88%
source_acceptance_test/tests/test_incremental.py       121     25    79%
source_acceptance_test/utils/common.py                  80     17    79%
source_acceptance_test/tests/test_core.py              294    106    64%
source_acceptance_test/utils/compare.py                 62     23    63%
source_acceptance_test/base.py                          10      4    60%
source_acceptance_test/utils/connector_runner.py       110     48    56%
------------------------------------------------------------------------
TOTAL                                                  960    246    74%
Name                        Stmts   Miss  Cover
-----------------------------------------------
source_stripe/source.py        22      0   100%
source_stripe/__init__.py       2      0   100%
source_stripe/streams.py      261     11    96%
-----------------------------------------------
TOTAL                         285     11    96%

Build Passed

Test summary info:

All Passed

@brianjlai
Copy link
Contributor Author

brianjlai commented Jul 7, 2022

/test connector=connectors/source-chargebee

🕑 connectors/source-chargebee https://github.com/airbytehq/airbyte/actions/runs/2632591320
✅ connectors/source-chargebee https://github.com/airbytehq/airbyte/actions/runs/2632591320
Python tests coverage:

Name                                                 Stmts   Miss  Cover
------------------------------------------------------------------------
source_acceptance_test/utils/__init__.py                 6      0   100%
source_acceptance_test/tests/__init__.py                 4      0   100%
source_acceptance_test/__init__.py                       2      0   100%
source_acceptance_test/tests/test_full_refresh.py       52      2    96%
source_acceptance_test/utils/asserts.py                 37      2    95%
source_acceptance_test/config.py                        77      6    92%
source_acceptance_test/utils/json_schema_helper.py     105     13    88%
source_acceptance_test/tests/test_incremental.py       121     25    79%
source_acceptance_test/utils/common.py                  80     17    79%
source_acceptance_test/tests/test_core.py              294    106    64%
source_acceptance_test/utils/compare.py                 62     23    63%
source_acceptance_test/base.py                          10      4    60%
source_acceptance_test/utils/connector_runner.py       110     48    56%
------------------------------------------------------------------------
TOTAL                                                  960    246    74%
Name                                Stmts   Miss  Cover
-------------------------------------------------------
source_chargebee/source.py             25      0   100%
source_chargebee/__init__.py            2      0   100%
source_chargebee/streams.py           159     27    83%
source_chargebee/rate_limiting.py      19      7    63%
-------------------------------------------------------
TOTAL                                 205     34    83%

Build Passed

Test summary info:

All Passed

@girarda girarda mentioned this pull request Jul 8, 2022
37 tasks
@brianjlai
Copy link
Contributor Author

brianjlai commented Jul 8, 2022

I wasn't super convinced that we run SAT on a PR against the current CDK changes (similar to how we had that gap in source acceptance tests before). But either way, I did some sanity checks against a couple of the connectors that use the new requests_native_auth locally for Hubspot and Square and both seem to look okay

@brianjlai
Copy link
Contributor Author

brianjlai commented Jul 8, 2022

/publish-cdk dry-run=true

🕑 https://github.com/airbytehq/airbyte/actions/runs/2638168045
https://github.com/airbytehq/airbyte/actions/runs/2638168045

@brianjlai
Copy link
Contributor Author

brianjlai commented Jul 8, 2022

/publish-cdk dry-run=false

🕑 https://github.com/airbytehq/airbyte/actions/runs/2638212414
https://github.com/airbytehq/airbyte/actions/runs/2638212414

@brianjlai
Copy link
Contributor Author

brianjlai commented Jul 8, 2022

/publish-cdk dry-run=true

🕑 https://github.com/airbytehq/airbyte/actions/runs/2638406518
https://github.com/airbytehq/airbyte/actions/runs/2638406518

@brianjlai
Copy link
Contributor Author

brianjlai commented Jul 8, 2022

/publish-cdk dry-run=false

🕑 https://github.com/airbytehq/airbyte/actions/runs/2638452018
https://github.com/airbytehq/airbyte/actions/runs/2638452018

@brianjlai brianjlai merged commit 374e265 into master Jul 8, 2022
@brianjlai brianjlai deleted the brian/oauth_configurable_payload branch July 8, 2022 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CDK Connector Development Kit
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants