Spaces:
Running
Running
Initial commit
Browse files- .DS_Store +0 -0
- __pycache__/bedrock_client.cpython-310.pyc +0 -0
- app.py +42 -0
- bedrock_client.py +25 -0
- bedrock_test.py +208 -0
- bedrock_test_Pixtral.py +58 -0
- requirements.txt +3 -0
.DS_Store
ADDED
Binary file (6.15 kB). View file
|
|
__pycache__/bedrock_client.cpython-310.pyc
ADDED
Binary file (898 Bytes). View file
|
|
app.py
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import os
|
3 |
+
from bedrock_client import get_anthropic_client, claude_stream_response
|
4 |
+
|
5 |
+
# Create Claude client via the official SDK
|
6 |
+
client = get_anthropic_client()
|
7 |
+
|
8 |
+
# Streaming chat handler
|
9 |
+
async def chat(user_message, history):
|
10 |
+
messages = history.copy()
|
11 |
+
messages.append({"role": "user", "content": user_message})
|
12 |
+
|
13 |
+
full_response = ""
|
14 |
+
|
15 |
+
def run_generator():
|
16 |
+
for chunk in claude_stream_response(messages, client):
|
17 |
+
yield chunk
|
18 |
+
|
19 |
+
for chunk in run_generator():
|
20 |
+
full_response += chunk
|
21 |
+
yield messages + [{"role": "assistant", "content": full_response}]
|
22 |
+
|
23 |
+
# Append full assistant response to history
|
24 |
+
messages.append({"role": "assistant", "content": full_response})
|
25 |
+
yield messages
|
26 |
+
|
27 |
+
# Gradio UI
|
28 |
+
with gr.Blocks() as demo:
|
29 |
+
gr.Markdown("# π€ Claude v2.1 Chatbot via Amazon Bedrock (`anthropic[bedrock]`)")
|
30 |
+
chatbot = gr.Chatbot(label="Claude v2.1", type="messages")
|
31 |
+
msg = gr.Textbox(placeholder="Ask Claude anything...", show_label=False)
|
32 |
+
state = gr.State([]) # chat history
|
33 |
+
clear = gr.Button("π§Ή Clear Chat")
|
34 |
+
|
35 |
+
def clear_chat():
|
36 |
+
return [], []
|
37 |
+
|
38 |
+
msg.submit(chat, [msg, state], chatbot, queue=True)
|
39 |
+
msg.submit(lambda: "", None, msg) # clear input
|
40 |
+
clear.click(clear_chat, None, [chatbot, state])
|
41 |
+
|
42 |
+
demo.queue().launch()
|
bedrock_client.py
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from anthropic import AnthropicBedrock
|
2 |
+
import os
|
3 |
+
|
4 |
+
def get_anthropic_client():
|
5 |
+
return AnthropicBedrock(
|
6 |
+
aws_access_key=os.environ["AWS_ACCESS_KEY_ID"],
|
7 |
+
aws_secret_key=os.environ["AWS_SECRET_ACCESS_KEY"],
|
8 |
+
aws_region=os.environ.get("AWS_DEFAULT_REGION", "us-east-1")
|
9 |
+
)
|
10 |
+
|
11 |
+
def claude_stream_response(messages, client):
|
12 |
+
stream = client.messages.create(
|
13 |
+
model="anthropic.claude-v2:1",
|
14 |
+
max_tokens=1024,
|
15 |
+
temperature=0.7,
|
16 |
+
messages=messages,
|
17 |
+
stream=True
|
18 |
+
)
|
19 |
+
|
20 |
+
for event in stream:
|
21 |
+
# Only yield parts that have actual text deltas
|
22 |
+
if event.type == "content_block_delta":
|
23 |
+
text = getattr(event.delta, "text", None)
|
24 |
+
if text:
|
25 |
+
yield text
|
bedrock_test.py
ADDED
@@ -0,0 +1,208 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
|
3 |
+
|
4 |
+
#%%
|
5 |
+
import boto3
|
6 |
+
import json
|
7 |
+
import logging
|
8 |
+
aws_access_key_id='AKIA2UC26WDCAFOF7X64'
|
9 |
+
aws_secret_access_key='4/EHQ3i2ci1seDA6OtxV6a4zaVz1W2uSZSrjjlFl'
|
10 |
+
aws_region = "eu-central-1"
|
11 |
+
#%%
|
12 |
+
from anthropic import AnthropicBedrock
|
13 |
+
|
14 |
+
client = AnthropicBedrock(
|
15 |
+
# Authenticate by either providing the keys below or use the default AWS credential providers, such as
|
16 |
+
# using ~/.aws/credentials or the "AWS_SECRET_ACCESS_KEY" and "AWS_ACCESS_KEY_ID" environment variables.
|
17 |
+
aws_access_key=aws_access_key_id,
|
18 |
+
aws_secret_key=aws_secret_access_key,
|
19 |
+
# Temporary credentials can be used with aws_session_token.
|
20 |
+
# Read more at https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html.
|
21 |
+
aws_session_token=None,
|
22 |
+
# aws_region changes the aws region to which the request is made. By default, we read AWS_REGION,
|
23 |
+
# and if that's not present, we default to us-east-1. Note that we do not read ~/.aws/config for the region.
|
24 |
+
aws_region=aws_region,
|
25 |
+
)
|
26 |
+
modelid='anthropic.claude-v2:1'
|
27 |
+
message = client.messages.create(
|
28 |
+
model=modelid,
|
29 |
+
max_tokens=256,
|
30 |
+
messages=[{"role": "user", "content": "Hello, world"}]
|
31 |
+
)
|
32 |
+
print(message.content)
|
33 |
+
#%%
|
34 |
+
|
35 |
+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
36 |
+
# SPDX-License-Identifier: Apache-2.0
|
37 |
+
"""
|
38 |
+
Shows how to generate a message with Anthropic Claude (on demand).
|
39 |
+
"""
|
40 |
+
import boto3
|
41 |
+
import json
|
42 |
+
import logging
|
43 |
+
|
44 |
+
from botocore.exceptions import ClientError
|
45 |
+
|
46 |
+
|
47 |
+
logger = logging.getLogger(__name__)
|
48 |
+
logging.basicConfig(level=logging.INFO)
|
49 |
+
|
50 |
+
def generate_message(bedrock_runtime, model_id, system_prompt, messages, max_tokens):
|
51 |
+
|
52 |
+
body=json.dumps(
|
53 |
+
{
|
54 |
+
"anthropic_version": "bedrock-2023-05-31",
|
55 |
+
"max_tokens": max_tokens,
|
56 |
+
"system": system_prompt,
|
57 |
+
"messages": messages
|
58 |
+
}
|
59 |
+
)
|
60 |
+
|
61 |
+
|
62 |
+
response = bedrock_runtime.invoke_model(body=body, modelId=model_id)
|
63 |
+
response_body = json.loads(response.get('body').read())
|
64 |
+
|
65 |
+
return response_body
|
66 |
+
|
67 |
+
def main():
|
68 |
+
"""
|
69 |
+
Entrypoint for Anthropic Claude message example.
|
70 |
+
"""
|
71 |
+
|
72 |
+
try:
|
73 |
+
# Define your credentials here (temporary for dev/testing only)
|
74 |
+
|
75 |
+
aws_region = "eu-central-1" # or the correct region
|
76 |
+
|
77 |
+
# Use boto3 session to inject credentials
|
78 |
+
session = boto3.Session(
|
79 |
+
aws_access_key_id=aws_access_key_id,
|
80 |
+
aws_secret_access_key=aws_secret_access_key,
|
81 |
+
region_name=aws_region
|
82 |
+
)
|
83 |
+
|
84 |
+
bedrock_runtime = session.client(service_name='bedrock-runtime')
|
85 |
+
|
86 |
+
model_id = 'anthropic.claude-v2:1'
|
87 |
+
system_prompt = "Please respond only with emoji."
|
88 |
+
max_tokens = 1000
|
89 |
+
|
90 |
+
# Prompt with user turn only.
|
91 |
+
user_message = {"role": "user", "content": "Hello World"}
|
92 |
+
messages = [user_message]
|
93 |
+
|
94 |
+
response = generate_message(bedrock_runtime, model_id, system_prompt, messages, max_tokens)
|
95 |
+
print("User turn only.")
|
96 |
+
print(json.dumps(response, indent=4))
|
97 |
+
|
98 |
+
# Prompt with both user and assistant messages
|
99 |
+
assistant_message = {"role": "assistant", "content": "<emoji>"}
|
100 |
+
messages = [user_message, assistant_message]
|
101 |
+
response = generate_message(bedrock_runtime, model_id, system_prompt, messages, max_tokens)
|
102 |
+
print("User turn and prefilled assistant response.")
|
103 |
+
print(json.dumps(response, indent=4))
|
104 |
+
|
105 |
+
except ClientError as err:
|
106 |
+
message = err.response["Error"]["Message"]
|
107 |
+
logger.error("A client error occurred: %s", message)
|
108 |
+
print("A client error occurred: " + format(message))
|
109 |
+
|
110 |
+
|
111 |
+
main()
|
112 |
+
|
113 |
+
#%%
|
114 |
+
from botocore.exceptions import ClientError
|
115 |
+
session = boto3.Session(
|
116 |
+
aws_access_key_id=aws_access_key_id,
|
117 |
+
aws_secret_access_key=aws_secret_access_key,
|
118 |
+
region_name=aws_region
|
119 |
+
)
|
120 |
+
|
121 |
+
bedrock_runtime = session.client("bedrock-runtime")
|
122 |
+
|
123 |
+
model_id = "anthropic.claude-v2:1"
|
124 |
+
|
125 |
+
payload = {
|
126 |
+
"anthropic_version": "bedrock-2023-05-31",
|
127 |
+
"max_tokens": 100,
|
128 |
+
"messages": [{"role": "user", "content": "Hello!"}]
|
129 |
+
}
|
130 |
+
|
131 |
+
try:
|
132 |
+
response = bedrock_runtime.invoke_model_with_response_stream(
|
133 |
+
modelId=model_id,
|
134 |
+
body=json.dumps(payload),
|
135 |
+
contentType="application/json",
|
136 |
+
accept="application/json"
|
137 |
+
)
|
138 |
+
|
139 |
+
print("β
Streaming appears to be enabled for Claude v2.1.")
|
140 |
+
for event in response['body']:
|
141 |
+
chunk = event['chunk']['bytes']
|
142 |
+
print(chunk.decode(), end="")
|
143 |
+
|
144 |
+
except ClientError as e:
|
145 |
+
code = e.response['Error']['Code']
|
146 |
+
if code == "AccessDeniedException":
|
147 |
+
print("β Streaming is NOT enabled for Claude v2.1: Access denied.")
|
148 |
+
elif code == "ValidationException":
|
149 |
+
print("β οΈ Model does not support streaming or bad payload.")
|
150 |
+
else:
|
151 |
+
print(f"β Unexpected error: {e}")
|
152 |
+
except Exception as e:
|
153 |
+
print(f"β General error: {e}")
|
154 |
+
#%%
|
155 |
+
messages = [
|
156 |
+
{"role": "user", "content": "Can you tell me a fun fact about llamas?"}
|
157 |
+
]
|
158 |
+
|
159 |
+
payload = {
|
160 |
+
"anthropic_version": "bedrock-2023-05-31",
|
161 |
+
"max_tokens": 256,
|
162 |
+
"messages": messages
|
163 |
+
}
|
164 |
+
|
165 |
+
# β
1. Test NON-streaming (invoke_model)
|
166 |
+
print("π§ͺ Testing invoke_model (non-streaming)...")
|
167 |
+
try:
|
168 |
+
response = client.invoke_model(
|
169 |
+
modelId=model_id,
|
170 |
+
body=json.dumps(payload),
|
171 |
+
contentType="application/json",
|
172 |
+
accept="application/json"
|
173 |
+
)
|
174 |
+
result = json.loads(response["body"].read().decode("utf-8"))
|
175 |
+
print("β
invoke_model succeeded.")
|
176 |
+
print("π§ Claude's reply:", result["content"][0]["text"])
|
177 |
+
except ClientError as e:
|
178 |
+
print("β invoke_model failed:", e)
|
179 |
+
|
180 |
+
# β 2. Test Streaming (invoke_model_with_response_stream)
|
181 |
+
print("\nπ§ͺ Testing invoke_model_with_response_stream (streaming)...")
|
182 |
+
try:
|
183 |
+
stream_response = client.invoke_model_with_response_stream(
|
184 |
+
modelId=model_id,
|
185 |
+
body=json.dumps(payload),
|
186 |
+
contentType="application/json",
|
187 |
+
accept="application/json"
|
188 |
+
)
|
189 |
+
|
190 |
+
print("β
Streaming supported. Response:")
|
191 |
+
for event in stream_response["body"]:
|
192 |
+
chunk = event.get("chunk", {}).get("bytes", b"")
|
193 |
+
if chunk:
|
194 |
+
decoded = json.loads(chunk.decode("utf-8"))
|
195 |
+
delta = decoded.get("delta", {}).get("content", "")
|
196 |
+
print(delta, end="", flush=True)
|
197 |
+
|
198 |
+
except ClientError as e:
|
199 |
+
code = e.response["Error"]["Code"]
|
200 |
+
if code == "AccessDeniedException":
|
201 |
+
print("β AccessDeniedException: Streaming is not enabled for your role.")
|
202 |
+
elif code == "ValidationException":
|
203 |
+
print("β οΈ ValidationException: Model might not support streaming or payload is malformed.")
|
204 |
+
else:
|
205 |
+
print(f"β Unexpected error: {e}")
|
206 |
+
except Exception as e:
|
207 |
+
print(f"β General error: {e}")
|
208 |
+
#%%
|
bedrock_test_Pixtral.py
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
|
3 |
+
|
4 |
+
#%%
|
5 |
+
aws_access_key_id='AKIA2UC26WDCAFOF7X64'
|
6 |
+
aws_secret_access_key='4/EHQ3i2ci1seDA6OtxV6a4zaVz1W2uSZSrjjlFl'
|
7 |
+
aws_region = "eu-central-1"
|
8 |
+
#%%
|
9 |
+
|
10 |
+
import boto3
|
11 |
+
import json
|
12 |
+
|
13 |
+
from botocore.exceptions import ClientError
|
14 |
+
|
15 |
+
|
16 |
+
bedrock_runtime = session.client(service_name='bedrock-runtime')
|
17 |
+
|
18 |
+
# π·οΈ Model ID for Pixtral
|
19 |
+
model_id = 'mistral.pixtral-large-2502-v1:0'
|
20 |
+
|
21 |
+
# βοΈ Define your prompt
|
22 |
+
prompt = "Describe the purpose of a 'hello world' program in one line."
|
23 |
+
|
24 |
+
# π§Ύ Format the request payload
|
25 |
+
native_request = {
|
26 |
+
"inputText": prompt,
|
27 |
+
"textGenerationConfig": {
|
28 |
+
"maxTokenCount": 512,
|
29 |
+
"temperature": 0.5,
|
30 |
+
"topP": 0.9
|
31 |
+
}
|
32 |
+
}
|
33 |
+
|
34 |
+
# π Convert to JSON
|
35 |
+
request = json.dumps(native_request)
|
36 |
+
|
37 |
+
try:
|
38 |
+
# π Invoke the model
|
39 |
+
response = bedrock_runtime.invoke_model(
|
40 |
+
modelId=model_id,
|
41 |
+
body=request,
|
42 |
+
contentType="application/json",
|
43 |
+
accept="application/json"
|
44 |
+
)
|
45 |
+
|
46 |
+
# π¦ Decode the response body
|
47 |
+
model_response = json.loads(response["body"].read())
|
48 |
+
|
49 |
+
# π¨οΈ Extract and print output text
|
50 |
+
response_text = model_response["results"][0]["outputText"]
|
51 |
+
print("β
Model response:")
|
52 |
+
print(response_text)
|
53 |
+
|
54 |
+
except ClientError as e:
|
55 |
+
print(f"β ClientError: {e.response['Error']['Message']}")
|
56 |
+
except Exception as e:
|
57 |
+
print(f"β ERROR: Can't invoke '{model_id}'. Reason: {e}")
|
58 |
+
#%%
|
requirements.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
gradio>=4.20.0
|
2 |
+
boto3>=1.34.0
|
3 |
+
botocore
|