chainlit 2.7.0__py3-none-any.whl → 2.7.1__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 chainlit might be problematic. Click here for more details.

Files changed (85) hide show
  1. {chainlit-2.7.0.dist-info → chainlit-2.7.1.dist-info}/METADATA +1 -1
  2. chainlit-2.7.1.dist-info/RECORD +4 -0
  3. chainlit/__init__.py +0 -207
  4. chainlit/__main__.py +0 -4
  5. chainlit/_utils.py +0 -8
  6. chainlit/action.py +0 -33
  7. chainlit/auth/__init__.py +0 -95
  8. chainlit/auth/cookie.py +0 -197
  9. chainlit/auth/jwt.py +0 -42
  10. chainlit/cache.py +0 -45
  11. chainlit/callbacks.py +0 -433
  12. chainlit/chat_context.py +0 -64
  13. chainlit/chat_settings.py +0 -34
  14. chainlit/cli/__init__.py +0 -235
  15. chainlit/config.py +0 -621
  16. chainlit/context.py +0 -112
  17. chainlit/data/__init__.py +0 -111
  18. chainlit/data/acl.py +0 -19
  19. chainlit/data/base.py +0 -107
  20. chainlit/data/chainlit_data_layer.py +0 -687
  21. chainlit/data/dynamodb.py +0 -616
  22. chainlit/data/literalai.py +0 -501
  23. chainlit/data/sql_alchemy.py +0 -741
  24. chainlit/data/storage_clients/__init__.py +0 -0
  25. chainlit/data/storage_clients/azure.py +0 -84
  26. chainlit/data/storage_clients/azure_blob.py +0 -94
  27. chainlit/data/storage_clients/base.py +0 -28
  28. chainlit/data/storage_clients/gcs.py +0 -101
  29. chainlit/data/storage_clients/s3.py +0 -88
  30. chainlit/data/utils.py +0 -29
  31. chainlit/discord/__init__.py +0 -6
  32. chainlit/discord/app.py +0 -364
  33. chainlit/element.py +0 -454
  34. chainlit/emitter.py +0 -450
  35. chainlit/hello.py +0 -12
  36. chainlit/input_widget.py +0 -182
  37. chainlit/langchain/__init__.py +0 -6
  38. chainlit/langchain/callbacks.py +0 -682
  39. chainlit/langflow/__init__.py +0 -25
  40. chainlit/llama_index/__init__.py +0 -6
  41. chainlit/llama_index/callbacks.py +0 -206
  42. chainlit/logger.py +0 -16
  43. chainlit/markdown.py +0 -57
  44. chainlit/mcp.py +0 -99
  45. chainlit/message.py +0 -619
  46. chainlit/mistralai/__init__.py +0 -50
  47. chainlit/oauth_providers.py +0 -835
  48. chainlit/openai/__init__.py +0 -53
  49. chainlit/py.typed +0 -0
  50. chainlit/secret.py +0 -9
  51. chainlit/semantic_kernel/__init__.py +0 -111
  52. chainlit/server.py +0 -1616
  53. chainlit/session.py +0 -304
  54. chainlit/sidebar.py +0 -55
  55. chainlit/slack/__init__.py +0 -6
  56. chainlit/slack/app.py +0 -427
  57. chainlit/socket.py +0 -381
  58. chainlit/step.py +0 -490
  59. chainlit/sync.py +0 -43
  60. chainlit/teams/__init__.py +0 -6
  61. chainlit/teams/app.py +0 -348
  62. chainlit/translations/bn.json +0 -214
  63. chainlit/translations/el-GR.json +0 -214
  64. chainlit/translations/en-US.json +0 -214
  65. chainlit/translations/fr-FR.json +0 -214
  66. chainlit/translations/gu.json +0 -214
  67. chainlit/translations/he-IL.json +0 -214
  68. chainlit/translations/hi.json +0 -214
  69. chainlit/translations/ja.json +0 -214
  70. chainlit/translations/kn.json +0 -214
  71. chainlit/translations/ml.json +0 -214
  72. chainlit/translations/mr.json +0 -214
  73. chainlit/translations/nl.json +0 -214
  74. chainlit/translations/ta.json +0 -214
  75. chainlit/translations/te.json +0 -214
  76. chainlit/translations/zh-CN.json +0 -214
  77. chainlit/translations.py +0 -60
  78. chainlit/types.py +0 -334
  79. chainlit/user.py +0 -43
  80. chainlit/user_session.py +0 -153
  81. chainlit/utils.py +0 -173
  82. chainlit/version.py +0 -8
  83. chainlit-2.7.0.dist-info/RECORD +0 -84
  84. {chainlit-2.7.0.dist-info → chainlit-2.7.1.dist-info}/WHEEL +0 -0
  85. {chainlit-2.7.0.dist-info → chainlit-2.7.1.dist-info}/entry_points.txt +0 -0
