Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

files.upload API return {'ok': False, 'error': 'error_creating_file_sync'} #1191

Closed
nkj2001 opened this issue Mar 14, 2022 · 19 comments
Closed
Assignees
Labels
auto-triage-skip bug M-T: A confirmed bug report. Issues are confirmed when the reproduction steps are documented server-side-issue Version: 3x web-client
Milestone

Comments

@nkj2001
Copy link

nkj2001 commented Mar 14, 2022

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" ?????

@srajiang
Copy link
Contributor

srajiang commented Mar 14, 2022

@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 srajiang added question M-T: User needs support to use the project and removed untriaged labels Mar 14, 2022
@nkj2001
Copy link
Author

nkj2001 commented Mar 14, 2022

@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 nkj2001 closed this as completed Mar 14, 2022
@srajiang
Copy link
Contributor

@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 nkj2001 reopened this Mar 14, 2022
@srajiang
Copy link
Contributor

@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 #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?

@nkj2001
Copy link
Author

nkj2001 commented Mar 15, 2022

@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.

@srajiang
Copy link
Contributor

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.

@nkj2001
Copy link
Author

nkj2001 commented Mar 15, 2022

@srajiang Thank you for your interest.

@willAIZ
Copy link

willAIZ commented Mar 25, 2022

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.

@seratch seratch added this to the 3.19.0 milestone Oct 3, 2022
@seratch seratch added bug M-T: A confirmed bug report. Issues are confirmed when the reproduction steps are documented web-client Version: 3x and removed question M-T: User needs support to use the project labels Oct 3, 2022
@seratch seratch self-assigned this Oct 3, 2022
@seratch
Copy link
Member

seratch commented Oct 5, 2022

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

@seratch seratch closed this as completed Oct 5, 2022
@elongl
Copy link

elongl commented Oct 26, 2022

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.

@elongl
Copy link

elongl commented Oct 26, 2022

How come files:read is also needed even though it successfully uploads the file without it?

@seratch
Copy link
Member

seratch commented Oct 26, 2022

@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 #1277 and #1282 for more details.

@elongl
Copy link

elongl commented Oct 26, 2022

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?

@seratch
Copy link
Member

seratch commented Oct 26, 2022

@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.

@Gluzdovska13
Copy link

Gluzdovska13 commented Jan 9, 2023

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.

@vesuvius13
Copy link

vesuvius13 commented Mar 6, 2023

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)

@seratch
Copy link
Member

seratch commented Mar 6, 2023

@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
Copy link

@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?

@seratch
Copy link
Member

seratch commented Mar 6, 2023

@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.

kylegwlawrence added a commit to kylegwlawrence/fridge-dev that referenced this issue May 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-triage-skip bug M-T: A confirmed bug report. Issues are confirmed when the reproduction steps are documented server-side-issue Version: 3x web-client
Projects
None yet
Development

No branches or pull requests

7 participants