comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/lib/python3.8/site-packages/urllib3/filepost.py @ 68:5028fdace37b

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 16:23:26 -0400
parents
children
comparison
equal deleted inserted replaced
67:0e9998148a16 68:5028fdace37b
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