Skip to content

Commit 1bce3cf

Browse files
committed
feat(traces): add list_traces and get_trace endpoints
Expose trace listing with full filter/pagination support and single-trace fetch via the public API, with corresponding Client delegation, tests, and API reference docs.
1 parent 2299101 commit 1bce3cf

5 files changed

Lines changed: 622 additions & 0 deletions

File tree

docs/API_REFERENCE.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Complete method reference for the Langfuse Ruby SDK.
88
- [Client Access](#client-access)
99
- [Prompt Management](#prompt-management)
1010
- [Tracing & Observability](#tracing--observability)
11+
- [Traces](#traces)
1112
- [Scoring](#scoring)
1213
- [Datasets](#datasets)
1314
- [Experiments](#experiments)
@@ -513,6 +514,92 @@ obs.update(
513514
)
514515
```
515516

517+
## Traces
518+
519+
### `Client#list_traces`
520+
521+
List traces in the project.
522+
523+
**Signature:**
524+
525+
```ruby
526+
list_traces(page: nil, limit: nil, **filters)
527+
```
528+
529+
**Parameters:**
530+
531+
| Parameter | Type | Required | Description |
532+
| ---------------- | ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- |
533+
| `page` | Integer | No | Page number |
534+
| `limit` | Integer | No | Results per page |
535+
| `user_id` | String | No | Filter by user ID |
536+
| `name` | String | No | Filter by trace name |
537+
| `session_id` | String | No | Filter by session ID |
538+
| `from_timestamp` | Time | No | Filter traces after this time |
539+
| `to_timestamp` | Time | No | Filter traces before this time |
540+
| `order_by` | String | No | Order by field |
541+
| `tags` | Array<String> | No | Filter by tags |
542+
| `version` | String | No | Filter by version |
543+
| `release` | String | No | Filter by release |
544+
| `environment` | String | No | Filter by environment |
545+
| `fields` | String | No | Comma-separated field groups to include (e.g. `"core,scores,metrics"`). Available: `core`, `io`, `scores`, `observations`, `metrics`. All fields returned if omitted. |
546+
| `filter` | String | No | JSON string for advanced filtering |
547+
548+
**Returns:** `Array<Hash>` of trace data
549+
550+
**Raises:**
551+
552+
- `UnauthorizedError` if authentication fails
553+
- `ApiError` for other API errors
554+
555+
**Examples:**
556+
557+
```ruby
558+
# Basic listing
559+
traces = client.list_traces(page: 1, limit: 20)
560+
561+
# Filter by user and name
562+
traces = client.list_traces(user_id: "user-123", name: "my-trace")
563+
564+
# Time range with field selection
565+
traces = client.list_traces(
566+
from_timestamp: Time.utc(2025, 1, 1),
567+
to_timestamp: Time.utc(2025, 1, 31),
568+
fields: "core,scores"
569+
)
570+
```
571+
572+
### `Client#get_trace`
573+
574+
Fetch a single trace by ID.
575+
576+
**Signature:**
577+
578+
```ruby
579+
get_trace(id) # => Hash
580+
```
581+
582+
**Parameters:**
583+
584+
| Parameter | Type | Required | Description |
585+
| --------- | ------ | -------- | ----------- |
586+
| `id` | String | Yes | Trace ID |
587+
588+
**Returns:** `Hash` of trace data
589+
590+
**Raises:**
591+
592+
- `NotFoundError` if the trace doesn't exist
593+
- `UnauthorizedError` if authentication fails
594+
- `ApiError` for other API errors
595+
596+
**Example:**
597+
598+
```ruby
599+
trace = client.get_trace("trace-uuid-123")
600+
puts trace["name"]
601+
```
602+
516603
## Scoring
517604

518605
### `Client#create_score`

lib/langfuse/api_client.rb

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,85 @@ def shutdown
285285
cache.shutdown if cache.respond_to?(:shutdown)
286286
end
287287

288+
# List traces in the project
289+
#
290+
# @param page [Integer, nil] Optional page number for pagination
291+
# @param limit [Integer, nil] Optional limit per page
292+
# @param user_id [String, nil] Filter by user ID
293+
# @param name [String, nil] Filter by trace name
294+
# @param session_id [String, nil] Filter by session ID
295+
# @param from_timestamp [Time, nil] Filter traces after this time
296+
# @param to_timestamp [Time, nil] Filter traces before this time
297+
# @param order_by [String, nil] Order by field
298+
# @param tags [Array<String>, nil] Filter by tags
299+
# @param version [String, nil] Filter by version
300+
# @param release [String, nil] Filter by release
301+
# @param environment [String, nil] Filter by environment
302+
# @param fields [String, nil] Comma-separated field groups to include (e.g. "core,scores,metrics")
303+
# @param filter [String, nil] JSON string for advanced filtering
304+
# @return [Array<Hash>] Array of trace hashes
305+
# @raise [UnauthorizedError] if authentication fails
306+
# @raise [ApiError] for other API errors
307+
#
308+
# @example
309+
# traces = api_client.list_traces(page: 1, limit: 10, name: "my-trace")
310+
# rubocop:disable Metrics/ParameterLists
311+
def list_traces(page: nil, limit: nil, user_id: nil, name: nil, session_id: nil,
312+
from_timestamp: nil, to_timestamp: nil, order_by: nil,
313+
tags: nil, version: nil, release: nil, environment: nil,
314+
fields: nil, filter: nil)
315+
result = list_traces_paginated(
316+
page: page, limit: limit, user_id: user_id, name: name,
317+
session_id: session_id, from_timestamp: from_timestamp,
318+
to_timestamp: to_timestamp, order_by: order_by, tags: tags,
319+
version: version, release: release, environment: environment,
320+
fields: fields, filter: filter
321+
)
322+
result["data"] || []
323+
end
324+
# rubocop:enable Metrics/ParameterLists
325+
326+
# Full paginated response including "meta" for internal pagination use
327+
#
328+
# @api private
329+
# @return [Hash] Full response hash with "data" array and "meta" pagination info
330+
# rubocop:disable Metrics/ParameterLists
331+
def list_traces_paginated(page: nil, limit: nil, user_id: nil, name: nil, session_id: nil,
332+
from_timestamp: nil, to_timestamp: nil, order_by: nil,
333+
tags: nil, version: nil, release: nil, environment: nil,
334+
fields: nil, filter: nil)
335+
with_faraday_error_handling do
336+
params = build_traces_params(
337+
page: page, limit: limit, user_id: user_id, name: name,
338+
session_id: session_id, from_timestamp: from_timestamp,
339+
to_timestamp: to_timestamp, order_by: order_by, tags: tags,
340+
version: version, release: release, environment: environment,
341+
fields: fields, filter: filter
342+
)
343+
response = connection.get("/api/public/traces", params)
344+
handle_response(response)
345+
end
346+
end
347+
# rubocop:enable Metrics/ParameterLists
348+
349+
# Fetch a trace by ID
350+
#
351+
# @param id [String] Trace ID
352+
# @return [Hash] The trace data
353+
# @raise [NotFoundError] if the trace is not found
354+
# @raise [UnauthorizedError] if authentication fails
355+
# @raise [ApiError] for other API errors
356+
#
357+
# @example
358+
# trace = api_client.get_trace("trace-uuid-123")
359+
def get_trace(id)
360+
with_faraday_error_handling do
361+
encoded_id = URI.encode_uri_component(id)
362+
response = connection.get("/api/public/traces/#{encoded_id}")
363+
handle_response(response)
364+
end
365+
end
366+
288367
# List all datasets in the project
289368
#
290369
# @param page [Integer, nil] Optional page number for pagination
@@ -525,6 +604,23 @@ def build_dataset_items_params(dataset_name:, page:, limit:,
525604
}.compact
526605
end
527606

607+
# Build query params for list_traces, mapping snake_case to camelCase
608+
# rubocop:disable Metrics/ParameterLists
609+
def build_traces_params(page:, limit:, user_id:, name:, session_id:,
610+
from_timestamp:, to_timestamp:, order_by:,
611+
tags:, version:, release:, environment:, fields:, filter:)
612+
{
613+
page: page, limit: limit, userId: user_id, name: name,
614+
sessionId: session_id,
615+
fromTimestamp: from_timestamp&.iso8601,
616+
toTimestamp: to_timestamp&.iso8601,
617+
orderBy: order_by, tags: tags, version: version,
618+
release: release, environment: environment, fields: fields,
619+
filter: filter
620+
}.compact
621+
end
622+
# rubocop:enable Metrics/ParameterLists
623+
528624
# Fetch with SWR cache
529625
def fetch_with_swr_cache(cache_key, name, version, label)
530626
cache.fetch_with_stale_while_revalidate(cache_key) do

lib/langfuse/client.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,35 @@ def list_datasets(page: nil, limit: nil)
439439
api_client.list_datasets(page: page, limit: limit)
440440
end
441441

442+
# List traces in the project
443+
#
444+
# @param page [Integer, nil] Optional page number for pagination
445+
# @param limit [Integer, nil] Optional limit per page
446+
# @param filters [Hash] Additional filters (user_id, name, session_id, etc.)
447+
# @return [Array<Hash>] Array of trace hashes
448+
# @raise [UnauthorizedError] if authentication fails
449+
# @raise [ApiError] for other API errors
450+
#
451+
# @example
452+
# traces = client.list_traces(page: 1, limit: 10, name: "my-trace")
453+
def list_traces(page: nil, limit: nil, **filters)
454+
api_client.list_traces(page: page, limit: limit, **filters)
455+
end
456+
457+
# Fetch a trace by ID
458+
#
459+
# @param id [String] Trace ID
460+
# @return [Hash] The trace data
461+
# @raise [NotFoundError] if the trace is not found
462+
# @raise [UnauthorizedError] if authentication fails
463+
# @raise [ApiError] for other API errors
464+
#
465+
# @example
466+
# trace = client.get_trace("trace-uuid-123")
467+
def get_trace(id)
468+
api_client.get_trace(id)
469+
end
470+
442471
# Create a new dataset item
443472
#
444473
# @param dataset_name [String] Name of the dataset to add item to (required)

0 commit comments

Comments
 (0)