Audacity Investments AI SDK — Bedrock-parity client for the Audacity LLM gateway
Project description
audacity-sdk
Python client for the Audacity Investments LLM gateway. Exposes the same Amazon Bedrock Converse surface so teams migrating off Bedrock can swap the client constructor and keep the rest of their call-sites unchanged.
Installation
pip install audacity-sdk
Zero runtime dependencies — stdlib only. Requires Python 3.9+.
Quick start
Non-streaming (Converse)
from audacity import Audacity
client = Audacity(api_key="audacity_api_…") # or set AUDACITY_API_KEY
response = client.converse(
modelId="gpt-5.4-mini",
messages=[{"role": "user", "content": [{"text": "What is 2+2?"}]}],
inferenceConfig={"maxTokens": 256, "temperature": 0.0},
)
print(response["output"]["message"]["content"][0]["text"])
print(response["stopReason"]) # "end_turn"
print(response["usage"]) # {"inputTokens": …, "outputTokens": …, "totalTokens": …}
print(response["metrics"]) # {"latencyMs": …}
Streaming (ConverseStream)
from audacity import Audacity
client = Audacity()
stream_response = client.converse_stream(
modelId="gpt-5.4-mini",
messages=[{"role": "user", "content": [{"text": "Write me a haiku."}]}],
)
for event in stream_response["stream"]: # boto3 parity: response["stream"]
if "contentBlockDelta" in event:
delta = event["contentBlockDelta"]["delta"]
print(delta.get("text", ""), end="", flush=True)
print() # newline at end
Migrating from boto3 bedrock-runtime
# BEFORE — boto3
import boto3
client = boto3.client("bedrock-runtime", region_name="us-east-1")
response = client.converse(
modelId="anthropic.claude-3-sonnet-20240229-v1:0",
messages=[{"role": "user", "content": [{"text": "Hi"}]}],
)
# AFTER — Audacity SDK
from audacity import Audacity
client = Audacity(api_key="audacity_api_…") # only line that changes
response = client.converse(
modelId="gpt-5.4-mini", # use Audacity model ID
messages=[{"role": "user", "content": [{"text": "Hi"}]}],
)
Streaming diff:
# BEFORE — boto3
stream_resp = client.converse_stream(modelId=…, messages=…)
for event in stream_resp["stream"]:
…
# AFTER — Audacity SDK (identical call-site)
stream_resp = client.converse_stream(modelId=…, messages=…)
for event in stream_resp["stream"]:
…
Tool use
response = client.converse(
modelId="gpt-5.4-mini",
messages=[{"role": "user", "content": [{"text": "What's the weather in NYC?"}]}],
toolConfig={
"tools": [{
"toolSpec": {
"name": "get_weather",
"description": "Get current weather for a city",
"inputSchema": {
"json": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
}
},
}
}],
"toolChoice": {"auto": {}},
},
)
# Assistant responds with a tool call
tool_use = response["output"]["message"]["content"][0]["toolUse"]
print(tool_use["name"]) # "get_weather"
print(tool_use["input"]) # {"city": "NYC"}
# Send tool result back
response2 = client.converse(
modelId="gpt-5.4-mini",
messages=[
{"role": "user", "content": [{"text": "What's the weather in NYC?"}]},
{"role": "assistant", "content": response["output"]["message"]["content"]},
{"role": "user", "content": [
{"toolResult": {
"toolUseId": tool_use["toolUseId"],
"content": [{"text": "Sunny, 72°F"}],
}}
]},
],
)
Images (vision models)
Bedrock-style image content blocks are supported in user messages. Pass raw
bytes (encoded for you) or a URL (Audacity extension):
with open("chart.png", "rb") as f:
image_bytes = f.read()
response = client.converse(
modelId="gpt-5.5",
messages=[{
"role": "user",
"content": [
{"text": "What does this chart show?"},
{"image": {"format": "png", "source": {"bytes": image_bytes}}},
],
}],
)
# Or reference a hosted image directly (not available in Bedrock):
# {"image": {"format": "jpeg", "source": {"url": "https://example.com/photo.jpg"}}}
format is one of png, jpeg, gif, webp. Use a vision-capable model.
Error handling
from audacity import Audacity
from audacity.exceptions import (
MissingApiKeyError,
AccessDeniedException,
ThrottlingException,
ServiceQuotaExceededException,
ModelStreamErrorException,
SdkError,
)
client = Audacity()
try:
response = client.converse(modelId="gpt-5.4-mini", messages=[…])
except client.exceptions.ThrottlingException as e:
print(f"Rate limited: {e.message}, retry after {e.retry_after_seconds}s")
except client.exceptions.AccessDeniedException as e:
print(f"Auth error [{e.status_code}]: {e.message}")
except client.exceptions.ServiceQuotaExceededException as e:
print(f"Budget exhausted: {e.message}")
except SdkError as e:
print(f"Network/decode error: {e.message}")
Streaming errors surface when you iterate the stream:
try:
for event in stream_response["stream"]:
…
except client.exceptions.ModelStreamErrorException as e:
print(f"Stream broken: {e.message}")
Configuration & environment variables
| Constructor parameter | Environment variable | Default |
|---|---|---|
api_key |
AUDACITY_API_KEY |
— (required) |
base_url |
AUDACITY_BASE_URL |
https://portal.audacityinvestments.com |
timeout |
— | 120.0 seconds |
max_retries |
— | 2 (3 total attempts) |
client = Audacity(
api_key="audacity_api_…",
base_url="https://portal.audacityinvestments.com",
timeout=60.0,
max_retries=3,
)
Retry behaviour
The SDK automatically retries transient failures with jittered exponential backoff (capped at 20 s):
- Retried:
ThrottlingException(429),ModelTimeoutException(408),ServiceUnavailableException(502/503/504),InternalServerException(500), network errors. - Never retried:
AccessDeniedException,ValidationException,ResourceNotFoundException,ServiceQuotaExceededException(includingBUDGET_EXCEEDEDat 429/402), or any 4xx except 408/429. - Streaming: retries apply only before the first SSE byte; after that,
connection drops raise
ModelStreamErrorException.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file audacity_sdk-0.1.1.tar.gz.
File metadata
- Download URL: audacity_sdk-0.1.1.tar.gz
- Upload date:
- Size: 30.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3b7595fd5239f185b661e0f9595f3d25c13aeef2612a4cb5da94afa40d2c5f1d
|
|
| MD5 |
84df148601bf29b12d75fa39b8d17b99
|
|
| BLAKE2b-256 |
914a4633eed9a485487bcef1b75ae45ed6d8b4e509c71c14d0e841133d479c9b
|
Provenance
The following attestation bundles were made for audacity_sdk-0.1.1.tar.gz:
Publisher:
publish-python-sdk.yml on Audacity-Investments/audacity
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
audacity_sdk-0.1.1.tar.gz -
Subject digest:
3b7595fd5239f185b661e0f9595f3d25c13aeef2612a4cb5da94afa40d2c5f1d - Sigstore transparency entry: 2053409704
- Sigstore integration time:
-
Permalink:
Audacity-Investments/audacity@759ecc210d474212f8a56296e0d43986da032d0f -
Branch / Tag:
refs/tags/python-sdk-v0.1.1 - Owner: https://github.com/Audacity-Investments
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python-sdk.yml@759ecc210d474212f8a56296e0d43986da032d0f -
Trigger Event:
push
-
Statement type:
File details
Details for the file audacity_sdk-0.1.1-py3-none-any.whl.
File metadata
- Download URL: audacity_sdk-0.1.1-py3-none-any.whl
- Upload date:
- Size: 19.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7ba8e44d9224c4c7dd755a9fa14f9d383c80ad6f4e598729f32d966d3201a62e
|
|
| MD5 |
206afe507deef75393b0b12a8f9975c5
|
|
| BLAKE2b-256 |
619f48882a7623faf8a1e9fdbc45ae94a11a507e717abd62d8b09b0f2e3b71e6
|
Provenance
The following attestation bundles were made for audacity_sdk-0.1.1-py3-none-any.whl:
Publisher:
publish-python-sdk.yml on Audacity-Investments/audacity
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
audacity_sdk-0.1.1-py3-none-any.whl -
Subject digest:
7ba8e44d9224c4c7dd755a9fa14f9d383c80ad6f4e598729f32d966d3201a62e - Sigstore transparency entry: 2053410211
- Sigstore integration time:
-
Permalink:
Audacity-Investments/audacity@759ecc210d474212f8a56296e0d43986da032d0f -
Branch / Tag:
refs/tags/python-sdk-v0.1.1 - Owner: https://github.com/Audacity-Investments
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python-sdk.yml@759ecc210d474212f8a56296e0d43986da032d0f -
Trigger Event:
push
-
Statement type: