Как открыть файл и использовать request.put для правильной загрузки файла в Python?
Я пытаюсь использовать библиотеку запросов в Python для загрузки файла в хранилище общих ресурсов Fedora на локальном хосте. Я вполне уверен, что моя главная проблема не в понимании open()
/ read()
и что мне нужно сделать, чтобы отправить данные с HTTP-запросом.
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)
Это успешно загрузит файл в хранилище, но он будет немного больше и поврежден после. Например, изображение размером 6,6 КБ стало 6,75 КБ и больше не могло быть открыто.
Так как же мне правильно открыть и загрузить файл, используя put в python?Дополнительные детали:
- когда я заменю
files=openBin
сdata=openBin
Я заканчиваю со своим словарем, и я предполагаю данные как строку. Я не знаю, полезна ли эта информация или нет. "file=FILE_NAME.extension&file=TYPE89a%24%02Q%03%E7%FF%00E%5B%19%FC%.... и размер файла увеличивается до количества мегабайт - Я специально использую put, потому что конечная точка RESTful HTTP API fedora говорит, что нужно использовать put. Следующая команда работает.
curl -u username:password -H "Content-Type: text/plain" -X PUT -T /path/to/someFile.jpeg http://localhost:8080/fcrepo/rest/someFile.jpeg
1 ответ
обновленный
С помощью requests.put()
с files
Параметр отправляет запрос в формате multipart/form-data, который, по-видимому, сервер не может обработать без повреждения данных, даже если объявлен правильный тип содержимого.
curl
Команда просто выполняет PUT с необработанными данными, содержащимися в теле запроса. Вы можете создать аналогичный запрос, передав данные файла в data
параметр. Укажите тип содержимого в заголовке:
headers = headers = {'Content-type': 'image/jpeg', 'Slug': fileName}
r = requests.put(url, data=open(path, 'rb'), headers=headers, auth=('username', 'pass'))
Вы можете варьировать Content-type
заголовок, чтобы соответствовать полезной нагрузке при необходимости.
Попробуйте установить Content-type
для файла.
Если вы уверены, что это текстовый файл, попробуйте text/plain
который вы использовали в своем curl
команда - даже если вы, казалось бы, загружать файл JPEG? Однако для изображения в формате JPEG используйте image/jpeg
,
В противном случае для произвольных двоичных данных вы можете использовать application/octet-stream
:
openBin = {'file': (fileName, open(path,'rb'), 'image/jpeg' )}
Также нет необходимости явно читать содержимое файла в вашем коде, requests
сделает это за вас, так что просто передайте дескриптор открытого файла, как показано выше.