Skip to main content

Unified Python library for interacting with LLM providers (OpenAI, Gemini, Anthropic Claude). Simple, consistent syntax with stateless design.

Project description

msgmodel

PyPI version Python 3.10+ License: MIT

A unified Python library and CLI for interacting with multiple Large Language Model (LLM) providers with a simple, consistent syntax.

Overview

msgmodel provides both a Python library and a command-line interface to interact with major LLM providers:

  • OpenAI (GPT models)
  • Google Gemini
  • Anthropic Claude

Privacy by Default

msgmodel takes a privacy-preserving stance by default. Where providers offer opt-out mechanisms, we use them automatically. Where they don't, we document the limitations honestly.

What msgmodel controls What msgmodel cannot control
✅ Sends X-OpenAI-No-Store header automatically ❌ OpenAI ZDR eligibility (requires account approval)
✅ Uses inline base64 encoding (no server-side file uploads) ❌ Gemini tier detection (paid vs. free)
✅ Stateless design (we retain nothing) ❌ Provider-side retention policies
✅ No parameters to accidentally enable retention ❌ Provider terms of service changes

You don't need to configure anything for privacy — msgmodel's defaults are already privacy-preserving. However, provider-level guarantees depend on your account status and tier. See the Data Retention & Privacy section for details.

Features

  • Unified API: Single query() and stream() functions work with all providers
  • Library & CLI: Use as a Python module or command-line tool
  • Streaming support: Stream responses in real-time
  • File attachments: Process images, PDFs, and text files with in-memory BytesIO
  • Flexible configuration: Dataclass-based configs with sensible defaults
  • Multiple API key sources: Direct parameter, environment variable, or key file
  • Exception-based error handling: Clean errors, no sys.exit() in library code
  • Type-safe: Full type hints throughout
  • Stateless design: msgmodel never retains your data; all processing is ephemeral

Installation

From PyPI (Recommended)

pip install msgmodel

From Source

# Clone the repository
git clone https://github.com/LeoooDias/msgmodel.git
cd msgmodel

# Install the package
pip install -e .

# Or with development dependencies
pip install -e ".[dev]"

Prerequisites

  • Python 3.10 or higher
  • API keys from the providers you wish to use

Quick Start

As a Library

from msgmodel import query, stream

# Simple query (uses OPENAI_API_KEY env var)
response = query("openai", "What is Python?")
print(response.text)

# With explicit API key
response = query("gemini", "Hello!", api_key="your-api-key")

# Streaming
for chunk in stream("openai", "Tell me a story"):
    print(chunk, end="", flush=True)

# With file attachment (in-memory BytesIO only)
import io
file_obj = io.BytesIO(your_binary_data)
response = query("gemini", "Describe this image", file_like=file_obj, filename="photo.jpg")

# With custom configuration
from msgmodel import OpenAIConfig

config = OpenAIConfig(model="gpt-4o-mini", temperature=0.7, max_tokens=2000)
response = query("openai", "Write a poem", config=config)

As a CLI

# Basic usage
python -m msgmodel -p openai "What is Python?"

# Using shorthand provider codes
python -m msgmodel -p g "Hello, Gemini!"    # g = gemini
python -m msgmodel -p o "Hello, OpenAI!"    # o = openai
python -m msgmodel -p c "Hello, Claude!"    # c = claude/anthropic

# With streaming
python -m msgmodel -p openai "Tell me a story" --stream

# From a file
python -m msgmodel -p gemini -f prompt.txt

# With system instruction
python -m msgmodel -p claude "Analyze this" -i "You are a data analyst"

# With file attachment (base64 inline)
python -m msgmodel -p gemini "Describe this" -b image.jpg

# Custom parameters
python -m msgmodel -p openai "Hello" -m gpt-4o-mini -t 500 --temperature 0.7

# Get full JSON response instead of just text
python -m msgmodel -p openai "Hello" --json

# Verbose output (shows model, provider, token usage)
python -m msgmodel -p openai "Hello" -v

API Key Configuration

API keys can be provided in three ways (in order of priority):

  1. Direct parameter: query("openai", "Hello", api_key="sk-...")
  2. Environment variable:
    • OPENAI_API_KEY for OpenAI
    • GOOGLE_API_KEY for Gemini
    • ANTHROPIC_API_KEY for Claude/Anthropic
  3. Key file in current directory:
    • openai-api.key
    • gemini-api.key
    • anthropic-api.key

Configuration

Each provider has its own configuration dataclass with sensible defaults:

from msgmodel import OpenAIConfig, GeminiConfig, AnthropicConfig

# OpenAI configuration
openai_config = OpenAIConfig(
    model="gpt-4o",           # Model to use
    temperature=1.0,          # Sampling temperature
    top_p=1.0,                # Nucleus sampling
    max_tokens=1000,          # Max output tokens
)

# Gemini configuration
gemini_config = GeminiConfig(
    model="gemini-2.5-flash",
    temperature=1.0,
    top_p=0.95,
    top_k=40,
    safety_threshold="BLOCK_NONE",
)

# Anthropic/Claude configuration
anthropic_config = AnthropicConfig(
    model="claude-haiku-4-5-20251001",  # Default; also: claude-sonnet-4-20250514
    temperature=1.0,
    top_p=1.0,
    max_tokens=1000,
)

Data Retention & Privacy

msgmodel is stateless — it never retains your data. All processing is ephemeral.

Provider behavior varies — and is ultimately outside our control. This section documents what msgmodel does by default and what depends on your provider account.

OpenAI

When using OpenAI:

  • Training opt-out: OpenAI does not use API data for model training (this is standard policy for all API users since March 2023)
  • Data storage: By default, OpenAI may retain API data for up to 30 days for abuse monitoring. The X-OpenAI-No-Store header is sent to request zero storage, but Zero Data Retention (ZDR) requires separate eligibility from OpenAI
  • File handling: All files are base64-encoded and embedded inline in prompts—no server-side uploads

Important: Training opt-out is automatic for all API users. However, if you need zero data storage (not just no training), you must be ZDR-eligible with OpenAI. Review OpenAI's data usage policy and ZDR documentation.

from msgmodel import query

response = query("openai", "Your prompt here")
# Training opt-out: automatic | ZDR header: sent (eligibility required)

Google Gemini

Google Gemini's data handling depends entirely on your account tier. msgmodel cannot detect or control which tier you're on.

Tier Training Opt-Out Data Retention
Paid (Cloud Billing) ✅ Yes ~24-72 hours (abuse monitoring only)
Free ❌ No Data may be used for model training

What msgmodel does: Uses inline base64 encoding for files (no server-side uploads).

What msgmodel cannot do: Detect your tier or change Google's data handling policies.

If privacy matters for your use case: Verify you have Google Cloud Billing enabled with paid API quota. Free tier users should assume their data may be used for training.

from msgmodel import query

# Data handling depends entirely on YOUR Google account tier
response = query("gemini", "Your prompt here")

Learn more: Google Gemini API Terms

Anthropic Claude

When using Anthropic Claude:

  • Default behavior: Anthropic does not use API data for model training by default
  • Data retention: Data may be retained temporarily for safety monitoring and abuse prevention
  • File handling: Base64-encoded inline embedding
from msgmodel import query

response = query("claude", "Your prompt here")
# or: query("anthropic", ...) or query("c", ...)

Learn more: Anthropic Privacy Policy

Summary

Provider What msgmodel does Training Opt-Out Data Retention
OpenAI Sends X-OpenAI-No-Store header ✅ Automatic (API policy) ~30 days; ZDR requires eligibility
Gemini Inline file encoding only ⚠️ Depends on YOUR tier Paid: ~24-72h / Free: training
Anthropic Standard API calls ✅ Default (API policy) Temporary (safety monitoring)

Limitations

msgmodel cannot:

  • Verify your OpenAI ZDR eligibility
  • Detect your Gemini account tier
  • Override provider terms of service
  • Guarantee provider policy compliance

For maximum privacy: Verify your account status directly with each provider. msgmodel sends all available privacy-preserving signals, but enforcement is provider-side.

File Uploads

The BytesIO-Only Approach

All file uploads in msgmodel v3.2.0+ use in-memory BytesIO objects with base64 inline encoding:

import io
from msgmodel import query

# Read file into memory
with open("document.pdf", "rb") as f:
    file_data = f.read()

# Create BytesIO object
file_obj = io.BytesIO(file_data)

# Query with file
response = query(
    "openai",
    "Summarize this document",
    file_like=file_obj,
    filename="document.pdf"  # Enables MIME type detection
)

