chainlit 1.0.0rc3__tar.gz → 1.0.100__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 (60) hide show
  1. {chainlit-1.0.0rc3 → chainlit-1.0.100}/PKG-INFO +3 -3
  2. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/__init__.py +14 -1
  3. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/auth.py +4 -3
  4. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/config.py +2 -6
  5. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/data/__init__.py +97 -24
  6. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/emitter.py +9 -5
  7. chainlit-1.0.100/chainlit/frontend/dist/assets/index-c4f40824.js +723 -0
  8. chainlit-1.0.0rc3/chainlit/frontend/dist/assets/react-plotly-c9578a93.js → chainlit-1.0.100/chainlit/frontend/dist/assets/react-plotly-259d6961.js +1 -1
  9. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/frontend/dist/index.html +1 -1
  10. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/haystack/callbacks.py +32 -6
  11. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/langchain/callbacks.py +8 -6
  12. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/llama_index/callbacks.py +13 -5
  13. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/message.py +1 -1
  14. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/oauth_providers.py +67 -0
  15. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/playground/config.py +2 -0
  16. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/playground/provider.py +1 -1
  17. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/playground/providers/__init__.py +1 -0
  18. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/playground/providers/anthropic.py +1 -1
  19. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/playground/providers/langchain.py +8 -7
  20. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/playground/providers/vertexai.py +51 -6
  21. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/server.py +35 -15
  22. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/session.py +5 -1
  23. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/socket.py +56 -18
  24. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/step.py +4 -4
  25. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/telemetry.py +2 -6
  26. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/types.py +1 -1
  27. {chainlit-1.0.0rc3 → chainlit-1.0.100}/pyproject.toml +7 -5
  28. chainlit-1.0.0rc3/chainlit/frontend/dist/assets/index-15bb372a.js +0 -697
  29. {chainlit-1.0.0rc3 → chainlit-1.0.100}/README.md +0 -0
  30. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/__main__.py +0 -0
  31. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/action.py +0 -0
  32. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/cache.py +0 -0
  33. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/chat_settings.py +0 -0
  34. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/cli/__init__.py +0 -0
  35. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/cli/utils.py +0 -0
  36. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/context.py +0 -0
  37. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/data/acl.py +0 -0
  38. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/element.py +0 -0
  39. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/frontend/dist/assets/index-d088547c.css +0 -0
  40. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/frontend/dist/assets/logo_dark-bc7401f6.svg +0 -0
  41. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/frontend/dist/assets/logo_light-f19fc2ea.svg +0 -0
  42. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/frontend/dist/favicon.svg +0 -0
  43. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/haystack/__init__.py +0 -0
  44. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/hello.py +0 -0
  45. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/input_widget.py +0 -0
  46. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/langchain/__init__.py +0 -0
  47. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/langflow/__init__.py +0 -0
  48. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/llama_index/__init__.py +0 -0
  49. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/logger.py +0 -0
  50. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/markdown.py +0 -0
  51. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/playground/__init__.py +0 -0
  52. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/playground/providers/huggingface.py +0 -0
  53. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/playground/providers/openai.py +0 -0
  54. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/py.typed +0 -0
  55. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/secret.py +0 -0
  56. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/sync.py +0 -0
  57. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/user.py +0 -0
  58. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/user_session.py +0 -0
  59. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/utils.py +0 -0
  60. {chainlit-1.0.0rc3 → chainlit-1.0.100}/chainlit/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: chainlit
3
- Version: 1.0.0rc3
3
+ Version: 1.0.100
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
@@ -15,7 +15,6 @@ Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Programming Language :: Python :: 3.12
16
16
  Requires-Dist: aiofiles (>=23.1.0,<24.0.0)
17
17
  Requires-Dist: asyncer (>=0.0.2,<0.0.3)
18
- Requires-Dist: chainlit_client (==0.1.0rc7)
19
18
  Requires-Dist: click (>=8.1.3,<9.0.0)
20
19
  Requires-Dist: dataclasses_json (>=0.5.7,<0.6.0)
21
20
  Requires-Dist: fastapi (>=0.100,<0.101)
@@ -23,6 +22,7 @@ Requires-Dist: fastapi-socketio (>=0.0.10,<0.0.11)
23
22
  Requires-Dist: filetype (>=1.2.0,<2.0.0)
24
23
  Requires-Dist: httpx (>=0.23.0,<0.25.0)
25
24
  Requires-Dist: lazify (>=0.4.0,<0.5.0)
25
+ Requires-Dist: literalai (==0.0.102)
26
26
  Requires-Dist: nest-asyncio (>=1.5.6,<2.0.0)
27
27
  Requires-Dist: packaging (>=23.1,<24.0)
28
28
  Requires-Dist: pydantic (>=1,<3)
@@ -32,7 +32,7 @@ Requires-Dist: python-graphql-client (>=0.4.3,<0.5.0)
32
32
  Requires-Dist: python-multipart (>=0.0.6,<0.0.7)
33
33
  Requires-Dist: syncer (>=2.0.3,<3.0.0)
34
34
  Requires-Dist: tomli (>=2.0.1,<3.0.0)
35
- Requires-Dist: uptrace (>=1.18.0,<2.0.0)
35
+ Requires-Dist: uptrace (>=1.22.0,<2.0.0)
36
36
  Requires-Dist: uvicorn (>=0.23.2,<0.24.0)
37
37
  Requires-Dist: watchfiles (>=0.20.0,<0.21.0)
38
38
  Project-URL: Repository, https://github.com/Chainlit/chainlit
@@ -7,6 +7,7 @@ env_found = load_dotenv(dotenv_path=os.path.join(os.getcwd(), ".env"))
7
7
  import asyncio
8
8
  from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional
9
9
 
10
+ from fastapi import Request, Response
10
11
  from starlette.datastructures import Headers
11
12
 
12
13
  if TYPE_CHECKING:
@@ -54,7 +55,7 @@ from chainlit.user import PersistedUser, User
54
55
  from chainlit.user_session import user_session
55
56
  from chainlit.utils import make_module_getattr, wrap_user_function
56
57
  from chainlit.version import __version__
57
- from chainlit_client import ChatGeneration, CompletionGeneration, GenerationMessage
58
+ from literalai import ChatGeneration, CompletionGeneration, GenerationMessage
58
59
 
59
60
  if env_found:
60
61
  logger.info("Loaded .env file")
@@ -127,6 +128,17 @@ def oauth_callback(
127
128
  return func
128
129
 
129
130
 
131
+ @trace
132
+ def on_logout(func: Callable[[Request, Response], Any]) -> Callable:
133
+ """
134
+ Function called when the user logs out.
135
+ Takes the FastAPI request and response as parameters.
136
+ """
137
+
138
+ config.code.on_logout = wrap_user_function(func)
139
+ return func
140
+
141
+
130
142
  @trace
131
143
  def on_message(func: Callable) -> Callable:
132
144
  """
@@ -320,6 +332,7 @@ __all__ = [
320
332
  "ChatGeneration",
321
333
  "CompletionGeneration",
322
334
  "GenerationMessage",
335
+ "on_logout",
323
336
  "on_chat_start",
324
337
  "on_chat_end",
325
338
  "on_chat_resume",
@@ -20,7 +20,7 @@ def get_jwt_secret():
20
20
  def ensure_jwt_secret():
21
21
  if require_login() and get_jwt_secret() is None:
22
22
  raise ValueError(
23
- "You must provide a JWT secret in the environment to use password authentication. Run `chainlit create-secret` to generate one."
23
+ "You must provide a JWT secret in the environment to use authentication. Run `chainlit create-secret` to generate one."
24
24
  )
25
25
 
26
26
 
@@ -30,7 +30,8 @@ def is_oauth_enabled():
30
30
 
31
31
  def require_login():
32
32
  return (
33
- config.code.password_auth_callback is not None
33
+ bool(os.environ.get("CHAINLIT_CUSTOM_AUTH"))
34
+ or config.code.password_auth_callback is not None
34
35
  or config.code.header_auth_callback is not None
35
36
  or is_oauth_enabled()
36
37
  )
@@ -74,7 +75,7 @@ async def authenticate_user(token: str = Depends(reuseable_oauth)):
74
75
  try:
75
76
  persisted_user = await data_layer.get_user(user.identifier)
76
77
  except Exception as e:
77
- raise HTTPException(status_code=500, detail=str(e))
78
+ return user
78
79
  if persisted_user == None:
79
80
  raise HTTPException(status_code=401, detail="User does not exist")
80
81
 
@@ -15,6 +15,7 @@ if TYPE_CHECKING:
15
15
  from chainlit.action import Action
16
16
  from chainlit.types import ChatProfile, ThreadDict
17
17
  from chainlit.user import User
18
+ from fastapi import Request, Response
18
19
 
19
20
 
20
21
  BACKEND_ROOT = os.path.dirname(__file__)
@@ -118,8 +119,6 @@ hide_cot = false
118
119
  generated_by = "{__version__}"
119
120
  """
120
121
 
121
- chainlit_prod_url = os.environ.get("CHAINLIT_PROD_URL")
122
-
123
122
 
124
123
  DEFAULT_HOST = "0.0.0.0"
125
124
  DEFAULT_PORT = 8000
@@ -200,6 +199,7 @@ class CodeSettings:
200
199
  oauth_callback: Optional[
201
200
  Callable[[str, str, Dict[str, str], "User"], Optional["User"]]
202
201
  ] = None
202
+ on_logout: Optional[Callable[["Request", "Response"], Any]] = None
203
203
  on_stop: Optional[Callable[[], Any]] = None
204
204
  on_chat_start: Optional[Callable[[], Any]] = None
205
205
  on_chat_end: Optional[Callable[[], Any]] = None
@@ -234,9 +234,6 @@ class ChainlitConfig:
234
234
  root = APP_ROOT
235
235
  # Chainlit server URL. Used only for cloud features
236
236
  chainlit_server: str
237
- # The url of the deployed app. Only set if the app is deployed.
238
- chainlit_prod_url = chainlit_prod_url
239
-
240
237
  run: RunSettings
241
238
  features: FeaturesSettings
242
239
  ui: UISettings
@@ -347,7 +344,6 @@ def load_config():
347
344
 
348
345
  config = ChainlitConfig(
349
346
  chainlit_server=chainlit_server,
350
- chainlit_prod_url=chainlit_prod_url,
351
347
  run=RunSettings(),
352
348
  **settings,
353
349
  )
@@ -1,20 +1,21 @@
1
1
  import functools
2
2
  import os
3
3
  from collections import deque
4
- from typing import TYPE_CHECKING, Dict, List, Optional
4
+ from typing import TYPE_CHECKING, Dict, List, Optional, Union
5
5
 
6
+ import aiofiles
6
7
  from chainlit.config import config
7
8
  from chainlit.context import context
8
9
  from chainlit.logger import logger
9
10
  from chainlit.session import WebsocketSession
10
11
  from chainlit.types import Feedback, Pagination, ThreadDict, ThreadFilter
11
12
  from chainlit.user import PersistedUser, User, UserDict
12
- from chainlit_client import Attachment
13
- from chainlit_client import Feedback as ClientFeedback
14
- from chainlit_client import PageInfo, PaginatedResponse
15
- from chainlit_client import Step as ClientStep
16
- from chainlit_client.thread import NumberListFilter, StringFilter, StringListFilter
17
- from chainlit_client.thread import ThreadFilter as ClientThreadFilter
13
+ from literalai import Attachment
14
+ from literalai import Feedback as ClientFeedback
15
+ from literalai import PageInfo, PaginatedResponse
16
+ from literalai import Step as ClientStep
17
+ from literalai.thread import NumberListFilter, StringFilter, StringListFilter
18
+ from literalai.thread import ThreadFilter as ClientThreadFilter
18
19
 
19
20
  if TYPE_CHECKING:
20
21
  from chainlit.element import Element, ElementDict
@@ -112,14 +113,29 @@ class BaseDataLayer:
112
113
  ):
