Skip to content

Commit 21ff8a2

Browse files
authored
Source Amazon Seller Partner: Add GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT report (#8179)
* Source Amazon Seller Partner: Add GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT report * loads * fixes and refactors * docs * fixes * Field definitions * versions * versions * refactor report options to scope by REPORT name * fix _report_data * 1 * make _augmented_data a static method * parse_document is static too
1 parent 91513f5 commit 21ff8a2

File tree

12 files changed

+136
-6
lines changed

12 files changed

+136
-6
lines changed

airbyte-config/init/src/main/resources/config/STANDARD_SOURCE_DEFINITION/e55879a8-0ef8-4557-abcf-ab34c53ec460.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"sourceDefinitionId": "e55879a8-0ef8-4557-abcf-ab34c53ec460",
33
"name": "Amazon Seller Partner",
44
"dockerRepository": "airbyte/source-amazon-seller-partner",
5-
"dockerImageTag": "0.2.5",
5+
"dockerImageTag": "0.2.6",
66
"documentationUrl": "https://docs.airbyte.io/integrations/sources/amazon-seller-partner",
77
"icon": "amazonsellerpartner.svg"
88
}

airbyte-config/init/src/main/resources/seed/source_definitions.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
- name: Amazon Seller Partner
2323
sourceDefinitionId: e55879a8-0ef8-4557-abcf-ab34c53ec460
2424
dockerRepository: airbyte/source-amazon-seller-partner
25-
dockerImageTag: 0.2.5
25+
dockerImageTag: 0.2.6
2626
sourceType: api
2727
documentationUrl: https://docs.airbyte.io/integrations/sources/amazon-seller-partner
2828
icon: amazonsellerpartner.svg

airbyte-config/init/src/main/resources/seed/source_specs.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@
153153
supportsNormalization: false
154154
supportsDBT: false
155155
supported_destination_sync_modes: []
156-
- dockerImage: "airbyte/source-amazon-seller-partner:0.2.5"
156+
- dockerImage: "airbyte/source-amazon-seller-partner:0.2.6"
157157
spec:
158158
documentationUrl: "https://docs.airbyte.io/integrations/sources/amazon-seller-partner"
159159
changelogUrl: "https://docs.airbyte.io/integrations/sources/amazon-seller-partner"

airbyte-integrations/connectors/source-amazon-seller-partner/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ RUN pip install .
1212
ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py"
1313
ENTRYPOINT ["python", "/airbyte/integration_code/main.py"]
1414

15-
LABEL io.airbyte.version=0.2.5
15+
LABEL io.airbyte.version=0.2.6
1616
LABEL io.airbyte.name=airbyte/source-amazon-seller-partner

airbyte-integrations/connectors/source-amazon-seller-partner/integration_tests/configured_catalog.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@
104104
"sync_mode": "incremental",
105105
"destination_sync_mode": "append",
106106
"cursor_field": ["Date"]
107+
},
108+
{
109+
"stream": {
110+
"name": "GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT",
111+
"json_schema": {},
112+
"supported_sync_modes": ["full_refresh"]
113+
},
114+
"sync_mode": "full_refresh",
115+
"destination_sync_mode": "overwrite"
107116
}
108117
]
109118
}

airbyte-integrations/connectors/source-amazon-seller-partner/integration_tests/sample_state.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,8 @@
2828
},
2929
"GET_SELLER_FEEDBACK_DATA": {
3030
"createdTime": "2021-07-01T00:00:00Z"
31+
},
32+
"GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT": {
33+
"createdTime": "2021-07-01T00:00:00Z"
3134
}
3235
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"title": "Brand Analytics Search Terms Reports",
3+
"description": "Brand Analytics Search Terms Reports",
4+
"type": "object",
5+
"$schema": "http://json-schema.org/draft-07/schema#",
6+
"properties": {
7+
"departmentName": {
8+
"type": ["null", "string"]
9+
},
10+
"searchTerm": {
11+
"type": ["null", "string"]
12+
},
13+
"searchFrequencyRank": {
14+
"type": ["null", "number"]
15+
},
16+
"clickedAsin": {
17+
"type": ["null", "string"]
18+
},
19+
"clickShareRank": {
20+
"type": ["null", "number"]
21+
},
22+
"clickShare": {
23+
"type": ["null", "number"]
24+
},
25+
"conversionShare": {
26+
"type": ["null", "number"]
27+
}
28+
}
29+
}

airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/source.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
SellerFeedbackReports,
2727
VendorDirectFulfillmentShipping,
2828
VendorInventoryHealthReports,
29+
BrandAnalyticsSearchTermsReports,
2930
)
3031

