Skip to content

Commit d211d41

Browse files
author
Anton Karpets
authored
🎉Source Marketo: migrate to low-code (#36854)
Signed-off-by: Artem Inzhyyants <[email protected]>
1 parent bc7b4cb commit d211d41

File tree

12 files changed

+701
-359
lines changed

12 files changed

+701
-359
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[run]
2+
omit =
3+
source_klaviyo/run.py

airbyte-integrations/connectors/source-marketo/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ See `sample_files/sample_config.json` for a sample config file.
3030
poetry run source-marketo spec
3131
poetry run source-marketo check --config secrets/config.json
3232
poetry run source-marketo discover --config secrets/config.json
33-
poetry run source-marketo read --config secrets/config.json --catalog sample_files/configured_catalog.json
33+
poetry run source-marketo read --config secrets/config.json --catalog integration_tests/configured_catalog.json
3434
```
3535

3636
### Running unit tests

airbyte-integrations/connectors/source-marketo/acceptance-test-config.yml

+2
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ acceptance_tests:
101101
bypass_reason: "Marketo does not provide a way to populate this stream without outside interaction"
102102
- name: "activities_interactedwith_documentin_conversational_flow"
103103
bypass_reason: "Marketo does not provide a way to populate this stream without outside interaction"
104+
- name: "activities_create_buying_group"
105+
bypass_reason: "Marketo does not provide a way to populate this stream without outside interaction"
104106
# 52 streams, most of them use BULK API therefore it takes much time to run a sync
105107
timeout_seconds: 9000
106108
fail_on_extra_columns: false

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ data:
1010
connectorSubtype: api
1111
connectorType: source
1212
definitionId: 9e0556f4-69df-4522-a3fb-03264d36b348
13-
dockerImageTag: 1.3.2
13+
dockerImageTag: 1.4.0
1414
dockerRepository: airbyte/source-marketo
1515
documentationUrl: https://docs.airbyte.com/integrations/sources/marketo
1616
githubIssueLabel: source-marketo
@@ -31,5 +31,5 @@ data:
3131
supportLevel: certified
3232
tags:
3333
- language:python
34-
- cdk:python
34+
- cdk:low-code
3535
metadataSpecVersion: "1.0"

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

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

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

+2-2
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.3.2"
6+
version = "1.4.0"
77
name = "source-marketo"
88
description = "Source implementation for Marketo."
99
authors = [ "Airbyte <[email protected]>",]
@@ -17,7 +17,7 @@ include = "source_marketo"
1717

1818
[tool.poetry.dependencies]
1919
python = "^3.9,<3.12"
20-
airbyte-cdk = "0.80.0"
20+
airbyte-cdk = "^0"
2121

2222
[tool.poetry.scripts]
2323
source-marketo = "source_marketo.run:run"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
version: 0.79.1
2+
type: DeclarativeSource
3+
4+
definitions:
5+
# Authenticator
6+
authenticator:
7+
type: OAuthAuthenticator
8+
client_id: "{{ config['client_id'] }}"
9+
client_secret: "{{ config['client_secret'] }}"
10+
token_refresh_endpoint: "{{ config['domain_url'] }}/identity/oauth/token"
11+
grant_type: client_credentials
12+
13+
# Requester
14+
requester:
15+
type: HttpRequester
16+
url_base: "{{ config['domain_url'].rstrip('/') }}/"
17+
authenticator: "#/definitions/authenticator"
18+
http_method: GET
19+
error_handler:
20+
type: DefaultErrorHandler
21+
response_filters:
22+
- type: HttpResponseFilter
23+
action: FAIL
24+
http_codes: [400, 403]
25+
error_message: Unable to connect to Marketo API with the provided credentials
26+
27+
# Selector
28+
selector:
29+
type: RecordSelector
30+
extractor:
31+
type: DpathExtractor
32+
field_path: ["result"]
33+
34+
# Paginators
35+
cursor_paginator:
36+
type: DefaultPaginator
37+
pagination_strategy:
38+
type: CursorPagination
39+
cursor_value: "{{ response.get('nextPageToken') }}"
40+
page_size: 300
41+
page_size_option:
42+
type: RequestOption
43+
field_name: "batchSize"
44+
inject_into: request_parameter
45+
page_token_option:
46+
type: RequestOption
47+
field_name: "nextPageToken"
48+
inject_into: request_parameter
49+
50+
offset_paginator:
51+
type: DefaultPaginator
52+
pagination_strategy:
53+
type: OffsetIncrement
54+
page_size: 200
55+
page_size_option:
56+
type: RequestOption
57+
field_name: "batchSize"
58+
inject_into: request_parameter
59+
page_token_option:
60+
type: RequestOption
61+
field_name: "offset"
62+
inject_into: request_parameter
63+
64+
# Retrievers
65+
base_retriever:
66+
type: SimpleRetriever
67+
record_selector: "#/definitions/selector"
68+
requester: "#/definitions/requester"
69+
paginator: "#/definitions/cursor_paginator"
70+
71+
semi_incremental_retriever:
72+
$ref: "#/definitions/base_retriever"
73+
record_selector:
74+
$ref: "#/definitions/selector"
75+
record_filter:
76+
type: RecordFilter
77+
condition: "{{ record['createdAt'] >= stream_state.get('createdAt', config['start_date']) }}"
78+
79+
# Base streams
80+
base_full_refresh_stream:
81+
type: DeclarativeStream
82+
primary_key: "id"
83+
retriever: "#/definitions/base_retriever"
84+
85+
base_semi_incremental_stream:
86+
$ref: "#/definitions/base_full_refresh_stream"
87+
retriever: "#/definitions/semi_incremental_retriever"
88+
incremental_sync:
89+
type: DatetimeBasedCursor
90+
cursor_field: "createdAt"
91+
datetime_format: "%Y-%m-%dT%H:%M:%SZ"
92+
start_datetime: "{{ config['start_date'] }}"
93+
94+
base_incremental_stream:
95+
$ref: "#/definitions/base_full_refresh_stream"
96+
incremental_sync:
97+
type: DatetimeBasedCursor
98+
cursor_field: "updatedAt"
99+
datetime_format: "%Y-%m-%dT%H:%M:%SZ"
100+
start_datetime: "{{ config['start_date'] }}"
101+
end_datetime: "{{ config.get('end_date', now_utc().strftime('%Y-%m-%dT%H:%M:%SZ')) }}"
102+
cursor_granularity: "PT1S"
103+
step: "P{{ config.get('window_in_days', 30) }}D"
104+
start_time_option:
105+
type: RequestOption
106+
field_name: "earliestUpdatedAt"
107+
inject_into: request_parameter
108+
end_time_option:
109+
type: RequestOption
110+
field_name: "latestUpdatedAt"
111+
inject_into: request_parameter
112+
113+
# Full refresh streams
114+
activity_types_stream:
115+
# API Docs: https://developers.marketo.com/rest-api/lead-database/activities/#describe
116+
name: "activity_types"
117+
$ref: "#/definitions/base_full_refresh_stream"
118+
$parameters:
119+
path: "rest/v1/activities/types.json"
120+
121+
segmentations_stream:
122+
# API Docs: https://developers.marketo.com/rest-api/endpoint-reference/asset-endpoint-reference/#!/Segments/getSegmentationUsingGET
123+
name: "segmentations"
124+
$ref: "#/definitions/base_full_refresh_stream"
125+
retriever:
126+
$ref: "#/definitions/base_retriever"
127+
paginator: "#/definitions/offset_paginator"
128+
$parameters:
129+
path: "rest/asset/v1/segmentation.json"
130+
131+
# Semi-Incremental streams
132+
campaigns_stream:
133+
# API Docs: https://developers.marketo.com/rest-api/endpoint-reference/lead-database-endpoint-reference/#!/Campaigns/getCampaignsUsingGET
134+
name: "campaigns"
135+
$ref: "#/definitions/base_semi_incremental_stream"
136+
$parameters:
137+
path: "rest/v1/campaigns.json"
138+
139+
lists_stream:
140+
# API Docs: https://developers.marketo.com/rest-api/endpoint-reference/lead-database-endpoint-reference/#!/Static_Lists/getListsUsingGET
141+
name: "lists"
142+
$ref: "#/definitions/base_semi_incremental_stream"
143+
$parameters:
144+
path: "rest/v1/lists.json"
145+
146+
# Incremental streams
147+
programs_stream:
148+
# API Docs: https://developers.marketo.com/rest-api/assets/programs/#by_date_range
149+
name: "programs"
150+
$ref: "#/definitions/base_incremental_stream"
151+
retriever:
152+
$ref: "#/definitions/base_retriever"
153+
paginator:
154+
$ref: "#/definitions/offset_paginator"
155+
page_size_option:
156+
type: RequestOption
157+
field_name: "maxReturn"
158+
inject_into: request_parameter
159+
transformations:
160+
- type: AddFields
161+
fields:
162+
- type: AddedFieldDefinition
163+
path: ["createdAt"]
164+
value: "{{ format_datetime(record['createdAt'].replace('Z',''), '%Y-%m-%dT%H:%M:%SZ') }}"
165+
- type: AddedFieldDefinition
166+
path: ["updatedAt"]
167+
value: "{{ format_datetime(record['updatedAt'].replace('Z',''), '%Y-%m-%dT%H:%M:%SZ') }}"
168+
$parameters:
169+
path: "rest/asset/v1/programs.json"
170+
171+
streams:
172+
# Full refresh streams
173+
- "#/definitions/activity_types_stream"
174+
- "#/definitions/segmentations_stream"
175+
176+
# Semi-Incremental streams
177+
- "#/definitions/campaigns_stream"
178+
- "#/definitions/lists_stream"
179+
180+
# Incremental streams
181+
- "#/definitions/programs_stream"
182+
183+
check:
184+
type: CheckStream
185+
stream_names:
186+
- programs

0 commit comments

Comments
 (0)