🐍aws-sdk-python-usage
- プラグイン
- aws-core
- ソース
- GitHub で見る ↗
説明
AWS SDK for Python(boto3/botocore)の開発パターンに関するスキル。 boto3 または botocore を使用して AWS サービスを操作する Python コードを記述する際は、**必ずこのスキルを使用してください。** 対象となる操作には以下が含まれます: - サービスクライアントまたはリソースの作成 - セッションおよびクレデンシャルの設定 - `ClientError` を使用したエラーハンドリング - ページネーターおよびウェイターの使用 - S3 ファイル転送および署名付き URL(presigned URLs) - DynamoDB テーブル操作 - boto3/botocore クライアントの各種設定 次のような場合に使用: Python コードが `boto3` または `botocore` をインポートしている場合、 あるいはユーザーが Python での AWS 操作について質問している場合。
原文を表示
AWS SDK for Python (boto3/botocore) development patterns. You MUST use this skill when writing Python code that uses AWS services via boto3 or botocore. This includes creating service clients or resources, configuring sessions and credentials, handling errors with ClientError, using paginators and waiters, S3 file transfers and presigned URLs, DynamoDB table operations, and any boto3/botocore client configuration. Use this skill whenever Python code imports boto3 or botocore, or when the user asks about AWS operations in Python.
ユースケース
- ✓boto3またはbotocoreをインポートするとき
- ✓AWSサービスを操作するPythonコードを記述するとき
- ✓サービスクライアントまたはリソースを作成するとき
- ✓ClientErrorでエラーハンドリングするとき
- ✓S3ファイル転送や署名付きURLを使用するとき
本文(日本語訳)
AWS SDK for Python (boto3)
boto3 はAWS向けの高レベルPython SDKです。低レベルSDKであるbotocore をラップし、 クライアント(低レベル、APIと1対1対応)とリソース(高レベル、オブジェクト指向) という2つの異なるインターフェースを提供します。どちらをいつ使うかを理解することが重要です。
クライアント vs リソース
クライアントはAWSサービスAPIに直接マッピングされます。すべてのサービスにクライアントが存在し、 レスポンスはプレーンなdictで返されます。
リソースは属性とアクションを持つオブジェクト指向インターフェースを提供します。 リソースが利用できるサービスは一部のみです(S3、DynamoDB、EC2、IAM、SQS、SNS、 CloudFormation、CloudWatch、Glacier)。リソースは型を自動マーシャリングします (特にDynamoDBで有効です)。
import boto3
# クライアント - 低レベル、全サービス対応
s3_client = boto3.client("s3")
response = s3_client.list_buckets()
buckets = response["Buckets"] # プレーンなdict
# リソース - 高レベル、一部サービスのみ
s3_resource = boto3.resource("s3")
for bucket in s3_resource.buckets.all():
print(bucket.name) # 属性アクセス(dictキーではない)
次のような場合に使用:
- クライアント → 完全なAPIカバレッジが必要な場合、またはリソースインターフェースが存在しないサービスを使用する場合
- リソース → リソースが存在し、コードをシンプルにできる場合(特にDynamoDBとS3)
セッションとクライアントの作成
import boto3
# デフォルトセッションは暗黙的に作成される
client = boto3.client("s3")
resource = boto3.resource("dynamodb")
# 明示的なセッション - クライアントの作成方法をカスタマイズしたい場合や
# 特定のプロファイルを使用したい場合などに利用する
session = boto3.Session(
profile_name="my-profile",
region_name="us-west-2",
)
client = session.client("s3")
クライアントをループ内で作成しないでください。単一のクライアントインスタンスを再利用してください。 クライアントはスレッドセーフであり、インスタンス化後はスレッド間で共有できます。
APIコールの実行
# クライアント - パラメータをキーワード引数で渡し、dictを受け取る
response = client.get_object(Bucket="my-bucket", Key="my-key")
data = response["Body"].read()
# リソース - オブジェクトのメソッドと属性を使用する
obj = s3_resource.Object("my-bucket", "my-key")
response = obj.get()
data = response["Body"].read()
パラメータ名はAWS APIの正確なケーシング(通常はPascalCase、snake_caseではない)に合わせてください。
エラーハンドリング
例外をキャッチするのは、フォールバック値の返却・リトライ・別のコードパスへの移行など、 具体的な対処ができる場合に限ってください。 例外をキャッチして単に出力し、握りつぶすだけの処理は誤りです。 それは実際のエラーを隠蔽し、呼び出し元が適切に対応する機会を奪います。 デフォルトでは例外を伝播させてください。
キャッチする場合は、文字列コードのマッチングによるジェネリックな ClientError ではなく、
client.exceptions 属性を通じた型付き例外を優先してください:
lambda_client = boto3.client("lambda")
def get_function_config(name: str) -> dict | None:
"""関数設定を返す。存在しない場合はNoneを返す。"""
try:
return lambda_client.get_function_configuration(FunctionName=name)
except lambda_client.exceptions.ResourceNotFoundException:
return None # 対処可能: 関数が存在しない場合をNoneに変換する
# それ以外はすべて伝播させる - 呼び出し元またはmain()が処理する
ジェネリックな ClientError は、ビジネスロジック関数内ではなく、
トップレベルのエラーハンドラーでのキャッチオール用途にのみ使用してください。
ClientError はboto3ではなくbotocoreに含まれます:
from botocore.exceptions import ClientError
def main() -> int:
try:
result = do_the_work()
print(result)
return 0
except ClientError as e:
print(f"Error: {e}", file=sys.stderr)
return 1
エラー階層の全体像およびbotocore例外の詳細については、references/error-handling.md を参照してください。
スクリプト構成
boto3 または botocore を使用するスクリプトの作成を求められた場合、
if __name__ == "__main__" は単一の関数呼び出しのみにしてください。
引数パース・エラーの表示・終了コードの処理は main() に集約し、
ビジネスロジック関数に散在させないでください:
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("bucket")
args = parser.parse_args()
try:
do_the_work(args.bucket)
return 0
except ClientError as e:
print(f"Error: {e}", file=sys.stderr)
return 1
if __name__ == "__main__":
sys.exit(main())
ビジネスロジック関数から sys.exit() を呼び出してはいけません。
それにより関数のテストが不可能になり、ライブラリとしての再利用もできなくなります。
代わりに例外を送出するかエラー値を返し、表示方法の決定は main() に委ねてください。
ページネーション
NextToken を使った手動ループは使用せず、ページネーターを使用してください。
特定のフィールドのみ必要な場合は、JMESPath式を使った .search() でページをまたいで
データを抽出・フラット化できます:
paginator = iam.get_paginator("list_users")
for name in paginator.paginate().search("Users[].UserName"):
print(name)
# フィルタリングと射影
for arn in paginator.paginate().search("Users[?Path == '/admin/'][].Arn"):
print(arn)
アイテムごとにレスポンスオブジェクト全体が必要な場合や、ページ単位の制御が必要な場合 (ページ数のカウント、ページ単位のバッチ処理など)は、ページを直接イテレートしてください:
for page in paginator.paginate():
for user in page.get("Users", []):
process(user)
ページネーションの詳細については、references/pagination.md を参照してください。
Waiter
リソースが目的の状態に達するまで待機する場合:
waiter = client.get_waiter("bucket_exists")
waiter.wait(
Bucket="my-bucket",
WaiterConfig={"Delay": 5, "MaxAttempts": 20},
)
Waiterの詳細については、references/waiters.md を参照してください。
クライアント設定
リトライ・タイムアウト・コネクションプール設定などには botocore.config.Config を使用してください:
from botocore.config import Config
config = Config(
retries={"total_max_attempts": 2, "mode": "adaptive"},
connect_timeout=5,
read_timeout=10,
max_pool_connections=50,
)
client = boto3.client("s3", config=config)
クライアントのカスタム設定を作成する場合は、references/configuration.md を参照してください。
ロギング
boto3とbotocoreはどちらも標準ライブラリの logging モジュールを使用します。
標準の logging APIを通じて設定することも、便宜上boto3とbotocoreが提供する
ヘルパーを使用することもできます:
# 簡易: botocoreのワイヤーレベルの詳細をすべてstderrに出力
boto3.set_stream_logger("") # ルートロガー -- すべてを出力
boto3.set_stream_logger("botocore") # botocoreのみ
# botocore: すべてのbotocore詳細をログ出力
import logging
from botocore.session import Session
session = Session()
session.set_stream_logger('botocore', logging.DEBUG)
# または: ファイルへのロギングを設定する
session.set_file_logger(logging.DEBUG, '/tmp/botocore.log')
set_stream_logger(name, level=logging.DEBUG) は指定した名前のロガーに
StreamHandler を追加します。これはSDKからリクエスト/レスポンスのデバッグ出力を
得るための慣用的な方法です。
よくある問題
問題: ClientErrorのインポート場所
誤り: from boto3.exceptions import ClientError
正しい: from botocore.exceptions import ClientError
サービス固有のカスタマイズ
以下のサービスを使用するPythonコードを書く場合は、ベストプラクティスおよびカスタム高レベルAPIのために、 必ず以下の追加リファレンスファイルを読み込んでください:
- S3 - 必ず
references/s3.mdを読み込むこと - DynamoDB - 必ず
references/dynamodb.mdを読み込むこと
リファレンス
- クライアント設定(リトライ・タイムアウト・エンドポイント):
references/configuration.md - クレデンシャルとセッション:
references/credentials.md - エラーハンドリングパターン:
references/error-handling.md - ページネーション:
references/pagination.md - Waiter:
references/waiters.md - S3転送と署名付きURL:
references/s3.md - DynamoDB操作:
references/dynamodb.md
原文(English)を表示
Do not use emojis in any code, comments, or output when this skill is active.
AWS SDK for Python (boto3)
boto3 is the high-level Python SDK for AWS. It wraps botocore (the low-level SDK) and provides two distinct interfaces: clients (low-level, 1:1 API mapping) and resources (high-level, object-oriented). Understanding which to use and when is essential.
Client vs Resource
Clients map directly to AWS service APIs. Every service has a client. Responses are plain dicts.
Resources provide an object-oriented interface with attributes and actions. Only some services have resources (S3, DynamoDB, EC2, IAM, SQS, SNS, CloudFormation, CloudWatch, Glacier). Resources auto-marshal types (especially useful for DynamoDB).
import boto3
# Client - low-level, all services
s3_client = boto3.client("s3")
response = s3_client.list_buckets()
buckets = response["Buckets"] # plain dicts
# Resource - high-level, select services
s3_resource = boto3.resource("s3")
for bucket in s3_resource.buckets.all():
print(bucket.name) # attribute access, not dict keys
Use clients when you need full API coverage or the service has no resource interface. Use resources when they exist and simplify your code (especially DynamoDB and S3).
Session and Client Creation
import boto3
# Default session implicitly created
client = boto3.client("s3")
resource = boto3.resource("dynamodb")
# Explicit session use when you need to customize how
# clients are created, use an explicit profile, etc.
session = boto3.Session(
profile_name="my-profile",
region_name="us-west-2",
)
client = session.client("s3")
Do not create clients inside loops - reuse a single client instance. Clients are thread safe and can be shared across threads once they're instantiated.
Making API Calls
# Client - pass parameters as keyword arguments, get dicts back
response = client.get_object(Bucket="my-bucket", Key="my-key")
data = response["Body"].read()
# Resource - use object methods and attributes
obj = s3_resource.Object("my-bucket", "my-key")
response = obj.get()
data = response["Body"].read()
Parameter names match the exact casing of the AWS API, which is typically PascalCase, not snake_case.
Error Handling
Only catch exceptions when you have something actionable to do - return a fallback value, retry, take a different code path. Catching an exception just to print it and swallow it is wrong: it hides the real error and prevents callers from reacting. Let exceptions propagate by default.
When you do catch, prefer typed exceptions on the client over generic
ClientError with string code matching through the client.exceptions
attribute:
lambda_client = boto3.client("lambda")
def get_function_config(name: str) -> dict | None:
"""Return function configuration, or None if it doesn't exist."""
try:
return lambda_client.get_function_configuration(FunctionName=name)
except lambda_client.exceptions.ResourceNotFoundException:
return None # actionable: convert missing function to None
# Everything else propagates - caller or main() handles it
Use generic ClientError only as a catch-all in a top-level error handler, not
in business logic functions. It lives in botocore, not boto3:
from botocore.exceptions import ClientError
def main() -> int:
try:
result = do_the_work()
print(result)
return 0
except ClientError as e:
print(f"Error: {e}", file=sys.stderr)
return 1
For the full error hierarchy and botocore exceptions, see references/error-handling.md.
Script Structure
When asked to write a script that uses boto3 or botocore, keep if __name__ == "__main__" to a single function call. Argument parsing, error presentation,
and exit codes belong in main(), not scattered across business logic
functions:
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("bucket")
args = parser.parse_args()
try:
do_the_work(args.bucket)
return 0
except ClientError as e:
print(f"Error: {e}", file=sys.stderr)
return 1
if __name__ == "__main__":
sys.exit(main())
Never call sys.exit() from a business logic function -- it makes the function
untestable and unusable as a library. Raise an exception or return an error
value instead, and let main() decide how to present it.
Pagination
Never manually loop with NextToken -- use paginators. When you only need
specific fields, use .search() with a JMESPath expression to extract and
flatten across pages:
paginator = iam.get_paginator("list_users")
for name in paginator.paginate().search("Users[].UserName"):
print(name)
# Filter and project
for arn in paginator.paginate().search("Users[?Path == '/admin/'][].Arn"):
print(arn)
When you need the full response object per item, or need per-page control (e.g. counting pages, batching by page), iterate pages directly:
for page in paginator.paginate():
for user in page.get("Users", []):
process(user)
For more details on pagination, see: references/pagination.md.
Waiters
Wait for a resource to reach a desired state:
waiter = client.get_waiter("bucket_exists")
waiter.wait(
Bucket="my-bucket",
WaiterConfig={"Delay": 5, "MaxAttempts": 20},
)
For more details on waiters, see references/waiters.md.
Client Configuration
Use botocore.config.Config for retries, timeouts, and connection pool
settings, etc.:
from botocore.config import Config
config = Config(
retries={"total_max_attempts": 2, "mode": "adaptive"},
connect_timeout=5,
read_timeout=10,
max_pool_connections=50,
)
client = boto3.client("s3", config=config)
When creating custom configuration for a client, see references/configuration.md.
Logging
Both boto3 and botocore use the standard library logging module. You can
configure logging through the standard logging APIs, or you can use
helpers provided by boto3 and botocore for convenience:
# Quick: log all botocore wire-level details to stderr
boto3.set_stream_logger("") # root logger -- everything
boto3.set_stream_logger("botocore") # just botocore
# Botocore, log all botocore details
import logging
from botocore.session import Session
session = Session()
session.set_stream_logger('botocore', logging.DEBUG)
# OR: Configure logging to a file.
session.set_file_logger(logging.DEBUG, '/tmp/botocore.log')
set_stream_logger(name, level=logging.DEBUG) adds a
StreamHandler to the named logger. This is the idiomatic way to get
request/response debug output from the SDK.
Common Issues
Issue: ClientError import location
Wrong: from boto3.exceptions import ClientError
Right: from botocore.exceptions import ClientError
Service specific customizations
When writing any Python code that uses the following services, you MUST load these additional reference files for best practices and custom high level APIs:
- S3 - you MUST load
references/s3.md. - Dynamodb - you MUST load
references/dynamodb.md.
References
- Client configuration (retries, timeouts, endpoints):
references/configuration.md - Credentials and sessions:
references/credentials.md - Error handling patterns:
references/error-handling.md - Pagination:
references/pagination.md - Waiters:
references/waiters.md - S3 transfers and presigned URLs:
references/s3.md - DynamoDB operations:
references/dynamodb.md
原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。