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

🎉 Source Chartmogul: Add CustomerCount stream #10756

Merged
merged 8 commits into from
Mar 2, 2022
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 @@ -119,7 +119,7 @@
- name: Chartmogul
sourceDefinitionId: b6604cbd-1b12-4c08-8767-e140d0fb0877
dockerRepository: airbyte/source-chartmogul
dockerImageTag: 0.1.0
dockerImageTag: 0.1.1
documentationUrl: https://docs.airbyte.io/integrations/sources/chartmogul
icon: chartmogul.svg
sourceType: api
Expand Down
15 changes: 14 additions & 1 deletion airbyte-config/init/src/main/resources/seed/source_specs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1000,7 +1000,7 @@
supportsNormalization: false
supportsDBT: false
supported_destination_sync_modes: []
- dockerImage: "airbyte/source-chartmogul:0.1.0"
- dockerImage: "airbyte/source-chartmogul:0.1.1"
spec:
documentationUrl: "https://docs.airbyte.io/integrations/sources/chartmogul"
connectionSpecification:
Expand All @@ -1009,6 +1009,8 @@
type: "object"
required:
- "api_key"
- "start_date"
- "interval"
additionalProperties: false
properties:
api_key:
Expand All @@ -1024,6 +1026,17 @@
examples:
- "2017-01-25T00:00:00Z"
order: 1
interval:
type: "string"
description: "Some APIs such as <a href=\"https://dev.chartmogul.com/reference/endpoint-overview-metrics-api\"\
>Metrics</a> require intervals to cluster data."
enum:
- "day"
- "week"
- "month"
- "quarter"
default: "month"
order: 2
supportsNormalization: false
supportsDBT: false
supported_destination_sync_modes: []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,5 @@ COPY source_chartmogul ./source_chartmogul
ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py"
ENTRYPOINT ["python", "/airbyte/integration_code/main.py"]

LABEL io.airbyte.version=0.1.0
LABEL io.airbyte.version=0.1.1
LABEL io.airbyte.name=airbyte/source-chartmogul
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Chartmogul is an online subscription analytics platform. It retrieves data from

