mirror of
https://github.com/ollama/ollama-python.git
synced 2026-08-03 03:47:46 +00:00
Examples and readme updates
This commit is contained in:
@@ -2,6 +2,11 @@
|
||||
|
||||
The Ollama Python library provides the easiest way to integrate Python 3.8+ projects with [Ollama](https://github.com/ollama/ollama).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Install [Ollama](https://ollama.com/download)
|
||||
- Pull a model: `ollama pull <model>` See [Ollama models](https://ollama.com/models)
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
# Running Examples
|
||||
|
||||
Run the examples in this directory with:
|
||||
```sh
|
||||
# Navigate to examples directory
|
||||
cd examples/
|
||||
|
||||
# Run example
|
||||
python3 <example>.py
|
||||
```
|
||||
|
||||
### Chat
|
||||
- [chat.py](chat.py) - Basic chat with model
|
||||
- [chat-stream.py](chat-stream.py) - Stream chat with model
|
||||
- [async-chat.py](async-chat.py) - Async chat with model
|
||||
|
||||
### Generate
|
||||
- [generate.py](generate.py) - Generate text with model
|
||||
- [generate-stream.py](generate-stream.py) - Stream generate text with model
|
||||
- [async-generate.py](async-generate.py) - Async generate text with model
|
||||
|
||||
### List
|
||||
- [list.py](list.py) - List all downloaded models and their properties
|
||||
- [async-list.py](async-list.py) - Async list all downloaded models and their properties
|
||||
|
||||
### Fill in the middle
|
||||
- [fill-in-middle.py](fill-in-middle.py) - Fill in the middle with model
|
||||
|
||||
|
||||
### Multimodal
|
||||
- [multimodal.py](multimodal.py) - Multimodal chat with model
|
||||
|
||||
### Pull Progress
|
||||
Requirement: `pip install tqdm`
|
||||
|
||||
- [pull-progress.py](pull-progress.py) - Pull progress with model
|
||||
|
||||
### Ollama create (create a model)
|
||||
- [create.py](create.py) - Create a model
|
||||
|
||||
### Ollama ps (show model status - cpu/gpu usage)
|
||||
- [ollama-ps.py](ollama-ps.py) - Ollama ps
|
||||
|
||||
### Tools/Function Calling
|
||||
- [tools.py](tools.py) - Simple example of Tools/Function Calling
|
||||
- [async-tools.py](async-tools.py) - Async example of Tools/Function Calling
|
||||
|
||||
## Configuring Clients
|
||||
Custom parameters can be passed to the client when initializing:
|
||||
```python
|
||||
import ollama
|
||||
client = ollama.Client(
|
||||
host='http://localhost:11434',
|
||||
timeout=10.0, # Default: None
|
||||
follow_redirects=True, # Default: True
|
||||
headers={'x-some-header': 'some-value'}
|
||||
)
|
||||
```
|
||||
|
||||
Similarly, the `AsyncClient` class can be configured with the same parameters.
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# async-chat-stream
|
||||
|
||||
This example demonstrates how to create a conversation history using an asynchronous Ollama client and the chat endpoint. The streaming response is outputted to `stdout` as well as a TTS if enabled with `--speak` and available. Supported TTS are `say` on macOS and `espeak` on Linux.
|
||||
@@ -1,59 +0,0 @@
|
||||
import shutil
|
||||
import asyncio
|
||||
import argparse
|
||||
|
||||
import ollama
|
||||
|
||||
|
||||
async def speak(speaker, content):
|
||||
if speaker:
|
||||
p = await asyncio.create_subprocess_exec(speaker, content)
|
||||
await p.communicate()
|
||||
|
||||
|
||||
async def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--speak', default=False, action='store_true')
|
||||
args = parser.parse_args()
|
||||
|
||||
speaker = None
|
||||
if not args.speak:
|
||||
...
|
||||
elif say := shutil.which('say'):
|
||||
speaker = say
|
||||
elif (espeak := shutil.which('espeak')) or (espeak := shutil.which('espeak-ng')):
|
||||
speaker = espeak
|
||||
|
||||
client = ollama.AsyncClient()
|
||||
|
||||
messages = []
|
||||
|
||||
while True:
|
||||
if content_in := input('>>> '):
|
||||
messages.append({'role': 'user', 'content': content_in})
|
||||
|
||||
content_out = ''
|
||||
message = {'role': 'assistant', 'content': ''}
|
||||
async for response in await client.chat(model='mistral', messages=messages, stream=True):
|
||||
if response['done']:
|
||||
messages.append(message)
|
||||
|
||||
content = response['message']['content']
|
||||
print(content, end='', flush=True)
|
||||
|
||||
content_out += content
|
||||
if content in ['.', '!', '?', '\n']:
|
||||
await speak(speaker, content_out)
|
||||
content_out = ''
|
||||
|
||||
message['content'] += content
|
||||
|
||||
if content_out:
|
||||
await speak(speaker, content_out)
|
||||
print()
|
||||
|
||||
|
||||
try:
|
||||
asyncio.run(main())
|
||||
except (KeyboardInterrupt, EOFError):
|
||||
...
|
||||
@@ -0,0 +1,35 @@
|
||||
import asyncio
|
||||
import ollama
|
||||
|
||||
|
||||
async def main():
|
||||
client = ollama.AsyncClient()
|
||||
messages = []
|
||||
|
||||
print("Chat with the model (type 'exit' to quit)")
|
||||
while True:
|
||||
# Get user input
|
||||
user_input = input('You: ')
|
||||
if user_input.lower() == 'exit':
|
||||
break
|
||||
|
||||
# Add user message to history
|
||||
messages.append({'role': 'user', 'content': user_input})
|
||||
|
||||
# Stream the response
|
||||
print('Assistant: ', end='', flush=True)
|
||||
async for chunk in await client.chat(model='llama3.1', messages=messages, stream=True):
|
||||
# Print the response chunk
|
||||
print(chunk['message']['content'], end='', flush=True)
|
||||
|
||||
# Update message history with complete response
|
||||
if chunk['done']:
|
||||
messages.append(chunk['message'])
|
||||
print('\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
asyncio.run(main())
|
||||
except KeyboardInterrupt:
|
||||
print('\nGoodbye!')
|
||||
@@ -0,0 +1,15 @@
|
||||
import asyncio
|
||||
import ollama
|
||||
|
||||
|
||||
async def main():
|
||||
client = ollama.AsyncClient()
|
||||
response = await client.generate('llama3.1', 'Why is the sky blue?')
|
||||
print(response['response'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
asyncio.run(main())
|
||||
except KeyboardInterrupt:
|
||||
print('\nGoodbye!')
|
||||
@@ -0,0 +1,37 @@
|
||||
import asyncio
|
||||
import ollama
|
||||
|
||||
|
||||
async def main():
|
||||
client = ollama.AsyncClient()
|
||||
|
||||
response = await client.list()
|
||||
models = response['models']
|
||||
models_data = []
|
||||
for model in models:
|
||||
if model.get('details'): # Check if details exist
|
||||
models_data.append(
|
||||
(
|
||||
model.get('name', 'N/A'),
|
||||
model.get('size', 0) / 1024 / 1024, # Convert to MB
|
||||
model.get('details', {}).get('format', 'N/A'),
|
||||
model.get('details', {}).get('family', 'N/A'),
|
||||
model.get('details', {}).get('parameter_size', 'N/A'),
|
||||
model.get('details', {}).get('quantization_level', 'N/A'),
|
||||
)
|
||||
)
|
||||
|
||||
print(f'\n{len(models)} models found!')
|
||||
print('\nDetailed model information:')
|
||||
for model in models_data:
|
||||
print(f'Name: {model[0]}')
|
||||
print(f'Size (MB): {model[1]:.2f}')
|
||||
print(f'Format: {model[2]}')
|
||||
print(f'Family: {model[3]}')
|
||||
print(f'Parameter Size: {model[4]}')
|
||||
print(f'Quantization Level: {model[5]}')
|
||||
print('-' * 50)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,40 @@
|
||||
import asyncio
|
||||
from ollama import AsyncClient
|
||||
|
||||
|
||||
async def main():
|
||||
client = AsyncClient()
|
||||
|
||||
response = await client.pull('llama3.1', stream=True)
|
||||
progress_states = set()
|
||||
async for progress in response:
|
||||
if progress.get('status') in progress_states:
|
||||
continue
|
||||
progress_states.add(progress.get('status'))
|
||||
print(progress.get('status'))
|
||||
|
||||
print('\n')
|
||||
|
||||
response = await client.chat('llama3.1', messages=[{'role': 'user', 'content': 'Hello!'}])
|
||||
print(response['message']['content'])
|
||||
|
||||
print('\n')
|
||||
|
||||
response = await client.ps()
|
||||
|
||||
name = response['models'][0]['name']
|
||||
size = response['models'][0]['size']
|
||||
size_vram = response['models'][0]['size_vram']
|
||||
|
||||
if size == size_vram:
|
||||
print(f'{name}: 100% GPU')
|
||||
elif not size_vram:
|
||||
print(f'{name}: 100% CPU')
|
||||
else:
|
||||
size_cpu = size - size_vram
|
||||
cpu_percent = round(size_cpu / size * 100)
|
||||
print(f'{name}: {cpu_percent}% CPU/{100 - cpu_percent}% GPU')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(main())
|
||||
@@ -6,6 +6,16 @@ import asyncio
|
||||
# Simulates an API call to get flight times
|
||||
# In a real application, this would fetch data from a live database or API
|
||||
def get_flight_times(departure: str, arrival: str) -> str:
|
||||
"""
|
||||
Get the flight times between two cities
|
||||
|
||||
Args:
|
||||
departure (str): The departure city (airport code)
|
||||
arrival (str): The arrival city (airport code)
|
||||
|
||||
Returns:
|
||||
str: The flight times between the two cities
|
||||
"""
|
||||
flights = {
|
||||
'NYC-LAX': {'departure': '08:00 AM', 'arrival': '11:30 AM', 'duration': '5h 30m'},
|
||||
'LAX-NYC': {'departure': '02:00 PM', 'arrival': '10:30 PM', 'duration': '5h 30m'},
|
||||
@@ -28,29 +38,7 @@ async def run(model: str):
|
||||
response = await client.chat(
|
||||
model=model,
|
||||
messages=messages,
|
||||
tools=[
|
||||
{
|
||||
'type': 'function',
|
||||
'function': {
|
||||
'name': 'get_flight_times',
|
||||
'description': 'Get the flight times between two cities',
|
||||
'parameters': {
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'departure': {
|
||||
'type': 'string',
|
||||
'description': 'The departure city (airport code)',
|
||||
},
|
||||
'arrival': {
|
||||
'type': 'string',
|
||||
'description': 'The arrival city (airport code)',
|
||||
},
|
||||
},
|
||||
'required': ['departure', 'arrival'],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
tools=[get_flight_times],
|
||||
)
|
||||
|
||||
# Add the model's response to the conversation history
|
||||
@@ -80,8 +68,8 @@ async def run(model: str):
|
||||
|
||||
# Second API call: Get final response from the model
|
||||
final_response = await client.chat(model=model, messages=messages)
|
||||
print(final_response['message']['content'])
|
||||
print(final_response.message.content)
|
||||
|
||||
|
||||
# Run the async function
|
||||
asyncio.run(run('mistral'))
|
||||
asyncio.run(run('llama3.1'))
|
||||
@@ -8,8 +8,7 @@ messages = [
|
||||
},
|
||||
]
|
||||
|
||||
for part in chat('mistral', messages=messages, stream=True):
|
||||
for part in chat('llama3.1', messages=messages, stream=True):
|
||||
print(part['message']['content'], end='', flush=True)
|
||||
|
||||
# end with a newline
|
||||
print()
|
||||
@@ -1,6 +1,5 @@
|
||||
from ollama import chat
|
||||
|
||||
|
||||
messages = [
|
||||
{
|
||||
'role': 'user',
|
||||
@@ -8,5 +7,5 @@ messages = [
|
||||
},
|
||||
]
|
||||
|
||||
response = chat('mistral', messages=messages)
|
||||
response = chat('llama3.1', messages=messages)
|
||||
print(response['message']['content'])
|
||||
@@ -1,5 +1,5 @@
|
||||
from ollama import generate
|
||||
|
||||
|
||||
for part in generate('mistral', 'Why is the sky blue?', stream=True):
|
||||
for part in generate('llama3.1', 'Why is the sky blue?', stream=True):
|
||||
print(part['response'], end='', flush=True)
|
||||
@@ -1,5 +1,5 @@
|
||||
from ollama import generate
|
||||
|
||||
|
||||
response = generate('mistral', 'Why is the sky blue?')
|
||||
response = generate('llama3.1', 'Why is the sky blue?')
|
||||
print(response['response'])
|
||||
@@ -0,0 +1,14 @@
|
||||
from ollama import list
|
||||
from ollama._types import ListResponse
|
||||
|
||||
response: ListResponse = list()
|
||||
|
||||
for model in response.models:
|
||||
if model.details:
|
||||
print(f'Name: {model.model}')
|
||||
print(f'Size (MB): {(model.size.real / 1024 / 1024):.2f}')
|
||||
print(f'Format: {model.details.format}')
|
||||
print(f'Family: {model.details.family}')
|
||||
print(f'Parameter Size: {model.details.parameter_size}')
|
||||
print(f'Quantization Level: {model.details.quantization_level}')
|
||||
print('-' * 50)
|
||||
@@ -4,7 +4,6 @@ import httpx
|
||||
|
||||
from ollama import generate
|
||||
|
||||
|
||||
latest = httpx.get('https://xkcd.com/info.0.json')
|
||||
latest.raise_for_status()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from ollama import ps, pull, chat
|
||||
|
||||
response = pull('mistral', stream=True)
|
||||
response = pull('llama3.1', stream=True)
|
||||
progress_states = set()
|
||||
for progress in response:
|
||||
if progress.get('status') in progress_states:
|
||||
@@ -10,7 +10,7 @@ for progress in response:
|
||||
|
||||
print('\n')
|
||||
|
||||
response = chat('mistral', messages=[{'role': 'user', 'content': 'Hello!'}])
|
||||
response = chat('llama3.1', messages=[{'role': 'user', 'content': 'Hello!'}])
|
||||
print(response['message']['content'])
|
||||
|
||||
print('\n')
|
||||
@@ -3,7 +3,7 @@ from ollama import pull
|
||||
|
||||
|
||||
current_digest, bars = '', {}
|
||||
for progress in pull('mistral', stream=True):
|
||||
for progress in pull('llama3.1', stream=True):
|
||||
digest = progress.get('digest', '')
|
||||
if digest != current_digest and current_digest in bars:
|
||||
bars[current_digest].close()
|
||||
@@ -1,9 +0,0 @@
|
||||
# pull-progress
|
||||
|
||||
This example emulates `ollama pull` using the Python library and [`tqdm`](https://tqdm.github.io/).
|
||||
|
||||
## Setup
|
||||
|
||||
```shell
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
@@ -1 +0,0 @@
|
||||
tqdm==4.66.1
|
||||
@@ -0,0 +1,67 @@
|
||||
from ollama import chat
|
||||
from ollama._types import ChatResponse
|
||||
|
||||
|
||||
def add_two_numbers(a: int, b: int) -> int:
|
||||
"""
|
||||
Add two numbers
|
||||
|
||||
Args:
|
||||
a (int): The first number
|
||||
b (int): The second number
|
||||
|
||||
Returns:
|
||||
int: The sum of the two numbers
|
||||
"""
|
||||
return a + b
|
||||
|
||||
|
||||
def subtract_two_numbers(a: int, b: int) -> int:
|
||||
"""
|
||||
Subtract two numbers
|
||||
"""
|
||||
return a - b
|
||||
|
||||
|
||||
# Tools can still be manually defined and passed into chat
|
||||
subtract_two_numbers_tool = {
|
||||
'type': 'function',
|
||||
'function': {
|
||||
'name': 'subtract_two_numbers',
|
||||
'description': 'Subtract two numbers',
|
||||
'parameters': {
|
||||
'type': 'object',
|
||||
'required': ['a', 'b'],
|
||||
'properties': {
|
||||
'a': {'type': 'integer', 'description': 'The first number'},
|
||||
'b': {'type': 'integer', 'description': 'The second number'},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
prompt = 'What is three minus one?'
|
||||
print(f'Prompt: {prompt}')
|
||||
|
||||
response: ChatResponse = chat(
|
||||
'llama3.1',
|
||||
messages=[{'role': 'user', 'content': prompt}],
|
||||
tools=[add_two_numbers, subtract_two_numbers_tool],
|
||||
)
|
||||
|
||||
available_functions = {
|
||||
'add_two_numbers': add_two_numbers,
|
||||
'subtract_two_numbers': subtract_two_numbers,
|
||||
}
|
||||
|
||||
if response.message.tool_calls:
|
||||
# There may be multiple tool calls in the response
|
||||
for tool in response.message.tool_calls:
|
||||
# Ensure the function is available, and then call it
|
||||
if tool.function.name in available_functions:
|
||||
print(f'Calling function {tool.function.name}')
|
||||
print(f'Arguments: {tool.function.arguments}')
|
||||
function_to_call = available_functions[tool.function.name]
|
||||
print(f'Function output: {function_to_call(**tool.function.arguments)}')
|
||||
else:
|
||||
print(f'Function {tool.function.name} not found')
|
||||
@@ -1,3 +0,0 @@
|
||||
# tools
|
||||
|
||||
This example demonstrates how to utilize tool calls with an asynchronous Ollama client and the chat endpoint.
|
||||
Reference in New Issue
Block a user