Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions src/examples/awsbedrock_examples/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
from examples.awsbedrock_examples.converse import use_converse
from examples.awsbedrock_examples.converse import (
use_converse_stream,
use_converse,
use_invoke_model_anthropic,
use_invoke_model_cohere,
use_invoke_model_amazon,
)
from langtrace_python_sdk import langtrace, with_langtrace_root_span

langtrace.init()


class AWSBedrockRunner:
@with_langtrace_root_span("AWS_Bedrock")
def run(self):

use_converse_stream()
use_converse()
use_invoke_model_anthropic()
use_invoke_model_cohere()
use_invoke_model_amazon()
168 changes: 154 additions & 14 deletions src/examples/awsbedrock_examples/converse.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,174 @@
import os
import boto3
import json
from langtrace_python_sdk import langtrace
from dotenv import load_dotenv
import botocore

load_dotenv()
langtrace.init(write_spans_to_console=False)

brt = boto3.client("bedrock-runtime", region_name="us-east-1")
brc = boto3.client("bedrock", region_name="us-east-1")


def use_converse_stream():
model_id = "anthropic.claude-3-haiku-20240307-v1:0"
conversation = [
{
"role": "user",
"content": [{"text": "what is the capital of France?"}],
}
]

try:
response = brt.converse_stream(
modelId=model_id,
messages=conversation,
inferenceConfig={"maxTokens": 4096, "temperature": 0},
additionalModelRequestFields={"top_k": 250},
)
# response_text = response["output"]["message"]["content"][0]["text"]
print(response)

except Exception as e:
print(f"ERROR: Can't invoke '{model_id}'. Reason: {e}")
exit(1)

langtrace.init(api_key=os.environ["LANGTRACE_API_KEY"])

def use_converse():
model_id = "anthropic.claude-3-haiku-20240307-v1:0"
client = boto3.client(
"bedrock-runtime",
region_name="us-east-1",
aws_access_key_id=os.environ["AWS_ACCESS_KEY_ID"],
aws_secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"],
)
conversation = [
{
"role": "user",
"content": [{"text": "Write a story about a magic backpack."}],
"content": [{"text": "what is the capital of France?"}],
}
]

