Class: Langfuse::ApiClient
- Inherits:
-
Object
- Object
- Langfuse::ApiClient
- Includes:
- PromptCacheEvents
- Defined in:
- lib/langfuse/api_client.rb
Overview
HTTP client for Langfuse API
Handles authentication, connection management, and HTTP requests to the Langfuse REST API.
Constant Summary
Constants included from PromptCacheEvents
PromptCacheEvents::PROMPT_CACHE_NOTIFICATION
Instance Attribute Summary collapse
-
#base_url ⇒ String
readonly
Base URL for Langfuse API.
-
#cache ⇒ PromptCache, ...
readonly
Optional cache for prompt responses.
-
#logger ⇒ Logger
readonly
Logger instance for debugging.
-
#public_key ⇒ String
readonly
Langfuse public API key.
-
#secret_key ⇒ String
readonly
Langfuse secret API key.
-
#timeout ⇒ Integer
readonly
HTTP request timeout in seconds.
Instance Method Summary collapse
-
#clear_prompt_cache ⇒ Integer?
Logically clear the whole Langfuse prompt cache namespace.
-
#connection(timeout: nil) ⇒ Faraday::Connection
Get a Faraday connection.
-
#create_dataset(name:, description: nil, metadata: nil) ⇒ Hash
Create a new dataset.
-
#create_dataset_item(dataset_name:, input: nil, expected_output: nil, metadata: nil, id: nil, source_trace_id: nil, source_observation_id: nil, status: nil) ⇒ Hash
Create a new dataset item (or upsert if id is provided).
-
#create_dataset_run_item(dataset_item_id:, run_name:, trace_id: nil, observation_id: nil, metadata: nil, run_description: nil) ⇒ Hash
Create a dataset run item (link a trace to a dataset item within a run).
-
#create_prompt(name:, prompt:, type:, config: {}, labels: [], tags: [], commit_message: nil) ⇒ Hash
Create a new prompt (or new version if prompt with same name exists).
-
#delete_dataset_item(id) ⇒ Hash
Delete a dataset item by ID.
-
#delete_dataset_run(dataset_name:, run_name:) ⇒ Hash?
Delete a dataset run by name.
-
#get_dataset(name) ⇒ Hash
Fetch a dataset by name.
-
#get_dataset_item(id) ⇒ Hash
Fetch a dataset item by ID.
-
#get_dataset_run(dataset_name:, run_name:) ⇒ Hash
Fetch a dataset run by dataset and run name.
-
#get_projects ⇒ Hash
Fetch projects accessible with the current API keys.
-
#get_prompt(name, version: nil, label: nil, cache_ttl: nil) ⇒ Hash
Fetch a prompt from the Langfuse API.
-
#get_prompt_result(name, version: nil, label: nil, cache_ttl: nil) ⇒ PromptFetchResult
Fetch a prompt and include cache metadata.
-
#get_trace(id) ⇒ Hash
Fetch a trace by ID.
-
#initialize(public_key:, secret_key:, base_url:, timeout: 5, logger: nil, cache: nil, cache_observer: nil) ⇒ ApiClient
constructor
Initialize a new API client.
-
#invalidate_prompt_cache(name, version: nil, label: nil) ⇒ PromptCacheKey
Invalidate one exact logical prompt cache key.
-
#invalidate_prompt_cache_by_name(name) ⇒ Integer?
Invalidate all cached variants for one prompt name.
-
#list_dataset_items ⇒ Array<Hash>
List items in a dataset with optional filters.
-
#list_dataset_items_paginated(dataset_name:, page: nil, limit: nil, source_trace_id: nil, source_observation_id: nil) ⇒ Hash
private
Full paginated response including “meta” for internal pagination use.
-
#list_dataset_runs(dataset_name:, page: nil, limit: nil) ⇒ Array<Hash>
List dataset runs in a dataset.
-
#list_dataset_runs_paginated(dataset_name:, page: nil, limit: nil) ⇒ Hash
private
Full paginated response including “meta” for internal pagination use.
-
#list_datasets(page: nil, limit: nil) ⇒ Array<Hash>
List all datasets in the project.
-
#list_prompts(page: nil, limit: nil) ⇒ Array<Hash>
List all prompts in the Langfuse project.
-
#list_traces(page: nil, limit: nil, user_id: nil, name: nil, session_id: nil, from_timestamp: nil, to_timestamp: nil, order_by: nil, tags: nil, version: nil, release: nil, environment: nil, fields: nil, filter: nil) ⇒ Array<Hash>
List traces in the project.
-
#list_traces_paginated(page: nil, limit: nil, user_id: nil, name: nil, session_id: nil, from_timestamp: nil, to_timestamp: nil, order_by: nil, tags: nil, version: nil, release: nil, environment: nil, fields: nil, filter: nil) ⇒ Hash
private
Full paginated response including “meta” for internal pagination use.
-
#prompt_cache_key(name, version: nil, label: nil) ⇒ PromptCacheKey
Inspect the logical and generated cache keys for a prompt.
-
#prompt_cache_stats ⇒ Hash
Return prompt cache statistics.
-
#refresh_prompt(name, version: nil, label: nil, cache_ttl: nil) ⇒ PromptFetchResult
Refresh a prompt from the API, optionally writing through to cache.
-
#send_batch(events) ⇒ void
Send a batch of events to the Langfuse ingestion API.
-
#shutdown ⇒ void
Shut down the API client and release resources.
-
#update_prompt(name:, version:, labels:) ⇒ Hash
Update labels for an existing prompt version.
-
#validate_prompt_cache_backend! ⇒ Boolean
Validate the configured prompt cache backend.
Methods included from PromptCacheEvents
build_payload, #emit_prompt_cache_event, #emit_prompt_fallback_event, #setup_prompt_cache_events
Constructor Details
#initialize(public_key:, secret_key:, base_url:, timeout: 5, logger: nil, cache: nil, cache_observer: nil) ⇒ ApiClient
Initialize a new API client
rubocop:disable Metrics/ParameterLists
58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/langfuse/api_client.rb', line 58 def initialize(public_key:, secret_key:, base_url:, timeout: 5, logger: nil, cache: nil, cache_observer: nil) @public_key = public_key @secret_key = secret_key @base_url = base_url @timeout = timeout @logger = logger || Logger.new($stdout, level: Logger::WARN) @cache = cache setup_prompt_cache_events(cache_observer: cache_observer) @prompt_cache_coordinator = PromptCacheCoordinator.new( cache: cache, event_emitter: self, fetch_prompt: ->(name, version:, label:) { fetch_prompt_from_api(name, version: version, label: label) } ) end |
Instance Attribute Details
#base_url ⇒ String (readonly)
Returns Base URL for Langfuse API.
36 37 38 |
# File 'lib/langfuse/api_client.rb', line 36 def base_url @base_url end |
#cache ⇒ PromptCache, ... (readonly)
Returns Optional cache for prompt responses.
45 46 47 |
# File 'lib/langfuse/api_client.rb', line 45 def cache @cache end |
#logger ⇒ Logger (readonly)
Returns Logger instance for debugging.
42 43 44 |
# File 'lib/langfuse/api_client.rb', line 42 def logger @logger end |
#public_key ⇒ String (readonly)
Returns Langfuse public API key.
30 31 32 |
# File 'lib/langfuse/api_client.rb', line 30 def public_key @public_key end |
#secret_key ⇒ String (readonly)
Returns Langfuse secret API key.
33 34 35 |
# File 'lib/langfuse/api_client.rb', line 33 def secret_key @secret_key end |
#timeout ⇒ Integer (readonly)
Returns HTTP request timeout in seconds.
39 40 41 |
# File 'lib/langfuse/api_client.rb', line 39 def timeout @timeout end |
Instance Method Details
#clear_prompt_cache ⇒ Integer?
Logically clear the whole Langfuse prompt cache namespace.
192 193 194 |
# File 'lib/langfuse/api_client.rb', line 192 def clear_prompt_cache @prompt_cache_coordinator.clear_prompt_cache end |
#connection(timeout: nil) ⇒ Faraday::Connection
Get a Faraday connection
78 79 80 81 82 83 84 85 86 |
# File 'lib/langfuse/api_client.rb', line 78 def connection(timeout: nil) if timeout # Create dedicated connection for custom timeout # to avoid mutating shared connection build_connection(timeout: timeout) else @connection ||= build_connection end end |
#create_dataset(name:, description: nil, metadata: nil) ⇒ Hash
Create a new dataset
511 512 513 514 |
# File 'lib/langfuse/api_client.rb', line 511 def create_dataset(name:, description: nil, metadata: nil) request(:post, "/api/public/v2/datasets", body: { name: name, description: description, metadata: }.compact) end |
#create_dataset_item(dataset_name:, input: nil, expected_output: nil, metadata: nil, id: nil, source_trace_id: nil, source_observation_id: nil, status: nil) ⇒ Hash
Create a new dataset item (or upsert if id is provided)
rubocop:disable Metrics/ParameterLists
537 538 539 540 541 542 543 544 545 546 547 |
# File 'lib/langfuse/api_client.rb', line 537 def create_dataset_item(dataset_name:, input: nil, expected_output: nil, metadata: nil, id: nil, source_trace_id: nil, source_observation_id: nil, status: nil) payload = { datasetName: dataset_name, id: id, input: input, expectedOutput: expected_output, metadata: , sourceTraceId: source_trace_id, sourceObservationId: source_observation_id, status: status&.to_s&.upcase }.compact request(:post, "/api/public/dataset-items", body: payload) end |
#create_dataset_run_item(dataset_item_id:, run_name:, trace_id: nil, observation_id: nil, metadata: nil, run_description: nil) ⇒ Hash
Create a dataset run item (link a trace to a dataset item within a run)
321 322 323 324 325 326 327 328 329 |
# File 'lib/langfuse/api_client.rb', line 321 def create_dataset_run_item(dataset_item_id:, run_name:, trace_id: nil, observation_id: nil, metadata: nil, run_description: nil) payload = { datasetItemId: dataset_item_id, runName: run_name, traceId: trace_id, observationId: observation_id, metadata: , runDescription: run_description }.compact request(:post, "/api/public/dataset-run-items", body: payload) end |
#create_prompt(name:, prompt:, type:, config: {}, labels: [], tags: [], commit_message: nil) ⇒ Hash
Create a new prompt (or new version if prompt with same name exists)
rubocop:disable Metrics/ParameterLists
236 237 238 239 240 241 242 243 |
# File 'lib/langfuse/api_client.rb', line 236 def create_prompt(name:, prompt:, type:, config: {}, labels: [], tags: [], commit_message: nil) payload = { name: name, prompt: prompt, type: type, config: config, labels: labels, tags: , commitMessage: }.compact request(:post, "/api/public/v2/prompts", body: payload) .tap { @prompt_cache_coordinator.invalidate_after_mutation(name) } end |
#delete_dataset_item(id) ⇒ Hash
404 responses are treated as success to keep DELETE idempotent across retries
Delete a dataset item by ID
604 605 606 607 608 609 610 611 612 613 |
# File 'lib/langfuse/api_client.rb', line 604 def delete_dataset_item(id) response = connection.delete("/api/public/dataset-items/#{URI.encode_uri_component(id)}") handle_delete_dataset_item_response(response, id) rescue Faraday::RetriableResponse => e logger.error("Faraday error: Retries exhausted - #{e.response.status}") handle_delete_dataset_item_response(e.response, id) rescue Faraday::Error => e logger.error("Faraday error: #{e.}") raise ApiError, "HTTP request failed: #{e.}" end |
#delete_dataset_run(dataset_name:, run_name:) ⇒ Hash?
404 responses raise NotFoundError to preserve strict delete semantics
Delete a dataset run by name
372 373 374 375 376 377 |
# File 'lib/langfuse/api_client.rb', line 372 def delete_dataset_run(dataset_name:, run_name:) with_faraday_error_handling do response = connection.delete(dataset_run_path(dataset_name: dataset_name, run_name: run_name)) response.status == 204 ? nil : handle_response(response) end end |
#get_dataset(name) ⇒ Hash
Fetch a dataset by name
496 497 498 |
# File 'lib/langfuse/api_client.rb', line 496 def get_dataset(name) request(:get, "/api/public/v2/datasets/#{URI.encode_uri_component(name)}") end |
#get_dataset_item(id) ⇒ Hash
Fetch a dataset item by ID
560 561 562 |
# File 'lib/langfuse/api_client.rb', line 560 def get_dataset_item(id) request(:get, "/api/public/dataset-items/#{URI.encode_uri_component(id)}") end |
#get_dataset_run(dataset_name:, run_name:) ⇒ Hash
Fetch a dataset run by dataset and run name
339 340 341 |
# File 'lib/langfuse/api_client.rb', line 339 def get_dataset_run(dataset_name:, run_name:) request(:get, dataset_run_path(dataset_name: dataset_name, run_name: run_name)) end |
#get_projects ⇒ Hash
Fetch projects accessible with the current API keys
388 389 390 |
# File 'lib/langfuse/api_client.rb', line 388 def get_projects # rubocop:disable Naming/AccessorMethodName request(:get, "/api/public/projects") end |
#get_prompt(name, version: nil, label: nil, cache_ttl: nil) ⇒ Hash
Fetch a prompt from the Langfuse API
Checks cache first if caching is enabled. On cache miss, fetches from API and stores in cache. When using Rails.cache backend, uses distributed lock to prevent cache stampedes.
123 124 125 |
# File 'lib/langfuse/api_client.rb', line 123 def get_prompt(name, version: nil, label: nil, cache_ttl: nil) get_prompt_result(name, version: version, label: label, cache_ttl: cache_ttl).prompt end |
#get_prompt_result(name, version: nil, label: nil, cache_ttl: nil) ⇒ PromptFetchResult
Fetch a prompt and include cache metadata.
139 140 141 |
# File 'lib/langfuse/api_client.rb', line 139 def get_prompt_result(name, version: nil, label: nil, cache_ttl: nil) @prompt_cache_coordinator.get_prompt_result(name, version: version, label: label, cache_ttl: cache_ttl) end |
#get_trace(id) ⇒ Hash
Fetch a trace by ID
468 469 470 |
# File 'lib/langfuse/api_client.rb', line 468 def get_trace(id) request(:get, "/api/public/traces/#{URI.encode_uri_component(id)}") end |
#invalidate_prompt_cache(name, version: nil, label: nil) ⇒ PromptCacheKey
Invalidate one exact logical prompt cache key.
177 178 179 |
# File 'lib/langfuse/api_client.rb', line 177 def invalidate_prompt_cache(name, version: nil, label: nil) @prompt_cache_coordinator.invalidate_prompt_cache(name, version: version, label: label) end |
#invalidate_prompt_cache_by_name(name) ⇒ Integer?
Invalidate all cached variants for one prompt name.
185 186 187 |
# File 'lib/langfuse/api_client.rb', line 185 def invalidate_prompt_cache_by_name(name) @prompt_cache_coordinator.invalidate_prompt_cache_by_name(name) end |
#list_dataset_items ⇒ Array<Hash>
List items in a dataset with optional filters
577 578 579 |
# File 'lib/langfuse/api_client.rb', line 577 def list_dataset_items(**) list_dataset_items_paginated(**)["data"] || [] end |
#list_dataset_items_paginated(dataset_name:, page: nil, limit: nil, source_trace_id: nil, source_observation_id: nil) ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Full paginated response including “meta” for internal pagination use
585 586 587 588 589 590 591 592 |
# File 'lib/langfuse/api_client.rb', line 585 def list_dataset_items_paginated(dataset_name:, page: nil, limit: nil, source_trace_id: nil, source_observation_id: nil) params = { datasetName: dataset_name, page: page, limit: limit, sourceTraceId: source_trace_id, sourceObservationId: source_observation_id }.compact request(:get, "/api/public/dataset-items", params: params) end |
#list_dataset_runs(dataset_name:, page: nil, limit: nil) ⇒ Array<Hash>
List dataset runs in a dataset
351 352 353 |
# File 'lib/langfuse/api_client.rb', line 351 def list_dataset_runs(dataset_name:, page: nil, limit: nil) list_dataset_runs_paginated(dataset_name: dataset_name, page: page, limit: limit)["data"] || [] end |
#list_dataset_runs_paginated(dataset_name:, page: nil, limit: nil) ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Full paginated response including “meta” for internal pagination use
359 360 361 |
# File 'lib/langfuse/api_client.rb', line 359 def list_dataset_runs_paginated(dataset_name:, page: nil, limit: nil) request(:get, dataset_runs_path(dataset_name), params: { page: page, limit: limit }.compact) end |
#list_datasets(page: nil, limit: nil) ⇒ Array<Hash>
List all datasets in the project
482 483 484 |
# File 'lib/langfuse/api_client.rb', line 482 def list_datasets(page: nil, limit: nil) request(:get, "/api/public/v2/datasets", params: { page: page, limit: limit }.compact)["data"] || [] end |
#list_prompts(page: nil, limit: nil) ⇒ Array<Hash>
List all prompts in the Langfuse project
Fetches a list of all prompt names available in your project. Note: This returns metadata only, not full prompt content.
104 105 106 |
# File 'lib/langfuse/api_client.rb', line 104 def list_prompts(page: nil, limit: nil) request(:get, "/api/public/v2/prompts", params: { page: page, limit: limit }.compact)["data"] || [] end |
#list_traces(page: nil, limit: nil, user_id: nil, name: nil, session_id: nil, from_timestamp: nil, to_timestamp: nil, order_by: nil, tags: nil, version: nil, release: nil, environment: nil, fields: nil, filter: nil) ⇒ Array<Hash>
List traces in the project
rubocop:disable Metrics/ParameterLists
424 425 426 427 428 429 430 431 432 433 434 435 |
# File 'lib/langfuse/api_client.rb', line 424 def list_traces(page: nil, limit: nil, user_id: nil, name: nil, session_id: nil, from_timestamp: nil, to_timestamp: nil, order_by: nil, tags: nil, version: nil, release: nil, environment: nil, fields: nil, filter: nil) list_traces_paginated( page: page, limit: limit, user_id: user_id, name: name, session_id: session_id, from_timestamp: , to_timestamp: , order_by: order_by, tags: , version: version, release: release, environment: environment, fields: fields, filter: filter )["data"] || [] end |
#list_traces_paginated(page: nil, limit: nil, user_id: nil, name: nil, session_id: nil, from_timestamp: nil, to_timestamp: nil, order_by: nil, tags: nil, version: nil, release: nil, environment: nil, fields: nil, filter: nil) ⇒ Hash
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Full paginated response including “meta” for internal pagination use
rubocop:disable Metrics/ParameterLists
443 444 445 446 447 448 449 450 451 452 453 454 455 |
# File 'lib/langfuse/api_client.rb', line 443 def list_traces_paginated(page: nil, limit: nil, user_id: nil, name: nil, session_id: nil, from_timestamp: nil, to_timestamp: nil, order_by: nil, tags: nil, version: nil, release: nil, environment: nil, fields: nil, filter: nil) params = build_traces_params( page: page, limit: limit, user_id: user_id, name: name, session_id: session_id, from_timestamp: , to_timestamp: , order_by: order_by, tags: , version: version, release: release, environment: environment, fields: fields, filter: filter ) request(:get, "/api/public/traces", params: params) end |
#prompt_cache_key(name, version: nil, label: nil) ⇒ PromptCacheKey
Inspect the logical and generated cache keys for a prompt.
166 167 168 |
# File 'lib/langfuse/api_client.rb', line 166 def prompt_cache_key(name, version: nil, label: nil) @prompt_cache_coordinator.prompt_cache_key(name, version: version, label: label) end |
#prompt_cache_stats ⇒ Hash
Return prompt cache statistics.
199 200 201 |
# File 'lib/langfuse/api_client.rb', line 199 def prompt_cache_stats @prompt_cache_coordinator.prompt_cache_stats end |
#refresh_prompt(name, version: nil, label: nil, cache_ttl: nil) ⇒ PromptFetchResult
Refresh a prompt from the API, optionally writing through to cache.
155 156 157 |
# File 'lib/langfuse/api_client.rb', line 155 def refresh_prompt(name, version: nil, label: nil, cache_ttl: nil) @prompt_cache_coordinator.refresh_prompt(name, version: version, label: label, cache_ttl: cache_ttl) end |
#send_batch(events) ⇒ void
This method returns an undefined value.
Send a batch of events to the Langfuse ingestion API
Sends events (scores, traces, observations) to the ingestion endpoint. Retries transient errors (429, 503, 504, network errors) with exponential backoff. Batch operations are idempotent (events have unique IDs), so retries are safe.
293 294 295 296 297 298 299 300 301 302 303 304 305 |
# File 'lib/langfuse/api_client.rb', line 293 def send_batch(events) raise ArgumentError, "events must be an array" unless events.is_a?(Array) raise ArgumentError, "events array cannot be empty" if events.empty? response = connection.post("/api/public/ingestion", { batch: events }) handle_batch_response(response) rescue Faraday::RetriableResponse => e logger.error("Langfuse batch send failed: Retries exhausted - #{e.response.status}") handle_batch_response(e.response) rescue Faraday::Error => e logger.error("Langfuse batch send failed: #{e.}") raise ApiError, "Batch send failed: #{e.}" end |
#shutdown ⇒ void
This method returns an undefined value.
Shut down the API client and release resources
Shuts down the cache backend’s SWR thread pool when present.
397 398 399 |
# File 'lib/langfuse/api_client.rb', line 397 def shutdown @cache&.shutdown end |
#update_prompt(name:, version:, labels:) ⇒ Hash
Update labels for an existing prompt version
263 264 265 266 267 268 269 |
# File 'lib/langfuse/api_client.rb', line 263 def update_prompt(name:, version:, labels:) raise ArgumentError, "labels must be an array" unless labels.is_a?(Array) path = "/api/public/v2/prompts/#{URI.encode_uri_component(name)}/versions/#{version}" request(:patch, path, body: { newLabels: labels }) .tap { @prompt_cache_coordinator.invalidate_after_mutation(name) } end |
#validate_prompt_cache_backend! ⇒ Boolean
Validate the configured prompt cache backend.
rubocop:disable Naming/PredicateMethod
208 209 210 211 |
# File 'lib/langfuse/api_client.rb', line 208 def validate_prompt_cache_backend! @cache&.validate! true end |