This section shows Python code examples that you can use for obtaining a token, uploading a file, and verifying the file was uploaded successfully. Note that rhe verification step is important because it verifies that the file you attempted to upload indeed was uploaded. For example if you attempted to upload a 10MB file and a network error occurred you need to determine if the upload was successful.
You can copy and paste the code into the Python IDE of your choice, or you can use the same concepts to upload files by creating programs in other languages such as Java, JavaScript, and C#.
Obtain a Token
JSON
1>>> import jsonrpclib2>>> api = jsonrpclib.Server('https://{Account name}.upload.llnw.net/jsonrpc2')3>> token, uid_gid = api.login('yourUser', 'yourPassword')4>>> print (token)5f3037573-2a6f-4042-ab8f-82d6823b0480
For complete details about
login
, see Logging in Using the JSON-RPC Interface.HTTP Example
JSON
1>>> import requests2>>> auth_headers = { 'X-Agile-Username': 'yourUser', 'X-Agile-Password': 'yourPassword' }3>>> url = 'https://{Account name}.upload.llnw.net/account/login'4>>> r = requests.post(url, headers=auth_headers)5>>> token = r.headers['x-agile-token']6>>> print (token)77c164371-d581-4068-8ce1-4d17b6a9d8a3
For complete details about
account/login
, see Logging in Using the HTTP Interface./post/file
Example
This section presents a simple example using only the X-Agile-Authorization header along with the uploadFile, basename, and directory form fields. Note that uploadFile is a multipart/form-data encoded payload so it is handled differently than other form fields.
For complete details about
/post/file
, see Web Browser Upload.Upload a File
1>>> import requests2>>> basename = 'file1.txt'3>>> file_to_upload ='/' + basename4>>> upload_headers = { 'X-Agile-Authorization': token}5>>> payload = {'basename': basename, 'directory': '/zz' }6>>> files = { 'uploadFile': open(file_to_upload, 'r') }7>>> r = requests.post('http://{Account name}.upload.llnw.net/post/file', data=payload, headers=upload_headers, files=files, verify=False)
Verify That the Upload Was Successful
You can use HTTP or JSON-RPC.
HTTP Example
Look at the headers returned from the request. The
/post/raw
request returns the upload status in the X-Agile-Status header. A value of 0 (zero) means success.1>>> print (r.headers2{'x-agile-status': '0', 'content-length': '0', 'access-control-allow-headers': 'X-Agile-Authorization, X-Content-Type', 'x-agile-checksum': 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 'keep-alive': 'timeout=5, max=100', 'server': 'Apache', 'x-agile-size': '0', 'connection': 'Keep-Alive', 'date': 'Mon, 17 Aug 2015 20:23:17 GMT', 'x-agile-path': '/{Account name}/zz/file1.txt', 'access-control-allow-origin': '*', 'access-control-allow-methods': 'OPTIONS', 'content-type': 'text/json;charset=utf-8'}
For other status codes, see HTTP Response Codes and Request Status Codes.
You can also issue a HEAD request against the object and look at the overall response code (200=OK) as well as the
X-Agile-Checksum
and Content-Length
response headers:1>>> r = requests.head('http://global.mt.lldns.net/<Account Name>/zz/file1.txt')2>>> print (r)3<Response [200]>4>>> print (r.headers)5{'x-agile-checksum': 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 'accept-ranges': 'bytes', 'server': 'nginx/1.6.2', 'last-modified': 'Mon, 17 Aug 2015 20:23:17 GMT', 'connection': 'keep-alive', 'date': 'Mon, 17 Aug 2015 20:33:02 GMT', 'content-type': 'text/plain'}
JSON-RPC Example
Use the stat function to get information on the uploaded file. The
stat
function has an optional ‘detail’ parameter. Pass True
for extended information, or pass False
(or omit) for an abbreviated response. A value of 0 in the returned code field indicate success. Other values indicate failure. You can also look at other fields such as size and checksum and compare them to known values.1>>> api.stat(token, 'zz/file1.txt', True)2{u'mimetype': u'text/plain', u'code': 0, u'uid': 12020, u'checksum': u'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', u'gid': 100, u'mtime': 1439842997, u'size': 0, u'type': 2, u'ctime': 1439842997}
For more information about the stat call, see Obtain File or Directory Metadata.
Complete HTTP Example
This section ties information together, providing a complete Python work sample that you can quickly and easily copy and paste into a Python file.
Always use https for logging in to prevent sniffer attacks that can detect your credentials and token.
1import jsonrpclib2import requests3api = jsonrpclib.Server('https://{Account Name}.upload.llnw.net/jsonrpc')4token, user = api.login('yourUser', 'yourPassword')56basename = 'file1.txt'7file_to_upload ='/' + basename8upload_headers = { 'X-Agile-Authorization': token}9payload = {'basename': basename, 'directory': '/zz' }10files = { 'uploadFile': open(file_to_upload, 'r') }11r = requests.post('http://{Account name}.upload.llnw.net/post/file', data=payload, headers=upload_headers, files=files, verify=False)12print (r)13print (r.headers)14r2 = requests.head('http://global.mt.lldns.net/{Account Name}/zz/file1.txt')15print (r2)16print (r2.headers)17api.stat(token, '/zz/file1.txt', True)
/post/raw
Example
This section presents a simple example using only the
X-Agile-Authorization
, X-Agile-Basename
, and X-Agile-Directory
headers.For complete details about /post/raw, see File Raw Post.
Upload a File
1>>> import requests2>>> file_to_upload = '\test.mp3'3>>> upload_headers = { 'X-Agile-Authorization': token, 'X-Agile-Basename': file_to_upload, 'X-Agile-Directory': '/' }4>>> with open(file_to_upload, 'rb') as filesrc:5 r = requests.post('http://{Account name}.upload.llnw.net/post/raw', data=filesrc, headers=upload_headers)
Verify That the Upload Was Successful
You can use HTTP or JSON-RPC.
HTTP Example
Look at the headers returned from the request. The
/post/raw
request returns the upload status in the X-Agile-Status
header. A value of 0 means success.1>>> print (r.headers2{'x-agile-status': '0', 'content-length': '0', 'access-control-allow-headers': 'X-Agile-Authorization, X-Content-Type', 'x-agile-checksum': 'f5d56bded9d953c31d4e257ecf606e152435af1c8139d32a5b367e9070ac783f', 'keep-alive': 'timeout=5, max=100', 'server': 'Apache', 'x-agile-size': '594472', 'connection': 'Keep-Alive', 'date': 'Mon, 17 Aug 2015 17:10:23 GMT', 'x-agile-path': '/{Account Name}/test.mp3', 'access-control-allow-origin': '*', 'access-control-allow-methods': 'OPTIONS', 'content-type': 'text/json;charset=utf-8'}
You can also issue a HEAD request against the object and look at the headers returned and the overall response code (200=OK).
Here is an example using the Python
requests
library:1>>> r2 = requests.head('http://{Account name}.upload.llnw.net/{Account Name}/' + basename)2>>> print (r2)3<Response [200]>4>>> print (r2.headers)5{'content-length': '594472', 'x-agile-checksum': 'f5d56bded9d953c31d4e257ecf606e152435af1c8139d32a5b367e9070ac783f', 'accept-ranges': 'bytes', 'server': 'nginx/1.6.2', 'last-modified': 'Mon, 17 Aug 2015 17:10:25 GMT', 'connection': 'keep-alive', 'date': 'Mon, 17 Aug 2015 17:15:07 GMT', 'content-type': 'audio/mpeg'}
JSON-RPC Example
Use the stat function to get information on the uploaded file. The
stat
function has an optional ‘detail’ parameter. Pass True
for extended information, or pass False
(or omit) for an abbreviated response. A value of 0 in the returned code field indicate success. Other values indicate failure. You can also look at other fields such as size and checksum and compare them to known values.1>>> api.stat(token, '/test.mp3', True)2{u'mimetype': u'audio/mpeg', u'code': 0, u'uid': 12020, u'checksum': u'f5d56bded9d953c31d4e257ecf606e152435af1c8139d32a5b367e9070ac783f', u'gid': 100, u'mtime': 1439831425, u'size': 594472, u'type': 2, u'ctime': 1439831425}
For more information about the
stat
call, see Obtain File or Directory Metadata.Complete HTTP Example
This section ties information together, providing a complete Python working sample that you can quickly and easily copy and paste into a Python file.
Always use https for logging in to prevent sniffer attacks that can detect your credentials and token.
1import jsonrpclib2import requests3api = jsonrpclib.Server('https://{Account Name}.upload.llnw.net/jsonrpc')4token, user = api.login('yourUser', 'yourPassword')56basename = 'test.mp3'7file_to_upload ='/' + basename8upload_headers = { 'X-Agile-Authorization': token, 'X-Agile-Basename': file_to_upload, 'X-Agile-Directory': '/' }9with open(file_to_upload, 'rb') as filesrc:10 r = requests.post('http://{Account name}.upload.llnw.net/post/raw', data=filesrc, headers=upload_headers)11print (r.headers12r2 = requests.head('http://global.mt.lldns.net/{Account Name}/' + basename)13print (r2)14print (r2.headers)15api.stat(token, "/" + basename, True)
Multipart Example
This section presents a simple scenario for initiating a multipart upload, adding a piece to the upload, and completing the upload. For complete information about multipart uploads, see Uploading Files — Multipart.
Calculate the SHA-256 Checksum For the File
You can use the value later to ensure the file was uploaded successfully.
Initiate the Upload
1>>> import requests2>>> serverDirectory = '/multipart'3>>> uploadBasename = 'text-file1.txt'4>>> headers = { 'X-Agile-Authorization': token, 'X-Agile-Basename': uploadBasename, 'X-Agile-Directory': serverDirectory}5>>> r = requests.post('http://[Account name]-l.upload.llnw.net/multipart/create', headers=headers, verify=False)
Verify That the Initiation Was Successful
Look at the headers returned from the request. The
/multipart/create
request returns the upload status in the X-Agile-Status
header. A value of 0 means success.1>>> print (r.headers)2{'x-agile-status': '0', 'content-length': '0', 'x-agile-meta': 'content_type=None mtime=0', 'keep-alive': 'timeout=5, max=100', 'server': 'Apache', 'connection': 'Keep-Alive', 'x-agile-multipart': 'e20207caa6234b53a93f671320ad7be6', 'date': 'Wed, 19 Aug 2015 21:23:41 GMT', 'x-agile-path': '/{Account Name}/multipart/text-file1.txt', 'access-control-allow-origin': '*', 'access-control-allow-methods': 'OPTIONS', 'content-type': 'text/json;charset=utf-8', 'access-control-allow-headers': 'X-Agile-Authorization, X-Content-Type'}
A multipart upload is not available until you have added pieces to it and completed it, so a HEAD request or a JSON-RPC stat request on the object at this point will fail.
Add a Piece To the Multipart Upload
This is a simple example that adds a complete file to the multipart upload. In real life you would stream the object, break the stream into chunks and upload each chunk as a piece.
1>>> mpid = r.headers['X-Agile-Multipart']2>>> pieceBasename = 'file1.txt'3>>> file_to_upload ='/' + pieceBasename4>>> headers = { 'X-Agile-Authorization': token, 'X-Agile-Multipart': mpid, 'X-Agile-Part': '1'}5>>> with open(file_to_upload, 'rb') as filesrc:6>>> r2 = requests.post('http://[Account name]-l.upload.llnw.net/multipart/piece', data=filesrc, headers=headers, verify=False)
Verify That the Piece Was Uploaded Successfully
Look at the headers returned from the request. The upload status is in the
X-Agile-Status
header. A value of 0 means success.Compare the checksum (
X-Agile-Checksum
header) with the value you calculated earlier.1>>> print (r2.headers)2{'x-agile-status': '0', 'content-length': '0', 'access-control-allow-headers': 'X-Agile-Authorization, X-Content-Type', 'x-agile-checksum': 'c28a4e896970557bea969cc591299183b341d90dad44ace3684994be80e8d07c', 'keep-alive': 'timeout=5, max=100', 'server': 'Apache', 'x-agile-size': '70', 'connection': 'Keep-Alive', 'date': 'Wed, 19 Aug 2015 21:23:46 GMT', 'access-control-allow-origin': '*', 'access-control-allow-methods': 'OPTIONS', 'content-type': 'text/json;charset=utf-8'}
Complete the Upload
1>>> headers = { 'X-Agile-Authorization': token, 'X-Agile-Multipart': mpid}2>>> r3 = requests.post('http://[Account name]-l.upload.llnw.net/multipart/complete', headers=headers, verify=False)
Verify That the Upload Was Successful
You can use HTTP or JSON-RPC.
HTTP Example
Look at the
X-Agile-Status
header. A value of 0 means success.1>>> print (r3.headers)2{'x-agile-status': '0', 'content-length': '0', 'x-agile-parts': '1', 'keep-alive': 'timeout=5, max=100', 'server': 'Apache', 'connection': 'Keep-Alive', 'X-Agile-Multipart': 'e20207caa6234b53a93f671320ad7be6', 'date': 'Wed, 19 Aug 2015 21:23:50 GMT', 'access-control-allow-origin': '*', 'access-control-allow-methods': 'OPTIONS', 'content-type': 'text/json;charset=utf-8', 'access-control-allow-headers': 'X-Agile-Authorization, X-Content-Type'}
You can also issue a
HEAD
request against the object and look at the headers returned and the overall response code (200=OK).1>>> r4 = requests.head('http://{Account name}.upload.llnw.net' + serverDirectory + '/' + uploadBasename)2>>> print (r4)3<Response [200]>4>>> print (r4 headers)5{'content-length': '70', 'x-agile-checksum': 'c28a4e896970557bea969cc591299183b341d90dad44ace3684994be80e8d07c', 'accept-ranges': 'bytes', 'server': 'nginx/1.6.2', 'last-modified': 'Wed, 19 Aug 2015 21:22:44 GMT', 'connection': 'keep-alive', 'date': 'Wed, 19 Aug 2015 21:23:53 GMT', 'content-type': 'text/plain'}
There is often a delay between the time you complete the multipart upload and the time it is ready for a HEAD request. Issuing a HEAD request too soon results in a 404 (not found) error.
JSON-RPC Example
Use the stat function to get information on the uploaded file. The stat function has an optional ‘detail’ parameter. Pass True for extended information, or pass False (or omit) for an abbreviated response. A value of 0 in the returned code field indicate success. Other values indicate failure. You can also look at other fields such as size and checksum and compare them to known values.
1>>> api.stat(token, serverDirectory + '/' + uploadBasename, True)2{u'mimetype': u'text/plain', u'code': 0, u'uid': 12020, u'checksum': u'c28a4e896970557bea969cc591299183b341d90dad44ace3684994be80e8d07c', u'gid': 100, u'mtime': 1440025478, u'size': 70, u'type': 2, u'ctime': 1440025489}
For more information about the stat call, see Obtain File or Directory Metadata.
Complete HTTP Example
This section ties information together, providing a complete Python working sample that you can quickly and easily copy and paste into a Python file.
Always use https for logging in to prevent sniffer attacks that can detect your credentials and token.
1import jsonrpclibimport requests2import os34######################################56# Log in7######################################8api = jsonrpclib.Server('https://{Account Name}.upload.llnw.net/jsonrpc')9token, user = api.login('yourUser', 'yourPassword')1011######################################12# Set Upload Variables13######################################14serverDirectory = '/multipart'15localDirectory = '/Temp/'16fileName = 'flat-irons3.jpg'17chunkSize = 2000001819print ('==================')20print ('Upload Information')21print ('==================')22print ('Upload file: ' + fileName)23print (' Server Dir: ' + serverDirectory)24print (' Piece Size: ' + str(chunkSize))25print ('')2627######################################28# Create multipart29######################################30print ('================')31print ('Multipart Create')32print ('================')3334headers = { 'X-Agile-Authorization': token, 'X-Agile-Basename': fileName, 'X-Agile-Directory': serverDirectory}35r = requests.post('http://{Account Name}.upload.llnw.net/multipart/create', headers=headers, verify=False)3637print ('Request Result')38print ('--------------')39print (str (r.status_code ) + ' (' + r.reason + ')')4041print ('')42print ('Multipart ID')43print ('------------')44mpid = r.headers['X-Agile-Multipart']45print (mpid)4647######################################48# Multipart Piece49######################################50print ('')5152print ('===============')53print ('Multipart Piece')54print ('===============')55file_to_upload = localDirectory + fileName56pieceNum = 157f = open(file_to_upload, 'rb')58while True:59 chunkBuff = f.read( chunkSize )60 if not chunkBuff:61 break62 else:63 headers = { 'X-Agile-Authorization': token, 'X-Agile-Multipart': mpid, 'X-Agile-Part': str( pieceNum )}64 print (' Sending piece: ' + str( pieceNum ) )65 r2 = requests.post('http://{Account Name}.upload.llnw.net/multipart/piece', data=chunkBuff, headers=headers, verify=False)66 print (' Result: ' + str (r2.status_code ) + ' (' + r2.reason + ')')67 status = r2.headers['X-Agile-Status']68 print ('X-Agile-Status: ' + str( status ))69 print ('------------------------')70 if status != "0":71 break72 else:73 pieceNum = pieceNum +174f.close()7576######################################77# Multipart Complete78######################################79print ('')80print ('==================')81print ('Multipart Complete')82print ('==================')83headers = { 'X-Agile-Authorization': token, 'X-Agile-Multipart': mpid}84r3 = requests.post('http://{Account Name}.upload.llnw.net/multipart/complete', headers=headers, verify=False)85print ('Request Result')86print ('--------------')87print (str (r3.status_code ) + ' (' + r3.reason + ')')88print ('X-Agile-Status: ' + r3.headers['x-agile-status'])8990######################################91# Sleep92######################################93from time import sleep94secs = 595print ('')96print ('**sleeping for ' + str(secs) + ' seconds...')97sleep( secs )9899######################################100# HEAD Request101######################################102print ('==================')103print ('HEAD Request')104print ('==================')105print ('HEAD request on ' + serverDirectory + '/' + fileName)106r4 = requests.head('http://{Account name}.upload.llnw.net' + serverDirectory + '/' + fileName)107print ('Request Result')108print ('--------------')109print (str (r4.status_code ) + ' (' + r4.reason + ')')110print ('')111print ('Checksum')112print ('--------')113print (r4.headers['x-agile-checksum'])114print ('')115print ('Content Length')116print ('--------------')117print (r4.headers['content-length'])118119######################################120# JSON-RPC stat Request121######################################122print ('')123print ('=====================')124print ('JSON-RPC stat Request')125print ('=====================')126print ('Requesting stat on ' + serverDirectory + '/' + fileName)127results = api.stat(token, serverDirectory + '/' + fileName, True))128print ('')129print ('Request Result')130print ('--------------')131print (str (results['code'] ))132statChecksum = results['checksum']133print ('')134print ('Checksum')135print ('--------')136print (statChecksum)137print ('')138print ('File Size')139print ('---------')140print (results['size'])141142########################################143# Get the SHA-256 hash of the local file144########################################145import hashlib146fh = None147try:148 fh = open(file_to_upload, 'rb')149except IOError, e:150 log.warn("checksum_file IOError: %s: %s" % (file_to_upload, e))151 fh = None152if fh != None:153 m = hashlib.sha256()154 while True:155 buf = fh.read(4096)156 if not buf:157 break158 m.update(buf)159 fh.close()160 localFileCkSum = m.hexdigest()161 print ('')162 print ('==========')163 print ('Local file')164 print ('==========')165 print ('Checksum')166 print ('--------')167 print (localFileCkSum)168169fileSize = os.path.getsize(file_to_upload)170print ('')171print ('File Size')172print ('---------')173print (fileSize)174print ('')175if statChecksum == localFileCkSum:176 print ('Local file checksum matches checksum from stat call.')177else:178 print ('Local file checksum does not match checksum returned from stat call.')179180########181#Log out182########183api.logout(token)