Skip to content

Commit e679191

Browse files
authored
✨ Source Sendgrid: Move contacts stream to async declarative component (#45191)
1 parent e4fec50 commit e679191

File tree

9 files changed

+508
-503
lines changed

9 files changed

+508
-503
lines changed

airbyte-integrations/connectors/source-sendgrid/metadata.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ data:
1010
connectorSubtype: api
1111
connectorType: source
1212
definitionId: fbb5fbe2-16ad-4cf4-af7d-ff9d9c316c87
13-
dockerImageTag: 1.0.18
13+
dockerImageTag: 1.1.0
1414
releases:
1515
breakingChanges:
1616
1.0.0:

airbyte-integrations/connectors/source-sendgrid/poetry.lock

+369-127
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

airbyte-integrations/connectors/source-sendgrid/pyproject.toml

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",]
33
build-backend = "poetry.core.masonry.api"
44

55
[tool.poetry]
6-
version = "1.0.18"
6+
version = "1.1.0"
77
name = "source-sendgrid"
88
description = "Source implementation for Sendgrid."
99
authors = [ "Airbyte <[email protected]>",]
@@ -16,8 +16,8 @@ repository = "https://github.com/airbytehq/airbyte"
1616
include = "source_sendgrid"
1717

1818
[tool.poetry.dependencies]
19-
python = "^3.9,<3.12"
20-
airbyte-cdk = "^0"
19+
python = "^3.10,<3.12"
20+
airbyte_cdk = "^5"
2121
pandas = "^2.1.1"
2222

2323
[tool.poetry.scripts]

airbyte-integrations/connectors/source-sendgrid/source_sendgrid/config_migrations.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@
88
import pendulum
99
from airbyte_cdk.config_observation import create_connector_config_control_message
1010
from airbyte_cdk.entrypoint import AirbyteEntrypoint
11+
from airbyte_cdk.models import AirbyteMessageSerializer
1112
from airbyte_cdk.sources import Source
1213
from airbyte_cdk.sources.message import InMemoryMessageRepository, MessageRepository
14+
from orjson import orjson
1315

1416
logger = logging.getLogger("airbyte_logger")
1517

@@ -68,7 +70,8 @@ def modify_and_save(cls, config_path: str, source: Source, config: Mapping[str,
6870

6971
@classmethod
7072
def emit_control_message(cls, migrated_config: Mapping[str, Any]) -> None:
71-
print(create_connector_config_control_message(migrated_config).json(exclude_unset=True))
73+
message = create_connector_config_control_message(migrated_config)
74+
print(orjson.dumps(AirbyteMessageSerializer.dump(message)).decode())
7275

7376
@classmethod
7477
def migrate(cls, args: List[str], source: Source) -> None:

airbyte-integrations/connectors/source-sendgrid/source_sendgrid/manifest.yaml

+57-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version: 0.81.1
1+
version: 5.5.0
22
type: DeclarativeSource
33
check:
44
type: CheckStream
@@ -874,6 +874,62 @@ streams:
874874
page_size: 100
875875
cursor_value: '{{ response.get("_metadata", {}).get("next", {}) }}'
876876
stop_condition: '{{ not response.get("_metadata", {}).get("next", {}) }}'
877+
878+
- type: DeclarativeStream
879+
name: contacts
880+
primary_key:
881+
- contact_id
882+
$parameters:
883+
name: contacts
884+
schema_loader:
885+
type: JsonFileSchemaLoader
886+
file_path: "./source_sendgrid/schemas/{{ parameters['name'] }}.json"
887+
retriever:
888+
type: AsyncRetriever
889+
status_mapping:
890+
running:
891+
- pending
892+
completed:
893+
- ready
894+
failed:
895+
- failed
896+
timeout:
897+
- timeout
898+
status_extractor:
899+
type: DpathExtractor
900+
field_path: ["status"]
901+
urls_extractor:
902+
type: DpathExtractor
903+
field_path: ["urls"]
904+
creation_requester:
905+
type: HttpRequester
906+
http_method: POST
907+
url_base: https://api.sendgrid.com
908+
path: /v3/marketing/contacts/exports
909+
authenticator:
910+
type: BearerAuthenticator
911+
api_token: "{{ config['api_key'] }}"
912+
polling_requester:
913+
type: HttpRequester
914+
http_method: GET
915+
url_base: https://api.sendgrid.com
916+
path: "/v3/marketing/contacts/exports/{{stream_slice['create_job_response'].json()['id'] }}"
917+
authenticator:
918+
type: BearerAuthenticator
919+
api_token: "{{ config['api_key'] }}"
920+
download_requester:
921+
type: HttpRequester
922+
http_method: GET
923+
url_base: ""
924+
path: "{{stream_slice['url']}}"
925+
record_selector:
926+
type: RecordSelector
927+
extractor:
928+
type: DpathExtractor
929+
field_path: []
930+
transformations:
931+
- type: KeysToLower
932+
877933
spec:
878934
connection_specification:
879935
$schema: http://json-schema.org/draft-07/schema#

airbyte-integrations/connectors/source-sendgrid/source_sendgrid/source.py

+1-17
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,10 @@
22
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
33
#
44

5-
from typing import Any, List, Mapping
65

76
from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource
8-
from airbyte_cdk.sources.streams import Stream
9-
from airbyte_cdk.sources.streams.http.requests_native_auth import TokenAuthenticator
107

11-
from .streams import Contacts
128

13-
14-
# Hybrid Declarative Source
159
class SourceSendgrid(YamlDeclarativeSource):
16-
def __init__(self):
17-
# this takes care of check and other methods
10+
def __init__(self) -> None:
1811
super().__init__(**{"path_to_yaml": "manifest.yaml"})
19-
20-
def streams(self, config: Mapping[str, Any]) -> List[Stream]:
21-
# get all the lowcode streams
22-
streams = super().streams(config)
23-
authenticator = TokenAuthenticator(config["api_key"])
24-
# this stream download a csv file from sendgrid and emits the records
25-
# it's not currently easy to do in lowcode, so we do it in python
26-
streams.append(Contacts(authenticator=authenticator))
27-
return streams

airbyte-integrations/connectors/source-sendgrid/source_sendgrid/streams.py

-199
This file was deleted.

0 commit comments

Comments
 (0)