113
114
  pass
114
115
 
116
+ async def create_user_session(
117
+ self,
118
+ id: str,
119
+ started_at: str,
120
+ anon_user_id: str,
121
+ user_id: Optional[str],
122
+ ) -> Dict:
123
+ return {}
124
+
125
+ async def update_user_session(
126
+ self, id: str, is_interactive: bool, ended_at: Optional[str]
127
+ ) -> Dict:
128
+ return {}
129
+
130
+ async def delete_user_session(self, id: str) -> bool:
131
+ return True
132
+
115
133
 
116
134
  class ChainlitDataLayer:
117
- def __init__(
118
- self, api_key: str, chainlit_server: Optional[str] = "https://cloud.chainlit.io"
119
- ):
120
- from chainlit_client import ChainlitClient
135
+ def __init__(self, api_key: str, server: Optional[str]):
136
+ from literalai import LiteralClient
121
137
 
122
- self.client = ChainlitClient(api_key=api_key, url=chainlit_server)
138
+ self.client = LiteralClient(api_key=api_key, url=server)
123
139
  logger.info("Chainlit data layer initialized")
124
140
 
125
141
  def attachment_to_element_dict(self, attachment: Attachment) -> "ElementDict":
@@ -194,6 +210,8 @@ class ChainlitDataLayer:
194
210
  _user = await self.client.api.create_user(
195
211
  identifier=user.identifier, metadata=user.metadata
196
212
  )
