Helper class for form body generation. Supports multipart/form-data and application/x-www-form-urlencoded.
| 15 | |
| 16 | |
| 17 | class FormData: |
| 18 | """Helper class for form body generation. |
| 19 | |
| 20 | Supports multipart/form-data and application/x-www-form-urlencoded. |
| 21 | """ |
| 22 | |
| 23 | def __init__( |
| 24 | self, |
| 25 | fields: Iterable[Any] = (), |
| 26 | quote_fields: bool = True, |
| 27 | charset: str | None = None, |
| 28 | *, |
| 29 | default_to_multipart: bool = False, |
| 30 | ) -> None: |
| 31 | self._writer = multipart.MultipartWriter("form-data") |
| 32 | self._fields: list[Any] = [] |
| 33 | self._is_multipart = default_to_multipart |
| 34 | self._quote_fields = quote_fields |
| 35 | self._charset = charset |
| 36 | |
| 37 | if isinstance(fields, dict): |
| 38 | fields = list(fields.items()) |
| 39 | elif not isinstance(fields, (list, tuple)): |
| 40 | fields = (fields,) |
| 41 | self.add_fields(*fields) |
| 42 | |
| 43 | @property |
| 44 | def is_multipart(self) -> bool: |
| 45 | return self._is_multipart |
| 46 | |
| 47 | def add_field( |
| 48 | self, |
| 49 | name: str, |
| 50 | value: Any, |
| 51 | *, |
| 52 | content_type: str | None = None, |
| 53 | filename: str | None = None, |
| 54 | content_transfer_encoding: str | None = None, |
| 55 | ) -> None: |
| 56 | |
| 57 | if isinstance(value, io.IOBase): |
| 58 | self._is_multipart = True |
| 59 | elif isinstance(value, (bytes, bytearray, memoryview)): |
| 60 | msg = ( |
| 61 | "In v4, passing bytes will no longer create a file field. " |
| 62 | "Please explicitly use the filename parameter or pass a BytesIO object." |
| 63 | ) |
| 64 | if filename is None and content_transfer_encoding is None: |
| 65 | warnings.warn(msg, DeprecationWarning) |
| 66 | filename = name |
| 67 | |
| 68 | _safe_header(name) |
| 69 | type_options: MultiDict[str] = MultiDict({"name": name}) |
| 70 | if filename is not None and not isinstance(filename, str): |
| 71 | raise TypeError("filename must be an instance of str. Got: %s" % filename) |
| 72 | if filename is None and isinstance(value, io.IOBase): |
| 73 | filename = guess_filename(value, name) |
| 74 | if filename is not None: |
no outgoing calls