Skip to main content

🚀 Inference Gateway Python SDK

A modern and easy-to-use Python SDK for the Inference Gateway

PyPI version Python Version License: Apache 2.0 Release

Connect to multiple LLM providers through a unified interface • Stream responses • Function calling • Vision support • MCP tools support • Pydantic validation

InstallationQuick StartExamplesLicense


Installation

To install the SDK, use pip:

pip install inference-gateway

Requires Python 3.12+.

Usage

Creating a Client

To create a client, instantiate InferenceGatewayClient:

from inference_gateway import InferenceGatewayClient, Message

client = InferenceGatewayClient("http://localhost:8080/v1")

The client also supports authentication, custom timeouts, and an optional httpx backend:

# With authentication
client = InferenceGatewayClient(
    "http://localhost:8080/v1",
    token="your-api-token",
    timeout=60.0,
)

# Using httpx instead of the default requests backend
client = InferenceGatewayClient(
    "http://localhost:8080/v1",
    use_httpx=True,
)

# Use as a context manager to ensure the underlying HTTP client is closed
with InferenceGatewayClient("http://localhost:8080/v1") as client:
    models = client.list_models()

Listing Models

To list available models, use the list_models method:

# List all models from all providers
models = client.list_models()
print("All available models:", models)

# List models for a specific provider
openai_models = client.list_models(provider="openai")
print("OpenAI models:", openai_models)

Listing MCP Tools

To list available MCP (Model Context Protocol) tools, use the list_tools method. This functionality is only available when MCP_ENABLE and MCP_EXPOSE are set on the Inference Gateway server:

tools = client.list_tools()

print(f"Found {len(tools.data)} MCP tools:")
for tool in tools.data:
    print(f"- {tool.name}: {tool.description} (Server: {tool.server})")

Note: The MCP tools endpoint requires authentication and is only accessible when the server has MCP_EXPOSE=true configured.

Server-Side Tool Management

The SDK currently supports listing available MCP tools, which is particularly useful for UI applications that need to display connected tools to users. The key advantage is that tools are managed server-side:

  • Automatic Tool Injection: Tools are automatically inferred and injected into requests by the Inference Gateway server
  • Simplified Client Code: No need to manually manage or configure tools in your client application
  • Transparent Tool Calls: During streaming chat completions with configured MCP servers, tool calls appear in the response stream - no special handling required except optionally displaying them to users

Generating Content

To generate content using a model, use the create_chat_completion method:

Note: Some models support reasoning capabilities. You can use the reasoning_format parameter to control how reasoning is provided in the response. The model's reasoning will be available in the reasoning or reasoning_content fields of the response message.

from inference_gateway import InferenceGatewayClient, Message

client = InferenceGatewayClient("http://localhost:8080/v1")

response = client.create_chat_completion(
    model="ollama/llama2",
    messages=[
        Message(role="system", content="You are a helpful assistant."),
        Message(role="user", content="What is Python?"),
    ],
)

print(response.choices[0].message.content.root)

# If reasoning was requested and the model supports it
if response.choices[0].message.reasoning:
    print("Reasoning:", response.choices[0].message.reasoning)

Vision Support

The SDK supports multimodal messages with images for vision-capable models like GPT-4o. You can include images via URLs or base64-encoded data URLs.

Simple Text Message

from inference_gateway import InferenceGatewayClient, Message

client = InferenceGatewayClient("http://localhost:8080/v1")

response = client.create_chat_completion(
    model="openai/gpt-4o",
    messages=[Message(role="user", content="What is the Python programming language?")],
)

Vision Message with Image URL

from inference_gateway import (
    InferenceGatewayClient,
    Message,
    TextContentPart,
    ImageContentPart,
    ImageURL,
)

client = InferenceGatewayClient("http://localhost:8080/v1")

response = client.create_chat_completion(
    model="openai/gpt-4o",
    messages=[
        Message(
            role="user",
            content=[
                TextContentPart(type="text", text="What is in this image?"),
                ImageContentPart(
                    type="image_url",
                    image_url=ImageURL(
                        url="https://example.com/image.jpg",
                        detail="auto",
                    ),
                ),
            ],
        )
    ],
)