213
+ elif _user.id:
214
+ await self.client.api.update_user(id=_user.id, metadata=user.metadata)
197
215
  return PersistedUser(
198
216
  id=_user.id or "",
199
217
  identifier=_user.identifier or "",
@@ -237,15 +255,38 @@ class ChainlitDataLayer:
237
255
  if not element.for_id:
238
256
  return
239
257
 
240
- await self.client.api.create_attachment(
241
- thread_id=element.thread_id,
242
- step_id=element.for_id,
243
- mime=element.mime,
244
- name=element.name,
245
- url=element.url,
246
- content=element.content,
247
- path=element.path,
248
- metadata=metadata,
258
+ object_key = None
259
+
260
+ if not element.url:
261
+ if element.path:
262
+ async with aiofiles.open(element.path, "rb") as f:
263
+ content = await f.read() # type: Union[bytes, str]
264
+ elif element.content:
265
+ content = element.content
266
+ else:
267
+ raise ValueError("Either path or content must be provided")
268
+ uploaded = await self.client.api.upload_file(
269
+ content=content, mime=element.mime, thread_id=element.thread_id
270
+ )
271
+ object_key = uploaded["object_key"]
272
+
273
+ await self.client.api.send_steps(
274
+ [
275
+ {
276
+ "id": element.for_id,
277
+ "threadId": element.thread_id,
278
+ "attachments": [
279
+ {
280
+ "id": element.id,
281
+ "name": element.name,
282
+ "metadata": metadata,
283
+ "mime": element.mime,
284
+ "url": element.url,
285
+ "objectKey": object_key,
286
+ }
287
+ ],
288
+ }
289
+ ]
249
290
  )
250
291
 
251
292
  async def get_element(
@@ -342,6 +383,8 @@ class ChainlitDataLayer:
342
383
  continue
343
384
  for attachment in step.attachments:
344
385
  elements.append(self.attachment_to_element_dict(attachment))
386
+ if not config.features.prompt_playground and step.generation:
387
+ step.generation = None
345
388
  steps.append(self.step_to_step_dict(step))
346
389
 
347
390
  user = None # type: Optional["UserDict"]
@@ -377,10 +420,40 @@ class ChainlitDataLayer:
377
420
  tags=tags,
378
421
  )
379
422
 
423
+ async def create_user_session(
424
+ self,
425
+ id: str,
426
+ started_at: str,
427
+ anon_user_id: str,
428
+ user_id: Optional[str],
429
+ ) -> Dict:
430
+ existing_session = await self.client.api.get_user_session(id=id)
431
+ if existing_session:
432
+ return existing_session
433
+ session = await self.client.api.create_user_session(
434
+ id=id,
435
+ started_at=started_at,
436
+ participant_identifier=user_id,
437
+ anon_participant_identifier=anon_user_id,
438
+ )
439
+ return session
440
+
441
+ async def update_user_session(
442
+ self, id: str, is_interactive: bool, ended_at: Optional[str]
443
+ ) -> Dict:
444
+ session = await self.client.api.update_user_session(
445
+ id=id, is_interactive=is_interactive, ended_at=ended_at
446
+ )
447
+ return session
448
+
449
+ async def delete_user_session(self, id: str) -> bool:
450
+ await self.client.api.delete_user_session(id=id)
451
+ return True
452
+
380
453
 
381
- if api_key := os.environ.get("CHAINLIT_API_KEY"):
382
- chainlit_server = os.environ.get("CHAINLIT_SERVER")
383
- _data_layer = ChainlitDataLayer(api_key=api_key, chainlit_server=chainlit_server)
454
+ if api_key := os.environ.get("LITERAL_API_KEY"):
455
+ server = os.environ.get("LITERAL_SERVER")
456
+ _data_layer = ChainlitDataLayer(api_key=api_key, server=server)
384
457
 
385
458
 
386
459
  def get_data_layer():
@@ -5,6 +5,7 @@ from typing import Any, Dict, List, Optional, Union, cast
5
5
 
6
6
  from chainlit.data import get_data_layer
7
7
  from chainlit.element import Element, File
8
+ from chainlit.logger import logger
8
9
  from chainlit.message import Message
9
10
  from chainlit.session import BaseSession, WebsocketSession
10
11
  from chainlit.step import StepDict
@@ -172,11 +173,14 @@ class ChainlitEmitter(BaseChainlitEmitter):
172
173
  user_id = self.session.user.id
173
174
  else:
174
175
  user_id = None
175
- await data_layer.update_thread(
176
- thread_id=self.session.thread_id,
177
- user_id=user_id,
178
- metadata={"name": interaction},
179
- )
176
+ try:
177
+ await data_layer.update_thread(
178
+ thread_id=self.session.thread_id,
179
+ user_id=user_id,
180
+ metadata={"name": interaction},
181
+ )
182
+ except Exception as e:
183
+ logger.error(f"Error updating thread: {e}")
180
184
  await self.session.flush_method_queue()
181
185
 
182
186
  async def init_thread(self, interaction: str):