Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
36d027f
Change copyright to Stitch
nick-mccoy Apr 26, 2019
921bd56
Update LICENSE to AGPL
dmosorast Apr 27, 2019
4ea0555
new streams(coupon_sets, coupon_codes, orders, gifts, creditnotes, co…
cb-svel Apr 29, 2019
d9567ab
add credit notes schema
dwallace0723 Apr 29, 2019
c7e834e
add credit notes stream
dwallace0723 Apr 29, 2019
67d66bb
update readme
dwallace0723 Apr 29, 2019
8247da4
Merge pull request #1 from envoy/dwall/add-credit-notes-stream
nick-mccoy Apr 30, 2019
c8608ee
Continuing to other streams incase order stream is not enabled
cb-svel May 2, 2019
894456a
removed comments, coupon_sets, coupon_codes
cb-svel May 2, 2019
97088e0
Added Orders, Gifts, Creditnotes in ReadMe
cb-svel May 3, 2019
4984a57
Merge branch 'alpha' into master
cb-svel May 3, 2019
1d9cdb6
Remove Invalid Fields from Stream Discovery (#4)
dwallace0723 May 7, 2019
e9dd678
removed SELECTED=true, added REPLICATION_METHOD, REPLICATION_KEY and …
cb-svel May 15, 2019
d93a84d
reverted replication method to INCREMENTAL
cb-svel May 15, 2019
f1b4774
promotional credit bookmark key changes
cb-svel May 15, 2019
8504cf7
Merge branch 'alpha' into master
cb-svel May 15, 2019
fca1ce1
code review; fix refs
May 17, 2019
10c4314
Merge branch 'alpha'
May 17, 2019
1e18993
bump to 0.0.7
May 17, 2019
b1773d8
gift schema changes, order schema changes
cb-svel May 29, 2019
1b5dd35
Hard delete handling by reading events
cb-svel May 29, 2019
aa9b28b
Merge branch 'alpha' into master
cb-svel May 30, 2019
a72fc90
removed selected-by-default
cb-svel May 30, 2019
167faca
Added new streams (Order, Gifts) & new fields in existing streams (#5)
cb-svel May 30, 2019
de39c16
bump to 0.0.8
May 30, 2019
0e49832
added more objects in events content
cb-svel May 31, 2019
201c334
added coupon sets and codes
cb-svel May 31, 2019
e5fb367
Update events.json (#8)
May 31, 2019
1f661b1
Bump to v0.0.9
May 31, 2019
a681b98
fix events schema
May 31, 2019
367ab36
bump to 0.0.10
May 31, 2019
d53195d
custom fields addition as json
cb-svel Jun 7, 2019
92a9c9c
Merge branch 'master' into master
cb-svel Jun 7, 2019
d40d104
remove old legacy tap framework code
dwallace0723 Jun 24, 2019
3fcca0b
Merge pull request #10 from dwallace0723/master
dmosorast Jun 28, 2019
4bf2026
Version 0.0.11
dmosorast Jun 28, 2019
3ffb729
code changed with slice and join for custom field processing in event…
cb-svel Jul 2, 2019
46ab5f0
Merge pull request #9 from cb-senthilvel/master
dmosorast Jul 2, 2019
a2015de
version 0.0.12 and changelog
dmosorast Jul 2, 2019
9c7f5b0
Bump to v1.0.0, update changelog (#20)
Oct 14, 2019
d167b69
Add PR template
Oct 28, 2019
eebd213
ORDER API FIX (#22)
cb-aravindh Mar 20, 2020
b00842b
fix retry logic and bump version (#23)
KAllan357 Mar 20, 2020
cb8bb80
Remove maxLength from payment_sources schema (#44)
dmosorast Apr 29, 2021
d6bdf7e
v1.0.3: Fix invalid json (#46)
dmosorast Apr 29, 2021
11a9ad2
Added basic config.yml for CircleCI (#49)
savan-chovatiya Jun 4, 2021
378f633
TDL-13343:Update type of cf_company_field to integer and string both …
savan-chovatiya Jun 9, 2021
5e44012
TDL-13802 : Add tap tester suites (#50)
savan-chovatiya Jun 9, 2021
f64bc4b
Copy of GEN 349 from cb-nandita (#56)
leslievandemark Jun 11, 2021
7c23cb2
changed assert to so stream passes (#60)
leslievandemark Jun 14, 2021
ccca20d
Version bump to v1.1.0 (#59)
leslievandemark Jun 14, 2021
f3294c6
Pr 62 (#65)
Jun 25, 2021
f63f84a
Bump to v1.1.1, update changelog (#66)
Jun 25, 2021
9c9ef83
case insensitive comparison of site name (#67)
cb-nandita Jun 29, 2021
292f2dd
Bump to v1.1.2, update changelog (#68)
Jun 29, 2021
fcd8863
Remove all minimum/maximum and minLength/maxLength (#45)
dmosorast Jun 30, 2021
5ec446f
TDL-13342: Fix JSONDecodeError in Invoices and Transactions streams …
savan-chovatiya Jun 30, 2021
7b7a9f8
Tdl 6287 add tiersprice attribute (#53)
dbshah1212 Jun 30, 2021
a003fb4
TDL-13802:Updated integration test to cover product catalog v1 and v2…
savan-chovatiya Jun 30, 2021
a2b874b
TDL-6342 Add additional fields from an api (#64)
savan-chovatiya Jul 7, 2021
8e9dd95
TDL-13904: Upgraded event stream schema. (#57)
dbshah1212 Jul 8, 2021
7299b3d
Tdl 6173 bookmark key handling (#54)
dbshah1212 Jul 9, 2021
482bdc7
bump v1.2.0 (#71)
zachharris1 Jul 20, 2021
ad153a6
Add MANIFEST.in (#72)
zachharris1 Jul 21, 2021
41d7e31
Update glob (#73)
Jul 21, 2021
b7ef659
Tdl 6624 adding comments stream (#52)
dbshah1212 Jul 22, 2021
71435be
TDL-13631: Added include_deleted configuration (#58)
dbshah1212 Jul 22, 2021
b2d76fc
TDL-6342: Add additional fields found during testing in schema apart …
savan-chovatiya Jul 22, 2021
5b47dbe
bump v1.3.0 (#74)
zachharris1 Jul 23, 2021
854a56f
Added support for Chargebee Quotes (#75)
cb-nandita Aug 30, 2021
89677ca
bump 1.3.1 (#76)
zachharris1 Aug 30, 2021
11207da
TDL-16367: Fix pagination test failure (#79)
savan-chovatiya Jun 2, 2022
af8d4e4
TDL-19270: Revert back bookmarking logic (#86)
hpatel41 Jun 2, 2022
10f2840
Bump version
Jun 7, 2022
2854321
Crest Work (#89)
hpatel41 Jun 28, 2022
f16afdd
Bump version (#90)
nitingaikwad1 Jun 28, 2022
6a8efb0
Added custom field support for Item Model entities (#94)
sgandhi1311 Sep 8, 2022
00dc882
bumped patch version and updated changelog (#95)
sgandhi1311 Sep 8, 2022
ebf3c7b
fix integration tests (#101)
RushiT0122 Oct 27, 2023
3e9cfd2
add missing customer details (#100)
RushiT0122 Oct 31, 2023
e0c2c95
fix: Prevent truncating invoice lineItem taxRates (#102)
RushiT0122 Oct 31, 2023
835dcd7
Bump version 1.3.5 (#103)
RushiT0122 Oct 31, 2023
3bdb7b8
Update subscriptions schema to include manual discounts (#107)
rubenharutyunov Apr 25, 2024
0b571d1
Fix integration tests and schema refactoring (#109)
shantanu73 Apr 29, 2024
cea0729
Enable copilot usage in PR template according to Qlik policy
eskaaren Sep 3, 2024
888de42
Initial commit
prijendev Nov 18, 2024
61083d1
Fix for pylint
prijendev Nov 18, 2024
abe4d56
Add missing fields into the schema
prijendev Nov 18, 2024
d5618e1
MInor enhancement
prijendev Nov 22, 2024
ba0feb4
fix:updated dependencies in setup.py
gl-romil May 20, 2025
ddec9ef
SAC-28166: CircleCI Upgrade, Swap to UV (#114)
dsprayberry Aug 7, 2025
eba07ad
Merge branch 'master' into TDL-26703-tap-refactoring
rdeshmukh15 Nov 24, 2025
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
61 changes: 61 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
version: 2
jobs:
build:
docker:
- image: 218546966473.dkr.ecr.us-east-1.amazonaws.com/circle-ci:stitch-tap-tester-uv
steps:
- checkout
- run:
name: 'Setup virtual env'
command: |
uv venv --python 3.9 /usr/local/share/virtualenvs/tap-chargebee
source /usr/local/share/virtualenvs/tap-chargebee/bin/activate
uv pip install -U 'pip<19.2' 'setuptools<51.0.0'
uv pip install .[dev]
- run:
name: 'JSON Validator'
command: |
source /usr/local/share/virtualenvs/tap-tester/bin/activate
stitch-validate-json tap_chargebee/schemas/*/*.json
- run:
name: 'Pylint'
command: |
source /usr/local/share/virtualenvs/tap-chargebee/bin/activate
uv pip install pylint==2.14.1
pylint tap_chargebee --disable C,W,R,no-member
- run:
name: 'Unit Tests'
command: |
source /usr/local/share/virtualenvs/tap-chargebee/bin/activate
uv pip install pytest coverage
coverage run -m pytest tests/unittests
coverage html
- store_test_results:
path: test_output/report.xml
- store_artifacts:
path: htmlcov
- run:
name: 'Integration Tests'
command: |
source /usr/local/share/virtualenvs/tap-tester/bin/activate
uv pip install --upgrade awscli
aws s3 cp s3://com-stitchdata-dev-deployment-assets/environments/tap-tester/tap_tester_sandbox dev_env.sh
source dev_env.sh
run-test --tap=tap-chargebee tests
workflows:
version: 2
commit:
jobs:
- build:
context: circleci-user
build_daily:
triggers:
- schedule:
cron: "0 0 * * *"
filters:
branches:
only:
- master
jobs:
- build:
context: circleci-user
15 changes: 15 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Description of change
(write a short description or paste a link to JIRA)

# Manual QA steps
-

# Risks
-

# Rollback steps
- revert this branch

#### AI generated code
https://internal.qlik.dev/general/ways-of-working/code-reviews/#guidelines-for-ai-generated-code
- [ ] this PR has been written with the help of GitHub Copilot or another generative AI tool
99 changes: 98 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,101 @@
# Changelog

## 1.4.0

- Added discounts field in subscriptions schema #[107](https://github.com/singer-io/tap-chargebee/pull/107)
- Fixed All fields & Pagination integration tests #[109](https://github.com/singer-io/tap-chargebee/pull/109)

## 1.3.5

- Add missing Business Entity Details from Chargebee customers details #[100](https://github.com/singer-io/tap-chargebee/pull/100)
- Prevent truncating invoice lineItem taxRates #[102](https://github.com/singer-io/tap-chargebee/pull/102)

## 1.3.4

- Custom field support for Item Model entities #[92](https://github.com/singer-io/tap-chargebee/pull/92)
- Updated integration test #[93](https://github.com/singer-io/tap-chargebee/pull/93)

## 1.3.3

- Implement request timeout #[78](https://github.com/singer-io/tap-chargebee/pull/78)
- Add missing tap-tester tests #[83](https://github.com/singer-io/tap-chargebee/pull/83)
- Add custom exception handling #[85](https://github.com/singer-io/tap-chargebee/pull/85)
- Add missing fields to schema #[87](https://github.com/singer-io/tap-chargebee/pull/87)
- Revert back bookmark logic #[88](https://github.com/singer-io/tap-chargebee/pull/88)

##1.3.2

- Revert back bookmarking logic [#86](https://github.com/singer-io/tap-chargebee/pull/86)

## 1.3.1

- Added support for Chargebee Quotes [#75](https://github.com/singer-io/tap-chargebee/pull/75)

## 1.3.0

- Added comments stream [#52](https://github.com/singer-io/tap-chargebee/pull/52)
- Added include_deleted configuration [#58](https://github.com/singer-io/tap-chargebee/pull/58)
- Added undocumented fields [#69](https://github.com/singer-io/tap-chargebee/pull/69)

## 1.2.2

- Update the schema glob so that we include all schemas in the package distribution [#73](https://github.com/singer-io/tap-chargebee/pull/73)

## 1.2.1

- Add a `MANIFEST.in` file to include schema files in the `tap-chargebee` package [#72](https://github.com/singer-io/tap-chargebee/pull/72)

## 1.2.0

- Remove all minimum/maximum and minLength/maxLength [#45][#45]
- Fix JSONDecodeError in Invoices and Transactions streams [#51][#51]
- Add Tiersprice attribute [#53][#53]
- Updated integration test to cover product catalog v1 and v2 [#63][#63]
- Add additional fields from API [#64][#64]
- Upgraded event stream schema [#57][#57]
- Updated Bookmark handling, date without tz will updated in UTC tz format [#54][#54]

[#45]: https://github.com/singer-io/tap-chargebee/pull/45
[#51]: https://github.com/singer-io/tap-chargebee/pull/51
[#53]: https://github.com/singer-io/tap-chargebee/pull/53
[#63]: https://github.com/singer-io/tap-chargebee/pull/63
[#64]: https://github.com/singer-io/tap-chargebee/pull/64
[#57]: https://github.com/singer-io/tap-chargebee/pull/57
[#54]: https://github.com/singer-io/tap-chargebee/pull/54

## 1.1.2

- Fix domain name comparison bug [#67](https://github.com/singer-io/tap-chargebee/pull/67)

## 1.1.1

- Add an error message when we get an unexpected response from the Configurations API [#62](https://github.com/singer-io/tap-chargebee/pull/62)

## 1.1.0

- Adds support for Item Model, Multi-decimal (for Plan Model), and Account hierarchy (for Plan Model) [#56](https://github.com/singer-io/tap-chargebee/pull/56)
- Organized the folder structure:
a. common(common schemas to both plan model and item model)
b. item_model
c. plan_model
- Introduces two new streams: ITEM_MODEL_AVAILABLE_STREAMS, PLAN_MODEL_AVAILABLE_STREAMS

## 1.0.3

- Fix invalid JSON from #44

## 1.0.2

- Remove `maxLength` from `payment_sources` schema to address certain integrations having IDs of greater length than specified, and make the schema more flexible as the API evolves [#44](https://github.com/singer-io/tap-chargebee/pull/44)

## 1.0.0

- No change from 0.0.12

## 0.0.12

- Add `custom_fields` to plans, addons, customers, and subscriptions [#9](https://github.com/singer-io/tap-chargebee/pull/9)

## 0.0.3
* Add `credit_notes` stream [#2](https://github.com/singer-io/tap-chargebee/pull/2)

- Add `credit_notes` stream [#2](https://github.com/singer-io/tap-chargebee/pull/2)
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include tap_chargebee/schemas/*/*.json
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ This tap:
- [Addons](https://apidocs.chargebee.com/docs/api/addons)
- [Coupons](https://apidocs.chargebee.com/docs/api/coupons)
- [Credit Notes](https://apidocs.chargebee.com/docs/api/credit_notes)
- [Comments](https://apidocs.chargebee.com/docs/api/comments)
- [Customers](https://apidocs.chargebee.com/docs/api/customers)
- [Events](https://apidocs.chargebee.com/docs/api/events)
- [Gifts](https://apidocs.chargebee.com/docs/api/gifts)
- [Invoices](https://apidocs.chargebee.com/docs/api/invoices)
- [Orders](https://apidocs.chargebee.com/docs/api/orders)
- [Payment Sources](https://apidocs.chargebee.com/docs/api/payment_sources)
- [Plans](https://apidocs.chargebee.com/docs/api/plans)
- [Subscriptions](https://apidocs.chargebee.com/docs/api/subscriptions)
Expand All @@ -36,19 +39,25 @@ This tap:

```json
{
"start_date": "2010-01-01",
"start_date": "2010-01-01T00:00:00Z",
"api_key": "<Chargebee API Key>",
"site": "<Chargebee Site>"
"site": "<Chargebee Site>",
"include_deleted": "True|False",
"request_timeout": 300
}
```

The `start_date` specifies the date at which the tap will begin pulling data
The `start_date` specifies the date in ISO(YYYY-mm-ddTHH:MM:SSZ) format at which the tap will begin pulling data
(for those resources that support this).

The `api_key` is the API key for your Chargebee site.

The `site` parameter represents the name of your specific Chargebee site (e.g. `https://{site}.chargebee.com/api/v2/subscriptions`)

The `include_deleted` is an optional flag to ask if you want deleted records of all streams or not. Default: true

The `request_timeout` is an optional paramater to set timeout for requests. Default: 300 seconds

4. Run the Tap in Discovery Mode

```bash
Expand Down
14 changes: 10 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
from setuptools import setup, find_packages

setup(name='tap-chargebee',
version='0.0.5',
version='1.4.0',
description='Singer.io tap for extracting data from the Chargebee API',
author='dwallace@envoy.com',
classifiers=['Programming Language :: Python :: 3 :: Only'],
py_modules=['tap_chargebee'],
install_requires=[
'tap-framework==0.1.0'
'singer-python==6.0.0',
'backoff==2.2.1',
'requests==2.31.0'
],
entry_points='''
[console_scripts]
Expand All @@ -18,6 +20,10 @@
packages=find_packages(),
package_data={
'tap_chargebee': [
'schemas/*.json'
'schemas/common/*.json',
'schemas/item_model/*.json',
'schemas/plan_model/*.json'
]
})
},
include_package_data=True)

122 changes: 106 additions & 16 deletions tap_chargebee/__init__.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,122 @@
import singer
import tap_framework
import tap_chargebee.client
import tap_chargebee.streams
import sys
import json
from singer import metadata, Catalog
from tap_chargebee.client import ChargebeeClient
import tap_chargebee.streams as streams

LOGGER = singer.get_logger()


class ChargebeeRunner(tap_framework.Runner):
pass
def stream_is_selected(mdata):
"""
Check if the stream is selected
"""
return mdata.get((), {}).get("selected", False)


def get_available_streams(config: dict, cb_client: ChargebeeClient):
"""
Prepare the available streams based on the product catalog version
"""
site_name = config.get("site")
LOGGER.info("Site Name %s", site_name)
configuration_url = f"https://{site_name}.chargebee.com/api/v2/configurations"

try:
# Make a request to the configurations API
response = cb_client.make_request(url=configuration_url, method="GET")
site_configurations = response["configurations"]
except Exception as e:
LOGGER.error("Failed to fetch configurations: %s", e)
raise e

# Fetch the product catalog version
product_catalog_version = next(
iter(
config["product_catalog_version"]
for config in site_configurations
if config["domain"].lower() == site_name.lower()
),
None,
)

if product_catalog_version == "v2":
available_streams = streams.ITEM_MODEL_AVAILABLE_STREAMS
config["item_model"] = True
LOGGER.info("Found product catalog version v2")
elif product_catalog_version == "v1":
available_streams = streams.PLAN_MODEL_AVAILABLE_STREAMS
config["item_model"] = False
LOGGER.info("Found product catalog version v1")
else:
LOGGER.error(
"Incorrect Product Catalog version {}".format(product_catalog_version)
)
raise RuntimeError("Incorrect Product Catalog version")

return available_streams


def do_discover(config: dict, state: dict, available_streams: list):
"""
Generate the catalog
"""
LOGGER.info("Starting discovery.")
catalog = []

# Generate catalog for each stream based on the product catalog version
for available_stream in available_streams:
stream = available_stream(config, state, None, None)
catalog += stream.generate_catalog()

json.dump({"streams": catalog}, sys.stdout, indent=4)
LOGGER.info("Finished discover mode")


def do_sync(config: dict, catalog: Catalog, state: dict, client: ChargebeeClient):
"""
Sync data from Chargebee.
"""

last_stream = singer.get_currently_syncing(state)
LOGGER.info("last/currently syncing stream: %s", last_stream)

# Resume sync from the last stream
for catalog_entry in catalog.get_selected_streams(state):
mdata = metadata.to_map(catalog_entry.metadata)
replication_key = metadata.get(mdata, (), "replication-key")
key_properties = metadata.get(mdata, (), "table-key-properties")
stream_name = catalog_entry.tap_stream_id

singer.set_currently_syncing(state, stream_name)
singer.write_state(state)
singer.write_schema(
stream_name, catalog_entry.schema.to_dict(), key_properties, replication_key
)

LOGGER.info("%s: Starting sync", stream_name)
instance = streams.STREAMS[stream_name](config, state, catalog_entry, client)
counter_value = instance.sync()
singer.set_currently_syncing(state, None)
singer.write_state(state)
LOGGER.info("%s: Completed sync (%s rows)", stream_name, counter_value)


@singer.utils.handle_top_exception(LOGGER)
def main():
args = singer.utils.parse_args(
required_config_keys=['api_key', 'start_date', 'site'])
required_config_keys=["api_key", "start_date", "site"]
)

client = tap_chargebee.client.ChargebeeClient(args.config)

runner = ChargebeeRunner(
args, client, tap_chargebee.streams.AVAILABLE_STREAMS
)
client = ChargebeeClient(args.config)
available_streams = get_available_streams(args.config, client)

if args.discover:
runner.do_discover()
else:
# import pdb; pdb.set_trace()
runner.do_sync()
do_discover(args.config, args.state, available_streams)
elif args.catalog:
do_sync(args.config, args.catalog, args.state, client)


if __name__ == '__main__':
if __name__ == "__main__":
main()
Loading