Build the mental model
Once you understand that Ollama, LM Studio's server mode, and llama.cpp's server all expose a local HTTP API, you can talk to a local model from any programming language that can make an HTTP request, not just from a chat window. The pieces of this puzzle are worth naming precisely.
- Localhost — a special hostname, backed by the address 127.0.0.1, that always means “this same machine,” so a request to localhost never leaves your computer and never touches the network.
- Port — a number, like 11434 or 1234, that identifies which particular program on the machine should receive the request, since many programs can be listening on the same machine at once.
- Endpoint — a specific URL path on that server dedicated to one job, such as /api/chat for a conversation or /api/embeddings for turning text into a vector; the same server can expose several endpoints for different tasks.
- Request — the message your application sends: which endpoint, which model name, and the conversation so far, usually encoded as JSON, a plain-text format for structured data that both humans and programs can read.
- Response — the server processes the request through the runtime and model, then sends this back, also JSON, containing the generated text and often some metadata like token counts.
This request-response cycle over HTTP is exactly how a web app talks to a remote API like a weather service; the only difference with a local AI API is that the server lives on your own machine instead of somewhere else on the internet.
- localhost
- A special hostname (backed by the address 127.0.0.1) that always refers to the same machine the request originates from, so it never travels over an external network.
- Endpoint
- A specific URL path on a server dedicated to one job — such as /api/chat for a conversation or /api/embeddings for turning text into a vector — with one server able to expose several endpoints.
- API
- A set of rules and endpoints a server exposes so other programs can send it requests and receive structured responses (usually JSON), letting software talk to software without a human clicking anything.
APP TO MODEL VIA LOCAL API
--------------------------
------------------------------------------------------------
YOUR APP
|
| HTTP request to
| http://localhost:PORT/endpoint
| (JSON body: model name + messages)
v
LOCAL RUNTIME (Ollama / llama.cpp server / LM Studio server)
|
| loads and runs
v
MODEL
|
| generates text
v
JSON RESPONSE (generated text + metadata)
|
| sent back over the same connection
v
YOUR APP (reads the response, uses the text)Connect it to a real scenario
Say you're building a small Python script that summarizes meeting notes using a locally running model, and you want it to work entirely offline.
Start Ollama and confirm the model
Start Ollama in the background, and confirm `llama3.2` is pulled.
Send the request to the chat endpoint
Instead of typing into the terminal chat, write a Python script that sends an HTTP POST request to `http://localhost:11434/api/chat`, the same endpoint the `ollama run` command uses internally. The request body is a JSON object naming the model and a list of chat messages: a system message instructing it to summarize concisely, and a user message containing the meeting notes text.
Handle it like a real API call
Check the response status code, handle a connection error if Ollama isn't running yet, and set a reasonable timeout since local generation can take longer than a typical web API call.
The code example below shows exactly this pattern using Python's `requests` library, written so you can adapt the endpoint URL and message content to any Ollama-compatible local server you're running.
A Preview: Don't Leave This Open
By default, a local AI server listens only on localhost, so nothing outside your machine can reach it. But it can be configured to listen on a network interface instead (for example binding to 0.0.0.0), and if you do that without adding authentication, any other device on the same network — or the internet, if the machine is exposed — can send it requests too. A dedicated later lesson covers securing a local AI server properly; for now, treat 'binds to something other than localhost' as a deliberate, security-relevant decision, not a default to reach for.
Try the working example
import requests
OLLAMA_CHAT_URL = "http://localhost:11434/api/chat"
def summarize_notes(model_name, meeting_notes):
payload = {
"model": model_name,
"messages": [
{
"role": "system",
"content": (
"You are a concise assistant. Summarize the given "
"meeting notes in three bullet points."
),
},
{"role": "user", "content": meeting_notes},
],
"stream": False,
}
try:
response = requests.post(OLLAMA_CHAT_URL, json=payload, timeout=60)
response.raise_for_status()
except requests.exceptions.ConnectionError:
print("Could not reach the local model server. Is Ollama running?")
return None
except requests.exceptions.Timeout:
print("The request timed out waiting for a reply.")
return None
except requests.exceptions.HTTPError as error:
print(f"The server returned an error: {error}")
return None
data = response.json()
return data["message"]["content"]
if __name__ == "__main__":
notes = (
"Team agreed to ship the search feature next sprint. "
"Backend needs the new /api/search endpoint. "
"Design will deliver mockups by Thursday."
)
summary = summarize_notes("llama3.2", notes)
if summary is not None:
print(summary)
Not runnable here
This code calls your own local AI server (e.g. Ollama) — this site's browser playground cannot reach a local server on your machine (network access is restricted there for safety). Run it yourself in a terminal or file where a local server is actually running.
This code is not executed here because it requires a running local Ollama server. If Ollama is running with `llama3.2` pulled, `summarize_notes` sends the notes to `/api/chat` and the server responds with a JSON object containing a `message` field holding the assistant's reply text; the function returns that text, and the `print` statement would display whatever three-bullet summary the model generated — the exact wording depends on the model and is not something to hardcode or predict. If Ollama isn't running, the `ConnectionError` branch prints a message instead of crashing.5-minute try-it
Modify `summarize_notes` so it also accepts a `style` parameter (for example `'three bullet points'` or `'one sentence'`) and interpolates it into the system message instead of hardcoding 'three bullet points'. Then write, without running it, the request payload your function would send for `style='one sentence'` and a short set of meeting notes of your choosing.
One important caution
Forgetting to handle a connection error when the local server isn't running yet, causing the script to crash with an unhelpful traceback instead of a clear message.
Setting no timeout (or too short a timeout) on the HTTP request — local generation can legitimately take much longer than a typical web API call.
Ollama API documentation — Local AI / Local LLM