Connector currently implements following full refresh streams:
* [Customers](https://dev.chartmogul.com/reference/list-customers)
* [CustomerCount] (https://dev.chartmogul.com/reference/retrieve-customer-count)
* [Activities](https://dev.chartmogul.com/reference/list-activities)

`start_date` config is used for retrieving `Activies`. `Customers` stream does not use this config. Even if it was possible to filter by `start_date`, it would cause issues when modeling data. That is because activies after `start_date` can be triggered by customers who were created way before that.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@
},
"sync_mode": "full_refresh",
"destination_sync_mode": "overwrite"
},
{
"stream": {
"name": "customer_count",
"json_schema": {},
"supported_sync_modes": ["full_refresh"]
},
"sync_mode": "full_refresh",
"destination_sync_mode": "overwrite"
}
]
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{
"api_key": "<invalid_key>"
"api_key": "<invalid_key>",
"start_date": "2017-01-25T00:00:00Z",
"interval": "day"
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"api_key": "<api-key>",
"start_date": "2022-01-05T12:09:00Z"
"start_date": "2022-01-05T12:09:00Z",
"interval": "day"
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@
},
"sync_mode": "full_refresh",
"destination_sync_mode": "overwrite"
},
{
"stream": {
"name": "customer_count",
"json_schema": {},
"supported_sync_modes": ["full_refresh"]
},
"sync_mode": "full_refresh",
"destination_sync_mode": "overwrite"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"date": {
"type": ["string"]
},
"customers": {
"type": ["integer"]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@

from abc import ABC
from base64 import b64encode
from datetime import datetime
from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Tuple
from urllib.parse import urljoin

import requests
from airbyte_cdk.sources import AbstractSource
from airbyte_cdk.sources.streams import Stream
from airbyte_cdk.sources.streams.http import HttpStream
from airbyte_cdk.sources.streams.http.auth import TokenAuthenticator
from airbyte_cdk.sources.streams.http.exceptions import RequestBodyException


# Basic full refresh stream
Expand Down Expand Up @@ -70,6 +73,52 @@ def path(self, **kwargs) -> str:
return "v1/activities"


class CustomerCount(ChartmogulStream):
primary_key = "date"

def __init__(self, start_date: str, interval: str, **kwargs):
super().__init__(**kwargs)
self.start_date = start_date
self.end_date = datetime.now().strftime("%Y-%m-%d")
self.interval = interval

def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]:
return None

def request_body_data(
self,
stream_state: Mapping[str, Any],
stream_slice: Mapping[str, Any] = None,
next_page_token: Mapping[str, Any] = None,
) -> Optional[Mapping]:
return {
"start-date": self.start_date,
"end-date": self.end_date,
"interval": self.interval,
}

def _create_prepared_request(
self, path: str, headers: Mapping = None, params: Mapping = None, json: Any = None, data: Any = None
) -> requests.PreparedRequest:
"""
Override to make possible sending http body with GET request.
"""
args = {"method": self.http_method, "url": urljoin(self.url_base, path), "headers": headers, "params": params}
if json and data:
raise RequestBodyException(
"At the same time only one of the 'request_body_data' and 'request_body_json' functions can return data"
)
elif json:
args["json"] = json
elif data:
args["data"] = data

return self._session.prepare_request(requests.Request(**args))

def path(self, **kwargs) -> str:
return "v1/metrics/customer-count"


class HttpBasicAuthenticator(TokenAuthenticator):
def __init__(self, token: str, auth_method: str = "Basic", **kwargs):
auth_string = f"{token}:".encode("utf8")
Expand All @@ -91,4 +140,8 @@ def check_connection(self, logger, config) -> Tuple[bool, any]:

def streams(self, config: Mapping[str, Any]) -> List[Stream]:
auth = HttpBasicAuthenticator(config["api_key"], auth_method="Basic")
return [Customers(authenticator=auth), Activities(authenticator=auth, start_date=config.get("start_date"))]
return [
Customers(authenticator=auth),
CustomerCount(authenticator=auth, start_date=config.get("start_date"), interval=config.get("interval")),
Activities(authenticator=auth, start_date=config.get("start_date")),
]
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Chartmogul Spec",
"type": "object",
"required": ["api_key"],
"required": ["api_key", "start_date", "interval"],
"additionalProperties": false,
"properties": {
"api_key": {
Expand All @@ -19,6 +19,13 @@
"description": "UTC date and time in the format 2017-01-25T00:00:00Z. When feasible, any data before this date will not be replicated.",
"examples": ["2017-01-25T00:00:00Z"],
"order": 1
},
"interval": {
"type": "string",
"description": "Some APIs such as <a href=\"https://dev.chartmogul.com/reference/endpoint-overview-metrics-api\">Metrics</a> require intervals to cluster data.",
"enum": ["day", "week", "month", "quarter"],
"default": "month",
"order": 2
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ def test_streams(mocker):
source = SourceChartmogul()
config_mock = MagicMock()
streams = source.streams(config_mock)
expected_streams_number = 2
expected_streams_number = 3
assert len(streams) == expected_streams_number
2 changes: 2 additions & 0 deletions docs/integrations/sources/chartmogul.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ If `start_date` is set, it will only apply to `Activities` stream. `Customers`'
This Source is capable of syncing the following streams:

* [Customers](https://dev.chartmogul.com/reference/list-customers)
* [CustomerCount] (https://dev.chartmogul.com/reference/retrieve-customer-count)
* [Activities](https://dev.chartmogul.com/reference/list-activities)

### Features
Expand Down Expand Up @@ -44,4 +45,5 @@ Please read [How to find your API key](https://dev.chartmogul.com/docs/authentic

| Version | Date | Pull Request | Subject |
| :--- | :--- | :--- | :--- |
| 0.1.1 | 2022-03-02 | [10756](https://github.com/airbytehq/airbyte/pull/10756) | Add new stream: customer-count |
| 0.1.0 | 2022-01-10 | [9381](https://github.com/airbytehq/airbyte/pull/9381) | New Source: Chartmogul |