Class: Langfuse::ApiClient
- Inherits:
-
Object
- Object
- Langfuse::ApiClient
- 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.
Instance Attribute Summary collapse
-
#base_url ⇒ Object
readonly
rubocop:disable Metrics/ClassLength.
-
#cache ⇒ Object
readonly
rubocop:disable Metrics/ClassLength.
-
#logger ⇒ Object
readonly
rubocop:disable Metrics/ClassLength.
-
#public_key ⇒ Object
readonly
rubocop:disable Metrics/ClassLength.
-
#secret_key ⇒ Object
readonly
rubocop:disable Metrics/ClassLength.
-
#timeout ⇒ Object
readonly
rubocop:disable Metrics/ClassLength.
Instance Method Summary collapse
-
#connection(timeout: nil) ⇒ Faraday::Connection
Get a Faraday connection.
-
#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).
-
#get_prompt(name, version: nil, label: nil) ⇒ Hash
Fetch a prompt from the Langfuse API.
-
#initialize(public_key:, secret_key:, base_url:, timeout: 5, logger: nil, cache: nil) ⇒ ApiClient
constructor
Initialize a new API client.
-
#list_prompts(page: nil, limit: nil) ⇒ Array<Hash>
List all prompts in the Langfuse project.
-
#send_batch(events) ⇒ void
Send a batch of events to the Langfuse ingestion API.
- #shutdown ⇒ Object
-
#update_prompt(name:, version:, labels:) ⇒ Hash
Update labels for an existing prompt version.
Constructor Details
#initialize(public_key:, secret_key:, base_url:, timeout: 5, logger: nil, cache: nil) ⇒ ApiClient
Initialize a new API client
35 36 37 38 39 40 41 42 |
# File 'lib/langfuse/api_client.rb', line 35 def initialize(public_key:, secret_key:, base_url:, timeout: 5, logger: nil, cache: 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 end |
Instance Attribute Details
#base_url ⇒ Object (readonly)
rubocop:disable Metrics/ClassLength
25 26 27 |
# File 'lib/langfuse/api_client.rb', line 25 def base_url @base_url end |
#cache ⇒ Object (readonly)
rubocop:disable Metrics/ClassLength
25 26 27 |
# File 'lib/langfuse/api_client.rb', line 25 def cache @cache end |
#logger ⇒ Object (readonly)
rubocop:disable Metrics/ClassLength
25 26 27 |
# File 'lib/langfuse/api_client.rb', line 25 def logger @logger end |
#public_key ⇒ Object (readonly)
rubocop:disable Metrics/ClassLength
25 26 27 |
# File 'lib/langfuse/api_client.rb', line 25 def public_key @public_key end |
#secret_key ⇒ Object (readonly)
rubocop:disable Metrics/ClassLength
25 26 27 |
# File 'lib/langfuse/api_client.rb', line 25 def secret_key @secret_key end |
#timeout ⇒ Object (readonly)
rubocop:disable Metrics/ClassLength
25 26 27 |
# File 'lib/langfuse/api_client.rb', line 25 def timeout @timeout end |
Instance Method Details
#connection(timeout: nil) ⇒ Faraday::Connection
Get a Faraday connection
48 49 50 51 52 53 54 55 56 |
# File 'lib/langfuse/api_client.rb', line 48 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_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
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/langfuse/api_client.rb', line 137 def create_prompt(name:, prompt:, type:, config: {}, labels: [], tags: [], commit_message: nil) path = "/api/public/v2/prompts" payload = { name: name, prompt: prompt, type: type, config: config, labels: labels, tags: } payload[:commitMessage] = if response = connection.post(path, payload) handle_response(response) rescue Faraday::RetriableResponse => e logger.error("Faraday error: Retries exhausted - #{e.response.status}") handle_response(e.response) rescue Faraday::Error => e logger.error("Faraday error: #{e.}") raise ApiError, "HTTP request failed: #{e.}" end |
#get_prompt(name, version: nil, label: 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.
107 108 109 110 111 112 113 |
# File 'lib/langfuse/api_client.rb', line 107 def get_prompt(name, version: nil, label: nil) raise ArgumentError, "Cannot specify both version and label" if version && label return fetch_prompt_from_api(name, version: version, label: label) if cache.nil? cache_key = PromptCache.build_key(name, version: version, label: label) fetch_with_appropriate_caching_strategy(cache_key, name, version, label) 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.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/langfuse/api_client.rb', line 74 def list_prompts(page: nil, limit: nil) params = {} params[:page] = page if page params[:limit] = limit if limit path = "/api/public/v2/prompts" response = connection.get(path, params) result = handle_response(response) # API returns { data: [...], meta: {...} } result["data"] || [] rescue Faraday::RetriableResponse => e logger.error("Faraday error: Retries exhausted - #{e.response.status}") handle_response(e.response) rescue Faraday::Error => e logger.error("Faraday error: #{e.}") raise ApiError, "HTTP request failed: #{e.}" 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.
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/langfuse/api_client.rb', line 214 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? path = "/api/public/ingestion" payload = { batch: events } response = connection.post(path, payload) handle_batch_response(response) rescue Faraday::RetriableResponse => e # Retry middleware exhausted all retries - handle the final response 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 ⇒ Object
232 233 234 |
# File 'lib/langfuse/api_client.rb', line 232 def shutdown cache.shutdown if cache.respond_to?(:shutdown) end |
#update_prompt(name:, version:, labels:) ⇒ Hash
Update labels for an existing prompt version
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/langfuse/api_client.rb', line 177 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}" payload = { newLabels: labels } response = connection.patch(path, payload) handle_response(response) rescue Faraday::RetriableResponse => e logger.error("Faraday error: Retries exhausted - #{e.response.status}") handle_response(e.response) rescue Faraday::Error => e logger.error("Faraday error: #{e.}") raise ApiError, "HTTP request failed: #{e.}" end |