Lesson 4.2 — Talk to Your Model from Code (Local API)
Introduction to AI · Module 4: Local LLMs · About 60 min · Windows PC, PowerShell 5, Ollama 0.40.11
Goal: call your local model from PowerShell and from Python, and build a summarise.py that works with the internet off.
http://localhost:11434. Apps "talk" to the model by sending it requests.Before you start
Step 1 · Is the server up? (⏱ 0:00–0:05)
Invoke-RestMethod http://localhost:11434/api/versionYou should see:
version
-------
0.40.11Step 2 · Chat via the API from PowerShell (⏱ 0:05–0:15)
Paste the whole block:
$body = @{
model = "qwen3.8:27b"
messages = @(@{ role = "user"; content = "Give me 3 tips for focus, one line each." })
stream = $false
} | ConvertTo-Json -Depth 5
$bytes = [System.Text.Encoding]::UTF8.GetBytes($body)
$r = Invoke-RestMethod http://localhost:11434/api/chat -Method Post -Body $bytes -ContentType "application/json"
$r.message.contentYou should see 3 one-line tips (after a short wait while the model loads).
$bytes line? PowerShell 5 otherwise sends text in an old encoding, which mangles apostrophes and emoji.Step 3 · Check Python (⏱ 0:15–0:20)
python --versionYou should see Python 3.x.x. If you get "not recognized", or the Microsoft Store opens:
winget install Python.Python.3.12Then open a new PowerShell window, run cd C:\llm-test, and check again.
Step 4 · Build summarise.py (⏱ 0:20–0:35)
This uses only Python's built-in modules, so there's nothing extra to install. Paste the whole block:
$code = @'
import json, sys, urllib.request
MODEL = "qwen3.8:27b"
text = open(sys.argv[1], encoding="utf-8-sig").read()
req = {"model": MODEL, "stream": False, "messages": [
{"role": "system", "content": "You summarise documents in 5 short bullet points, then list action items."},
{"role": "user", "content": text}]}
data = json.dumps(req).encode("utf-8")
r = urllib.request.Request("http://localhost:11434/api/chat", data,
{"Content-Type": "application/json"})
print(json.load(urllib.request.urlopen(r))["message"]["content"])
'@
[IO.File]::WriteAllText("C:\llm-test\summarise.py", $code)
python summarise.py t2.txtYou should see 5 bullets and the action items for your task-2 notes from Lesson 4.1.
Step 5 · The OpenAI-compatible endpoint (⏱ 0:35–0:45)
Many apps speak "OpenAI". Ollama can pretend to be OpenAI, so those apps can use your local model.
python -m pip install openai
$code = @'
from openai import OpenAI
c = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
r = c.chat.completions.create(model="qwen3.8:27b",
messages=[{"role": "user", "content": "Say hello in 5 words."}])
print(r.choices[0].message.content)
'@
[IO.File]::WriteAllText("C:\llm-test\openai_test.py", $code)
python openai_test.pyYou should see a 5-word hello. The api_key can be any text; Ollama ignores it.
Step 6 · The offline test (⏱ 0:45–0:55)
- Turn off Wi-Fi and unplug Ethernet (or click the network icon → Airplane mode).
- Check you're really offline:
Test-Connection 8.8.8.8 -Count 1 -QuietYou should see False.
- Run:
python summarise.py t2.txtYou should see the summary again, so it worked with no internet. Turn the network back on afterwards.
✅ Pass check
Troubleshooting
| Problem | Fix |
|---|---|
| "Unable to connect to the remote server" | Ollama isn't running: start it from the Start menu, or run ollama serve in another window. |
model not found | Run ollama list and copy the exact name into MODEL / model. |
| Answer starts with long "thinking" | Normal for reasoning models. To skip it, add "think": False, to the req dict (Python) or think = $false to $body (PowerShell). |
pip not recognized | Use python -m pip install openai exactly as written. |
| UnicodeDecodeError | Save the .txt from Notepad as UTF-8 (File → Save as → Encoding: UTF-8). |
| Slow first reply | The model is loading into VRAM (10–30 s). Later calls are faster. |
Finish this lesson
Nice work! Pick your next step: