chainlit 0.6.3__tar.gz → 0.6.401__tar.gz

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 chainlit might be problematic. Click here for more details.

Files changed (64) hide show
  1. {chainlit-0.6.3 → chainlit-0.6.401}/PKG-INFO +6 -5
  2. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/__init__.py +38 -1
  3. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/cache.py +6 -9
  4. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/cli/deploy.py +2 -2
  5. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/client/base.py +2 -1
  6. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/client/cloud.py +10 -8
  7. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/client/local.py +4 -1
  8. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/client/utils.py +4 -2
  9. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/config.py +22 -1
  10. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/context.py +1 -1
  11. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/db/prisma/schema.prisma +2 -1
  12. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/element.py +6 -1
  13. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/emitter.py +6 -1
  14. chainlit-0.6.401/chainlit/frontend/dist/assets/index-69562d52.js +543 -0
  15. chainlit-0.6.3/chainlit/frontend/dist/assets/index-34600e45.js → chainlit-0.6.401/chainlit/frontend/dist/assets/index-ace9588d.js +1 -1
  16. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/frontend/dist/index.html +1 -1
  17. chainlit-0.6.401/chainlit/haystack/__init__.py +6 -0
  18. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/input_widget.py +35 -0
  19. chainlit-0.6.401/chainlit/langchain/__init__.py +6 -0
  20. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/langchain/callbacks.py +98 -30
  21. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/langflow/__init__.py +5 -10
  22. chainlit-0.6.401/chainlit/llama_index/__init__.py +6 -0
  23. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/llama_index/callbacks.py +16 -8
  24. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/message.py +17 -4
  25. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/playground/config.py +14 -14
  26. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/playground/providers/__init__.py +1 -0
  27. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/playground/providers/huggingface.py +3 -1
  28. chainlit-0.6.401/chainlit/playground/providers/langchain.py +87 -0
  29. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/playground/providers/openai.py +2 -2
  30. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/prompt.py +8 -1
  31. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/server.py +9 -8
  32. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/socket.py +16 -1
  33. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/sync.py +3 -1
  34. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/types.py +12 -7
  35. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/utils.py +23 -0
  36. {chainlit-0.6.3 → chainlit-0.6.401}/pyproject.toml +6 -5
  37. chainlit-0.6.3/chainlit/frontend/dist/assets/index-87533cb5.js +0 -533
  38. chainlit-0.6.3/chainlit/haystack/__init__.py +0 -11
  39. chainlit-0.6.3/chainlit/langchain/__init__.py +0 -11
  40. chainlit-0.6.3/chainlit/llama_index/__init__.py +0 -11
  41. {chainlit-0.6.3 → chainlit-0.6.401}/README.md +0 -0
  42. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/__main__.py +0 -0
  43. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/action.py +0 -0
  44. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/chat_settings.py +0 -0
  45. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/cli/__init__.py +0 -0
  46. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/cli/auth.py +0 -0
  47. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/cli/utils.py +0 -0
  48. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/db/__init__.py +0 -0
  49. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/frontend/dist/assets/index-a6e13df6.css +0 -0
  50. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/frontend/dist/assets/logo_dark-bc7401f6.svg +0 -0
  51. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/frontend/dist/assets/logo_light-f19fc2ea.svg +0 -0
  52. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/frontend/dist/favicon.svg +0 -0
  53. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/haystack/callbacks.py +0 -0
  54. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/hello.py +0 -0
  55. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/logger.py +0 -0
  56. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/markdown.py +0 -0
  57. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/playground/__init__.py +0 -0
  58. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/playground/provider.py +0 -0
  59. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/playground/providers/anthropic.py +0 -0
  60. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/py.typed +0 -0
  61. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/session.py +0 -0
  62. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/telemetry.py +0 -0
  63. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/user_session.py +0 -0
  64. {chainlit-0.6.3 → chainlit-0.6.401}/chainlit/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: chainlit
3
- Version: 0.6.3
3
+ Version: 0.6.401
4
4
  Summary: A faster way to build chatbot UIs.
5
5
  Home-page: https://github.com/Chainlit/chainlit
6
6
  License: Apache-2.0 license
@@ -18,20 +18,21 @@ Requires-Dist: asyncer (>=0.0.2,<0.0.3)
18
18
  Requires-Dist: auth0-python (>=4.4.0,<5.0.0)
