Provider Adapters¶
Provider adapters wrap AI provider clients so applications can keep their normal provider calls while Spendware adds preflight checks, usage extraction, logging, and runtime context.
Supported Surfaces¶
- OpenAI: responses, chat completions, and parse surfaces.
- Anthropic: messages and streaming messages.
- Gemini: content generation, interaction calls, and chat send methods.
- Azure OpenAI and OpenAI-compatible clients.
- Bedrock where package support is installed.
Example¶
curl "$SPENDWARE_BASE_URL/api/v1/usage/preflight-with-key" \
-H "Content-Type: application/json" \
-d '{"key":"SPENDWARE_CUSTOMER_KEY","service_provider_name":"openai","service_name":"gpt-4o","input_tokens":120,"output_tokens":45}'
import os
from openai import OpenAI
from spendware_provider_sdk import create_spendware_config, wrap_openai_client
from spendware_provider_sdk.core.adapter_types import AdapterCommonOptions
from spendware_provider_sdk.core.types import KeyAuthConfig
openai_client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
config = create_spendware_config(
spendware_base_url="SPENDWARE_BASE_URL",
auth=KeyAuthConfig(customer_key="SPENDWARE_CUSTOMER_KEY"),
)
wrapped = wrap_openai_client(openai_client, AdapterCommonOptions(config=config))
response = wrapped.client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
spendware={"runtime_context": {"feature": "chat"}},
)
wrapped.shutdown()
import OpenAI from "openai";
import { createSpendwareConfig, wrapOpenAIClient } from "@spendware/provider-adapters-sdk";
const openaiClient = new OpenAI({ apiKey: "OPENAI_API_KEY" });
const config = createSpendwareConfig({
spendwareBaseUrl: "SPENDWARE_BASE_URL",
auth: { mode: "customer_key", customerKey: "SPENDWARE_CUSTOMER_KEY" },
});
const wrapped = wrapOpenAIClient(openaiClient, { config });
const response = await wrapped.client.chat.completions.create(
{
model: "gpt-4o",
messages: [{ role: "user", content: "Hello" }],
},
{ spendware: { runtimeContext: { feature: "chat" } } },
);
await wrapped.shutdown();
Runtime Context¶
Use runtime context resolvers or per-call overrides when one process serves multiple tenants. Prefer external project and customer IDs when internal Spendware IDs are not available.
Common Errors¶
- Forgetting
shutdown()can leave async usage logs queued. - Dry-run mode skips backend calls by design.
- Missing customer/project context can prevent usage attribution.