-
Notifications
You must be signed in to change notification settings - Fork 184
File.get_contents() now broken #687
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
Comments
Note this also affects the Edit: following up on @byubean's hypothesis, if you manually use the
Edit 2: But if you clear the session cookies PRIOR to downloading...everything is all good so does seem like a cookie problem.
Specifically the following two cookies are the culprits:
Which are the Canvas session cookies. If you include these in the GET request, you get a 401. If you don't...you get a 200 and the response as expected. |
@bainco thank you for giving a solution, |
After a little more investigation, I think the problem is that if you accidentally add a (maybe) malformed cookie to the session at any point, that session will now get 401s from this endpoint until you delete those cookies: Say you have some Step 0You can 100% use the
Step 1But, if you make a seemingly valid request for a sub attachment using the
This results in the
Step 2To recover, you have to go and delete the aforementioned cookies inside the session:
Which now result in a 200 code and the correct response. If you want to reset the
|
Underlying reason aside, seems like you can patch in place by specifying from canvasapi.file import File
def patched_download(self, location):
"""
Download the file to specified location.
:param location: The path to download to.
:type location: str
"""
response = self._requester.request("GET", _url=self.url, use_auth=False)
with open(location, "wb") as file_out:
file_out.write(response.content)
def patched_get_contents(self, binary=False):
"""
Download the contents of this file.
Pass binary=True to return a bytes object instead of a str.
:rtype: str or bytes
"""
response = self._requester.request("GET", _url=self.url, use_auth=False)
if binary:
return response.content
else:
return response.text
File.get_contents = patched_get_contents
File.download = patched_download |
Roughly April 10th, 2025, something changed about the way auth was handled for files. By including the auth headers in GET requests for files, a session cookie was being set that seemed to cause 401s for any file requests. In essence, one bad request meant that you couldn't recover unless you specifically cleared those cookies out of the session. Here we avoid that problem entirely by simply not sending auth headers when requesting attachment downloads. More discussion here: ucfopen#687
Roughly April 10th, 2025, something changed about the way auth was handled for files. By including the auth headers in GET requests for files, a session cookie was being set that seemed to cause 401s for any file requests. In essence, one bad request meant that you couldn't recover unless you specifically cleared those cookies out of the session. Here we avoid that problem entirely by simply not sending auth headers when requesting attachment downloads. More discussion here: ucfopen#687
This might be fixed on Canvas's end - can someone confirm (besides my testing). |
Hi @ururk, most likely this was caused in Canvas by this commit instructure/canvas-lms@8ed721d was reverted instructure/canvas-lms@fe37f85 yesterday. |
Yes, I have been in contact with Canvas team since last Friday, and they started to work on it. They got back to me ,yesterday or today about them having dealt with it. Not sure if they completely reverted the change or did a revert+fix. Either way, I could confirm that it worked for my script again. |
Closing this as it seems like this case was a Canvas issue. I feel like a more generic fix would be to have it easier to pass |
Describe the bug
File.get_contents() now gets a 401 Unauthorized error.
To Reproduce
Expected behavior
Should print the file contents.
Environment information
Additional context
The existing code worked without issue last week. First noticed the problem today (April 10, 2025).
My guess is that Canvas API changed how it processes the file download urls in such a way that
canvasapi
is now doing it wrong.The token is valid: all the other commands described work fine.
Workaound
Instead of using
.get_contents()
I now use:Which works just file.
The file
url
field has an access token as a query parameter, so you don't need an Auth header to access the file using the credentialed URL (hence a plainrequests.get
works fine).My hypothesis is that the
canvasapi
requester is always including the auth headers (reasonable), but perhaps there is now an issue when trying to access the credentialed file URL while also passing the auth header?The text was updated successfully, but these errors were encountered: