NL ▾
API-sleutel aanvragen

Ollama API in Python en een gehost alternatief

De Ollama API in Python is in ongeveer tien regels geschreven, en dezelfde codestructuur werkt ook tegen een gehost endpoint. Dit artikel toont beide manieren en legt uit wanneer je welke kiest.

Bijgewerkt

Belangrijkste punten

  • Ollama luistert op poort 11434 en biedt een native API plus een OpenAI-achtig /v1-endpoint.
  • Het ollama-pakket, gewone requests en de OpenAI SDK werken allemaal; de OpenAI SDK is het meest draagbaar.
  • Naar een gehoste API gaan betekent de base URL, de sleutel en de modelnaam wijzigen.
  • Lokaal is het beste voor offline werk en vaste hardware; gehost is eenvoudiger als je geen GPU hebt.
Een lokale computer verbonden met een cloudserver via een gloeiende kabel, die lokale en gehoste LLM-API's voorstelt

De korte versie

Als je zoekt naar ollama api python, wil je meestal een van drie dingen: een model aanroepen dat op je eigen machine draait, tokens streamen vanaf dat model, of hetzelfde script op een andere plek laten werken. Ollama biedt je alle drie. Het draait een lokale server, standaard op http://localhost:11434, en je communiceert ermee via het ollama Python-pakket, met plain HTTP, of met elke OpenAI-client die op zijn /v1-pad is ingesteld.

Het nadeel is dat het model op je hardware moet draaien. Een laptop zonder een degelijke GPU zal langzaam zijn bij grotere modellen, en een server zonder GPU is daar niet geschikt voor. Voor dat geval is een gehost OpenAI-compatibele API de eenvoudigere route, en omdat het verzoekformaat hetzelfde is, kost overschakelen je drie regels configuratie. Beide paden worden hieronder behandeld, met code die je kunt plakken.

Een lokaal model aanroepen met het ollama-pakket

Installeer Ollama, haal een model op en zorg dat de server draait. Installeer vervolgens de Python-client:

pip install ollama
ollama pull llama3.2

Een basis chat-aanroep ziet er als volgt uit. De modelnaam is wat je hebt opgehaald; llama3.2 is slechts een voorbeeld.

import ollama

response = ollama.chat(
    model="llama3.2",
    messages=[{"role": "user", "content": "Explain DNS in two sentences."}],
)
print(response["message"]["content"])

Streaming

Geef stream=True door en je krijgt een iterator van chunks in plaats van één antwoord. Elke chunk bevat een deel van het antwoord in message.content.

import ollama

stream = ollama.chat(
    model="llama3.2",
    messages=[{"role": "user", "content": "Write a haiku about servers."}],
    stream=True,
)
for chunk in stream:
    print(chunk["message"]["content"], end="", flush=True)
print()

De client naar een andere machine wijzen

Als Ollama op een andere host draait, maak je een client met een expliciet adres, bijvoorbeeld ollama.Client(host="http://192.168.1.20:11434"). Standaard luistert de server alleen op de lokale machine, dus externe toegang vereist een bewuste instelling aan de serverkant. Stel het niet bloot aan het publieke internet zonder een proxy en authenticatie ervoor, omdat de native API geen eigen sleutelcontrole heeft.

Plain HTTP met requests

Je hebt het pakket helemaal niet nodig. Het native chat-endpoint is POST /api/chat. Streaming is daar standaard, en de stream is newline-delimited JSON, geen SSE. Stel "stream": false in als je één object terug wilt krijgen.

import requests

r = requests.post(
    "http://localhost:11434/api/chat",
    json={
        "model": "llama3.2",
        "messages": [{"role": "user", "content": "Name three HTTP status codes."}],
        "stream": False,
    },
    timeout=120,
)
r.raise_for_status()
print(r.json()["message"]["content"])

Stel een royale timeout in. De eerste aanvraag na een pull moet het model in het geheugen laden, en dat kan veel langer duren dan latere aanvragen.

De stream handmatig lezen is slechts een paar regels meer. Roep requests.post(..., stream=True) aan, loop over r.iter_lines(), sla lege regels over en voer json.loads uit op elke regel. Elk object bevat een klein deel van het antwoord, en het laatste heeft "done": true. Dit is handig in een minimale container waar je liever geen ander pakket installeert, en het maakt duidelijk wat de bibliotheek voor je doet. De gehoste API streamt anders, als SSE-regels die beginnen met data:, wat nog een reden is om de OpenAI SDK de stream te laten parseren voor draagbare code.

