LINUX.ORG.RU

Кодировки в питоне

 , , ,


0

1

Здравствуйте. В задаче имеется REST API сервиса SendPulse, и некая прослойка в виде минимального вебсервиса принимающего JSON и передающего данные через API. Все на питоне.

Собственно сама проблема:

Если JSON запрос находится непосредственно в коде, то все выполняется корректно. Если же я его беру из файла:

    with open('mail.json') as js:    
        data = json.load(js)
в ответ получаю

UnicodeEncodeError: 'ascii' codec can't encode characters in position 4-9: ordinal not in range(128)

если же декодирую словарь:

data = {k: unicode(v).encode("utf-8") for k,v in data.iteritems()}
в ответ дэбаг говорит:

Request response: {u'message': u'Empty «From» email', u'error_code': 10}

при попытке дэкодировать в ASCII или теряю русские символы, или получаю новые ошибки.

Вот сама функция которая из API.

    def smtp_send_mail(self, email):
        logging.info("Function call: smtp_send_mail")
        if not email.get('html') or not email.get('text'):
            return self.__handle_error('Seems we have empty body')
        elif not email.get('subject'):
            return self.__handle_error('Seems we have empty subject')
        elif not email.get('from') or not email.get('to'):
            return self.__handle_error("Seems we have empty some credentials 'from': '{}' or 'to': '{}' fields".format(email.get('from'), email.get('to')))
        email['html'] = base64.b64encode(email.get('html'))
        return self.__handle_result(self.__send_request('smtp/emails', 'POST', {'email': json.dumps(email)}))
GitHub API

Пример JSON

{
    "subject": "Это тестовое письмо отправленное через REST API sendpulse",
    "html": "<h1>Привет!</h1><p>Это тестовое письмо</p>",
    "text": "Привет!\nЭто тестовое письмо",
    "from": {"name": "Test SMTP Python", "email": "my@mail.xyz"},
    "to": [
        {"name": "SMTP test", "email": "first@mail.xyz"}
    ],
    "bcc": [
        {"name": "SMTP test", "email": "second@mail.xyz"}
    ]
}

Собственно нуждаюсь в совете или решении данной задачи. Как правильно открыть или конвертировать JSON, чтобы его смогла принять данная функция.

У меня на втором питоне данный код выполняется успешно.

import json

with open('mail.json') as js:    
    data = json.load(js)

unicode(foo) — всегда ошибочная конструкция.

В целом советую изучить эту статью. Но твою ошибку воспроизвести не смог.

PolarFox ★★★★★ ()

Попробуй

import codecs

codecs.open(«mail.json», «r», «utf-8»)

pawnhearts ★★★★★ ()

data = {k: unicode(v).encode(«utf-8») for k,v in data.iteritems()}

У тебя в data некоторые значения v сами являются словарями, а ты их сериализуешь в unicode. По-моему, тут придётся писать что-то типа

def recode_dict(x):
    if isinstance(x, unicode):
        return x.encode('utf-8')
    elif isinstance(x, dict):
        return {recode_dict(k): recode_dict(v) for k,v in x.iteritems()}
    else:
        return x
data = recode_dict(data)

proud_anon ★★★★★ ()
Ответ на: комментарий от PolarFox

В целом советую изучить эту статью. Но твою ошибку воспроизвести не смог.

А ты его ошибку реально на SendPulse API воспроизводил? Поскольку, как я понимаю, ТСовские сообщения об ошибках выпадают не из кусков кода, под которыми он их написал, а из метода smtp_send_mail.

proud_anon ★★★★★ ()
Ответ на: комментарий от proud_anon

Без полного трейсбека и, желательно, короткого воспроизводимого примера конкретные указания дать трудно.

PolarFox ★★★★★ ()
with open('1.js') as js:
    data = json.loads(js.read().decode('utf-8'))

UPD. Верхняя конструкция на твоем файле споткнулась, а такая вот работает

with open('1.js') as js:
    data = json.loads(js.read(), encoding="utf-8")

UPD. Как впрочем и эта

with open('1.js') as js:
    data = json.load(js, encoding="utf-8")
vvn_black ★★★★★ ()
Последнее исправление: vvn_black (всего исправлений: 2 )
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.