jupyter笔记本中的Ipython错误,没有堆栈跟踪

Posted

技术标签:

【中文标题】jupyter笔记本中的Ipython错误,没有堆栈跟踪【英文标题】:Ipython error in jupyter notebook, no stack trace 【发布时间】:2018-09-12 05:18:18 【问题描述】:

我正在使用这里的代码:Sending email via gmail & python 第 3 步,(我的版本如下所示)

import httplib2
import os
import oauth2client
from oauth2client import client, tools
import base64
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from apiclient import errors, discovery
import mimetypes
from email.mime.image import MIMEImage
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase

SCOPES = 'https://www.googleapis.com/auth/gmail.send'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Gmail API Python Send Email'

def get_credentials():
    home_dir = "C:\\Users\\kelvi_000\\Documents\\Jupyter Notebooks\\"
    credential_dir = os.path.join(home_dir, '.credentials')
    if not os.path.exists(credential_dir):
        os.makedirs(credential_dir)
    credential_path = os.path.join(credential_dir, 'gmail-python-email-send.json')
    store = oauth2client.file.Storage(credential_path)
    #credentials = store.get()
    credentails = False
    if True: #not credentials or credentials.invalid:
        flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
        flow.user_agent = APPLICATION_NAME
        credentials = tools.run_flow(flow, store)
        print('Storing credentials to ' + credential_path)
    return credentials

def SendMessage(sender, to, subject, msghtml, msgPlain, attachmentFile=None):
    credentials = get_credentials()
    http = credentials.authorize(httplib2.Http())
    service = discovery.build('gmail', 'v1', http=http)
    if attachmentFile:
        message1 = createMessageWithAttachment(sender, to, subject, msgHtml, msgPlain, attachmentFile)
    else: 
        message1 = CreateMessageHtml(sender, to, subject, msgHtml, msgPlain)
    result = SendMessageInternal(service, "me", message1)
    return result

def SendMessageInternal(service, user_id, message):
    try:
        message = (service.users().messages().send(userId=user_id, body=message).execute())
        print('Message Id: %s' % message['id'])
        return message
    except errors.HttpError as error:
        print('An error occurred: %s' % error)
        return "Error"
    return "OK"

def CreateMessageHtml(sender, to, subject, msgHtml, msgPlain):
    msg = MIMEMultipart('alternative')
    msg['Subject'] = subject
    msg['From'] = sender
    msg['To'] = to
    msg.attach(MIMEText(msgPlain, 'plain'))
    msg.attach(MIMEText(msgHtml, 'html'))
    return 'raw': base64.urlsafe_b64encode(msg.as_string())

def createMessageWithAttachment(
    sender, to, subject, msgHtml, msgPlain, attachmentFile):
    """Create a message for an email.

    Args:
      sender: Email address of the sender.
      to: Email address of the receiver.
      subject: The subject of the email message.
      msgHtml: Html message to be sent
      msgPlain: Alternative plain text message for older email clients          
      attachmentFile: The path to the file to be attached.

    Returns:
      An object containing a base64url encoded email object.
    """
    message = MIMEMultipart('mixed')
    message['to'] = to
    message['from'] = sender
    message['subject'] = subject

    messageA = MIMEMultipart('alternative')
    messageR = MIMEMultipart('related')

    messageR.attach(MIMEText(msgHtml, 'html'))
    messageA.attach(MIMEText(msgPlain, 'plain'))
    messageA.attach(messageR)

    message.attach(messageA)

    print("create_message_with_attachment: file: %s" % attachmentFile)
    content_type, encoding = mimetypes.guess_type(attachmentFile)

    if content_type is None or encoding is not None:
        content_type = 'application/octet-stream'
    main_type, sub_type = content_type.split('/', 1)
    if main_type == 'text':
        fp = open(attachmentFile, 'rb')
        msg = MIMEText(fp.read(), _subtype=sub_type)
        fp.close()
    elif main_type == 'image':
        fp = open(attachmentFile, 'rb')
        msg = MIMEImage(fp.read(), _subtype=sub_type)
        fp.close()
    elif main_type == 'audio':
        fp = open(attachmentFile, 'rb')
        msg = MIMEAudio(fp.read(), _subtype=sub_type)
        fp.close()
    else:
        fp = open(attachmentFile, 'rb')
        msg = MIMEBase(main_type, sub_type)
        msg.set_payload(fp.read())
        fp.close()
    filename = os.path.basename(attachmentFile)
    msg.add_header('Content-Disposition', 'attachment', filename=filename)
    message.attach(msg)

    return 'raw': base64.urlsafe_b64encode(message.as_string())


def main():
    to = "to@address.com"
    sender = "from@address.com"
    subject = "subject"
    msgHtml = "Hi<br/>Html Email"
    msgPlain = "Hi\nPlain Email"
    SendMessage(sender, to, subject, msgHtml, msgPlain)
    # Send message with attachment: 
    SendMessage(sender, to, subject, msgHtml, msgPlain, '/path/to/file.pdf')

if __name__ == '__main__':
    main()

与其他答案的不同之处在于第 19 行,我已将变量 [home_dir] 修改为:

home_dir = "C:\\Users\\kelvi_000\\Documents\\Jupyter Notebooks\\"

除了:

#credentials = store.get()
credentails = False
if True: #not credentials or credentials.invalid:

注释掉 [credentials] 的声明并修改 if 凭证不是有效的部分。 (第 25-27 行)

现在的问题是:

usage: ipykernel_launcher.py [--auth_host_name AUTH_HOST_NAME]
                             [--noauth_local_webserver]
                             [--auth_host_port [AUTH_HOST_PORT [AUTH_HOST_PORT ...]]]
                             [--logging_level DEBUG,INFO,WARNING,ERROR,CRITICAL]
ipykernel_launcher.py: error: unrecognized arguments: -f C:\Users\kelvi_000\AppData\Roaming\jupyter\runtime\kernel-942a92b5-f8cf-4ec2-8348-138e4580d562.json
An exception has occurred, use %tb to see the full traceback.

SystemExit: 2


C:\Users\kelvi_000\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py:2918: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
  warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)

没有堆栈跟踪、没有行号、没有 ipykernel_launcher……只是这个愚蠢的错误,在谷歌上搜索时没有显示任何内容……

使用python3


更新: 我已经追踪到问题所在:

credentials = tools.run_flow(flow, store)

在函数中

get_credentials

【问题讨论】:

【参考方案1】:

好吧,这完全令人费解。解决方案是将脚本放在它自己的 python 文件中,因为这有点不同。

然后从 jupyter notebook 运行

%run [your filename].py

它有效吗?!

Your browser has been opened to visit:

    [censored]

If your browser is on a different machine then exit and re-run this
application with the command-line parameter

  --noauth_local_webserver

Authentication successful.
Storing credentials to C:\Users\kelvi_000\Documents\Jupyter Notebooks\.credentials\gmail-python-email-send.json

【讨论】:

以上是关于jupyter笔记本中的Ipython错误,没有堆栈跟踪的主要内容,如果未能解决你的问题,请参考以下文章

Pandas/iPython 笔记本(Jupyter)中 DataFrame/table 中的 GROUP BY 行?

如何将IPython v3笔记本转换为Jupyter v4?

Ipython笔记本(jupyter),opencv(cv2)和绘图?

在 jupyter/iPython notebook 脚本和类方法之间同步代码

在 ipython/Jupyter notebook 中导入 scikit-learn

更改 IPython/Jupyter 笔记本工作目录