A unified Python interface and API server for running local Large Language Models.
Project description
One interface. Every local LLM.
A unified Python SDK and OpenAI-compatible API server for local large language models.
Quick Start • Features • Architecture • Installation • Usage • API Server • Contributing
Features
| Feature | Description |
|---|---|
| Multi-Backend | Swap between Ollama and llama.cpp with a single parameter change |
| Chat Sessions | Built-in conversation memory and history management |
| Streaming | Real-time token-by-token streaming (sync & async) |
| Tool Calling | Native function/tool calling support across backends |
| JSON Mode | Enforce structured JSON output from any supported model |
| OpenAI-Compatible API | Drop-in FastAPI server compatible with the OpenAI SDK |
| Async-First | Full async/await support for high-concurrency workloads |
| Auto Model Pull | Automatically downloads models from Ollama or Hugging Face Hub |
Quick Start
# Install
pip install omni-local-llm
# Or with uv (recommended)
uv pip install omni-local-llm
from omnillm import LocalLLMManager
manager = LocalLLMManager()
response = manager.chat(
backend="ollama",
model="llama3",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response)
That's it. Switch to llama.cpp by changing one word:
response = manager.chat(
backend="llama.cpp",
model="unsloth/llama-3-8b-Instruct-GGUF",
messages=[{"role": "user", "content": "Hello!"}],
filename="llama-3-8b-Instruct-Q4_K_M.gguf"
)
Architecture
┌─────────────────────────────────────────────────────────┐
│ Your Application │
├─────────────┬─────────────────────┬─────────────────────┤
│ Python │ Interactive CLI │ OpenAI-Compatible │
│ SDK │ (python -m omnillm)│ FastAPI Server │
├─────────────┴─────────────────────┴─────────────────────┤
│ ChatSession │
│ (History · Streaming · Tools) │
├─────────────────────────────────────────────────────────┤
│ LocalLLMManager │
│ (Backend Registry & Router) │
├────────────────────────┬────────────────────────────────┤
│ OllamaAdapter │ LlamaCPPAdapter │
│ (ollama Python SDK) │ (llama-cpp-python + HF Hub) │
└────────────────────────┴────────────────────────────────┘
Module Map
| Module | Purpose |
|---|---|
omnillm/core/base.py |
LLMBackend — abstract base class for all adapters |
omnillm/core/manager.py |
LocalLLMManager — backend registry & request router |
omnillm/core/session.py |
ChatSession — conversation state, streaming, tool calls |
omnillm/adapters/ollama_adapter.py |
Ollama integration via official Python client |
omnillm/adapters/llamacpp_adapter.py |
llama.cpp integration + automatic GGUF model caching |
omnillm/server.py |
OpenAI-compatible FastAPI HTTP server |
omnillm/__main__.py |
Interactive CLI chat interface |
Installation
Prerequisites
- Python 3.12+
- uv (recommended) or pip
- At least one backend:
- Ollama installed and running, or
- A GGUF model on Hugging Face Hub (auto-downloaded)
Install from source
git clone https://github.com/matteoespo/omni-local-llm.git
cd omni-local-llm
uv pip install -e .
Install from PyPI
pip install omni-local-llm
# or
uv pip install omni-local-llm
Usage
Python SDK
Basic Chat
from omnillm import LocalLLMManager
manager = LocalLLMManager()
response = manager.chat(
backend="ollama",
model="llama3",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response)
Chat Session (with Memory)
session = manager.create_session(
backend="ollama",
model="llama3",
system_prompt="You are a helpful assistant."
)
response1 = session.send("Hello, I am Bob.")
response2 = session.send("What is my name?") # Remembers "Bob"
Async & Streaming
import asyncio
from omnillm import LocalLLMManager
async def main():
manager = LocalLLMManager()
session = manager.create_session(backend="ollama", model="llama3")
stream = await session.asend("Tell me a short story.", stream=True)
async for chunk in stream:
print(chunk, end="", flush=True)
asyncio.run(main())
Tool Calling
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"}
},
"required": ["city"]
}
}
}]
response = manager.chat(
backend="ollama",
model="llama3",
messages=[{"role": "user", "content": "What's the weather in Tokyo?"}],
tools=tools
)
# response["tool_calls"] contains the function call
JSON Mode
response = manager.chat(
backend="ollama",
model="llama3",
messages=[{"role": "user", "content": "List 3 colors as JSON"}],
json_mode=True
)
# Returns valid JSON string
Interactive CLI
Start an interactive chat session directly in your terminal:
# Using Ollama
python -m omnillm --backend ollama --model llama3
# Using llama.cpp (auto-downloads from Hugging Face)
python -m omnillm --backend llama.cpp \
--model unsloth/llama-3-8b-Instruct-GGUF \
--filename llama-3-8b-Instruct-Q4_K_M.gguf
# With a system prompt
python -m omnillm --backend ollama --model llama3 \
--system "You are a pirate. Respond only in pirate speak."
API Server
Launch an OpenAI-compatible local API server:
python -m omnillm.server
# Server runs on http://localhost:8000
Use with the OpenAI SDK
import openai
client = openai.OpenAI(
base_url="http://localhost:8000/v1",
api_key="not-needed"
)
response = client.chat.completions.create(
model="ollama/llama3", # prefix with backend name
messages=[{"role": "user", "content": "Explain relativity in one sentence."}]
)
print(response.choices[0].message.content)
Use with curl
curl -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "ollama/llama3",
"messages": [{"role": "user", "content": "Hello!"}]
}'
Running Tests
# With uv (recommended)
uv run pytest
# Or activate the venv first
source .venv/bin/activate
pytest
# With coverage
uv run pytest --cov=omnillm --cov-report=term-missing
Contributing
Contributions are welcome! Please see the Contributing Guide for details on:
- Setting up your development environment
- Adding new LLM backend adapters
- Submitting pull requests
License
This project is licensed under the MIT License — see the LICENSE file for details.
Roadmap
- vLLM backend adapter
- KoboldCpp backend adapter
- Token usage tracking and reporting
- Vision/multimodal support
- Model hot-swapping in sessions
- Prompt template management
- Docker image for the API server
Made with ❤️ by matteoespo
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file omni_local_llm-0.1.0.tar.gz.
File metadata
- Download URL: omni_local_llm-0.1.0.tar.gz
- Upload date:
- Size: 60.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0c0d604398b369779e206424655a5722b587b67f27fe8f5533bca7b665e83a30
|
|
| MD5 |
724532a911a887876674bea0110a7050
|
|
| BLAKE2b-256 |
0a78602dc38cfdbfc264f880cfe49feef185e4a372a5006cc07b4f62a7d6601c
|
Provenance
The following attestation bundles were made for omni_local_llm-0.1.0.tar.gz:
Publisher:
release.yml on matteoespo/omni-local-llm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
omni_local_llm-0.1.0.tar.gz -
Subject digest:
0c0d604398b369779e206424655a5722b587b67f27fe8f5533bca7b665e83a30 - Sigstore transparency entry: 2106745455
- Sigstore integration time:
-
Permalink:
matteoespo/omni-local-llm@1a29087aa123af6f821cb65f1567098e29daa390 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/matteoespo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1a29087aa123af6f821cb65f1567098e29daa390 -
Trigger Event:
push
-
Statement type:
File details
Details for the file omni_local_llm-0.1.0-py3-none-any.whl.
File metadata
- Download URL: omni_local_llm-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b37e948087aac14356378e615dcec25adf3ddfc60a1ad778253ffab1a7a81ce
|
|
| MD5 |
7ed6716a081d7be76b2a899aeb21184a
|
|
| BLAKE2b-256 |
628f6320e66e38aea17c4ede5e508cbc8d23f1603085df39af61c5b32b14ce42
|
Provenance
The following attestation bundles were made for omni_local_llm-0.1.0-py3-none-any.whl:
Publisher:
release.yml on matteoespo/omni-local-llm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
omni_local_llm-0.1.0-py3-none-any.whl -
Subject digest:
0b37e948087aac14356378e615dcec25adf3ddfc60a1ad778253ffab1a7a81ce - Sigstore transparency entry: 2106745644
- Sigstore integration time:
-
Permalink:
matteoespo/omni-local-llm@1a29087aa123af6f821cb65f1567098e29daa390 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/matteoespo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1a29087aa123af6f821cb65f1567098e29daa390 -
Trigger Event:
push
-
Statement type: