Description
Zulip's API has a pair of related URLs for accessing uploaded files that need better documentation and tooling:
GET /user_uploads/...
GET /api/v1/user_uploads/...
The former just downloads a file (possibly via a 302 redirect to a temporary access URL of the form /user_uploads/temporary/...
). The latter returns such a temporary access URL (basically what the former would have redirected to), which is useful for cases where a client's HTTP library doesn't support following redirects. Neither is currently covered in our API documentation.
The consequence of this is background is that client.call_endpoint()
in the Python bindings using logic like this:
path: str = re.fullmatch(
'\s*cat\s*\[[^\[\]]*\]\(([^\(\)]*)\)\s*', message['content']
).group(1)
content = str(client.call_endpoint(url = path, method = 'GET'))
which is the most convenient way to provide authentication, may end up visiting /api/v1/user_uploads
and returning a temporary access URL, rather than downloading the file. What we need is an alternative to client.call_endpoint
that doesn't prepend /api/v1/
. One option would be to refactor the call_endpoint
system to require passing /api/v1
explicitly, which might be a better system in any case; then something like the code above would work. (I'd want to provide an explicit client.fetch_upload(path | url)
method in any case, but it could just call client.call_endpoint
, and we'd have a clear mechanism for how to use API authentication to request other similar endpoints that don't have an /api/v1 prefix in the future -- which will largely be endpoints that serve images or other assets that need to be shared between web and mobile)
https://chat.zulip.org/#narrow/stream/49-development-help/topic/Bot.20download.20file/near/1027190 has more background