Why BytesIO?

  • Stateless operation—each request is completely independent
  • No server-side file uploads (Files API not used)
  • Files are base64-encoded inline in prompts

File Size Limits

  • OpenAI: ~15-20MB practical limit (base64 overhead + token limits)
  • Gemini: ~22MB practical limit (base64 overhead + token limits)
  • Anthropic: ~20MB practical limit (base64 overhead + token limits)

If API returns a size-related error, the file exceeds practical limits for that provider.

Error Handling

The library uses exceptions instead of sys.exit():

from msgmodel import query, MsgModelError, AuthenticationError, APIError

try:
    response = query("openai", "Hello")
except AuthenticationError as e:
    print(f"API key issue: {e}")
except APIError as e:
    print(f"API call failed: {e}")
    print(f"Status code: {e.status_code}")
except MsgModelError as e:
    print(f"General error: {e}")

Response Object

The query() function returns an LLMResponse object:

response = query("openai", "Hello")

print(response.text)          # The generated text
print(response.model)         # Model used (e.g., "gpt-4o")
print(response.provider)      # Provider name (e.g., "openai")
print(response.usage)         # Token usage dict (if available)
print(response.raw_response)  # Complete API response

Project Structure

msgmodel/
├── msgmodel/                    # Python package
│   ├── __init__.py              # Public API exports
│   ├── __main__.py              # CLI entry point
│   ├── core.py                  # Core query/stream functions
│   ├── config.py                # Configuration dataclasses
│   ├── exceptions.py            # Custom exceptions
│   ├── py.typed                 # PEP 561 marker for typed package
│   └── providers/               # Provider implementations
│       ├── __init__.py
│       ├── openai.py
│       └── gemini.py
├── tests/                       # Test suite
│   ├── test_config.py
│   ├── test_core.py
│   └── test_exceptions.py
├── pyproject.toml               # Package configuration
├── LICENSE                      # MIT License
├── MANIFEST.in                  # Distribution manifest
├── requirements.txt             # Dependencies
└── README.md

CLI Usage

After installation, the msgmodel command is available:

# Basic usage
msgmodel -p openai "What is Python?"

# Or using python -m
python -m msgmodel -p openai "What is Python?"

# Provider shortcuts: o=openai, g=gemini
msgmodel -p g "Hello, Gemini!"

# With streaming
msgmodel -p openai "Tell me a story" --stream

# From a file
msgmodel -p gemini -f prompt.txt

Running Tests

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run with coverage
pytest --cov=msgmodel

Building & Publishing

# Install build tools
pip install build twine

# Build the package
python -m build

# Check the distribution
twine check dist/*

# Upload to PyPI (requires PyPI account)
twine upload dist/*

# Upload to TestPyPI first (recommended)
twine upload --repository testpypi dist/*

License

MIT License - see LICENSE for details.

Author

Leo Dias

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

msgmodel-4.1.1.tar.gz (75.6 kB view details)

Uploaded Source

Built Distribution

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

msgmodel-4.1.1-py3-none-any.whl (47.9 kB view details)

Uploaded Python 3

File details

Details for the file msgmodel-4.1.1.tar.gz.

File metadata

  • Download URL: msgmodel-4.1.1.tar.gz
  • Upload date:
  • Size: 75.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for msgmodel-4.1.1.tar.gz
Algorithm Hash digest
SHA256 6a0cba4973c08fd05d31eba981139826e407a770fe72497a9ca0b639ca8d76e2
MD5 e231b6ca70cf046980b0c55b5ac6e85b
BLAKE2b-256 3915df211a5dadbb0eaadb0361564bbb219c1c04b714338c1da8581607812fe5

See more details on using hashes here.

File details

Details for the file msgmodel-4.1.1-py3-none-any.whl.

File metadata

  • Download URL: msgmodel-4.1.1-py3-none-any.whl
  • Upload date:
  • Size: 47.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.11

File hashes

Hashes for msgmodel-4.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9e642e9d4883c0320342daab869d63f4d843e45e00379dabff2994553701e87d
MD5 7abcca66b1b0b16b0672c025ae890929
BLAKE2b-256 5f29e59da84aaefdc00212b4a52f23176a714da98e56d53663236171b5ae40c5

See more details on using hashes here.

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