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

# Tracing LLM calls in FastAPI with Tracevell

## Overview

We'll create a FastAPI application that:

1. Accepts support ticket submissions
2. Uses an LLM to classify the ticket
3. Returns the classification result
4. Traces the entire process with Tracevell

## Setup

You can also use the example app from our GitHub [repo](https://github.com/lmnr-ai/lmnr-python/tree/main/examples/fastapi-app).

Alternatively, for a clean install, follow the steps below:

**1. Install Dependencies**

First, let's install the required packages:

```bash theme={null}
pip install -U fastapi uvicorn openai lmnr python-dotenv
```

**2. Environment Setup**

Create a `.env` file with your API keys:

```bash theme={null}
LMNR_PROJECT_API_KEY="your-tracevell-project-api-key"
OPENAI_API_KEY="your-openai-api-key"
```

**3. Project Structure**

Create the following project structure:

```
fastapi-app/
├── .env
├── requirements.txt
└── src/
    ├── main.py
    ├── llm.py
    └── schemas.py
```

## Implementation

Let's create our FastAPI application with Tracevell tracing. We'll split the code into three files:

### 1. schemas.py

This file will contain the Pydantic models for the request and response.

```python schemas.py theme={null}
from enum import Enum
from pydantic import BaseModel

class TicketCategory(str, Enum):
    REFUND = "REFUND"
    BUG = "BUG"
    QUESTION = "QUESTION"
    OTHER = "OTHER"

class Ticket(BaseModel):
    title: str
    description: str
    customer_email: str

class TicketClassification(BaseModel):
    category: TicketCategory
    reasoning: str
```

### 2. llm.py

This file will contain the logic that handles the LLM. In a production app,
this will likely be a much bigger module with classes, routing, etc.

For now, we'll just have a function that handles an OpenAI call.

```python llm.py theme={null}
from dotenv import load_dotenv
from lmnr import observe
from openai import OpenAI
from schemas import Ticket, TicketCategory, TicketClassification

import os

load_dotenv(override=True)

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

@observe()
def model_classify_ticket(ticket: Ticket) -> TicketClassification:
    response = client.beta.chat.completions.parse(
        model="gpt-5.6-luna",
        response_format=TicketClassification,
        messages=[
            {
                "role": "system",
                "content": """You are a support ticket classifier.
Classify the ticket that a user sends you""",
            },
            {
                "role": "user",
                "content": f"""Title: {ticket.title}
Description: {ticket.description}
Customer Email: {ticket.customer_email}""",
            },
        ],
    )
    
    return response.choices[0].message.parsed or TicketClassification(
        category=TicketCategory.OTHER,
        reasoning=response.choices[0].message.content,
    )
```

### 3. main.py

This file will contain the logic that handles the FastAPI app.

> [!NOTE]
>
> Tracevell must be initialized once at the entry point of the application.
> For FastAPI, this is typically `main.py`, right before creating `app`.

```python main.py {4,9,10} theme={null}
from dotenv import load_dotenv
from fastapi import FastAPI, HTTPException
from llm import model_classify_ticket
from lmnr import Tracevell
from schemas import Ticket, TicketClassification

load_dotenv(override=True)

# Tracevell must be initialized once, preferably at the entry point of the application
Laminar.initialize()

app = FastAPI()

@app.post("/api/v1/tickets/classify", response_model=TicketClassification)
async def classify_ticket(ticket: Ticket):
    try:
        classification = model_classify_ticket(ticket)
        print(classification)
        return classification
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))
```

## Running the Application

Start the FastAPI server:

```bash theme={null}
uvicorn src.main:app --reload --port 8011
```

## Testing the API

You can test the API using curl:

```bash theme={null}
curl --location 'localhost:8011/api/v1/tickets/classify' \
--header 'Content-Type: application/json' \
--data-raw '{
    "title": "Can'\''t access my account",
    "description": "I'\''ve been trying to log in for the past hour but keep getting an error message",
    "customer_email": "user@example.com"
}'
```

## Viewing Traces

After making a request, you can view the traces in your Tracevell dashboard at [https://tracevell.com](https://tracevell.com). The trace will show:

1. The ticket classification function execution
2. The OpenAI API call

## Key Features Demonstrated

1. **Automatic Tracing**: Tracevell automatically traces OpenAI calls and functions marked with `@observe`
2. **Tokens Usage**: Tracevell automatically calculates the tokens used for each OpenAI call
3. **Cost Estimation**: Tracevell automatically estimates the cost of each OpenAI call

## Troubleshooting

If you encounter issues:

* Check that your API keys are correctly set in the `.env` file and that it is loaded correctly
* Verify that Tracevell is properly initialized
* Ensure all dependencies are installed
* Review the FastAPI logs for any application errors


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.