chainlit 0.7.604rc2__py3-none-any.whl → 1.0.0rc0__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.
- chainlit/__init__.py +32 -23
- chainlit/auth.py +9 -10
- chainlit/cache.py +3 -3
- chainlit/cli/__init__.py +12 -2
- chainlit/config.py +22 -13
- chainlit/context.py +7 -3
- chainlit/data/__init__.py +375 -9
- chainlit/data/acl.py +6 -5
- chainlit/element.py +86 -123
- chainlit/emitter.py +117 -50
- chainlit/frontend/dist/assets/index-6aee009a.js +697 -0
- chainlit/frontend/dist/assets/{react-plotly-16f7de12.js → react-plotly-2f07c02a.js} +1 -1
- chainlit/frontend/dist/index.html +1 -1
- chainlit/haystack/callbacks.py +45 -43
- chainlit/hello.py +1 -1
- chainlit/langchain/callbacks.py +135 -120
- chainlit/llama_index/callbacks.py +68 -48
- chainlit/message.py +179 -207
- chainlit/oauth_providers.py +39 -34
- chainlit/playground/provider.py +44 -30
- chainlit/playground/providers/anthropic.py +4 -4
- chainlit/playground/providers/huggingface.py +2 -2
- chainlit/playground/providers/langchain.py +8 -10
- chainlit/playground/providers/openai.py +19 -13
- chainlit/server.py +155 -99
- chainlit/session.py +109 -40
- chainlit/socket.py +54 -38
- chainlit/step.py +393 -0
- chainlit/types.py +78 -21
- chainlit/user.py +32 -0
- chainlit/user_session.py +1 -5
- {chainlit-0.7.604rc2.dist-info → chainlit-1.0.0rc0.dist-info}/METADATA +12 -31
- chainlit-1.0.0rc0.dist-info/RECORD +60 -0
- chainlit/client/base.py +0 -169
- chainlit/client/cloud.py +0 -500
- chainlit/frontend/dist/assets/index-c58dbd4b.js +0 -871
- chainlit/prompt.py +0 -40
- chainlit-0.7.604rc2.dist-info/RECORD +0 -61
- {chainlit-0.7.604rc2.dist-info → chainlit-1.0.0rc0.dist-info}/WHEEL +0 -0
- {chainlit-0.7.604rc2.dist-info → chainlit-1.0.0rc0.dist-info}/entry_points.txt +0 -0
chainlit/client/cloud.py
DELETED
|
@@ -1,500 +0,0 @@
|
|
|
1
|
-
import uuid
|
|
2
|
-
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
3
|
-
|
|
4
|
-
import httpx
|
|
5
|
-
from chainlit.logger import logger
|
|
6
|
-
|
|
7
|
-
from .base import (
|
|
8
|
-
AppUser,
|
|
9
|
-
ChainlitGraphQLClient,
|
|
10
|
-
ConversationDict,
|
|
11
|
-
ConversationFilter,
|
|
12
|
-
ElementDict,
|
|
13
|
-
MessageDict,
|
|
14
|
-
PageInfo,
|
|
15
|
-
PaginatedResponse,
|
|
16
|
-
Pagination,
|
|
17
|
-
PersistedAppUser,
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class ChainlitCloudClient(ChainlitGraphQLClient):
|
|
22
|
-
chainlit_server: str
|
|
23
|
-
|
|
24
|
-
def __init__(self, api_key: str, chainlit_server="https://cloud.chainlit.io"):
|
|
25
|
-
# Remove trailing slash
|
|
26
|
-
chainlit_server = chainlit_server.rstrip("/")
|
|
27
|
-
super().__init__(api_key=api_key, chainlit_server=chainlit_server)
|
|
28
|
-
self.chainlit_server = chainlit_server
|
|
29
|
-
|
|
30
|
-
async def create_app_user(self, app_user: AppUser) -> Optional[PersistedAppUser]:
|
|
31
|
-
mutation = """
|
|
32
|
-
mutation ($username: String!, $role: Role!, $tags: [String!], $provider: String, $image: String) {
|
|
33
|
-
createAppUser(username: $username, role: $role, tags: $tags, provider: $provider, image: $image) {
|
|
34
|
-
id,
|
|
35
|
-
username,
|
|
36
|
-
role,
|
|
37
|
-
tags,
|
|
38
|
-
provider,
|
|
39
|
-
image,
|
|
40
|
-
createdAt
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
"""
|
|
44
|
-
variables = app_user.to_dict()
|
|
45
|
-
res = await self.mutation(mutation, variables)
|
|
46
|
-
|
|
47
|
-
if self.check_for_errors(res):
|
|
48
|
-
logger.warning("Could not create app user.")
|
|
49
|
-
return None
|
|
50
|
-
|
|
51
|
-
return PersistedAppUser.from_dict(res["data"]["createAppUser"])
|
|
52
|
-
|
|
53
|
-
async def update_app_user(self, app_user: AppUser) -> Optional[PersistedAppUser]:
|
|
54
|
-
mutation = """
|
|
55
|
-
mutation ($username: String!, $role: Role!, $tags: [String!], $provider: String, $image: String) {
|
|
56
|
-
updateAppUser(username: $username, role: $role, tags: $tags, provider: $provider, image: $image) {
|
|
57
|
-
id,
|
|
58
|
-
username,
|
|
59
|
-
role,
|
|
60
|
-
tags,
|
|
61
|
-
provider,
|
|
62
|
-
image,
|
|
63
|
-
createdAt
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
"""
|
|
67
|
-
variables = app_user.to_dict()
|
|
68
|
-
res = await self.mutation(mutation, variables)
|
|
69
|
-
|
|
70
|
-
if self.check_for_errors(res):
|
|
71
|
-
logger.warning("Could not update app user.")
|
|
72
|
-
return None
|
|
73
|
-
|
|
74
|
-
return PersistedAppUser.from_dict(res["data"]["updateAppUser"])
|
|
75
|
-
|
|
76
|
-
async def get_app_user(self, username: str) -> Optional[PersistedAppUser]:
|
|
77
|
-
query = """
|
|
78
|
-
query ($username: String!) {
|
|
79
|
-
getAppUser(username: $username) {
|
|
80
|
-
id,
|
|
81
|
-
username,
|
|
82
|
-
role,
|
|
83
|
-
tags,
|
|
84
|
-
provider,
|
|
85
|
-
image,
|
|
86
|
-
createdAt
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
"""
|
|
90
|
-
variables = {"username": username}
|
|
91
|
-
res = await self.query(query, variables)
|
|
92
|
-
|
|
93
|
-
if self.check_for_errors(res):
|
|
94
|
-
logger.warning("Could not get app user.")
|
|
95
|
-
return None
|
|
96
|
-
|
|
97
|
-
return PersistedAppUser.from_dict(res["data"]["getAppUser"])
|
|
98
|
-
|
|
99
|
-
async def delete_app_user(self, username: str) -> bool:
|
|
100
|
-
mutation = """
|
|
101
|
-
mutation ($username: String!) {
|
|
102
|
-
deleteAppUser(username: $username) {
|
|
103
|
-
id,
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
"""
|
|
107
|
-
variables = {"username": username}
|
|
108
|
-
res = await self.mutation(mutation, variables)
|
|
109
|
-
|
|
110
|
-
if self.check_for_errors(res):
|
|
111
|
-
logger.warning("Could not delete app user.")
|
|
112
|
-
return False
|
|
113
|
-
|
|
114
|
-
return True
|
|
115
|
-
|
|
116
|
-
async def create_conversation(
|
|
117
|
-
self, app_user_id: Optional[str], tags: Optional[List[str]]
|
|
118
|
-
) -> Optional[str]:
|
|
119
|
-
mutation = """
|
|
120
|
-
mutation ($appUserId: String, $tags: [String!]) {
|
|
121
|
-
createConversation (appUserId: $appUserId, tags: $tags) {
|
|
122
|
-
id
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
"""
|
|
126
|
-
variables = {} # type: Dict[str, Any]
|
|
127
|
-
if app_user_id is not None:
|
|
128
|
-
variables["appUserId"] = app_user_id
|
|
129
|
-
|
|
130
|
-
if tags:
|
|
131
|
-
variables["tags"] = tags
|
|
132
|
-
|
|
133
|
-
res = await self.mutation(mutation, variables)
|
|
134
|
-
|
|
135
|
-
if self.check_for_errors(res):
|
|
136
|
-
logger.warning("Could not create conversation.")
|
|
137
|
-
return None
|
|
138
|
-
|
|
139
|
-
return res["data"]["createConversation"]["id"]
|
|
140
|
-
|
|
141
|
-
async def delete_conversation(self, conversation_id: str) -> bool:
|
|
142
|
-
mutation = """
|
|
143
|
-
mutation ($id: ID!) {
|
|
144
|
-
deleteConversation(id: $id) {
|
|
145
|
-
id
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
"""
|
|
149
|
-
variables = {"id": conversation_id}
|
|
150
|
-
res = await self.mutation(mutation, variables)
|
|
151
|
-
self.check_for_errors(res, raise_error=True)
|
|
152
|
-
|
|
153
|
-
return True
|
|
154
|
-
|
|
155
|
-
async def get_conversation_author(self, conversation_id: str) -> Optional[str]:
|
|
156
|
-
query = """
|
|
157
|
-
query ($id: ID!) {
|
|
158
|
-
conversation(id: $id) {
|
|
159
|
-
appUser {
|
|
160
|
-
username
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
"""
|
|
165
|
-
variables = {
|
|
166
|
-
"id": conversation_id,
|
|
167
|
-
}
|
|
168
|
-
res = await self.query(query, variables)
|
|
169
|
-
self.check_for_errors(res, raise_error=True)
|
|
170
|
-
data = res.get("data")
|
|
171
|
-
conversation = data.get("conversation") if data else None
|
|
172
|
-
return (
|
|
173
|
-
conversation["appUser"].get("username") if conversation["appUser"] else None
|
|
174
|
-
)
|
|
175
|
-
|
|
176
|
-
async def get_conversation(self, conversation_id: str) -> ConversationDict:
|
|
177
|
-
query = """
|
|
178
|
-
query ($id: ID!) {
|
|
179
|
-
conversation(id: $id) {
|
|
180
|
-
id
|
|
181
|
-
createdAt
|
|
182
|
-
tags
|
|
183
|
-
metadata
|
|
184
|
-
appUser {
|
|
185
|
-
id
|
|
186
|
-
username
|
|
187
|
-
}
|
|
188
|
-
messages {
|
|
189
|
-
id
|
|
190
|
-
isError
|
|
191
|
-
parentId
|
|
192
|
-
indent
|
|
193
|
-
author
|
|
194
|
-
content
|
|
195
|
-
waitForAnswer
|
|
196
|
-
humanFeedback
|
|
197
|
-
humanFeedbackComment
|
|
198
|
-
disableHumanFeedback
|
|
199
|
-
language
|
|
200
|
-
prompt
|
|
201
|
-
authorIsUser
|
|
202
|
-
createdAt
|
|
203
|
-
}
|
|
204
|
-
elements {
|
|
205
|
-
id
|
|
206
|
-
conversationId
|
|
207
|
-
type
|
|
208
|
-
name
|
|
209
|
-
mime
|
|
210
|
-
url
|
|
211
|
-
display
|
|
212
|
-
language
|
|
213
|
-
size
|
|
214
|
-
forIds
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
"""
|
|
219
|
-
variables = {
|
|
220
|
-
"id": conversation_id,
|
|
221
|
-
}
|
|
222
|
-
res = await self.query(query, variables)
|
|
223
|
-
self.check_for_errors(res, raise_error=True)
|
|
224
|
-
|
|
225
|
-
return res["data"]["conversation"]
|
|
226
|
-
|
|
227
|
-
async def update_conversation_metadata(self, conversation_id: str, metadata: Dict):
|
|
228
|
-
mutation = """mutation ($conversationId: ID!, $metadata: Json!) {
|
|
229
|
-
updateConversationMetadata(conversationId: $conversationId, metadata: $metadata) {
|
|
230
|
-
id
|
|
231
|
-
}
|
|
232
|
-
}"""
|
|
233
|
-
variables = {
|
|
234
|
-
"conversationId": conversation_id,
|
|
235
|
-
"metadata": metadata,
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
res = await self.mutation(mutation, variables)
|
|
239
|
-
self.check_for_errors(res, raise_error=True)
|
|
240
|
-
|
|
241
|
-
return True
|
|
242
|
-
|
|
243
|
-
async def get_conversations(
|
|
244
|
-
self, pagination: Pagination, filter: ConversationFilter
|
|
245
|
-
):
|
|
246
|
-
query = """query (
|
|
247
|
-
$first: Int
|
|
248
|
-
$cursor: String
|
|
249
|
-
$withFeedback: Int
|
|
250
|
-
$username: String
|
|
251
|
-
$search: String
|
|
252
|
-
) {
|
|
253
|
-
conversations(
|
|
254
|
-
first: $first
|
|
255
|
-
cursor: $cursor
|
|
256
|
-
withFeedback: $withFeedback
|
|
257
|
-
username: $username
|
|
258
|
-
search: $search
|
|
259
|
-
) {
|
|
260
|
-
pageInfo {
|
|
261
|
-
endCursor
|
|
262
|
-
hasNextPage
|
|
263
|
-
}
|
|
264
|
-
edges {
|
|
265
|
-
cursor
|
|
266
|
-
node {
|
|
267
|
-
id
|
|
268
|
-
createdAt
|
|
269
|
-
tags
|
|
270
|
-
appUser {
|
|
271
|
-
username
|
|
272
|
-
}
|
|
273
|
-
messages {
|
|
274
|
-
content
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
}"""
|
|
280
|
-
|
|
281
|
-
variables = {
|
|
282
|
-
"first": pagination.first,
|
|
283
|
-
"cursor": pagination.cursor,
|
|
284
|
-
"withFeedback": filter.feedback,
|
|
285
|
-
"username": filter.username,
|
|
286
|
-
"search": filter.search,
|
|
287
|
-
}
|
|
288
|
-
res = await self.query(query, variables)
|
|
289
|
-
self.check_for_errors(res, raise_error=True)
|
|
290
|
-
|
|
291
|
-
conversations = []
|
|
292
|
-
|
|
293
|
-
for edge in res["data"]["conversations"]["edges"]:
|
|
294
|
-
node = edge["node"]
|
|
295
|
-
conversations.append(node)
|
|
296
|
-
|
|
297
|
-
page_info = res["data"]["conversations"]["pageInfo"]
|
|
298
|
-
|
|
299
|
-
return PaginatedResponse(
|
|
300
|
-
pageInfo=PageInfo(
|
|
301
|
-
hasNextPage=page_info["hasNextPage"],
|
|
302
|
-
endCursor=page_info["endCursor"],
|
|
303
|
-
),
|
|
304
|
-
data=conversations,
|
|
305
|
-
)
|
|
306
|
-
|
|
307
|
-
async def set_human_feedback(
|
|
308
|
-
self, message_id: str, feedback: int, feedbackComment: Optional[str]
|
|
309
|
-
) -> bool:
|
|
310
|
-
mutation = """mutation ($messageId: ID!, $humanFeedback: Int!, $humanFeedbackComment: String) {
|
|
311
|
-
setHumanFeedback(messageId: $messageId, humanFeedback: $humanFeedback, humanFeedbackComment: $humanFeedbackComment) {
|
|
312
|
-
id
|
|
313
|
-
humanFeedback
|
|
314
|
-
humanFeedbackComment
|
|
315
|
-
}
|
|
316
|
-
}"""
|
|
317
|
-
variables = {
|
|
318
|
-
"messageId": message_id,
|
|
319
|
-
"humanFeedback": feedback,
|
|
320
|
-
}
|
|
321
|
-
if feedbackComment:
|
|
322
|
-
variables["humanFeedbackComment"] = feedbackComment
|
|
323
|
-
res = await self.mutation(mutation, variables)
|
|
324
|
-
self.check_for_errors(res, raise_error=True)
|
|
325
|
-
|
|
326
|
-
return True
|
|
327
|
-
|
|
328
|
-
async def get_message(self):
|
|
329
|
-
raise NotImplementedError
|
|
330
|
-
|
|
331
|
-
async def create_message(self, variables: MessageDict) -> Optional[str]:
|
|
332
|
-
mutation = """
|
|
333
|
-
mutation ($id: ID!, $conversationId: ID!, $author: String!, $content: String!, $language: String, $prompt: Json, $isError: Boolean, $parentId: String, $indent: Int, $authorIsUser: Boolean, $disableHumanFeedback: Boolean, $waitForAnswer: Boolean, $createdAt: StringOrFloat) {
|
|
334
|
-
createMessage(id: $id, conversationId: $conversationId, author: $author, content: $content, language: $language, prompt: $prompt, isError: $isError, parentId: $parentId, indent: $indent, authorIsUser: $authorIsUser, disableHumanFeedback: $disableHumanFeedback, waitForAnswer: $waitForAnswer, createdAt: $createdAt) {
|
|
335
|
-
id
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
"""
|
|
339
|
-
res = await self.mutation(mutation, variables)
|
|
340
|
-
if self.check_for_errors(res):
|
|
341
|
-
logger.warning("Could not create message.")
|
|
342
|
-
return None
|
|
343
|
-
|
|
344
|
-
return res["data"]["createMessage"]["id"]
|
|
345
|
-
|
|
346
|
-
async def update_message(self, message_id: str, variables: MessageDict) -> bool:
|
|
347
|
-
mutation = """
|
|
348
|
-
mutation ($messageId: ID!, $author: String!, $content: String!, $parentId: String, $language: String, $prompt: Json, $disableHumanFeedback: Boolean) {
|
|
349
|
-
updateMessage(messageId: $messageId, author: $author, content: $content, parentId: $parentId, language: $language, prompt: $prompt, disableHumanFeedback: $disableHumanFeedback) {
|
|
350
|
-
id
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
"""
|
|
354
|
-
res = await self.mutation(mutation, dict(messageId=message_id, **variables))
|
|
355
|
-
|
|
356
|
-
if self.check_for_errors(res):
|
|
357
|
-
logger.warning("Could not update message.")
|
|
358
|
-
return False
|
|
359
|
-
|
|
360
|
-
return True
|
|
361
|
-
|
|
362
|
-
async def delete_message(self, message_id: str) -> bool:
|
|
363
|
-
mutation = """
|
|
364
|
-
mutation ($messageId: ID!) {
|
|
365
|
-
deleteMessage(messageId: $messageId) {
|
|
366
|
-
id
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
"""
|
|
370
|
-
res = await self.mutation(mutation, {"messageId": message_id})
|
|
371
|
-
|
|
372
|
-
if self.check_for_errors(res):
|
|
373
|
-
logger.warning("Could not delete message.")
|
|
374
|
-
return False
|
|
375
|
-
|
|
376
|
-
return True
|
|
377
|
-
|
|
378
|
-
async def get_element(
|
|
379
|
-
self, conversation_id: str, element_id: str
|
|
380
|
-
) -> Optional[ElementDict]:
|
|
381
|
-
query = """query (
|
|
382
|
-
$conversationId: ID!
|
|
383
|
-
$id: ID!
|
|
384
|
-
) {
|
|
385
|
-
element(
|
|
386
|
-
conversationId: $conversationId,
|
|
387
|
-
id: $id
|
|
388
|
-
) {
|
|
389
|
-
id
|
|
390
|
-
conversationId
|
|
391
|
-
type
|
|
392
|
-
name
|
|
393
|
-
mime
|
|
394
|
-
url
|
|
395
|
-
display
|
|
396
|
-
language
|
|
397
|
-
size
|
|
398
|
-
forIds
|
|
399
|
-
}
|
|
400
|
-
}"""
|
|
401
|
-
|
|
402
|
-
variables = {
|
|
403
|
-
"conversationId": conversation_id,
|
|
404
|
-
"id": element_id,
|
|
405
|
-
}
|
|
406
|
-
res = await self.query(query, variables)
|
|
407
|
-
self.check_for_errors(res, raise_error=True)
|
|
408
|
-
|
|
409
|
-
return res["data"]["element"]
|
|
410
|
-
|
|
411
|
-
async def create_element(self, variables: ElementDict) -> Optional[ElementDict]:
|
|
412
|
-
mutation = """
|
|
413
|
-
mutation ($conversationId: ID!, $type: String!, $name: String!, $display: String!, $forIds: [String!]!, $url: String, $objectKey: String, $size: String, $language: String, $mime: String) {
|
|
414
|
-
createElement(conversationId: $conversationId, type: $type, url: $url, objectKey: $objectKey, name: $name, display: $display, size: $size, language: $language, forIds: $forIds, mime: $mime) {
|
|
415
|
-
id,
|
|
416
|
-
type,
|
|
417
|
-
url,
|
|
418
|
-
objectKey,
|
|
419
|
-
name,
|
|
420
|
-
display,
|
|
421
|
-
size,
|
|
422
|
-
language,
|
|
423
|
-
forIds,
|
|
424
|
-
mime
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
"""
|
|
428
|
-
res = await self.mutation(mutation, variables)
|
|
429
|
-
|
|
430
|
-
if self.check_for_errors(res):
|
|
431
|
-
logger.warning("Could not create element.")
|
|
432
|
-
return None
|
|
433
|
-
|
|
434
|
-
return res["data"]["createElement"]
|
|
435
|
-
|
|
436
|
-
async def update_element(self, variables: ElementDict) -> Optional[ElementDict]:
|
|
437
|
-
mutation = """
|
|
438
|
-
mutation ($conversationId: ID!, $id: ID!, $forIds: [String!]!) {
|
|
439
|
-
updateElement(conversationId: $conversationId, id: $id, forIds: $forIds) {
|
|
440
|
-
id,
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
"""
|
|
444
|
-
|
|
445
|
-
res = await self.mutation(mutation, variables)
|
|
446
|
-
|
|
447
|
-
if self.check_for_errors(res):
|
|
448
|
-
logger.warning("Could not update element.")
|
|
449
|
-
return None
|
|
450
|
-
|
|
451
|
-
return res["data"]["updateElement"]
|
|
452
|
-
|
|
453
|
-
async def upload_element(
|
|
454
|
-
self, content: Union[bytes, str], mime: str, conversation_id: Optional[str]
|
|
455
|
-
) -> Dict:
|
|
456
|
-
id = str(uuid.uuid4())
|
|
457
|
-
body = {"fileName": id, "contentType": mime}
|
|
458
|
-
|
|
459
|
-
if conversation_id:
|
|
460
|
-
body["conversationId"] = conversation_id
|
|
461
|
-
|
|
462
|
-
path = "/api/upload/file"
|
|
463
|
-
|
|
464
|
-
async with httpx.AsyncClient() as client:
|
|
465
|
-
response = await client.post(
|
|
466
|
-
f"{self.chainlit_server}{path}",
|
|
467
|
-
json=body,
|
|
468
|
-
headers=self.headers,
|
|
469
|
-
)
|
|
470
|
-
if response.status_code != 200:
|
|
471
|
-
reason = response.text
|
|
472
|
-
logger.error(f"Failed to sign upload url: {reason}")
|
|
473
|
-
return {"object_key": None, "url": None}
|
|
474
|
-
json_res = response.json()
|
|
475
|
-
|
|
476
|
-
upload_details = json_res["post"]
|
|
477
|
-
object_key = upload_details["fields"]["key"]
|
|
478
|
-
signed_url = json_res["signedUrl"]
|
|
479
|
-
|
|
480
|
-
# Prepare form data
|
|
481
|
-
form_data = {} # type: Dict[str, Tuple[Union[str, None], Any]]
|
|
482
|
-
for field_name, field_value in upload_details["fields"].items():
|
|
483
|
-
form_data[field_name] = (None, field_value)
|
|
484
|
-
|
|
485
|
-
# Add file to the form_data
|
|
486
|
-
# Note: The content_type parameter is not needed here, as the correct MIME type should be set in the 'Content-Type' field from upload_details
|
|
487
|
-
form_data["file"] = (id, content)
|
|
488
|
-
|
|
489
|
-
async with httpx.AsyncClient() as client:
|
|
490
|
-
upload_response = await client.post(
|
|
491
|
-
upload_details["url"],
|
|
492
|
-
files=form_data,
|
|
493
|
-
)
|
|
494
|
-
try:
|
|
495
|
-
upload_response.raise_for_status()
|
|
496
|
-
url = f'{upload_details["url"]}/{object_key}'
|
|
497
|
-
return {"object_key": object_key, "url": signed_url}
|
|
498
|
-
except Exception as e:
|
|
499
|
-
logger.error(f"Failed to upload file: {str(e)}")
|
|
500
|
-
return {"object_key": None, "url": None}
|