Разбор и сохранение данных многокомпонентной формы из файла с помощью werkzeug

У меня есть файл ниже, который был сохранен из HTTP POST, который я хочу проанализировать с помощью Python с помощью werkzeug parse_form_data(). Обратите внимание, что я получаю не через запрос, а через файл. Я не могу получить файл напрямую из запроса колбы по другим причинам. Так как я использовал Flask, я попытался использовать для этого werkzeug. Я думал, что у меня есть проблемы с границей с посторонними дефисами '-', но я сокращаю все до очень простого формата в следующем тестовом файле:

Вот файл в файловой системе (myinputfile):

--806243354728155036129379
Content-Disposition: form-data; name="myfile"; filename="text.py"
Content-Type: application/octet-stream

some text in a file

--806243354728155036129379
Content-Disposition: form-data; name="field1"

abcde
--806243354728155036129379
Content-Disposition: form-data; name="field2"
123456678
--806243354728155036129379--

Вот код, который я использую:

from werkzeug import parse_form_data
import io

inputfile = 'myinputfile'
content_type = 'Content-Type: multipart/form-data; boundary=806243354728155036129379'


environ = {
    'wsgi.input': io.open(inputfile, 'rb'),
    'CONTENT_LENGTH': '',
    'CONTENT_TYPE': content_type,
    'REQUEST_METHOD': 'POST'}

stream, form, files = parse_form_data(environ, silent=False)

Я продолжаю получать эту ошибку:

File "/usr/local/lib/python2.7/dist-packages/werkzeug/formparser.py", line 92, in parse_form_data
cls, silent).parse_from_environ(environ)
File "/usr/local/lib/python2.7/dist-packages/werkzeug/formparser.py", line 171, in parse_from_environ
content_length, options)
File "/usr/local/lib/python2.7/dist-packages/werkzeug/formparser.py", line 195, in parse
content_length, options)
File "/usr/local/lib/python2.7/dist-packages/werkzeug/formparser.py", line 100, in wrapper
return f(self, stream, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/werkzeug/formparser.py", line 212, in _parse_multipart
form, files = parser.parse(stream, boundary, content_length)
File "/usr/local/lib/python2.7/dist-packages/werkzeug/formparser.py", line 519, in parse
return self.cls(form), self.cls(files)
File "/usr/local/lib/python2.7/dist-packages/werkzeug/datastructures.py", line 406, in __init__
for key, value in mapping or ():
File "/usr/local/lib/python2.7/dist-packages/werkzeug/formparser.py", line 517, in <genexpr>
form = (p[1] for p in formstream if p[0] == 'form')
File "/usr/local/lib/python2.7/dist-packages/werkzeug/formparser.py", line 476, in parse_parts
for ellt, ell in self.parse_lines(file, boundary, content_length):
File "/usr/local/lib/python2.7/dist-packages/werkzeug/formparser.py", line 395, in parse_lines
self.fail('Expected boundary at start of multipart data')
File "/usr/local/lib/python2.7/dist-packages/werkzeug/formparser.py", line 327, in fail
raise ValueError(message)
ValueError: Expected boundary at start of multipart data

В конечном счете, я хочу иметь возможность сохранить файл (который может быть двоичным) и получить данные формы 'Field1' и 'Field2' из dict. Есть идеи? Я открыт для использования других методов тоже.

1 ответ

Хорошо, я понял это. Изначально я думал, что длину контента можно оставить пустой. Это работает, указав длину следующим образом:

Вот последний код, который я использовал:

def fileuploaded():
    import io

    # print 'request headers {}'.format(request.headers)
    rawfilename = request.headers.get('X_File')
    content_type = request.headers.get('Content-Type')
    print 'rawfilename = {}'.format(rawfilename)
    print 'content_type= {}'.format(content_type)

    # build the environ with the file stream
    environ = {
        'wsgi.input': io.open(rawfilename, 'rb'),
        'CONTENT_LENGTH': os.path.getsize(rawfilename),
        'CONTENT_TYPE': content_type,
        'REQUEST_METHOD': 'POST'}

    stream, form, files = parse_form_data(environ, silent=False)
    f = files.get('infile')
    f.save('/newfilepath/{}'.format(f.filename))
Другие вопросы по тегам