Call a hosted model and read the bill
Send a chat request to a hosted model from your own script, keep a conversation going, and print what each call costs.
You build: chat.py: a 60-line chat client that prints the answer, the token counts and the cost of every call.
- Python 3.11 or newer and uv
- An OpenRouter key (free models are enough)
-
01Put your key and a model name in the environment
Keep the key in your shell or a .env file that git ignores. Never paste it into a script.
test -n "$OPENROUTER_API_KEY" && test -n "$MODEL" && echo readyYou pass when: It prints ready. MODEL holds a model id you picked from the OpenRouter model list (filter by price: free).
-
02Write chat.py: one system message, one user message, print the answer and the usage
Use the openai package with base_url set to https://openrouter.ai/api/v1. The same script talks to Ollama if you point base_url at http://localhost:11434/v1.
uv run --with openai chat.py "Explain a context window to a ten year old"You pass when: An answer prints, then one line with prompt tokens and completion tokens.
-
03Add a --chat mode that resends the whole conversation each turn
The model remembers nothing. The conversation is a list you keep and send again, which is why long chats cost more per turn.
uv run --with openai chat.py --chatYou pass when: Tell it your name in turn one and ask for it in turn two: it answers correctly, and the prompt token count grows every turn.
-
04Print the cost of each call from the model's listed prices
uv run --with openai chat.py "Give me three names for a parcel company"You pass when: A cost line prints in dollars. On a free model it is 0, so also print what the same call would cost on one paid model you name.
The check runs on the computer, not on your word: a step passes when its command exits with 0 there.
Computers are not set up on this site yet. Run each command on your own machine and compare with "You pass when".
Commands run in labs/11-chat-api and may take up to 60 seconds each. Every command starts a new shell: put keys and settings in a .env file there, it is loaded each time.