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

Connector Health: Fixed SAT for close-com, facebook-marketing, freshsales, greenhouse, hubspot, intercom, jira, mixpanel, monday, pipedrive, recharge, sentry, slack, strava, stripe, trello, twitter, youtube-analytics, twillio, faker #24361

Merged
merged 20 commits into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,10 @@
icon: mixpanel.svg
sourceType: api
releaseStage: generally_available
allowedHosts:
hosts:
- "mixpanel.com"
- "eu.mixpanel.com"
- name: Monday
sourceDefinitionId: 80a54ea2-9959-4040-aac1-eee42423ec9b
dockerRepository: airbyte/source-monday
Expand Down Expand Up @@ -2205,6 +2209,9 @@
icon: youtube-analytics.svg
sourceType: api
releaseStage: beta
allowedHosts:
hosts:
- "*.googleapis.com"
- name: Vantage
sourceDefinitionId: 28ce1fbd-1e15-453f-aa9f-da6c4d928e92
dockerRepository: airbyte/source-vantage
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from airbyte_cdk.models import AuthSpecification, ConnectorSpecification, DestinationSyncMode, OAuth2Specification
from airbyte_cdk.sources import AbstractSource
from airbyte_cdk.sources.streams import Stream
from pydantic.error_wrappers import ValidationError
from source_facebook_marketing.api import API
from source_facebook_marketing.spec import ConnectorConfig
from source_facebook_marketing.streams import (
Expand Down Expand Up @@ -55,14 +56,15 @@ def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) ->
:param config: the user-input config object conforming to the connector's spec.json
:return Tuple[bool, Any]: (True, None) if the input config can be used to connect to the API successfully, (False, error) otherwise.
"""
config = self._validate_and_transform(config)
if config.end_date < config.start_date:
return False, "end_date must be equal or after start_date."

try:
config = self._validate_and_transform(config)

if config.end_date < config.start_date:
return False, "end_date must be equal or after start_date."

api = API(account_id=config.account_id, access_token=config.access_token)
logger.info(f"Select account {api.account}")
except requests.exceptions.RequestException as e:
except (requests.exceptions.RequestException, ValidationError) as e:
return False, e

# make sure that we have valid combination of "action_breakdowns" and "breakdowns" parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

from copy import deepcopy

import pydantic
import pytest
from airbyte_cdk.models import AirbyteConnectionStatus, ConnectorSpecification, Status
from facebook_business import FacebookAdsApi, FacebookSession
Expand Down Expand Up @@ -69,19 +68,17 @@ def test_check_connection_end_date_before_start_date(self, api, config, logger_m

def test_check_connection_empty_config(self, api, logger_mock):
config = {}
ok, error_msg = SourceFacebookMarketing().check_connection(logger_mock, config=config)

with pytest.raises(pydantic.ValidationError):
SourceFacebookMarketing().check_connection(logger_mock, config=config)

assert not api.called
assert not ok
assert error_msg

def test_check_connection_invalid_config(self, api, config, logger_mock):
config.pop("start_date")
ok, error_msg = SourceFacebookMarketing().check_connection(logger_mock, config=config)

with pytest.raises(pydantic.ValidationError):
SourceFacebookMarketing().check_connection(logger_mock, config=config)

assert not api.called
assert not ok
assert error_msg

def test_check_connection_exception(self, api, config, logger_mock):
api.side_effect = RuntimeError("Something went wrong!")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ acceptance_tests:
basic_read:
tests:
- config_path: secrets/config.json
empty_streams: []
expect_records:
path: integration_tests/expected_records.jsonl
full_refresh:
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ acceptance_tests:
- config_path: "secrets/config.json"
status: "succeed"
- config_path: "integration_tests/invalid_config.json"
status: "failed"
status: "exception"
discovery:
tests:
- config_path: "secrets/config.json"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ acceptance_tests:
expect_records:
path: "integration_tests/expected_records.jsonl"
fail_on_extra_columns: false
ignored_fields:
users:
- name: updated_at
bypass_reason: "Updated when you login to account"
full_refresh:
tests:
- config_path: "secrets/config.json"
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
{"stream": "admins", "data": {"type": "admin", "email": "integration-test@airbyte.io", "id": "4423433", "name": "Airbyte Team", "away_mode_enabled": false, "away_mode_reassign": false, "has_inbox_seat": true, "team_ids": [5077733], "team_priority_level": {"primary_team_ids": [5077733]}}, "emitted_at": 1674662478119}
{"stream": "admins", "data": {"type": "admin", "email": "operator+wjw5eps7@intercom.io", "id": "4423434", "name": "Operator", "away_mode_enabled": false, "away_mode_reassign": false, "has_inbox_seat": false, "team_ids": [], "team_priority_level": {}}, "emitted_at": 1674662478120}
{"stream": "admins", "data": {"type": "admin", "email": "jared@daxtarity.com", "id": "4425337", "name": "Jared Rhizor", "away_mode_enabled": false, "away_mode_reassign": false, "has_inbox_seat": false, "team_ids": [], "team_priority_level": {}}, "emitted_at": 1674662478120}
{"stream": "companies", "data": {"type": "company", "company_id": "63ecc3d60e3c81baaad9f9ef-qualification-company", "id": "63ecc3d60e3c81baaad9f9ee", "app_id": "wjw5eps7", "name": "Company 1", "created_at": 1676461015, "updated_at": 1676461042, "monthly_spend": 0.0, "session_count": 0, "user_count": 1, "size": 25, "website": "www.company1.com", "industry": "Sales", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": null}}, "emitted_at": 1674662479200}
{"stream": "companies", "data": {"type": "company", "company_id": "63ecc5d32059cdacf4ac6171-qualification-company", "id": "63ecc5d32059cdacf4ac6170", "app_id": "wjw5eps7", "name": "Test Company 9", "created_at": 1676461523, "updated_at": 1676461542, "monthly_spend": 0.0, "session_count": 0, "user_count": 1, "size": 75, "website": "www.company9.com", "industry": "Sales", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {}}, "emitted_at": 1674662479201}
{"stream": "companies", "data": {"type": "company", "company_id": "63ecc4af3c8e034aa0ce74e2-qualification-company", "id": "63ecc4af3c8e034aa0ce74e1", "app_id": "wjw5eps7", "name": "Test Company 5", "created_at": 1676461231, "updated_at": 1676461928, "monthly_spend": 0.0, "session_count": 0, "user_count": 1, "size": 98, "website": "www.company5.com", "industry": "Sales", "tags": {"type": "tag.list", "tags": [{"type": "tag", "id": 7799633, "name": "Tag5"}, {"type": "tag", "id": 7799634, "name": "Tag6"}, {"type": "tag", "id": 7799640, "name": "Tag10"}]}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {}}, "emitted_at": 1674662479201}
{"stream": "admins", "data": {"type": "admin", "email": "integration-test@airbyte.io", "id": "4423433", "name": "Airbyte Team", "job_title": "Admin", "away_mode_enabled": false, "away_mode_reassign": false, "has_inbox_seat": true, "team_ids": [5077733], "team_priority_level": {"primary_team_ids": [5077733]}}, "emitted_at": 1679497749992}
{"stream": "admins", "data": {"type": "admin", "email": "operator+wjw5eps7@intercom.io", "id": "4423434", "name": "Operator", "away_mode_enabled": false, "away_mode_reassign": false, "has_inbox_seat": false, "team_ids": [], "team_priority_level": {}}, "emitted_at": 1679497749992}
{"stream": "companies", "data": {"type": "company", "company_id": "63ecc52f00fc87e58e8fb1f2-qualification-company", "id": "63ecc52f00fc87e58e8fb1f1", "app_id": "wjw5eps7", "name": "Test Company 7", "created_at": 1676461359, "updated_at": 1679484653, "monthly_spend": 0.0, "session_count": 0, "user_count": 1, "size": 23, "website": "www.company7.com", "industry": "Production", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1679999066538}
{"stream": "companies", "data": {"type": "company", "company_id": "63ecc5731d460cdc137c906d-qualification-company", "id": "63ecc5731d460cdc137c906c", "app_id": "wjw5eps7", "name": "Test Company 8", "created_at": 1676461427, "updated_at": 1679484652, "monthly_spend": 0.0, "session_count": 0, "user_count": 1, "size": 49, "website": "www.company8.com", "industry": "Manufacturing", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1679999066540}
{"stream": "companies", "data": {"type": "company", "company_id": "63ecc4af3c8e034aa0ce74e2-qualification-company", "id": "63ecc4af3c8e034aa0ce74e1", "app_id": "wjw5eps7", "name": "Test Company 5", "created_at": 1676461231, "updated_at": 1679484653, "monthly_spend": 0.0, "session_count": 0, "user_count": 1, "size": 98, "website": "www.company5.com", "industry": "Sales", "tags": {"type": "tag.list", "tags": [{"type": "tag", "id": 7799633, "name": "Tag5"}, {"type": "tag", "id": 7799634, "name": "Tag6"}, {"type": "tag", "id": 7799640, "name": "Tag10"}]}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1679999066541}
{"stream": "company_attributes", "data": {"type": "data_attribute", "name": "name", "full_name": "name", "label": "Company name", "description": "The name of a company", "data_type": "string", "api_writable": true, "ui_writable": true, "custom": false, "archived": false, "model": "company"}, "emitted_at": 1674662480699}
{"stream": "company_attributes", "data": {"type": "data_attribute", "name": "company_id", "full_name": "company_id", "label": "Company ID", "description": "A number identifying a company", "data_type": "string", "api_writable": false, "ui_writable": false, "custom": false, "archived": false, "model": "company"}, "emitted_at": 1674662480700}
{"stream": "company_attributes", "data": {"type": "data_attribute", "name": "last_request_at", "full_name": "last_request_at", "label": "Company last seen", "description": "The last day anyone from a company visited your site or app", "data_type": "date", "api_writable": false, "ui_writable": false, "custom": false, "archived": false, "model": "company"}, "emitted_at": 1674662480700}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,15 @@ def test_companies_scroll(stream_attributes):
for slice in stream2.stream_slices(sync_mode=SyncMode.full_refresh):
records += list(stream2.read_records(sync_mode=SyncMode.full_refresh, stream_slice=slice))
assert len(records) == 12
assert (time.time() - start_time) > 60.0
assert int(time.time() - start_time) >= 60.0

start_time = time.time()
# read all records
records = []
for slice in stream3.stream_slices(sync_mode=SyncMode.full_refresh):
records += list(stream3.read_records(sync_mode=SyncMode.full_refresh, stream_slice=slice))
assert len(records) == 12
assert (time.time() - start_time) < 5.0
assert int(time.time() - start_time) <= 5.0


@patch("source_intercom.source.Companies.can_use_scroll", lambda *args: False)
Expand All @@ -130,12 +130,12 @@ def test_switch_to_standard_endpoint(stream_attributes):
assert stream2._endpoint_type == Companies.EndpointType.standard
assert stream2._total_count == 12
assert len(records) == 12
assert (time.time() - start_time) < 5.0
assert int(time.time() - start_time) <= 5.0

start_time = time.time()
# read all children records
records = []
for slice in stream3.stream_slices(sync_mode=SyncMode.full_refresh):
records += list(stream3.read_records(sync_mode=SyncMode, stream_slice=slice))
assert len(records) == 17
assert (time.time() - start_time) < 8.0
assert int(time.time() - start_time) <= 8.0
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ acceptance_tests:
bypass_reason: "unable to populate"
- name: "screen_tab_fields"
bypass_reason: "unable to populate"
timeout_seconds: 2400
fail_on_extra_columns: false
incremental:
tests:
Expand Down
29 changes: 17 additions & 12 deletions airbyte-integrations/connectors/source-jira/source_jira/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
from typing import Any, List, Mapping, Optional, Tuple

import pendulum
import requests
from airbyte_cdk import AirbyteLogger
from airbyte_cdk.sources import AbstractSource
from airbyte_cdk.sources.streams import Stream
from airbyte_cdk.sources.streams.http.auth import BasicHttpAuthenticator
from pydantic.error_wrappers import ValidationError

from .streams import (
ApplicationRoles,
Expand Down Expand Up @@ -81,18 +83,21 @@ def get_authenticator(config: Mapping[str, Any]):
return BasicHttpAuthenticator(config["email"], config["api_token"])

def check_connection(self, logger: AirbyteLogger, config: Mapping[str, Any]) -> Tuple[bool, Optional[Any]]:
config = self._validate_and_transform(config)
authenticator = self.get_authenticator(config)
kwargs = {"authenticator": authenticator, "domain": config["domain"], "projects": config["projects"]}
labels_stream = Labels(**kwargs)
next(read_full_refresh(labels_stream), None)
# check projects
projects_stream = Projects(**kwargs)
projects = {project["key"] for project in read_full_refresh(projects_stream)}
unknown_projects = set(config["projects"]) - projects
if unknown_projects:
return False, "unknown project(s): " + ", ".join(unknown_projects)
return True, None
try:
config = self._validate_and_transform(config)
authenticator = self.get_authenticator(config)
kwargs = {"authenticator": authenticator, "domain": config["domain"], "projects": config["projects"]}
labels_stream = Labels(**kwargs)
next(read_full_refresh(labels_stream), None)
# check projects
projects_stream = Projects(**kwargs)
projects = {project["key"] for project in read_full_refresh(projects_stream)}
unknown_projects = set(config["projects"]) - projects
if unknown_projects:
return False, "unknown project(s): " + ", ".join(unknown_projects)
return True, None
except (requests.exceptions.RequestException, ValidationError) as e:
return False, e

def streams(self, config: Mapping[str, Any]) -> List[Stream]:
config = self._validate_and_transform(config)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ def check_connection(self, logger: AirbyteLogger, config: Mapping[str, Any]) ->
:param logger: logger object
:return Tuple[bool, any]: (True, None) if the input config can be used to connect to the API successfully, (False, error) otherwise.
"""
config = self._validate_and_transform(config)
try:
config = self._validate_and_transform(config)
auth = self.get_authenticator(config)
FunnelsList.max_retries = 0
funnels = FunnelsList(authenticator=auth, **config)
Expand Down
Loading