Lightweight Python AI client/router with async support, local tools, observability hooks, retries, structured output, and lightweight conversation history.
Project description
Lunox v5.0.0
Lunox is a compact Python library for sending prompts to multiple AI providers through one consistent API.
It focuses on:
- simple
client.ask(...)usage - lightweight routing between
geminianddeepseek - retry and fallback handling
- structured output parsing with
Schema - optional Tavily-backed
searchandextract - local tool injection
- async support
- lightweight conversation history
Installation
pip install lunox
Optional for Tavily-based search and extract:
pip install "lunox[tavily]"
This keeps tavily-python optional, which helps on devices where building Rust-backed dependencies is problematic.
Quick Start
from lunox import Client, Config
cfg = Config(
provider="gemini",
timeout=20.0,
custom_instruction="You are Lunox. Explain things clearly for beginner developers.",
)
client = Client(cfg=cfg)
res = client.ask("Explain the difference between REST and GraphQL in simple terms.")
print(res.text)
print(res.provider)
print(res.model)
print(res.reason)
Main API
from lunox import Client
client = Client()
res = client.ask("Summarize retry logic in API clients.")
print(res.text)
Useful Config helpers:
set_instruction(text): set default instruction once for every requestset_provider(provider, model=None): switch default provider and optionally its modelset_retry_policy(...): tune retries and backoff in one placeenable_search(...): enable automatic Tavily-backed groundinguse_tavily(api_key, tool_name="tavily", limit=None): store Tavily settings in configas_dict(): inspect the active config as a normal dictionary
Built-in fake streaming helpers:
type_out(text, delay=0.02): print text with a typing animationshow_response(res, delay=0.02): printRes.textwith the same effectclient.show(res, delay=0.02): instance helper if you prefer calling it fromClient
Async works the same way:
import asyncio
from lunox import AsyncClient
async def main() -> None:
client = AsyncClient()
res = await client.ask("Explain exponential backoff simply.")
print(res.text)
asyncio.run(main())
Lightweight History
Use a session when you want short conversation memory:
from lunox import Client
client = Client()
session = client.session(max_turns=6)
session.ask("My product is a Python SDK for AI providers.")
res = session.ask("Give me three tagline ideas.")
print(res.text)
Or pass a shared history list directly:
history: list[tuple[str, str]] = []
client.ask("Remember that my app is called Lunox Studio.", history=history, history_limit=6)
res = client.ask("What is my app called?", history=history, history_limit=6)
print(res.text)
Structured Output
Use Schema when you want parsed output in res.data.
from lunox import Client, Schema
client = Client()
schema = Schema(
name="ticket",
fields={
"title": str,
"priority": str,
"items": [str],
},
)
res = client.ask("Summarize this bug report.", schema=schema)
print(res.data)
Providers
res = client.ask("What is Python used for?")
fast = client.ask("Summarize HTTP status codes.", mode="fast")
reasoning = client.ask("Compare monolith vs microservices.", mode="reasoning")
forced = client.ask("Analyze this architecture tradeoff.", provider="deepseek")
Compatibility note:
provider="flash"is still accepted and mapped togemini- the legacy
javaxFlashpackage remains as a compatibility shim
Config
from lunox import Client, Config
cfg = Config(
timeout=20.0,
retries=3,
backoff=0.5,
backoff_rate=2.0,
backoff_max=8.0,
jitter=0.2,
fallback=True,
)
client = Client(cfg=cfg)
Environment-based config:
from lunox import Config
cfg = Config.from_env()
Useful environment variables:
LUNOX_TIMEOUTLUNOX_MAX_RETRIESLUNOX_BACKOFF_BASELUNOX_BACKOFF_MULTIPLIERLUNOX_BACKOFF_MAXLUNOX_JITTERLUNOX_DEFAULT_PROVIDERLUNOX_DEFAULT_MODELLUNOX_FALLBACK_PROVIDERLUNOX_PROVIDER_MODELSLUNOX_AUTO_ROUTELUNOX_AUTO_SEARCHLUNOX_TAVILY_API_KEYLUNOX_SEARCH_TOOL_NAMELUNOX_SEARCH_MAX_RESULTSLUNOX_SEARCH_TIMEOUT
Local Tools And Search
from lunox import Client
client = Client()
client.add_fn("project_info", lambda: {"title": "Project", "content": "The library focuses on multi-provider routing."})
res = client.ask("Summarize the current project focus.", tool_calls={"project_info": {}})
print(res.text)
res = client.ask("What is the latest Python release?", skills="search")
print(res.search_query)
Development
pytest
python3 -m compileall lunox javaxFlash tests examples
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 lunox-5.0.0.tar.gz.
File metadata
- Download URL: lunox-5.0.0.tar.gz
- Upload date:
- Size: 25.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb6ef7c086b9f4a376e46bdb4a9d68b6ccf7cc7e471fecffc11f2f86a06b6b77
|
|
| MD5 |
da4e8f09f7975adb23bd18d14987826d
|
|
| BLAKE2b-256 |
06da8e4ceb0eb72479f16bdc2404933becfb9b206712a4235e0e6201a019aa76
|
File details
Details for the file lunox-5.0.0-py3-none-any.whl.
File metadata
- Download URL: lunox-5.0.0-py3-none-any.whl
- Upload date:
- Size: 22.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
043a3b4fe5650cbdfe9f52f697621462013b3dfa7476f6f4f12d5565438d2d14
|
|
| MD5 |
db5c2128214ed2472f311d78e9ad8740
|
|
| BLAKE2b-256 |
a0bc1465227fb89078b340dbde8e61226c96e3e275b2187de21c0049252b3907
|