question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

files_upload_v2 does not work with io.BytesIO file parameters

See original GitHub issue

Is this type hint correct? I tried to pass in a io.BytesIO object here as the file as I thought IOBase covers that as well as a real file handle (e.g. from open("filename", "rb")) - but it failed with TypeError: object of type '_io.BytesIO' has no len() - len comes from _to_v2_file_upload_item I believe. So either the type hint is incorrect or the implementation of _to_v2_file_upload_item needs tweaking? You could probably just do something like this?

def _to_v2_file_upload_item(upload_file: Dict[str, Any]) -> Dict[str, Optional[Any]]:
    file = upload_file.get("file")
    content = upload_file.get("content")
    data: Optional[bytes] = None
    if file is not None:
        if isinstance(file, str):  # filepath
            with open(file.encode("utf-8", "ignore"), "rb") as readable:
                data = readable.read()
        elif isinstance(file, io.IOBase):
            # new stuff
            data = file.read()
            if isinstance(data, str):
                data = data.encode()
        elif isinstance(file, bytes):
            data = file
        else:
            raise SlackRequestError("The given file must be either a filepath as str or data as bytes/IOBase")
    elif content is not None:
        if isinstance(content, str):  # str content
            data = content.encode("utf-8")
        elif isinstance(content, bytes):
            data = content
        else:
            raise SlackRequestError("The given content given as str or as bytes")

    filename = upload_file.get("filename")
    if upload_file.get("filename") is None and isinstance(file, str):
        # use the local filename if filename is missing
        if upload_file.get("filename") is None:
            filename = file.split(os.path.sep)[-1]
        else:
            filename = "Uploaded file"

    title = upload_file.get("title", "Uploaded file")
    if data is None:
        raise SlackRequestError(f"File content not found for filename: {filename}, title: {title}")

    if title is None:
        title = filename  # to be consistent with files.upload API

    return {
        "filename": filename,
        "data": data,
        "length": len(data),
        "title": title,
        "alt_txt": upload_file.get("alt_txt"),
        "snippet_type": upload_file.get("snippet_type"),
    }

_Originally posted by @Alex-ley-scrub in https://github.com/slackapi/python-slack-sdk/pull/1272#discussion_r1008760159_

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
WilliamBergamincommented, Nov 2, 2022

Hi @Alex-ley-scrub from what I know there are limitations with the initial_comment not supporting markdown for the near future.

If I understand your use case correctly I would tend to use client.files_upload_v2 with the appropriate files:read scope and use client.chat_postMessage over initial_comment to post the message to a channel with multiple files. If this fails files_upload is still a valid option

1reaction
eddygcommented, Nov 2, 2022

Yes, in that case you will need to add the files:read scope to the app (see this comment for an explanation), or continue to use the legacy files_upload method and accept the reliability issues.

Read more comments on GitHub >

github_iconTop Results From Across the Web

io — Core tools for working with streams — Python 3.11.1 ...
Finally, StringIO is an in-memory stream for text. Argument names are not part of the specification, and only the arguments of open() are...
Read more >
Error using io.StringIO() and io.BytesIO() - Stack Overflow
I'm trying to read a .pptx file from an AWS s3 bucket, change the underlying data for the ...
Read more >
files.upload API return {'ok': False, 'error ... - GitHub
Looking at your example code supplied, open method appears to return a python file object which you are supplying as file . If...
Read more >
Python io - BytesIO, StringIO - DigitalOcean
It takes input POSIX based arguments and returns a file descriptor which represents the opened file. It does not return a file object;...
Read more >
django.core.files.uploadhandler - Django documentation
Base file upload handler classes, and the built-in concrete subclasses """ import os from io import BytesIO from django.conf import settings from ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found