interop-router 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,113 @@
1
+ Metadata-Version: 2.3
2
+ Name: interop-router
3
+ Version: 0.1.0
4
+ Summary: Interoperate between AI providers using the OpenAI Responses API as a common interface.
5
+ Author: David Koleczek
6
+ Author-email: David Koleczek <45405824+DavidKoleczek@users.noreply.github.com>
7
+ Requires-Dist: anthropic>=0.75,<1.0
8
+ Requires-Dist: google-genai>=1.56,<2.0
9
+ Requires-Dist: openai[aiohttp]>=2.14,<3.0
10
+ Requires-Dist: pydantic>=2.12,<3.0
11
+ Requires-Python: >=3.11
12
+ Description-Content-Type: text/markdown
13
+
14
+ <h1 align="center">
15
+ InteropRouter
16
+ </h1>
17
+ <p align="center">
18
+ <p align="center">Seamlessly call major LLMs and image generation models through a unified interface.
19
+ </p>
20
+ </p>
21
+
22
+ InteropRouter is designed to seamlessly interoperate between the most common AI providers at a high level of quality.
23
+ It uses the [OpenAI Responses API](https://platform.openai.com/docs/guides/migrate-to-responses) types as a common denominator for inputs and outputs, allowing you to switch between providers with minimal code changes.
24
+ See [examples/](examples/) for detailed notebooks covering interoperability, function calling, image generation, and more.
25
+
26
+ ## Getting Started
27
+
28
+ ### Installation
29
+
30
+ ```bash
31
+ # With uv.
32
+ uv add interop-router
33
+
34
+ # With pip.
35
+ pip install interop-router
36
+ ```
37
+
38
+ ### Usage
39
+
40
+ ```python
41
+ from anthropic import AsyncAnthropic
42
+ from google import genai
43
+ from openai import AsyncOpenAI
44
+ from openai.types.responses import EasyInputMessageParam
45
+
46
+ from interop_router.router import Router
47
+ from interop_router.types import ChatMessage
48
+
49
+ router = Router()
50
+ router.register("openai", AsyncOpenAI())
51
+ router.register("gemini", genai.Client())
52
+ router.register("anthropic", AsyncAnthropic())
53
+
54
+ # InteropRouter is strictly typed, so be sure to use OpenAI's Response types for inputs.
55
+ # See https://platform.openai.com/docs/guides/migrate-to-responses and the library source for more details on typing.
56
+ messages = [ChatMessage(message=EasyInputMessageParam(role="user", content="Hello!"))]
57
+
58
+ response = await router.create(input=messages, model="gpt-5.2")
59
+ response = await router.create(input=messages, model="gemini-3-flash-preview")
60
+ response = await router.create(input=messages, model="claude-sonnet-4-5-20250929")
61
+ ```
62
+
63
+ ### InteropRouter Design Philosophy
64
+
65
+ The only goal of InteropRouter is to interoperate between the most common AI providers. To make this goal achievable, we make several trade-offs:
66
+ - Only support OpenAI (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 providers.
67
+ - Only support async APIs, but not streaming token by token as this adds significant complexity, and for agents the latency is not as important.
68
+ - We do not support stateful features where possible. These features are contradictory to the goal of seamless swapping between providers.
69
+ - 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".
70
+ - The supported features will be rigorously tested to ensure seamless swapping between providers within a single conversation.
71
+
72
+
73
+ ## Development
74
+
75
+ ### Prerequisites
76
+
77
+ - [uv](https://docs.astral.sh/uv/getting-started/installation/)
78
+ - [prek](https://github.com/j178/prek/blob/master/README.md#installation)
79
+
80
+ ### Setup
81
+
82
+ Create uv virtual environment and install dependencies:
83
+
84
+ ```bash
85
+ uv sync --frozen --all-extras --all-groups
86
+ ```
87
+
88
+ Set up git hooks:
89
+
90
+ ```bash
91
+ prek install
92
+ ```
93
+
94
+ To update dependencies (updates the lock file):
95
+
96
+ ```bash
97
+ uv sync --all-extras --all-groups
98
+ ```
99
+
100
+ Run formatting, linting, type checking, and tests in one command:
101
+
102
+ ```bash
103
+ uv run ruff format && uv run ruff check --fix && uv run ty check && uv run pytest
104
+ ```
105
+
106
+ ### Further Information
107
+
108
+ [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)
109
+
110
+
111
+ ## Compatibility and Roadmap
112
+
113
+ [docs/COMPATIBILITY_AND_ROADMAP.md](docs/COMPATIBILITY_AND_ROADMAP.md)
@@ -0,0 +1,100 @@
1
+ <h1 align="center">
2
+ InteropRouter
3
+ </h1>
4
+ <p align="center">
5
+ <p align="center">Seamlessly call major LLMs and image generation models through a unified interface.
6
+ </p>
7
+ </p>
8
+
9
+ InteropRouter is designed to seamlessly interoperate between the most common AI providers at a high level of quality.
10
+ It uses the [OpenAI Responses API](https://platform.openai.com/docs/guides/migrate-to-responses) types as a common denominator for inputs and outputs, allowing you to switch between providers with minimal code changes.
11
+ See [examples/](examples/) for detailed notebooks covering interoperability, function calling, image generation, and more.
12
+
13
+ ## Getting Started
14
+
15
+ ### Installation
16
+
17
+ ```bash
18
+ # With uv.
19
+ uv add interop-router
20
+
21
+ # With pip.
22
+ pip install interop-router
23
+ ```
24
+
25
+ ### Usage
26
+
27
+ ```python
28
+ from anthropic import AsyncAnthropic
29
+ from google import genai
30
+ from openai import AsyncOpenAI
31
+ from openai.types.responses import EasyInputMessageParam
32
+
33
+ from interop_router.router import Router
34
+ from interop_router.types import ChatMessage
35
+
36
+ router = Router()
37
+ router.register("openai", AsyncOpenAI())
38
+ router.register("gemini", genai.Client())
39
+ router.register("anthropic", AsyncAnthropic())
40
+
41
+ # InteropRouter is strictly typed, so be sure to use OpenAI's Response types for inputs.
42
+ # See https://platform.openai.com/docs/guides/migrate-to-responses and the library source for more details on typing.
43
+ messages = [ChatMessage(message=EasyInputMessageParam(role="user", content="Hello!"))]
44
+
45
+ response = await router.create(input=messages, model="gpt-5.2")
46
+ response = await router.create(input=messages, model="gemini-3-flash-preview")
47
+ response = await router.create(input=messages, model="claude-sonnet-4-5-20250929")
48
+ ```
49
+
50
+ ### InteropRouter Design Philosophy
51
+
52
+ The only goal of InteropRouter is to interoperate between the most common AI providers. To make this goal achievable, we make several trade-offs:
53
+ - Only support OpenAI (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 providers.
54
+ - Only support async APIs, but not streaming token by token as this adds significant complexity, and for agents the latency is not as important.
55
+ - We do not support stateful features where possible. These features are contradictory to the goal of seamless swapping between providers.
56
+ - 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".
57
+ - The supported features will be rigorously tested to ensure seamless swapping between providers within a single conversation.
58
+
59
+
60
+ ## Development
61
+
62
+ ### Prerequisites
63
+
64
+ - [uv](https://docs.astral.sh/uv/getting-started/installation/)
65
+ - [prek](https://github.com/j178/prek/blob/master/README.md#installation)
66
+
67
+ ### Setup
68
+
69
+ Create uv virtual environment and install dependencies:
70
+
71
+ ```bash
72
+ uv sync --frozen --all-extras --all-groups
73
+ ```
74
+
75
+ Set up git hooks:
76
+
77
+ ```bash
78
+ prek install
79
+ ```
80
+
81
+ To update dependencies (updates the lock file):
82
+
83
+ ```bash
84
+ uv sync --all-extras --all-groups
85
+ ```
86
+
87
+ Run formatting, linting, type checking, and tests in one command:
88
+
89
+ ```bash
90
+ uv run ruff format && uv run ruff check --fix && uv run ty check && uv run pytest
91
+ ```
92
+
93
+ ### Further Information
94
+
95
+ [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)
96
+
97
+
98
+ ## Compatibility and Roadmap
99
+
100
+ [docs/COMPATIBILITY_AND_ROADMAP.md](docs/COMPATIBILITY_AND_ROADMAP.md)
@@ -0,0 +1,70 @@
1
+ [project]
2
+ name = "interop-router"
3
+ version = "0.1.0"
4
+ description = "Interoperate between AI providers using the OpenAI Responses API as a common interface."
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "David Koleczek", email = "45405824+DavidKoleczek@users.noreply.github.com" }
8
+ ]
9
+ requires-python = ">=3.11"
10
+ dependencies = [
11
+ "anthropic>=0.75,<1.0",
12
+ "google-genai>=1.56,<2.0",
13
+ "openai[aiohttp]>=2.14,<3.0",
14
+ "pydantic>=2.12,<3.0",
15
+ ]
16
+
17
+ [build-system]
18
+ requires = ["uv_build>=0.9.15,<0.10.0"]
19
+ build-backend = "uv_build"
20
+
21
+ [dependency-groups]
22
+ dev = [
23
+ "ipykernel>=7.1",
24
+ "nbclient>=0.10",
25
+ "pytest>=9.0",
26
+ "pytest-asyncio>=1.3",
27
+ "ruff>=0.14",
28
+ "ty>=0.0.5",
29
+ ]
30
+
31
+ [tool.ruff]
32
+ line-length = 120
33
+ target-version = "py311"
34
+
35
+ [tool.ruff.lint]
36
+ select = [
37
+ "F", # pyflakes
38
+ "E", # pycodestyle
39
+ "I", # isort
40
+ "N", # pep8-naming
41
+ "UP", # pyupgrade
42
+ "RUF", # ruff
43
+ "B", # flake8-bugbear
44
+ "C4", # flake8-comprehensions
45
+ "ISC", # flake8-implicit-str-concat
46
+ "PIE", # flake8-pie
47
+ "PT", # flake-pytest-style
48
+ "PTH", # flake8-use-pathlib
49
+ "SIM", # flake8-simplify
50
+ "TID", # flake8-tidy-imports
51
+ ]
52
+ ignore = [
53
+ "E501", # line-too-long (formatter makes best-effort attempt)
54
+ # The following rules conflict with the formatter, see: https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
55
+ "W191", # tab-indentation
56
+ "E111", # indentation-with-invalid-multiple
57
+ "E114", # indentation-with-invalid-multiple-comment
58
+ "E117", # over-indented
59
+ "ISC002", # multi-line-implicit-string-concatenation
60
+ ]
61
+
62
+ [tool.ruff.lint.isort]
63
+ force-sort-within-sections = true
64
+ split-on-trailing-comma = false
65
+
66
+ [tool.ruff.lint.flake8-tidy-imports]
67
+ ban-relative-imports = "all"
68
+
69
+ [tool.pytest.ini_options]
70
+ asyncio_mode = "auto"
File without changes