> ## Documentation Index
> Fetch the complete documentation index at: https://futureagi.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Set Session ID and User ID

> Adding SessionID and UserID as attributes to Spans for Tracing

#### Understanding Sessions

A session groups traces using a `session ID` attribute. This is particularly useful when developing or debugging a chatbot application, as it allows you to view collections of messages or traces that belong to a series of interactions between a human and the AI. By incorporating `session.id` and `user.id` as span attributes, you can:

* Pinpoint where a conversation "breaks" or deviates. This helps in identifying if a user becomes increasingly frustrated or if a chatbot is ineffective.
* Identify trace groups where your application underperforms. Adding `session.id` and/or `user.id` from an application allows for grouping and further filtering of interactions.
* Develop custom metrics based on evaluations using `session.id` or `user.id` to identify the best and worst performing sessions and users.

### Adding SessionID and UserID

Session and user IDs can be added to a span through auto instrumentation or manual instrumentation of traceAI. Any LLM call within the context (the `with` block in the example below) will include the corresponding `session.id` or `user.id` as a span attribute. Both `session.id` and `user.id` must be non-empty strings.

When setting up your instrumentation, you can pass the `sessionID` attribute as demonstrated below.

## `using_session`

This context manager adds a session ID to the current OpenTelemetry Context. traceAI auto instrumentators will read this Context and pass the session ID as a span attribute, adhering to the traceAI semantic conventions. The session ID input must be a non-empty string.

<CodeGroup>
  ```python Python theme={null}
  from fi_instrumentation import using_session

  with using_session(session_id="my-session-id"):
      # Calls within this block will generate spans with the attributes:
      # "session.id" = "my-session-id"
      ...
  ```

  ```javascript JS/TS theme={null}
  import { context, propagation } from "@opentelemetry/api";

  const sessionId = "my-js-session-id"; // Example session ID

  const activeContext = context.active();
  const baggageWithSession = propagation.createBaggage({
      "session.id": { value: sessionId }
  });
  const newContext = propagation.setBaggage(activeContext, baggageWithSession);

  context.with(newContext, () => {
      // Calls within this block by auto-instrumented libraries (like traceAI)
      // should generate spans with the attribute: "session.id" = "my-js-session-id"
      // e.g., myInstrumentedFunction();
  });
  ```
</CodeGroup>

It can also be applied as a decorator:

```python Python theme={null}
@using_session(session_id="my-session-id")
def call_fn(*args, **kwargs):
    # Calls within this function will generate spans with the attributes:
    # "session.id" = "my-session-id"
    ...
```

## `using_user`

This context manager adds a user ID to the current OpenTelemetry Context. traceAI auto instrumentators will read this Context and pass the user ID as a span attribute, following the traceAI semantic conventions. The user ID input must be a non-empty string.

<CodeGroup>
  ```python Python theme={null}
  from fi_instrumentation import using_user

  with using_user("my-user-id"):
      # Calls within this block will generate spans with the attributes:
      # "user.id" = "my-user-id"
      ...
  ```

  ```javascript JS/TS theme={null}
  import { context, propagation } from "@opentelemetry/api";

  const userId = "my-js-user-id"; // Example user ID

  const activeContext = context.active();
  const baggageWithUser = propagation.createBaggage({
      "user.id": { value: userId }
  });
  const newContext = propagation.setBaggage(activeContext, baggageWithUser);

  context.with(newContext, () => {
      // Calls within this block by auto-instrumented libraries (like traceAI)
      // should generate spans with the attribute: "user.id" = "my-js-user-id"
      // e.g., myInstrumentedFunction();
  });
  ```
</CodeGroup>

It can also be applied as a decorator:

```python Python theme={null}
@using_user("my-user-id")
def call_fn(*args, **kwargs):
    # Calls within this function will generate spans with the attributes:
    # "user.id" = "my-user-id"
    ...
```

### Additional Examples

Install the required package:

<CodeGroup>
  ```bash Python theme={null}
  pip install traceAI-openai
  ```

  ```bash JS/TS theme={null}
  npm install @opentelemetry/api # or yarn add @opentelemetry/api
  # Assuming your traceAI or equivalent auto-instrumentation package is already installed.
  ```
</CodeGroup>

