Serverless Operations, inc

>_cd /blog/id_m6ql4bklh77u

title

AWS LambdaにおけるPythonを使った開発の基礎知識

summary

本記事ではAWS LambdaをPythonで開発する場合に必要となる基礎知識やツールを紹介しています。どのようなプログラミング言語であっても開発を進めていくために必要な基礎概念は大きく変わりませんが、ツールやそれぞれの細かい部分でのプラクティスは言語によって変わってきます。特に最近では生成AI関連の開発を行う場合にAWS LambdaをPythonで記述する機会が増えてきました。また、Pythonは初学者にとっては扱いやすい言語でもあり非常に人気が高いです。本記事ではローカル環境の構築やパッケージマネージャーの紹介、静的構文解析やユニットテストのためのツール、開発を行うための便利なツールキットなどについての紹介を行っています

開発環境のセットアップ

まずはローカル環境をセットアップするための方法としてPoetryというパッケージマネージャーを使う方法とVenv + Pipを使う方法を紹介します。どちらか一方を好みやチームの方針に合わせて選ぶとよいでしょう。

Poetryを使った環境構築

PoetryはPythonのパッケージマネージャーです。プロジェクトごとに必要なライブラリをインストールして依存関係を管理、更新を簡単に行うことが出来ます。Nodejsのnpm等と同じように専用のロックファイルを作成することで、バージョン管理ツール等で配布しても確実に同じバージョンかつ依存関係の保ったパッケージ群を構成することが出来ます。

Linux, macOS, Windows (WSL)環境の場合は以下のコマンドで公式のインストーラーからPoetryのインストールが可能です

$ curl -sSL https://install.python-poetry.org | python3 -

また、pipxを使用している場合は以下のコマンドでもインストールが可能です

$ pipx install poetry

まずは以下のコマンドでプロジェクトを作成します。

$ poetry new <project name>

プロジェクトを作成すると以下のようなディレクトリ構成が作成されます。python_lambda配下にこのプロジェクトのメインのソースコードは記述していき、それに対応するテストコードをtests配下においていきます。インストールしたライブラリ等はpyproject.tomlにて管理されます。このファイルはTOML (Tom's Obvious, Minimal Language) という形式で書かれています。TOMLは設定ファイルやデータのシリアライズ形式の一つです。主にシンプルで人間が読みやすく、かつ機械的に解析しやすいことを目指して設計されています。poetry.lock ファイルには、プロジェクトに必要なすべてのパッケージとその正確なバージョンが記録されています。これにより、異なる環境で同じ依存関係がインストールされ、予期せぬ問題を防ぐことができます。poetry.lock に記録されたバージョンを基に、他の開発者やCI/CD環境でも同じ依存関係がインストールされるので、環境間での一貫性が保たれます。

python_lambda
├── README.md
├── poetry.lock
├── pyproject.toml
├── python_lambda
│   └── __init__.py
└── tests
    └── __init__.py

poetry add コマンドを使うとPython プロジェクトに新しい依存パッケージを追加する事ができます。指定したパッケージをプロジェクトの依存関係にインストールし、pyproject.toml ファイルと poetry.lock ファイルを自動的に更新します。requestsライブラリをインストールする場合は以下のようにします。インストールと同時に、pyproject.toml ファイルの [tool.poetry.dependencies] セクションに追加されます。また、poetry.lock ファイルも更新されて、依存関係のバージョンが固定されます。

$ poetry add requests

開発環境専用の依存関係を追加するには、--dev フラグを使用します。このオプションは、ユニットテスト、リンティング、ドキュメント生成などに必要なツールをインストールする際に便利です。

$ poetry add --dev pytest

これにより、pytest が開発用の依存関係としてインストールされ、pyproject.toml ファイルの [tool.poetry.dev-dependencies] セクションに追加されます。以下が、requestspytestをインストールした状態のpyproject.tomlです。

[tool.poetry]
name = "python-lambda"
version = "0.1.0"
description = ""
authors = ["horike37 <horike@serverless.co.jp>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.9"
requests = "^2.32.3"

[tool.poetry.dev.dependencies]
pytest = "^8.3.2"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

Venvとpipを使った環境構築

VenvとはプロジェクトごとにPythonの環境を分離してくれるための仕組みです。これにより、pipでインストールされたライブラリはそのプロジェクトのみで使用できるようになります。これにより、開発者は異なるプロジェクト間での依存関係の競合を防ぎ、環境の一貫性を保つことができます。

プロジェクトのルートフォルダで以下のコマンドを実行することで専用の環境を作り出し有効化してくれます。

$ python3 -m venv venv
$ . venv/bin/activate

その後、requirements.txt をインストールするようにします。

$ pip3 install -r requirements.txt

パッケージマネージャーとは、そのアプリケーション用にインストールされた外部ライブラリを記録し、新しいライブラリのインストール・新しいバージョンへの更新・以前インストールしたライブラリの削除を容易に行えるようにするためのツールです。Pythonではpip というパッケージマネージャーがよく利用されます。

以下のコマンドで必要なライブラリをインストールします。

$ pip3 install boto3

そして一度インストールしたライブラリは以下のコマンドで表示できます。

$ pip3 freeze
agate==1.6.0
agate-dbf==0.2.0
agate-excel==0.2.1
agate-sql==0.5.2

そして、以下のように requirements.txt というファイルにインストール済みのライブラリを書き込みます。最終的にそれをGitにコミットすることで使用するライブラリとそのバージョンを管理します。

$ pip3 freeze > requirements.txt

他のチームメンバーは以下のコマンドでrequirements.txt に書かれたライブラリをローカル環境にインストールします。

$ pip3 install -r requirements.txt

ローカル開発の方法

ローカル開発ではSAM Localを使用することをお勧めします。AWSでクラウドネイティブ(サーバレス)な開発を行うために覚えておくべき開発のワークフローの記事の中で詳しく使用方法について述べていますので参照してみてください

Linterによる静的構文解析

ソースコードの静的構文解析は、開発において非常に重要な役割を果たします。誤った記法や不適切なコーディングスタイルを早期に検出することで、チーム全体で統一されたコード品質を保つことができ、後々のトラブルを未然に防ぐことができます。特に、大規模なプロジェクトや複数の開発者が関わるプロジェクトでは、コーディングルールに従った一貫性のあるコードを書くことが重要であり、静的構文解析はそのための強力な手段です。

静的構文解析ツールを導入することで、コードがデプロイされる前に潜在的なエラーや警告を検出し、修正することが可能になります。これにより、デプロイ後に予期せぬエラーが発生し、緊急対応を余儀なくされるリスクが大幅に低減されます。結果として、開発プロセス全体の効率が向上し、よりスムーズにプロジェクトを進めることができるのです。

Python+AWS Lambdaの開発においては、flake8 という静的構文解析ツールを使用することをお勧めします。flake8 は、Pythonの公式コーディングスタイルガイドである PEP 8 に準拠したコードの検査を行います。PEP 8 は、Pythonコードの読みやすさやメンテナンス性を高めるために提唱されたガイドラインであり、これに従うことで、コードベースの一貫性が保たれ、他の開発者がコードを理解しやすくなります。

ユニットテスト

Pythonでのユニットテストは、pytest というライブラリを活用することをお勧めします。Pythonの中では一番メジャーなテスト用のライブラリでしょう。pytest は、シンプルでありながら強力な機能を持ち、ユニットテストの記述から実行まで、Pythonでのテストプロセスを包括的にサポートしてくれるオールインワンのフレームワークです。

pytest の最大の魅力は、その使いやすさと柔軟性にあります。テストコードは非常に簡潔に書くことができ、わずかな記述で強力なテストを行うことが可能です。また、従来のPython標準ライブラリである unittest モジュールと互換性があり、既存のテストコードをそのまま pytest に移行することもできます。さらに、pytest はデフォルトで非常に分かりやすいエラーメッセージを提供し、どのテストが失敗したのかを一目で理解できるように工夫されています。

pytest は、シンプルなユニットテストだけでなく、複雑なテストシナリオにも対応しています。たとえば、テスト関数に複数のパラメータを渡して同じテストを異なる条件下で実行する「パラメトリックテスト」や、テストの前後に特定のセットアップやクリーンアップ処理を行う「フィクスチャ」の機能を利用することができます。これにより、再利用可能で効率的なテストコードを簡単に書くことができるようになります。

AWS Lambda Python Power Tools

AWS Lambda Python Power ToolsはPythonでのLambda開発で便利なトレーシングやデコレータ、ロギング、メトリクス、イベントハンドラーなどの機能を提供してくれるツールキットです。必ずインストールして開発を行うことをお勧めします。主に以下のような機能が提供されています。

ユーティリティ

説明

Tracing

Lambda関数ハンドラー、および同期・非同期関数をトレースするためのデコレータとユーティリティ

Logger

構造化ロギングを簡単にし、Lambdaコンテキストの重要な詳細情報で構造化ロギングを強化するデコレータ

Metrics

CloudWatch Embedded Metric Format (EMF) を使用して非同期に作成されたカスタムメトリクス

AppSync

Lambda Direct Resolver および Amplify GraphQL Transformer 関数用の AppSync イベントハンドラー

API Gateway, ALB, Lambda Function URL

プロキシ統合を使用して起動された Lambda 関数用の Amazon API Gateway REST/HTTP API および ALB イベントハンドラー、Lambda Function URL

Middleware factory

各 Lambda 呼び出しの前後にロジックを実行するための独自のミドルウェアを作成するデコレータファクトリー

Parameters

AWS Systems Manager Parameter Store、AWS Secrets Manager、または Amazon DynamoDB からパラメータ値を取得し、特定の時間キャッシュする

Batch processing

AWS SQS バッチ処理の部分的な失敗を処理する

Typing

IDEでの開発を迅速化するための静的型付けクラス

Validation

インバウンドイベントやレスポンスのための JSON Schema バリデーター

Event source data classes

一般的な Lambda イベントトリガーのスキーマを記述するデータクラス

Parser

Pydantic を使用したデータの解析と深いバリデーション

Idempotency

冪等な Lambda ハンドラー

Data Masking

機密データの削除や暗号化を簡単に行うための機能

Feature Flags

入力に応じて一つ以上のフィーチャーを有効にするかどうかを評価するシンプルなルールエンジン

Streaming

利用可能なメモリより大きなデータセットをストリーミングデータとしてストリーム処理

Poetryやpipを使ってインストールが可能ですが、SAM CLIを使うことで以下のようにサンプルコードとともにAWS Lambda Python Power Toolsを組み込んだプロジェクトが生成可能です。これにより、開発者はすぐにプロジェクトの実装を始めることができ、複雑なセットアップを行う必要がありません。また、SAM CLIのテンプレートを利用することで、ベストプラクティスに従ったLambda関数の構築が容易に行えるため、より効率的な開発プロセスが実現します。

$ sam init --app-template hello-world-powertools-python --name sam-app --package-type Zip --runtime python3.11 --no-tracing

すると以下のようなhello worldのサンプルと共にプロジェクトが展開されます。Rest APIでhello worldのメッセージを返すのみのソースコードです。こちらを元にしてAWS Lambda Python Power Toolsの使い方を学んでいくのが良いでしょう。

from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.utilities.typing import LambdaContext
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools import Logger
from aws_lambda_powertools import Tracer
from aws_lambda_powertools import Metrics
from aws_lambda_powertools.metrics import MetricUnit

app = APIGatewayRestResolver()
tracer = Tracer()
logger = Logger()
metrics = Metrics(namespace="Powertools")

@app.get("/hello")
@tracer.capture_method
def hello():
    # adding custom metrics
    # See: https://awslabs.github.io/aws-lambda-powertools-python/latest/core/metrics/
    metrics.add_metric(name="HelloWorldInvocations", unit=MetricUnit.Count, value=1)

    # structured log
    # See: https://awslabs.github.io/aws-lambda-powertools-python/latest/core/logger/
    logger.info("Hello world API - HTTP 200")
    return {"message": "hello world"}

# Enrich logging with contextual information from Lambda
@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST)
# Adding tracer
# See: https://awslabs.github.io/aws-lambda-powertools-python/latest/core/tracer/
@tracer.capture_lambda_handler
# ensures metrics are flushed upon request completion/failure and capturing ColdStart metric
@metrics.log_metrics(capture_cold_start_metric=True)
def lambda_handler(event: dict, context: LambdaContext) -> dict:
    return app.resolve(event, context)
Written by
CEO

堀家 隆宏

Takahiro Horike

  • Facebook->
  • X->
  • GitHub->

Share

Facebook->X->
Back
to list
<-