* Connector files * Add test files * Add integration test config files * Multiple changes to make it on Airbyte standards * Cleaning up * More clean ups * More clean ups * Removed max pages * Remove unused variable * Correctly separating Full refresh and incremental * Removed unused variables * Fix full_refresh class * Better code for creating stream classes * Fixing review comments * Update docs and Enum class * Update type conversion function * Fix enum class and update docs * Update discover * Implemented some unit tests * Update discover * Update test_source * Increase discovery test timeout * Update configured_catalog * Fix default_cursor_field * Adding final unit tests * Update spec: set client_id and tenant_id as secrets * Update discover to deal with Lookup and Picklist types * Fix Lookup data type conversion * add microsoft dataverse to source def * run format * auto-bump connector version Co-authored-by: Marcelo Pio de Castro <marcelopiocastro@gmail.com> Co-authored-by: daniloss99 <danilosiqueira99@gmail.com> Co-authored-by: Marcos Marx <marcosmarxm@users.noreply.github.com> Co-authored-by: marcosmarxm <marcosmarxm@gmail.com> Co-authored-by: Octavia Squidington III <octavia-squidington-iii@users.noreply.github.com>
81 lines
2.5 KiB
Python
81 lines
2.5 KiB
Python
#
|
|
# Copyright (c) 2022 Airbyte, Inc., all rights reserved.
|
|
#
|
|
|
|
from enum import Enum
|
|
from typing import Any, Mapping, MutableMapping, Optional
|
|
|
|
import requests
|
|
from airbyte_cdk.sources.streams.http.requests_native_auth.oauth import Oauth2Authenticator
|
|
|
|
|
|
class MicrosoftOauth2Authenticator(Oauth2Authenticator):
|
|
def build_refresh_request_body(self) -> Mapping[str, Any]:
|
|
"""
|
|
Returns the request body to set on the refresh request
|
|
"""
|
|
payload: MutableMapping[str, Any] = {
|
|
"grant_type": "client_credentials",
|
|
"client_id": self.get_client_id(),
|
|
"client_secret": self.get_client_secret(),
|
|
"scope": self.get_scopes(),
|
|
}
|
|
|
|
return payload
|
|
|
|
|
|
class AirbyteType(Enum):
|
|
|
|
String = {"type": ["null", "string"]}
|
|
Boolean = {"type": ["null", "boolean"]}
|
|
Timestamp = {"type": ["null", "string"], "format": "date-time", "airbyte_type": "timestamp_with_timezone"}
|
|
Integer = {"type": ["null", "integer"]}
|
|
Number = {"type": ["null", "number"]}
|
|
|
|
|
|
class DataverseType(Enum):
|
|
|
|
String = AirbyteType.String
|
|
Uniqueidentifier = AirbyteType.String
|
|
DateTime = AirbyteType.Timestamp
|
|
Integer = AirbyteType.Integer
|
|
BigInt = AirbyteType.Integer
|
|
Money = AirbyteType.Number
|
|
Boolean = AirbyteType.Boolean
|
|
Double = AirbyteType.Number
|
|
Decimal = AirbyteType.Number
|
|
Status = AirbyteType.Integer
|
|
State = AirbyteType.Integer
|
|
Picklist = AirbyteType.Integer
|
|
Lookup = AirbyteType.String
|
|
Virtual = None
|
|
|
|
|
|
def get_auth(config: Mapping[str, Any]) -> MicrosoftOauth2Authenticator:
|
|
return MicrosoftOauth2Authenticator(
|
|
token_refresh_endpoint=f'https://login.microsoftonline.com/{config["tenant_id"]}/oauth2/v2.0/token',
|
|
client_id=config["client_id"],
|
|
client_secret=config["client_secret_value"],
|
|
scopes=[f'{config["url"]}/.default'],
|
|
refresh_token="",
|
|
)
|
|
|
|
|
|
def do_request(config: Mapping[str, Any], path: str):
|
|
auth = get_auth(config)
|
|
headers = auth.get_auth_header()
|
|
# Call a protected API with the access token.
|
|
return requests.get(
|
|
config["url"] + "/api/data/v9.2/" + path,
|
|
headers=headers,
|
|
)
|
|
|
|
|
|
def convert_dataverse_type(dataverse_type: str) -> Optional[dict]:
|
|
if dataverse_type in DataverseType.__members__:
|
|
enum_type = DataverseType[dataverse_type]
|
|
if enum_type:
|
|
return enum_type.value if enum_type.value is None else enum_type.value.value
|
|
|
|
return AirbyteType.String.value
|