Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
kalshi (0.0.2)
kalshi (0.0.3)
dry-cli
dry-configurable
dry-container
Expand Down Expand Up @@ -230,7 +230,7 @@ CHECKSUMS
httpx (1.7.0) sha256=e219689555951f9c13c40862da120cdd2535e1454189bed589f04d7059557154
io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc
json (2.18.0) sha256=b10506aee4183f5cf49e0efc48073d7b75843ce3782c68dbeb763351c08fd505
kalshi (0.0.2)
kalshi (0.0.3)
language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
Expand Down
36 changes: 35 additions & 1 deletion lib/kalshi/api_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,46 @@

module Rubyists
module Kalshi
# API Client Base Class
# Base class for API client wrappers that automatically configure URL prefixes
#
# @example Using ApiClient with a Search namespace
# # For Rubyists::Kalshi::Search::Client, the prefix will be "search"
# class Search::Client < ApiClient
# # API calls will automatically use /search/ prefix
# end
#
# @example Overriding the automatic prefix
# class CustomClient < ApiClient
# self.prefix = 'custom_api'
# end
class ApiClient
attr_reader :client

# Automatically extract the URL prefix from the module hierarchy
#
# The prefix is derived by taking the second-to-last component of the
# fully qualified class name and converting it to lowercase. For example:
# - Rubyists::Kalshi::Search::Client => "search"
# - Rubyists::Kalshi::Market::Client => "market"
#
# @return [String] the URL prefix for API calls
def self.prefix
@prefix ||= to_s.split('::')[-2].downcase
end

# Set a custom URL prefix for API calls, for overriding the default behavior
def self.prefix=(value) # rubocop:disable Style/TrivialAccessors
@prefix = value
end

# Initialize the ApiClient with a given client instance
#
# @param client [Rubyists::Kalshi::Client] the client instance to wrap
#
# @return [void]
def initialize(client)
@client = client
client.prefix = self.class.prefix
Comment on lines 10 to +44
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initialize method modifies the shared client instance by setting its prefix. This creates a side effect where if the same client instance is reused across multiple ApiClient subclasses, the prefix will be overwritten. Consider if this is the intended behavior or if each ApiClient should use its own client instance.

Suggested change
@client = client
client.prefix = self.class.prefix
@client = client.dup
@client.prefix = self.class.prefix

Copilot uses AI. Check for mistakes.
end
Comment on lines 42 to 45
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initialize method in ApiClient lacks test coverage. Consider adding a test that verifies the client is properly assigned and that the prefix is set on the client instance when an ApiClient subclass is instantiated.

Copilot uses AI. Check for mistakes.
end
end
Expand Down
6 changes: 5 additions & 1 deletion lib/kalshi/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ def initialize(base_url: Kalshi.config.base_url)
end

def get(path, params: {})
response = @http.get(full_url(path), params:)
get_without_prefix(full_url(path), params:)
end

def get_without_prefix(path, params: {})
response = @http.get(path, params:)
handle_response(response)
end
Comment on lines 22 to 29
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new get_without_prefix method and the refactored get method lack test coverage. Consider adding tests that verify the prefix is correctly applied when calling get, and that get_without_prefix bypasses the prefix logic.

Copilot uses AI. Check for mistakes.

Expand Down
2 changes: 1 addition & 1 deletion lib/kalshi/search/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def tags_by_categories
SeriesTags.new(client).all
end

def filters_by_sports
def filters_by_sport
SportsFilters.new(client).all
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/kalshi/search/series_tags.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Search
# Series Tags API endpoint
class SeriesTags < Kalshi::Endpoint
def all
client.get('search/tags_by_categories')
client.get('tags_by_categories')
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/kalshi/search/sports_filters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Search
# Sports Filters API endpoint
class SportsFilters < Kalshi::Endpoint
def all
client.get('search/filters_by_sports')
client.get('filters_by_sport')
end
end
end
Expand Down
18 changes: 18 additions & 0 deletions test/kalshi/api_client_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

require_relative '../helper'

describe Rubyists::Kalshi::ApiClient do
# rubocop:disable Lint/ConstantDefinitionInBlock
class TestApiClient < Rubyists::Kalshi::ApiClient
end
# rubocop:enable Lint/ConstantDefinitionInBlock

describe '.prefix=' do
it 'sets the prefix' do
TestApiClient.prefix = 'test'

assert_equal 'test', TestApiClient.prefix
end
end
end
8 changes: 4 additions & 4 deletions test/kalshi/search/client_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
end
end

describe '#filters_by_sports' do
it 'fetches filters by sports' do
stub_request(:get, "#{base_url}/search/filters_by_sports")
describe '#filters_by_sport' do
it 'fetches filters by sport' do
stub_request(:get, "#{base_url}/search/filters_by_sport")
.to_return(status: 200, body: '{"filters_by_sports": {}}', headers: { 'Content-Type' => 'application/json' })

response = search_client.filters_by_sports
response = search_client.filters_by_sport

assert_equal({ filters_by_sports: {} }, response)
end
Expand Down