19
19
  Requires-Dist: click (>=8.1.3,<9.0.0)
20
20
  Requires-Dist: dataclasses_json (>=0.5.7,<0.6.0)
21
- Requires-Dist: fastapi (>=0.97.0,<0.98.0)
21
+ Requires-Dist: fastapi (>=0.99.0,<0.100.0)
22
22
  Requires-Dist: fastapi-socketio (>=0.0.10,<0.0.11)
23
23
  Requires-Dist: filetype (>=1.2.0,<2.0.0)
24
24
  Requires-Dist: lazify (>=0.4.0,<0.5.0)
25
25
  Requires-Dist: nest-asyncio (>=1.5.6,<2.0.0)
26
- Requires-Dist: prisma (>=0.9.0,<0.10.0)
26
+ Requires-Dist: packaging (>=23.1,<24.0)
27
+ Requires-Dist: prisma (>=0.10.0,<0.11.0)
27
28
  Requires-Dist: pydantic (>=1.10.8,<2.0.0)
28
29
  Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
29
30
  Requires-Dist: python-graphql-client (>=0.4.3,<0.5.0)
30
31
  Requires-Dist: syncer (>=2.0.3,<3.0.0)
31
32
  Requires-Dist: tomli (>=2.0.1,<3.0.0)
32
33
  Requires-Dist: uptrace (>=1.18.0,<2.0.0)
33
- Requires-Dist: uvicorn (>=0.22.0,<0.23.0)
34
- Requires-Dist: watchfiles (>=0.19.0,<0.20.0)
34
+ Requires-Dist: uvicorn (>=0.23.2,<0.24.0)
35
+ Requires-Dist: watchfiles (>=0.20.0,<0.21.0)
35
36
  Project-URL: Repository, https://github.com/Chainlit/chainlit
36
37
  Description-Content-Type: text/markdown
37
38
 
@@ -1,6 +1,6 @@
1
1
  import asyncio
2
2
  import os
3
- from typing import TYPE_CHECKING, Any, Callable, Dict, Optional
3
+ from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union
4
4
 
5
5
  from dotenv import load_dotenv
6
6
  from starlette.datastructures import Headers
@@ -13,6 +13,7 @@ if TYPE_CHECKING:
13
13
  AsyncLangchainCallbackHandler,
14
14
  )
15
15
  from chainlit.llama_index.callbacks import LlamaIndexCallbackHandler
16
+
16
17
  import chainlit.input_widget as input_widget
17
18
  from chainlit.action import Action
18
19
  from chainlit.cache import cache
@@ -35,6 +36,7 @@ from chainlit.logger import logger
35
36
  from chainlit.message import AskFileMessage, AskUserMessage, ErrorMessage, Message
36
37
  from chainlit.sync import make_async, run_sync
37
38
  from chainlit.telemetry import trace
39
+ from chainlit.types import FileSpec
38
40
  from chainlit.user_session import user_session
39
41
  from chainlit.utils import make_module_getattr, wrap_user_function
40
42
  from chainlit.version import __version__
