跳转到主要内容

multipart/form-data 解析器

项目描述

Tests Status Latest Version License

此模块提供了RFC-7578 multipart/form-data的多个解析器,既有针对框架作者的底层解析器,也有针对WSGI应用开发者的高层解析器。

  • PushMultipartParser:一个适合asyncio和其他时间或内存受限环境的底层增量 SansIO(非阻塞)解析器。

  • MultipartParser:一个流式解析器,生成内存和磁盘缓冲的 MultipartPart 实例。

  • parse_form_data:一个辅助函数,用于从WSGI环境解析 multipart/form-dataapplication/x-www-form-urlencoded 表单提交。

安装

pip install multipart

特性

  • 纯Python单文件模块,无依赖。

  • 100%测试覆盖率。使用实际浏览器和HTTP客户端的输入进行测试。

  • 在现代硬件上解析多个GB/s(快速测试,无正式基准测试)。

  • 快速拒绝恶意或损坏的输入,并发出有用的错误信息。

  • 强制执行可配置的内存和磁盘资源限制,以防止DoS攻击。

限制:该解析器实现了与实际现代浏览器和HTTP客户端相同的使用方式multipart/form-data,这意味着

  • 仅支持multipart/form-data,不适用于电子邮件解析。

  • 不支持multipart/mixed(在RFC 7578中被弃用)。

  • 不支持base64quoted-printable传输编码(在RFC 7578中被弃用)。

  • 不支持encoded-wordname=_charset_编码标记(在RFC 7578中被不鼓励使用)。

  • 不支持明显损坏的输入(例如无效的换行符或头名称)。

使用和示例

对于WSGI应用程序开发者,我们强烈建议使用parse_form_data辅助函数。它接受一个WSGI environ字典,并根据请求的实际内容类型解析两种类型的表单提交(multipart/form-dataapplication/x-www-form-urlencoded)。您将返回两个MultiDict实例,一个用于文本字段,另一个用于文件上传

from multipart import parse_form_data

def wsgi(environ, start_response):
  if environ["REQUEST_METHOD"] == "POST":
    forms, files = parse_form_data(environ)

    title = forms["title"]    # string
    upload = files["upload"]  # MultipartPart
    upload.save_as(...)

parse_form_data辅助函数内部使用MultipartParser,这是一个流式解析器,它从multipart/form-data编码的二进制数据流中读取,并在完全解析一个部分后立即发出MultipartPart实例。如果您想尽快消费各个部分,而不是等待整个请求被解析,这将非常有用

from multipart import parse_options_header, MultipartParser

def wsgi(environ, start_response):
  assert environ["REQUEST_METHOD"] == "POST"
  ctype, copts = parse_options_header(environ.get("CONTENT_TYPE", ""))
  boundary = copts.get("boundary")
  charset = copts.get("charset", "utf8")
  assert ctype == "multipart/form-data"

  parser = MultipartParser(environ["wsgi.input"], boundary, charset)
  for part in parser:
    if part.filename:
      print(f"{part.name}: File upload ({part.size} bytes)")
      part.save_as(...)
    elif part.size < 1024:
      print(f"{part.name}: Text field ({part.value!r})")
    else:
      print(f"{part.name}: Test field, but too big to print :/")

MultipartParser为您处理IO和文件缓冲,但它使用阻塞API。如果您需要完全控制解析过程,并且不惜一切代价避免阻塞IO,那么请查看PushMultipartParser,这是一个低级非阻塞增量multipart/form-data解析器,为该库中的所有其他解析器提供动力

from multipart import PushMultipartParser, MultipartSegment

async def process_multipart(reader: asyncio.StreamReader, boundary: str):
  with PushMultipartParser(boundary) as parser:
    while not parser.closed:
      chunk = await reader.read(1024*64)
      for result in parser.parse(chunk):
        if isinstance(result, MultipartSegment):
          print(f"== Start of segment: {result.name}")
          for header, value in result.headerlist:
            print(f"{header}: {value}")
        elif result:  # Result is a non-empty bytearray
          print(f"[received {len(result)} bytes of data]")
        else:         # Result is None
          print(f"== End of segment")

变更日志

  • 1.1

    • 其中一些修复更改了行为以匹配文档或规范,其中没有一个应该令人惊讶。现有应用程序应该能够在不进行更改的情况下升级。

    • 修复:在输入包含无效换行符时更快失败(#55)

    • 修复:允许空段名称(#56)

    • 修复:在使用parse_form_data时避免ResourceWarning(#57)

    • 修复:MultipartPart现在始终具有合理的MIME类型。

    • 修复:在上下文管理器退出时实际检查解析器状态。

    • 修复:如果存在,则尊重Content-Length头。

    • 性能:减少小段落的开销(-21%)

    • 性能:减少大上传的写入开销(-2%)

  • 1.0

    • 一个全新的、快速的、非阻塞的PushMultipartParser解析器,现在作为所有其他解析器的基础。

    • 新解析器更加严格,并且在非严格模式下更快地拒绝明显损坏的输入(例如无效的换行符或头名称)。这不应影响实际浏览器或HTTP客户端发送的数据。

    • MultipartParser头和文本字段的默认字符集更改为utf8,如W3C HTTP建议。

    • MultipartParser的默认磁盘和内存限制已提高,但添加了多个其他限制以实现更精细的控制。请检查新默认值是否满足您的需求。

    • 未记录的API已弃用或删除,其中一些并非严格私有。这包括MultipartParser的参数和一些MultipartPart方法,但它们不应该被除解析器自身之外的人使用。

  • 0.2.5

    • 不要在urlencoded数据中测试分号分隔符(#33)

    • 添加python-requires指令,指示需要Python 3.5或更高版本,并防止旧版本的Python尝试下载此版本(#32)

    • 添加对Python 3.10-3.12的官方支持(#38,#48)

    • copy_file的默认值应为2 ** 16,而不是2 * 16(#41)

    • 更新Bottle的URL(#42)

  • 0.2.4

    • 始终解码非UTF-8 URL编码的表单数据

  • 0.2.3

    • 从collections.abc导入MutableMapping(#23)

    • 修复测试套件中的几个ResourceWarnings(#24)

    • 允许流在第一个边界之前包含数据(#25)

  • 0.2.2

    • 修复Python 3上的#21 ResourceWarnings(#25)

  • 0.2.1

    • 修复#20空有效载荷(#20)

  • 0.2

    • 已取消对低于3.6版本的Python的支持。如果您需要Python 2.5+支持,请保持在0.1版本。

  • 0.1

    • 第一个版本

项目详情


下载文件

为您的平台下载文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分布

multipart-1.1.0.tar.gz (34.6 kB 查看哈希值)

上传时间

构建分布

multipart-1.1.0-py3-none-any.whl (13.6 kB 查看哈希值)

上传时间 Python 3

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面