Debe usar el files
parámetro para enviar una solicitud POST de formulario multiparte incluso cuando no necesite cargar ningún archivo.
De la fuente original de solicitudes :
def request(method, url, **kwargs):
"""Constructs and sends a :class:`Request <Request>`.
...
:param files: (optional) Dictionary of ``'name': file-like-objects``
(or ``{'name': file-tuple}``) for multipart encoding upload.
``file-tuple`` can be a 2-tuple ``('filename', fileobj)``,
3-tuple ``('filename', fileobj, 'content_type')``
or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``,
where ``'content-type'`` is a string
defining the content type of the given file
and ``custom_headers`` a dict-like object
containing additional headers to add for the file.
La parte relevante es: file-tuple can be a
2-tuple
, 3-tuple
or a
4-tuple
.
Con base en lo anterior, la solicitud de formulario multiparte más simple que incluye tanto archivos para cargar como campos de formulario se verá así:
multipart_form_data = {
'file2': ('custom_file_name.zip', open('myfile.zip', 'rb')),
'action': (None, 'store'),
'path': (None, '/path1')
}
response = requests.post('https://httpbin.org/post', files=multipart_form_data)
print(response.content)
☝ Tenga en cuenta que None
es el primer argumento en la tupla para campos de texto sin formato: este es un marcador de posición para el campo de nombre de archivo que solo se usa para cargar archivos, pero para los campos de texto que pasan None
como primer parámetro es necesario para que los datos se envíen .
Múltiples campos con el mismo nombre.
Si necesita publicar múltiples campos con el mismo nombre, en lugar de un diccionario, puede definir su carga útil como una lista (o una tupla) de tuplas:
multipart_form_data = (
('file2', ('custom_file_name.zip', open('myfile.zip', 'rb'))),
('action', (None, 'store')),
('path', (None, '/path1')),
('path', (None, '/path2')),
('path', (None, '/path3')),
)
API de solicitudes de transmisión
Si la API anterior no es lo suficientemente pitónica para usted, entonces considere usar el toolbelt de solicitudes ( pip install requests_toolbelt
), que es una extensión del módulo de solicitudes principales que proporciona soporte para la transmisión de carga de archivos, así como el MultipartEncoder que se puede usar en lugar de files
, y que también permite Usted define la carga útil como un diccionario, tupla o lista.
MultipartEncoder
se puede usar tanto para solicitudes de varias partes con o sin campos de carga reales. Debe asignarse al data
parámetro.
import requests
from requests_toolbelt.multipart.encoder import MultipartEncoder
multipart_data = MultipartEncoder(
fields={
# a file upload field
'file': ('file.zip', open('file.zip', 'rb'), 'text/plain')
# plain text fields
'field0': 'value0',
'field1': 'value1',
}
)
response = requests.post('http://httpbin.org/post', data=multipart_data,
headers={'Content-Type': multipart_data.content_type})
Si necesita enviar varios campos con el mismo nombre, o si el orden de los campos del formulario es importante, puede usar una tupla o una lista en lugar de un diccionario:
multipart_data = MultipartEncoder(
fields=(
('action', 'ingest'),
('item', 'spam'),
('item', 'sausage'),
('item', 'eggs'),
)
)