-
Notifications
You must be signed in to change notification settings - Fork 448
Implement call to move to highest supported REST API version #100
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,19 @@ | ||
| import xml.etree.ElementTree as ET | ||
|
|
||
| from .exceptions import NotSignedInError | ||
| from .endpoint import Sites, Views, Users, Groups, Workbooks, Datasources, Projects, Auth, Schedules, ServerInfo | ||
| from .endpoint import Sites, Views, Users, Groups, Workbooks, Datasources, Projects, Auth, \ | ||
| Schedules, ServerInfo, ServerInfoEndpointNotFoundError | ||
|
|
||
| import requests | ||
|
|
||
| _PRODUCT_TO_REST_VERSION = { | ||
| '10.0': '2.3', | ||
| '9.3': '2.2', | ||
| '9.2': '2.1', | ||
| '9.1': '2.0', | ||
| '9.0': '2.0' | ||
| } | ||
|
|
||
|
|
||
| class Server(object): | ||
| class PublishMode: | ||
|
|
@@ -47,6 +58,29 @@ def _set_auth(self, site_id, user_id, auth_token): | |
| self._user_id = user_id | ||
| self._auth_token = auth_token | ||
|
|
||
| def _get_legacy_version(self): | ||
| response = self._session.get(self.server_address + "/auth?format=xml") | ||
| info_xml = ET.fromstring(response.content) | ||
| prod_version = info_xml.find('.//product_version').text | ||
| version = _PRODUCT_TO_REST_VERSION.get(prod_version, '2.1') # 2.1 | ||
| return version | ||
|
|
||
| def _determine_highest_version(self): | ||
| try: | ||
| old_version = self.version | ||
| self.version = "2.4" | ||
| version = self.server_info.get().rest_api_version | ||
| except ServerInfoEndpointNotFoundError: | ||
| version = self._get_legacy_version() | ||
|
|
||
| finally: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems a bit weird. We are setting the version, determining the new version, and then resetting the old version. I think with the way this is written, we probably don't need _determine_highest_version to be it's own function. In this case, we could do something like the following pseudo-code I'm not sure which version would be clearer to understand.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I currently have it this way so that this function simply retrieves the highest supported version, and the caller is responsible for setting it wherever it wants to be set -- this lets us reuse the function elsewhere (I don't know a use case yet, but I don't think the premature refactor makes it harder to follow). I'd prefer the separation, if there's a strong objection let me know and I can combine it. I'm pro-flag that does this automatically!!! I'll let Lee weigh in and can respond accordingly
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not have a strong opinion either way, like I said, I wasn't sure which direction was clearer, and you make a good point about reuse. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefer the API is set to the highest level (since that is usually what most people expect). If someone wants to fix the version - they can set the version after sign in.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you think if you put this in the use_highest_version() function it could not be used elsewhere? Just because it is a public function doesn't mean you can't call it from other parts of the code. Seems like we don't need two functions.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think As a side benefit I think it keeps the little bits with the try/excepts much easier to follow to a new reader of the code, vs jamming it all into one function that also sets it on the |
||
| self.version = old_version | ||
|
|
||
| return version | ||
|
|
||
| def use_highest_version(self): | ||
| self.version = self._determine_highest_version() | ||
|
|
||
| @property | ||
| def baseurl(self): | ||
| return "{0}/api/{1}".format(self._server_address, str(self.version)) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <tsResponse xmlns="http://tableau.com/api" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://tableau.com/api http://tableau.com/api/ts-api-2.3.xsd"> | ||
| <error code="404003"> | ||
| <summary>Resource Not Found</summary> | ||
| <detail>Unknown resource '/2.4/serverInfo' specified in URI.</detail> | ||
| </error> | ||
| </tsResponse> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| <authinfo> | ||
| <version version="0.31"> | ||
| <api_version>0.31</api_version> | ||
| <server_api_version>0.31</server_api_version> | ||
| <document_version>9.2</document_version> | ||
| <product_version>9.3</product_version> | ||
| <external_version>9.3.4</external_version> | ||
| <build>hello.16.1106.2025</build> | ||
| <publishing_method>unrestricted</publishing_method> | ||
| <mobile_api_version>2.6</mobile_api_version> | ||
| </version> | ||
| </authinfo> |
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.
I'll make that comment not a random repetition:
2.1 is the version with permissions changesThere 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.
Personally, I am not sure I would include this code. The implication of adding this is that we actually test against some of these older versions, which we don't. While believe we should work with most of it, my inclination would be that if the user asks us to pick the latest version, and we can't find it (ie there is no serverInfo endpoint), we set it to 9.3. I am open to discuss, though. I am sure it is helpful, however we do need to be clear about what we actually test against.
Uh oh!
There was an error while loading. Please reload this page.
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.
We could just default to 9.3's REST API version -- this was recommended by @RussTheAerialist since I think he plans to decorate versions back farther than 9.3.
I'm fine either way