Estoy tratando de enviar datos de publicación a una API que debe estar en json. Si el encabezado de las solicitudes no tiene Content-type: application-json, la solicitud falla y obtengo un HTTPError: 415 Client Error: Unsupported Media Type for url

Sin embargo, las solicitudes solo parecen agregarse en este encabezado si utilizo el analizador json incorporado. Aunque los documentos parecen sugerir que lo siguiente es equivalente:

>>> r = requests.post(url, data=json.dumps(payload))

>>> r = requests.post(url, json=payload)

Lo que significa que necesito usar el analizador json integrado (o agregar manualmente el encabezado Content-type).

Sin embargo, mis datos de publicación tienen varios campos decimales (desde una API convertida a través de json.loads(response.text, parse_float=decimal.Decimal) para guardar en un django DecimalField) que al usar el analizador de solicitudes incorporado da el error:

TypeError: Decimal('1560.35') is not JSON serialisable

¿Hay alguna manera de usar un analizador json diferente con solicitudes (por ejemplo, simplejson que trata con decimales) y tener el tipo de contenido todavía especificado?

0
Yunti 10 may. 2016 a las 14:14

3 respuestas

La mejor respuesta

No sé cómo usar un analizador json diferente, pero puede configurar el encabezado (y, por lo tanto, el tipo de contenido).

r = requests.post(url, data=json.dumps(payload), headers={'Content-type': 'application/json'})
# or with a session object
s = requests.Session()
s.headers['Content-Type'] = 'application/json'
s.post(url, data=json.dumps(payload))
2
salomonderossi 10 may. 2016 a las 11:32

Los decimales se pueden serializar al pasar por una función personalizada.

def decimal_default(obj):
    if isinstance(obj, Decimal):
        return str(obj)
    raise TypeError


data = json.dumps(payload, default=decimal_default)

response = requests.post(
    url=url,
    data=data,
    headers={
        'Content-type': 'application/json',
    }
)
2
pymarco 26 may. 2017 a las 17:57

Simplemente instale simplejson y requests lo usará para serializar decimales:

$ pip3 install simplejson    

Esto ya no generará un TypeError:

>>> requests.post(url, json={'foo': Decimal('1.23')})
0
Max Malysh 14 abr. 2018 a las 19:36