chatlas 0.6.0__py3-none-any.whl → 0.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of chatlas might be problematic. Click here for more details.
- chatlas/__init__.py +5 -0
- chatlas/_anthropic.py +12 -6
- chatlas/_auto.py +7 -3
- chatlas/_chat.py +339 -120
- chatlas/_content.py +230 -32
- chatlas/_databricks.py +145 -0
- chatlas/_display.py +13 -7
- chatlas/_google.py +9 -5
- chatlas/_ollama.py +3 -2
- chatlas/_openai.py +9 -8
- chatlas/_snowflake.py +46 -23
- chatlas/_utils.py +36 -1
- chatlas/_version.py +2 -2
- chatlas/types/openai/_submit.py +11 -1
- {chatlas-0.6.0.dist-info → chatlas-0.7.0.dist-info}/METADATA +29 -1
- {chatlas-0.6.0.dist-info → chatlas-0.7.0.dist-info}/RECORD +17 -16
- {chatlas-0.6.0.dist-info → chatlas-0.7.0.dist-info}/WHEEL +0 -0
chatlas/_snowflake.py
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
import asyncio
|
|
2
|
+
import json
|
|
3
|
+
from typing import TYPE_CHECKING, Iterable, Literal, Optional, TypedDict, cast, overload
|
|
2
4
|
|
|
3
5
|
from pydantic import BaseModel
|
|
4
6
|
|
|
5
7
|
from ._chat import Chat
|
|
6
|
-
from ._content import Content
|
|
8
|
+
from ._content import Content, ContentJson, ContentText
|
|
7
9
|
from ._logging import log_model_default
|
|
8
10
|
from ._provider import Provider
|
|
9
|
-
from ._tools import Tool
|
|
11
|
+
from ._tools import Tool, basemodel_to_param_schema
|
|
10
12
|
from ._turn import Turn, normalize_turns
|
|
11
|
-
from ._utils import drop_none
|
|
13
|
+
from ._utils import drop_none, wrap_async_iterable
|
|
12
14
|
|
|
13
15
|
if TYPE_CHECKING:
|
|
14
16
|
from snowflake.snowpark import Column
|
|
@@ -237,9 +239,18 @@ class SnowflakeProvider(Provider["Completion", "CompletionChunk", "CompletionChu
|
|
|
237
239
|
data_model: Optional[type[BaseModel]] = None,
|
|
238
240
|
kwargs: Optional["SubmitInputArgs"] = None,
|
|
239
241
|
):
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
)
|
|
242
|
+
from snowflake.cortex import complete
|
|
243
|
+
|
|
244
|
+
kwargs = self._chat_perform_args(stream, turns, tools, data_model, kwargs)
|
|
245
|
+
|
|
246
|
+
# Prevent the main thread from being blocked (Snowflake doesn't have native async support)
|
|
247
|
+
res = await asyncio.to_thread(complete, **kwargs)
|
|
248
|
+
|
|
249
|
+
# When streaming, res is an iterable of strings, but Chat() wants an async iterable
|
|
250
|
+
if stream:
|
|
251
|
+
res = wrap_async_iterable(cast(Iterable[str], res))
|
|
252
|
+
|
|
253
|
+
return res
|
|
243
254
|
|
|
244
255
|
def _chat_perform_args(
|
|
245
256
|
self,
|
|
@@ -249,27 +260,31 @@ class SnowflakeProvider(Provider["Completion", "CompletionChunk", "CompletionChu
|
|
|
249
260
|
data_model: Optional[type[BaseModel]] = None,
|
|
250
261
|
kwargs: Optional["SubmitInputArgs"] = None,
|
|
251
262
|
):
|
|
252
|
-
# Cortex doesn't seem to support tools
|
|
253
|
-
if tools:
|
|
254
|
-
raise ValueError("Snowflake does not currently support tools.")
|
|
255
|
-
|
|
256
|
-
# TODO: implement data_model when this PR makes it into snowflake-ml-python
|
|
257
|
-
# https://github.com/snowflakedb/snowflake-ml-python/pull/141
|
|
258
|
-
# https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-llm-rest-api#structured-output-example
|
|
259
|
-
if data_model:
|
|
260
|
-
raise NotImplementedError(
|
|
261
|
-
"The snowflake-ml-python package currently doesn't support structured output. "
|
|
262
|
-
"Upvote this PR to help prioritize it: "
|
|
263
|
-
"https://github.com/snowflakedb/snowflake-ml-python/pull/141"
|
|
264
|
-
)
|
|
265
|
-
|
|
266
263
|
kwargs_full: "SubmitInputArgs" = {
|
|
267
264
|
"stream": stream,
|
|
268
265
|
"prompt": self._as_prompt_input(turns),
|
|
269
266
|
"model": self._model,
|
|
267
|
+
"session": self._session,
|
|
270
268
|
**(kwargs or {}),
|
|
271
269
|
}
|
|
272
270
|
|
|
271
|
+
# TODO: get tools working
|
|
272
|
+
if tools:
|
|
273
|
+
raise ValueError("Snowflake does not currently support tools.")
|
|
274
|
+
|
|
275
|
+
if data_model is not None:
|
|
276
|
+
params = basemodel_to_param_schema(data_model)
|
|
277
|
+
opts = kwargs_full.get("options") or {}
|
|
278
|
+
opts["response_format"] = {
|
|
279
|
+
"type": "json",
|
|
280
|
+
"schema": {
|
|
281
|
+
"type": "object",
|
|
282
|
+
"properties": params["properties"],
|
|
283
|
+
"required": params["required"],
|
|
284
|
+
},
|
|
285
|
+
}
|
|
286
|
+
kwargs_full["options"] = opts
|
|
287
|
+
|
|
273
288
|
return kwargs_full
|
|
274
289
|
|
|
275
290
|
def stream_text(self, chunk):
|
|
@@ -312,10 +327,18 @@ class SnowflakeProvider(Provider["Completion", "CompletionChunk", "CompletionChu
|
|
|
312
327
|
res.append(
|
|
313
328
|
{
|
|
314
329
|
"role": turn.role,
|
|
315
|
-
"content": turn
|
|
330
|
+
"content": str(turn),
|
|
316
331
|
}
|
|
317
332
|
)
|
|
318
333
|
return res
|
|
319
334
|
|
|
320
335
|
def _as_turn(self, completion, has_data_model) -> Turn:
|
|
321
|
-
|
|
336
|
+
completion = cast(str, completion)
|
|
337
|
+
|
|
338
|
+
if has_data_model:
|
|
339
|
+
data = json.loads(completion)
|
|
340
|
+
contents = [ContentJson(value=data)]
|
|
341
|
+
else:
|
|
342
|
+
contents = [ContentText(text=completion)]
|
|
343
|
+
|
|
344
|
+
return Turn("assistant", contents)
|
chatlas/_utils.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import asyncio
|
|
3
4
|
import functools
|
|
4
5
|
import inspect
|
|
5
6
|
import os
|
|
6
7
|
import re
|
|
7
|
-
from typing import Awaitable, Callable, TypeVar, cast
|
|
8
|
+
from typing import Any, AsyncIterable, Awaitable, Callable, Iterable, TypeVar, cast
|
|
8
9
|
|
|
9
10
|
from ._typing_extensions import ParamSpec, TypeGuard
|
|
10
11
|
|
|
@@ -61,6 +62,40 @@ def is_async_callable(
|
|
|
61
62
|
return False
|
|
62
63
|
|
|
63
64
|
|
|
65
|
+
def wrap_async_iterable(x: Iterable[Any] | AsyncIterable[Any]) -> AsyncIterable[Any]:
|
|
66
|
+
"""
|
|
67
|
+
Given any iterable, return an async iterable. The async iterable will yield the
|
|
68
|
+
values of the original iterable, but will also yield control to the event loop
|
|
69
|
+
after each value. This is useful when you want to interleave processing with other
|
|
70
|
+
tasks, or when you want to simulate an async iterable from a regular iterable.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
if isinstance(x, AsyncIterable):
|
|
74
|
+
return x
|
|
75
|
+
|
|
76
|
+
if not isinstance(x, Iterable):
|
|
77
|
+
raise TypeError("wrap_async_iterable requires an Iterable object.")
|
|
78
|
+
|
|
79
|
+
return MakeIterableAsync(x)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class MakeIterableAsync:
|
|
83
|
+
def __init__(self, iterable: Iterable[Any]):
|
|
84
|
+
self.iterable = iterable
|
|
85
|
+
|
|
86
|
+
def __aiter__(self):
|
|
87
|
+
self.iterator = iter(self.iterable)
|
|
88
|
+
return self
|
|
89
|
+
|
|
90
|
+
async def __anext__(self):
|
|
91
|
+
try:
|
|
92
|
+
value = next(self.iterator)
|
|
93
|
+
await asyncio.sleep(0) # Yield control to the event loop
|
|
94
|
+
return value
|
|
95
|
+
except StopIteration:
|
|
96
|
+
raise StopAsyncIteration
|
|
97
|
+
|
|
98
|
+
|
|
64
99
|
T = TypeVar("T")
|
|
65
100
|
|
|
66
101
|
|
chatlas/_version.py
CHANGED
chatlas/types/openai/_submit.py
CHANGED
|
@@ -38,6 +38,16 @@ class SubmitInputArgs(TypedDict, total=False):
|
|
|
38
38
|
model: Union[
|
|
39
39
|
str,
|
|
40
40
|
Literal[
|
|
41
|
+
"gpt-4.1",
|
|
42
|
+
"gpt-4.1-mini",
|
|
43
|
+
"gpt-4.1-nano",
|
|
44
|
+
"gpt-4.1-2025-04-14",
|
|
45
|
+
"gpt-4.1-mini-2025-04-14",
|
|
46
|
+
"gpt-4.1-nano-2025-04-14",
|
|
47
|
+
"o4-mini",
|
|
48
|
+
"o4-mini-2025-04-16",
|
|
49
|
+
"o3",
|
|
50
|
+
"o3-2025-04-16",
|
|
41
51
|
"o3-mini",
|
|
42
52
|
"o3-mini-2025-01-31",
|
|
43
53
|
"o1",
|
|
@@ -119,7 +129,7 @@ class SubmitInputArgs(TypedDict, total=False):
|
|
|
119
129
|
openai.NotGiven,
|
|
120
130
|
]
|
|
121
131
|
seed: Union[int, None, openai.NotGiven]
|
|
122
|
-
service_tier: Union[Literal["auto", "default"], None, openai.NotGiven]
|
|
132
|
+
service_tier: Union[Literal["auto", "default", "flex"], None, openai.NotGiven]
|
|
123
133
|
stop: Union[str, None, list[str], openai.NotGiven]
|
|
124
134
|
store: Union[bool, None, openai.NotGiven]
|
|
125
135
|
stream: Union[Literal[False], None, Literal[True], openai.NotGiven]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chatlas
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: A simple and consistent interface for chatting with LLMs
|
|
5
5
|
Project-URL: Homepage, https://posit-dev.github.io/chatlas
|
|
6
6
|
Project-URL: Documentation, https://posit-dev.github.io/chatlas
|
|
@@ -18,7 +18,9 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.13
|
|
19
19
|
Requires-Python: >=3.9
|
|
20
20
|
Requires-Dist: jinja2
|
|
21
|
+
Requires-Dist: orjson
|
|
21
22
|
Requires-Dist: pydantic>=2.0
|
|
23
|
+
Requires-Dist: requests
|
|
22
24
|
Requires-Dist: rich
|
|
23
25
|
Provides-Extra: anthropic
|
|
24
26
|
Requires-Dist: anthropic; extra == 'anthropic'
|
|
@@ -26,9 +28,13 @@ Provides-Extra: azure-openai
|
|
|
26
28
|
Requires-Dist: openai; extra == 'azure-openai'
|
|
27
29
|
Provides-Extra: bedrock-anthropic
|
|
28
30
|
Requires-Dist: anthropic[bedrock]; extra == 'bedrock-anthropic'
|
|
31
|
+
Provides-Extra: databricks
|
|
32
|
+
Requires-Dist: databricks-sdk[openai]; extra == 'databricks'
|
|
29
33
|
Provides-Extra: dev
|
|
30
34
|
Requires-Dist: anthropic[bedrock]; extra == 'dev'
|
|
35
|
+
Requires-Dist: databricks-sdk; extra == 'dev'
|
|
31
36
|
Requires-Dist: google-genai>=1.2.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: htmltools; extra == 'dev'
|
|
32
38
|
Requires-Dist: matplotlib; extra == 'dev'
|
|
33
39
|
Requires-Dist: numpy>1.24.4; extra == 'dev'
|
|
34
40
|
Requires-Dist: openai; extra == 'dev'
|
|
@@ -37,6 +43,7 @@ Requires-Dist: python-dotenv; extra == 'dev'
|
|
|
37
43
|
Requires-Dist: ruff>=0.6.5; extra == 'dev'
|
|
38
44
|
Requires-Dist: shiny; extra == 'dev'
|
|
39
45
|
Requires-Dist: snowflake-ml-python; extra == 'dev'
|
|
46
|
+
Requires-Dist: tenacity; extra == 'dev'
|
|
40
47
|
Requires-Dist: tiktoken; extra == 'dev'
|
|
41
48
|
Requires-Dist: torch; (python_version <= '3.11') and extra == 'dev'
|
|
42
49
|
Provides-Extra: docs
|
|
@@ -122,6 +129,7 @@ It also supports the following enterprise cloud providers:
|
|
|
122
129
|
|
|
123
130
|
* AWS Bedrock: [`ChatBedrockAnthropic()`](https://posit-dev.github.io/chatlas/reference/ChatBedrockAnthropic.html).
|
|
124
131
|
* Azure OpenAI: [`ChatAzureOpenAI()`](https://posit-dev.github.io/chatlas/reference/ChatAzureOpenAI.html).
|
|
132
|
+
* Databricks: [`ChatDatabricks()`](https://posit-dev.github.io/chatlas/reference/ChatDatabricks.html).
|
|
125
133
|
* Snowflake Cortex: [`ChatSnowflake()`](https://posit-dev.github.io/chatlas/reference/ChatSnowflake.html).
|
|
126
134
|
* Vertex AI: [`ChatVertex()`](https://posit-dev.github.io/chatlas/reference/ChatVertex.html).
|
|
127
135
|
|
|
@@ -281,6 +289,26 @@ chat.extract_data(
|
|
|
281
289
|
|
|
282
290
|
Learn more in the [structured data article](https://posit-dev.github.io/chatlas/structured-data.html)
|
|
283
291
|
|
|
292
|
+
### Multi-modal input
|
|
293
|
+
|
|
294
|
+
Attach images and pdfs when submitting input to using any one of the `content_*` functions.
|
|
295
|
+
|
|
296
|
+
```python
|
|
297
|
+
from chatlas import content_image_url
|
|
298
|
+
|
|
299
|
+
chat.chat(
|
|
300
|
+
content_image_url("https://www.python.org/static/img/python-logo.png"),
|
|
301
|
+
"What do you see in this image?"
|
|
302
|
+
)
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
```
|
|
306
|
+
This image displays the logo of the Python programming language. It features the word "python" alongside the distinctive two snake heads logo, which is colored in blue and yellow.
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
Learn more in the [content reference pages](https://posit-dev.github.io/chatlas/reference/content_image_url.html) for more details on the available content types.
|
|
310
|
+
|
|
311
|
+
|
|
284
312
|
### Export chat
|
|
285
313
|
|
|
286
314
|
Easily get a full markdown or HTML export of a conversation:
|
|
@@ -1,30 +1,31 @@
|
|
|
1
|
-
chatlas/__init__.py,sha256=
|
|
2
|
-
chatlas/_anthropic.py,sha256=
|
|
3
|
-
chatlas/_auto.py,sha256=
|
|
4
|
-
chatlas/_chat.py,sha256=
|
|
5
|
-
chatlas/_content.py,sha256=
|
|
1
|
+
chatlas/__init__.py,sha256=5bHHZOdSM84VUD1WlUYH7vYxGiHygYEoRsQzGHHDXXk,1531
|
|
2
|
+
chatlas/_anthropic.py,sha256=VAtzRcrWPVe38wBBtDapxURISF2qn2yd6wg_8VY94Lk,24994
|
|
3
|
+
chatlas/_auto.py,sha256=HsAvVwpSOkI9fdC35YX8beaE2IBnWLWTzOzu0ny951o,6129
|
|
4
|
+
chatlas/_chat.py,sha256=wTkXu_AmL2frIHy-JZveuY44BigkrG21_06beyD3pIw,52691
|
|
5
|
+
chatlas/_content.py,sha256=VW1iKOWlzeoOjTg_TNQTj1zlmdWbDXqTjBy3fxddhdc,15767
|
|
6
6
|
chatlas/_content_image.py,sha256=EUK6wAint-JatLsiwvaPDu4D3W-NcIsDCkzABkXgfDg,8304
|
|
7
7
|
chatlas/_content_pdf.py,sha256=cffeuJxzhUDukQ-Srkmpy62M8X12skYpU_FVq-Wvya4,2420
|
|
8
|
-
chatlas/
|
|
8
|
+
chatlas/_databricks.py,sha256=G87AB6qWGxIlIP8tc6iHeaMpjXe47FuVZ00anPoM9ZI,4919
|
|
9
|
+
chatlas/_display.py,sha256=wyQzSc6z1VqrJfkTLkw1wQcti9s1Pr4qT8UxFJESn4U,4664
|
|
9
10
|
chatlas/_github.py,sha256=8_vvUIBCprgrQ5UItky5yETfEQPG2fCMM57ga77p28E,4377
|
|
10
|
-
chatlas/_google.py,sha256=
|
|
11
|
+
chatlas/_google.py,sha256=FfBnkXRtdJiBTViOqOg7qoConcRPLAKqWhUYKcfvhO4,19356
|
|
11
12
|
chatlas/_groq.py,sha256=iuFvxeXkq81sDHxVV9zbVHjf2ZuNT94P-XkuXvqtGms,4160
|
|
12
13
|
chatlas/_interpolate.py,sha256=ykwLP3x-ya9Q33U4knSU75dtk6pzJAeythEEIW-43Pc,3631
|
|
13
14
|
chatlas/_live_render.py,sha256=UMZltE35LxziDKPMEeDwQ9meZ95SeqwhJi7j-y9pcro,4004
|
|
14
15
|
chatlas/_logging.py,sha256=7a20sAl1PkW1qBNrfd_ieUbQXV8Gf4Vuf0Wn62LNBmk,2290
|
|
15
16
|
chatlas/_merge.py,sha256=SGj_BetgA7gaOqSBKOhYmW3CYeQKTEehFrXvx3y4OYE,3924
|
|
16
|
-
chatlas/_ollama.py,sha256=
|
|
17
|
-
chatlas/_openai.py,sha256=
|
|
17
|
+
chatlas/_ollama.py,sha256=np7s43abaNKt4eSygerHugvtzHjCyOQjSo0ZIRkE8Yc,3769
|
|
18
|
+
chatlas/_openai.py,sha256=AIYZ6yc_euymi0OSE0ccPdA2nJLP-8wJSVSyPHckcBw,24653
|
|
18
19
|
chatlas/_perplexity.py,sha256=j-jfOIYefZC5XzGjmya9GCCGQN003cRmiAv6vmo0rTQ,4454
|
|
19
20
|
chatlas/_provider.py,sha256=YmdBbz_u5aP_kBxl6s26OPiSnWG_vZ_fvf9L2qvBmyI,3809
|
|
20
|
-
chatlas/_snowflake.py,sha256=
|
|
21
|
+
chatlas/_snowflake.py,sha256=xlDdaM-YCmz3Y8KU6jxdCICuS-H4XLpQBHjqnaiEqKk,11576
|
|
21
22
|
chatlas/_tokens.py,sha256=3W3EPUp9eWXUiwuzJwEPBv43AUznbK46pm59Htti7z4,2392
|
|
22
23
|
chatlas/_tokens_old.py,sha256=L9d9oafrXvEx2u4nIn_Jjn7adnQyLBnYBuPwJUE8Pl8,5005
|
|
23
24
|
chatlas/_tools.py,sha256=-qt4U1AFkebQoX9kpsBy5QXK8a2PpHX6Amgm44gcQ68,4113
|
|
24
25
|
chatlas/_turn.py,sha256=7pve6YmD-L4c7Oxd6_ZAPkDudJ8AMpa6pP-pSroA1dM,5067
|
|
25
26
|
chatlas/_typing_extensions.py,sha256=YdzmlyPSBpIEcsOkoz12e6jETT1XEMV2Q72haE4cfwY,1036
|
|
26
|
-
chatlas/_utils.py,sha256=
|
|
27
|
-
chatlas/_version.py,sha256=
|
|
27
|
+
chatlas/_utils.py,sha256=lli8ChbPUwEPebW8AoOoNoqiA95SVtoW2gb6ymj9gw4,4028
|
|
28
|
+
chatlas/_version.py,sha256=itvIHlqPKoO_13qf_yPD2pmcp0U4z1s19vvBGZM927Q,511
|
|
28
29
|
chatlas/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
30
|
chatlas/types/__init__.py,sha256=P_EDL4eqsigKwB-u2qRmKlYQS5Y65m7oWjGC3cYmxO4,719
|
|
30
31
|
chatlas/types/anthropic/__init__.py,sha256=OwubA-DPHYpYo0XyRyAFwftOI0mOxtHzAyhUSLcDx54,417
|
|
@@ -37,9 +38,9 @@ chatlas/types/google/_submit.py,sha256=b-ZqMvI551Ia7pFlWdqUQJjov3neHmVwLFw-P2bgU
|
|
|
37
38
|
chatlas/types/openai/__init__.py,sha256=Q2RAr1bSH1nHsxICK05nAmKmxdhKmhbBkWD_XHiVSrI,411
|
|
38
39
|
chatlas/types/openai/_client.py,sha256=YGm_EHtRSSHeeOZe-CV7oNvMJpEblEta3UTuU7lSRO8,754
|
|
39
40
|
chatlas/types/openai/_client_azure.py,sha256=jx8D_p46CLDGzTP-k-TtGzj-f3junj6or-86m8DD_0w,858
|
|
40
|
-
chatlas/types/openai/_submit.py,sha256=
|
|
41
|
+
chatlas/types/openai/_submit.py,sha256=R0PUgXmhywLzRT_C3DYCsfbHCB1mD7cMY3zd8q7E-PU,6574
|
|
41
42
|
chatlas/types/snowflake/__init__.py,sha256=NVKw_gLVnSlMNdE6BpikrQw8GV8LvIn5SR8eI8Afgbs,273
|
|
42
43
|
chatlas/types/snowflake/_submit.py,sha256=Fgcb2Z4mXYwAR2b7Kn3SdEYFlO4gJiUvkDJ3lDoN0IY,799
|
|
43
|
-
chatlas-0.
|
|
44
|
-
chatlas-0.
|
|
45
|
-
chatlas-0.
|
|
44
|
+
chatlas-0.7.0.dist-info/METADATA,sha256=rb2oYfWSve7uDdoKouiZb2OAltvOMc-gXfucQRJ4skY,15425
|
|
45
|
+
chatlas-0.7.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
46
|
+
chatlas-0.7.0.dist-info/RECORD,,
|
|
File without changes
|