AWS Bedrock Integration Guide (for repos with similar structure)
This guide shows what to change when moving from an OpenAI-style service to AWS Bedrock in a repo structured like:
asr_app/core/security.pyasr_app/services/openai_assessment_service.py
1) Environment and settings changes
.env additions
AWS_ACCESS_KEY_ID=your_access_key_id
AWS_SECRET_ACCESS_KEY=your_secret_access_key
AWS_REGION=ap-south-1
BEDROCK_MODEL_ID=anthropic.claude-3-haiku-20240307-v1:0
# Optional only if your org uses bearer-token based gateway
AWS_BEARER_TOKEN_BEDROCK=your_bearer_token
BEDROCK_RUNTIME_ENDPOINT=https://bedrock-runtime.ap-south-1.amazonaws.com
asr_app/core/security.py additions
class Settings(BaseSettings):
...
AWS_ACCESS_KEY_ID: str
AWS_SECRET_ACCESS_KEY: str
AWS_REGION: str
AWS_BEARER_TOKEN_BEDROCK: str
BEDROCK_RUNTIME_ENDPOINT: Optional[str] = None
BEDROCK_MODEL_ID: Optional[str] = None
If you want IAM-only auth (recommended), make bearer token optional:
AWS_BEARER_TOKEN_BEDROCK: Optional[str] = None
2) Service-layer changes
Use Bedrock runtime endpoint and model id:
import os
import requests
AWS_REGION = os.getenv("AWS_REGION", "ap-south-1")
MODEL_ID = os.getenv("BEDROCK_MODEL_ID", "anthropic.claude-3-haiku-20240307-v1:0")
BEARER_TOKEN = os.getenv("AWS_BEARER_TOKEN_BEDROCK")
BEDROCK_ENDPOINT = (
f"https://bedrock-runtime.{AWS_REGION}.amazonaws.com/model/{MODEL_ID}/invoke"
)
Claude Messages request body for Bedrock:
body = {
"anthropic_version": "bedrock-2023-05-31",
"messages": [
{
"role": "user",
"content": [{"type": "text", "text": full_prompt}],
}
],
"max_tokens": 600,
"temperature": 0.7,
}
API call (your current bearer-token style):
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {BEARER_TOKEN}",
}
response = requests.post(
BEDROCK_ENDPOINT,
headers=headers,
json=body,
timeout=30,
)
response.raise_for_status()
response_body = response.json()
content = response_body["content"][0]["text"]
3) Recommended production auth update (IAM SigV4)
If this is a standard AWS setup, prefer boto3 instead of raw requests + bearer token:
import boto3
import json
import os
AWS_REGION = os.getenv("AWS_REGION", "ap-south-1")
MODEL_ID = os.getenv("BEDROCK_MODEL_ID", "anthropic.claude-3-haiku-20240307-v1:0")
client = boto3.client("bedrock-runtime", region_name=AWS_REGION)
payload = {
"anthropic_version": "bedrock-2023-05-31",
"messages": [{"role": "user", "content": [{"type": "text", "text": full_prompt}]}],
"max_tokens": 600,
"temperature": 0.7,
}
resp = client.invoke_model(
modelId=MODEL_ID,
body=json.dumps(payload),
contentType="application/json",
accept="application/json",
)
result = json.loads(resp["body"].read())
content = result["content"][0]["text"]
4) OpenAI-to-Bedrock mapping checklist
- Replace OpenAI client initialization with Bedrock runtime setup.
- Replace OpenAI message schema with Bedrock Claude schema (
anthropic_version+messages). - Replace OpenAI response parsing with Bedrock parsing (
result["content"][0]["text"]). - Add Bedrock env vars to
.envand settings model. - Verify timeout and error handling (
requests.exceptions.RequestExceptionorbotocore.exceptions.ClientError). - Keep existing business prompt logic unchanged to reduce regression risk.
5) Drop-in function template
def generate_practice_content_by_bedrock(level: str, language: str, wrong_words: list) -> str:
try:
# 1) validate level and build prompt
# 2) call Bedrock
# 3) parse response content[0].text
# 4) clean output and return
return cleaned_text
except Exception as e:
return f"Error: {e}"
6) Validation steps after migration
- Run one request for each level:
word,sentence,paragraph,story. - Run with and without
wrong_words. - Confirm output parsing is stable and no extra metadata leaks to users.
- Confirm env loading works in local, staging, and production.
- Confirm the selected model is enabled in your AWS account/region.