try:
response = client.converse(
response = brt.converse(
modelId=model_id,
messages=conversation,
inferenceConfig={"maxTokens":4096,"temperature":0},
additionalModelRequestFields={"top_k":250}
inferenceConfig={"maxTokens": 4096, "temperature": 0},
additionalModelRequestFields={"top_k": 250},
)
response_text = response["output"]["message"]["content"][0]["text"]
print(response_text)

except (Exception) as e:
except Exception as e:
print(f"ERROR: Can't invoke '{model_id}'. Reason: {e}")
exit(1)
exit(1)


def get_foundation_models():
for model in brc.list_foundation_models()["modelSummaries"]:
print(model["modelId"])


# Invoke Model API
# Amazon Titan Models
def use_invoke_model_titan(stream=False):
try:
prompt_data = "what's the capital of France?"
body = json.dumps(
{
"inputText": prompt_data,
"textGenerationConfig": {
"maxTokenCount": 1024,
"topP": 0.95,
"temperature": 0.2,
},
}
)
modelId = "amazon.titan-text-express-v1" # "amazon.titan-tg1-large"
accept = "application/json"
contentType = "application/json"

if stream:

response = brt.invoke_model_with_response_stream(
body=body, modelId=modelId, accept=accept, contentType=contentType
)
else:
response = brt.invoke_model(
body=body, modelId=modelId, accept=accept, contentType=contentType
)
response_body = json.loads(response.get("body").read())

except botocore.exceptions.ClientError as error:

if error.response["Error"]["Code"] == "AccessDeniedException":
print(
f"\x1b[41m{error.response['Error']['Message']}\
\nTo troubeshoot this issue please refer to the following resources.\
\nhttps://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_access-denied.html\
\nhttps://docs.aws.amazon.com/bedrock/latest/userguide/security-iam.html\x1b[0m\n"
)

else:
raise error


# Anthropic Models
def use_invoke_model_anthropic(stream=False):
body = json.dumps(
{
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 1024,
"temperature": 0.1,
"top_p": 0.9,
"messages": [{"role": "user", "content": "Hello, Claude"}],
}
)
modelId = "anthropic.claude-v2"
accept = "application/json"
contentType = "application/json"

if stream:
response = brt.invoke_model_with_response_stream(body=body, modelId=modelId)
stream_response = response.get("body")
if stream_response:
for event in stream_response:
chunk = event.get("chunk")
if chunk:
print(json.loads(chunk.get("bytes").decode()))

else:
response = brt.invoke_model(
body=body, modelId=modelId, accept=accept, contentType=contentType
)
response_body = json.loads(response.get("body").read())
# text
print(response_body.get("completion"))


def use_invoke_model_llama():
model_id = "meta.llama3-8b-instruct-v1:0"
prompt = "What is the capital of France?"
max_gen_len = 128
temperature = 0.1
top_p = 0.9

# Create request body.
body = json.dumps(
{
"prompt": prompt,
"max_gen_len": max_gen_len,
"temperature": temperature,
"top_p": top_p,
}
)
response = brt.invoke_model(body=body, modelId=model_id)

response_body = json.loads(response.get("body").read())

return response_body


# print(get_foundation_models())
def use_invoke_model_cohere():
model_id = "cohere.command-r-plus-v1"
prompt = "What is the capital of France?"
body = json.dumps({"prompt": prompt, "max_tokens": 1024, "temperature": 0.1})
response = brt.invoke_model(body=body, modelId=model_id)
response_body = json.loads(response.get("body").read())
print(response_body)
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from langtrace.trace_attributes import AWSBedrockMethods

APIS = {
"INVOKE_MODEL": {
"METHOD": "aws_bedrock.invoke_model",
"ENDPOINT": "/invoke-model",
},
"CONVERSE": {
"METHOD": AWSBedrockMethods.CONVERSE.value,
"ENDPOINT": "/converse",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import json
from wrapt import ObjectProxy


class StreamingWrapper(ObjectProxy):
def __init__(
self,
response,
stream_done_callback=None,
):
super().__init__(response)

self._stream_done_callback = stream_done_callback
self._accumulating_body = {}

def __iter__(self):
for event in self.__wrapped__:
self._process_event(event)
yield event

def _process_event(self, event):
chunk = event.get("chunk")
if not chunk:
return

decoded_chunk = json.loads(chunk.get("bytes").decode())
type = decoded_chunk.get("type")

if type == "message_start":
self._accumulating_body = decoded_chunk.get("message")
elif type == "content_block_start":
self._accumulating_body["content"].append(
decoded_chunk.get("content_block")
)
elif type == "content_block_delta":
self._accumulating_body["content"][-1]["text"] += decoded_chunk.get(
"delta"
).get("text")
elif type == "message_stop" and self._stream_done_callback:
self._accumulating_body["invocation_metrics"] = decoded_chunk.get(
"amazon-bedrock-invocationMetrics"
)
self._stream_done_callback(self._accumulating_body)
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,13 @@
from opentelemetry.trace import get_tracer
from wrapt import wrap_function_wrapper as _W

from langtrace_python_sdk.instrumentation.aws_bedrock.patch import (
converse, converse_stream
)
from langtrace_python_sdk.instrumentation.aws_bedrock.patch import patch_aws_bedrock

logging.basicConfig(level=logging.FATAL)

def _patch_client(client, version: str, tracer) -> None:

# Store original methods
original_converse = client.converse

# Replace with wrapped versions
client.converse = converse("aws_bedrock.converse", version, tracer)(original_converse)

class AWSBedrockInstrumentation(BaseInstrumentor):

def instrumentation_dependencies(self) -> Collection[str]:
return ["boto3 >= 1.35.31"]

Expand All @@ -46,13 +37,11 @@ def _instrument(self, **kwargs):
tracer = get_tracer(__name__, "", tracer_provider)
version = importlib.metadata.version("boto3")

def wrap_create_client(wrapped, instance, args, kwargs):
result = wrapped(*args, **kwargs)
if args and args[0] == 'bedrock-runtime':
_patch_client(result, version, tracer)
return result

_W("boto3", "client", wrap_create_client)
_W(
module="boto3",
name="client",
wrapper=patch_aws_bedrock(tracer, version),
)

def _uninstrument(self, **kwargs):
pass
pass
Loading
Loading