Skip to content

Commit 779bc57

Browse files
atttiwariAtul Tiwari
andauthored
Gl Work (#4)
* SAC-28202: Initial Commit * SAC-28202: Updated readme file * SAC-28202: Update in config * SAC-28202: Update in client.py file for refresh token * SAC-28202: Updated in base url creation * SAC-28202: Fix base url issue * SAC-28202: Update for unittest default implementaion and schema update * SAC-28202: Updated for no content in response data * SAC-28202: Updated auto add new metadata field * SAC-28202: Updated required field name * SAC-28202: Updated config.yaml * SAC-28202: Updated config.yaml file * SAC-28202: Added parameterized module * SAC-28202: Updated unitest module in config.yaml file * SAC-28202: Updated config.yaml file * SAC-28204: Generate Schema for Streams Including Dynamic Schemas (#1) * SAC-28204: Implemented logic to fetch dynamic schema * SAC-28204: Implemented logic to fetch dynamic schema * SAC-28204: Updated for pk_field default id * SAC-28204: Update for response variable * SAC-28204: Updated for config fields * SAC-28204: Addressed Copilot review comments * SAC-28204: Addressed Copilot comments * SAC-28204: Addressed review comments * SAC-28204: Adderessed review comments * Implement data sync with pagination, bookmark handling, and unit tests (#2) * SAC-28501: Added Sync logic * SAC-28501: Updated for unit test cases * SAC-28501:Updated code to address copilot review comments * SAC-28501:Updated code to address copilot review comments * Create copilot-instructions.md * SAC-28501: Addressed copilot reviewed comments * SAC-28501: Addressed copilot review remarks * SAC-28501: Updated unittest cases, remove use of pytest module * SAC-28501: Addressed copilot review comments * SAC-28501: Addressed review comments * SAC-28501: Addressed review comments * SAC-28501: Addressed review comments * SAC-28501: Addressed review comments * SAC-28202: Updated copilot instructions.md file * SAC-28202: Updated for integration tests * SAC-28202: Update in circle.ci file * SAC-28504: Update for integration test fix * SAC-28504: Updated for integration bug fixes * SAC-28504: Added retry for 400 access denied error * SAC-28504: Added retry for 400 access denied error * SAC-28202: removed api_version key from config/endpoint url * SAC-28504: Finale updated code for readme and spike template file * SAC-28504: update in config.yaml * SAC-28504: Update in clients.py for comment * SAC-28504: Updated unittest cases --------- Co-authored-by: Atul Tiwari <attiwari@gcp-qlink01.c.qlik-mobile-app-devel-11014270.internal>
1 parent ec58801 commit 779bc57

41 files changed

Lines changed: 4157 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.circleci/config.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
version: 2.1
2+
jobs:
3+
build:
4+
docker:
5+
- image: 218546966473.dkr.ecr.us-east-1.amazonaws.com/circle-ci:stitch-tap-tester
6+
steps:
7+
- checkout
8+
- run:
9+
name: "Setup virtual env"
10+
command: |
11+
python3 -mvenv /usr/local/share/virtualenvs/tap-zoho-crm
12+
source /usr/local/share/virtualenvs/tap-zoho-crm/bin/activate
13+
pip install -U "pip==22.2.2" "setuptools==65.3.0"
14+
pip install .[dev]
15+
- run:
16+
name: "JSON Validator"
17+
command: |
18+
source /usr/local/share/virtualenvs/tap-tester/bin/activate
19+
stitch-validate-json tap_zoho_crm/schemas/*.json
20+
- run:
21+
name: "pylint"
22+
command: |
23+
source /usr/local/share/virtualenvs/tap-zoho-crm/bin/activate
24+
pip install pylint
25+
pylint tap_zoho_crm -d C,R,W
26+
- add_ssh_keys
27+
- run:
28+
name: "Unit Tests"
29+
command: |
30+
source /usr/local/share/virtualenvs/tap-zoho-crm/bin/activate
31+
pip install nose coverage
32+
nosetests --with-coverage --cover-erase --cover-package=tap_zoho_crm --cover-html-dir=htmlcov tests/unittests
33+
coverage html
34+
- store_test_results:
35+
path: test_output/report.xml
36+
- store_artifacts:
37+
path: htmlcov
38+
# - run:
39+
# name: "Integration Tests"
40+
# command: |
41+
# aws s3 cp s3://com-stitchdata-dev-deployment-assets/environments/tap-tester/tap_tester_sandbox dev_env.sh
42+
# source dev_env.sh
43+
# source /usr/local/share/virtualenvs/tap-tester/bin/activate
44+
# run-test --tap=tap-zoho-crm tests
45+
46+
47+
workflows:
48+
version: 2
49+
commit:
50+
jobs:
51+
- build:
52+
context: circleci-user
53+
build_daily:
54+
triggers:
55+
- schedule:
56+
cron: "0 19 * * *"
57+
filters:
58+
branches:
59+
only:
60+
- master
61+
jobs:
62+
- build:
63+
context: circleci-user

.github/copilot-instructions.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Instructions for Building a Singer Tap/Target
2+
3+
This document provides guidance for implementing a high-quality Singer Tap (or Target) in compliance with the Singer specification and community best practices. Use it in conjunction with GitHub Copilot or your preferred IDE.
4+
5+
---
6+
7+
## 1. Rate Limiting
8+
9+
- Respect API rate limits (e.g., daily quotas or per-second limits).
10+
- For short-term rate limits, detect HTTP 429 or similar errors and implement retries with sleep/delay.
11+
- Use Singer’s built-in rate-limiting utilities where available.
12+
13+
14+
## 2. Memory Efficiency
15+
16+
- Minimize RAM usage by streaming data.
17+
Example: Use generators or iterators instead of loading entire datasets into memory.
18+
19+
20+
## 3. Consistent Date Handling
21+
22+
- Use RFC 3339 format (including time zone offset). UTC (Z) is preferred.
23+
Examples:
24+
Good: 2017-01-01T00:00:00Z, 2017-01-01T00:00:00-05:00
25+
Bad: 2017-01-01 00:00:00
26+
Use pytz for timezone-aware conversions.
27+
28+
29+
## 4. Logging & Exception Handling
30+
31+
- Log every API request (URL + parameters), omitting sensitive info (e.g., API keys).
32+
- Log progress updates (e.g., “Starting stream X”).
33+
- On API errors, log status code and response body.
34+
35+
For fatal errors:
36+
- Log at CRITICAL or FATAL level.
37+
- Exit with non-zero status.
38+
- Omit stack trace for known, user-triggered conditions.
39+
- Include full trace for unexpected exceptions.
40+
- For recoverable errors, implement retries with exponential backoff (e.g., using the backoff library).
41+
42+
43+
## 5. Module Structure
44+
45+
- Organize code into a proper Python module (directory with __init__.py), not a single script file.
46+
47+
48+
## 6. Schema Management
49+
50+
- For static schemas, store them as .json files in a schemas/ directory—not as inline Python dicts.
51+
Prefer explicit schemas:
52+
- Avoid additionalProperties: true or vague typing.
53+
- Use clear field names and types.
54+
- Set additionalProperties: false when schemas must be strict.
55+
- Be cautious when tightening schemas in new versions—it may require a major version bump per semantic versioning.
56+
57+
58+
## 7. JSON Schema Guidelines
59+
60+
- All files under schemas/*.json must follow the JSON Schema standard.
61+
- Any fields named created_time, modified_time, ending in _time or ending in _date must use the date-time format.
62+
- Avoid using additionalProperties at the root level. It's allowed in nested fields only.
63+
64+
Example:
65+
{
66+
"type": "object",
67+
"properties": {
68+
"created_time": {
69+
"type": ["null", "string"],
70+
"format": "date-time"
71+
},
72+
"last_access_time": {
73+
"type": ["null", "string"],
74+
"format": "date-time"
75+
}
76+
}
77+
}
78+
79+
80+
## 8. Validating Bookmarking
81+
82+
We use the singer.bookmarks module to read from and write to the bookmark state file.
83+
To ensure correctness, always validate the structure of the bookmark state before processing or committing any changes.
84+
- In abstract.py, we use get_bookmark() and write_bookmark() to manage bookmarks for streams.
85+
- The write_bookmark() function overrides the one from the singer module to apply custom behavior.
86+
- Always confirm that the state structure matches the expected format before writing.
87+
88+
Format Example:
89+
{
90+
"bookmarks": {
91+
"stream_name": {
92+
"replication_key": "2024-01-01T00:00:00Z"
93+
}
94+
}
95+
}
96+
97+
98+
Optional validation function:
99+
def is_valid_bookmark_state(state):
100+
return isinstance(state, dict) and \
101+
"bookmarks" in state and \
102+
isinstance(state["bookmarks"], dict)
103+
104+
105+
## 9. Code Quality
106+
107+
- Use pylint and aim for zero error-level messages.
108+
- CI pipelines (e.g., CircleCI) should enforce linting.
109+
- Fix or explicitly disable warnings when appropriate.

.gitignore

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
2+
!*.*
3+
4+
5+
__pycache__/
6+
*.py[cod]
7+
*$py.class
8+
9+
10+
*.so
11+
12+
13+
.Python
14+
env/
15+
build/
16+
develop-eggs/
17+
dist/
18+
downloads/
19+
eggs/
20+
.eggs/
21+
lib/
22+
lib64/
23+
parts/
24+
sdist/
25+
var/
26+
*.egg-info/
27+
.installed.cfg
28+
*.egg
29+
30+
31+
32+
33+
*.manifest
34+
*.spec
35+
36+
37+
pip-log.txt
38+
pip-delete-this-directory.txt
39+
40+
41+
htmlcov/
42+
.tox/
43+
.coverage
44+
.coverage.*
45+
.cache
46+
nosetests.xml
47+
coverage.xml
48+
*,cover
49+
.hypothesis/
50+
51+
52+
*.mo
53+
*.pot
54+
55+
56+
*.log
57+
local_settings.py
58+
59+
60+
instance/
61+
.webassets-cache
62+
63+
64+
.scrapy
65+
66+
67+
docs/_build/
68+
69+
70+
target/
71+
72+
73+
.ipynb_checkpoints
74+
75+
76+
.python-version
77+
78+
79+
celerybeat-schedule
80+
81+
82+
.env
83+
84+
85+
venv/
86+
ENV/
87+
88+
89+
.spyderproject
90+
91+
92+
.ropeproject
93+
94+
95+
._*
96+
.DS_Store
97+
98+
99+
env.sh
100+
config.json
101+
.autoenv.zsh
102+
103+
rsa-key
104+
tags
105+
singer-check-tap-data
106+
state.json
107+
108+
catalog.json
109+
get_catalog.py
110+
persist/
111+
configs/
112+
current_state/

.pre-commit-config.yaml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
default_stages: [commit]
2+
repos:
3+
- repo: https://github.com/pre-commit/pre-commit-hooks
4+
rev: v5.0.0
5+
hooks:
6+
- id: check-merge-conflict
7+
- id: check-docstring-first
8+
- id: debug-statements
9+
- id: trailing-whitespace
10+
- id: check-toml
11+
- id: end-of-file-fixer
12+
- id: check-yaml
13+
- id: sort-simple-yaml
14+
- id: check-json
15+
- id: pretty-format-json
16+
args: ['--autofix','--no-sort-keys']
17+
18+
- repo: https://github.com/psf/black
19+
rev: 23.12.0
20+
hooks:
21+
- id: black
22+
23+
- repo: https://github.com/pycqa/flake8
24+
rev: 7.1.2
25+
hooks:
26+
- id: flake8
27+
args: ["--ignore=W503,E501,C901"]
28+
additional_dependencies: [
29+
'flake8-print',
30+
'flake8-debugger',
31+
]
32+
33+
- repo: https://github.com/PyCQA/bandit
34+
rev: '1.7.10'
35+
hooks:
36+
- id: bandit
37+
38+
- repo: https://github.com/PyCQA/docformatter
39+
rev: v1.7.5
40+
hooks:
41+
- id: docformatter
42+
args: [--in-place]
43+
44+
- repo: https://github.com/codespell-project/codespell
45+
rev: v2.4.1
46+
hooks:
47+
- id: codespell

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
## 0.0.1
2+
* Initial Commit

0 commit comments

Comments
 (0)