Scoping
Create scoped views of secrets with prefix stripping.
The scope() method creates a new Secrets object containing only keys that start with a specific prefix, with that prefix removed from the key names.
Basic Usage#
secrets = redenv.load()
# Your secrets:
# AWS_ACCESS_KEY=AKIA...
# AWS_SECRET_KEY=wJalr...
# AWS_REGION=us-east-1
# DATABASE_URL=postgres://...
aws = secrets.scope("AWS_")
# {"ACCESS_KEY": "AKIA...", "SECRET_KEY": "wJalr...", "REGION": "us-east-1"}
print(aws["ACCESS_KEY"]) # "AKIA..."
print(aws["REGION"]) # "us-east-1"Why Scope?#
Scoping is useful for:
- Modular Configuration - Pass only relevant secrets to modules
- Clean Interfaces - Avoid prefix repetition in code
- Library Integration - Match expected configuration shapes
Without Scoping#
import boto3
s3_client = boto3.client(
"s3",
region_name=secrets["AWS_REGION"],
aws_access_key_id=secrets["AWS_ACCESS_KEY"],
aws_secret_access_key=secrets["AWS_SECRET_KEY"],
)With Scoping#
import boto3
aws = secrets.scope("AWS_")
s3_client = boto3.client(
"s3",
region_name=aws["REGION"],
aws_access_key_id=aws["ACCESS_KEY"],
aws_secret_access_key=aws["SECRET_KEY"],
)Practical Examples#
AWS SDK Configuration#
import boto3
secrets = redenv.load()
aws = secrets.scope("AWS_")
s3 = boto3.client(
"s3",
region_name=aws["REGION"],
aws_access_key_id=aws["ACCESS_KEY"],
aws_secret_access_key=aws["SECRET_KEY"],
)Database Configuration#
secrets = redenv.load()
# Secrets: DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME
db = secrets.scope("DB_")
connection = create_connection(
host=db["HOST"],
port=db.get("PORT", 5432, cast=int),
user=db["USER"],
password=db["PASSWORD"],
database=db["NAME"],
)Multi-Service Configuration#
secrets = redenv.load()
# Stripe configuration
stripe_config = secrets.scope("STRIPE_")
stripe.api_key = stripe_config["SECRET_KEY"]
# SendGrid configuration
sendgrid_config = secrets.scope("SENDGRID_")
sg = sendgrid.SendGridAPIClient(sendgrid_config["API_KEY"])
# Twilio configuration
twilio_config = secrets.scope("TWILIO_")
twilio_client = Client(twilio_config["SID"], twilio_config["AUTH_TOKEN"])Chaining with Other Methods#
Scoped secrets retain all Secrets capabilities:
secrets = redenv.load()
aws = secrets.scope("AWS_")
# Type casting works
timeout = aws.get("TIMEOUT", 5000, cast=int)
# Validation works
aws.require("ACCESS_KEY", "SECRET_KEY")
# Iteration works
for key, value in aws.items():
print(f"{key}: {value}")Nested Scoping#
You can scope multiple times:
secrets = redenv.load()
# Secrets:
# AWS_S3_BUCKET=my-bucket
# AWS_S3_REGION=us-east-1
# AWS_SQS_QUEUE=my-queue
aws = secrets.scope("AWS_")
s3 = aws.scope("S3_")
print(s3["BUCKET"]) # "my-bucket"
print(s3["REGION"]) # "us-east-1"With Validation#
Validate before scoping to ensure all required secrets exist:
secrets = redenv.load()
# Validate full paths first
secrets.require("AWS_ACCESS_KEY", "AWS_SECRET_KEY", "AWS_REGION")
# Then scope for cleaner access
aws = secrets.scope("AWS_")Or validate within the scoped context:
aws = secrets.scope("AWS_")
aws.require("ACCESS_KEY", "SECRET_KEY", "REGION")