Vision Message with Base64 Encoded Image

from inference_gateway import ImageContentPart, ImageURL

ImageContentPart(
    type="image_url",
    image_url=ImageURL(
        url="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD...",
        detail="high",  # better quality, more expensive
    ),
)

Multiple Images in One Message

Message(
    role="user",
    content=[
        TextContentPart(type="text", text="Compare these images:"),
        ImageContentPart(type="image_url", image_url=ImageURL(url="https://example.com/image1.jpg")),
        ImageContentPart(type="image_url", image_url=ImageURL(url="https://example.com/image2.jpg")),
    ],
)

Image Detail Levels:

  • "auto": Automatic detail level (default)
  • "low": Lower resolution, faster and cheaper
  • "high": Higher resolution, better quality but more expensive

For a complete example, see the chat example.

Using ReasoningFormat

You can enable reasoning capabilities by setting the reasoning_format parameter in your request:

from inference_gateway import InferenceGatewayClient, Message

client = InferenceGatewayClient("http://localhost:8080/v1")

response = client.create_chat_completion(
    model="anthropic/claude-3-opus-20240229",
    messages=[
        Message(role="system", content="You are a helpful assistant. Please include your reasoning for complex questions."),
        Message(role="user", content="What is the square root of 144 and why?"),
    ],
    reasoning_format="parsed",  # "raw" or "parsed" - defaults to "parsed"
)

print("Content:", response.choices[0].message.content.root)
if response.choices[0].message.reasoning:
    print("Reasoning:", response.choices[0].message.reasoning)

Sampling and Output Controls

create_chat_completion and create_chat_completion_stream accept the full set of OpenAI-compatible request parameters as keyword arguments. The SDK only sends the parameters you set explicitly - spec defaults you do not specify are left off the request so each provider applies its own.

from inference_gateway import InferenceGatewayClient, Message

client = InferenceGatewayClient("http://localhost:8080/v1")

response = client.create_chat_completion(
    model="openai/gpt-4o",
    messages=[Message(role="user", content="Describe Python as a JSON object.")],
    temperature=0.2,            # 0-2, sampling temperature
    top_p=0.9,                  # 0-1, nucleus sampling
    n=1,                        # 1-128, number of choices to generate
    stop=["\n\n"],              # a string, or up to 4 strings
    frequency_penalty=0.0,      # -2..2
    presence_penalty=0.0,       # -2..2
    seed=42,                    # best-effort determinism
    max_completion_tokens=512,  # preferred over the deprecated max_tokens
    response_format={"type": "json_object"},
    reasoning_effort="medium",  # minimal | low | medium | high
)

response_format and tool_choice are oneOf unions. You can pass plain dicts (they are validated for you) or use the exported typed models:

from inference_gateway import (
    ChatCompletionNamedToolChoice,
    ResponseFormatJsonObject,
)

response = client.create_chat_completion(
    model="openai/gpt-4o",
    messages=[Message(role="user", content="What's the weather in Paris?")],
    response_format=ResponseFormatJsonObject(type="json_object"),
    tool_choice=ChatCompletionNamedToolChoice(
        type="function",
        function={"name": "get_weather"},
    ),
)

Note: max_tokens is deprecated in favor of max_completion_tokens.

Streaming Content

To generate content using streaming mode, use the create_chat_completion_stream method. It yields SSEvent objects:

import json
from pydantic import ValidationError
from inference_gateway import InferenceGatewayClient, Message
from inference_gateway.models import CreateChatCompletionStreamResponse

client = InferenceGatewayClient("http://localhost:8080/v1")

for chunk in client.create_chat_completion_stream(
    model="ollama/llama2",
    messages=[
        Message(role="system", content="You are a helpful assistant."),
        Message(role="user", content="Tell me a story."),
    ],
):
    if not chunk.data:
        continue

    try:
        data = json.loads(chunk.data)
        stream_response = CreateChatCompletionStreamResponse.model_validate(data)
    except (json.JSONDecodeError, ValidationError):
        continue

    for choice in stream_response.choices:
        # Reasoning content (both reasoning and reasoning_content fields)
        if choice.delta.reasoning:
            print(f"💭 Reasoning: {choice.delta.reasoning}")
        if choice.delta.reasoning_content:
            print(f"💭 Reasoning: {choice.delta.reasoning_content}")

        if choice.delta.content:
            print(choice.delta.content, end="", flush=True)

Tool-Use

To use tools with the SDK, define a tool with the type-safe Pydantic models and pass it to the request:

from inference_gateway import InferenceGatewayClient, Message
from inference_gateway.models import ChatCompletionTool, FunctionObject, FunctionParameters

client = InferenceGatewayClient("http://localhost:8080/v1")

tools = [
    ChatCompletionTool(
        type="function",
        function=FunctionObject(
            name="get_current_weather",
            description="Get the current weather in a given location",
            parameters=FunctionParameters(
                type="object",
                properties={
                    "location": {
                        "type": "string",
                        "enum": ["san francisco", "new york", "london", "tokyo", "sydney"],
                        "description": "The city and state, e.g. San Francisco, CA",
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "The temperature unit to use",
                    },
                },
                required=["location"],
            ),
        ),
    ),
    ChatCompletionTool(
        type="function",
        function=FunctionObject(
            name="get_current_time",
            description="Get the current time in a given location",
            parameters=FunctionParameters(
                type="object",
                properties={
                    "location": {
                        "type": "string",
                        "enum": ["san francisco", "new york", "london", "tokyo", "sydney"],
                        "description": "The city and state, e.g. San Francisco, CA",
                    },
                },
                required=["location"],
            ),
        ),
    ),
]

response = client.create_chat_completion(
    model="openai/gpt-4o",
    messages=[
        Message(role="system", content="You are a helpful assistant with access to weather and time information."),
        Message(role="user", content="What is the weather like in New York?"),
    ],
    tools=tools,
)

# Inspect any tool calls made by the model
if response.choices[0].message.tool_calls:
    for tool_call in response.choices[0].message.tool_calls:
        print(f"Tool called: {tool_call.function.name}")
        print(f"Arguments: {tool_call.function.arguments}")

Provider-Specific Tool-Call Metadata

Some providers attach opaque, per-call metadata that must be echoed back on follow-up requests. The most notable case is Google Gemini's reasoning models, which return a thought_signature on each tool call - the next request must round-trip it verbatim or the provider will reject it.

The SDK preserves this automatically as long as you append the assistant message back to the conversation as a model object (rather than reconstructing it from a dict):

response = client.create_chat_completion(
    model="google/gemini-3-pro",
    messages=messages,
    tools=tools,
)

assistant_message = response.choices[0].message
messages.append(assistant_message)  # preserves extra_content.google.thought_signature

# ... append your tool results, then send the follow-up request ...

If you need to construct one explicitly:

from inference_gateway import Google, ToolCallExtraContent

extra = ToolCallExtraContent(google=Google(thought_signature="..."))

The field is fully optional - providers that don't use it ignore it entirely, and model_dump(exclude_none=True) strips it from the wire when unset.

Messages API (Anthropic-compatible)

The gateway also exposes an Anthropic-compatible Messages API (POST /messages). Use create_message for standard requests - it returns a validated MessagesResponse:

from inference_gateway import InferenceGatewayClient, MessagesMessage, MessagesTextBlock

client = InferenceGatewayClient("http://localhost:8080/v1")

response = client.create_message(
    model="anthropic/claude-sonnet-5",
    messages=[
        MessagesMessage(role="user", content="Hello! Please introduce yourself briefly."),
    ],
    max_tokens=100,
    system="You are a helpful assistant",
)

for block in response.content:
    if isinstance(block.root, MessagesTextBlock):
        print(block.root.text)

print(f"Stop reason: {response.stop_reason}")
print(f"Usage: {response.usage.input_tokens} in / {response.usage.output_tokens} out")

create_message_stream yields typed MessagesStreamEvent objects (message_start, content_block_delta, message_stop, ...) - no manual SSE parsing needed:

for event in client.create_message_stream(
    model="anthropic/claude-sonnet-5",
    messages=[
        MessagesMessage(role="user", content="Tell me a short story."),
    ],
    max_tokens=200,
):
    if event.type == "content_block_delta" and event.delta and event.delta.text:
        print(event.delta.text, end="", flush=True)