Once your OpenAI client is defined, any call inside our context managers will attach the corresponding attributes to the spans.

<CodeGroup>
  ```python Python theme={null}
  import openai
  from fi_instrumentation import using_attributes

  client = openai.OpenAI()

  # Defining a Session
  with using_attributes(session_id="my-session-id"):
      response = client.chat.completions.create(
          model="gpt-3.5-turbo",
          messages=[{"role": "user", "content": "Write a haiku."}],
          max_tokens=20,
      )
  ```

  ```javascript JS/TS theme={null}
  import { context, propagation } from "@opentelemetry/api";
  // Assume 'openai' client or equivalent is initialized and used here.
  // import OpenAI from 'openai';
  // const client = new OpenAI();

  const sessionId = "my-js-session-id";

  const activeContext = context.active();
  const baggageWithSession = propagation.createBaggage({
      "session.id": { value: sessionId }
  });
  const newContext = propagation.setBaggage(activeContext, baggageWithSession);

  context.with(newContext, () => {
      // Example LLM call that would pick up the session.id from context
      // response = client.chat.completions.create(
      //     model="gpt-3.5-turbo",
      //     messages=[{"role": "user", "content": "Write a haiku in JavaScript context."}],
      //     max_tokens=20,
      // );
      console.log('In context with session.id set via Baggage');
  });
  ```
</CodeGroup>

# Defining a User

<CodeGroup>
  ```python Python theme={null}
  # Ensure 'client' and 'using_attributes' are imported as in the previous Python example.
  with using_attributes(user_id="my-user-id"):
      response = client.chat.completions.create(
          model="gpt-3.5-turbo",
          messages=[{"role": "user", "content": "Write a haiku."}],
          max_tokens=20,
      )
  ```

  ```javascript JS/TS theme={null}
  import { context, propagation } from "@opentelemetry/api";
  // Assume 'client' (e.g., OpenAI client) is initialized and used here.

  const userId = "my-js-user-id";

  const activeContext = context.active();
  const baggageWithUser = propagation.createBaggage({
      "user.id": { value: userId }
  });
  const newContext = propagation.setBaggage(activeContext, baggageWithUser);

  context.with(newContext, () => {
      // Example LLM call that would pick up the user.id from context
      // response = client.chat.completions.create(...);
      console.log('In context with user.id set via Baggage');
  });
  ```
</CodeGroup>

# Defining a Session AND a User

<CodeGroup>
  ```python Python theme={null}
  # Ensure 'client' and 'using_attributes' are imported as in the previous Python example.
  with using_attributes(
      session_id="my-session-id",
      user_id="my-user-id",
  ):
      response = client.chat.completions.create(
          model="gpt-3.5-turbo",
          messages=[{"role": "user", "content": "Write a haiku."}],
          max_tokens=20,
      )
  ```

  ```javascript JS/TS theme={null}
  import { context, propagation } from "@opentelemetry/api";
  // Assume 'client' (e.g., OpenAI client) is initialized and used here.

  const sessionId = "my-js-session-id";
  const userId = "my-js-user-id";

  const activeContext = context.active();
  const baggageWithBoth = propagation.createBaggage({
      "session.id": { value: sessionId },
      "user.id": { value: userId }
  });
  const newContext = propagation.setBaggage(activeContext, baggageWithBoth);

  context.with(newContext, () => {
      // Example LLM call that would pick up both session.id and user.id from context
      // response = client.chat.completions.create(...);
      console.log('In context with session.id and user.id set via Baggage');
  });
  ```
</CodeGroup>

Alternatively, if you wrap your calls inside functions, you can use them as decorators:

```python Python theme={null}
from fi_instrumentation import using_attributes

client = openai.OpenAI()

# Defining a Session
@using_attributes(session_id="my-session-id")
def call_fn(client, *args, **kwargs):
    return client.chat.completions.create(*args, **kwargs)
    
# Defining a User
@using_attributes(user_id="my-user-id")
def call_fn(client, *args, **kwargs):
    return client.chat.completions.create(*args, **kwargs)

# Defining a Session AND a User
@using_attributes(
    session_id="my-session-id",
    user_id="my-user-id",
)
def call_fn(client, *args, **kwargs):
    return client.chat.completions.create(*args, **kwargs)
```
