Сообщение python-requests с именами файлов в unicode

Я прочитал несколько связанных вопросов здесь, на SO, но не нашел рабочего решения.

У меня есть сервер Flask с этим упрощенным кодом:

app = Flask(__name__)
api = Api(app)


class SendMailAPI(Resource):
    def post(self):
        print request.files
        return Response(status=200)

api.add_resource(SendMailAPI, '/')

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

Затем в клиенте:

# coding:utf-8

import requests

eng_file_name = 'a.txt'
heb_file_name = u'א.txt'

requests.post('http://localhost:5000/', files={'file0': open(eng_file_name, 'rb')})
requests.post('http://localhost:5000/', files={'file0': open(heb_file_name, 'rb')})

При отправке первого запроса с именем файла не-utf-8 сервер получает запрос с файлом и печатает ImmutableMultiDict([('file0', <FileStorage: u'a.txt' (None)>)]), но при отправке файла с именем файла utf-8 сервер, похоже, не получает файл при печати ImmutableMultiDict([]).

Я использую запросы 2.3.0, но проблема не решена и с последней версией (2.8.1), версия флекса 0.10.1 и версия Flask-RESTful 0.3.4.

Я проделал некоторое копание в requests, и запрос, кажется, был отправлен нормально (т.е. с файлом), и я распечатал запрос прямо перед его отправкой и увидел, что имя файла действительно закодировано в RFC2231

--6ea257530b254861b71626f10a801726
Content-Disposition: form-data; name="file0"; filename*=utf-8''%D7%90.txt

Чтобы подвести итог, я не совсем уверен, что проблема лежит в requests, которая не прикрепляет файл к запросу должным образом, или если Flask имеет проблемы с сбором файлов с именами файлов, которые закодированный в соответствии с RFC2231.

UPDATE: В этой теме возникла проблема в requests GitHub: https://github.com/kennethreitz/requests/issues/2505

Ответ 1

Я думаю, может быть, здесь здесь запутанная кодировка -

eng_file_name = 'a.txt'  # ASCII encoded, by default in Python 2
heb_file_name = u'א.txt'  # NOT UTF-8 Encoded - just a unicode object

Чтобы отправить второй сервер на сервер, что вы хотите сделать, выполните следующие действия:

requests.post('http://localhost:5000/', files={'file0': open(heb_file_name.encode('utf-8'), 'rb')})

Я немного удивлен, что он не вызывает ошибку на клиенте, пытающейся открыть файл, хотя - вы ничего не видите на конце клиента, указывающего на ошибку?

EDIT: простой способ подтвердить или опровергнуть мою идею - это, конечно, распечатать содержимое внутри клиента, чтобы обеспечить его правильное чтение.

Ответ 2

Я обойду эту проблему, вручную прочитав файл с помощью read(), а затем разместив его содержимое:

requests.post(upload_url, files={
    'file': ("photo.jpg", open(path_with_unicode_filename, 'rb').read())
})