Tools use the MessagesTool shape, and tool calls come back as MessagesToolUseBlock content blocks:

from inference_gateway import MessagesTool, MessagesToolUseBlock
from inference_gateway.models import FunctionParameters

tools = [
    MessagesTool(
        name="get_current_weather",
        description="Get the current weather in a given location",
        input_schema=FunctionParameters(
            type="object",
            properties={
                "location": {"type": "string", "description": "The city, e.g. San Francisco"},
            },
            required=["location"],
        ),
    ),
]

response = client.create_message(
    model="anthropic/claude-sonnet-5",
    messages=[MessagesMessage(role="user", content="What is the weather in New York?")],
    max_tokens=200,
    tools=tools,
)

for block in response.content:
    if isinstance(block.root, MessagesToolUseBlock):
        print(f"Tool called: {block.root.name}")
        print(f"Input: {block.root.input}")

Note: Not every provider implements the Messages API. Requests routed to a provider without support return a 400 error - use create_chat_completion for those providers.

Proxy Requests

To proxy a raw request directly to a provider's API through the gateway, use proxy_request:

response = client.proxy_request(
    provider="openai",
    path="/v1/models",
    method="GET",
)

print("OpenAI models:", response)

Health Check

To check if the API is healthy:

if client.health_check():
    print("API is healthy")
else:
    print("API is unavailable")

Error Handling

The SDK provides several exception types:

from inference_gateway import (
    InferenceGatewayError,
    InferenceGatewayAPIError,
    InferenceGatewayValidationError,
)

try:
    response = client.create_chat_completion(...)
except InferenceGatewayAPIError as e:
    print(f"API Error: {e} (Status: {e.status_code})")
    print("Response:", e.response_data)
except InferenceGatewayValidationError as e:
    print(f"Validation Error: {e}")
except InferenceGatewayError as e:
    print(f"General Error: {e}")

Examples

For more detailed examples and use cases, check out the examples directory. The examples include:

Each example includes its own README with specific instructions and explanations.

Supported Providers

The SDK supports the following LLM providers:

  • Ollama ("ollama")
  • Ollama Cloud ("ollama_cloud")
  • Groq ("groq")
  • OpenAI ("openai")
  • DeepSeek ("deepseek")
  • Cloudflare ("cloudflare")
  • Cohere ("cohere")
  • Anthropic ("anthropic")
  • Google ("google")
  • Mistral AI ("mistral")
  • MiniMax ("minimax")
  • Moonshot ("moonshot")
  • NVIDIA ("nvidia")

License

This SDK is distributed under the Apache 2.0 License, see LICENSE for more information.

Release files for inference-gateway 0.18.1

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

Source distribution (sdist)

Source distribution for inference-gateway 0.18.1
File Size Uploaded
inference_gateway-0.18.1.tar.gz 49.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for inference-gateway 0.18.1
File Interpreter ABI Platform
inference_gateway-0.18.1-py3-none-any.whl Python 3 none any Details

Total release size: 86.3 kB

Release files / inference_gateway-0.18.1.tar.gz

Download URL inference_gateway-0.18.1.tar.gz
Size 49.6 kB
Tags Source
SHA-256 checksum
How to use checksums
2bda7b53bccb79021caf385a0e558bb51cfc229c4193fc9b1336e01399b12e3e
BLAKE2b-256 checksum
How to use checksums
acfb8d48dea7069ae231d2f706c71fe3bd5b5f9de13c78374dbfa0e49527c358
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 Sep 4, 2026.

Transparency log

Release files / inference_gateway-0.18.1-py3-none-any.whl

Download URL inference_gateway-0.18.1-py3-none-any.whl
Size 36.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fda5f5c84112e0d89cfde88700a1560bdbbc74965164a8553a201fd79fc49594
BLAKE2b-256 checksum
How to use checksums
5c033ff8e692daae5e1bce460c0465fbc06399a43ffdf805f2572ba63605e706
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 Sep 4, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.18.1 This release

2 release files

0.17.0

2 release files

0.14.0

2 release files

0.13.0

2 release files

0.12.1

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.3

2 release files

0.1.1

2 release files

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