Подтвердить что ты не робот

Объект HTTPResponse - объект JSON должен быть str, а не 'bytes'

Я пытаюсь обновить небольшую библиотеку Python под названием libpynexmo для работы с Python 3.

Я застрял в этой функции:

def send_request_json(self, request):
    url = request
    req =  urllib.request.Request(url=url)
    req.add_header('Accept', 'application/json')
    try:
        return json.load(urllib.request.urlopen(req))
    except ValueError:
        return False

Когда это дойдет до этого, json отвечает:

TypeError: the JSON object must be str, not 'bytes'

Я прочитал в нескольких местах, что для json.load вы должны передать объекты (в этом случае объект HTTPResponse) с прикрепленным .read(), но он не работает с объектами HTTPResponse.

Я не понимаю, куда идти дальше, но, поскольку моя целая 1500 строк script только что преобразована в Python 3, мне не хочется возвращаться к 2.7.

4b9b3361

Ответ 1

Недавно я написал небольшую функцию для отправки сообщений Nexmo. Если вам не нужна полная функциональность кода libpynexmo, это должно выполнить эту работу за вас. И если вы хотите продолжить капитальный ремонт libpynexmo, просто скопируйте этот код. Ключ является кодировкой utf8.

Если вы хотите отправить какие-либо другие поля с вашим сообщением, полная документация для того, что вы можете включить с сообщением об отсутствии nexmo здесь

Python 3.4 протестирован Nexmo исходящий (JSON):

def nexmo_sendsms(api_key, api_secret, sender, receiver, body):
    """
    Sends a message using Nexmo.

    :param api_key: Nexmo provided api key
    :param api_secret: Nexmo provided secrety key
    :param sender: The number used to send the message
    :param receiver: The number the message is addressed to
    :param body: The message body
    :return: Returns the msgid received back from Nexmo after message has been sent.
    """


    msg = {
        'api_key': api_key,
        'api_secret': api_secret,
        'from': sender,
        'to': receiver,
        'text': body
    }
    nexmo_url = 'https://rest.nexmo.com/sms/json'
    data = urllib.parse.urlencode(msg)
    binary_data = data.encode('utf8')
    req = urllib.request.Request(nexmo_url, binary_data)
    response = urllib.request.urlopen(req)
    result = json.loads(response.readall().decode('utf-8'))
    return result['messages'][0]['message-id']

Ответ 2

Опираясь на ту же проблему, я решаю ее с помощью decode()

...
rawreply = connection.getresponse().read()
reply = json.loads(rawreply.decode())

Ответ 3

Я тоже встретил проблему, и теперь она проходит

import json
import urllib.request as ur
import urllib.parse as par

html = ur.urlopen(url).read()
print(type(html))
data = json.loads(html.decode('utf-8'))

Ответ 4

Поскольку вы получаете HTTPResponse, вы можете использовать Tornado.escape и его json_decode(), чтобы преобразовать JSON strign в словарь:

from tornado import escape

body = escape.json_decode(body)

Из руководства:

tornado.escape.json_decode (значение)

Возвращает объекты Python для данной строки JSON.