3132

@@ -44,6 +45,11 @@ class Config:
4445
description="Will be used for stream slicing for initial full_refresh sync when no updated state is present for reports that support sliced incremental sync.",
4546
examples=["30", "365"],
4647
)
48+
report_options: str = Field(
49+
None,
50+
description="Additional information passed to reports. This varies by report type. Must be a valid json string.",
51+
examples=['{"GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT": {"reportPeriod": "WEEK"}}', '{"GET_SOME_REPORT": {"custom": "true"}}'],
52+
)
4753
refresh_token: str = Field(
4854
description="The Refresh Token obtained via OAuth flow authorization.",
4955
title="Refresh Token",
@@ -98,6 +104,7 @@ def _get_stream_kwargs(self, config: ConnectorConfig) -> Mapping[str, Any]:
98104
"replication_start_date": config.replication_start_date,
99105
"marketplace_ids": [marketplace_id],
100106
"period_in_days": config.period_in_days,
107+
"report_options": config.report_options,
101108
}
102109
return stream_kwargs
103110

@@ -136,6 +143,7 @@ def streams(self, config: Mapping[str, Any]) -> List[Stream]:
136143
VendorInventoryHealthReports(**stream_kwargs),
137144
Orders(**stream_kwargs),
138145
SellerFeedbackReports(**stream_kwargs),
146+
BrandAnalyticsSearchTermsReports(**stream_kwargs),
139147
]
140148

141149
def spec(self, *args, **kwargs) -> ConnectorSpecification:

airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/spec.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@
1919
"type": "integer",
2020
"default": 30
2121
},
22+
"report_options": {
23+
"title": "Report Options",
24+
"description": "Additional information passed to reports. This varies by report type. Must be a valid json string.",
25+
"examples":["{\"GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT\": {\"reportPeriod\": \"WEEK\"}}", "{\"GET_SOME_REPORT\": {\"custom\": \"true\"}}"],
26+
"type": "string"
27+
},
2228
"refresh_token": {
2329
"title": "Refresh Token",
2430
"description": "The Refresh Token obtained via OAuth flow authorization.",

airbyte-integrations/connectors/source-amazon-seller-partner/source_amazon_seller_partner/streams.py

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535

3636
DATE_TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ"
3737

38-
3938
class AmazonSPStream(HttpStream, ABC):
4039
data_field = "payload"
4140

@@ -46,6 +45,7 @@ def __init__(
4645
replication_start_date: str,
4746
marketplace_ids: List[str],
4847
period_in_days: Optional[int],
48+
report_options: Optional[str],
4949
*args,
5050
**kwargs,
5151
):
@@ -151,6 +151,7 @@ def __init__(
151151
replication_start_date: str,
152152
marketplace_ids: List[str],
153153
period_in_days: Optional[int],
154+
report_options: Optional[str],
154155
authenticator: HttpAuthenticator = NoAuth(),
155156
):
156157
self._authenticator = authenticator
@@ -160,6 +161,7 @@ def __init__(
160161
self._replication_start_date = replication_start_date
161162
self.marketplace_ids = marketplace_ids
162163
self.period_in_days = period_in_days
164+
self._report_options = report_options
163165

164166
@property
165167
def url_base(self) -> str:
@@ -282,9 +284,16 @@ def parse_response(self, response: requests.Response) -> Iterable[Mapping]:
282284
payload,
283285
)
284286

285-
document_records = csv.DictReader(StringIO(document), delimiter="\t")
287+
document_records = self.parse_document(document)
286288
yield from document_records
287289

290+
@staticmethod
291+
def parse_document(document):
292+
return csv.DictReader(StringIO(document), delimiter="\t")
293+
294+
def report_options(self) -> Mapping[str, Any]:
295+
return json_lib.loads(self._report_options).get(self.name)
296+
288297
def read_records(
289298
self,
290299
sync_mode: SyncMode,
@@ -377,6 +386,69 @@ class FbaShipmentsReports(ReportsAmazonSPStream):
377386
class VendorInventoryHealthReports(ReportsAmazonSPStream):
378387
name = "GET_VENDOR_INVENTORY_HEALTH_AND_PLANNING_REPORT"
379388

389+
class BrandAnalyticsSearchTermsReports(ReportsAmazonSPStream):
390+
"""
391+
Field definitions: https://sellercentral.amazon.co.uk/help/hub/reference/G5NXWNY8HUD3VDCW
392+
"""
393+
394+
name = "GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT"
395+
396+
@staticmethod
397+
def parse_document(document):
398+
parsed = json_lib.loads(document)
399+
return parsed.get("dataByDepartmentAndSearchTerm", {})
400+
401+
def _report_data(
402+
self,
403+
sync_mode: SyncMode,
404+
cursor_field: List[str] = None,
405+
stream_slice: Mapping[str, Any] = None,
406+
stream_state: Mapping[str, Any] = None,
407+
) -> Mapping[str, Any]:
408+
data = super()._report_data(sync_mode, cursor_field, stream_slice, stream_state)
409+
options = self.report_options()
410+
if options is not None:
411+
data.update(self._augmented_data(options))
412+
413+
return data
414+
415+
@staticmethod
416+
def _augmented_data(report_options) -> Mapping[str, Any]:
417+
if report_options.get("reportPeriod") is None:
418+
return {}
419+
else:
420+
now = pendulum.now("utc")
421+
if report_options["reportPeriod"] == "DAY":
422+
now = now.subtract(days=1)
423+
data_start_time = now.start_of("day")
424+
data_end_time = now.end_of("day")
425+
elif report_options["reportPeriod"] == "WEEK":
426+
now = now.subtract(weeks=1)
427+
428+
# According to report api docs
429+
# dataStartTime must be a Sunday and dataEndTime must be the following Saturday
430+
pendulum.week_starts_at(pendulum.SUNDAY)
431+
pendulum.week_ends_at(pendulum.SATURDAY)
432+
433+
data_start_time = now.start_of("week")
434+
data_end_time = now.end_of("week")
435+
436+
# Reset week start and end
437+
pendulum.week_starts_at(pendulum.MONDAY)
438+
pendulum.week_ends_at(pendulum.SUNDAY)
439+
elif report_options["reportPeriod"] == "MONTH":
440+
now = now.subtract(months=1)
441+
data_start_time = now.start_of("month")
442+
data_end_time = now.end_of("month")
443+
else:
444+
raise Exception([{"message": "This reportPeriod is not implemented."}])
445+
446+
return {
447+
"dataStartTime": data_start_time.strftime(DATE_TIME_FORMAT),
448+
"dataEndTime": data_end_time.strftime(DATE_TIME_FORMAT),
449+
"reportOptions": report_options,
450+
}
451+
380452

381453
class IncrementalReportsAmazonSPStream(ReportsAmazonSPStream):
382454
@property

airbyte-integrations/connectors/source-amazon-seller-partner/unit_tests/test_repots_streams_rate_limits.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ def reports_stream():
2828
marketplace_ids=["id"],
2929
authenticator=NoAuth(),
3030
period_in_days=0,
31+
report_options=None,
3132
)
3233
return stream
3334

docs/integrations/sources/amazon-seller-partner.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ This source is capable of syncing the following streams:
2424
* [Orders](https://github.com/amzn/selling-partner-api-docs/blob/main/references/orders-api/ordersV0.md) \(incremental\)
2525
* [VendorDirectFulfillmentShipping](https://github.com/amzn/selling-partner-api-docs/blob/main/references/vendor-direct-fulfillment-shipping-api/vendorDirectFulfillmentShippingV1.md)
2626
* [Seller Feedback Report](https://github.com/amzn/selling-partner-api-docs/blob/main/references/reports-api/reporttype-values.md#performance-reports)
27+
* [Brand Analytics Search Terms Report](https://github.com/amzn/selling-partner-api-docs/blob/main/references/reports-api/reporttype-values.md#brand-analytics-reports)
2728

2829
## Getting started
2930

@@ -63,6 +64,7 @@ Information about rate limits you may find [here](https://github.com/amzn/sellin
6364

6465
| Version | Date | Pull Request | Subject |
6566
| :--- | :--- | :--- | :--- |
67+
| `0.2.6` | 2021-12-10 | [\#8179](https://github.com/airbytehq/airbyte/pull/8179) | Add GET_BRAND_ANALYTICS_SEARCH_TERMS_REPORT report |
6668
| `0.2.5` | 2021-12-06 | [\#8425](https://github.com/airbytehq/airbyte/pull/8425) | Update title, description fields in spec |
6769
| `0.2.4` | 2021-11-08 | [\#8021](https://github.com/airbytehq/airbyte/pull/8021) | Added GET_SELLER_FEEDBACK_DATA report with incremental sync capability |
6870
| `0.2.3` | 2021-11-08 | [\#7828](https://github.com/airbytehq/airbyte/pull/7828) | Remove datetime format from all streams |

0 commit comments

Comments
 (0)