Skip to content

feat(client): add shade.api_base override support#29

Merged
codebestia merged 1 commit into
ShadeProtocol:mainfrom
Tijesunimi004:feature/api-base-override
Jun 26, 2026
Merged

feat(client): add shade.api_base override support#29
codebestia merged 1 commit into
ShadeProtocol:mainfrom
Tijesunimi004:feature/api-base-override

Conversation

@Tijesunimi004

@Tijesunimi004 Tijesunimi004 commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Closes #6

What changed

src/shade/config.py (new)

  • Environment enum with MAINNET and TESTNET variants, each exposing base_url and network_passphrase (sourced from stellar_sdk.Network constants)
  • Module-level api_base: Optional[str] = None — the single source of truth for the global override

src/shade/__init__.py

  • shade.api_base is now a settable module-level attribute backed by config.api_base via a module __class__ override (standard Python pattern — no extra dependencies)
  • Exports Environment and ShadeClient (alias for Gateway)

src/shade/gateway.py

  • New environment: Environment = Environment.MAINNET parameter; controls Stellar network passphrase and fallback URL independently of api_base
  • New api_base: Optional[str] = None parameter; takes precedence over the module-level value and environment URL
  • Resolution order: explicit api_base arg > shade.api_base > legacy base_url > environment.base_url
  • Trailing slashes stripped from whichever source wins

tests/test_api_base.py (new, 23 tests)

  • Module-level read/write, trailing slash normalisation, reset behaviour
  • Per-client override, HTTP client propagation
  • Precedence ordering
  • Environment URL and passphrase values
  • ShadeClient alias

Acceptance criteria

Criterion How it is met
shade.api_base = "https://staging..." routes all requests there Module-level attribute writes through to config.api_base; Gateway reads it at init time
ShadeClient(api_base="http://localhost:8000") routes locally api_base param beats module-level and environment URL
Environment still controls Stellar network passphrase when api_base is set gateway.environment is stored independently; only URL resolution uses api_base
Trailing slashes normalised resolved.rstrip("/") applied to the winning value

Summary by CodeRabbit

  • New Features

    • Added support for selecting between mainnet and testnet environments.
    • Added a configurable API base URL override for custom deployments and testing.
    • Introduced a ShadeClient alias for the main client interface.
  • Bug Fixes

    • Ensured API base URL values are normalized consistently, including trailing slashes.
    • Preserved network passphrase selection when overriding the API base URL.

- Add config.py with Environment enum (MAINNET/TESTNET) exposing base_url
  and network_passphrase via stellar_sdk.Network constants
- Add shade.api_base module-level attribute (backed by config.api_base)
  that routes all new clients to a custom host when set
- Add api_base and environment parameters to Gateway; resolution order:
  explicit api_base > shade.api_base > legacy base_url > environment URL
- Trailing slashes on any provided api_base are trimmed
- Export ShadeClient as an alias for Gateway
- Add tests covering all acceptance criteria
Copilot AI review requested due to automatic review settings June 25, 2026 16:07
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds module-level API base override support, introduces Environment for mainnet/testnet URLs and network passphrases, updates Gateway URL resolution to honor explicit and global overrides, and expands tests for module exports, precedence, and environment behavior.

Changes

API base override support

Layer / File(s) Summary
Config and environment values
src/shade/config.py, tests/test_api_base.py
shade.config defines api_base and Environment, with tests covering environment URL and network passphrase values.
Module exports and api_base bridge
src/shade/__init__.py, tests/test_api_base.py
shade exports Environment, ShadeClient, and module-level api_base, with tests covering the module override state and alias behavior.
Gateway URL resolution
src/shade/gateway.py, tests/test_api_base.py
Gateway.__init__ resolves _base_url from explicit, module, legacy, or environment values, and tests cover per-client precedence, trailing-slash normalization, and passphrase behavior.

Sequence Diagram(s)

sequenceDiagram
  participant ClientCode as Client code
  participant ShadeApiBase as shade.api_base
  participant ConfigApiBase as shade.config.api_base
  participant GatewayInit as Gateway.__init__
  participant HttpClients as sync and async HTTP clients

  ClientCode->>ShadeApiBase: set api_base
  ShadeApiBase->>ConfigApiBase: store override value
  ClientCode->>GatewayInit: create Gateway(api_base=...)
  GatewayInit->>ConfigApiBase: read module-level api_base
  GatewayInit->>GatewayInit: resolve api_base, _config.api_base, base_url, Environment.base_url
  GatewayInit->>HttpClients: initialize with resolved _base_url
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A rabbit hopped through URL vines 🌿
and found a shiny api_base sign.
Mainnet stayed star-bright, testnet too,
while gateway hops arrived just right.
Hop-hop — the shade was fine! 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description summarizes the feature but omits the template's type, testing, and checklist sections. Add the required Type of change, How Has This Been Tested, and Checklist sections, and use the template's Fixes # format.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding shade.api_base override support.
Linked Issues check ✅ Passed The changes implement the requested api_base override, precedence, trailing-slash trimming, and preserved environment passphrase behavior.
Out of Scope Changes check ✅ Passed No clearly unrelated changes stand out; the added exports, config, gateway updates, and tests all support the requested override feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds first-class support for overriding the Shade API base URL at both the module level (shade.api_base) and per-client level (Gateway(api_base=...)), while introducing an Environment enum to standardize default URLs and Stellar network passphrases.

