mirror of
https://github.com/ollama/ollama-python.git
synced 2026-06-19 06:33:24 +00:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2b77cd1ec1 | |||
| 60e7b2f9ce | |||
| d1d704050b | |||
| 115792583e |
@@ -13,7 +13,7 @@ jobs:
|
||||
id-token: write
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
- uses: astral-sh/setup-uv@v5
|
||||
with:
|
||||
|
||||
@@ -10,16 +10,28 @@ jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- uses: astral-sh/setup-uv@v5
|
||||
with:
|
||||
enable-cache: true
|
||||
- run: uvx hatch test -acp
|
||||
if: ${{ always() }}
|
||||
test-legacy:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.8', '3.9']
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: astral-sh/setup-uv@v5
|
||||
with:
|
||||
enable-cache: true
|
||||
- name: Run tests on Python ${{ matrix.python-version }}
|
||||
run: uv run --python ${{ matrix.python-version }} --with pytest --with pytest-anyio --with pytest-httpserver pytest tests/
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6
|
||||
- uses: astral-sh/setup-uv@v5
|
||||
with:
|
||||
|
||||
@@ -50,6 +50,82 @@ for chunk in stream:
|
||||
print(chunk['message']['content'], end='', flush=True)
|
||||
```
|
||||
|
||||
## Cloud Models
|
||||
|
||||
Run larger models by offloading to Ollama’s cloud while keeping your local workflow.
|
||||
|
||||
- Supported models: `deepseek-v3.1:671b-cloud`, `gpt-oss:20b-cloud`, `gpt-oss:120b-cloud`, `kimi-k2:1t-cloud`, `qwen3-coder:480b-cloud`, `kimi-k2-thinking` See [Ollama Models - Cloud](https://ollama.com/search?c=cloud) for more information
|
||||
|
||||
### Run via local Ollama
|
||||
|
||||
1) Sign in (one-time):
|
||||
|
||||
```
|
||||
ollama signin
|
||||
```
|
||||
|
||||
2) Pull a cloud model:
|
||||
|
||||
```
|
||||
ollama pull gpt-oss:120b-cloud
|
||||
```
|
||||
|
||||
3) Make a request:
|
||||
|
||||
```python
|
||||
from ollama import Client
|
||||
|
||||
client = Client()
|
||||
|
||||
messages = [
|
||||
{
|
||||
'role': 'user',
|
||||
'content': 'Why is the sky blue?',
|
||||
},
|
||||
]
|
||||
|
||||
for part in client.chat('gpt-oss:120b-cloud', messages=messages, stream=True):
|
||||
print(part.message.content, end='', flush=True)
|
||||
```
|
||||
|
||||
### Cloud API (ollama.com)
|
||||
|
||||
Access cloud models directly by pointing the client at `https://ollama.com`.
|
||||
|
||||
1) Create an API key from [ollama.com](https://ollama.com/settings/keys) , then set:
|
||||
|
||||
```
|
||||
export OLLAMA_API_KEY=your_api_key
|
||||
```
|
||||
|
||||
2) (Optional) List models available via the API:
|
||||
|
||||
```
|
||||
curl https://ollama.com/api/tags
|
||||
```
|
||||
|
||||
3) Generate a response via the cloud API:
|
||||
|
||||
```python
|
||||
import os
|
||||
from ollama import Client
|
||||
|
||||
client = Client(
|
||||
host='https://ollama.com',
|
||||
headers={'Authorization': 'Bearer ' + os.environ.get('OLLAMA_API_KEY')}
|
||||
)
|
||||
|
||||
messages = [
|
||||
{
|
||||
'role': 'user',
|
||||
'content': 'Why is the sky blue?',
|
||||
},
|
||||
]
|
||||
|
||||
for part in client.chat('gpt-oss:120b', messages=messages, stream=True):
|
||||
print(part.message.content, end='', flush=True)
|
||||
```
|
||||
|
||||
## Custom client
|
||||
A custom client can be created by instantiating `Client` or `AsyncClient` from `ollama`.
|
||||
|
||||
|
||||
+14
-1
@@ -1,3 +1,4 @@
|
||||
import contextlib
|
||||
import ipaddress
|
||||
import json
|
||||
import os
|
||||
@@ -75,7 +76,7 @@ from ollama._types import (
|
||||
T = TypeVar('T')
|
||||
|
||||
|
||||
class BaseClient:
|
||||
class BaseClient(contextlib.AbstractContextManager, contextlib.AbstractAsyncContextManager):
|
||||
def __init__(
|
||||
self,
|
||||
client,
|
||||
@@ -116,6 +117,12 @@ class BaseClient:
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
self.close()
|
||||
|
||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
||||
await self.close()
|
||||
|
||||
|
||||
CONNECTION_ERROR_MESSAGE = 'Failed to connect to Ollama. Please check that Ollama is downloaded, running and accessible. https://ollama.com/download'
|
||||
|
||||
@@ -124,6 +131,9 @@ class Client(BaseClient):
|
||||
def __init__(self, host: Optional[str] = None, **kwargs) -> None:
|
||||
super().__init__(httpx.Client, host, **kwargs)
|
||||
|
||||
def close(self):
|
||||
self._client.close()
|
||||
|
||||
def _request_raw(self, *args, **kwargs):
|
||||
try:
|
||||
r = self._client.request(*args, **kwargs)
|
||||
@@ -702,6 +712,9 @@ class AsyncClient(BaseClient):
|
||||
def __init__(self, host: Optional[str] = None, **kwargs) -> None:
|
||||
super().__init__(httpx.AsyncClient, host, **kwargs)
|
||||
|
||||
async def close(self):
|
||||
await self._client.aclose()
|
||||
|
||||
async def _request_raw(self, *args, **kwargs):
|
||||
try:
|
||||
r = await self._client.request(*args, **kwargs)
|
||||
|
||||
@@ -32,6 +32,9 @@ extra-dependencies = [
|
||||
'pytest-httpserver',
|
||||
]
|
||||
|
||||
[[tool.hatch.envs.hatch-test.matrix]]
|
||||
python = ["3.10", "3.11", "3.12", "3.13"]
|
||||
|
||||
[tool.hatch.envs.hatch-static-analysis]
|
||||
dependencies = [ 'ruff>=0.9.1' ]
|
||||
config-path = 'none'
|
||||
|
||||
@@ -1347,3 +1347,33 @@ def test_client_explicit_bearer_header_overrides_env(monkeypatch: pytest.MonkeyP
|
||||
client = Client(headers={'Authorization': 'Bearer explicit-token'})
|
||||
assert client._client.headers['authorization'] == 'Bearer explicit-token'
|
||||
client.web_search('override check')
|
||||
|
||||
|
||||
def test_client_close():
|
||||
client = Client()
|
||||
client.close()
|
||||
assert client._client.is_closed
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_async_client_close():
|
||||
client = AsyncClient()
|
||||
await client.close()
|
||||
assert client._client.is_closed
|
||||
|
||||
|
||||
def test_client_context_manager():
|
||||
with Client() as client:
|
||||
assert isinstance(client, Client)
|
||||
assert not client._client.is_closed
|
||||
|
||||
assert client._client.is_closed
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_async_client_context_manager():
|
||||
async with AsyncClient() as client:
|
||||
assert isinstance(client, AsyncClient)
|
||||
assert not client._client.is_closed
|
||||
|
||||
assert client._client.is_closed
|
||||
|
||||
Reference in New Issue
Block a user