Skip to content

Feature: configurable base URL for OpenAI and Anthropic backends (custom providers) #981

Description

@TommyC81

Summary

The OpenAI and Anthropic backends hardcode their base_url, making it impossible to use OpenAI-compatible or Anthropic-compatible API providers (Z.ai, OpenRouter, Together, Groq, Azure OpenAI, etc.) without modifying source.

The ollama backend already supports this via OLLAMA_BASE_URL — the same pattern should apply to other backends.

Related

This issue expands on #959 by also covering the Anthropic backend and proposing two complementary approaches.

Current Behavior

graphify/llm.py BACKENDS dict:

"openai": {
    "base_url": "https://api.openai.com/v1",   # hardcoded
    "env_key": "OPENAI_API_KEY",
    ...
},
"claude": {
    "base_url": "https://api.anthropic.com",    # hardcoded
    "env_key": "ANTHROPIC_API_KEY",
    ...
},
"ollama": {
    "base_url": os.environ.get("OLLAMA_BASE_URL", "http://localhost:11434/v1"),  # ✓ configurable
    ...
},

At runtime, _call_openai_compat receives the base_url from the dict directly (line ~578):

return _call_openai_compat(
    cfg["base_url"],  # always the hardcoded value
    ...
)

And _call_claude creates the Anthropic client with no base_url at all (line ~397):

client = anthropic.Anthropic(api_key=api_key)  # defaults to api.anthropic.com

Proposed Solution

Option A: env var overrides per backend (minimal change)

Add GRAPHIFY_OPENAI_BASE_URL and GRAPHIFY_ANTHROPIC_BASE_URL env var support, following the existing OLLAMA_BASE_URL pattern:

"openai": {
    "base_url": os.environ.get("GRAPHIFY_OPENAI_BASE_URL", "https://api.openai.com/v1"),
    ...
},
"claude": {
    "base_url": os.environ.get("GRAPHIFY_ANTHROPIC_BASE_URL", "https://api.anthropic.com"),
    ...
},

And pass it through in _call_claude:

cfg = BACKENDS["claude"]
client = anthropic.Anthropic(api_key=api_key, base_url=cfg["base_url"])

Option B: generic custom backend

Support a custom backend that takes all config from env vars:

GRAPHIFY_CUSTOM_BASE_URL=https://api.z.ai/api/paas/v4/ \
GRAPHIFY_CUSTOM_API_KEY=... \
GRAPHIFY_CUSTOM_MODEL=glm-5.1 \
graphify extract . --backend custom

Option A is a smaller change that unblocks the most common use cases. Option B is more flexible but higher surface area. Both can coexist.

Use Cases

  • Z.ai — Two OpenAI-compatible endpoints:
    • Standard: api.z.ai/api/paas/v4/ (pay-per-token)
    • Coding Plan: api.z.ai/api/coding/paas/v4 (subscription with higher usage limits)
  • OpenRouter — routes to many models via a single OpenAI-compatible API
  • Azure OpenAI — different base URL per deployment
  • Together AI / Groq / Fireworks — OpenAI-compatible with different URLs
  • vLLM / local inference — self-hosted OpenAI-compatible servers
  • Corporate proxies — self-hosted API gateways with OpenAI-compatible interfaces

Environment

  • graphify v0.8.14
  • Windows 10 (also applies to all platforms)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions