aws-sdk-python-usage

작성자: aws

AWS SDK for Python(boto3/botocore) 개발 패턴. boto3 또는 botocore를 통해 AWS 서비스를 사용하는 Python 코드를 작성할 때 반드시 이 스킬을 사용해야 합니다. 이…

npx skills add https://github.com/aws/agent-toolkit-for-aws --skill aws-sdk-python-usage

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

aws의 다른 스킬

analyzing-release-readiness
aws
GitHub PR, GitLab MR 또는 로컬 브랜치에서 병합 전 릴리스 준비 검토를 트리거합니다. 사용자가 코드 변경 사항의 위험성, 정확성 등을 분석하려 할 때 사용합니다.
scanning-with-aws-security-agent
aws
작업 공간에서 AWS Security Agent 스캔 실행 — 소스를 AWS에 업로드하고, 관리형 Security Agent 서비스로 스캔한 후, 순위가 매겨진 검증된 결과를 반환합니다…
coordinating-multi-space-devops-agent
aws
하나의 Claude Code 세션에서 여러 AgentSpaces에 걸쳐 AWS DevOps Agent를 조정하세요 — 질문을 올바른 공간(프로덕션 vs 스테이징 vs 지식)으로 라우팅하고,…
aws-security
aws
AWS 보안 서비스 및 워크플로우를 다룹니다 — Security Hub V2 (OCSF) findings, 커넥터, 애그리게이터, 자동화 규칙, 보안 상태 요약 등…
querying-aws-sagemaker-catalog
aws
SageMaker Catalog 자산 메타데이터 테이블에서 SQL 분석을 실행하며, S3 Tables에서 Apache Iceberg로 내보낸 데이터를 대상으로 합니다. 거버넌스 쿼리, 자산 성장 추적 등을 다룹니다.
agents-connect
aws
에이전트를 Gateway를 통해 외부 API, 도구 또는 서비스에 연결하거나 Cedar 정책으로 도구 접근을 제한할 때 사용합니다. 게이트웨이 설정, 대상...
aurora-dsql
aws
Aurora DSQL 클러스터를 프로비저닝하고 관리하며, psql 또는 DSQL 커넥터를 통해 연결하고, 스키마를 관리하고, 쿼리를 실행하고, MySQL에서 마이그레이션하고, 쿼리 계획을 진단합니다.
transitgateway
aws
AWS Transit Gateway를 구성합니다: 허브를 생성하고 VPC를 연결하며, 라우팅 테이블로 트래픽을 분리하고, 허브를 통해 이그레스 및 검사를 중앙화합니다…