chainlit/session.py DELETED
@@ -1,304 +0,0 @@
1
- import asyncio
2
- import json
3
- import mimetypes
4
- import shutil
5
- import uuid
6
- from contextlib import AsyncExitStack
7
- from typing import TYPE_CHECKING, Any, Callable, Deque, Dict, Literal, Optional, Union
8
-
9
- import aiofiles
10
-
11
- from chainlit.logger import logger
12
- from chainlit.types import AskFileSpec, FileReference
13
-
14
- if TYPE_CHECKING:
15
- from mcp import ClientSession
16
-
17
- from chainlit.types import FileDict
18
- from chainlit.user import PersistedUser, User
19
-
20
- ClientType = Literal["webapp", "copilot", "teams", "slack", "discord"]
21
-
22
-
23
- class JSONEncoderIgnoreNonSerializable(json.JSONEncoder):
24
- def default(self, o):
25
- try:
26
- return super().default(o)
27
- except TypeError:
28
- return None
29
-
30
-
31
- def clean_metadata(metadata: Dict, max_size: int = 1048576):
32
- cleaned_metadata = json.loads(
33
- json.dumps(metadata, cls=JSONEncoderIgnoreNonSerializable, ensure_ascii=False)
34
- )
35
-
36
- metadata_size = len(json.dumps(cleaned_metadata).encode("utf-8"))
37
- if metadata_size > max_size:
38
- # Redact the metadata if it exceeds the maximum size
39
- cleaned_metadata = {
40
- "message": f"Metadata size exceeds the limit of {max_size} bytes. Redacted."
41
- }
42
-
43
- return cleaned_metadata
44
-
45
-
46
- class BaseSession:
47
- """Base object."""
48
-
49
- thread_id_to_resume: Optional[str] = None
50
- client_type: ClientType
51
- current_task: Optional[asyncio.Task] = None
52
-
53
- def __init__(
54
- self,
55
- # Id of the session
56
- id: str,
57
- client_type: ClientType,
58
- # Thread id
59
- thread_id: Optional[str],
60
- # Logged-in user information
61
- user: Optional[Union["User", "PersistedUser"]],
62
- # Logged-in user token
63
- token: Optional[str],
64
- # User specific environment variables. Empty if no user environment variables are required.
65
- user_env: Optional[Dict[str, str]],
66
- # WSGI environment variables for the connection request
67
- environ: Optional[dict[str, Any]] = None,
68
- # Chat profile selected before the session was created
69
- chat_profile: Optional[str] = None,
70
- ):
71
- if thread_id:
72
- self.thread_id_to_resume = thread_id
73
- self.thread_id = thread_id or str(uuid.uuid4())
74
- self.user = user
75
- self.client_type = client_type
76
- self.token = token
77
- self.has_first_interaction = False
78
- self.user_env = user_env or {}
79
- self.environ = environ or {}
80
- self.chat_profile = chat_profile
81
-
82
- self.files: Dict[str, FileDict] = {}
83
- self.files_spec: Dict[str, AskFileSpec] = {}
84
-
85
- self.id = id
86
-
87
- self.chat_settings: Dict[str, Any] = {}
88
-
89
- @property
90
- def files_dir(self):
91
- from chainlit.config import FILES_DIRECTORY
92
-
93
- return FILES_DIRECTORY / self.id
94
-
95
- async def persist_file(
96
- self,
97
- name: str,
98
- mime: str,
99
- path: Optional[str] = None,
100
- content: Optional[Union[bytes, str]] = None,
101
- ) -> FileReference:
102
- if not path and not content:
103
- raise ValueError(
104
- "Either path or content must be provided to persist a file"
105
- )
106
-
107
- self.files_dir.mkdir(exist_ok=True)
108
-
109
- file_id = str(uuid.uuid4())
110
-
111
- file_path = self.files_dir / file_id
112
-
113
- file_extension = mimetypes.guess_extension(mime)
114
-
115
- if file_extension:
116
- file_path = file_path.with_suffix(file_extension)
117
-
118
- if path:
119
- # Copy the file from the given path
120
- async with (
121
- aiofiles.open(path, "rb") as src,
122
- aiofiles.open(file_path, "wb") as dst,
123
- ):
124
- await dst.write(await src.read())
125
- elif content:
126
- # Write the provided content to the file
127
- async with aiofiles.open(file_path, "wb") as buffer:
128
- if isinstance(content, str):
129
- content = content.encode("utf-8")
130
- await buffer.write(content)
131
-
132
- # Get the file size
133
- file_size = file_path.stat().st_size
134
- # Store the file content in memory
135
- self.files[file_id] = {
136
- "id": file_id,
137
- "path": file_path,
138
- "name": name,
139
- "type": mime,
140
- "size": file_size,
141
- }
142
-
143
- return {"id": file_id}
144
-
145
- def to_persistable(self) -> Dict:
146
- from chainlit.user_session import user_sessions
147
-
148
- user_session = user_sessions.get(self.id) or {} # type: Dict
149
- user_session["chat_settings"] = self.chat_settings
150
- user_session["chat_profile"] = self.chat_profile
151
- user_session["client_type"] = self.client_type
152
- metadata = clean_metadata(user_session)
153
- return metadata
154
-
155
-
156
- class HTTPSession(BaseSession):
157
- """Internal HTTP session object. Used to consume Chainlit through API (no websocket)."""
158
-
159
- def __init__(
160
- self,
161
- # Id of the session
162
- id: str,
163
- client_type: ClientType,
164
- # Thread id
165
- thread_id: Optional[str] = None,
166
- # Logged-in user information
167
- user: Optional[Union["User", "PersistedUser"]] = None,
168
- # Logged-in user token
169
- token: Optional[str] = None,
170
- user_env: Optional[Dict[str, str]] = None,
171
- # WSGI environment variables for the connection request
172
- environ: Optional[dict[str, Any]] = None,
173
- ):
174
- super().__init__(
175
- id=id,
176
- thread_id=thread_id,
177
- user=user,
178
- token=token,
179
- client_type=client_type,
180
- user_env=user_env,
181
- environ=environ,
182
- )
183
-
184
- async def delete(self):
185
- """Delete the session."""
186
- if self.files_dir.is_dir():
187
- shutil.rmtree(self.files_dir)
188
-
189
-
190
- ThreadQueue = Deque[tuple[Callable, object, tuple, Dict]]
191
-
192
-
193
- class WebsocketSession(BaseSession):
194
- """Internal web socket session object.
195
-
196
- A socket id is an ephemeral id that can't be used as a session id
197
- (as it is for instance regenerated after each reconnection).
198
-
199
- The Session object store an internal mapping between socket id and
200
- a server generated session id, allowing to persists session
201
- between socket reconnection but also retrieving a session by
202
- socket id for convenience.
203
- """
204
-
205
- to_clear: bool = False
206
-
207
- mcp_sessions: dict[str, tuple["ClientSession", AsyncExitStack]]
208
-
209
- def __init__(
210
- self,
211
- # Id from the session cookie
212
- id: str,
213
- # Associated socket id
214
- socket_id: str,
215
- # Function to emit to the client
216
- emit: Callable[[str, Any], None],
217
- # Function to emit to the client and wait for a response
218
- emit_call: Callable[[Literal["ask", "call_fn"], Any, Optional[int]], Any],
219
- # User specific environment variables. Empty if no user environment variables are required.
220
- user_env: Dict[str, str],
221
- client_type: ClientType,
222
- # WSGI environment variables for the connection request
223
- environ: Optional[dict[str, Any]] = None,
224
- # Thread id
225
- thread_id: Optional[str] = None,
226
- # Logged-in user information
227
- user: Optional[Union["User", "PersistedUser"]] = None,
228
- # Logged-in user token
229
- token: Optional[str] = None,
230
- # Chat profile selected before the session was created
231
- chat_profile: Optional[str] = None,
232
- ):
233
- super().__init__(
234
- id=id,
235
- thread_id=thread_id,
236
- user=user,
237
- token=token,
238
- user_env=user_env,
239
- client_type=client_type,
240
- chat_profile=chat_profile,
241
- environ=environ,
242
- )
243
-
244
- self.socket_id = socket_id
245
- self.emit_call = emit_call
246
- self.emit = emit
247
-
248
- self.restored = False
249
-
250
- self.thread_queues: Dict[str, ThreadQueue] = {}
251
- self.mcp_sessions = {}
252
-
253
- ws_sessions_id[self.id] = self
254
- ws_sessions_sid[socket_id] = self
255
-
256
- def restore(self, new_socket_id: str):
257
- """Associate a new socket id to the session."""
258
- ws_sessions_sid.pop(self.socket_id, None)
259
- ws_sessions_sid[new_socket_id] = self
260
- self.socket_id = new_socket_id
261
- self.restored = True
262
-
263
- async def delete(self):
264
- """Delete the session."""
265
- if self.files_dir.is_dir():
266
- shutil.rmtree(self.files_dir)
267
- ws_sessions_sid.pop(self.socket_id, None)
268
- ws_sessions_id.pop(self.id, None)
269
-
270
- for _, exit_stack in self.mcp_sessions.values():
271
- try:
272
- await exit_stack.aclose()
273
- except Exception:
274
- pass
275
-
276
- async def flush_method_queue(self):
277
- for method_name, queue in self.thread_queues.items():
278
- while queue:
279
- method, self, args, kwargs = queue.popleft()
280
- try:
281
- await method(self, *args, **kwargs)
282
- except Exception as e:
283
- logger.error(f"Error while flushing {method_name}: {e}")
284
-
285
- @classmethod
286
- def get(cls, socket_id: str):
287
- """Get session by socket id."""
288
- return ws_sessions_sid.get(socket_id)
289
-
290
- @classmethod
291
- def get_by_id(cls, session_id: str):
292
- """Get session by session id."""
293
- return ws_sessions_id.get(session_id)
294
-
295
- @classmethod
296
- def require(cls, socket_id: str):
297
- """Throws an exception if the session is not found."""
298
- if session := cls.get(socket_id):
299
- return session
300
- raise ValueError("Session not found")
301
-
302
-
303
- ws_sessions_sid: Dict[str, WebsocketSession] = {}
304
- ws_sessions_id: Dict[str, WebsocketSession] = {}
chainlit/sidebar.py DELETED
@@ -1,55 +0,0 @@
1
- import asyncio
2
- from typing import List, Optional
3
-
4
- from chainlit.context import context
5
- from chainlit.element import ElementBased
6
-
7
-
8
- class ElementSidebar:
9
- """Helper class to open/close the element sidebar server side.
10
- The element sidebar accepts a title and list of elements."""
11
-
12
- @staticmethod
13
- async def set_title(title: str):
14
- """
15
- Sets the title of the element sidebar and opens it.
16
-
17
- The sidebar will automatically open when a title is set using this method.
18
-
19
- Args:
20
- title (str): The title to display at the top of the sidebar.
21
-
22
- Returns:
23
- None: This method does not return anything.
24
- """
25
- await context.emitter.emit("set_sidebar_title", title)
26
-
27
- @staticmethod
28
- async def set_elements(elements: List[ElementBased], key: Optional[str] = None):
29
- """
30
- Sets the elements to display in the sidebar and controls sidebar visibility.
31
-
32
- This method sends all provided elements to the client and updates the sidebar.
33
- Passing an empty list will close the sidebar, while passing at least one element
34
- will open it.
35
-
36
- Args:
37
- elements (List[ElementBased]): A list of ElementBased objects to display in the sidebar.
38
- key (Optional[str], optional): If the sidebar is already opened with the same key, elements will not be replaced.
39
-
40
- Returns:
41
- None: This method does not return anything.
42
-
43
- Note:
44
- This method first sends each element separately using their send() method,
45
- then emits an event with all element dictionaries and the optional key.
46
- """
47
- coros = [
48
- element.send(for_id=element.for_id or "", persist=False)
49
- for element in elements
50
- ]
51
- await asyncio.gather(*coros)
52
- await context.emitter.emit(
53
- "set_sidebar_elements",
54
- {"elements": [el.to_dict() for el in elements], "key": key},
55
- )
@@ -1,6 +0,0 @@
1
- import importlib.util
2
-
3
- if importlib.util.find_spec("slack_bolt") is None:
4
- raise ValueError(
5
- "The slack_bolt package is required to integrate Chainlit with a Slack app. Run `pip install slack_bolt --upgrade`"
6
- )