You might see that the Dropbox Community team have been busy working on some major updates to the Community itself! So, here is some info on what’s changed, what’s staying the same and what you can expect from the Dropbox Community overall.
Forum Discussion
ethanfang
3 years agoExplorer | Level 4
If the cursor is too long, list_folder_continue api always encounter 504 timeout
Hi,
We've designed an app and found that if we create more than 5000 team folders under team root (eg. 1st level folder). The cursor returned by list folder api (eg. https://api.dropboxapi.com/2/fi...
ethanfang
Explorer | Level 4
Hi,
We've attempted to set the limit to a low number (eg. 20), it still leads to timeout after 1m30s.
However, we really need to set recursive as true. Or there will be lots of api calls. (eg. 5000 folders, so at least 5000 calls)
Thank you very much~!
Best regards,
Ethan Fang
Здравко
3 years agoLegendary | Level 20
Hi ethanfang,
The problem in your case is that you have lots of namespaces. Every single namespace gets locked by self. Since you need to lock all namespaces together, looks like the task takes too long. You need to split list processing for different namespaces to avoid such a deadlock. On other side, as you mentioned too many calls take too long to establish connections (Dropbox SDKs doesn't support multi-call on single connection). As a workaround you can perform such a request serie on you own on a single connection and so speed up the processing. I just created a simple example in Python:
#!/usr/bin/python3
from http.client import HTTPSConnection, _CS_IDLE
from urllib.parse import urlparse, urlunparse
from json import JSONDecoder, JSONEncoder
token = '<your access token here>'
paths = ['', '/path1', 'id:..', ...] # id's or paths to all your namespaces
def requestListResponse(conn, path):
body = JSONEncoder().encode({"path": path,
"include_mounted_folders": False,
"recursive": True}).encode()
headers = {'Host': conn.host,
'Content-Length': len(body),
'Connection': 'Keep-Alive',
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'}
conn._HTTPConnection__state = _CS_IDLE
conn.request("POST", "/2/files/list_folder", body, headers)
return conn.response_class(conn.sock, method=conn._method)
def requestListContResponse(conn, cursor):
body = '{"cursor":"' f"{cursor}" '"}'
headers = {'Host': conn.host,
'Content-Length': len(body),
'Connection': 'Keep-Alive',
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'}
conn._HTTPConnection__state = _CS_IDLE
conn.request("POST", "/2/files/list_folder/continue", body, headers)
return conn.response_class(conn.sock, method=conn._method)
def handleResponse(resp):
resp.begin()
if 200 != resp.status:
raise RuntimeError(f"Status: {resp.status}\nHeader info:\n{resp.info()}\n"
f"\n{resp.read().decode()}")
return JSONDecoder().decode(resp.read().decode())
def listFolders(paths):
conn = HTTPSConnection("api.dropboxapi.com")
responses = []
for path in paths:
responses.append(requestListResponse(conn, path))
while len(responses) > 4:
resp = responses.pop(0)
result = handleResponse(resp)
for entry in result['entries']:
yield entry
if result['has_more']:
responses.append(requestListContResponse(conn, result['cursor']))
while len(responses):
resp = responses.pop(0)
result = handleResponse(resp)
for entry in result['entries']:
yield entry
if result['has_more']:
responses.append(requestListContResponse(conn, result['cursor']))
for e in listFolders(paths):
print(f"{e['.tag']}: {e['name']} with path -> {e['path_lower']}")
Hope the above demonstrates the idea clearly.
About Dropbox API Support & Feedback
Find help with the Dropbox API from other developers.
5,915 PostsLatest Activity: 5 hours agoIf you need more help you can view your support options (expected response time for an email or ticket is 24 hours), or contact us on X or Facebook.
For more info on available support options for your Dropbox plan, see this article.
If you found the answer to your question in this Community thread, please 'like' the post to say thanks and to let us know it was useful!