comparison 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
comparison
equal deleted inserted replaced
6:b2745907b1eb 7:5eb2d5e3bf22
1 from __future__ import annotations
2
3 import binascii
4 import codecs
5 import os
6 import typing
7 from io import BytesIO
8
9 from .fields import _TYPE_FIELD_VALUE_TUPLE, RequestField
10
11 writer = codecs.lookup("utf-8")[3]
12
13 _TYPE_FIELDS_SEQUENCE = typing.Sequence[
14 typing.Union[typing.Tuple[str, _TYPE_FIELD_VALUE_TUPLE], RequestField]
15 ]
16 _TYPE_FIELDS = typing.Union[
17 _TYPE_FIELDS_SEQUENCE,
18 typing.Mapping[str, _TYPE_FIELD_VALUE_TUPLE],
19 ]
20
21
22 def choose_boundary() -> str:
23 """
24 Our embarrassingly-simple replacement for mimetools.choose_boundary.
25 """
26 return binascii.hexlify(os.urandom(16)).decode()
27
28
29 def iter_field_objects(fields: _TYPE_FIELDS) -> typing.Iterable[RequestField]:
30 """
31 Iterate over fields.
32
33 Supports list of (k, v) tuples and dicts, and lists of
34 :class:`~urllib3.fields.RequestField`.
35
36 """
37 iterable: typing.Iterable[RequestField | tuple[str, _TYPE_FIELD_VALUE_TUPLE]]
38
39 if isinstance(fields, typing.Mapping):
40 iterable = fields.items()
41 else:
42 iterable = fields
43
44 for field in iterable:
45 if isinstance(field, RequestField):
46 yield field
47 else:
48 yield RequestField.from_tuples(*field)
49
50
51 def encode_multipart_formdata(
52 fields: _TYPE_FIELDS, boundary: str | None = None
53 ) -> tuple[bytes, str]:
54 """
55 Encode a dictionary of ``fields`` using the multipart/form-data MIME format.
56
57 :param fields:
58 Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`).
59 Values are processed by :func:`urllib3.fields.RequestField.from_tuples`.
60
61 :param boundary:
62 If not specified, then a random boundary will be generated using
63 :func:`urllib3.filepost.choose_boundary`.
64 """
65 body = BytesIO()
66 if boundary is None:
67 boundary = choose_boundary()
68
69 for field in iter_field_objects(fields):
70 body.write(f"--{boundary}\r\n".encode("latin-1"))
71
72 writer(body).write(field.render_headers())
73 data = field.data
74
75 if isinstance(data, int):
76 data = str(data) # Backwards compatibility
77
78 if isinstance(data, str):
79 writer(body).write(data)
80 else:
81 body.write(data)
82
83 body.write(b"\r\n")
84
85 body.write(f"--{boundary}--\r\n".encode("latin-1"))
86
87 content_type = f"multipart/form-data; boundary={boundary}"
88
89 return body.getvalue(), content_type