Skip to main content

A unified Python SDK for querying AI models from multiple providers

Project description

ai-query

A unified Python SDK for querying AI models from multiple providers with a consistent interface.

Installation

uv add ai-query
# or
pip install ai-query

For MCP (Model Context Protocol) support:

uv add ai-query[mcp]
# or
pip install ai-query[mcp]

Quick Start

import asyncio
from ai_query import generate_text, openai

async def main():
    result = await generate_text(
        model=openai("gpt-4o"),
        prompt="What is the capital of France?"
    )
    print(result.text)

asyncio.run(main())

Streaming

from ai_query import stream_text, google

async def main():
    result = stream_text(
        model=google("gemini-2.0-flash"),
        prompt="Write a short story."
    )

    async for chunk in result.text_stream:
        print(chunk, end="", flush=True)

    usage = await result.usage
    print(f"\nTokens: {usage.total_tokens}")

Tool Calling

Define tools and let the model use them automatically. The library handles the execution loop. Tools can be defined using the @tool decorator with type hints and the Field class for descriptions.

from ai_query import generate_text, google, tool, Field, step_count_is

# Define tools using decorators
@tool(description="Get the current weather for a location")
async def get_weather(
    location: str = Field(description="City name")
) -> str:
    # Function implementation
    return f"Weather in {location}: 72°F, Sunny"

@tool(description="Perform math calculations")
def calculate(
    expression: str = Field(description="Math expression")
) -> str:
    return str(eval(expression))

async def main():
    result = await generate_text(
        model=google("gemini-2.0-flash"),
        prompt="What's the weather in Paris? Also, what is 25 * 4?",
        tools={
            "weather": get_weather,
            "calculator": calculate
        },
        stop_when=step_count_is(5),  # Max 5 model calls
    )
    print(result.text)
    print(f"Steps: {len(result.response['steps'])}")

Stop Conditions

Control when the tool execution loop stops:

from ai_query import step_count_is, has_tool_call

# Stop after N model calls
stop_when=step_count_is(5)

# Stop when a specific tool is called
stop_when=has_tool_call("final_answer")

# Multiple conditions (stops when any is true)
stop_when=[step_count_is(10), has_tool_call("done")]

MCP (Model Context Protocol) Support

ai-query supports MCP - a standard for AI tool integration. Connect to any MCP server and use its tools seamlessly.

Transports

Transport Function Use Case
stdio mcp() Local servers (python, node, npx)
SSE mcp_sse() Remote servers (legacy)
Streamable HTTP mcp_http() Remote servers (recommended)

Local MCP Server (stdio)

from ai_query import generate_text, google, mcp

async def main():
    # Connect to a local Python MCP server
    async with mcp("python", "my_server.py") as server:
        print(f"Available tools: {list(server.tools.keys())}")

        result = await generate_text(
            model=google("gemini-2.0-flash"),
            prompt="Calculate 25 * 4",
            tools=server.tools,
        )
        print(result.text)

Using npx for npm MCP packages

from ai_query import generate_text, openai, mcp

async with mcp("npx", "-y", "@modelcontextprotocol/server-fetch") as server:
    result = await generate_text(
        model=openai("gpt-4o"),
        prompt="Fetch and summarize https://example.com",
        tools=server.tools,
    )

Remote MCP Server (SSE)

from ai_query import generate_text, openai, mcp_sse

async with mcp_sse("http://localhost:8000/sse") as server:
    result = await generate_text(
        model=openai("gpt-4o"),
        prompt="Hello!",
        tools=server.tools,
    )

# With authentication
async with mcp_sse(
    "https://api.example.com/mcp/sse",
    headers={"Authorization": "Bearer token123"}
) as server:
    ...

Remote MCP Server (Streamable HTTP)

from ai_query import generate_text, openai, mcp_http

async with mcp_http("http://localhost:8000/mcp") as server:
    result = await generate_text(
        model=openai("gpt-4o"),
        prompt="Hello!",
        tools=server.tools,
    )

Combining Multiple Tool Sources

Use merge_tools to combine tools from multiple MCP servers or mix with local tools:

from ai_query import generate_text, openai, mcp, merge_tools, tool, Field

@tool(description="Calculate math expressions")
def calculate(expr: str = Field(description="Expression")) -> str:
    return str(eval(expr))

