IT ▾
Ottieni la chiave API

API Ollama in Python e un'alternativa ospitata

L'API Ollama in Python richiede circa dieci righe e lo stesso codice funziona anche con un endpoint ospitato. Questo articolo mostra entrambi e spiega quando scegliere l'uno o l'altro.

Aggiornato

Punti chiave

  • Ollama ascolta sulla porta 11434 e offre un'API nativa più un endpoint /v1 in stile OpenAI.
  • Il pacchetto ollama, requests puro e l'SDK OpenAI funzionano tutti; l'SDK OpenAI è il più portabile.
  • Passare a un'API ospitata significa cambiare l'URL base, la chiave e il nome del modello.
  • Il locale è ideale per il lavoro offline e l'hardware fisso; l'opzione ospitata è più semplice se non hai una GPU.
Un computer locale collegato con un cavo luminoso a un server cloud, che rappresenta le API LLM locali e in hosting

La versione breve

Se cerchi ollama api python, di solito vuoi una di tre cose: chiamare un modello in esecuzione sulla tua macchina, eseguire lo streaming dei token da esso, o far funzionare lo stesso script altrove. Ollama ti offre tutte e tre le opzioni. Esegue un server locale, di default su http://localhost:11434, e puoi interagire con esso tramite il pacchetto Python ollama, con HTTP puro, o con qualsiasi client OpenAI puntato al suo percorso /v1.

Il problema è che il modello deve essere eseguito sull'hardware locale. Un portatile senza una GPU decente sarà lento con modelli più grandi, e un server senza di essa è una scelta poco adatta. Per questo caso, un'API OpenAI compatibile in hosting è la strada più semplice e, poiché il formato della richiesta è lo stesso, il passaggio richiede solo tre righe di configurazione. Entrambe le strade sono coperte di seguito, con codice che puoi incollare.

Chiamata a un modello locale con il pacchetto ollama

Installa Ollama, scarica un modello e assicurati che il server sia in esecuzione. Poi installa il client Python:

pip install ollama
ollama pull llama3.2

Una chiamata chat di base ha questo aspetto. Il nome del modello è quello che hai scaricato; llama3.2 è solo un esempio.

import ollama

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

Streaming

Passa stream=True e otterrai un iteratore di chunk invece di una singola risposta. Ogni chunk contiene una parte della risposta 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()

Puntare il client su un'altra macchina

Se Ollama è in esecuzione su un host diverso, crea un client con un indirizzo esplicito, ad esempio ollama.Client(host="http://192.168.1.20:11434"). Di default il server ascolta solo sulla macchina locale, quindi l'accesso remoto richiede un'impostazione esplicita sul lato server. Non esporlo a Internet senza un proxy e un'autenticazione davanti, perché l'API nativa non ha un controllo della chiave autonomo.

HTTP puro con requests

Non hai affatto bisogno del pacchetto. L'endpoint chat nativo è POST /api/chat. Lo streaming è il default lì, e lo stream è JSON delimitato a capo, non SSE. Imposta "stream": false se vuoi un singolo oggetto come risposta.

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"])

Imposta un timeout generoso. La prima richiesta dopo un download deve caricare il modello in memoria, e questo può richiedere molto più tempo delle richieste successive.

Leggere lo stream manualmente richiede solo poche righe in più. Chiama requests.post(..., stream=True), scorri r.iter_lines(), salta le righe vuote ed esegui json.loads su ciascuna. Ogni oggetto contiene una piccola parte della risposta, e l'ultima ha "done": true. Questo è utile in un container minimale dove preferiresti non installare un altro pacchetto, e rende chiaro cosa fa la libreria per te. L'API in hosting esegue lo streaming in modo diverso, come linee SSE che iniziano con data:, che è un'altra ragione per lasciare che l'SDK OpenAI analizzi lo stream per te nel codice portatile.

Uso dell'SDK OpenAI con Ollama

Ollama espone anche un endpoint in stile OpenAI sotto /v1. Questo significa che il pacchetto ufficiale openai funziona, e così fa la maggior parte del software che ti permette di impostare un URL di base personalizzato. La chiave è richiesta dall'SDK ma ignorata da un Ollama locale, quindi va bene qualsiasi stringa.

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)

Questa è la forma più utile, perché disaccoppia il tuo codice dal server. La stessa funzione può parlare con un modello locale oggi e con qualcos'altro domani, come nella sezione successiva.

Lo stesso codice contro un'API in hosting

L'opzione in hosting qui è un'API OpenAI compatibile con un singolo modello, uncensored, gestita da un provider indipendente e ottimizzata per rispondere senza rifiuti di contenuti per uso adulto legale. È solo testo. L'URL di base è https://api.ollamaapi.cc/v1, e ti autentichi con una chiave Bearer dalla pagina delle chiavi API.

Ecco una versione che legge il suo bersaglio dalle variabili d'ambiente, con i valori in hosting come default. Per tornare al tuo server locale, esporta due variabili e non cambiare nient'altro.

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)

Per le esecuzioni locali, imposta LLM_BASE_URL=http://localhost:11434/v1, LLM_API_KEY=ollama e LLM_MODEL=llama3.2. La guida rapida ha la stessa configurazione in curl e Node.

Streaming, modalità JSON e strumenti lato hosting

