import chatlas as ctlchat = ctl.ChatAnthropic()chat.chat("What is the most popular Python package for data analysis?")
That’s it. One import, two lines, streaming output.
Bring your own provider
# Hostedchat = ctl.ChatAnthropic() # Claudechat = ctl.ChatOpenAI() # GPTchat = ctl.ChatGoogle() # Gemini# Local (no API key needed)chat = ctl.ChatOllama() # Ollamachat = ctl.ChatLMStudio() # LM Studio# Pick via a single stringchat = ctl.ChatAuto("anthropic:claude-sonnet-4-6")
Same API, every provider. Use whatever you have today.
System prompt
chat = ctl.ChatAnthropic( system_prompt=("You are a data science tutor. ""Explain concepts simply, using analogies from everyday life." ),)chat.chat("What is a p-value?")
The system prompt is your invisible hand — it shapes every response without the user seeing it.
Multi-turn: the chat remembers
chat.chat("What about confidence intervals?")
chat.chat("How do those two concepts relate?")
Chat objects are stateful — they accumulate conversation history.
chat.get_turns() # inspect the historychat.set_turns([]) # reset to start fresh
# Returns a generator you controlfor chunk in chat.stream("Explain PCA"):print(chunk, end="")
Great for Shiny, FastAPI, etc.
Both have async variants: .chat_async() and .stream_async()
Tool calling: the big idea
LLMs can’t do things — but they can ask you to do things.
sequenceDiagram
participant U as You
participant L as LLM
participant T as Your Tool
U->>L: "What's the weather in Paris?"
L->>T: get_weather(city="Paris")
T-->>L: {"temp": 18, "condition": "cloudy"}
L->>U: "It's 18°C and cloudy in Paris."
The model decides what to call. Your code executes it.
Your first tool
def get_current_weather(lat: float, lng: float):"""Get the current weather for a location. Parameters ---------- lat The latitude. lng The longitude. """import requests resp = requests.get("https://api.open-meteo.com/v1/forecast", params={"latitude": lat, "longitude": lng, "current": "temperature_2m"}, )return resp.json()["current"]chat = ctl.ChatAnthropic()chat.register_tool(get_current_weather)chat.chat("What's the weather in Paris?")
What just happened?
When you ran chat.chat(...), chatlas ran this loop for you:
Sent your message + the tool schema to the model
Model responded: “call get_current_weather(48.85, 2.35)”
chatlas called your function with those arguments
Sent the result back to the model
Model responded with a natural language answer
Steps 2–4 can repeat — the model can call multiple tools in sequence.
Tools for data scientists
import pandas as pdtips = pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv")def query_tips(code: str):"""Execute Python code to answer a question about the tips dataset. Parameters ---------- code Python code to run. The `tips` DataFrame and `pd` (pandas) are available. """returnstr(eval(code, {"tips": tips, "pd": pd}))chat = ctl.ChatAnthropic()chat.register_tool(query_tips)chat.chat("What's the average tip percentage by day of the week?")
Built-in tools
from chatlas import tool_web_searchchat = ctl.ChatAnthropic()chat.register_tool(tool_web_search())chat.chat("What were the top Python packages released this month?")
No API key, no configuration — the provider handles it natively.
Quick tour: more capabilities
Structured output
from pydantic import BaseModelclass Person(BaseModel): name: str age: intchat.chat_structured("Susan is 13 years old", data_model=Person,)# → Person(name='Susan', age=13)