Skip to content

Instantly share code, notes, and snippets.

@bnordgren
Created March 9, 2022 23:31
Show Gist options
  • Save bnordgren/5ffb9598b4d600ef9a46502d204f641b to your computer and use it in GitHub Desktop.
Save bnordgren/5ffb9598b4d600ef9a46502d204f641b to your computer and use it in GitHub Desktop.
Upload to Box using file request URL
import datetime
import requests
import urllib
import os.path
import sys
import json
#
# Given a "File Request URL" and a local file, this program uploads to a box folder.
#
class BoxUploader(object) :
def __init__(self, requestURL) :
self.request_url = requestURL
o = urllib.parse.urlparse(requestURL)
self.boxDomain = o.hostname
self.fileRequestId = os.path.basename(o.path)
self.initialUrl = 'https://' + self.boxDomain + '/app-api/file-request-web/public/file-request?urlId=' + self.fileRequestId
self.formResponseUrl = 'https://' + self.boxDomain + '/app-api/file-request-web/public/form-response'
self.optionsUrl = 'https://' + self.boxDomain + '/api/2.1/files/content'
def upload_file(self, fname) :
#
# Initial call to the "get" url
#
rfc3339_format='%Y-%m-%dT%H:%M:%S%z'
response = requests.get(self.initialUrl)
jsonResponse = response.json()
basename = os.path.basename(fname)
local_timezone= datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo
modifiedTime = datetime.datetime.fromtimestamp(os.path.getmtime(fname), tz=local_timezone)
#
# Submit a form response to get an upload token
#
boxFileRequestId = jsonResponse['id']
boxFolderId = jsonResponse['folder']['id']
formVersionId = jsonResponse['form']['versionId']
fileLength = os.path.getsize(fname)
print("Form Version ID: " + formVersionId)
requestContent = { "fileRequestURL" : self.fileRequestId,
"formVersionId" : formVersionId,
"values" : {"element-0" : { "type":"files", "data":[ {"local_path":fname, "size":fileLength}] },
"folder" : {"type" : "folder", "id": boxFolderId}}}
uploadFormResponse = requests.post(self.formResponseUrl, json=requestContent)
uploadFormResponseJson = uploadFormResponse.json()
#
# Make a call to the options url to get the actual url to
# upload the file to.
#
uploadToken = uploadFormResponseJson['uploadToken']
headers = { "Authorization" : "Bearer " + uploadToken }
requestContent = { "name" : fname,
"parent": { "id" : boxFolderId },
"size": fileLength}
optionsResponse = requests.options(self.optionsUrl, headers=headers, json=requestContent)
optionsResponseJson = optionsResponse.json()
# Upload the file.
upload_url = optionsResponseJson['upload_url']
form_attributes = { 'name' : fname,
'parent': {"id": boxFolderId},
'content_modified_at' : modifiedTime.strftime(rfc3339_format) }
files={ 'attributes' : (None, json.dumps(form_attributes), 'application/json', {'Content-Disposition':'form-data'}),
'file' : (fname, open(fname, 'rb')) }
#upload_request = requests.Request('POST', upload_url, headers=headers, files=files).prepare()
#print(upload_request.headers)
#print(upload_request.body)
uploadResponse = requests.post(upload_url, headers=headers, files=files)
print(json.dumps(uploadResponse.json(), indent=2))
def main(requestUrl, file) :
uploader = BoxUploader(requestUrl)
uploader.upload_file(file)
if __name__ == '__main__' :
url = sys.argv[1]
file = sys.argv[2]
main(url, file)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment