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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chainlit
3
- Version: 2.7.0
3
+ Version: 2.7.1
4
4
  Summary: Build Conversational AI.
5
5
  Project-URL: Homepage, https://chainlit.io/
6
6
  Project-URL: Documentation, https://docs.chainlit.io/
@@ -0,0 +1,4 @@
1
+ chainlit-2.7.1.dist-info/METADATA,sha256=jnq2rEhRbW3jO5LPp4OspbbHU17_j8s3Sk_Bwricewg,8008
2
+ chainlit-2.7.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
3
+ chainlit-2.7.1.dist-info/entry_points.txt,sha256=6bh2dHNg8oKZ_Vi97RjwoZQ1CMlI6Rcw4H5CSCnd_Lo,46
4
+ chainlit-2.7.1.dist-info/RECORD,,
chainlit/__init__.py DELETED
@@ -1,207 +0,0 @@
1
- import os
2
-
3
- from dotenv import load_dotenv
4
-
5
- # ruff: noqa: E402
6
- # Keep this here to ensure imports have environment available.
7
- env_file = os.getenv("CHAINLIT_ENV_FILE", ".env")
8
- env_found = load_dotenv(dotenv_path=os.path.join(os.getcwd(), env_file))
9
-
10
- from chainlit.logger import logger
11
-
12
- if env_found:
13
- logger.info(f"Loaded {env_file} file")
14
-
15
- import asyncio
16
- from typing import TYPE_CHECKING, Any, Dict
17
-
18
- from literalai import ChatGeneration, CompletionGeneration, GenerationMessage
19
- from pydantic.dataclasses import dataclass
20
-
21
- import chainlit.input_widget as input_widget
22
- from chainlit.action import Action
23
- from chainlit.cache import cache
24
- from chainlit.chat_context import chat_context
25
- from chainlit.chat_settings import ChatSettings
26
- from chainlit.context import context
27
- from chainlit.element import (
28
- Audio,
29
- CustomElement,
30
- Dataframe,
31
- File,
32
- Image,
33
- Pdf,
34
- Plotly,
35
- Pyplot,
36
- Task,
37
- TaskList,
38
- TaskStatus,
39
- Text,
40
- Video,
41
- )
42
- from chainlit.message import (
43
- AskActionMessage,
44
- AskElementMessage,
45
- AskFileMessage,
46
- AskUserMessage,
47
- ErrorMessage,
48
- Message,
49
- )
50
- from chainlit.sidebar import ElementSidebar
51
- from chainlit.step import Step, step
52
- from chainlit.sync import make_async, run_sync
53
- from chainlit.types import ChatProfile, InputAudioChunk, OutputAudioChunk, Starter
54
- from chainlit.user import PersistedUser, User
55
- from chainlit.user_session import user_session
56
- from chainlit.utils import make_module_getattr
57
- from chainlit.version import __version__
58
-
59
- from .callbacks import (
60
- action_callback,
61
- author_rename,
62
- data_layer,
63
- header_auth_callback,
64
- oauth_callback,
65
- on_app_shutdown,
66
- on_app_startup,
67
- on_audio_chunk,
68
- on_audio_end,
69
- on_audio_start,
70
- on_chat_end,
71
- on_chat_resume,
72
- on_chat_start,
73
- on_feedback,
74
- on_logout,
75
- on_mcp_connect,
76
- on_mcp_disconnect,
77
- on_message,
78
- on_settings_update,
79
- on_stop,
80
- on_window_message,
81
- password_auth_callback,
82
- send_window_message,
83
- set_chat_profiles,
84
- set_starters,
85
- )
86
-
87
- if TYPE_CHECKING:
88
- from chainlit.langchain.callbacks import (
89
- AsyncLangchainCallbackHandler,
90
- LangchainCallbackHandler,
91
- )
92
- from chainlit.llama_index.callbacks import LlamaIndexCallbackHandler
93
- from chainlit.mistralai import instrument_mistralai
94
- from chainlit.openai import instrument_openai
95
- from chainlit.semantic_kernel import SemanticKernelFilter
96
-
97
-
98
- def sleep(duration: int):
99
- """
100
- Sleep for a given duration.
101
- Args:
102
- duration (int): The duration in seconds.
103
- """
104
- return asyncio.sleep(duration)
105
-
106
-
107
- @dataclass()
108
- class CopilotFunction:
109
- name: str
110
- args: Dict[str, Any]
111
-
112
- def acall(self):
113
- return context.emitter.send_call_fn(self.name, self.args)
114
-
115
-
116
- __getattr__ = make_module_getattr(
117
- {
118
- "LangchainCallbackHandler": "chainlit.langchain.callbacks",
119
- "AsyncLangchainCallbackHandler": "chainlit.langchain.callbacks",
120
- "LlamaIndexCallbackHandler": "chainlit.llama_index.callbacks",
121
- "instrument_openai": "chainlit.openai",
122
- "instrument_mistralai": "chainlit.mistralai",
123
- "SemanticKernelFilter": "chainlit.semantic_kernel",
124
- "server": "chainlit.server",
125
- }
126
- )
127
-
128
- __all__ = [
129
- "Action",
130
- "AskActionMessage",
131
- "AskElementMessage",
132
- "AskFileMessage",
133
- "AskUserMessage",
134
- "AsyncLangchainCallbackHandler",
135
- "Audio",
136
- "ChatGeneration",
137
- "ChatProfile",
138
- "ChatSettings",
139
- "CompletionGeneration",
140
- "CopilotFunction",
141
- "CustomElement",
142
- "Dataframe",
143
- "ElementSidebar",
144
- "ErrorMessage",
145
- "File",
146
- "GenerationMessage",
147
- "Image",
148
- "InputAudioChunk",
149
- "LangchainCallbackHandler",
150
- "LlamaIndexCallbackHandler",
151
- "Message",
152
- "OutputAudioChunk",
153
- "Pdf",
154
- "PersistedUser",
155
- "Plotly",
156
- "Pyplot",
157
- "SemanticKernelFilter",
158
- "Starter",
159
- "Step",
160
- "Task",
161
- "TaskList",
162
- "TaskStatus",
163
- "Text",
164
- "User",
165
- "Video",
166
- "__version__",
167
- "action_callback",
168
- "author_rename",
169
- "cache",
170
- "chat_context",
171
- "context",
172
- "data_layer",
173
- "header_auth_callback",
174
- "input_widget",
175
- "instrument_mistralai",
176
- "instrument_openai",
177
- "make_async",
178
- "oauth_callback",
179
- "on_app_shutdown",
180
- "on_app_startup",
181
- "on_audio_chunk",
182
- "on_audio_end",
183
- "on_audio_start",
184
- "on_chat_end",
185
- "on_chat_resume",
186
- "on_chat_start",
187
- "on_feedback",
188
- "on_logout",
189
- "on_mcp_connect",
190
- "on_mcp_disconnect",
191
- "on_message",
192
- "on_settings_update",
193
- "on_stop",
194
- "on_window_message",
195
- "password_auth_callback",
196
- "run_sync",
197
- "send_window_message",
198
- "set_chat_profiles",
199
- "set_starters",
200
- "sleep",
201
- "step",
202
- "user_session",
203
- ]
204
-
205
-
206
- def __dir__():
207
- return __all__
chainlit/__main__.py DELETED
@@ -1,4 +0,0 @@
1
- from chainlit.cli import cli
2
-
3
- if __name__ == "__main__":
4
- cli(prog_name="chainlit")
chainlit/_utils.py DELETED
@@ -1,8 +0,0 @@
1
- """Util functions which are explicitly not part of the public API."""
2
-
3
- from pathlib import Path
4
-
5
-
6
- def is_path_inside(child_path: Path, parent_path: Path) -> bool:
7
- """Check if the child path is inside the parent path."""
8
- return parent_path.resolve() in child_path.resolve().parents
chainlit/action.py DELETED
@@ -1,33 +0,0 @@
1
- import uuid
2
- from typing import Dict, Optional
3
-
4
- from dataclasses_json import DataClassJsonMixin
5
- from pydantic import Field
6
- from pydantic.dataclasses import dataclass
7
-
8
- from chainlit.context import context
9
-
10
-
11
- @dataclass
12
- class Action(DataClassJsonMixin):
13
- # Name of the action, this should be used in the action_callback
14
- name: str
15
- # The parameters to call this action with.
16
- payload: Dict
17
- # The label of the action. This is what the user will see.
18
- label: str = ""
19
- # The tooltip of the action button. This is what the user will see when they hover the action.
20
- tooltip: str = ""
21
- # The lucid icon name for this action.
22
- icon: Optional[str] = None
23
- # This should not be set manually, only used internally.
24
- forId: Optional[str] = None
25
- # The ID of the action
26
- id: str = Field(default_factory=lambda: str(uuid.uuid4()))
27
-
28
- async def send(self, for_id: str):
29
- self.forId = for_id
30
- await context.emitter.emit("action", self.to_dict())
31
-
32
- async def remove(self):
33
- await context.emitter.emit("remove_action", self.to_dict())
chainlit/auth/__init__.py DELETED
@@ -1,95 +0,0 @@
1
- import os
2
-
3
- from fastapi import Depends, HTTPException
4
-
5
- from chainlit.config import config
6
- from chainlit.data import get_data_layer
7
- from chainlit.logger import logger
8
- from chainlit.oauth_providers import get_configured_oauth_providers
9
-
10
- from .cookie import (
11
- OAuth2PasswordBearerWithCookie,
12
- clear_auth_cookie,
13
- get_token_from_cookies,
14
- set_auth_cookie,
15
- )
16
- from .jwt import create_jwt, decode_jwt, get_jwt_secret
17
-
18
- reuseable_oauth = OAuth2PasswordBearerWithCookie(tokenUrl="/login", auto_error=False)
19
-
20
-
21
- def ensure_jwt_secret():
22
- if require_login() and get_jwt_secret() is None:
23
- raise ValueError(
24
- "You must provide a JWT secret in the environment to use authentication. Run `chainlit create-secret` to generate one."
25
- )
26
-
27
-
28
- def is_oauth_enabled():
29
- return config.code.oauth_callback and len(get_configured_oauth_providers()) > 0
30
-
31
-
32
- def require_login():
33
- return bool(os.environ.get("CHAINLIT_AUTH_SECRET"))
34
-
35
-
36
- def get_configuration():
37
- return {
38
- "requireLogin": require_login(),
39
- "passwordAuth": config.code.password_auth_callback is not None,
40
- "headerAuth": config.code.header_auth_callback is not None,
41
- "oauthProviders": (
42
- get_configured_oauth_providers() if is_oauth_enabled() else []
43
- ),
44
- "default_theme": config.ui.default_theme,
45
- "ui": {
46
- "login_page_image": config.ui.login_page_image,
47
- "login_page_image_filter": config.ui.login_page_image_filter,
48
- "login_page_image_dark_filter": config.ui.login_page_image_dark_filter,
49
- },
50
- }
51
-
52
-
53
- async def authenticate_user(token: str = Depends(reuseable_oauth)):
54
- try:
55
- user = decode_jwt(token)
56
- except Exception as e:
57
- raise HTTPException(
58
- status_code=401, detail="Invalid authentication token"
59
- ) from e
60
-
61
- if data_layer := get_data_layer():
62
- # Get or create persistent user if we've a data layer available.
63
- try:
64
- persisted_user = await data_layer.get_user(user.identifier)
65
- if persisted_user is None:
66
- persisted_user = await data_layer.create_user(user)
67
- assert persisted_user
68
- except Exception as e:
69
- logger.exception("Unable to get persisted_user from data layer: %s", e)
70
- return user
71
-
72
- if user and user.display_name:
73
- # Copy ephemeral display_name from authenticated user to persistent user.
74
- persisted_user.display_name = user.display_name
75
-
76
- return persisted_user
77
-
78
- return user
79
-
80
-
81
- async def get_current_user(token: str = Depends(reuseable_oauth)):
82
- if not require_login():
83
- return None
84
-
85
- return await authenticate_user(token)
86
-
87
-
88
- __all__ = [
89
- "clear_auth_cookie",
90
- "create_jwt",
91
- "get_configuration",
92
- "get_current_user",
93
- "get_token_from_cookies",
94
- "set_auth_cookie",
95
- ]
chainlit/auth/cookie.py DELETED
@@ -1,197 +0,0 @@
1
- import os
2
- from typing import Literal, Optional, cast
3
-
4
- from fastapi import Request, Response
5
- from fastapi.exceptions import HTTPException
6
- from fastapi.security.base import SecurityBase
7
- from fastapi.security.utils import get_authorization_scheme_param
8
- from starlette.status import HTTP_401_UNAUTHORIZED
9
-
10
- from chainlit.config import config
11
-
12
- """ Module level cookie settings. """
13
- _cookie_samesite = cast(
14
- Literal["lax", "strict", "none"],
15
- os.environ.get("CHAINLIT_COOKIE_SAMESITE", "lax"),
16
- )
17
-
18
- assert _cookie_samesite in [
19
- "lax",
20
- "strict",
21
- "none",
22
- ], (
23
- "Invalid value for CHAINLIT_COOKIE_SAMESITE. Must be one of 'lax', 'strict' or 'none'."
24
- )
25
- _cookie_secure = _cookie_samesite == "none"
26
- if _cookie_root_path := os.environ.get("CHAINLIT_ROOT_PATH", None):
27
- _cookie_path = os.environ.get(_cookie_root_path, "/")
28
- else:
29
- _cookie_path = os.environ.get("CHAINLIT_AUTH_COOKIE_PATH", "/")
30
- _state_cookie_lifetime = 3 * 60 # 3m
31
- _auth_cookie_name = os.environ.get("CHAINLIT_AUTH_COOKIE_NAME", "access_token")
32
- _state_cookie_name = "oauth_state"
33
-
34
-
35
- class OAuth2PasswordBearerWithCookie(SecurityBase):
36
- """
37
- OAuth2 password flow with cookie support with fallback to bearer token.
38
- """
39
-
40
- def __init__(
41
- self,
42
- tokenUrl: str,
43
- scheme_name: Optional[str] = None,
44
- auto_error: bool = True,
45
- ):
46
- self.tokenUrl = tokenUrl
47
- self.scheme_name = scheme_name or self.__class__.__name__
48
- self.auto_error = auto_error
49
-
50
- async def __call__(self, request: Request) -> Optional[str]:
51
- # First try to get the token from the cookie
52
- token = get_token_from_cookies(request.cookies)
53
-
54
- # If no cookie, try the Authorization header as fallback
55
- if not token:
56
- # TODO: Only bother to check if cookie auth is explicitly disabled.
57
- authorization = request.headers.get("Authorization")
58
- if authorization:
59
- scheme, token = get_authorization_scheme_param(authorization)
60
- if scheme.lower() != "bearer":
61
- if self.auto_error:
62
- raise HTTPException(
63
- status_code=HTTP_401_UNAUTHORIZED,
64
- detail="Invalid authentication credentials",
65
- headers={"WWW-Authenticate": "Bearer"},
66
- )
67
- else:
68
- return None
69
- else:
70
- if self.auto_error:
71
- raise HTTPException(
72
- status_code=HTTP_401_UNAUTHORIZED,
73
- detail="Not authenticated",
74
- headers={"WWW-Authenticate": "Bearer"},
75
- )
76
- else:
77
- return None
78
-
79
- return token
80
-
81
-
82
- def _get_chunked_cookie(cookies: dict[str, str], name: str) -> Optional[str]:
83
- # Gather all auth_chunk_i cookies, sorted by their index
84
- chunk_parts = []
85
-
86
- i = 0
87
- while True:
88
- cookie_key = f"{_auth_cookie_name}_{i}"
89
- if cookie_key not in cookies:
90
- break
91
-
92
- chunk_parts.append(cookies[cookie_key])
93
- i += 1
94
-
95
- joined = "".join(chunk_parts)
96
-
97
- return joined if joined != "" else None
98
-
99
-
100
- def get_token_from_cookies(cookies: dict[str, str]) -> Optional[str]:
101
- """
102
- Read all chunk cookies and reconstruct the token
103
- """
104
-
105
- # Default/unchunked cookies
106
- if value := cookies.get(_auth_cookie_name):
107
- return value
108
-
109
- return _get_chunked_cookie(cookies, _auth_cookie_name)
110
-
111
-
112
- def set_auth_cookie(request: Request, response: Response, token: str):
113
- """
114
- Helper function to set the authentication cookie with secure parameters
115
- and remove any leftover chunks from a previously larger token.
116
- """
117
-
118
- _chunk_size = 3000
119
-
120
- existing_cookies = {
121
- k for k in request.cookies.keys() if k.startswith(_auth_cookie_name)
122
- }
123
-
124
- if len(token) > _chunk_size:
125
- chunks = [token[i : i + _chunk_size] for i in range(0, len(token), _chunk_size)]
126
-
127
- for i, chunk in enumerate(chunks):
128
- k = f"{_auth_cookie_name}_{i}"
129
-
130
- response.set_cookie(
131
- key=k,
132
- value=chunk,
133
- httponly=True,
134
- secure=_cookie_secure,
135
- samesite=_cookie_samesite,
136
- max_age=config.project.user_session_timeout,
137
- )
138
-
139
- existing_cookies.discard(k)
140
- else:
141
- # Default (shorter cookies)
142
- response.set_cookie(
143
- key=_auth_cookie_name,
144
- value=token,
145
- httponly=True,
146
- secure=_cookie_secure,
147
- samesite=_cookie_samesite,
148
- max_age=config.project.user_session_timeout,
149
- )
150
-
151
- existing_cookies.discard(_auth_cookie_name)
152
-
153
- # Delete remaining prior cookies/cookie chunks
154
- for k in existing_cookies:
155
- response.delete_cookie(
156
- key=k, path=_cookie_path, secure=_cookie_secure, samesite=_cookie_samesite
157
- )
158
-
159
-
160
- def clear_auth_cookie(request: Request, response: Response):
161
- """
162
- Helper function to clear the authentication cookie
163
- """
164
-
165
- existing_cookies = {
166
- k for k in request.cookies.keys() if k.startswith(_auth_cookie_name)
167
- }
168
-
169
- for k in existing_cookies:
170
- response.delete_cookie(
171
- key=k, path=_cookie_path, secure=_cookie_secure, samesite=_cookie_samesite
172
- )
173
-
174
-
175
- def set_oauth_state_cookie(response: Response, token: str):
176
- response.set_cookie(
177
- _state_cookie_name,
178
- token,
179
- httponly=True,
180
- samesite=_cookie_samesite,
181
- secure=_cookie_secure,
182
- max_age=_state_cookie_lifetime,
183
- )
184
-
185
-
186
- def validate_oauth_state_cookie(request: Request, state: str):
187
- """Check the state from the oauth provider against the browser cookie."""
188
-
189
- oauth_state = request.cookies.get(_state_cookie_name)
190
-
191
- if oauth_state != state:
192
- raise Exception("oauth state does not correspond")
193
-
194
-
195
- def clear_oauth_state_cookie(response: Response):
196
- """Oauth complete, delete state token."""
197
- response.delete_cookie(_state_cookie_name) # Do we set path here?
chainlit/auth/jwt.py DELETED
@@ -1,42 +0,0 @@
1
- import os
2
- from datetime import datetime, timedelta, timezone
3
- from typing import Any, Dict, Optional
4
-
5
- import jwt as pyjwt
6
-
7
- from chainlit.config import config
8
- from chainlit.user import User
9
-
10
-
11
- def get_jwt_secret() -> Optional[str]:
12
- return os.environ.get("CHAINLIT_AUTH_SECRET")
13
-
14
-
15
- def create_jwt(data: User) -> str:
16
- to_encode: Dict[str, Any] = data.to_dict()
17
- to_encode.update(
18
- {
19
- "exp": datetime.now(timezone.utc)
20
- + timedelta(seconds=config.project.user_session_timeout),
21
- "iat": datetime.now(timezone.utc), # Add issued at time
22
- }
23
- )
24
-
25
- secret = get_jwt_secret()
26
- assert secret
27
- encoded_jwt = pyjwt.encode(to_encode, secret, algorithm="HS256")
28
- return encoded_jwt
29
-
30
-
31
- def decode_jwt(token: str) -> User:
32
- secret = get_jwt_secret()
33
- assert secret
34
-
35
- dict = pyjwt.decode(
36
- token,
37
- secret,
38
- algorithms=["HS256"],
39
- options={"verify_signature": True},
40
- )
41
- del dict["exp"]
42
- return User(**dict)
chainlit/cache.py DELETED
@@ -1,45 +0,0 @@
1
- import importlib.util
2
- import os
3
- import threading
4
- from typing import Any
5
-
6
- from chainlit.config import config
7
- from chainlit.logger import logger
8
-
9
-
10
- def init_lc_cache():
11
- use_cache = config.project.cache is True and config.run.no_cache is False
12
-
13
- if use_cache and importlib.util.find_spec("langchain") is not None:
14
- from langchain.cache import SQLiteCache
15
- from langchain.globals import set_llm_cache
16
-
17
- if config.project.lc_cache_path is not None:
18
- set_llm_cache(SQLiteCache(database_path=config.project.lc_cache_path))
19
-
20
- if not os.path.exists(config.project.lc_cache_path):
21
- logger.info(
22
- f"LangChain cache created at: {config.project.lc_cache_path}"
23
- )
24
-
25
-
26
- _cache: dict[tuple, Any] = {}
27
- _cache_lock = threading.Lock()
28
-
29
-
30
- def cache(func):
31
- def wrapper(*args, **kwargs):
32
- # Create a cache key based on the function name, arguments, and keyword arguments
33
- cache_key = (
34
- (func.__name__,) + args + tuple((k, v) for k, v in sorted(kwargs.items()))
35
- )
36
-
37
- with _cache_lock:
38
- # Check if the result is already in the cache
39
- if cache_key not in _cache:
40
- # If not, call the function and store the result in the cache
41
- _cache[cache_key] = func(*args, **kwargs)
42
-
43
- return _cache[cache_key]
44
-
45
- return wrapper