@@ -176,6 +178,37 @@ def db_client_factory(
176
178
  return func
177
179
 
178
180
 
181
+ def on_file_upload(
182
+ accept: Union[List[str], Dict[str, List[str]]],
183
+ max_size_mb: int = 2,
184
+ max_files: int = 1,
185
+ ) -> Callable:
186
+ """
187
+ A decorator designed for handling spontaneously uploaded files.
188
+ This decorator is intended to be used with files that are uploaded on-the-fly.
189
+
190
+ Args:
191
+ accept (Union[List[str], Dict[str, List[str]]]): A list of accepted file extensions or a dictionary of extension lists per field.
192
+ type (Optional[str]): The type of upload, defaults to "file".
193
+ max_size_mb (Optional[int]): The maximum file size in megabytes, defaults to 2.
194
+ max_files (Optional[int]): The maximum number of files allowed to be uploaded, defaults to 1.
195
+
196
+ Returns:
197
+ Callable: The decorated function for handling spontaneous file uploads.
198
+ """
199
+
200
+ def decorator(func: Callable) -> Callable:
201
+ config.code.on_file_upload_config = FileSpec(
202
+ accept=accept,
203
+ max_size_mb=max_size_mb,
204
+ max_files=max_files,
205
+ )
206
+ config.code.on_file_upload = wrap_user_function(func)
207
+ return func
208
+
209
+ return decorator
210
+
211
+
179
212
  def sleep(duration: int):
180
213
  """
181
214
  Sleep for a given duration.
@@ -230,3 +263,7 @@ __all__ = [
230
263
  "LlamaIndexCallbackHandler",
231
264
  "HaystackAgentCallbackHandler",
232
265
  ]
266
+
267
+
268
+ def __dir__():
269
+ return __all__
@@ -5,17 +5,14 @@ from chainlit.config import config
5
5
  from chainlit.logger import logger
6
6
 
7
7
 
8
- def is_langchain_installed():
9
- from chainlit.langchain import LANGCHAIN_INSTALLED
10
-
11
- return LANGCHAIN_INSTALLED
12
-
13
-
14
8
  def init_lc_cache():
15
- use_cache = config.run.no_cache is False and config.run.ci is False
9
+ use_cache = config.project.cache is True and config.run.no_cache is False
16
10
 
17
- if use_cache and is_langchain_installed():
18
- import langchain
11
+ if use_cache:
12
+ try:
13
+ import langchain
14
+ except ImportError:
15
+ return
19
16
  from langchain.cache import SQLiteCache
20
17
 
21
18
  if config.project.lc_cache_path is not None:
@@ -57,7 +57,7 @@ def upload_tar_gz_archive(access_token: str, archive_path: str):
57
57
  json_res = res.json()
58
58
 
59
59
  upload_details = json_res["post"]
60
- permanent_url = json_res["permanentUrl"]
60
+ signedUrl = json_res["signedUrl"]
61
61
 
62
62
  files = {"file": open(archive_path, "rb")}
63
63
 
@@ -69,7 +69,7 @@ def upload_tar_gz_archive(access_token: str, archive_path: str):
69
69
  raise Exception(f"Failed to upload archive: {res.text}")
70
70
 
71
71
  url = f'{upload_details["url"]}/{upload_details["fields"]["key"]}'
72
- return permanent_url, url
72
+ return signedUrl, url
73
73
 
74
74
 
75
75
  def deploy(target: str):
@@ -53,6 +53,7 @@ class ElementDict(TypedDict):
53
53
  conversationId: Optional[str]
54
54
  type: ElementType
55
55
  url: str
56
+ objectKey: Optional[str]
56
57
  name: str
57
58
  display: ElementDisplay
58
59
  size: Optional[ElementSize]
@@ -145,7 +146,7 @@ class BaseDBClient(ABC):
145
146
  pass
146
147
 
147
148
  @abstractmethod
148
- async def upload_element(self, content: Union[bytes, str], mime: str) -> str:
149
+ async def upload_element(self, content: Union[bytes, str], mime: str) -> Dict:
149
150
  pass
150
151
 
151
152
  @abstractmethod
@@ -424,11 +424,12 @@ class CloudDBClient(BaseDBClient, GraphQLClient):
424
424
  return None
425
425
 
426
426
  mutation = """
427
- mutation ($conversationId: ID!, $type: String!, $url: String!, $name: String!, $display: String!, $forIds: [String!]!, $size: String, $language: String) {
428
- createElement(conversationId: $conversationId, type: $type, url: $url, name: $name, display: $display, size: $size, language: $language, forIds: $forIds) {
427
+ mutation ($conversationId: ID!, $type: String!, $name: String!, $display: String!, $forIds: [String!]!, $url: String, $objectKey: String, $size: String, $language: String) {
428
+ createElement(conversationId: $conversationId, type: $type, url: $url, objectKey: $objectKey, name: $name, display: $display, size: $size, language: $language, forIds: $forIds) {
429
429
  id,
430
430
  type,
431
431
  url,
432
+ objectKey,
432
433
  name,
433
434
  display,
434
435
  size,
@@ -471,7 +472,7 @@ class CloudDBClient(BaseDBClient, GraphQLClient):
471
472
 
472
473
  return res["data"]["updateElement"]
473
474
 
474
- async def upload_element(self, content: Union[bytes, str], mime: str) -> str:
475
+ async def upload_element(self, content: Union[bytes, str], mime: str) -> Dict:
475
476
  id = str(uuid.uuid4())
476
477
  body = {"projectId": self.project_id, "fileName": id, "contentType": mime}
477
478
 
@@ -486,11 +487,12 @@ class CloudDBClient(BaseDBClient, GraphQLClient):
486
487
  if not r.ok:
487
488
  reason = await r.text()
488
489
  logger.error(f"Failed to upload file: {reason}")
489
- return ""
490
+ return {"object_key": None, "url": None}
490
491
  json_res = await r.json()
491
492
 
492
493
  upload_details = json_res["post"]
493
- permanent_url = json_res["permanentUrl"]
494
+ object_key = upload_details["fields"]["key"]
495
+ signed_url = json_res["signedUrl"]
494
496
 
495
497
  form_data = aiohttp.FormData()
496
498
 
@@ -508,7 +510,7 @@ class CloudDBClient(BaseDBClient, GraphQLClient):
508
510
  if not upload_response.ok:
509
511
  reason = await upload_response.text()
510
512
  logger.error(f"Failed to upload file: {reason}")
511
- return ""
513
+ return {"object_key": None, "url": None}
512
514
 
513
- url = f'{upload_details["url"]}/{upload_details["fields"]["key"]}'
514
- return permanent_url
515
+ url = f'{upload_details["url"]}/{object_key}'
516
+ return {"object_key": object_key, "url": signed_url}
@@ -39,6 +39,9 @@ class LocalDBClient(BaseDBClient):
39
39
  # Sqlite doesn't support list of primitives, so we need to serialize it.
40
40
  variables["forIds"] = json.dumps(variables["forIds"])
41
41
 
42
+ if "streaming" in variables:
43
+ del variables["streaming"]
44
+
42
45
  def after_read(self, variables: Dict):
43
46
  if "prompt" in variables:
44
47
  # Sqlite doesn't support json fields, so we need to parse it.
@@ -288,7 +291,7 @@ class LocalDBClient(BaseDBClient):
288
291
  await out.flush()
289
292
 
290
293
  url = f"/files/{sub_path}"
291
- return url
294
+ return {"object_key": "", "url": url}
292
295
 
293
296
  async def set_human_feedback(self, message_id, feedback):
294
297
  from prisma.models import Message
@@ -1,6 +1,6 @@
1
1
  from typing import Dict, Optional
2
2
 
3
- from fastapi import Request
3
+ from fastapi import HTTPException, Request
4
4
  from starlette.datastructures import Headers
5
5
 
6
6
  from chainlit.client.base import BaseAuthClient, BaseDBClient, UserDict
@@ -30,7 +30,9 @@ async def get_auth_client(
30
30
  # Check if the user is a member of the project
31
31
  is_project_member = await auth_client.is_project_member()
32
32
  if not is_project_member:
33
- raise ConnectionRefusedError("User is not a member of the project")
33
+ raise HTTPException(
34
+ status_code=401, detail="User is not a member of the project"
35
+ )
34
36
 
35
37
  return auth_client
36
38
 
@@ -48,6 +48,15 @@ user_env = []
48
48
  # Duration (in seconds) during which the session is saved when the connection is lost
49
49
  session_timeout = 3600
50
50
 
51
+ # Enable third parties caching (e.g LangChain cache)
52
+ cache = false
53
+
54
+ # Follow symlink for asset mount (see https://github.com/Chainlit/chainlit/issues/317)
55
+ # follow_symlink = false
56
+
57
+ # Chainlit server address
58
+ # chainlit_server = ""
59
+
51
60
  [UI]
52
61
  # Name of the app and chatbot.
53
62
  name = "Chatbot"
@@ -90,7 +99,7 @@ generated_by = "{__version__}"
90
99
  """
91
100
 
92
101
  chainlit_prod_url = os.environ.get("CHAINLIT_PROD_URL")
93
- chainlit_server = "https://cloud.chainlit.io"
102
+ default_chainlit_server = "https://cloud.chainlit.io"
94
103
 
95
104
 
96
105
  DEFAULT_HOST = "0.0.0.0"
@@ -150,6 +159,7 @@ class CodeSettings:
150
159
  on_stop: Optional[Callable[[], Any]] = None
151
160
  on_chat_start: Optional[Callable[[], Any]] = None
152
161
  on_message: Optional[Callable[[str], Any]] = None
162
+ on_file_upload: Optional[Callable[[str], Any]] = None
153
163
  auth_client_factory: Optional[
154
164
  Callable[[Optional[Dict[str, str]], Optional[Headers]], "BaseAuthClient"]
155
165
  ] = None
@@ -194,6 +204,12 @@ class ProjectSettings(DataClassJsonMixin):
194
204
  local_fs_path: Optional[str] = None
195
205
  # Duration (in seconds) during which the session is saved when the connection is lost
196
206
  session_timeout: int = 3600
207
+ # Enable third parties caching (e.g LangChain cache)
208
+ cache: bool = False
209
+ # Follow symlink for asset mount (see https://github.com/Chainlit/chainlit/issues/317)
210
+ follow_symlink: bool = False
211
+ # Chainlit server address
212
+ chainlit_server: Optional[str] = None
197
213
 
198
214
 
199
215
  @dataclass()
@@ -308,6 +324,11 @@ def load_config():
308
324
 
309
325
  settings = load_settings()
310
326
 
327
+ chainlit_server = default_chainlit_server
328
+ project_settings = settings.get("project")
329
+ if project_settings and project_settings.chainlit_server:
330
+ chainlit_server = project_settings.chainlit_server
331
+
311
332
  config = ChainlitConfig(
312
333
  chainlit_server=chainlit_server,
313
334
  chainlit_prod_url=chainlit_prod_url,
@@ -47,4 +47,4 @@ def get_context() -> ChainlitContext:
47
47
  raise ChainlitContextException()
48
48
 
49
49
 
50
- context = LazyProxy(get_context, enable_cache=False)
50
+ context: ChainlitContext = LazyProxy(get_context, enable_cache=False)
@@ -32,7 +32,8 @@ model Element {
32
32
  conversationId String
33
33
  conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
34
34
  type String
35
- url String
35
+ objectKey String?
36
+ url String?
36
37
  name String
37
38
  display String
38
39
  size String?
@@ -30,6 +30,8 @@ class Element:
30
30
  name: Optional[str] = None
31
31
  # The URL of the element if already hosted somehwere else.
32
32
  url: Optional[str] = None
33
+ # The S3 object key.
34
+ object_key: Optional[str] = None
33
35
  # The local path of the element.
34
36
  path: Optional[str] = None
35
37
  # The byte content of the element.
@@ -58,6 +60,7 @@ class Element:
58
60
  "url": self.url or "",
59
61
  "name": self.name or "",
60
62
  "display": self.display,
63
+ "objectKey": getattr(self, "object_key", None),
61
64
  "size": getattr(self, "size", None),
62
65
  "language": getattr(self, "language", None),
63
66
  "forIds": getattr(self, "for_ids", None),
@@ -84,7 +87,9 @@ class Element:
84
87
  if self.type in mime_types
85
88
  else filetype.guess_mime(self.content)
86
89
  )
87
- self.url = await client.upload_element(content=self.content, mime=mime)
90
+ upload_res = await client.upload_element(content=self.content, mime=mime)
91
+ self.url = upload_res["url"]
92
+ self.object_key = upload_res["object_key"]
88
93
 
89
94
  if not self.persisted:
90
95
  element_dict = await client.create_element(self.to_dict())
@@ -6,7 +6,7 @@ from socketio.exceptions import TimeoutError
6
6
  from chainlit.client.base import BaseDBClient, MessageDict
7
7
  from chainlit.message import Message
8
8
  from chainlit.session import Session
9
- from chainlit.types import AskSpec
9
+ from chainlit.types import AskSpec, FileSpec
10
10
 
11
11
 
12
12
  class ChainlitEmitter:
@@ -69,6 +69,11 @@ class ChainlitEmitter:
69
69
 
70
70
  return self.emit("clear_ask", {})
71
71
 
72
+ def enable_file_upload(self, spec: FileSpec):
73
+ """Enable uploading file in the UI."""
74
+
75
+ return self.emit("enable_file_upload", spec.to_dict())
76
+
72
77
  async def process_user_message(self, message_dict: MessageDict) -> Message:
73
78
  # Temporary UUID generated by the frontend should use v4
74
79
  assert uuid.UUID(message_dict["id"]).version == 4