L'endpoint in hosting supporta lo streaming su SSE, la modalità JSON, la chiamata di funzioni e i parametri di campionamento standard (temperature, top_p, stop, seed e le penalità). Lo streaming con l'SDK è lo stesso ciclo che scriveresti per qualsiasi server in stile OpenAI:

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)

Per l'output strutturato, imposta response_format={"type": "json_object"} e specifica nel prompt che vuoi JSON. Analizza sempre all'interno di un blocco try; un modello può comunque restituire qualcosa che non ti aspettavi.

Una differenza rispetto all'uso locale conta nel codice: i limiti. Una chiave completa permette 8 richieste parallele e 300 richieste al minuto, e una richiesta in streaming mantiene il suo slot fino alla fine dello stream. Se fai fan-out con thread, limita il pool a 8 e riprova su HTTP 429 usando l'intestazione Retry-After quando è presente.

Mantenere viva una conversazione

Né l'endpoint chat locale né quello in hosting ricordano nulla tra le chiamate. Il server vede solo i messaggi che invii, quindi un chatbot è una lista a cui aggiungi e reinvii. Il pattern è identico per entrambi i bersagli, che è un'altra ragione per mantenere il client in stile OpenAI come tuo default.

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."))

Due note pratiche. Primo, i modelli locali hanno una lunghezza di contesto che imposti e che la memoria deve contenere; se la cronologia cresce oltre questo limite, i turni più vecchi vengono tagliati o la chiamata fallisce, a seconda delle impostazioni. Il modello in hosting accetta una finestra di 100.000 token incluso il completamento, che è molto più di quanto la maggior parte delle chat necessiti, ma le cronologie lunghe costano ancora token di input ad ogni turno. Secondo, una volta che una cronologia diventa lunga, riassumi i turni più vecchi in un breve messaggio invece di reinviarli tutti. Questo mantiene la latenza e il costo stabili su entrambi i backend.

Riprova con cortesia

Sull'API in hosting un sovraccarico temporaneo restituisce HTTP 429 con un'intestazione Retry-After: 5. Un piccolo wrapper lo gestisce:

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")

Ollama locale non ti limita con rate limit, ma accoda le richieste quando il modello è occupato, quindi lo stesso wrapper non fa danno lì.

Locale o hosting: come decidere

Nessuna scelta è migliore in generale. Usa i punti seguenti come checklist.

  • Scegli Ollama locale se devi lavorare offline, se i dati non devono mai lasciare la macchina, se possiedi già una GPU capace, o se vuoi provare rapidamente molti modelli open diversi.
  • Scegli un'API ospitata se non hai una GPU, se esegui su un piccolo VPS o in CI, se più persone o servizi condividono un backend, o se vuoi una finestra di contesto lunga senza dimensionare la memoria da solo. Il servizio ospitato accetta fino a 100.000 token di prompt più completamento.
  • Combina entrambi durante lo sviluppo: itera localmente, poi punta la produzione all'URL ospitato tramite variabili d'ambiente.

L'uso ospitato è fatturato per token, a $0,15 per 1M di token di input e $0,50 per 1M di token di output, dal credito prepagato. La pagina dei prezzi elenca gli importi di ricarica e i nuovi account possono richiedere un credito di prova gratuito di $0,50 con un clic, senza carta. I prompt non sono usati per l'addestramento.

Errori che incontrerai

SintomoCausa probabileSoluzione
Connessione rifiutata sulla porta 11434Il server Ollama non è in esecuzioneAvvia l'app o esegui ollama serve
Modello non trovatoIl modello non è mai stato recuperato o il nome contiene un errore di battituraEsegui ollama list, poi ollama pull il nome che usi
La prima chiamata va in timeoutIl modello è ancora in caricamentoAumenta il timeout o invia una richiesta di riscaldamento
Errore di autenticazione sull'API ospitataChiave Bearer mancante o errataVerifica LLM_API_KEY e l'URL di base
HTTP 429 con codice concurrencyPiù di 8 richieste in corso (2 su una chiave di prova)Riduci il numero di worker
HTTP 429 con codice rate_limitedSuperato il limite di richieste al minutoRiduci la frequenza e riprova

Le richieste fallite o rifiutate sul lato ospitato non vengono addebitate, quindi la logica di retry non ti comporta costi per i tentativi falliti.

Domande e risposte

Qual è l'indirizzo predefinito dell'API Ollama?

Un server Ollama locale ascolta su http://localhost:11434. Gli endpoint nativi si trovano sotto /api, come /api/chat, e l'endpoint in stile OpenAI si trova sotto /v1.

Posso usare l'SDK Python di OpenAI con Ollama?

Sì. Imposta base_url su http://localhost:11434/v1 e passa qualsiasi stringa come chiave API. L'SDK invia quindi richieste standard di completamento chat al tuo modello locale.

Come passo da Ollama a un'API ospitata?

Modifica l'URL di base, la chiave e il nome del modello. Se il tuo codice li legge dalle variabili di ambiente, non è necessaria alcuna modifica al codice.

L'API ospitata funziona senza una GPU dal mio lato?

Sì. Il modello gira sul provider, quindi il tuo script ha solo bisogno di una connessione internet e di una chiave Bearer. Paghi a consumo di token usando il credito prepagato.

La tua chiave è a un modulo di distanza

Crea un account, copia la chiave, modifica l'URL di base. È tutta la configurazione.

Ottieni la chiave API