I am trying to use the requests library in Python to upload a file into Fedora commons repository on localhost. I'm fairly certain my main problem is not understanding open()
/ read()
and what I need to do to send data with an http request.
def postBinary(fileName,dirPath,url):
path = dirPath+'/'+fileName
print('to ' + url + '\n' + path)
openBin = {'file':(fileName,open(path,'rb').read())}
headers = {'Slug': fileName} #not important
r = requests.put(url, files=openBin,headers=headers, auth=HTTPBasicAuth('username', 'pass'))
print(r.text)
print("and the url used:")
print(r.url)
This will successfully upload a file in the repository, but it will be slightly larger and corrupted after. For example an image that was 6.6kb became 6.75kb and was not openable anymore.
So how should I properly open and upload a file using put in python?###Extra details:###
When I replace
files=openBin
withdata=openBin
I end up with my dictionary and I presume the data as a string. I don't know if that information is helpful or not.
"file=FILE_NAME.extension&file=TYPE89a%24%02Q%03%E7%FF%00E%5B%19%FC%.... and the size of the file increases to a number of megabytesI am using specifically put because the Fedora RESTful HTTP API end point says to use
put
.
The following command does work:
curl -u username:password -H "Content-Type: text/plain" -X PUT -T /path/to/someFile.jpeg http://localhost:8080/fcrepo/rest/someFile.jpeg
Updated
Using
requests.put()
with thefiles
parameter sends a multipart/form-data encoded request which the server does not seem to be able to handle without corrupting the data, even when the correct content type is declared.The
curl
command simply performs a PUT with the raw data contained in the body of the request. You can create a similar request by passing the file data in thedata
parameter. Specify the content type in the header:You can vary the
Content-type
header to suit the payload as required.Try setting the
Content-type
for the file.If you are sure that it is a text file then try
text/plain
which you used in yourcurl
command - even though you would appear to be uploading a jpeg file? However, for a jpeg image, you should useimage/jpeg
.Otherwise for arbitrary binary data you can use
application/octet-stream
:Also it is not necessary to explicitly read the file contents in your code,
requests
will do that for you, so just pass the open file handle as shown above.