python-slack-sdk
python-slack-sdk copied to clipboard
files.upload API return {'ok': False, 'error': 'error_creating_file_sync'}
filepath = "test.file" # about 300Mb r = client.files_upload(file=open(filepath, "rb"), channels="MYCHANNELID") print(r.data)
error: slack_sdk.errors.SlackApiError: The request to the Slack API failed. (url: https://www.slack.com/api/files.upload) The server responded with: {'ok': False, 'error': 'error_creating_file_sync'}
what means "error_creating_file_sync" ?????
@nkj2001 - The error just means that Slack failed to create your file (the sync part just means that it attempted to create your file synchronously). Looking at your example code supplied, open
method appears to return a python file object which you are supplying as file
. If I were to guess, you should be sending text data instead.
Does this work?
r = client.files_upload(file=open(filepath, "rb").read(), channels="MYCHANNELID")
@srajiang
def files_upload(
self,
*,
file: Optional[Union[str, bytes, IOBase]] = None,
content: Optional[str] = None,
filename: Optional[str] = None,
filetype: Optional[str] = None,
initial_comment: Optional[str] = None,
thread_ts: Optional[str] = None,
title: Optional[str] = None,
channels: Optional[Union[str, Sequence[str]]] = None,
**kwargs,
) -> SlackResponse:
file is not a problem. And for roughly 150-200 mega files, there's no problem.
app.client.files_upload(file=filepath, channels="CHANNEL_ID")
app.client.files_upload(file=open(filepath, "rb"), channels="CHANNEL_ID")
app.client.files_upload(file=open(filepath, "rb").read(), channels="CHANNEL_ID")
requests.post('https://slack.com/api/files.upload', data=data, files={"file": open(filepath, "rb")}, headers=headers)
requests.post('https://slack.com/api/files.upload', data=data, files={"file": open(filepath, "rb").read()}, headers=headers)
requests.post('https://slack.com/api/files.upload', data=data, files=files, headers=headers)
There are many more methods I've tested. But the problem was not resolved.
@nkj2001 - I see you closed the issue, so I'm assuming you were able to resolve the error you were seeing 🎉
But for the benefit of others' future reference would you please confirm what you changed?
@nkj2001 - Alright, thanks for clarifying. So you're not having issues with files 150-200MB, but larger than that you're getting the error back? There is an outstanding bug server-side which we are aware of that might be related to this.
Here's a possible related thread (though I will note in this case the file upload appears to succeed, even though an error is thrown https://github.com/slackapi/python-slack-sdk/issues/1165). It's a bit confusing because different users are reporting different behavior, so thanks for your patience.
Also, can you turn on debug logging on your app and provide the system logs you're getting when you receive your errors?
@srajiang
from slack_sdk import WebClient
client = WebClient(SLACK_USER_TOKEN, timeout=7000)
filepath = "C:\\test.300mb.mp4"
channel_id = "CHANNELID"
r = client.files_upload(file=open(filepath, "rb").read(), channels=channel_id)
print(r.data)
If run the code
r = client.files_upload(file=open(filepath, "rb").read(), channels="**********")
File "C:\Python310\lib\site-packages\slack_sdk\web\client.py", line 2995, in files_upload
return self.api_call("files.upload", files={"file": file}, data=kwargs)
File "C:\Python310\lib\site-packages\slack_sdk\web\base_client.py", line 145, in api_call
return self._sync_send(api_url=api_url, req_args=req_args)
File "C:\Python310\lib\site-packages\slack_sdk\web\base_client.py", line 182, in _sync_send
return self._urllib_api_call(
File "C:\Python310\lib\site-packages\slack_sdk\web\base_client.py", line 324, in _urllib_api_call
).validate()
File "C:\Python310\lib\site-packages\slack_sdk\web\slack_response.py", line 205, in validate
raise e.SlackApiError(message=msg, response=self)
slack_sdk.errors.SlackApiError: The request to the Slack API failed. (url: https://www.slack.com/api/files.upload)
The server responded with: {'ok': False, 'error': 'error_creating_file_sync'}
An error occurs when the file exceeds 230-300 megabytes. Socket mode and HTTP mode are the same. Using slack_sdk, slack_bolt or calling directly with requests or equivalent. The server always returned the same result when sending the file using all available methods.
filepath = "C:\\test.300MB.mp4"
C_ID = "CHANNELID"
with open(filepath, "rb") as f:
headers={"Authorization": "Bearer {}".format(SLACK_BOT_TOKEN)}
r = requests.post(
'https://slack.com/api/files.upload',
data={"title": "TEST", "channels": C_ID},
files={"file": f},
headers=headers
)
print(r.text)
If I send a file using the requests library
{"ok":false,"error":"error_creating_file_sync"}
requests didn't throw any errors and the server just returns this status.
Okay @nkj2001 - Thanks for providing the additional detail, I am confident that this is server-side issue and not an issue with the SDK tooling. I will raise the isue (again) to those internal teams about the behavior you're seeing to get this on their radar and mark this issue with a flag to keep it open until we find a resolution.
@srajiang Thank you for your interest.
Hi, any update on this by any chance? I see the exact same behavior, 125MB file upload works correctly, but 250MB upload encounters the
{'ok': False, 'error': 'error_creating_file_sync'}
Our code issues several retries with some exponential backoff in between, but each retry encounters the same issue.
Hi all, let me share some updates on this issue.
Firstly, sincere apologies for taking a long time to resolve this issue on the Slack platform side. We do understand that this issue has been critical for many people.
As a solution, we just released v3.19.0, which includes a new method named WebClient#files_upload_v2()
. This new method is much stabler and is mostly compatible with the existing files_upload()
method. Please migrate to the new method if your app is affected by the server-side performance issue described here. Here is an example code demonstrating how to use the v2 method:
response = client.files_upload_v2(
file="./logo.png",
title="New company logo",
# Note that channels still works but going with channel="C12345" is recommended
# channels=["C111", "C222"] is no longer supported. In this case, an exception can be thrown
channels=["C12345"],
initial_comment="Here is the latest version of our new company logo :wave:",
)
The new method eliminates the timeouts. In addition, it enables 3rd party app developers to upload multiple files like humans do in Slack clients. This feature addition can be useful for many use cases. Here is a simple example code:
response = client.files_upload_v2(
file_uploads=[
{
"file": "./logo.png",
"title": "New company logo",
},
{
"content": "Minutes ....",
"filename": "team-meeting-minutes-2022-03-01.md",
"title": "Team meeting minutes (2022-03-01)",
},
],
channel="C12345",
initial_comment="Here is the latest version of our new company logo :wave:",
)
response.get("files") # returns the full metadata of all the uploaded files
Please refer to the release notes for more details: https://github.com/slackapi/python-slack-sdk/releases/tag/v3.19.0
Worth mentioning that unlike the previous function (files_upload
), the new function (files_upload_v2
) expects and supports only a channel ID and not a channel name.
How come files:read
is also needed even though it successfully uploads the file without it?
@elongl For better compatibility with legacy files.upload
, the v2 method calls files.info to fetch the uploaded files' full metadata. We know that some people do not want to have files:read
scope for the purpose, so in the upcoming patch release, you can pass request_file_info=False to the method to disable the file metadata loading part. Refer to https://github.com/slackapi/python-slack-sdk/issues/1277 and https://github.com/slackapi/python-slack-sdk/pull/1282 for more details.
Thanks a lot for the explanation.
I'd appreciate it if you could explain,
if files.upload
previously returned the files' full metadata without the files:read
scope.
Why is it no longer possible now?
@elongl It is due to Slack server-side reasons and we won't change it, unfortunately. The underlying files.completeUploadExternal
API method, which is part of files_upload_v2, works with only files:write
scope, but it returns only file's ID and title unlike the legacy one. To mitigate developers' surprise here, the v2 method fetches other properties using files:read
.
By the way, this issue is already closed. If you have further questions, please start a new question issue for it.
Hello i have no exactly problem like that, but similar. I have cicle of files upload, and when files in my cicle is too big only first file was loaded and gave me mistake in responce, in thi case i use something like that, mayby it can help someone:
client_slack = AsyncWebClient(token=os.environ.get("SLACK_BOT_TOKEN"))
for df in dfs:
buff = BytesIO()
df.to_csv(buff, index=False)
buff.seek(0)
try:
await client_slack.files_upload(
file=buff,
channels=channel_id,
filename="some name",
filetype='csv')
except Exception as err:
print(f"{err} error slack")
With exaption all files loaded, no limits for size.
I'm getting an error while using client.files_upload_v2
method when I use a dataframe in content
to be sent as a csv file.
The code:-
client.files_upload_v2( channel = "Channel ID", initial_comment = "Have fun analysing my csv file! :stuck_out_tongue:", filename = "filename.csv", content = df)
This is the error:-
/databricks/python/lib/python3.8/site-packages/slack_sdk/web/client.py in files_upload_v2(self, filename, file, content, title, alt_txt, snippet_type, file_uploads, channel, initial_comment, thread_ts, request_file_info, **kwargs)
3092 files.append(_to_v2_file_upload_item(f))
3093 else:
-> 3094 f = _to_v2_file_upload_item(
3095 {
3096 "filename": filename,
/databricks/python/lib/python3.8/site-packages/slack_sdk/web/internal_utils.py in _to_v2_file_upload_item(upload_file)
332 data = content
333 else:
--> 334 raise SlackRequestError("content for file upload must be 'str' (UTF-8 encoded) or 'bytes' (for data)")
335
336 filename = upload_file.get("filename")
SlackRequestError: content for file upload must be 'str' (UTF-8 encoded) or 'bytes' (for data)
@vesuvius13
content for file upload must be 'str' (UTF-8 encoded) or 'bytes' (for data)
As this error message indicates, a dataframe object is not supported for the content parameter. Please convert the data to either str or byte array before passing it.
@vesuvius13
content for file upload must be 'str' (UTF-8 encoded) or 'bytes' (for data)
As this error message indicates, a dataframe object is not supported for the content parameter. Please convert the data to either str or byte array before passing it.
But it was supported under files_upload
right?
@vesuvius13 Thanks for sharing this. Indeed, the validation did not exist in the legacy one. But the legacy one does not intentionally support the data structure (at least we don't have any unit tests for it). I hear you on the frustration but please convert the data to any of the compatible ones when migrating to v2.