completion(): your first call
litellm.completion takes a model name and messages in the OpenAI shape and returns the answer in it. mock_response answers without calling any provider.
from litellm import completion
response = completion(
model="openai/gpt-4o-mini",
messages=[{"role": "user", "content": "I was charged twice for one order"}],
mock_response="billing",
)
print(response.choices[0].message.content)
print(response.choices[0].finish_reason)
print(response.usage)mock_response is documented for tests: LiteLLM builds a normal response around that text instead of sending the request, so no key is needed. Take it out and set OPENAI_API_KEY, and the same call goes to OpenAI.
The answer is where lesson 1 found it for OpenAI, choices[0].message.content, whichever provider answered. finish_reason says why the model stopped. The mock's usage numbers are made-up placeholders, not counts of this text.
Dictionary style works too
response = completion(model="openai/gpt-4o-mini", messages=[{"role": "user", "content": "hi"}], mock_response="Hello!")
print(response["choices"][0]["message"]["content"])
print(type(response).__name__)The result is a ModelResponse object that also answers square-bracket access, so code written against OpenAI's JSON keeps working.
Async
import asyncio
from litellm import acompletion
async def main():
response = await acompletion(model="openai/gpt-4o-mini", messages=[{"role": "user", "content": "hi"}], mock_response="Hello from async")
print(response.choices[0].message.content)
asyncio.run(main())acompletion is the same call for async code, so many requests can be waiting at once, as in Python for AI.
- Pass
mock_response=""and print the content. - Print
response.model. - Add a system message to
messages. Nothing else in the call changes.
You understood something today that you didn't yesterday.