De OpenAI SDK gebruiken met Ollama

Ollama biedt ook een OpenAI-stijl endpoint aan onder /v1. Dat betekent dat het officiële openai-pakket werkt, en de meeste software waarmee je een aangepaste basis-URL kunt instellen ook. De sleutel is vereist door de SDK, maar wordt genegeerd door een lokale Ollama, dus elke string werkt.

from openai import OpenAI

client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
resp = client.chat.completions.create(
    model="llama3.2",
    messages=[{"role": "user", "content": "Give me a one-line summary of TCP."}],
)
print(resp.choices[0].message.content)

Dit is de meest nuttige vorm, omdat het je code ontkoppelt van de server. Dezelfde functie kan vandaag nog praten met een lokaal model en morgen met iets anders, wat de volgende sectie is.

Dezelfde code tegen een gehoste API

De gehoste optie hier is een OpenAI-compatibele API met één model, uncensored, gerund door een onafhankelijke provider en afgestemd om te antwoorden zonder inhoudelijke weigeringen voor legaal gebruik door volwassenen. Het is alleen tekst. De base URL is https://api.ollamaapi.cc/v1, en je authenticeert met een Bearer-sleutel van de API-sleutelpagina.

Hier is een versie die zijn doel leest uit omgevingsvariabelen, met de gehoste waarden als standaard. Om terug te gaan naar je lokale server, exporteer je twee variabelen en verander je niets anders.

import os
from openai import OpenAI

client = OpenAI(
    base_url=os.getenv("LLM_BASE_URL", "https://api.ollamaapi.cc/v1"),
    api_key=os.getenv("LLM_API_KEY", "YOUR_API_KEY"),
)
MODEL = os.getenv("LLM_MODEL", "uncensored")

resp = client.chat.completions.create(
    model=MODEL,
    messages=[
        {"role": "system", "content": "You are a concise assistant."},
        {"role": "user", "content": "List four uses of a message queue."},
    ],
    temperature=0.7,
)
print(resp.choices[0].message.content)

Stel voor lokale runs LLM_BASE_URL=http://localhost:11434/v1, LLM_API_KEY=ollama en LLM_MODEL=llama3.2 in. De quickstart heeft dezelfde setup in curl en Node.

Streaming, JSON-modus en tools aan de gehoste kant

Het gehoste endpoint ondersteunt streaming via SSE, JSON-modus, tool calling, en de gebruikelijke samplingparameters (temperature, top_p, stop, seed en de straffen). Streaming met de SDK is dezelfde lus die je zou schrijven voor elke OpenAI-achtige server:

