-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Tdl 19964 add missing tap tester tests (#65) * TDL-19964 Added missing tap-tester commits * updated tap-tester tests * updated bookmarks tap-tester test * Updated and removed extra comments * updated start date as per format * updated pagination test case * resolved review comments * added new stream in tap-tester * fixed the cci issues * added missing assertion for all fields * removed get_logger() * added logger instead of print * TDL-19957 Update dict based to class based implementation (#64) * TDL-19957 update dict based to class based * updated while condition * updated while condition * removed incremental_range from REQUIRED_CONFIG_KEYS * updated discover and schema file * updated to replication_key instead of keys * updated schemas and added comments * added unittests for code coverage * added unittests for sync.py * added parameterized in setup.py * added parameterized in config.yml and updated unittests * updated the replication key to list instead of a single key * fixed the issue for Keyerror of form_id in answers stream * updated unittests * added configurable page size param * handled page_size for 0 and updated unittests * resolved bug fixes for pagination and removed incompleted_forms_only param * added new stream unsubmitted landings * resolved PR review comments * added page_size in example config * added back incremental_range in the tap-tester * raised exc instead of fatal error message and updated unittests * resolved PR comments * fixed the issue when page_size not passed in config * TDL-19801: Tap fetch data for sub-questions (#62) * TDL-19801: Tap does not support fetching data for the questions nested within a Question Group. * addressed the comments * add unittest * modify funciton comment * formated test_case value in unittest * formated expected_case * Updated schema in questions.json * resolved build fail error * resolve build fail error * updated unittest * updated setup.py * add parameterized * change start date in start_date_test * make change in bookmark test * Updated unit test case. * Updated schemas and keyerror. Co-authored-by: Jay Tilala <[email protected]> Co-authored-by: prijendev <[email protected]> * TDL-19959 added missing fields (#63) * added missing fields * TDL-19957 update dict based to class based * updated while condition * updated while condition * removed incremental_range from REQUIRED_CONFIG_KEYS * TDL-19964 Added missing tap-tester commits * updated discover and schema file * updated tap-tester tests * updated to replication_key instead of keys * updated schemas and added comments * added unittests for code coverage * updated bookmarks tap-tester test * added unittests for sync.py * added parameterized in setup.py * added parameterized in config.yml and updated unittests * updated the replication key to list instead of a single key * Updated and removed extra comments * fixed the issue for Keyerror of form_id in answers stream * updated unittests * updated start date as per format * added configurable page size param * updated pagination test case * handled page_size for 0 and updated unittests * resolved review comments * resolved bug fixes for pagination and removed incompleted_forms_only param * updated array type schema * added new stream unsubmitted landings * added new stream in tap-tester * updated indentation * resolved PR review comments * updated indentation to use 2 spaces * added page_size in example config * added back incremental_range in the tap-tester * fixed the cci issues * added missing fields to a dict * added missing assertion for all fields * updated comment * raised exc instead of fatal error message and updated unittests * removed get_logger() * added logger instead of print * Updated schema for questions. * Removed duplicate assertion in all_fields test. Co-authored-by: prijendev <[email protected]> * Updated schema for answers stream. Co-authored-by: namrata270998 <[email protected]> Co-authored-by: jtilala <[email protected]> Co-authored-by: Jay Tilala <[email protected]>
- Loading branch information
1 parent
023c187
commit 29f0ba4
Showing
35 changed files
with
2,423 additions
and
1,354 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ | |
"ratelimit", | ||
"backoff", | ||
"requests", | ||
"parameterized", | ||
], | ||
extras_require={ | ||
'dev': [ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,131 +1,52 @@ | ||
#!/usr/bin/env python3 | ||
import singer | ||
from singer import utils | ||
from singer.catalog import Catalog, metadata_module as metadata | ||
from tap_typeform import streams | ||
from tap_typeform.context import Context | ||
from tap_typeform.http import Client | ||
from tap_typeform import schemas | ||
from tap_typeform.discover import discover as _discover | ||
from tap_typeform.sync import _forms_to_list, sync as _sync | ||
from tap_typeform.client import Client | ||
from tap_typeform.streams import Forms | ||
|
||
REQUIRED_CONFIG_KEYS = ["token", "forms", "incremental_range"] | ||
REQUIRED_CONFIG_KEYS = ["start_date", "token", "forms"] | ||
|
||
LOGGER = singer.get_logger() | ||
|
||
#def check_authorization(atx): | ||
# atx.client.get('/settings') | ||
class FormMistmatchError(Exception): | ||
pass | ||
|
||
class NoFormsProvidedError(Exception): | ||
pass | ||
|
||
|
||
# Some taps do discovery dynamically where the catalog is read in from a | ||
# call to the api but with the typeform structure, we won't do that here | ||
# because it's always the same so we just pull it from file we never use | ||
# atx in here since the schema is from file but we would use it if we | ||
# pulled schema from the API def discover(atx): | ||
def discover(): | ||
streams = [] | ||
for tap_stream_id in schemas.STATIC_SCHEMA_STREAM_IDS: | ||
#print("tap stream id=",tap_stream_id) | ||
key_properties = schemas.PK_FIELDS[tap_stream_id] | ||
schema = schemas.load_schema(tap_stream_id) | ||
replication_method = schemas.REPLICATION_METHODS[tap_stream_id].get("replication_method") | ||
replication_keys = schemas.REPLICATION_METHODS[tap_stream_id].get("replication_keys") | ||
meta = metadata.get_standard_metadata(schema=schema, | ||
key_properties=key_properties, | ||
replication_method=replication_method, | ||
valid_replication_keys=replication_keys) | ||
|
||
meta = metadata.to_map(meta) | ||
|
||
if replication_keys: | ||
meta = metadata.write(meta, ('properties', replication_keys[0]), 'inclusion', 'automatic') | ||
|
||
meta = metadata.to_list(meta) | ||
|
||
streams.append({ | ||
'stream': tap_stream_id, | ||
'tap_stream_id': tap_stream_id, | ||
'key_properties': key_properties, | ||
'schema': schema, | ||
'metadata': meta, | ||
'replication_method': replication_method, | ||
'replication_key': replication_keys[0] if replication_keys else None | ||
}) | ||
return Catalog.from_dict({'streams': streams}) | ||
|
||
|
||
# this is already defined in schemas.py though w/o dependencies. do we keep this for the sync? | ||
def load_schema(tap_stream_id): | ||
path = "schemas/{}.json".format(tap_stream_id) | ||
schema = utils.load_json(get_abs_path(path)) | ||
dependencies = schema.pop("tap_schema_dependencies", []) | ||
refs = {} | ||
for sub_stream_id in dependencies: | ||
refs[sub_stream_id] = load_schema(sub_stream_id) | ||
if refs: | ||
singer.resolve_schema_references(schema, refs) | ||
return schema | ||
|
||
|
||
def sync(atx): | ||
|
||
# write schemas for selected streams\ | ||
for stream in atx.catalog.streams: | ||
if stream.tap_stream_id in atx.selected_stream_ids: | ||
schemas.load_and_write_schema(stream.tap_stream_id) | ||
|
||
# since there is only one set of schemas for all forms, they will always be selected | ||
streams.sync_forms(atx) | ||
|
||
LOGGER.info('--------------------') | ||
for stream_name, stream_count in atx.counts.items(): | ||
LOGGER.info('%s: %d', stream_name, stream_count) | ||
LOGGER.info('--------------------') | ||
|
||
|
||
def _compare_forms(config_forms, api_forms): | ||
return config_forms.difference(api_forms) | ||
|
||
|
||
def _forms_to_list(config, keyword='forms'): | ||
"""Splits entries into a list and strips out surrounding blank spaces""" | ||
return list(map(str.strip, config.get(keyword).split(','))) | ||
|
||
|
||
def validate_form_ids(config): | ||
def validate_form_ids(client, config): | ||
"""Validate the form ids passed in the config""" | ||
client = Client(config) | ||
form_stream = Forms() | ||
|
||
if not config.get('forms'): | ||
LOGGER.fatal("No forms were provided in config") | ||
raise NoFormsProvidedError | ||
raise NoFormsProvidedError("No forms were provided in the config") | ||
|
||
config_forms = set(_forms_to_list(config)) | ||
api_forms = {form.get('id') for form in client.get_forms()} | ||
config_forms = _forms_to_list(config) | ||
api_forms = {form.get('id') for res in form_stream.get_forms(client) for form in res} | ||
|
||
mismatched_forms = _compare_forms(config_forms, api_forms) | ||
mismatched_forms = config_forms.difference(api_forms) | ||
|
||
if len(mismatched_forms) > 0: | ||
LOGGER.fatal(f"FormMistmatchError: forms {mismatched_forms} not returned by API") | ||
raise FormMistmatchError | ||
# Raise an error if any form-id from config is not matching | ||
# from ids from API response | ||
raise FormMistmatchError("FormMistmatchError: forms {} not returned by API".format(mismatched_forms)) | ||
|
||
|
||
@utils.handle_top_exception(LOGGER) | ||
def main(): | ||
args = utils.parse_args(REQUIRED_CONFIG_KEYS) | ||
atx = Context(args.config, args.state) | ||
config = args.config | ||
client = Client(config) | ||
validate_form_ids(client, config) | ||
if args.discover: | ||
validate_form_ids(args.config) | ||
# the schema is static from file so we don't need to pass in atx for connection info. | ||
catalog = discover() | ||
catalog = _discover() | ||
catalog.dump() | ||
else: | ||
atx.catalog = args.catalog \ | ||
if args.catalog else discover() | ||
sync(atx) | ||
catalog = args.catalog \ | ||
if args.catalog else _discover() | ||
_sync(client, config, args.state, catalog.to_dict()) | ||
|
||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.