Skip to content
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

Keyerror data token #316

Merged
merged 12 commits into from
Feb 16, 2022
Merged

Conversation

RichieB2B
Copy link
Contributor

Breaking change

Proposed change

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New service (thank you!)
  • New feature (which adds functionality to an existing service)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests
  • Documentation or code sample

Example of code:

api = PyiCloudService(username.strip(), password.strip())
drive = api.drive
for i in api.drive.dir()
    item = drive[i]
    if item.type == "file":
        localfile = os.path.join('.', item.name)
        with item.open(stream=True) as response:
            with open(localfile, "wb") as file_out:
                copyfileobj(response.raw, file_out)

This produces a KeyError: 'data_token' before this patch when a packaged file like a keynote presentation is attempted to be downloaded.

Additional information

I was unable to download keynote files. Even though they have type FILE they do not contain a data_token URL. Instead they have a package_token URL. This patch tries them in that order or returns None if neither are available.

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

  • Documentation added/updated to README

@RichieB2B
Copy link
Contributor Author

I chose to return None because get_file() also returns None when response.ok is false. This actually makes detecting why get_file() failed pretty hard.

Maybe get_file() should raise a PyiCloudAPIResponseException instead when response.ok is false, and a KeyError when neither data_token and package_token are found?

@mandarons
Copy link

Any plan to merge this PR?

@RichieB2B
Copy link
Contributor Author

Maybe @nzapponi can approve it?

@osheanlee
Copy link

Hi! I was also working on a code that's on the README right now, i.e.:

with drive_file.open(stream=True) as response:
  with open(drive_file.name, 'wb') as file_out:
    copyfileobj(response.raw, file_out)

Then I got the KeyError: 'data_toke' message. And I happened to see this. Would this be somehow related? The error is being produced by the first line of the ^ code.

@RichieB2B
Copy link
Contributor Author

Would this be somehow related? The error is being produced by the first line of the ^ code.

If you try to open a package file like a Keynote or similar: yes, definitely.

@RichieB2B
Copy link
Contributor Author

@balloob Please consider this PR that fixed an import bug. It merges nicely with the current master.

pyicloud/services/drive.py Outdated Show resolved Hide resolved
pyicloud/services/drive.py Outdated Show resolved Hide resolved
Comment on lines 71 to 72
else:
raise KeyError("'data_token' nor 'package_token'")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
else:
raise KeyError("'data_token' nor 'package_token'")
raise PyiCloudAPIResponseException("'data_token' nor 'package_token' found")

Copy link
Contributor Author

@RichieB2B RichieB2B Feb 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before my patch get_file did return a KeyError just like get_children also does. IMHO KeyError is the correct exception because the data_token is missing the expected keys.

def get_children(self):
"""Gets the node children."""
if not self._children:
if "items" not in self.data:
self.data.update(self.connection.get_node_data(self.data["docwsid"]))
if "items" not in self.data:
raise KeyError("No items in folder, status: %s" % self.data["status"])
self._children = [
DriveNode(self.connection, item_data)
for item_data in self.data["items"]
]
return self._children

pyicloud/services/drive.py Outdated Show resolved Hide resolved
@balloob balloob merged commit 42331c3 into picklepete:master Feb 16, 2022
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants