LangfuseLangfuse Python SDK 4.15.4 · Python 3.10+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
38 small wins to finish your pathNext lesson

Three tickets, and the card number

One program decides where traces and model calls go, and what is stripped before anything leaves. It runs three tickets, one with a card number in it.

This is the only file that knows about servers and keys. The desk module knows none of it.

Exampleapp.py
from langfuse import Langfuse
from langfuse.openai import OpenAI

import local_langfuse
import support_desk
from privacy import mask_cards
from shop_model import reply

url = local_langfuse.start(model=reply)
langfuse = Langfuse(public_key="pk-lf-local", secret_key="sk-lf-local", base_url=url,
                    environment="production", release="2026.03.1", mask_otel_spans=mask_cards)
support_desk.model = OpenAI(base_url=f"{url}/v1", api_key="not-a-real-key")
langfuse.create_prompt(name="desk-system", prompt=support_desk.FALLBACK, labels=["production"])

The client carries the environment and the version of the deployment, so traces can be filtered by either, and the masking function from part 4, which runs on everything exported. The desk's model client is set here too, which is how the tests point it somewhere else.

Exampleapp.py, continued
tickets = [("ticket-1042", "Where is my order A17?"),
           ("ticket-1043", "Is B22 on its way? Card 4111 1111 1111 1111 was charged."),
           ("ticket-1044", "I want a refund for A17")]
for number, text in tickets:
    print(number, "->", support_desk.handle(number, text, customer="cust-42", chat="chat-0042"))
support_desk.record_feedback("ticket-1043", helpful=False, comment="B22 is on my receipt")

langfuse.flush()
local_langfuse.tree()
print([(s["name"], s["attributes"]["langfuse.observation.status_message"]) for s in local_langfuse.SPANS
       if s["attributes"].get("langfuse.observation.level") == "WARNING"])
print("card exported:", "4111" in str([s["attributes"] for s in local_langfuse.SPANS]))
Example
python app.py

Three traces, each rooted in support-ticket with the model call and any lookup under it. The B22 ticket carries the warning. The card number reached the desk and was replaced before export, so the last line prints False.

Three tickets through the traced support desk
support-ticketorder idthenticketmay hold a cardanswer-ticketagent, prompt from Langfuselookup-ordertool, WARNING when missingwrite-replygeneration via langfuse.openaimask_cardsmask_otel_spanslocal_langfusewhat was sentrecord_feedbackscore by ticket id
Hover or tap a piece to see what it is and which lesson built it.
Follow a ticket

Pick one to watch it run, step by step.

Click through the three tickets in the drawing: the answer, the warning and the masked card each take a different path through the same desk.

Try it yourself
  • Add a fourth ticket with an email address and mask that too.
  • Set environment="staging" and find it on the observations.
  • Remove mask_otel_spans and watch the last line turn to True.

Slow is fine. Stopping is the only problem.