Skip to content

Commit 64c1eb7

Browse files
ParthSareenfujitatomoyamxyng
authored
Examples refactor (#329)
* Examples and README updates --------- Co-authored-by: fujitatomoya <tomoya.fujita825@gmail.com> Co-authored-by: Michael Yang <mxyng@pm.me>
1 parent 139c89e commit 64c1eb7

28 files changed

+457
-282
lines changed

README.md

Lines changed: 79 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
The Ollama Python library provides the easiest way to integrate Python 3.8+ projects with [Ollama](https://github.com/ollama/ollama).
44

5+
## Prerequisites
6+
7+
- [Ollama](https://ollama.com/download) should be installed and running
8+
- Pull a model to use with the library: `ollama pull <model>` e.g. `ollama pull llama3.2`
9+
- See [Ollama.com](https://ollama.com/search) for more information on the models available.
10+
511
## Install
612

713
```sh
@@ -11,25 +17,34 @@ pip install ollama
1117
## Usage
1218

1319
```python
14-
import ollama
15-
response = ollama.chat(model='llama3.1', messages=[
20+
from ollama import chat
21+
from ollama import ChatResponse
22+
23+
response: ChatResponse = chat(model='llama3.2', messages=[
1624
{
1725
'role': 'user',
1826
'content': 'Why is the sky blue?',
1927
},
2028
])
2129
print(response['message']['content'])
30+
# or access fields directly from the response object
31+
print(response.message.content)
2232
```
2333

34+
See [_types.py](ollama/_types.py) for more information on the response types.
35+
2436
## Streaming responses
2537

26-
Response streaming can be enabled by setting `stream=True`, modifying function calls to return a Python generator where each part is an object in the stream.
38+
Response streaming can be enabled by setting `stream=True`.
39+
40+
> [!NOTE]
41+
> Streaming Tool/Function calling is not yet supported.
2742
2843
```python
29-
import ollama
44+
from ollama import chat
3045

31-
stream = ollama.chat(
32-
model='llama3.1',
46+
stream = chat(
47+
model='llama3.2',
3348
messages=[{'role': 'user', 'content': 'Why is the sky blue?'}],
3449
stream=True,
3550
)
@@ -38,20 +53,68 @@ for chunk in stream:
3853
print(chunk['message']['content'], end='', flush=True)
3954
```
4055

56+
## Custom client
57+
A custom client can be created by instantiating `Client` or `AsyncClient` from `ollama`.
58+
59+
All extra keyword arguments are passed into the [`httpx.Client`](https://www.python-httpx.org/api/#client).
60+
61+
```python
62+
from ollama import Client
63+
client = Client(
64+
host='http://localhost:11434',
65+
headers={'x-some-header': 'some-value'}
66+
)
67+
response = client.chat(model='llama3.2', messages=[
68+
{
69+
'role': 'user',
70+
'content': 'Why is the sky blue?',
71+
},
72+
])
73+
```
74+
75+
## Async client
76+
77+
The `AsyncClient` class is used to make asynchronous requests. It can be configured with the same fields as the `Client` class.
78+
79+
```python
80+
import asyncio
81+
from ollama import AsyncClient
82+
83+
async def chat():
84+
message = {'role': 'user', 'content': 'Why is the sky blue?'}
85+
response = await AsyncClient().chat(model='llama3.2', messages=[message])
86+
87+
asyncio.run(chat())
88+
```
89+
90+
Setting `stream=True` modifies functions to return a Python asynchronous generator:
91+
92+
```python
93+
import asyncio
94+
from ollama import AsyncClient
95+
96+
async def chat():
97+
message = {'role': 'user', 'content': 'Why is the sky blue?'}
98+
async for part in await AsyncClient().chat(model='llama3.2', messages=[message], stream=True):
99+
print(part['message']['content'], end='', flush=True)
100+
101+
asyncio.run(chat())
102+
```
103+
41104
## API
42105

43106
The Ollama Python library's API is designed around the [Ollama REST API](https://github.com/ollama/ollama/blob/main/docs/api.md)
44107

45108
### Chat
46109

47110
```python
48-
ollama.chat(model='llama3.1', messages=[{'role': 'user', 'content': 'Why is the sky blue?'}])
111+
ollama.chat(model='llama3.2', messages=[{'role': 'user', 'content': 'Why is the sky blue?'}])
49112
```
50113

51114
### Generate
52115

53116
```python
54-
ollama.generate(model='llama3.1', prompt='Why is the sky blue?')
117+
ollama.generate(model='llama3.2', prompt='Why is the sky blue?')
55118
```
56119

57120
### List
@@ -63,14 +126,14 @@ ollama.list()
63126
### Show
64127

65128
```python
66-
ollama.show('llama3.1')
129+
ollama.show('llama3.2')
67130
```
68131

69132
### Create
70133

71134
```python
72135
modelfile='''
73-
FROM llama3.1
136+
FROM llama3.2
74137
SYSTEM You are mario from super mario bros.
75138
'''
76139

@@ -80,37 +143,37 @@ ollama.create(model='example', modelfile=modelfile)
80143
### Copy
81144

82145
```python
83-
ollama.copy('llama3.1', 'user/llama3.1')
146+
ollama.copy('llama3.2', 'user/llama3.2')
84147
```
85148

86149
### Delete
87150

88151
```python
89-
ollama.delete('llama3.1')
152+
ollama.delete('llama3.2')
90153
```
91154

92155
### Pull
93156

94157
```python
95-
ollama.pull('llama3.1')
158+
ollama.pull('llama3.2')
96159
```
97160

98161
### Push
99162

100163
```python
101-
ollama.push('user/llama3.1')
164+
ollama.push('user/llama3.2')
102165
```
103166

104167
### Embed
105168

106169
```python
107-
ollama.embed(model='llama3.1', input='The sky is blue because of rayleigh scattering')
170+
ollama.embed(model='llama3.2', input='The sky is blue because of rayleigh scattering')
108171
```
109172

110173
### Embed (batch)
111174

112175
```python
113-
ollama.embed(model='llama3.1', input=['The sky is blue because of rayleigh scattering', 'Grass is green because of chlorophyll'])
176+
ollama.embed(model='llama3.2', input=['The sky is blue because of rayleigh scattering', 'Grass is green because of chlorophyll'])
114177
```
115178

116179
### Ps
@@ -119,50 +182,6 @@ ollama.embed(model='llama3.1', input=['The sky is blue because of rayleigh scatt
119182
ollama.ps()
120183
```
121184

122-
## Custom client
123-
124-
A custom client can be created with the following fields:
125-
126-
- `host`: The Ollama host to connect to
127-
- `timeout`: The timeout for requests
128-
129-
```python
130-
from ollama import Client
131-
client = Client(host='http://localhost:11434')
132-
response = client.chat(model='llama3.1', messages=[
133-
{
134-
'role': 'user',
135-
'content': 'Why is the sky blue?',
136-
},
137-
])
138-
```
139-
140-
## Async client
141-
142-
```python
143-
import asyncio
144-
from ollama import AsyncClient
145-
146-
async def chat():
147-
message = {'role': 'user', 'content': 'Why is the sky blue?'}
148-
response = await AsyncClient().chat(model='llama3.1', messages=[message])
149-
150-
asyncio.run(chat())
151-
```
152-
153-
Setting `stream=True` modifies functions to return a Python asynchronous generator:
154-
155-
```python
156-
import asyncio
157-
from ollama import AsyncClient
158-
159-
async def chat():
160-
message = {'role': 'user', 'content': 'Why is the sky blue?'}
161-
async for part in await AsyncClient().chat(model='llama3.1', messages=[message], stream=True):
162-
print(part['message']['content'], end='', flush=True)
163-
164-
asyncio.run(chat())
165-
```
166185

167186
## Errors
168187

examples/README.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Running Examples
2+
3+
Run the examples in this directory with:
4+
```sh
5+
# Run example
6+
python3 examples/<example>.py
7+
```
8+
9+
### Chat - Chat with a model
10+
- [chat.py](chat.py)
11+
- [async-chat.py](async-chat.py)
12+
- [chat-stream.py](chat-stream.py) - Streamed outputs
13+
- [chat-with-history.py](chat-with-history.py) - Chat with model and maintain history of the conversation
14+
15+
16+
### Generate - Generate text with a model
17+
- [generate.py](generate.py)
18+
- [async-generate.py](async-generate.py)
19+
- [generate-stream.py](generate-stream.py) - Streamed outputs
20+
- [fill-in-middle.py](fill-in-middle.py) - Given a prefix and suffix, fill in the middle
21+
22+
23+
### Tools/Function Calling - Call a function with a model
24+
- [tools.py](tools.py) - Simple example of Tools/Function Calling
25+
- [async-tools.py](async-tools.py)
26+
27+
28+
### Multimodal with Images - Chat with a multimodal (image chat) model
29+
- [multimodal_chat.py](multimodal_chat.py)
30+
- [multimodal_generate.py](multimodal_generate.py)
31+
32+
33+
### Ollama List - List all downloaded models and their properties
34+
- [list.py](list.py)
35+
36+
37+
### Ollama ps - Show model status with CPU/GPU usage
38+
- [ps.py](ps.py)
39+
40+
41+
### Ollama Pull - Pull a model from Ollama
42+
Requirement: `pip install tqdm`
43+
- [pull.py](pull.py)
44+
45+
46+
### Ollama Create - Create a model from a Modelfile
47+
```python
48+
python create.py <model> <modelfile>
49+
```
50+
- [create.py](create.py)
51+
52+
See [ollama/docs/modelfile.md](https://github.com/ollama/ollama/blob/main/docs/modelfile.md) for more information on the Modelfile format.
53+
54+
55+
### Ollama Embed - Generate embeddings with a model
56+
- [embed.py](embed.py)
57+

examples/async-chat-stream/README.md

Lines changed: 0 additions & 3 deletions
This file was deleted.

examples/async-chat-stream/main.py

Lines changed: 0 additions & 59 deletions
This file was deleted.

examples/async-chat.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import asyncio
2+
from ollama import AsyncClient
3+
4+
5+
async def main():
6+
messages = [
7+
{
8+
'role': 'user',
9+
'content': 'Why is the sky blue?',
10+
},
11+
]
12+
13+
client = AsyncClient()
14+
response = await client.chat('llama3.2', messages=messages)
15+
print(response['message']['content'])
16+
17+
18+
if __name__ == '__main__':
19+
asyncio.run(main())

examples/async-generate.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import asyncio
2+
import ollama
3+
4+
5+
async def main():
6+
client = ollama.AsyncClient()
7+
response = await client.generate('llama3.2', 'Why is the sky blue?')
8+
print(response['response'])
9+
10+
11+
if __name__ == '__main__':
12+
try:
13+
asyncio.run(main())
14+
except KeyboardInterrupt:
15+
print('\nGoodbye!')

0 commit comments

Comments
 (0)