ccs-llmconnector
ccs-llmconnector is a thin Python wrapper around leading large-language-model SDKs,
including the OpenAI Responses API, Google's Gemini SDK, Anthropic's Claude
Messages API, and xAI's Grok chat API. It exposes a minimal interface that
forwards the most common options such as API key, prompt, optional reasoning
effort hints, token limits, and image inputs, and includes helpers to enumerate
the models available to your account with each provider.
Installation
# from PyPI (normalized project name)
pip install ccs-llmconnector
# or from source (this repository)
pip install .
Requirements
- Python 3.10+
- Provider SDKs installed automatically with the package:
openaigoogle-genaianthropicxai-sdk
Components
OpenAIResponsesClient- direct wrapper around the OpenAI Responses API, ideal when your project only targets OpenAI models. Includes a model discovery helper.GeminiClient- thin wrapper around the Google Gemini SDK. Includes a model discovery helper.AnthropicClient- lightweight wrapper around the Anthropic Claude Messages API. Includes a model discovery helper.GrokClient- wrapper around the xAI Grok chat API. Includes a model discovery helper.LLMClient- provider router that delegates to registered clients for OpenAI, Gemini, Anthropic, and Grok (alias:xai) without changing call sites.
Common Options
All clients expose the same optional controls:
messages: list of{role, content}entries (e.g.,system,user,assistant). If bothpromptandmessagesare provided,promptis appended as the last user message.temperature: optional sampling temperature.top_p: optional nucleus sampling value.request_id: free-form request identifier for tracing/logging.timeout_s: optional timeout in seconds (best-effort depending on provider).max_retriesandretry_backoff_s: retry count and exponential backoff base delay.
Async counterparts are available as async_generate_response, async_generate_image, and async_list_models.
GeminiClient
Usage
Use the GeminiClient when you want direct access to the Google Gemini SDK without
going through the provider router.
Requires the
google-genaiPython package (installed automatically withllmconnector).
from llmconnector import GeminiClient
client = GeminiClient()
text_response = client.generate_response(
api_key="your-gemini-api-key",
prompt="Summarize the key benefits of unit testing.",
model="gemini-2.5-flash",
max_tokens=2000,
)
# System messages are automatically extracted and passed as Gemini's
# system_instruction config parameter (Gemini does not support a "system"
# role in contents).
chat_response = client.generate_response(
api_key="your-gemini-api-key",
messages=[
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "Explain dependency injection in one paragraph."},
],
model="gemini-2.5-flash",
)
vision_response = client.generate_response(
api_key="your-gemini-api-key",
prompt="Describe the main action in this image.",
model="gemini-2.5-flash",
images=[
"/absolute/path/to/local-image.png",
"https://example.com/sample.jpg",
],
)
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
api_key |
str |
Yes | GEMINI or GOOGLE API key used for authentication. |
prompt |
Optional[str] |
Conditional | Plain-text prompt. Required unless images is supplied. |
model |
str |
Yes | Target model identifier, e.g. gemini-2.5-flash. |
max_tokens |
int |
No | Defaults to 32000. Passed to the SDK as max_output_tokens. |
messages |
Optional[Sequence[dict]] |
No | Chat-style messages (role, content). Messages with role: "system" are extracted and passed as Gemini's system_instruction. |
reasoning_effort |
Optional[str] |
No | Set to "none", "minimal", "low", "medium", or "high" to configure Gemini thinking (for supported models). |
temperature |
Optional[float] |
No | Sampling temperature forwarded to Gemini GenerateContentConfig. |
top_p |
Optional[float] |
No | Nucleus sampling value forwarded to Gemini GenerateContentConfig. |
images |
Optional[Sequence[str | Path]] |
No | Image references (local paths, URLs, or data URLs) read and forwarded to the Gemini SDK. |
cached_content |
Optional[str] |
No | Name of a prompt cache from create_prompt_cache. The cache holds the system instruction, so no system messages may be passed with it. |
references are automatically converted into the appropriate types.Part instances,
allowing you to mix text and visuals in a single request.
generate_response_with_usage also reports reasoning_tokens (Gemini thinking tokens, billed as
output) and cached_input_tokens (the part of input_tokens served from a prompt cache).
Prompt caching
A long system prompt that many requests share can be cached once (Gemini explicit context caching). Cached input tokens are billed at the model's cached-input price plus a small storage fee per hour until the cache expires or is deleted. Gemini rejects caches below a model-specific minimum size.
from llmconnector import LLMClient
client = LLMClient()
cache = client.create_prompt_cache(
provider="gemini",
api_key="your-gemini-api-key",
model="gemini-2.5-flash",
system=long_system_prompt,
ttl_s=3600,
)
response = client.generate_response_with_usage(
provider="gemini",
api_key="your-gemini-api-key",
model="gemini-2.5-flash", # must be the cache's model
messages=[{"role": "user", "content": "Next question"}], # no system message
cached_content=cache.name,
)
print(response.usage.cached_input_tokens)
client.delete_prompt_cache(provider="gemini", api_key="your-gemini-api-key", name=cache.name)
Async variants: async_create_prompt_cache and async_delete_prompt_cache. Providers without
explicit prompt caches raise ValueError for these calls and for cached_content.
Image Generation
Use generate_image to create images using Gemini's image generation models (e.g., gemini-3-pro-image-preview).
image_bytes = client.generate_image(
api_key="your-gemini-api-key",
prompt="Generate an infographic of the current weather in Tokyo.",
model="gemini-3-pro-image-preview",
image_size="2K", # Optional, defaults to "2K"
aspect_ratio="16:9", # Optional, e.g. "16:9", "4:3"
)
with open("weather_tokyo.png", "wb") as f:
f.write(image_bytes)
You can also provide an input image for editing tasks:
image_bytes = client.generate_image(
api_key="your-gemini-api-key",
prompt="Make the background a sunset.",
model="gemini-3-pro-image-preview",
image="/path/to/original.png",
)
Listing models
Use list_models to enumerate the Gemini models available to your account:
from llmconnector import GeminiClient
client = GeminiClient()
for model in client.list_models(api_key="your-gemini-api-key"):
print(model["id"], model["display_name"])
AnthropicClient
Usage
Use the AnthropicClient when you want direct access to Anthropic's Claude Messages API.
Requires the
anthropicPython package (installed automatically withllmconnector).
from llmconnector import AnthropicClient
client = AnthropicClient()
text_response = client.generate_response(
api_key="sk-ant-api-key",
prompt="Summarize the key benefits of unit testing.",
model="claude-sonnet-4-5-20250929",
max_tokens=2000,
)
vision_response = client.generate_response(
api_key="sk-ant-api-key",
prompt="Describe the main action in this image.",
model="claude-3-5-sonnet-20241022",
images=[
"/absolute/path/to/local-image.png",
"https://example.com/sample.jpg",
],
)
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
api_key |
str |
Yes | Anthropic API key used for authentication. |
prompt |
Optional[str] |
Conditional | Plain-text prompt. Required unless images is supplied. |
model |
str |
Yes | Target model identifier, e.g. claude-3-5-sonnet-20241022. |
max_tokens |
int |
No | Defaults to 32000. Passed to the SDK as max_tokens. |
messages |
Optional[Sequence[dict]] |
No | Chat-style messages (role, content). Messages with role: "system" are sent as Anthropic's top-level system parameter. |
reasoning_effort |
Optional[str] |
No | Present for parity with other clients; currently ignored by the Anthropic SDK. |
temperature |
Optional[float] |
No | Sampling temperature forwarded to Anthropic messages.create. |
top_p |
Optional[float] |
No | Nucleus sampling value forwarded to Anthropic messages.create. |
images |
Optional[Sequence[str | Path]] |
No | Image references (local paths, URLs, or data URLs) read and converted to base64 blocks. |
The method returns the generated model output as a plain string. Optional image
references are automatically transformed into Anthropic image blocks so you can
mix text and visual inputs in a single request.
Listing models
Use list_models to enumerate the Anthropic models available to your account:
from llmconnector import AnthropicClient
client = AnthropicClient()
for model in client.list_models(api_key="sk-ant-api-key"):
print(model["id"], model["display_name"])
GrokClient
Usage
Use the GrokClient when you want direct access to xAI's Grok chat API.
Requires the
xai-sdkPython package (installed automatically withllmconnector). Note:xai-sdktargets Python 3.10 and newer.
from llmconnector import GrokClient
client = GrokClient()
text_response = client.generate_response(
api_key="xai-api-key",
prompt="Summarize the key benefits of unit testing.",
model="grok-3",
max_tokens=2000,
)
vision_response = client.generate_response(
api_key="xai-api-key",
prompt="Describe the main action in this image.",
model="grok-2-vision",
images=[
"/absolute/path/to/local-image.png",
"https://example.com/sample.jpg",
],
)
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
api_key |
str |
Yes | xAI API key used for authentication. |
prompt |
Optional[str] |
Conditional | Plain-text prompt. Required unless images is supplied. |
model |
str |
Yes | Target model identifier, e.g. grok-3. |
max_tokens |
int |
No | Defaults to 32000. Passed to the Grok API as max_tokens. |
reasoning_effort |
Optional[str] |
No | Hint for reasoning-focused models ("none", "low", "medium", or "high"). |
temperature |
Optional[float] |
No | Sampling temperature forwarded to the Grok request. |
top_p |
Optional[float] |
No | Nucleus sampling value forwarded to the Grok request. |
images |
Optional[Sequence[str | Path]] |
No | Image references (local paths converted to data URLs, or remote URLs passed through). |
Image Generation
Use generate_image with xAI image generation models such as grok-imagine-image.
image_bytes = client.generate_image(
api_key="xai-api-key",
prompt="Generate a clean product mockup on a white background.",
model="grok-imagine-image",
image_size="2K",
aspect_ratio="16:9",
)
Listing models
Use list_models to enumerate the Grok language models available to your account:
from llmconnector import GrokClient
client = GrokClient()
for model in client.list_models(api_key="xai-api-key"):
print(model["id"], model["display_name"])
OpenAIResponsesClient
Usage
Use the OpenAIResponsesClient when you want direct access to the OpenAI Responses API.
Requires the
openaiPython package. It is declared as a dependency ofllmconnector, but you can also install it manually withpip install openai.
from llmconnector import OpenAIResponsesClient
client = OpenAIResponsesClient()
text_response = client.generate_response(
api_key="sk-your-api-key", # required OpenAI API key
prompt="Summarize the key benefits of unit testing.", # plain-text prompt
model="gpt-4o", # any Responses API compatible model
reasoning_effort="medium", # optional: "none" | "minimal" | "low" | "medium" | "high" | "xhigh"
max_tokens=2000, # optional: caps the full response length
)
response_with_usage = client.generate_response_with_usage(
api_key="sk-your-api-key",
prompt="Summarize the key benefits of unit testing.",
model="gpt-4o",
reasoning_effort="medium",
max_tokens=2000,
)
print(response_with_usage.text)
print(response_with_usage.usage.total_tokens if response_with_usage.usage else None)
vision_response = client.generate_response(
api_key="sk-your-api-key",
prompt="Describe the main action in this image.",
model="gpt-4o-mini",
images=[
"/absolute/path/to/local-image.png", # local file paths are converted to data URLs
"https://example.com/sample.jpg", # remote URLs are passed through directly
],
)
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
api_key |
str |
Yes | OpenAI API key used for authentication. |
prompt |
Optional[str] |
Conditional | Plain-text prompt. Required unless images is supplied. |
model |
str |
Yes | Target model identifier, e.g. gpt-4o. |
max_tokens |
int |
No | Defaults to 32000. Passed to the Responses API as max_output_tokens. |
reasoning_effort |
Optional[str] |
No | For models that support reasoning hints ("none", "minimal", "low", "medium", "high", "xhigh"). Supported values vary by model. |
temperature |
Optional[float] |
No | Sampling temperature forwarded to the Responses API. |
top_p |
Optional[float] |
No | Nucleus sampling value forwarded to the Responses API. |
images |
Optional[Sequence[str | Path]] |
No | List of image URLs or local paths converted to data URLs. |
generate_response returns the generated model output as a plain string.
generate_response_with_usage returns an LLMResponse containing text plus token counts when the provider reports them (input_tokens, output_tokens, total_tokens, and OpenAI reasoning and cached input tokens when available).
The wrapper accepts
promptas plain text and translates it into the structured input format expected by the Responses API.
Image Generation
Use generate_image with OpenAI image models. If image is supplied, the wrapper calls the image edit endpoint; otherwise it calls image generation.
image_bytes = client.generate_image(
api_key="sk-your-api-key",
prompt="Generate a simple icon of a relay connector.",
model="gpt-image-1",
image_size="1024x1024",
)
Listing models
Use list_models to enumerate the OpenAI models available to your account:
from llmconnector import OpenAIResponsesClient
client = OpenAIResponsesClient()
for model in client.list_models(api_key="sk-your-api-key"):
print(model["id"], model["display_name"])
LLMClient
Usage
LLMClient routes requests to whichever provider has been registered; OpenAI, Gemini, Anthropic, and Grok (alias: xai) are configured by default. The client also exposes list_models to surface the identifiers available for the selected provider.
from llmconnector import LLMClient
llm_client = LLMClient()
response_via_router = llm_client.generate_response(
provider="openai", # selects the OpenAI wrapper
api_key="sk-your-api-key",
prompt="List three advantages of integration testing.",
model="gpt-4o",
max_tokens=1500,
)
# async usage
# response_via_router = await llm_client.async_generate_response(
# provider="openai",
# api_key="sk-your-api-key",
# messages=[{"role": "system", "content": "You are concise."}],
# prompt="Summarize the plan.",
# model="gpt-4o-mini",
# )
gemini_response = llm_client.generate_response(
provider="gemini", # google-genai is installed with llmconnector
api_key="your-gemini-api-key",
prompt="Outline best practices for prompt engineering.",
model="gemini-2.5-flash",
max_tokens=1500,
)
anthropic_response = llm_client.generate_response(
provider="anthropic",
api_key="sk-ant-api-key",
prompt="Summarize when to rely on retrieval-augmented generation.",
model="claude-sonnet-4-5-20250929",
max_tokens=1500,
)
# Additional providers can be registered at runtime:
# llm_client.register_provider("custom", CustomProviderClient())
# llm_client.generate_response(provider="custom", ...)
# Image generation (currently only supported by Gemini)
image_bytes = llm_client.generate_image(
provider="gemini",
api_key="your-gemini-api-key",
prompt="A futuristic city",
model="gemini-3-pro-image-preview",
aspect_ratio="16:9",
)
Listing models
from llmconnector import LLMClient
llm_client = LLMClient()
for model in llm_client.list_models(provider="openai", api_key="sk-your-api-key"):
print(model["id"], model["display_name"])
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
provider |
str |
Yes | Registered provider key (default registry includes 'openai', 'gemini', 'anthropic', 'grok'/'xai'). |
api_key |
str |
Yes | Provider-specific API key. |
prompt |
Optional[str] |
Conditional | Plain-text prompt. Required unless images is supplied. |
messages |
Optional[Sequence[dict]] |
No | Chat-style messages (role, content). |
model |
str |
Yes | Provider-specific model identifier. |
max_tokens |
int |
No | Defaults to 32000. |
reasoning_effort |
Optional[str] |
No | Reasoning hint forwarded when supported (e.g. OpenAI, Grok, Gemini). |
temperature |
Optional[float] |
No | Sampling temperature forwarded to the selected provider when supported. |
top_p |
Optional[float] |
No | Nucleus sampling value forwarded to the selected provider when supported. |
images |
Optional[Sequence[str | Path]] |
No | Image references forwarded to the provider implementation. |
request_id |
Optional[str] |
No | Request identifier for tracing/logging. |
timeout_s |
Optional[float] |
No | Timeout in seconds (best-effort). |
max_retries |
Optional[int] |
No | Retry count for transient failures. |
retry_backoff_s |
Optional[float] |
No | Base delay (seconds) for exponential backoff. |
Use LLMClient.register_provider(name, client) to add additional providers that implement
generate_response with the same signature.
CLI
The package provides a simple CLI entry point named client_cli (see pyproject.toml).
It reads API keys from environment variables and supports generating responses and
listing models.
- API key environment variables:
- OpenAI:
OPENAI_API_KEY - Gemini:
GEMINI_API_KEY(fallback:GOOGLE_API_KEY) - Anthropic:
ANTHROPIC_API_KEY - Grok/xAI:
GROK_API_KEYorXAI_API_KEY(either works)
- OpenAI:
Examples:
# Generate a response
client_cli respond --provider openai --model gpt-4o --prompt "Hello!"
# Generate with retry/timeout controls
client_cli respond --provider openai --model gpt-4o --prompt "Hello!" --timeout-s 30 --max-retries 2
# Generate with explicit sampling controls
client_cli respond --provider openai --model gpt-4o --prompt "Hello!" --temperature 0.8 --top-p 0.9
# Generate with reasoning effort; response text is printed to stdout and token usage to stderr
client_cli respond --provider openai --model gpt-5 --prompt "Solve this carefully." --reasoning-effort high
# List models for one provider (human-readable)
client_cli models --provider gemini
# List models for one provider (JSON)
client_cli models --provider anthropic --json
# List models for all registered providers
client_cli all-models
Development
The project uses a standard pyproject.toml based packaging layout with sources
stored under src/. Install the project in editable mode and run your preferred tooling:
pip install -e .
Requires Python 3.10+.
Metadata
Release files for ccs-llmconnector 1.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| ccs_llmconnector-1.5.0.tar.gz | 33.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ccs_llmconnector-1.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 69.7 kB
Release files / ccs_llmconnector-1.5.0.tar.gz
| Download URL | ccs_llmconnector-1.5.0.tar.gz |
|---|---|
| Size | 33.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9134418e240d909e65f58c9d6700258a31106b3b5a89d436c52c57014d1f905a
|
|
BLAKE2b-256 checksum How to use checksums |
bd84be204aa8d92695f007a04ed8e1ebd20d6b285a376cf433ac6e9a0550e393
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.5
|
Release files / ccs_llmconnector-1.5.0-py3-none-any.whl
| Download URL | ccs_llmconnector-1.5.0-py3-none-any.whl |
|---|---|
| Size | 36.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8d561d0a95086146b0e1e324d8de1860de6799471fca3789972dc65d8442b799
|
|
BLAKE2b-256 checksum How to use checksums |
f74c221f72ebf13ed50a089cae4ded758cbb8cbfc1b8f69d7ef22852456fc10a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.5
|
Security for ccs-llmconnector 1.5.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.