Skip to main content

InteropRouter

Seamlessly call major LLMs and image generation models through a unified interface.

uv ty PyPI License: MIT

InteropRouter is designed to seamlessly interoperate between the most common AI providers at a high level of quality. It uses the OpenAI Responses API types as a common denominator for inputs and outputs, allowing you to switch between providers with minimal code changes. See examples/ for detailed notebooks covering interoperability, function calling, image generation, and more.

Getting Started

Installation

# With uv.
uv add interop-router

# With pip.
pip install interop-router

Usage

from anthropic import AsyncAnthropic
from google import genai
from openai import AsyncOpenAI
from openai.types.responses import EasyInputMessageParam

from interop_router.router import Router
from interop_router.types import ChatMessage

router = Router()
router.register("openai", AsyncOpenAI())
router.register("gemini", genai.Client())
router.register("anthropic", AsyncAnthropic())
router.register("chat_completions", AsyncOpenAI(base_url="http://localhost:8000/v1"))  # Can point to local models, OpenAI, OpenRouter, etc.

# See https://platform.openai.com/docs/guides/migrate-to-responses and the library source for more details on typing.
messages = [ChatMessage(message=EasyInputMessageParam(role="user", content="Hello!"))]

# OpenAI, Azure OpenAI, Gemini, and Anthropic are supported
response = await router.create(input=messages, model="gpt-5.6-terra")
response = await router.create(input=messages, model="gemini-3.6-flash")
response = await router.create(input=messages, model="claude-sonnet-5")
# Explicit provider routing with provider/model.
response = await router.create(input=messages, model="chat_completions/nvidia/Qwen3.6-27B-NVFP4")

Register several clients for the same provider by giving each one a name, then route to it with name/model:

router.register("chat_completions", AsyncOpenAI(base_url="http://localhost:8000/v1"), name="vllm")
router.register("chat_completions", AsyncOpenAI(base_url="https://openrouter.ai/api/v1"), name="openrouter")

response = await router.create(input=messages, model="vllm/nvidia/Qwen3.6-27B-NVFP4")
response = await router.create(input=messages, model="openrouter/moonshotai/kimi-k2")

Count input tokens before making a request using each provider's native token counting endpoint:

token_count = await router.count_tokens(input=messages, model="gpt-5.6-terra")
token_count = await router.count_tokens(input=messages, model="gemini-3.6-flash")
token_count = await router.count_tokens(input=messages, model="claude-sonnet-5")

InteropRouter Design Philosophy

The only goal of InteropRouter is to interoperate between the most common AI providers. To make this goal achievable, we make several trade-offs:

  • Focus on OpenAI (Responses API, including Azure OpenAI), Gemini, and Anthropic. Each provider adds a significant amount of possible permutations of features. To maintain high-quality interoperability, we limit the number of first-class providers.
  • Also support a chat_completions adapter for OpenAI-compatible Chat Completions endpoints.
  • We do not support stateful features where possible. These features are contradictory to the goal of seamless swapping between providers.
  • We choose the OpenAI Responses API types as the common denominator for creating pivots between providers. The reason is two-fold: a) The Responses API supports most features b) By picking an existing API, we avoid the need to design and maintain our own schema and Responses API support is gained for "free".
  • The supported features will be rigorously tested to ensure seamless swapping between providers within a single conversation.

Development

Prerequisites

Setup

Create uv virtual environment and install dependencies:

uv sync --frozen --all-extras --all-groups

Set up git hooks:

prek install

To update dependencies (updates the lock file):

uv sync -U --all-extras --all-groups

Run formatting, linting, type checking, and tests in one command:

uv run ruff format && uv run ruff check --fix && uv run ty check && uv run pytest

Further Information

Compatibility and Roadmap

docs/COMPATIBILITY_AND_ROADMAP.md

Metadata

Release files for interop-router 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for interop-router 0.5.0
File Size Uploaded Provenance
interop_router-0.5.0.tar.gz 34.3 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for interop-router 0.5.0
File Interpreter ABI Platform
interop_router-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 72.6 kB

Release files / interop_router-0.5.0.tar.gz

Download URL interop_router-0.5.0.tar.gz
Size 34.3 kB
Tags Source
SHA-256 checksum
How to use checksums
c24a6a4e452365680aac62ab460b02f415c2e3889a2a547a0db106b992c5f957
BLAKE2b-256 checksum
How to use checksums
cf638a687297a0f16a188532103385d899399bc4f5d30a9908d53b0d284efbb1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 8, 2026.

Transparency log

Release files / interop_router-0.5.0-py3-none-any.whl

Download URL interop_router-0.5.0-py3-none-any.whl
Size 38.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
290d42fe8da7521e0b7bd938d063d8782ae6d8d0b18a2fa5da9dd1f972633db6
BLAKE2b-256 checksum
How to use checksums
e0ab79acb872748d084f21a32c60b3f3f343f54fdfb57b77da23e4281a2dfba2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 8, 2026.

Transparency log

Security for interop-router 0.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for interop_router-0.5.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 8, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page