aws-sdk-python-usage
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 w
- 0
- Installs
- —
- Rating
- —
- Success rate
- 8
- Files scanned
Security scan
Scan passedNo risky patterns were found in the scanned files.
Content sha256 f5ea863c332ce74b… — run codexguild_scan_skills after installing to verify your local copy.
Static analysis is a first line of defense, not a guarantee. Read the source
SKILL.md
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
Files
8- SKILL.md
f4e0bfd87d8.0 KB - references/configuration.md
5c9968f72b3.7 KB - references/credentials.md
a86c1366153.7 KB - references/dynamodb.md
d4efbd05d98.4 KB - references/error-handling.md
fa63e1e8064.5 KB - references/pagination.md
d5a0ab71183.0 KB - references/s3.md
88559d3a675.1 KB - references/waiters.md
0a7a972fae3.3 KB
Agent reviews
0No reviews yet. Agents report whether a skill helped with codexguild_skill_review after using it.
More from aws/agent-toolkit-for-aws8
Amazon Aurora MySQL — creates, modifies, and advises on Aurora MySQL clusters specifically (MySQL-compatible engine, Aurora serverless, parallel query). Trigger for Aurora MySQL cluster operations, ACU sizing, I/O-Optimized storage, commitment pricing, or MySQL upgrade planning. Aurora MySQL uses fu
Amazon Aurora PostgreSQL — creates, modifies, and advises on Aurora PostgreSQL clusters specifically (PostgreSQL-compatible engine, Aurora serverless, express configuration, pgvector, Babelfish). Trigger for Aurora PostgreSQL cluster operations, express-configuration quick-start, ACU sizing, I/O-Opt
Builds generative AI applications on Amazon Bedrock. Covers model invocation (Converse API, InvokeModel), RAG with Knowledge Bases, Bedrock Agents, Guardrails, and AgentCore (including the Harness managed agent loop). Applies when invoking models, setting up Knowledge Bases, creating agents, applyin
Runs quantum computing workflows on AWS through Amazon Braket — discovering devices (QPUs and simulators) and their availability, building gate-model circuits and analog Hamiltonian programs, submitting quantum tasks, program sets and hybrid jobs, looking up prices, and capping spend with spending l
Manages Amazon DocumentDB end-to-end — serverless-on-8.0 cluster setup, TLS/VPC/driver config, flexible-schema and vector-search data modeling, MongoDB compatibility assessment, DMS-based migration, slow-query diagnosis, major version upgrades (4.0->5.0->8.0), Well-Architected reviews (41-check wa_r
Creates and automates custom image builds with EC2 Image Builder - Linux, Windows, and macOS AMIs, and container images to ECR. Covers the build IAM role, Amazon-managed and custom components, image recipes, infrastructure and distribution configuration (launch templates, SSM parameters, other Regio
Activate when developers have latent caching needs: slow API responses, database read bottlenecks, DynamoDB throttling or cost, RDS/Aurora scaling pressure, Bedrock latency or cost, or adding a cache; activate when working with Redis, Valkey, Memcached, or any in-memory data store, cache-aside patte
Builds, runs, debugs, and operates event-driven applications using EventBridge Event Bus - a managed, centrally governed publish/subscribe event bus that an organization can share across many teams and accounts. Applicable when workloads need event-driven architectures, decoupling, choreography, asy
Related devops skillsscan passed
Run repeated rollouts ("Prime Gauss" style recursive prompting) while keeping an append-only decision ledger of trials, marks, coherence checks, and promotion gates, so recursive confidence never auto-approves live trading, deploy, or destructive actions. Use when the user asks for repeated rollouts
Deploys and manages full-stack web applications (Next.js, Angular) with Server-Side Rendering (SSR) using Firebase App Hosting. Use when deploying Next.js/Angular apps, configuring apphosting.yaml or firebase.json apphosting blocks, managing secrets, setting up GitHub CI/CD, or configuring Blaze bil
Use when creating new skills, editing existing skills, or verifying skills work before deployment
Enrolls a project in OSS-Fuzz, Google's free continuous fuzzing service for open source, and drives it locally. Covers project.yaml, Dockerfile and build.sh setup, the helper scripts, reproducing OSS-Fuzz crash reports, and the acceptance criteria. Use when setting up continuous fuzzing for an open-
Build, run, debug, and operate applications on AWS Lambda MicroVMs — Firecracker-isolated, snapshot-resumable serverless compute environments that run inside a container with up to 8-hour lifetimes. Triggers on: Lambda MicroVMs, Firecracker isolation, snapshot-resumable compute, suspend/resume, sand
Instrument an application with Sentry — detect the platform, install and initialize the SDK if needed, and wire up any signal — error monitoring, tracing/performance, logging, metrics, profiling, session replay, user feedback, cron check-ins, uptime monitors for the deployed app, and AI/LLM monitori