How connection_tester.py Validates AI Provider Credentials with Minimal API Calls

connection_tester.py proves API keys and endpoints by sending a single lightweight GET request to each provider's model-listing endpoint, skipping expensive inference entirely.

Open Notebook is an open-source project that unifies multiple AI providers behind a single interface. In open_notebook/ai/connection_tester.py, the application validates credentials using minimal API calls before any costly inference runs. This design keeps credential checks fast, bandwidth-light, and free of per-token charges while still guaranteeing that the supplied configuration actually works.

Why Minimal API Calls Are Used for Credential Validation

Full chat-completion or embedding requests consume tokens and add latency. Instead, the module issues the smallest possible HTTP request that still requires authentication: listing available models. A successful response proves the endpoint is reachable and the key is valid, while a failure surfaces configuration errors immediately.

Provider-Specific Validation Methods in connection_tester.py

Azure OpenAI

For Azure, _test_azure_connection (lines 40-71) sends a GET request to {endpoint}/openai/models?api-version={version}. This endpoint is authenticated but stateless, so a 200 response confirms both the endpoint and API key are functional. If the caller omits values, the function derives defaults from AZURE_* environment variables (lines 51-54).

Ollama

The _test_ollama_connection helper (lines 97-113) hits {base_url}/api/tags. Because this route returns the catalog of locally available models, a successful 200 proves the Ollama server is running and reachable without executing inference.

OpenAI-Compatible Servers

For generic OpenAI-compatible backends, _test_openai_compatible_connection (lines 32-45) calls GET {base_url}/models, optionally injecting an Authorization: Bearer header. A 200 response validates the custom base URL and token without running a model.

Generic Providers

Major hosted providers such as OpenAI, Anthropic, Google, and Groq are not validated via an early network call in this module. Instead, connection_tester.py defers to the provider-specific ModelManager—defined in open_notebook/ai/models.py—when test_individual_model is invoked later in the lifecycle.

Request Flow and Response Interpretation

The validation sequence in open_notebook/ai/connection_tester.py follows a strict five-step pattern:

  1. Select the helper based on the provider name, such as azure, ollama, or openai_compatible.
  2. Derive defaults from environment variables when the caller supplies empty values.
  3. Issue a single GET request through httpx.AsyncClient with a sharp 10-second timeout.
  4. Interpret the status code:
    • 200 → success; the function extracts a short list of model names for a friendly confirmation message.
    • 401 → returned as "Invalid API key".
    • 403 → returned as "API key lacks required permissions".
    • Other codes → mapped to a generic failure message.
  5. Return a (bool, str) tuple representing success and a human-readable message that api/routers/credentials.py propagates to the client.

Error Handling Without Noise

All three network helpers wrap their httpx calls in exception handlers for httpx.ConnectError, httpx.TimeoutException, and generic Exception. Raw errors are funneled through _normalize_error_message (lines 36-53) so the UI receives clean, actionable text rather than stack traces.

Practical Code Examples

Validate Azure OpenAI credentials directly or let the helper read environment variables:

from open_notebook.ai.connection_tester import _test_azure_connection

ok, msg = await _test_azure_connection(
    endpoint="https://my-azure.openai.azure.com",
    api_key="sk-xxxx",
    api_version="2024-10-21",
)
print(ok, msg)   # → True "Connected. 5 models: gpt-35-turbo, …"

Check a local Ollama server:

from open_notebook.ai.connection_tester import _test_ollama_connection

ok, msg = await _test_ollama_connection("http://localhost:11434")
print(ok, msg)   # → True "Connected. 12 models available: llama, …"

Verify an OpenAI-compatible endpoint such as Together or another proxy:

from open_notebook.ai.connection_tester import _test_openai_compatible_connection

ok, msg = await _test_openai_compatible_connection(
    base_url="https://api.together.xyz",
    api_key="together-xxxx",
)
print(ok, msg)   # → True "Connected. 8 models available: meta-llama/…"

Summary

  • open_notebook/ai/connection_tester.py validates credentials by sending one lightweight GET request per provider instead of running inference.
  • Azure, Ollama, and OpenAI-compatible servers each expose a model-listing endpoint that proves authentication without consuming tokens.
  • Hosted generic providers skip this phase and rely on ModelManager in open_notebook/ai/models.py for later per-model testing.
  • Every helper uses httpx.AsyncClient with a 10-second timeout and normalizes errors through _normalize_error_message.
  • The calling router in api/routers/credentials.py receives a simple (bool, str) tuple and surfaces it to the user.

Frequently Asked Questions

What HTTP method does connection_tester.py use to validate credentials?

The module exclusively uses GET requests to read-only model-listing endpoints. This avoids side effects, token consumption, and latency while still requiring valid authentication.

Why doesn't the module validate generic providers like Anthropic or Google with a network call?

connection_tester.py intentionally defers validation for generic hosted providers to the provider-specific ModelManager class in open_notebook/ai/models.py. The test_individual_model method handles those checks later, keeping the initial credential endpoint lightweight and provider-agnostic.

How does the validation flow handle timeouts or unreachable endpoints?

Each helper catches httpx.ConnectError and httpx.TimeoutException alongside generic exceptions. These are passed through _normalize_error_message (lines 36-53) to produce clean user-facing strings instead of raw tracebacks.

Which Open Notebook API routes consume connection_tester.py?

The primary consumer is api/routers/credentials.py, which exposes a credentials endpoint that invokes the tester. api/credentials_service.py wraps the result and translates failures into appropriate HTTP errors before returning them to the client.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →