This PR adds context in failure scenarios for certain requests.
Manual QA Steps
I generated 3 tokens with different sets of scopes
Accounts:Read
Forms:Read
Forms:Read and Responses:Read
I ran the tap with each token in the order described above. Note that each time the tap made it father "into" the code
The logs to prove we need more scopes on the token
Accounts:Read
INFO form: t6sbkCIz
INFO METRIC: {"type": "timer", "metric": "job_duration", "value": 0.3381948471069336, "tags": {"job_type": "form definition t6sbkCIz", "status": "failed"}}
CRITICAL HTTP-error-code: 403, Error: User doesn't have permission to access the resource.
Traceback (most recent call last):
File "/usr/local/share/virtualenvs/tap-typeform/bin/tap-typeform", line 33, in <module>
sys.exit(load_entry_point('tap-typeform', 'console_scripts', 'tap-typeform')())
File "/usr/local/share/virtualenvs/tap-typeform/lib/python3.8/site-packages/singer/utils.py", line 229, in wrapped
return fnc(*args, **kwargs)
File "/opt/code/tap-typeform/tap_typeform/__init__.py", line 128, in main
sync(atx)
File "/opt/code/tap-typeform/tap_typeform/__init__.py", line 81, in sync
streams.sync_forms(atx)
File "/opt/code/tap-typeform/tap_typeform/streams.py", line 282, in sync_forms
sync_form_definition(atx, form_id)
File "/opt/code/tap-typeform/tap_typeform/streams.py", line 96, in sync_form_definition
response = get_form_definition(atx, form_id)
File "/opt/code/tap-typeform/tap_typeform/streams.py", line 68, in get_form_definition
return atx.client.get_form_definition(form_id)
File "/opt/code/tap-typeform/tap_typeform/http.py", line 131, in get_form_definition
return self.request('get', url, **kwargs)
File "/usr/local/share/virtualenvs/tap-typeform/lib/python3.8/site-packages/backoff/_sync.py", line 94, in retry
ret = target(*args, **kwargs)
File "/usr/local/share/virtualenvs/tap-typeform/lib/python3.8/site-packages/backoff/_sync.py", line 94, in retry
ret = target(*args, **kwargs)
File "/opt/code/tap-typeform/tap_typeform/http.py", line 99, in request
raise_for_error(response)
File "/opt/code/tap-typeform/tap_typeform/http.py", line 170, in raise_for_error
raise exc(formatted_message, response) from None
tap_typeform.http.TypeformForbiddenError: HTTP-error-code: 403, Error: User doesn't have permission to access the resource.
Forms:Read
INFO form: t6sbkCIz
INFO METRIC: {"type": "timer", "metric": "job_duration", "value": 0.32311463356018066, "tags": {"job_type": "form definition t6sbkCIz", "status": "succeeded"}}
INFO METRIC: {"type": "counter", "metric": "record_count", "value": 2, "tags": {"endpoint": "questions"}}
INFO All landings query
CRITICAL HTTP-error-code: 403, Error: User doesn't have permission to access the resource.
Traceback (most recent call last):
File "/usr/local/share/virtualenvs/tap-typeform/bin/tap-typeform", line 33, in <module>
sys.exit(load_entry_point('tap-typeform', 'console_scripts', 'tap-typeform')())
File "/usr/local/share/virtualenvs/tap-typeform/lib/python3.8/site-packages/singer/utils.py", line 229, in wrapped
return fnc(*args, **kwargs)
File "/opt/code/tap-typeform/tap_typeform/__init__.py", line 128, in main
sync(atx)
File "/opt/code/tap-typeform/tap_typeform/__init__.py", line 81, in sync
streams.sync_forms(atx)
File "/opt/code/tap-typeform/tap_typeform/streams.py", line 285, in sync_forms
sync_landings(atx, form_id)
File "/opt/code/tap-typeform/tap_typeform/streams.py", line 244, in sync_landings
response = get_landings(atx, form_id)
File "/opt/code/tap-typeform/tap_typeform/streams.py", line 87, in get_landings
return atx.client.get_form_responses(form_id)
File "/opt/code/tap-typeform/tap_typeform/http.py", line 136, in get_form_responses
return self.request('get', url, **kwargs)
File "/usr/local/share/virtualenvs/tap-typeform/lib/python3.8/site-packages/backoff/_sync.py", line 94, in retry
ret = target(*args, **kwargs)
File "/usr/local/share/virtualenvs/tap-typeform/lib/python3.8/site-packages/backoff/_sync.py", line 94, in retry
ret = target(*args, **kwargs)
File "/opt/code/tap-typeform/tap_typeform/http.py", line 99, in request
raise_for_error(response)
File "/opt/code/tap-typeform/tap_typeform/http.py", line 170, in raise_for_error
raise exc(formatted_message, response) from None
tap_typeform.http.TypeformForbiddenError: HTTP-error-code: 403, Error: User doesn't have permission to access the resource.
Forms:Read and Responses:Read
INFO form: t6sbkCIz
INFO METRIC: {"type": "timer", "metric": "http_request_duration", "value": 0.2069098949432373, "tags": {"endpoint": "https://api.typeform.com/forms/t6sbkCIz", "status": "succeeded"}}
INFO METRIC: {"type": "timer", "metric": "job_duration", "value": 0.20743322372436523, "tags": {"job_type": "form definition t6sbkCIz", "status": "succeeded"}}
INFO METRIC: {"type": "counter", "metric": "record_count", "value": 2, "tags": {"endpoint": "questions"}}
INFO All landings query
INFO raw data items= 0
INFO METRIC: {"type": "timer", "metric": "http_request_duration", "value": 0.0352473258972168, "tags": {"endpoint": "https://api.typeform.com/forms/t6sbkCIz/responses", "status": "succeeded"}}
INFO METRIC: {"type": "counter", "metric": "record_count", "value": 0, "tags": {"endpoint": "landings"}}
INFO Forms query - form: t6sbkCIz start_date: 2021-05-10 00:00 end_date: 2021-05-11 00:00
INFO raw data items= 0
INFO METRIC: {"type": "timer", "metric": "http_request_duration", "value": 0.030831575393676758, "tags": {"endpoint": "https://api.typeform.com/forms/t6sbkCIz/responses", "status": "succeeded"}}
INFO METRIC: {"type": "timer", "metric": "job_duration", "value": 0.031381845474243164, "tags": {"job_type": "form t6sbkCIz", "status": "succeeded"}}
The new and improved logs
Accounts:Read
INFO form: t6sbkCIz
INFO METRIC: {"type": "timer", "metric": "http_request_duration", "value": 1.006927490234375, "tags": {"endpoint": "https://api.typeform.com/forms/t6sbkCIz", "status": "failed"}}
INFO METRIC: {"type": "timer", "metric": "job_duration", "value": 1.0073966979980469, "tags": {"job_type": "form definition t6sbkCIz", "status": "failed"}}
CRITICAL Maybe add the Forms:Read scope to your token
Traceback (most recent call last):
File "/opt/code/tap-typeform/tap_typeform/http.py", line 134, in get_form_definition
return self.request('get', url, **kwargs)
File "/usr/local/share/virtualenvs/tap-typeform/lib/python3.8/site-packages/backoff/_sync.py", line 94, in retry
ret = target(*args, **kwargs)
File "/usr/local/share/virtualenvs/tap-typeform/lib/python3.8/site-packages/backoff/_sync.py", line 94, in retry
ret = target(*args, **kwargs)
File "/opt/code/tap-typeform/tap_typeform/http.py", line 99, in request
raise_for_error(response)
File "/opt/code/tap-typeform/tap_typeform/http.py", line 179, in raise_for_error
raise exc(formatted_message, response) from None
tap_typeform.http.TypeformForbiddenError: HTTP-error-code: 403, Error: User doesn't have permission to access the resource.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/share/virtualenvs/tap-typeform/bin/tap-typeform", line 33, in <module>
sys.exit(load_entry_point('tap-typeform', 'console_scripts', 'tap-typeform')())
File "/usr/local/share/virtualenvs/tap-typeform/lib/python3.8/site-packages/singer/utils.py", line 229, in wrapped
return fnc(*args, **kwargs)
File "/opt/code/tap-typeform/tap_typeform/__init__.py", line 128, in main
sync(atx)
File "/opt/code/tap-typeform/tap_typeform/__init__.py", line 81, in sync
streams.sync_forms(atx)
File "/opt/code/tap-typeform/tap_typeform/streams.py", line 282, in sync_forms
sync_form_definition(atx, form_id)
File "/opt/code/tap-typeform/tap_typeform/streams.py", line 96, in sync_form_definition
response = get_form_definition(atx, form_id)
File "/opt/code/tap-typeform/tap_typeform/streams.py", line 68, in get_form_definition
return atx.client.get_form_definition(form_id)
File "/opt/code/tap-typeform/tap_typeform/http.py", line 136, in get_form_definition
raise RuntimeError("Maybe add the Forms:Read scope to your token") from err
RuntimeError: Maybe add the Forms:Read scope to your token
Forms:Read
INFO form: t6sbkCIz
INFO METRIC: {"type": "timer", "metric": "http_request_duration", "value": 0.1775655746459961, "tags": {"endpoint": "https://api.typeform.com/forms/t6sbkCIz", "status": "succeeded"}}
INFO METRIC: {"type": "timer", "metric": "job_duration", "value": 0.17805051803588867, "tags": {"job_type": "form definition t6sbkCIz", "status": "succeeded"}}
{"type": "RECORD", "stream": "questions", "record": {"form_id": "t6sbkCIz", "question_id": "e4hDM6IBIpyw"}, "time_extracted": "2021-07-27T03:32:02.618334Z"}
{"type": "RECORD", "stream": "questions", "record": {"form_id": "t6sbkCIz", "question_id": "IIYseA58pKxJ"}, "time_extracted": "2021-07-27T03:32:02.618334Z"}
INFO METRIC: {"type": "counter", "metric": "record_count", "value": 2, "tags": {"endpoint": "questions"}}
INFO All landings query
INFO METRIC: {"type": "timer", "metric": "http_request_duration", "value": 0.01852250099182129, "tags": {"endpoint": "https://api.typeform.com/forms/t6sbkCIz/responses", "status": "failed"}}
CRITICAL Maybe add the Responses:Read scope to your token
Traceback (most recent call last):
File "/opt/code/tap-typeform/tap_typeform/http.py", line 143, in get_form_responses
return self.request('get', url, **kwargs)
File "/usr/local/share/virtualenvs/tap-typeform/lib/python3.8/site-packages/backoff/_sync.py", line 94, in retry
ret = target(*args, **kwargs)
File "/usr/local/share/virtualenvs/tap-typeform/lib/python3.8/site-packages/backoff/_sync.py", line 94, in retry
ret = target(*args, **kwargs)
File "/opt/code/tap-typeform/tap_typeform/http.py", line 99, in request
raise_for_error(response)
File "/opt/code/tap-typeform/tap_typeform/http.py", line 179, in raise_for_error
raise exc(formatted_message, response) from None
tap_typeform.http.TypeformForbiddenError: HTTP-error-code: 403, Error: User doesn't have permission to access the resource.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/share/virtualenvs/tap-typeform/bin/tap-typeform", line 33, in <module>
sys.exit(load_entry_point('tap-typeform', 'console_scripts', 'tap-typeform')())
File "/usr/local/share/virtualenvs/tap-typeform/lib/python3.8/site-packages/singer/utils.py", line 229, in wrapped
return fnc(*args, **kwargs)
File "/opt/code/tap-typeform/tap_typeform/__init__.py", line 128, in main
sync(atx)
File "/opt/code/tap-typeform/tap_typeform/__init__.py", line 81, in sync
streams.sync_forms(atx)
File "/opt/code/tap-typeform/tap_typeform/streams.py", line 285, in sync_forms
sync_landings(atx, form_id)
File "/opt/code/tap-typeform/tap_typeform/streams.py", line 244, in sync_landings
response = get_landings(atx, form_id)
File "/opt/code/tap-typeform/tap_typeform/streams.py", line 87, in get_landings
return atx.client.get_form_responses(form_id)
File "/opt/code/tap-typeform/tap_typeform/http.py", line 145, in get_form_responses
raise RuntimeError("Maybe add the Responses:Read scope to your token") from err
RuntimeError: Maybe add the Responses:Read scope to your token
Forms:Read and Responses:Read
INFO form: t6sbkCIz
INFO METRIC: {"type": "timer", "metric": "http_request_duration", "value": 0.3422980308532715, "tags": {"endpoint": "https://api.typeform.com/forms/t6sbkCIz", "status": "succeeded"}}
INFO METRIC: {"type": "timer", "metric": "job_duration", "value": 0.34274935722351074, "tags": {"job_type": "form definition t6sbkCIz", "status": "succeeded"}}
INFO METRIC: {"type": "counter", "metric": "record_count", "value": 2, "tags": {"endpoint": "questions"}}
INFO All landings query
INFO raw data items= 0
INFO METRIC: {"type": "timer", "metric": "http_request_duration", "value": 0.034545183181762695, "tags": {"endpoint": "https://api.typeform.com/forms/t6sbkCIz/responses", "status": "succeeded"}}
INFO METRIC: {"type": "counter", "metric": "record_count", "value": 0, "tags": {"endpoint": "landings"}}
INFO Forms query - form: t6sbkCIz start_date: 2021-05-10 00:00 end_date: 2021-05-11 00:00
INFO raw data items= 0
INFO METRIC: {"type": "timer", "metric": "http_request_duration", "value": 0.03435397148132324, "tags": {"endpoint": "https://api.typeform.com/forms/t6sbkCIz/responses", "status": "succeeded"}}
INFO METRIC: {"type": "timer", "metric": "job_duration", "value": 0.034932851791381836, "tags": {"job_type": "form t6sbkCIz", "status": "succeeded"}}
Risks
It appeared that the release of v1.3.0 affected the scopes on the tokens somehow. Because tap runs that would previously succeed on v1.2.0 failed on v1.3.0 and v1.3.2.
Since things are broken, this PR should be very low risk because it only helps people help themselves
Description
This PR adds context in failure scenarios for certain requests.
Manual QA Steps
I generated 3 tokens with different sets of scopes
Accounts:Read
Forms:Read
Forms:Read
andResponses:Read
I ran the tap with each token in the order described above. Note that each time the tap made it father "into" the code
The logs to prove we need more scopes on the token
Accounts:Read
Forms:Read
Forms:Read
andResponses:Read
The new and improved logs
Accounts:Read
Forms:Read
Forms:Read
andResponses:Read
Risks
It appeared that the release of
v1.3.0
affected the scopes on the tokens somehow. Because tap runs that would previously succeed onv1.2.0
failed onv1.3.0
andv1.3.2
.Since things are broken, this PR should be very low risk because it only helps people help themselves
Rollback Steps
Revert the commit and bump the version