Getting started with jangada
jangada is a thin layer over the official LLM SDKs (Anthropic, OpenAI,
Groq, Gemini). The goal is to swap provider / model / api_key without changing
the rest of your code.
Just want to try it out? Open the quickstart on Colab (1 click, paste your key, and run).
Installation
The base installs without any SDK. You pick the extras based on what you'll use — install only the provider you need, plus the optional capabilities.
pip install jangada-ai # base; imported as jangada_aiThe distribution name is
jangada-ai(the namejangadawas already taken on PyPI). The package is imported asimport jangada_ai(hyphen becomes underscore). Imports are lazy:import jangada_aiworks without any SDK installed.
Providers (choose what you'll use)
| Extra | Command | Enables |
|---|---|---|
anthropic | pip install "jangada-ai[anthropic]" | Claude |
openai | pip install "jangada-ai[openai]" | GPT |
groq | pip install "jangada-ai[groq]" | Groq |
gemini | pip install "jangada-ai[gemini]" | Gemini |
Optional capabilities
| Extra | Command | Enables |
|---|---|---|
files | pip install "jangada-ai[files]" | docx/pdf/csv/xlsx documents |
rag | pip install "jangada-ai[rag]" | RAG (pgvector / Mongo / BM25) |
mcp | pip install "jangada-ai[mcp]" | MCP client |
Shortcuts and combining
| Command | What it installs |
|---|---|
pip install "jangada-ai[all]" | all providers + files |
pip install "jangada-ai[anthropic,groq]" | combine extras with a comma |
pip install "jangada-ai[all,rag,mcp]" | everything, including RAG and MCP |
The [all] extra includes all providers + files, but does NOT include
rag or mcp. Those must be added separately —
e.g.: pip install "jangada-ai[all,rag,mcp]".
First call
from jangada_ai import LLM
llm = LLM("anthropic", "claude-opus-4-8")
print(llm.complete("Explain {{topic}} in 2 sentences.", topic="MCP").text)complete() accepts {{ }} templates directly in the prompt — the variables come
in as keyword args. See Generation parameters to control
temperature, max_tokens, etc.
Signature of complete() and parse()
Beyond prompt, both take a set of keyword args. The "happy path" shortcut
(prompt + variables) covers most cases, but the kwargs below are what unlock a
separate system prompt, multi-turn, and tools:
def complete(
self,
prompt, # str | None — the user prompt (accepts {{ }} templates)
*,
system=None, # str | None — system instruction for this call only
history=None, # list[Message] | None — previous turns (multi-turn)
images=None, # list[str | ImagePart] | None — images (path or ImagePart)
files=None, # list[Document] | None — docx/pdf/csv/xlsx (text or vision)
tools=None, # list[Tool] | None — functions for function calling
tool_choice=None, # str | None — force the tool choice
mcp_servers=None, # list[MCPServer] | None — remote MCP servers
params=None, # dict | None — per-call generation params override
**variables, # variables for the {{ }} template
) -> Completion: ...
def parse(
self,
prompt,
schema, # type[BaseModel] | dict — the structured-output schema
*,
system=None,
history=None,
images=None,
files=None,
params=None,
**variables,
) -> Completion: ...The async variants — acomplete() and aparse() — have identical signatures.
parse() does not accept tools/tool_choice/mcp_servers (no function
calling). Important detail: parse() returns a Completion, and the
validated Pydantic object lives in .parsed:
resp = llm.parse("Extract the data.", Invoice, files=["invoice.pdf"])
invoice = resp.parsed # ← the Pydantic instance lives here
print(invoice.supplier, resp.cost)system= here overrides, for this call only, the system= passed to the LLM
constructor. For history, images and interleaved multimodal, see
Messages and multimodal.
Switching providers
Only the first two arguments change; the rest of your code stays the same:
LLM("openai", "gpt-4o-mini")
LLM("groq", "llama-3.3-70b-versatile")
LLM("gemini", "gemini-2.5-flash")API keys come from api_key=, from the provider's environment variable, or from a
.env file detected at import time. Precedence:
explicit api_key= > environment variable > .env.
Extras and lifecycle (1.9.0)
New extras: jangada-ai[ollama] (Ollama provider) and pypdfium2 inside
[files] (scanned PDFs in vision). [mcp] accepts mcp 1.x and 2.x, and [all]
includes ollama and mcp.
LLM closes the SDK's HTTP connections with close()/aclose() or as a context
manager — useful in workers and long-lived processes:
from jangada_ai import LLM
async with LLM("openai", "gpt-5-mini") as llm:
print((await llm.acomplete("Hi!")).text)Next steps
Documentation
Jangada AI — a thin, adaptable layer over LLM SDKs. Swap provider, model, or api_key without changing the rest of your code.
Generation parameters and per-model profiles
jangada accepts canonical parameter names and each adapter translates them to the SDK's native name, discarding the unsupported ones.