Define and log attributes ↗
noOriginal Documentation
Documentation Index#
Fetch the complete documentation index at: https://docs.wandb.ai/llms.txt Use this file to discover all available pages before exploring further.
Use attributes to add meta data to your traces and evaluations.
Attributes in Weave allow you to attach custom metadata to your traces and evaluations. This metadata can include information like environment names, model versions, experiment IDs, user IDs, or other contextual information to help you organize, filter, and analyze your Weave data.
Weave provides two ways to add attributes:
- Per-call attributes: Use the
weave.attributes()to add metadata to specific operations or code blocks - Global attributes: Use the
global_attributesfield to set attributes at initialization that apply to all traces and evaluations in your project
You can view all attributes logged during traces and evaluation in the UI. You can then use them to filter and group data.
call.attributes cannot be modified once the call starts. Use this
context manager to set any metadata before invoking the op.
Per-call attributes#
The weave.attributes() context manager allows you to add metadata to specific traced operations. This allows you to tag particular function calls or evaluation runs with contextual information.
import weave
weave.init("attribute-check")
@weave.op
def my_function(name: str):
return f"Hello, {name}!"
# Add attributes to a specific call
with weave.attributes({'env': 'production', 'user_id': '12345'}):
result = my_function("World")
```
<span class="tab-end"></span>
<span class="tab-start" data-tab-title="TypeScript"></span>
```typescript
import {init, op, withAttributes} from 'weave';
async function main() {
await init('your-team/attribute-example');
const myFunction = op(async function myFunction(name: string) {
return `Hello, ${name}!`;
});
// Add attributes to a specific call
const result = await withAttributes(
{env: 'production', user_id: '12345'},
async () => myFunction('World')
);
console.log('Result:', result);
}
main().catch(console.error);
```
<span class="tab-end"></span>
<span class="tab-group-end"></span>
The function attaches the attributes to all traced operations within the context manager block (Python) or callback function (TypeScript).
You can also nest `weave.attributes()` contexts. Inner contexts override outer contexts for the same keys:
<span class="tab-group-start"></span>
<span class="tab-start" data-tab-title="Python"></span>
```python
@weave.op
def process_data(data: str):
return data.upper()
# Outer context
with weave.attributes({
"env": "production",
"version": "1.0.0",
"region": "us-west-2"
}):
process_data("hello") # Has all three attributes
# Inner context overrides 'version'
with weave.attributes({
"version": "1.1.0",
"experiment": "exp-456"
}):
process_data("world") # Has env='production', version='1.1.0', region='us-west-2', experiment='exp-456'
```
<span class="tab-end"></span>
<span class="tab-start" data-tab-title="TypeScript"></span>
```typescript
import {init, op, withAttributes} from 'weave';
async function main() {
await init('your-team/attribute-example');
const processData = op(async function processData(data: string) {
return data.toUpperCase();
});
// Outer context
await withAttributes(
{
env: 'production',
version: '1.0.0',
region: 'us-west-2'
},
async () => {
await processData('hello'); // Has all three attributes
// Inner context overrides 'version'
await withAttributes(
{
version: '1.1.0',
experiment: 'exp-456'
},
async () => {
await processData('world'); // Has env='production', version='1.1.0', region='us-west-2', experiment='exp-456'
}
);
}
);
}
main().catch(console.error);
```
<span class="tab-end"></span>
<span class="tab-group-end"></span>
## Global attributes
When you set global attributes during Weave initialization, they automatically apply to **all** traces and evaluations in your project. This is useful for propagating project-wide metadata like environment, deployment version, or team information.
<span class="tab-group-start"></span>
<span class="tab-start" data-tab-title="Python"></span>
```python
import weave
weave.init(
"my-project",
global_attributes={
"env": "production",
"app_version": "2.1.0",
"region": "us-west-2",
"team": "ml-platform"
}
)
# The global_attributes dictionary now applies these attributes to all subsequent operations
@weave.op
def my_function():
return "Hello"
my_function() # Automatically has all global attributes
# Evaluations also get global attributes
evaluation = weave.Evaluation(dataset=examples, scorers=[scorer])
asyncio.run(evaluation.evaluate(model)) # Has all global attributes
```
<span class="tab-end"></span>
<span class="tab-start" data-tab-title="TypeScript"></span>
```typescript
import {init, op, withAttributes} from 'weave';
async function main() {
await init('your-team/attribute-example', {
globalAttributes: {
env: 'production',
app_version: '2.1.0',
region: 'us-west-2',
team: 'ml-platform'
}
});
// The globalAttributes object now applies these attributes to all subsequent operations
const myFunction = op(async function myFunction() {
return 'Hello';
});
const result = await myFunction(); // Automatically has all global attributes
console.log('Result:', result);
}
main().catch(console.error);
```
<span class="tab-end"></span>
<span class="tab-group-end"></span>
### Combine global and per-call attributes
You can use global attributes and per-call attributes together. Per-call attributes with the same key override global attributes:
<span class="tab-group-start"></span>
<span class="tab-start" data-tab-title="Python"></span>
```python
import weave
# Set global attributes
weave.init(
"my-project",
global_attributes={
"env": "production",
"app_version": "2.1.0"
}
)
@weave.op
def process(data: str):
return data
# This call has: env='production', app_version='2.1.0'
process("test1")
# This call has: env='staging', app_version='2.1.0', experiment='A'
with weave.attributes({'env': 'staging', 'experiment': 'A'}):
process("test2")
```
<span class="tab-end"></span>
<span class="tab-start" data-tab-title="TypeScript"></span>
```typescript
import {init, op, withAttributes} from 'weave';
async function main() {
// Set global attributes
await init('your-team/attribute-example', {
globalAttributes: {
env: 'production',
app_version: '2.1.0'
}
});
const process = op(async function process(data: string) {
return data;
});
// This call has: env='production', app_version='2.1.0'
await process('test1');
// This call has: env='staging', app_version='2.1.0', experiment='A'
await withAttributes(
{env: 'staging', experiment: 'A'},
async () => process('test2')
);
}
main().catch(console.error);
```
<span class="tab-end"></span>
<span class="tab-group-end"></span>
## Get attributes during execution
Return the current set of attributes logged to your call. This can help you debug your calls or context for conditional logic.
<span class="tab-group-start"></span>
<span class="tab-start" data-tab-title="Python"></span>
The following example sets the Weave decorator to log the `process_data` function, configures attributes to log, and then returns them on execution.
```python
import weave
weave.init("your-team/your-project")
@weave.op
def process_data(data: str):
# Get the current call inside the op
call = weave.get_current_call()
if call:
print(f"Attributes: {call.attributes}")
return data.upper()
# Set attributes and execute the function
with weave.attributes({
"env": "production",
"version": "1.0.0",
"region": "us-west-2"
}):
process_data("hello")
with weave.attributes({
"version": "1.1.0",
"experiment": "exp-456"
}):
process_data("world")
```
This outputs:
```shell
Attributes: {'env': 'production', 'version': '1.0.0', 'region': 'us-west-2'}
Attributes: {'env': 'production', 'version': '1.1.0', 'region': 'us-west-2', 'experiment': 'exp-456'}
```
<span class="callout-start" data-callout-type="note"></span>
`weave.get_current_call()` only works **inside** a `@weave.op` decorated function. Outside of an op, it returns `None`.
<span class="callout-end"></span>
<span class="tab-end"></span>
<span class="tab-start" data-tab-title="TypeScript"></span>
Using the Weave TypeScript SDK, you can get the current attributes using `client.getCurrentAttributes()`. Unlike the Weave Python SDK, you can access TypeScript attributes within a `withAttributes()` context, not just inside an op.
```typescript
import * as weave from 'weave';
import { withAttributes } from 'weave';
async function main() {
const client = await weave.init('your-team/your-project');
const processData = weave.op(async function processData(data: string) {
// You can also access attributes inside an op
const attrs = client.getCurrentAttributes();
console.log('Attributes inside op:', attrs);
return data.toUpperCase();
});
// Set attributes and execute the function
await withAttributes(
{
env: 'production',
version: '1.0.0',
region: 'us-west-2'
},
async () => {
// Get attributes from anywhere in the context
console.log('Current attributes:', client.getCurrentAttributes());
await processData('hello');
await withAttributes(
{
version: '1.1.0',
experiment: 'exp-456'
},
async () => {
console.log('Nested attributes:', client.getCurrentAttributes());
await processData('world');
}
);
}
);
}
main().catch(console.error);
```
This outputs:
```shell
Current attributes: { env: 'production', version: '1.0.0', region: 'us-west-2' }
Attributes inside op: { env: 'production', version: '1.0.0', region: 'us-west-2' }
Nested attributes: { env: 'production', version: '1.1.0', region: 'us-west-2', experiment: 'exp-456' }
Attributes inside op: { env: 'production', version: '1.1.0', region: 'us-west-2', experiment: 'exp-456' }
```
<span class="tab-end"></span>
<span class="tab-group-end"></span>