5

I'm trying to list the folders for a team member on our Dropbox Business account.

https://api.dropboxapi.com/2/files/list_folder requires that we add the Dropbox-API-Select-User header, but it does not seem to be working.

This is my code so far:

import requests

url = "https://api.dropboxapi.com/2/files/list_folder"

headers = {
    "Authorization": "Bearer MY_TOKEN",
    "Dropbox-API-Select-User": "dbid:ACCOUNT_ID"
    }

data = {
    "path": "/",
}

r = requests.post(url, headers=headers, json=data)
r.raise_for_status()
print(r.json())

Note that the json= argument in the post() function sets the content type to application/json so that should be correct.

The code above raises an exception:

requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://api.dropboxapi.com/2/files/list_folder

I have tried using the team member ID (bdmid:) instead of the account ID but got the same error.

Do you have any idea what's wrong?

Thanks in advance for any help.

I'm using Python 3.6 if that makes any difference.

blokeley
  • 6,726
  • 9
  • 53
  • 75
  • Are you sure it's supposed to be `POST`? To me it would seem more appropriate for a *list*-type call to use `GET` instead? But I've never used the Dropbox API, so I have no idea what the base requirements are. – idjaw Mar 19 '17 at 20:48
  • Provide the right path and then Try again ... also add one more header Content-Type: application/json" – BugHunter Mar 19 '17 at 21:07
  • Isn't there a Python client that will do all this for you? – idjaw Mar 19 '17 at 21:16
  • @Jitendra: isn't "/" a valid path? It should be the root directory. Also, please see my note in the question that the content type is already set to "application/json" by using the `json` argument – blokeley Mar 19 '17 at 21:19
  • @blokeley: set path to {"path":""} and it would work :) – BugHunter Mar 19 '17 at 21:21
  • @idjaw: Dropbox uses POST for most requests. See https://blogs.dropbox.com/developers/2015/03/limitations-of-the-get-method-in-http/ – blokeley Mar 19 '17 at 21:22
  • @idjaw: I could use the SDK for this trivial example but my app does some things that mean raw requests will be better – blokeley Mar 19 '17 at 21:23
  • @blokeley Thanks for the link! At least there's an explanation :). Sorry don't have much to offer in terms of help for this. – idjaw Mar 19 '17 at 21:24
  • @Jitendra: I'll try that when I'm coding again tomorrow. Thanks – blokeley Mar 19 '17 at 21:27
  • Also, are we supposed to use the user account id (dbid:) or the Dropbox Business team member id (dbmid:)? – blokeley Mar 19 '17 at 21:28
  • @Jitendra: {"path": ""} gets the same HTTP 400 error – blokeley Mar 20 '17 at 09:20
  • @blokeley : remove "Dropbox-API-Select-User" header. Can you please show the full error message? – BugHunter Mar 20 '17 at 09:56

1 Answers1

7

First, I should note that we do recommend using the official Dropbox API v2 Python SDK as it takes care of a lot of the underlying networking/formatting work for you. That said, you can certainly use the underlying HTTPS endpoints directly like this if you prefer.

Anyway, when dealing with issues like this, be sure to print out the body of the response itself, as it will contain a more helpful error message. You can do so like this:

print(r.text)

In this case with this code, that yields an error message:

Error in call to API function "files/list_folder": Invalid select user id format

Another issue is that with API v2, the root path is supposed to be specified as empty string, "":

Error in call to API function "files/list_folder": request body: path: Specify the root folder as an empty string rather than as "/".

That's because when using the member file access feature like this, you are supposed to supply the member ID, not the account ID.

So, fixing those issues, the working code looks this:

import requests

url = "https://api.dropboxapi.com/2/files/list_folder"

headers = {
    "Authorization": "Bearer MY_TOKEN",
    "Dropbox-API-Select-User": "dbmid:MEMBER_ID"
    }

data = {
    "path": "",
}

r = requests.post(url, headers=headers, json=data)
print(r.text)
r.raise_for_status()
print(r.json())

Edited to add, if you want to use the Dropbox API v2 Python SDK for this, you would use DropboxTeam.as_user like this:

import dropbox

dbx_team = dropbox.DropboxTeam("MY_TOKEN")
dbx_user = dbx_team.as_user("dbmid:MEMBER_ID")

print(dbx_user.files_list_folder(""))
Greg
  • 16,359
  • 2
  • 34
  • 44
  • Excellent answer, thanks. The combination of 1) using the member id and 2) the non-standard empty string "" instead of the standard slash "/" for the root directory worked. I still couldn't see how to call the dropbox SDK functions as a team member though. The dropbox SDK appears to be written for individual users, not Dropbox Business – blokeley Mar 20 '17 at 20:44
  • I edited my answer with a sample for the SDK. Hope this helps! – Greg Mar 20 '17 at 21:02
  • Excellent. Now I can see the point of the SDK! I wish there was documentation with Dropbox Business SDK examples somewhere. The one-page dump of the docstrings seen on readthedocs isn't very enlightening – blokeley Mar 20 '17 at 21:17