Evernote SDK for Python3のget_note_store()でエラーが発生するようになり対処した話

Evernote SDK for Python3を1.25.14に更新したら解消しました。
2020.07.19

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部の若槻です。

ノートテイキングアプリEvernoteのAPIをPython3から利用するためには、Evernoteが公式提供している次のSDKを使用する必要があります。

このSDKを使ってAWS Lambda上に実装していたプログラムを久し振りに使うことになりテスト実行をしてみたところ、なぜかエラーとなったため対処した際の記録を今回は残させて頂きます。

事象が発生した環境

  • AWS Lambda(Python3.7ランタイム)
  • Evernote SDK for Python3(evernote3 1.25.13

事象

プログラムのうち次のようなget_note_store()によるNoteStoreオブジェクトの初期化を実施するコードで、

from evernote.api.client import EvernoteClient

client = EvernoteClient(token=access_token, sandbox=False)
note_store = client.get_note_store()

下記のようなエラーが発生するようになりました。

[ERROR] MemoryError
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 37, in lambda_handler
    note_store = client.get_note_store()
  File "/opt/python/evernote/api/client.py", line 106, in get_note_store
    note_store_uri = user_store.getNoteStoreUrl()
  File "/opt/python/evernote/api/client.py", line 167, in delegate_method
    )(**dict(list(zip(arg_names, args))))
  File "/opt/python/evernote/edam/userstore/UserStore.py", line 1156, in getNoteStoreUrl
    return self.recv_getNoteStoreUrl()
  File "/opt/python/evernote/edam/userstore/UserStore.py", line 1167, in recv_getNoteStoreUrl
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
  File "/opt/python/thrift/protocol/TBinaryProtocol.py", line 144, in readMessageBegin
    name = self.trans.readAll(sz)
  File "/opt/python/thrift/transport/THttpClient.py", line 104, in readAll
    return self.read(sz)
  File "/opt/python/thrift/transport/THttpClient.py", line 101, in read
    return self.response.read(sz)
  File "/var/lang/lib/python3.7/http/client.py", line 456, in read
    b = bytearray(amt)

[ERROR] MemoryErrorとあるためメモリ不足かな?と思いLambdaのメモリサイズの設定を128から512MBに上げたところ、次は同じ箇所で下記のようなエラーが発生するようになりました。

[ERROR] error: unpack requires a buffer of 1 bytes
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 37, in lambda_handler
    note_store = client.get_note_store()
  File "/opt/python/evernote/api/client.py", line 106, in get_note_store
    note_store_uri = user_store.getNoteStoreUrl()
  File "/opt/python/evernote/api/client.py", line 167, in delegate_method
    )(**dict(list(zip(arg_names, args))))
  File "/opt/python/evernote/edam/userstore/UserStore.py", line 1156, in getNoteStoreUrl
    return self.recv_getNoteStoreUrl()
  File "/opt/python/evernote/edam/userstore/UserStore.py", line 1167, in recv_getNoteStoreUrl
    (fname, mtype, rseqid) = self._iprot.readMessageBegin()
  File "/opt/python/thrift/protocol/TBinaryProtocol.py", line 145, in readMessageBegin
    type = self.readByte()
  File "/opt/python/thrift/protocol/TBinaryProtocol.py", line 201, in readByte
    val, = unpack('!b', buff)

次にアクセストークン切れを疑い、以下の記事を参考に新しいトークン取得して既存のトークンと差し替えてみましたが、

前述のunpack requires a buffer of 1 bytesエラーは解消されませんでした。

解決

Evernote SDK for Python3のGitHubリポジトリで次のissueが上がっているのを見つけました。

issueの内容を要約すると以下のようになります。

  • 今回と同様の事象が2020年6月頃に報告されている
  • それを受けて修正版のSDKevernote3 1.25.14が同月にリリース済み
  • 1.25.13バージョンに含まれているThrift SDKが古く、API側の更新に対応できなかったことが原因だった

そこで私もLambdaのコードに含めているEvernote SDK for Python3を1.25.14に更新したところ、エラーが解消して問題なく実行されるようになりました。

また、更新後はLambdaのメモリサイズを128に戻しても問題はありませんでした。

おわりに

Evernote SDK for Python3のget_note_store()でエラーが発生するようになり対処した話でした。

メモ・タスク管理アプリとしての利用を一時中断していたEvernoteにこのたび戻ることとなり、中断前に停止していたEvernote向けの自動化プログラムを点検していたところ、今回のエラーに直面しました。Evernote SDKはそんなに頻繁に更新がされるイメージはなかったのですが、今回迅速なアップデートにより解決がされていて良かったです。

以上