stream = client.chat.completions.create(
    model="uncensored",
    messages=[{"role": "user", "content": "Tell a two-paragraph story about a lighthouse."}],
    stream=True,
    stream_options={"include_usage": True},
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

Stel voor gestructureerde uitvoer response_format={"type": "json_object"} in en geef in de prompt aan dat je JSON wilt. Parse altijd binnen een try-blok; een model kan nog steeds iets teruggeven dat je niet verwachtte.

Een verschil met lokaal gebruik is belangrijk in code: limieten. Een volledige sleutel staat 8 gelijktijdige verzoeken en 300 verzoeken per minuut toe, en een gestreamd verzoek houdt zijn slot vast tot de stream eindigt. Als je fan-out met threads doet, beperk dan de pool tot 8 en probeer opnieuw bij HTTP 429 met behulp van de Retry-After-header wanneer deze aanwezig is.

Een gesprek gaande houden

Noch het lokale noch het gehoste chat-endpoint onthoudt iets tussen aanroepen. De server ziet alleen de berichten die je stuurt, dus een chatbot is een lijst die je uitbreidt en opnieuw verstuurt. Het patroon is identiek voor beide doelen, wat nog een reden is om de OpenAI-achtige client als je standaardclient te houden.

history = [{"role": "system", "content": "You are a helpful assistant."}]

def ask(text):
    history.append({"role": "user", "content": text})
    resp = client.chat.completions.create(model=MODEL, messages=history)
    answer = resp.choices[0].message.content
    history.append({"role": "assistant", "content": answer})
    return answer

print(ask("Pick a name for a hiking app."))
print(ask("Give me a tagline for it."))

Twee praktische opmerkingen. Eerst hebben lokale modellen een contextlengte die jij instelt en die het geheugen moet vasthouden; als de geschiedenis daarvoor te lang wordt, worden eerdere beurten afgekapt of mislukt de aanroep, afhankelijk van de instellingen. Het gehoste model accepteert een contextvenster van 100.000 tokens inclusief de completion, wat veel meer is dan de meeste chats nodig hebben, maar lange geschiedenis kost nog steeds input-tokens bij elke beurt. Ten tweede, zodra een geschiedenis lang wordt, vat je de oudste beurten samen tot één kort bericht in plaats van ze allemaal opnieuw te versturen. Dat houdt vertraging en kosten stabiel op beide backends.

Beleefd opnieuw proberen

Op de gehoste API retourneert een tijdelijke overbelasting HTTP 429 met een Retry-After: 5-header. Een kleine wrapper behandelt dit:

import time
from openai import RateLimitError

def chat_with_retry(messages, tries=4):
    for attempt in range(tries):
        try:
            return client.chat.completions.create(model=MODEL, messages=messages)
        except RateLimitError:
            time.sleep(5 * (attempt + 1))
    raise RuntimeError("still rate limited")

Lokale Ollama rate limiet je niet, maar het zet verzoeken in de wachtrij wanneer het model druk is, dus dezelfde wrapper doet daar geen kwaad.

Lokaal of gehost: hoe te beslissen

Geen van beide keuzes is over het algemeen beter. Gebruik de onderstaande punten als checklist.

  • Kies voor lokale Ollama als je offline moet werken, als data het apparaat nooit mag verlaten, als je al een capabele GPU hebt, of als je snel veel verschillende open modellen wilt uitproberen.
  • Kies voor een gehost API als je geen GPU hebt, als je draait op een kleine VPS of in CI, als meerdere mensen of services één backend delen, of als je een lang contextvenster wilt zonder zelf geheugen te hoeven inrichten. Het gehoste model accepteert tot 100.000 tokens aan prompt plus completion.
  • Combineer beide tijdens de ontwikkeling: iteratief lokaal werken, en de productie dan via omgevingsvariabelen op de gehoste URL laten draaien.

Gehost gebruik wordt gefactureerd per token, tegen $0,15 per 1M input-tokens en $0,50 per 1M output-tokens, van prepaid tegoed. De prijzenpagina vermeldt de bedragen voor opwaarderen, en nieuwe accounts kunnen met één klik $0,50 proeftegoed claimen zonder creditcard. Prompts worden niet gebruikt voor training.

Fouten die je zult tegenkomen

SymptoomWaarschijnlijke oorzaakOplossing
Verbinding geweigerd op poort 11434De Ollama-server draait nietStart de app of voer ollama serve uit
Model niet gevondenHet model is nooit opgehaald, of de naam heeft een typefoutVoer ollama list uit, en daarna ollama pull de naam die je gebruikt
Eerste aanroep time-outHet model wordt nog geladenVerhoog de time-out of stuur een warm-up-verzoek
Authenticatiefout op de gehoste APIOntbrekende of verkeerde Bearer-sleutelControleer LLM_API_KEY en de base URL
HTTP 429 met code concurrencyMeer dan 8 verzoeken in behandeling (2 op een proefsleutel)Verlaag het aantal workers
HTTP 429 met code rate_limitedLimiet voor verzoeken per minuut overschredenWacht en probeer het opnieuw

Mislukte of geweigerde verzoeken aan de gehoste kant worden niet in rekening gebracht, dus retrylogica kost je niets voor de mislukte pogingen.

Vragen en antwoorden

Wat is het standaard Ollama API-adres?

Een lokale Ollama-server luistert op http://localhost:11434. De native endpoints zijn beschikbaar onder /api, zoals /api/chat, en het OpenAI-stijl endpoint is beschikbaar onder /v1.

Kan ik de OpenAI Python SDK met Ollama gebruiken?

Ja. Stel base_url in op http://localhost:11434/v1 en geef een willekeurige string door als API-sleutel. De SDK stuurt dan standaard chat completion-verzoeken naar je lokale model.

Hoe schakel ik over van Ollama naar een gehoste API?

Wijzig de base URL, de sleutel en de modelnaam. Als je code ze uit omgevingsvariabelen leest, is er geen codewijziging nodig.

Werkt de gehoste API zonder GPU aan mijn kant?

Ja. Het model draait bij de provider, dus je script heeft alleen een internetverbinding en een Bearer-sleutel nodig. Je betaalt per token van prepaid tegoed.

Je sleutel is nog maar één formulier verwijderd

Maak een account aan, kopieer de sleutel, pas de basis-URL aan. Dat is de hele setup.

API-sleutel aanvragen