Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save hankei6km/e75a6db9c302caac1b54cdc65cee86fe to your computer and use it in GitHub Desktop.
Save hankei6km/e75a6db9c302caac1b54cdc65cee86fe to your computer and use it in GitHub Desktop.
SAM ローカルの python3.6 ランタイムと Visual Studio Code でデバッグ

SAM ローカルの python3.6 ランタイムと Visual Studio Code でデバッグ

python のランタイムでデバッグする場合、以下のような注意書きがあったり、Visual Studio Code でリモートデバッグするときは ptvsd を使う等いろいろあったのでメモ.

SAM ローカルを使用してサーバーレスアプリケーションをローカルでテストする - AWS Lambda

Python で記述された関数のデバッグ

Node.js や Java とは異なり、Python では Lambda 関数コードでリモートデバッグを有効にする必要があります。Python ランタイム (2.7 または 3.6) のいずれかを使用する関数に対して (上述の --debug-port オプションまたは -d オプションを使用して) デバッグを有効にすると、SAM Local はそのポートを通じてホストマシンから Lambda コンテナへのマッピングを行います。リモートデバッグを有効にするには、remote-pdb などの Python パッケージを使用します。

SAM ローカルで Python 関数が動作するようにしておく.

適当なディレクトリを作成し、以下のような template.ymlproducts.py を保存.

  • template.yml
AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: My first serverless application(debug).

Resources:

  Products:
    Type: AWS::Serverless::Function
    Properties:
      Handler: products.lambda_handler
      Runtime: python3.6
      Events:
        ListProducts:
          Type: Api
          Properties:
            Path: /products
            Method: get
  • products.py
def lambda_handler(event, context):
    response = {
        "statusCode": 200,
        "headers": {
            "my_header": "my_value"
        },
        "body": event['queryStringParameters']['key1'] + ':test',
        "isBase64Encoded": False
    }
    return response

$ sam localt start-api を実行した後に、$ curl http://127.0.0.1:3000/products?key1=foo を実行. foo:test が返ってくることを確認する.

ptvsd をインストール

Visual Stduio Code + Python でリモートデバッグする場合は、ptvsd を利用することになっているようなのでインストールする.

なお、インストールにあたっては以下のような注意点がある.

  • 現時点で pip install ptvsd を実行すると 3.2.1 がインストールされるが、Visual Studio Code + Python では 3.0.0 までのプロトコルにしか対応していない.
  • AWS Lambda 用にサードパーティライブラリをインストール場合には、関数のソースと同じディレクトリに配置する.

これらを踏まえて、ptvsd は以下のようにインストールする.

$ pip install ptvsd==3.0.0 -t /path/to/project-dir

なお、環境によっては、エラーでインストールできないときがある. とりあえず以下のように --system を指定することで回避できることもある.

$ pip install ptvsd==3.0.0 -t /path/to/project-dir --system

参考:

ptvsd で接続待ちするコードを追加

template.yml に以下のように環境変数の定義を追加する.

AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: My first serverless application(debug).

Resources:

  Products:
    Type: AWS::Serverless::Function
    Properties:
      Handler: products.lambda_handler
      Runtime: python3.6
      Environment:
        Variables:
          PTVSD: "off"
      Events:
        ListProducts:
          Type: Api
          Properties:
            Path: /products
            Method: get

products.py に以下のようにコードを追加する. なお、インターフェースの指定は 127.0.0.1 ではなく 0.0.0.0 にする必要がある(らしい).

def lambda_handler(event, context):
    from os import environ
    if environ.get('PTVSD', '') == 'on':
        import ptvsd
        ptvsd.enable_attach(secret="my_secret", address=('0.0.0.0', 5959))
        ptvsd.wait_for_attach()

    response = {
        "statusCode": 200,
        "headers": {
            "my_header": "my_value"
        },
        "body": event['queryStringParameters']['key1'] + ':test',
        "isBase64Encoded": False
    }
    return response

Visual Studio Code に接続設定を追加

Visual Studio Code で関数のディレクトリをオープンした後に、デバッグビューへ切り替える. 歯車アイコンをクリックし launch.json が編集できるようになったら、以下のような記述を追加する. 設定のポイントとしては、「port を上記の接続待ちポートにあわせる」「remoteRoot/var/taskにする」.

{
    "name": "Attach (Remote SAM Debug)",
    "type": "python",
    "request": "attach",
    "localRoot": "${workspaceFolder}",
    "remoteRoot": "/var/task",
    "port": 5858,
    "secret": "my_secret",
     "host": "localhost"
},

デバッグ

SAM ローカルを以下のように(シェル変数 PTVSD-d オプション付き)で起動する.

$ PTVSDN=on sam-local start-api -d 5858

関数を以下のように起動する。なお、今回はデバッガが動作していることを確認するために key1 ではなく key2 を指定している.

$ curl http://127.0.0.1:3000/products?key2=foo

Visual Studio Code のデバッグビューで BREAKPOINTS セクションの「All Exceptions」をチェック、その後、上記で追加した接続設定でデバッグを開始する.

これで、key1 にアクセスしようとしてエラーになったところで停止している状態になるので、 event['queryStringParameters'] の内容等を確認してみる.

問題点

  • BREAKPOINT がうまく動作しない.

これは SAM ローカルとの組み合わせだけの問題ではないのだが、 (以前にも ntvsd を使ったときに BREAKPOINTS の指定が効いたり効かなかったり等があった). とりあえず、execption 補足はできるようなので、当面はその辺を利用することになるかも.

  • ptvsd 関連の設定やコードが残ってしまう.

まだ、デプロイパッケージの作成等は試していないので予想になってしまうが、おそらくは、 パッケージ化する(zip に固める)ときには ptvsd を削除するか除外する必要がある. また、ptvsd で接続待ちにするコードも記述されたままになるので、その辺の扱いはどのようにするのか (いまのところは環境変数で切り替えるようにしているが、それで良いのか?).

ptvsd の扱いについては、ptvsd インストール済のローカルイメージを作成し、 sam local start-api 開始時に --skip-pull-image を指定するという方法もありそうだが、それはそれでイメージのメンテ等の手間が増えそうなので、出来ることなら避けたい手順である.

その他

SAM ローカルを起動した環境と Docker ホストが異る構成になっている場合、 -d で指定したポートは Docker ホスト側にマッピングされることになる.

よって、SAM ローカルを起動した環境で Visual Studio Code を起動した場合は、 接続先の host の指定を Docker ホストにする(あるいはコンテナを直接指定してしまう)等、 構成にあわせて変更する必要がある.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment