Skip to content

Config: validate base_url includes /trade-api/v2 path component (silent sign-path corruption) #202

Closed

Description

@TexasCoding

Summary

SyncTransport.__init__ caches self._base_path = urlparse(config.base_url).path and signs requests with sign_path = self._base_path + path. The signature MUST be computed over the canonical server-visible path (/trade-api/v2/markets).

If a user constructs KalshiConfig(base_url="https://api.elections.kalshi.com") — dropping the /trade-api/v2 path component, which _validate_url does NOT require — _base_path becomes "" and every request is signed as /markets instead of /trade-api/v2/markets. Worse:

  • The httpx request goes to https://api.elections.kalshi.com/markets (no /trade-api/v2 prefix), producing a 404.
  • If the user adds /trade-api/v2/ to each call manually thinking they have to compensate, signing breaks invisibly with 401s.

_validate_url (kalshi/config.py:67-95) validates scheme + host but never path, so this misconfig is undetectable until first request.

Location

  • kalshi/_base_client.py:102 — self._base_path = urlparse(config.base_url).path
  • kalshi/_base_client.py:136 — sign_path = self._base_path + path
  • kalshi/config.py:67-95 — _validate_url (scheme/host only)

Evidence

# kalshi/_base_client.py:102
self._base_path = urlparse(config.base_url).path  # "" if base_url has no path

# kalshi/_base_client.py:136
sign_path = self._base_path + path  # corrupted if path component missing
# kalshi/config.py:67-95
# _validate_url checks scheme + host only, never path → misconfig is silent

Recommended fix

In KalshiConfig.__post_init__ (or _validate_url), require the base_url path to be the canonical versioned segment (/trade-api/v2). Two options:

Strict (recommended):

parsed = urlparse(base_url)
if parsed.path not in ("/trade-api/v2", "/trade-api/v2/"):
    raise ValueError(
        f"KalshiConfig.base_url must include the /trade-api/v2 path component, "
        f"got base_url={base_url!r}"
    )

Lenient (auto-fix):
If path is empty/just /, append /trade-api/v2 and log a warning. Strict is preferred because it surfaces the misconfig at construction.

Add tests:

  • test_base_url_without_path_raises
  • test_base_url_with_trade_api_v2_accepted
  • test_base_url_with_trailing_slash_accepted

Severity & category

medium / correctness

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions