A unified and consistent interface for working with multiple LLM providers.
Project description
gais: Generative AI Suite for Multi-Provider Access
A unified and consistent interface for working with multiple LLM providers.
gais provides:
- Parallel multi-prompt generation: run several prompts at once using a single provider.
- Multi-provider generation: send one prompt to multiple providers and collect all responses together.
- Structured outputs with Pydantic: clean, validated responses using Pydantic models.
- Universal parsing support: uses native parsing when available (e.g., OpenAI .parse), and an automatic fallback parser when it isn’t.
Currently supported providers: OpenAI, DeepSeek, Groq, Anthropic, Fireworks, Gemini, and Ollama.
NOTE: For detailed usage, see the
gaisdocumentation
Installation
Install via pip:
```bash
pip install gais
```
Or from source:
```bash
git https://github.com/hanifsajid/gais.git
cd gais
pip install -e .
```
Usage
from pydantic import BaseModel, Field
from gais import Generator, MultiPromptGenerator, MultiProviderGenerator, DeepSeek, OpenAI
class Capital(BaseModel):
"""Structured Pydantic model representing a capital city."""
capital: str = Field(..., description="The name of the capital city.")
class Joke(BaseModel):
"""Structured Pydantic model representing a joke response."""
joke: str = Field(..., description="A one- or two-sentence joke.")
# Initialize provider
api_key = "YOUR_OPENAI_API_KEY"
openai_provider = OpenAI(model="gpt-4o-mini", api_key=api_key)
1. SINGLE-PROMPT GENERATION
single_gen = Generator(openai_provider)
# ---- Parsed with Pydantic model ----
parsed_response = single_gen.generate(
"What is the capital of France?",
parse=True,
response_format=Capital,
)
print("Parsed Response:", parsed_response.parsed)
# ---- Standard unparsed output ----
std_response = single_gen.generate(
"What is the capital of France?",
parse=False,
)
print("Raw Response:", std_response)
# ---- With custom generation kwargs ----
custom_response = single_gen.generate(
"What is the capital of France?",
parse=True,
response_format=Capital,
temperature=0.2,
max_tokens=50,
)
print("Custom Params Parsed Response:", custom_response.parsed)
2. MULTI-PROMPT GENERATION
multi_prompts = [
"What is the capital of France?",
"Tell me a joke.",
"What is the capital of USA?",
]
# Per-prompt response formats
multi_formats = [Capital, Joke, Capital]
multi_gen = MultiPromptGenerator(provider=openai_provider, max_workers=3)
# ---- Parsed multi-prompt output ----
parsed_multi = multi_gen.run(
multi_prompts,
parse=True,
response_format=multi_formats,
temperature=0.3,
)
for i, r in enumerate(parsed_multi):
print(f"Parsed Multi-Prompt {i+1}: {r.parsed}")
# ---- Standared multi-prompt output ----
raw_multi = multi_gen.run(multi_prompts, parse=False)
for i, r in enumerate(raw_multi):
print(f"Raw Multi-Prompt {i+1}:", r)
3. MULTI-PROVIDER GENERATION
from gais import DeepSeek
providers = [
openai_provider,
DeepSeek(model="deepseek-chat", api_key=DEEPSEEK_API_KEY),
]
multi_provider_gen = MultiProviderGenerator(providers, max_workers=2)
# Per-provider response formats
provider_response_formats = {
providers[0].name: Capital,
providers[1].name: Capital,
}
# Provider-specific overrides
provider_specific_params = {
providers[1].name: {
"temperature": 0.1, # Override for 2nd provider
"max_tokens": 30,
}
}
# ---- Parsed multi-provider output ----
provider_results = multi_provider_gen.run(
prompt="What is the capital of Germany?",
parse=True,
response_format=provider_response_formats,
provider_params=provider_specific_params,
temperature=0.5, # Common parameter (all providers)
max_tokens=80,
)
for r in provider_results:
if r["success"]:
print(f"Provider {r['provider']} Parsed:", r["response"].parsed)
else:
print(f"Provider {r['provider']} Error:", r["error"])
# ---- Raw multi-provider output ----
provider_results_raw = multi_provider_gen.run(
prompt="Tell me a joke.",
parse=False,
provider_params=provider_specific_params,
temperature=0.8,
)
for r in provider_results_raw:
if r["success"]:
print(f"Provider {r['provider']} Raw:", r["response"])
else:
print(f"Provider {r['provider']} Error:", r["error"])
Cite this Project
If you use gais in your work, please cite it as:
@misc{gais,
title = {gais},
author = {Hanif Sajid},
year = {2025},
month = November,
version = {0.1.0},
howpublished = {https://github.com/hanifsajid/gais},
note = {MIT License}
}
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 gais-0.1.1.tar.gz.
File metadata
- Download URL: gais-0.1.1.tar.gz
- Upload date:
- Size: 8.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.2.1 CPython/3.11.14 Linux/6.11.0-1018-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
547b97ae2d0c01bb6c9b1265bfe596f4661255813a58f633c469200d5ee3b715
|
|
| MD5 |
45a39a3c1459b3c1502047fd80400f40
|
|
| BLAKE2b-256 |
3c9bd01557a17fa68585a61d782f56873a8c752efec5ff1136a00accf44a4fd3
|
File details
Details for the file gais-0.1.1-py3-none-any.whl.
File metadata
- Download URL: gais-0.1.1-py3-none-any.whl
- Upload date:
- Size: 8.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.2.1 CPython/3.11.14 Linux/6.11.0-1018-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3503112c904503bf1a71cea0301a5e1f467d7dcd0454b532a8e9ecc6a70481c
|
|
| MD5 |
d8dc5721bb34dbbce4e0328c0465f9fc
|
|
| BLAKE2b-256 |
b2fb2503678a038585cc016efab9d824d130e55bd513acb38090c22f752a26e8
|