Changes:

  • Introduces shade.config.Environment and a module-level config.api_base override source of truth.
  • Updates Gateway to resolve its base URL via a defined precedence order and normalize trailing slashes.
  • Adds a comprehensive test suite for api_base behavior and exports ShadeClient as an alias for Gateway.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/shade/config.py Adds Environment enum and global api_base override storage.
src/shade/__init__.py Exposes shade.api_base as a settable module attribute; exports Environment and ShadeClient.
src/shade/gateway.py Implements URL resolution precedence across api_base, module override, legacy base_url, and environment defaults.
tests/test_api_base.py Adds tests covering override behavior, precedence, normalization, environment passphrases, and ShadeClient aliasing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/shade/gateway.py
Comment on lines 35 to +39
def __init__(
self,
api_key: str = "",
environment: Environment = Environment.MAINNET,
api_base: Optional[str] = None,
Comment thread tests/test_api_base.py
Comment on lines +123 to +141
class TestUrlResolutionPrecedence:
def test_environment_url_is_default(self):
gw = Gateway(api_key="test-key", environment=Environment.MAINNET)
assert gw._base_url == Environment.MAINNET.base_url

def test_module_level_beats_environment(self):
shade.api_base = "https://staging.shadeprotocol.io"
gw = Gateway(api_key="test-key", environment=Environment.MAINNET)
assert gw._base_url == "https://staging.shadeprotocol.io"

def test_per_client_beats_module_level(self):
shade.api_base = "https://staging.shadeprotocol.io"
gw = Gateway(api_key="test-key", api_base="http://localhost:8000")
assert gw._base_url == "http://localhost:8000"

def test_testnet_environment_url_used_by_default(self):
gw = Gateway(api_key="test-key", environment=Environment.TESTNET)
assert gw._base_url == Environment.TESTNET.base_url

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/shade/gateway.py (1)

49-52: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Confirm intended precedence: global shade.api_base overrides an explicitly-passed per-client base_url.

In api_base or _config.api_base or base_url or environment.base_url, a process-wide shade.api_base outranks a per-client legacy base_url= argument. A caller who explicitly passes the (deprecated but still supported) base_url per client may be surprised to have it silently overridden by a global. If the intent is that any explicit per-client argument should win over the module-level global, consider ordering legacy base_url ahead of _config.api_base.

♻️ Optional reordering so explicit per-client args beat the global
-        resolved = api_base or _config.api_base or base_url or environment.base_url
+        resolved = api_base or base_url or _config.api_base or environment.base_url

Confirm the desired precedence between per-client base_url and global shade.api_base; current tests don't exercise this combination.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/shade/gateway.py` around lines 49 - 52, Confirm and enforce the intended
URL precedence in Gateway initialization: the current resolution in
Gateway.__init__ lets the module-level shade.api_base override an explicitly
passed per-client base_url, which may be unintended. Update the ordering of
resolved so the chosen precedence is explicit and consistent, then add or adjust
tests covering the interaction between the deprecated base_url argument and
_config.api_base to lock in the behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/shade/gateway.py`:
- Around line 49-52: Confirm and enforce the intended URL precedence in Gateway
initialization: the current resolution in Gateway.__init__ lets the module-level
shade.api_base override an explicitly passed per-client base_url, which may be
unintended. Update the ordering of resolved so the chosen precedence is explicit
and consistent, then add or adjust tests covering the interaction between the
deprecated base_url argument and _config.api_base to lock in the behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 70ae44dd-f123-413d-bc40-c6356f0c8509

📥 Commits

Reviewing files that changed from the base of the PR and between f6a4cff and 3d21f6d.

📒 Files selected for processing (4)
  • src/shade/__init__.py
  • src/shade/config.py
  • src/shade/gateway.py
  • tests/test_api_base.py

@codebestia

Copy link
Copy Markdown
Contributor

@Tijesunimi004
Please resolve the coderabbit reviews

@codebestia codebestia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM!
Thank you for your contribution.

@codebestia codebestia merged commit 3ad7931 into ShadeProtocol:main Jun 26, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add shade.api_base override support

3 participants