Skip to main content

SmolLLM

A minimal Python library for interacting with various LLM providers, featuring automatic API key load balancing and streaming responses.

Installation

pip install smolllm
uv add "smolllm @ ../smolllm"

Quick Start

import asyncio
from smolllm import ask_llm

async def main():
    response = await ask_llm(
        "Say hello world",
        model="gemini/gemini-2.0-flash"
    )
    print(response)
    print(response.actual_model)

if __name__ == "__main__":
    asyncio.run(main())

response.model is the winning requested model spec. response.resolved_model is the optional model identity reported by the server. Use response.actual_model for the best available identity: reported when present, otherwise requested.

Reasoning Effort

For reasoning-capable models, pass reasoning_effort through to the provider. Useful for Ollama reasoning models where omitting it can make replies much slower.

response = await ask_llm(
    "Reply with one word.",
    model="ollama/qwen3.5:0.8b",
    base_url="http://rocry-ubuntu.local:11434/v1",
    reasoning_effort="none",
)

Images

image_paths accepts file paths or data: URLs. Each image becomes an image_url part on the last user message: the prompt string, or the last entry of a message list. Files are base64-encoded with a mime type guessed from the extension.

response = await ask_llm(
    "What is in this picture?",
    model="openai/gpt-4o",
    image_paths=["photo.jpg", "data:image/png;base64,iVBORw0..."],
)

With a message list the last message must be a user turn with content, or a ValueError is raised.

Tool Calling

Pass tools through the extra_body escape hatch; assembled tool calls come back on the response. smolllm never executes a tool — you run the loop and replay the results as assistant + tool messages. See examples/tool_calling.py.

response = await ask_llm(messages, extra_body={"tools": TOOLS})
for call in response.tool_calls:
    name = call["function"]["name"]
    args = json.loads(call["function"]["arguments"])

extra_body also carries any other raw request field the library does not model (response_format, service_tier, provider-private params); it is merged last, so you win over library defaults. Fields the library reads back — stream, stream_options, messages, model — are rejected.

Provider Configuration

Format: provider/model_name (e.g., openai/gpt-4, gemini/gemini-2.0-flash)

A bare model name (no /) targets an endpoint directly — pass base_url and api_key explicitly (no env fallback):

response = await ask_llm(
    "hi",
    model="gpt-4",
    base_url="https://my-proxy.example/v1",
    api_key="sk-xxx",
)

API Keys

The library looks for API keys in environment variables following the pattern: {PROVIDER}_API_KEY

Example:

# .env
OPENAI_API_KEY=sk-xxx
GEMINI_API_KEY=key1,key2  # Multiple keys supported

Key/endpoint pairs rejected with a permanent credential status (for example CONSUMER_SUSPENDED or API_KEY_INVALID) are removed from the active pool for the rest of the process lifetime. Error logs redact credential-shaped content; eviction is identified only by a one-way key fingerprint.

Custom Base URLs

Override default API endpoints using: {PROVIDER}_BASE_URL

Example:

OPENAI_BASE_URL=https://custom.openai.com/v1
OLLAMA_BASE_URL=http://localhost:11434/v1

Advanced Configuration

You can combine multiple keys and base URLs in several ways:

  1. One key with multiple base URLs:
OLLAMA_API_KEY=ollama
OLLAMA_BASE_URL=http://localhost:11434/v1,http://other-server:11434/v1
  1. Multiple keys with one base URL:
GEMINI_API_KEY=key1,key2
GEMINI_BASE_URL=https://api.gemini.com/v1
  1. Paired keys and base URLs:
# Must have equal number of keys and URLs
# The library will randomly select matching pairs
GEMINI_API_KEY=key1,key2
GEMINI_BASE_URL=https://api.gemini.com/v1,https://api.gemini.com/v2

Environment Setup Best Practices

When using SmolLLM in your project, you should handle environment variables at your application level:

  1. Create a .env file:
# .env
OPENAI_API_KEY=sk-xxx
GEMINI_API_KEY=xxx,xxx2
ANTHROPIC_API_KEY=sk-xxx
  1. Load the file at the application/process boundary:
uv run --env-file .env app.py

Tips

  • Keep sensitive API keys in .env (add to .gitignore)
  • Create .env.example for documentation
  • For production, consider using your platform's secret management system
  • When using multiple keys, separate with commas (no spaces)

Metadata

Release files for smolllm 0.11.4

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

Source distribution (sdist)

Source distribution for smolllm 0.11.4
File Size Uploaded
smolllm-0.11.4.tar.gz 87.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for smolllm 0.11.4
File Interpreter ABI Platform
smolllm-0.11.4-py3-none-any.whl Python 3 none any Details

Total release size: 122.6 kB

Release files / smolllm-0.11.4.tar.gz

Download URL smolllm-0.11.4.tar.gz
Size 87.6 kB
Tags Source
SHA-256 checksum
How to use checksums
10b13e24118df13a451dfbd58f18237d27271189f4b72c054a70587633f3110a
BLAKE2b-256 checksum
How to use checksums
38f9baab24d97db0562170b107835f44f0403498b06ada4a3460004249a48076
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 7, 2026.

Transparency log

Release files / smolllm-0.11.4-py3-none-any.whl

Download URL smolllm-0.11.4-py3-none-any.whl
Size 35.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3ceddd5851889ce086128777fbe5c75cd0cc6bc20a781a8f4f3c6a53d3c270fd
BLAKE2b-256 checksum
How to use checksums
414fd705da89c7685c97eefd62e18c27a3a40c3270d89bd6d8570dd1d272be48
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 7, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.11.4 This release

2 release files

0.11.3

2 release files

0.11.2

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.5

2 release files

0.1.1

2 release files

0.1.0

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