Merge pull request #1 from EUrouter/DavidLoDico/add-eurouter-provider

feat: add EUrouter as an OpenAI-compatible provider
This commit is contained in:
David Lo Dico 2026-04-01 19:23:14 +02:00 committed by GitHub
commit 98d323c8f2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 184 additions and 0 deletions

View file

@ -0,0 +1,101 @@
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# EUrouter
[EUrouter](https://eurouter.eu) is an EU-hosted, GDPR-compliant AI model routing service. It's a drop-in replacement for OpenRouter, routing requests to providers like OpenAI, Anthropic, Mistral, Google, and others — with guaranteed EU data residency.
EUrouter is OpenAI-compatible, so it works with LiteLLM out of the box.
## Quick Start
### Environment Variables
```bash
export EUROUTER_API_KEY="your-eurouter-api-key"
```
### Usage
<Tabs>
<TabItem value="sdk" label="SDK">
```python
import litellm
response = litellm.completion(
model="eurouter/mistral/mistral-large-3",
messages=[{"role": "user", "content": "Hello from the EU!"}],
)
```
</TabItem>
<TabItem value="proxy" label="PROXY">
1. Add to your LiteLLM Proxy config.yaml:
```yaml
model_list:
- model_name: mistral-large-3
litellm_params:
model: eurouter/mistral/mistral-large-3
api_key: os.environ/EUROUTER_API_KEY
- model_name: gpt-4o
litellm_params:
model: eurouter/openai/gpt-4o
api_key: os.environ/EUROUTER_API_KEY
- model_name: claude-sonnet-4-6
litellm_params:
model: eurouter/anthropic/claude-sonnet-4-6
api_key: os.environ/EUROUTER_API_KEY
```
2. Start the proxy:
```bash
litellm --config config.yaml
```
3. Make a request:
```bash
curl http://localhost:4000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-1234" \
-d '{
"model": "mistral-large-3",
"messages": [{"role": "user", "content": "Hello!"}]
}'
```
</TabItem>
</Tabs>
## Supported Models
EUrouter routes to 100+ models from 15+ providers. Use the `eurouter/` prefix followed by the provider and model name:
| Model | LiteLLM Model String |
|-------|---------------------|
| Mistral Large 3 | `eurouter/mistral/mistral-large-3` |
| GPT-4o | `eurouter/openai/gpt-4o` |
| GPT-4.1 | `eurouter/openai/gpt-4.1` |
| Claude Sonnet 4.6 | `eurouter/anthropic/claude-sonnet-4-6` |
| Claude Haiku 4.5 | `eurouter/anthropic/claude-haiku-4.5` |
| DeepSeek V3 | `eurouter/deepseek/deepseek-v3` |
| Llama 4 Maverick | `eurouter/meta/llama-4-maverick` |
| Llama 3.3 70B | `eurouter/meta/llama-3.3-70b-instruct` |
For a full list, visit the [EUrouter Models page](https://eurouter.eu/models) or call:
```bash
curl https://api.eurouter.ai/api/v1/models
```
## Why EUrouter?
- **EU Data Residency** — Requests are routed only to EU-hosted endpoints
- **GDPR Compliance** — Built for European data protection requirements
- **OpenAI Compatible** — Drop-in replacement, same API format
- **Multi-Provider** — Access OpenAI, Anthropic, Mistral, Google, and more through a single API
- **Transparent Pricing** — Model cost + 5% platform fee, all in EUR

View file

@ -907,6 +907,7 @@ const sidebars = {
"providers/deepseek",
"providers/docker_model_runner",
"providers/elevenlabs",
"providers/eurouter",
"providers/fal_ai",
"providers/featherless_ai",
"providers/fireworks_ai",

View file

@ -101,5 +101,10 @@
"param_mappings": {
"max_completion_tokens": "max_tokens"
}
},
"eurouter": {
"base_url": "https://api.eurouter.ai/api/v1",
"api_key_env": "EUROUTER_API_KEY",
"api_base_env": "EUROUTER_API_BASE"
}
}

View file

@ -3281,6 +3281,7 @@ class LlmProviders(str, Enum):
MANUS = "manus"
WANDB = "wandb"
OVHCLOUD = "ovhcloud"
EUROUTER = "eurouter"
LEMONADE = "lemonade"
AMAZON_NOVA = "amazon_nova"
A2A_AGENT = "a2a_agent"

View file

@ -0,0 +1,76 @@
"""
Tests for EUrouter provider configuration and integration.
EUrouter is an EU-hosted, GDPR-compliant AI routing service that is
OpenAI-compatible (similar to OpenRouter).
"""
import os
import sys
try:
import pytest
except ImportError:
pytest = None
# Add workspace to path
workspace_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../.."))
sys.path.insert(0, workspace_path)
import litellm
class TestEUrouterProviderConfig:
"""Test EUrouter provider configuration"""
def test_eurouter_in_provider_list(self):
"""Test that eurouter is in the provider list"""
from litellm import LlmProviders
assert hasattr(LlmProviders, "EUROUTER")
assert LlmProviders.EUROUTER.value == "eurouter"
assert "eurouter" in litellm.provider_list
def test_eurouter_json_config_exists(self):
"""Test that eurouter is configured in providers.json"""
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
assert JSONProviderRegistry.exists("eurouter")
eurouter = JSONProviderRegistry.get("eurouter")
assert eurouter is not None
assert eurouter.base_url == "https://api.eurouter.ai/api/v1"
assert eurouter.api_key_env == "EUROUTER_API_KEY"
def test_eurouter_provider_resolution(self):
"""Test that provider resolution finds eurouter"""
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
model, provider, api_key, api_base = get_llm_provider(
model="eurouter/mistral/mistral-large-3",
custom_llm_provider=None,
api_base=None,
api_key=None,
)
assert provider == "eurouter"
assert api_base == "https://api.eurouter.ai/api/v1"
def test_eurouter_router_config(self):
"""Test that eurouter can be used in Router configuration"""
from litellm import Router
router = Router(
model_list=[
{
"model_name": "gpt-4o",
"litellm_params": {
"model": "eurouter/mistral/mistral-large-3",
"api_key": "test-key",
},
}
]
)
assert len(router.model_list) == 1
assert router.model_list[0]["model_name"] == "gpt-4o"