async with mcp("python", "weather_server.py") as weather:
    async with mcp("python", "search_server.py") as search:
        all_tools = merge_tools(
            {"calculator": calculate},  # Local tool
            weather,                      # MCP server
            search,                       # Another MCP server
        )

        result = await generate_text(
            model=openai("gpt-4o"),
            prompt="What's the weather in Tokyo, search for news, and calculate 100/4",
            tools=all_tools,
        )

Manual Connection Management

For long-lived connections, use connect_mcp, connect_mcp_sse, or connect_mcp_http:

from ai_query import connect_mcp

server = await connect_mcp("python", "server.py")
try:
    # Use server.tools for multiple requests...
    result = await generate_text(...)
finally:
    await server.close()

Step Callbacks

Monitor and react to each step in the execution loop with on_step_start and on_step_finish.

from ai_query import generate_text, google, StepStartEvent, StepFinishEvent

def on_start(event: StepStartEvent):
    print(f"Step {event.step_number} starting...")
    print(f"  Messages: {len(event.messages)}")
    # event.messages can be modified before the model call

def on_finish(event: StepFinishEvent):
    print(f"Step {event.step_number} finished")

    # Current step details
    if event.step.tool_calls:
        for tc in event.step.tool_calls:
            print(f"  Called: {tc.name}({tc.arguments})")
    if event.step.tool_results:
        for tr in event.step.tool_results:
            print(f"  Result: {tr.result}")

    # Accumulated state
    print(f"  Total tokens: {event.usage.total_tokens}")
    print(f"  Text so far: {event.text[:50]}...")

result = await generate_text(
    model=google("gemini-2.0-flash"),
    prompt="What's the weather in Tokyo?",
    tools={"weather": get_weather},
    on_step_start=on_start,
    on_step_finish=on_finish,
)

StepStartEvent

Field Type Description
step_number int 1-indexed step number
messages list[Message] Conversation history (modifiable)
tools ToolSet | None Available tools

StepFinishEvent

Field Type Description
step_number int 1-indexed step number
step StepResult Current step (text, tool_calls, tool_results)
text str Accumulated text from all steps
usage Usage Accumulated token usage
steps list[StepResult] All completed steps

Both callbacks support sync and async functions.

Providers

Built-in support for:

  • OpenAI: openai("gpt-4o") - uses OPENAI_API_KEY
  • Anthropic: anthropic("claude-sonnet-4-20250514") - uses ANTHROPIC_API_KEY
  • Google: google("gemini-2.0-flash") - uses GOOGLE_API_KEY

Pass API keys directly if needed:

model = google("gemini-2.0-flash", api_key="your_key")

Provider Options

Pass provider-specific parameters:

result = await generate_text(
    model=google("gemini-2.0-flash"),
    prompt="Tell me a story",
    provider_options={
        "google": {
            "safety_settings": {"HARM_CATEGORY_VIOLENCE": "BLOCK_NONE"}
        }
    }
)

Examples

See the examples/ folder for agent implementations.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ai_query-1.6.0.tar.gz (569.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ai_query-1.6.0-py3-none-any.whl (74.2 kB view details)

Uploaded Python 3

File details

Details for the file ai_query-1.6.0.tar.gz.

File metadata

  • Download URL: ai_query-1.6.0.tar.gz
  • Upload date:
  • Size: 569.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ai_query-1.6.0.tar.gz
Algorithm Hash digest
SHA256 448c8a1ebd7d17b4648cce9e1a9ca37ca98e7f19ba2b87f133eb54749a776133
MD5 9ee5b7bd06d9130308959ffa163fd189
BLAKE2b-256 16edf7c2d6a7b29e017775e7b80d3160d1854328956419264a68be622b15dcf6

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai_query-1.6.0.tar.gz:

Publisher: release.yml on Abdulmumin1/ai-query

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ai_query-1.6.0-py3-none-any.whl.

File metadata

  • Download URL: ai_query-1.6.0-py3-none-any.whl
  • Upload date:
  • Size: 74.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for ai_query-1.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ff6c81f0e08427cf9dc782cff8e5a57b08d2390c017d3adbf49ca3a3976ec827
MD5 3472fc2a50db64c16136c7707acc6480
BLAKE2b-256 a3e20c2e25dcbf917306f61a6e73850bd01800d75c409e32129c7f14eb31fdff

See more details on using hashes here.

Provenance

The following attestation bundles were made for ai_query-1.6.0-py3-none-any.whl:

Publisher: release.yml on Abdulmumin1/ai-query

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page