limpiar - Solicitudes de Python: publicar JSON y archivar en una sola solicitud
limpiar json python (5)
No codifique utilizando json.
import requests
info = {
''var1'' : ''this'',
''var2'' : ''that'',
}
data = {
''token'' : auth_token,
''info'' : info,
}
headers = {''Content-type'': ''multipart/form-data''}
files = {''document'': open(''file_name.pdf'', ''rb'')}
r = requests.post(url, files=files, data=data, headers=headers)
Tenga en cuenta que esto puede no ser necesariamente lo que desea, ya que se convertirá en otra sección de datos de formulario.
Necesito hacer una llamada a la API para cargar un archivo junto con una cadena JSON con detalles sobre el archivo.
Estoy tratando de usar las peticiones de python lib para hacer esto:
import requests
info = {
''var1'' : ''this'',
''var2'' : ''that'',
}
data = json.dumps({
''token'' : auth_token,
''info'' : info,
})
headers = {''Content-type'': ''multipart/form-data''}
files = {''document'': open(''file_name.pdf'', ''rb'')}
r = requests.post(url, files=files, data=data, headers=headers)
Esto arroja el siguiente error:
raise ValueError("Data must not be a string.")
ValueError: Data must not be a string
Si elimino los ''archivos'' de la solicitud, funciona.
Si elimino los ''datos'' de la solicitud, funciona.
Si no codifico datos como JSON funciona.
Por este motivo, creo que el error está relacionado con el envío de datos y archivos JSON en la misma solicitud.
¿Alguna idea sobre cómo hacer que esto funcione?
No creo que pueda enviar datos y archivos en un archivo codificado en varias partes, por lo que también necesita hacer de sus datos un "archivo":
files = {
''data'' : data,
''document'': open(''file_name.pdf'', ''rb'')
}
r = requests.post(url, files=files, headers=headers)
Para el envío de la API de Facebook Messenger, cambié todos los valores del diccionario de carga útil a cadenas. Entonces, puedo pasar la carga útil como parámetro de data
.
import requests
ACCESS_TOKEN = ''''
url = ''https://graph.facebook.com/v2.6/me/messages''
payload = {
''access_token'' : ACCESS_TOKEN,
''messaging_type'' : "UPDATE",
''recipient'' : ''{"id":"1111111111111"}'',
''message'' : ''{"attachment":{"type":"image", "payload":{"is_reusable":true}}}'',
}
files = {''filedata'': (file, open(file, ''rb''), ''image/png'')}
r = requests.post(url, files=files, data=payload)
Qué es más:
files = {
''document'': open(''file_name.pdf'', ''rb'')
}
Eso solo funcionará si su archivo está en el mismo directorio donde está su script.
Si desea agregar un archivo de un directorio diferente, debe hacer:
files = {
''document'': open(os.path.join(dir_path, ''file_name.pdf''), ''rb'')
}
Donde dir_path es un directorio con su archivo ''nombre_archivo.pdf'' .
Pero, ¿qué pasa si desea enviar varios archivos PDF?
Simplemente puede hacer una función personalizada para devolver una lista de los archivos que necesita (en su caso, solo pueden ser aquellos con la extensión .pdf ). Eso también incluye archivos en subdirectorios (búsqueda de archivos recursivamente):
def prepare_pdfs():
return sorted([os.path.join(root, filename) for root, dirnames, filenames in os.walk(dir_path) for filename in filenames if filename.endswith(''.pdf'')])
Entonces puedes llamarlo:
my_data = prepare_pdfs()
Y con bucle simple:
for file in my_data:
pdf = open(file, ''rb'')
files = {
''document'': pdf
}
r = requests.post(url, files=files, ...)
Ver este hilo Cómo enviar JSON como parte de una solicitud POST multiparte
No configure el encabezado de tipo de Contenido usted mismo, deje eso a pyrequests para generar
def send_request():
payload = {"param_1": "value_1", "param_2": "value_2"}
files = {
''json'': (None, json.dumps(payload), ''application/json''),
''file'': (os.path.basename(file), open(file, ''rb''), ''application/octet-stream'')
}
r = requests.post(url, files=files)
print(r.content)