Skip to main content

pypaya-llm-client

One small client for every OpenAI-compatible LLM server — local or hosted — with images and audio as plain message parts.

Most "LLM client" code differs between providers only in the base URL. This library leans into that: one class, preset shorthands for the common servers, and multimodal input handled the way the chat protocol actually works — as content parts in a message list. ~330 lines, one required dependency (openai).

Install

pip install pypaya-llm-client
# with in-memory PIL image support:
pip install pypaya-llm-client[pil]

Quick start

from pypaya_llm_client import LLMClient

# Local model via Ollama
client = LLMClient(base_url="ollama", model="gemma4:latest")
print(client.chat("What is a neural network?").content)

# Same code, hosted via OpenRouter
client = LLMClient(base_url="openrouter", model="qwen/qwen3-vl-30b-a3b-instruct",
                   api_key="sk-or-...")

Preset base URLs (KNOWN_BACKENDS): ollama, lmstudio, vllm, llamacpp, openrouter, openai — or pass any full URL.

Images and audio

Modalities are just content-part types; pass file paths, raw bytes, or PIL images:

reply = client.chat("What text is on the button in the bottom-left?",
                    images=["screenshot.png"])

reply = client.chat("How many beeps do you hear?", audios=["alert.wav"])

Audio requires an audio-capable (omni) model. Note from real testing: an "audio input" flag does not guarantee audio understanding — pick models known to comprehend your kind of audio, and verify with a cheap test of your own.

Multi-turn conversations, mixed modalities

from pypaya_llm_client import LLMClient, build_user_message

client = LLMClient(base_url="openrouter", model="google/gemini-2.5-flash", api_key="...")
messages = [{"role": "system", "content": "You are analyzing a GUI test session."}]

messages.append(build_user_message("The session ID is ALPHA-7. Confirm."))
messages.append({"role": "assistant", "content": client.chat_messages(messages).content})

messages.append(build_user_message("New screen and new alert sound attached. "
                                   "How many beeps, what does the orange button say, "
                                   "and what was the session ID?",
                                   images=[screenshot], audios=[alert_wav_bytes]))
print(client.chat_messages(messages).content)   # e.g. "2, DEPLOY, ALPHA-7"

Metrics for free

Every call returns an LLMResponse with content, model, duration_ms, prompt_tokens, completion_tokens — enough to track latency and cost without extra instrumentation.

Per-call overrides

client.chat("Say OK.", model="qwen/qwen3-vl-8b-instruct", max_tokens=10)

Useful for model ladders (try a cheap model, fall back to a stronger one) without constructing new clients.

API surface

  • LLMClient(base_url, model, api_key, temperature, timeout, max_tokens)
  • .chat(prompt, *, system, images, audios, model, max_tokens) -> LLMResponse
  • .chat_messages(messages, *, model, max_tokens) -> LLMResponse
  • .is_available() -> bool — probe the server
  • build_user_message(text, images, audios) -> dict — build one OpenAI-format message
  • encode_image_base64(path | bytes | PIL.Image), get_image_media_type(...)

Tests

pytest

The suite runs fully offline — no server, no API key, no network.

License

MIT

Metadata

Release files for pypaya-llm-client 0.1.0

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

Source distribution (sdist)

Source distribution for pypaya-llm-client 0.1.0
File Size Uploaded Provenance Actions
pypaya_llm_client-0.1.0.tar.gz 7.5 kB Without provenance Details for pypaya_llm_client-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pypaya-llm-client 0.1.0
File Interpreter ABI Platform Actions
pypaya_llm_client-0.1.0-py3-none-any.whl Python 3 none any Details for pypaya_llm_client-0.1.0-py3-none-any.whl

Total release size: 16.6 kB

Release files / pypaya_llm_client-0.1.0.tar.gz

Download URL pypaya_llm_client-0.1.0.tar.gz
Size 7.5 kB
Tags Source
SHA-256 checksum
How to use checksums
65648f90bdd509a956818c3c0277ff36a5709b68a0648e81693e6868cd368638
BLAKE2b-256 checksum
How to use checksums
46d7a5ffcdb2c4dfbddd9a1bcc556dcfbd76b9b0d15cb453c27729a3fc4122cf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release files / pypaya_llm_client-0.1.0-py3-none-any.whl

Download URL pypaya_llm_client-0.1.0-py3-none-any.whl
Size 9.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e1811073c650b035b7a0f0581a67c4d60e049a4ea1ca9e1bc758b3bb14d864f0
BLAKE2b-256 checksum
How to use checksums
f7dc4ae92c8c2db6328932c3283ed51600c41f035443e93798ffa0966166b8c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Security for pypaya-llm-client 0.1.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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