-
Notifications
You must be signed in to change notification settings - Fork 38
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
Tdl 14803 check api access in discovery mode #74
base: master
Are you sure you want to change the base?
Conversation
tap_zendesk/discover.py
Outdated
elif json.loads(e.args[0]).get('description') == "You are missing the following required scopes: read": | ||
error_list.append(s.name) | ||
else: | ||
raise e |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Raise an exception from None.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Raised an exception from None.
tap_zendesk/http.py
Outdated
except Exception: # pylint: disable=broad-except | ||
response_json = {} | ||
if response.status_code != 200: | ||
message = "HTTP-error-code: {}, Error: {}".format( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use f-strings instead of format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replaced format with f-string.
tap_zendesk/streams.py
Outdated
headers = { | ||
'Content-Type': 'application/json', | ||
'Accept': 'application/json', | ||
'Authorization': 'Bearer {}'.format(self.config['access_token']) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
headers = { | |
'Content-Type': 'application/json', | |
'Accept': 'application/json', | |
'Authorization': 'Bearer {}'.format(self.config['access_token']) | |
} | |
headers = { | |
'Content-Type': 'application/json', | |
'Accept': 'application/json', | |
'Authorization': f'Bearer {self.config['access_token']}' | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replaced format with f-string.
tap_zendesk/streams.py
Outdated
LOGGER.warning("The account credentials supplied do not have access to `%s` custom fields.", | ||
stream) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LOGGER.warning("The account credentials supplied do not have access to `%s` custom fields.", | |
stream) | |
LOGGER.warning("The account credentials supplied do not have access to `%s` custom fields.", | |
stream) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved
}, | ||
403: { | ||
"raise_exception": ZendeskForbiddenError, | ||
"message": "You are missing the following required scopes: read" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will it be each time read
only? If No then please put a generalized message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Because we are calling just GET API for each stream. So, it will return the same message of read scopes.
tap_zendesk/http.py
Outdated
}, | ||
404: { | ||
"raise_exception": ZendeskNotFoundError, | ||
"message": "There is no help desk configured at this address. This means that the address is available and that you can claim it at http://www.zendesk.com/signup" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above if it is not the fixed message for 404 each time then please put a generalized message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to generalized message.
tap_zendesk/streams.py
Outdated
@@ -114,13 +115,33 @@ def load_metadata(self): | |||
def is_selected(self): | |||
return self.stream is not None | |||
|
|||
def check_access(self): | |||
''' | |||
Check whether permission given to access stream resource or not. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check whether permission given to access stream resource or not. | |
Check whether the permission was given to access stream resources or not. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
tap_zendesk/streams.py
Outdated
def raise_or_log_zenpy_apiexception(schema, stream, e): | ||
# There are multiple tiers of Zendesk accounts. Some of them have | ||
# access to `custom_fields` and some do not. This is the specific | ||
# error that appears to be return from the API call in the event that | ||
# it doesn't have access. | ||
if not isinstance(e, zenpy.lib.exception.APIException): | ||
raise ValueError("Called with a bad exception type") from e | ||
#If read permission not available in oauth access_token, then it returns below error. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#If read permission not available in oauth access_token, then it returns below error. | |
#If read permission is not available in OAuth access_token, then it returns the below error. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
…//github.com/singer-io/tap-zendesk into TDL-14803-check-api-access-in-discovery-mode
|
||
return 400 <=status_code < 500 | ||
|
||
def raise_for_error(response): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add comments for this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added comments.
else: | ||
raise e | ||
|
||
except http.ZendeskNotFoundError: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add comment for this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added comments.
tap_zendesk/discover.py
Outdated
try: | ||
# Here it call the check_access method to check whether stream have read permission or not. | ||
# If stream does not have read permission then append that stream name to list and at the end of all streams | ||
# raise forbidden error with proper message containinn stream names. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Typo in 'containing' word in the comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
tap_zendesk/discover.py
Outdated
for s in STREAMS.values(): | ||
s = s(client) | ||
s = s(client, config) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Can you please give understandable variable name instead of 's'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In existing code they have used 's'. Change in name will reflect lot off changes in code as it is used in many place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Please do the variable name changes. If it means change will reflect lot off changes that's fine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Add Comments to the code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Add Comments to the code
Added comments to the code. And you can find detailed comments in the try
block as well. Also updated the variable name s
to stream
tap_zendesk/discover.py
Outdated
# raise forbidden error with proper message containinn stream names. | ||
s.check_access() | ||
except ZendeskForbiddenError as e: | ||
error_list.append(s.name) # Append stream name to the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Incomplete comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
tap_zendesk/discover.py
Outdated
except ZendeskForbiddenError as e: | ||
error_list.append(s.name) # Append stream name to the | ||
except zenpy.lib.exception.APIException as e: | ||
err = json.loads(e.args[0]).get('error') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Since e.args[0]
is being used multiple times. Please make it a variable and get it converted in the json.loads
. and re-use it further everywhere
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
if error_list: | ||
streams_name = ", ".join(error_list) | ||
message = "HTTP-error-code: 403, Error: You are missing the following required scopes: read. "\ | ||
"The account credentials supplied do not have read access for the following stream(s): {}".format(streams_name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev As per the best practices, we should not use format()
. Please update this code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They don't updated python to the latest version. That's why format()
has been kept.
response_json = {} | ||
if response.status_code != 200: | ||
if response_json.get('error'): | ||
message = "HTTP-error-code: {}, Error: {}".format(response.status_code, response_json.get('error')) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Don't use format()
in the code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They don't updated python to the latest version. That's why format()
has been kept.
except http.ZendeskNotFoundError: | ||
# Skip stream if ticket_audit does not found for particular ticekt_id. Earlier it throwing HTTPError | ||
# but now as error handling updated, it throws ZendeskNotFoundError. | ||
message = "Unable to retrieve audits for ticket (ID: {}), record not found".format(ticket['id']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Don't use format()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They don't updated python to the latest version. That's why format()
has been kept.
if metrics_stream.is_selected(): | ||
try: | ||
for metric in metrics_stream.sync(ticket["id"]): | ||
self._buffer_record(metric) | ||
except HTTPError as e: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Why did we remove the HTTPError exception?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because earlier it throwing HTTPError but now as error handling updated, it throws ZendeskNotFoundError. So we replaced HTTPError with ZendeskNotFoundError. Added comment in code also.
tap_zendesk/streams.py
Outdated
url = self.endpoint.format(self.config['subdomain']) | ||
HEADERS['Authorization'] = 'Bearer {}'.format(self.config["access_token"]) | ||
|
||
http.call_api(url, self.config.get('request_timeout', DEFAULT_TIMEOUT), params={'start_time': 1610368140, 'per_page': 1}, headers=HEADERS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Why is there a static time in the code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here we calls api to just check api permission and we need to pass required start_time
parameter. It can be anything. Replaced it with constant
tap_zendesk/streams.py
Outdated
url = self.endpoint.format(self.config['subdomain']) | ||
HEADERS['Authorization'] = 'Bearer {}'.format(self.config["access_token"]) | ||
|
||
http.call_api(url, self.config.get('request_timeout', DEFAULT_TIMEOUT), params={'per_page': 1}, headers=HEADERS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Wouldn't there be a data-type issue here if config['request_timeout']
would be a number in string format?
Eg: config[request_timeout]: '200'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated it. Actually I had updated it in PR 79 as part of request timeout but remained that changes this PR.
tap_zendesk/streams.py
Outdated
|
||
for page in http.get_cursor_based(url, self.config['access_token'], **kwargs): | ||
# Pass `request_timeout` parameter | ||
for page in http.get_cursor_based(url, self.config['access_token'], self.config.get('request_timeout', DEFAULT_TIMEOUT), **kwargs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment here as well
Please initialize this value at a common place in the file and use it everywhere
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated it.
tap_zendesk/streams.py
Outdated
''' | ||
Check whether the permission was given to access stream resources or not. | ||
''' | ||
self.client.search("", updated_after=datetime.datetime.utcnow(), updated_before='2000-01-02T00:00:00Z', type="user") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev What are we searching here?
What does "" mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are using this API call in sync. This API call is used to retrieve users records in sync. We just checking whether that stream has read permission or not by same API call which used in sync. "" parameter is just any name of query. We followed the same call as in sync.
args0 = json.loads(e.args[0]) | ||
err = args0.get('error') | ||
|
||
if isinstance(err, dict): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Can you add same comment here as it is added in this PR - https://github.com/singer-io/tap-zendesk/pull/69/files#diff-89887ca52395ce152e9723c5595655edcd41793204060336e88ea9805c274433R142
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
tap_zendesk/streams.py
Outdated
@@ -16,6 +15,12 @@ | |||
LOGGER = singer.get_logger() | |||
KEY_PROPERTIES = ['id'] | |||
|
|||
REQUEST_TIMEOUT = 300 | |||
TICKET_START_TIME = 1610368140 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Why to keep a static value. You can use start time provided in the config.json file. Correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, updated and removed static time
@@ -199,7 +200,7 @@ def main(): | |||
LOGGER.error("""No suitable authentication keys provided.""") | |||
|
|||
if parsed_args.discover: | |||
do_discover(client) | |||
do_discover(client, parsed_args.config) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add comments to the code changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add comments to the code changes
Added comments
tap_zendesk/discover.py
Outdated
for s in STREAMS.values(): | ||
s = s(client) | ||
s = s(client, config) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Please do the variable name changes. If it means change will reflect lot off changes that's fine
tap_zendesk/discover.py
Outdated
for s in STREAMS.values(): | ||
s = s(client) | ||
s = s(client, config) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@prijendev Add Comments to the code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please look at my comments
Description of change
TDL-14803 Check API access in Discovery mode
Note - Added code of PR79 in this PR because it was require. So, first PR79 need to merge and once that PR merged changes will not be reflected here.
Manual QA steps
Risks
Rollback steps