fern/03-reference/baml_client/with_options.mdx
The with_options function creates a new client with default configuration options for logging, client registry, and type builders. These options are automatically applied to all function calls made through this client, but can be overridden on a per-call basis when needed.
my_b = b.with_options(client="openai/gpt-5-mini")
collector = Collector(name="my-collector") client_registry = ClientRegistry() client_registry.set_primary("openai/gpt-5-mini") env = {"BAML_LOG": "DEBUG", "OPENAI_API_KEY": "key-123"}
my_b = b.with_options(collector=collector, client_registry=client_registry, env=env)
result = my_b.ExtractResume("...")
other_collector = Collector(name="other-collector") result2 = my_b.ExtractResume("...", baml_options={"collector": other_collector})
</Tab>
<Tab title="TypeScript" language="typescript">
```typescript
import { b } from "baml_client"
import { Collector, ClientRegistry } from "@boundaryml/baml"
// Simple: just set the client name
const myB = b.withOptions({ client: "openai/gpt-5-mini" })
// Or with full options for advanced use cases
const collector = new Collector("my-collector")
const clientRegistry = new ClientRegistry()
clientRegistry.setPrimary("openai/gpt-5-mini")
const env = {"BAML_LOG": "DEBUG", "OPENAI_API_KEY": "key-123"}
// Create client with default options
const myBAdvanced = b.withOptions({ collector, clientRegistry, env })
// Uses the default options
const result = await myBAdvanced.ExtractResume("...")
// Override options for a specific call
const otherCollector = new Collector("other-collector")
const result2 = await myBAdvanced.ExtractResume("...", { collector: otherCollector })
package main
import (
"context"
b "example.com/myproject/baml_client"
)
func run() {
ctx := context.Background()
// Simple: just set the client name
result, err := b.ExtractResume(ctx, "...", b.WithClient("openai/gpt-5-mini"))
if err != nil {
panic(err)
}
// Or with full options for advanced use cases
collector, err := b.NewCollector("my-collector")
if err != nil {
panic(err)
}
env := map[string]string{
"BAML_LOG": "DEBUG",
"OPENAI_API_KEY": "key-123",
}
// Make function call with multiple options
result, err = b.ExtractResume(ctx, "...",
b.WithClient("openai/gpt-5-mini"),
b.WithCollector(collector),
b.WithEnv(env))
if err != nil {
panic(err)
}
// Override options for a specific call
otherCollector, err := b.NewCollector("other-collector")
if err != nil {
panic(err)
}
result2, err := b.ExtractResume(ctx, "...", b.WithCollector(otherCollector))
if err != nil {
panic(err)
}
}
collector = Baml::Collector.new(name: "my-collector") client_registry = Baml::ClientRegistry.new client_registry.set_primary("openai/gpt-5-mini") env = {"BAML_LOG": "DEBUG", "OPENAI_API_KEY": "key-123"}
my_b = Baml.Client.with_options(collector: collector, client_registry: client_registry, env: env)
result = my_b.ExtractResume(input: "...")
other_collector = Baml::Collector.new(name: "other-collector") result2 = my_b.ExtractResume(input: "...", baml_options: { collector: other_collector })
</Tab>
<Tab title="Rust" language="rust">
<Note>
Rust doesn't have a `with_options` method. Instead, use builder methods like `.with_client()`, `.with_collector()`, `.with_client_registry()`, and `.with_env_var()` directly on function calls.
</Note>
```rust
use myproject::baml_client::sync_client::B;
use myproject::baml_client::new_collector;
use baml::ClientRegistry;
use std::collections::HashMap;
fn main() {
let collector = new_collector("my-collector");
let mut registry = ClientRegistry::new();
registry.set_primary_client("openai/gpt-5-mini");
// Pass options per call using builder methods
let result = B.ExtractResume
.with_collector(&collector)
.with_client_registry(®istry)
.with_env_var("BAML_LOG", "DEBUG")
.call("...")
.unwrap();
}
Use with_options to create a client with default settings that will be applied to all function calls made through this client. These defaults can be overridden when needed.
def run(): # Configure options collector = Collector(name="my-collector") client_registry = ClientRegistry() client_registry.set_primary("openai/gpt-5-mini")
# Create configured client
my_b = b.with_options(collector=collector, client_registry=client_registry)
# All calls will use the configured options
res = my_b.ExtractResume("...")
invoice = my_b.ExtractInvoice("...")
# Access configuration
print(my_b.client_registry)
# Access logs from the collector
print(collector.logs)
print(collector.last)
</Tab>
<Tab title="TypeScript" language="typescript">
```typescript
import { b } from "baml_client"
import { Collector, ClientRegistry } from "@boundaryml/baml"
const collector = new Collector("my-collector")
const clientRegistry = new ClientRegistry()
clientRegistry.setPrimary("openai/gpt-5-mini")
const myB = b.withOptions({ collector, clientRegistry })
// All calls will use the configured options
const res = await myB.ExtractResume("...")
const invoice = await myB.ExtractInvoice("...")
// Access configuration
console.log(myB.clientRegistry)
console.log(collector.logs)
console.log(collector.last?.usage)
package main
import (
"context"
"fmt"
b "example.com/myproject/baml_client"
)
func run() {
ctx := context.Background()
// Configure options for reuse
collector, err := b.NewCollector("my-collector")
if err != nil {
panic(err)
}
clientRegistry, err := b.NewClientRegistry()
if err != nil {
panic(err)
}
err = clientRegistry.SetPrimary("openai/gpt-5-mini")
if err != nil {
panic(err)
}
// All calls must explicitly pass options
res, err := b.ExtractResume(ctx, "...", nil,
b.WithCollector(collector),
b.WithClientRegistry(clientRegistry))
if err != nil {
panic(err)
}
invoice, err := b.ExtractInvoice(ctx, "...",
b.WithCollector(collector),
b.WithClientRegistry(clientRegistry))
if err != nil {
panic(err)
}
// Access logs from collector
logs, err := collector.Logs()
if err != nil {
panic(err)
}
fmt.Printf("Logs: %+v\n", logs)
}
collector = Baml::Collector.new(name: "my-collector") client_registry = Baml::ClientRegistry.new client_registry.set_primary("openai/gpt-5-mini")
my_b = Baml.Client.with_options(collector: collector, client_registry: client_registry)
res = my_b.ExtractResume(input: "...") invoice = my_b.ExtractInvoice(input: "...")
print(my_b.client_registry) print(collector.logs) print(collector.last.usage)
</Tab>
<Tab title="Rust" language="rust">
```rust
use myproject::baml_client::sync_client::B;
use myproject::baml_client::new_collector;
use baml::ClientRegistry;
fn main() {
let collector = new_collector("my-collector");
let mut registry = ClientRegistry::new();
registry.set_primary_client("openai/gpt-5-mini");
// Pass options per call using builder methods
let res = B.ExtractResume
.with_collector(&collector)
.with_client_registry(®istry)
.call("...")
.unwrap();
let invoice = B.ExtractInvoice
.with_collector(&collector)
.with_client_registry(®istry)
.call("...")
.unwrap();
// Access logs from collector
let logs = collector.logs();
println!("{:?}", logs);
}
Add tags to a specific BAML function call. Tags are useful for correlating requests, A/B versions, user IDs, etc.
<Tabs> <Tab title="Python" language="python"> ```python from baml_client import b from baml_py import Collectorcollector = Collector(name="tags-collector") res = b.TestOpenAIGPT4oMini( "hello", baml_options={ "collector": collector, "tags": {"call_id": "first", "version": "v1"}, }, )
print(collector.last.tags)
</Tab>
<Tab title="TypeScript" language="typescript">
```typescript
import { b } from "baml_client";
import { Collector } from "@boundaryml/baml";
const collector = new Collector("tags-collector");
await b.TestOpenAIGPT4oMini("hello", { collector, tags: { callId: "first", version: "v1" } });
console.log(collector.last!.tags);
let collector = new_collector("tags-collector"); let result = B.TestOpenAIGPT4oMini .with_collector(&collector) .with_tag("call_id", "first") .with_tag("version", "v1") .call("hello") .unwrap();
let logs = collector.logs(); if let Some(log) = logs.last() { println!("{:?}", log.tags()); }
</Tab>
</Tabs>
### Parallel Execution
When running functions in parallel, `with_options` helps maintain consistent configuration across all calls. This works seamlessly with the [`Collector`](./collector) functionality.
<Tabs>
<Tab title="Python" language="python">
```python
from baml_client.async_client import b
from baml_py import ClientRegistry, Collector
import asyncio
async def run():
collector = Collector(name="my-collector")
my_b = b.with_options(collector=collector, client_registry=client_registry)
# Run multiple functions in parallel
res, invoice = await asyncio.gather(
my_b.ExtractResume("..."),
my_b.ExtractInvoice("...")
)
# Access results and logs
print(res)
print(invoice)
# Use tags or iterate logs to correlate specific calls
for log in collector.logs:
print(log.usage)
const collector = new Collector("my-collector") const myB = b.withOptions({ collector, clientRegistry })
// Run multiple functions in parallel const [ {data: res, id: resumeId}, {data: invoice, id: invoiceId} ] = await Promise.all([ myB.raw.ExtractResume("..."), myB.raw.ExtractInvoice("...") ])
// Access results and logs console.log(res) console.log(invoice) // Use tags or iterate logs to correlate specific calls for (const log of collector.logs) { console.log(log.usage) }
</Tab>
<Tab title="Ruby" language="ruby">
BAML Ruby (beta) does not currently support async/concurrent calls. Reach out to us if it's something you need!
</Tab>
</Tabs>
### Streaming Mode
`with_options` can be used with streaming functions while maintaining all configured options.
<Tabs>
<Tab title="Python" language="python">
```python
from baml_client.async_client import b
from baml_py import Collector
async def run():
collector = Collector(name="my-collector")
my_b = b.with_options(collector=collector, client_registry=client_registry)
stream = my_b.stream.ExtractResume("...")
async for chunk in stream:
print(chunk)
result = await stream.get_final_result()
# Use tags or collector.last / collector.logs for usage
print(collector.last.usage)
const collector = new Collector("my-collector") const myB = b.withOptions({ collector, clientRegistry })
const stream = myB.stream.ExtractResume("...") for await (const chunk of stream) { console.log(chunk) }
const result = await stream.getFinalResult() // Use tags or collector.last / collector.logs for usage console.log(collector.last?.usage)
</Tab>
<Tab title="Ruby" language="ruby">
```ruby
require 'baml_client'
collector = Baml::Collector.new(name: "my-collector")
my_b = Baml.Client.with_options(collector: collector, client_registry: client_registry)
stream = my_b.stream.ExtractResume(input: "...")
stream.each do |chunk|
print(chunk)
end
result = stream.get_final_result
# Use tags or collector.last / collector.logs for usage
print(collector.last.usage)
let collector = new_collector("my-collector");
let mut stream = B.ExtractResume .with_collector(&collector) .stream("...")?;
for partial in stream.partials() { println!("{:?}", partial?); }
let result = stream.get_final_response()?; // Access usage from collector println!("{:?}", collector.usage());
</Tab>
</Tabs>
## API Reference
### with_options Parameters
<Note>
These can always be overridden on a per-call basis with the `baml_options` parameter in any function call.
</Note>
| Parameter | Type | Description |
|-----------|------|-------------|
| `client` | `string` | Client name to use for all calls (shorthand for `client_registry.set_primary()`) |
| `collector` | [`Collector`](/ref/baml_client/collector) | Collector instance for tracking function calls and usage metrics |
| `client_registry` | `ClientRegistry` | Registry for managing LLM clients and their configurations |
| `type_builder` | [`TypeBuilder`](/ref/baml_client/type-builder) | Custom type builder for function inputs and outputs |
| `env` | `Dict/Object` | Environment variables to set for the client |
| `tags` (per-call) | `Dict/Object` | Arbitrary metadata for this call; merged with parent trace tags |
### Configured Client Properties
<Info>
The configured client maintains the same interface as the base `baml_client`, so you can use all the same functions and methods.
</Info>
## Related Topics
- [Collector](/ref/baml_client/collector) - Track function calls and usage metrics
- [TypeBuilder](/ref/baml_client/type-builder) - Build custom types for your functions
- [Client Registry](/ref/baml_client/client-registry) - Manage LLM clients and their configurations
- [Environment Variables](/ref/baml/general-baml-syntax/environment-variables) - Set environment variables
- [AbortController](/ref/baml_client/abort-signal) - Cancel in-flight operations
<Info>
The configured client maintains the same interface as the base client, so you can use all the same functions and methods.
</Info>