diff urllib3/filepost.py @ 7:5eb2d5e3bf22

planemo upload for repository https://toolrepo.galaxytrakr.org/view/jpayne/bioproject_to_srr_2/556cac4fb538
author jpayne
date Sun, 05 May 2024 23:32:17 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/urllib3/filepost.py	Sun May 05 23:32:17 2024 -0400
@@ -0,0 +1,89 @@
+from __future__ import annotations
+
+import binascii
+import codecs
+import os
+import typing
+from io import BytesIO
+
+from .fields import _TYPE_FIELD_VALUE_TUPLE, RequestField
+
+writer = codecs.lookup("utf-8")[3]
+
+_TYPE_FIELDS_SEQUENCE = typing.Sequence[
+    typing.Union[typing.Tuple[str, _TYPE_FIELD_VALUE_TUPLE], RequestField]
+]
+_TYPE_FIELDS = typing.Union[
+    _TYPE_FIELDS_SEQUENCE,
+    typing.Mapping[str, _TYPE_FIELD_VALUE_TUPLE],
+]
+
+
+def choose_boundary() -> str:
+    """
+    Our embarrassingly-simple replacement for mimetools.choose_boundary.
+    """
+    return binascii.hexlify(os.urandom(16)).decode()
+
+
+def iter_field_objects(fields: _TYPE_FIELDS) -> typing.Iterable[RequestField]:
+    """
+    Iterate over fields.
+
+    Supports list of (k, v) tuples and dicts, and lists of
+    :class:`~urllib3.fields.RequestField`.
+
+    """
+    iterable: typing.Iterable[RequestField | tuple[str, _TYPE_FIELD_VALUE_TUPLE]]
+
+    if isinstance(fields, typing.Mapping):
+        iterable = fields.items()
+    else:
+        iterable = fields
+
+    for field in iterable:
+        if isinstance(field, RequestField):
+            yield field
+        else:
+            yield RequestField.from_tuples(*field)
+
+
+def encode_multipart_formdata(
+    fields: _TYPE_FIELDS, boundary: str | None = None
+) -> tuple[bytes, str]:
+    """
+    Encode a dictionary of ``fields`` using the multipart/form-data MIME format.
+
+    :param fields:
+        Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`).
+        Values are processed by :func:`urllib3.fields.RequestField.from_tuples`.
+
+    :param boundary:
+        If not specified, then a random boundary will be generated using
+        :func:`urllib3.filepost.choose_boundary`.
+    """
+    body = BytesIO()
+    if boundary is None:
+        boundary = choose_boundary()
+
+    for field in iter_field_objects(fields):
+        body.write(f"--{boundary}\r\n".encode("latin-1"))
+
+        writer(body).write(field.render_headers())
+        data = field.data
+
+        if isinstance(data, int):
+            data = str(data)  # Backwards compatibility
+
+        if isinstance(data, str):
+            writer(body).write(data)
+        else:
+            body.write(data)
+
+        body.write(b"\r\n")
+
+    body.write(f"--{boundary}--\r\n".encode("latin-1"))
+
+    content_type = f"multipart/form-data; boundary={boundary}"
+
+    return body.getvalue(), content_type