I've been trying to upload a file using the box v2 api with requests.
So far I had little luck though. Maybe someone here can help me see what I'm actually doing wrong.
file_name = "%s%s" % (slugify(sync_file.description), file_suffix)
file_handle = open(settings.MEDIA_ROOT + str(sync_file.document), 'rb')
folder_id = str(sync_file.patient.box_patient_folder_id)
r = requests.post(
files_url,
headers=headers,
files={
file_name: file_handle,
"folder_id": folder_id,
},
)
My authentication works, because I'm creating a folder just before that, using the same data.
A response looks something like this:
{
u'status': 404,
u'code': u'not_found',
u'help_url': u'http://developers.box.com/docs/#errors',
u'request_id': u'77019510950608f791a0c1',
u'message': u'Not Found',
u'type': u'error'
}
Maybe someone on here ran into a similar issue.
You need to pass 2 Python dictionaries, files and data. files are {uniqFileName:openFileObj}
, and data are {uniqFileName:filename}
. Below is the upload method from my box class. And remember to add a final entry in data, 'folder_id': destination_id
.
def uploadFiles(self, ufiles, folid):
'''uploads 1 or more files in the ufiles list of tuples containing
(src fullpath, dest name). folid is the id of the folder to
upload to.'''
furl = URL2 + 'files/data'
data, files = {}, {}
for i, v in enumerate(ufiles):
ff = v[0]
fn = v[1]
#copy to new, renamed file in tmp folder if necessary
#can't find a way to do this with the api
if os.path.basename(ff) != fn:
dest = os.path.join(TMP, fn)
shutil.copy2(ff, dest)
ff = dest
f = open(ff, 'rb')
k = 'filename' + str(i)
data[k] = fn
files[k] = f
data['folder_id'] = folid
res = self.session.post(furl, files=files, data=data)
for k in files:
files[k].close()
return res.status_code
Here is a sample call:
destFol = '406600304'
ret = box.uploadFile((('c:/1temp/hc.zip', 'hz.zip'),), destFol)
Like I said, the above function is a method of a class, with an instance attr that holds a requests session. But you can use requests.post
instead of self.session.post
, and it will work just the same. Just remember to add the headers with your apikey and token if you do it outside a session.
According to the documentation, you are supposed to be able to rename the file by giving it a new name in the data dict. But I can't make this work except by copying the src file to a temp dir with the desired name and uploading that. It's a bit of a hack, but it works.
good luck, Mike