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

Upload a file #64

Closed
jonathan-s opened this issue Feb 16, 2016 · 31 comments
Closed

Upload a file #64

jonathan-s opened this issue Feb 16, 2016 · 31 comments

Comments

@jonathan-s
Copy link

It says here: https://api.slack.com/methods/files.upload that files need to be uploaded via multipart/form-data, which it looks like the current client doesn't support.

If we moved to requests #54, it would make it easier to use their files argument for that.

@prongs
Copy link

prongs commented Mar 10, 2016

Have you found a workaround for that?

@prongs
Copy link

prongs commented Mar 10, 2016

I see that's merged. So can you paste sample code for upload?

@MidTin
Copy link

MidTin commented Mar 30, 2016

@jonathan-s It works when using the argument 'content' instead of 'file'.

@prongs
Copy link

prongs commented Mar 30, 2016

I tried to upload an image like this. It uploaded alright, but it uploaded as a text file. How do I upload an image?

@MidTin
Copy link

MidTin commented Mar 30, 2016

You should override the method 'do' of slackclient._slackrequest.SlackRequest, make it looks like this:

@staticmethod
- def do(token, request="?", post_data=None, domain="slack.com"):
+ def do(token, request="?", post_data=None, domain="slack.com", **kwargs):
       if post_data is None:
            post_data = {}

       return requests.post(
           'https://{0}/api/{1}'.format(domain, request),
           data=dict(post_data, token=token),
+          **kwargs
       )

and you can upload an image like this:

with open('my_image.png', 'rb') as f:
    client.api_call('files.upload', channels=[...], filename='pic.png', files={'file': f})

@MidTin
Copy link

MidTin commented Mar 30, 2016

@prongs oh, sorry. Only overrides the method 'do' of slackclient._slackrequest.SlackRequest is not enough,the method 'api_call' of slackclient._client.SlackClient should be overrided too.

@prongs
Copy link

prongs commented Mar 30, 2016

Can't someone put a pull request for this? I'd spent 3-4 hours on this last and couldn't get it right.

@lcd1232
Copy link

lcd1232 commented Apr 2, 2016

Easy way. Change file _slackrequest.py to this

import requests


class SlackRequest(object):

    @staticmethod
    def do(token, request="?", post_data=None, domain="slack.com"):
        if post_data is None:
            post_data = {}

        if "files" in post_data:
            temp = {element:post_data[element] for element in post_data if not "files" in element}
            return requests.post(
            'https://{0}/api/{1}'.format(domain, request),
            data=dict(temp, token=token), files=post_data["files"]
            )
        else:
            return requests.post(
                'https://{0}/api/{1}'.format(domain, request),
                data=dict(post_data, token=token),
            )
files = {'file': open('test.png', 'rb')}
client.api_call('files.upload', channels=[...], filename='pic.png', files=files)

@prongs
Copy link

prongs commented Apr 2, 2016

Thanks, it worked. Do you wanna post it as a pull request? If not, can I post it?

@lcd1232
Copy link

lcd1232 commented Apr 2, 2016

I can but I don't know how

On Sat, Apr 2, 2016, 16:56 Rajat Khandelwal notifications@github.com
wrote:

Thanks, it worked. Do you wanna post it as a pull request? If not, can I
post it?


You are receiving this because you commented.
Reply to this email directly or view it on GitHub
#64 (comment)

@prongs
Copy link

prongs commented Apr 2, 2016

Just fork the repo, make changes and push those in your fork. Then click on New pull request on https://github.com/slackhq/python-slackclient. If stuck, internet is your friend. I found one tutorial: https://yangsu.github.io/pull-request-tutorial/

@rgreasons
Copy link

Has anyone tried doing this since this issue was closed? I'm getting some errors when trying to send a file. Looks like in the time between this was closed and python 2 & 3 has been included via six. The new out-of-the-box logic now tries to serialize the JSON file.

@liuhenry
Copy link

@rgreasons looks like this is fixed by 5766321 but there hasn't been a PyPI release yet

@Yasumoto
Copy link
Contributor

A new version was pushed to pypi thanks to @jammons !

@SadE54
Copy link

SadE54 commented Oct 27, 2016

I still got the error with the 1.0.2 :-/
TypeError: <_io.BufferedReader name='test.txt'> is not JSON serializable

@dj80hd
Copy link

dj80hd commented Nov 9, 2016

@SadE54 Yup. I confirmed still an issue with 1.0.2 as well

@Wouter0100
Copy link

@SadE54 I can confirm this as well in the latest pypi release.

@Roach Roach added the bug label Nov 22, 2016
@heejune
Copy link

heejune commented Dec 19, 2016

For those who're still experiencing this,

Instead of following,

files = {'file': open('test.png', 'rb')}
client.api_call('files.upload', channels=[...], filename='pic.png', files=files)

Try this:

client.api_call('files.upload', channels=[...], filename='pic.png', files=open('test.png', 'rb'))

  1. channels param requires a single string, not a list
  2. files param should be a file object, not a dict

For example, I successfully uploaded a plain text file through:

self.sc.api_call("files.upload", filename='result.txt', channels='#somechannel', file= io.BytesIO(str.encode(content)))

@Jacob-Dixon
Copy link

Heejune is just about right. In version 1.0.2 it expects 'file', NOT ''files'. So typing:
client.api_call('files.upload', channels=[...], filename='pic.png', files=open('test.png', 'rb'))
will currently give you a JSON serializable error. But:
client.api_call('files.upload', channels=[...], filename='pic.png', file=open('test.png', 'rb'))
works just fine.

@qria
Copy link

qria commented Apr 7, 2017

Those of you still getting JSON serializable error, check if you aren't calling 'file.upload' instead of 'files.upload'.

Pretty stupid, I know, but it took me a good one hour to realize this error.

@stianlp
Copy link

stianlp commented Oct 22, 2017

I cannot figure out how to upload a file. I am getting 200 and ok: True, but no success uploading the file to the channel.

self.slack_client.api_call('files.upload',
channel='notifications',
filename='heeeelooo.jpg',
file=open('heeeelooo.jpg', 'rb'))

Using kwarg file and not files.

Sending text messages works fine.

Anyone with similar issues?

EDIT: If I try to open any of the urls I get: The requested file could not be found.

@alexandraj777
Copy link

FWIW I'm using slackclient 1.0.9 and I just successfully used the following code to upload a file via a bot user:

from slackclient import SlackClient
sc = SlackClient(SLACK_TOKEN)
sc.api_call(
  'files.upload', 
  channels='#slacktesting', 
  as_user=True, 
  filename='pic.jpg', 
  file=open('puppy.jpg', 'rb'),
)

@stianlp Is 'notifications' a channel? If so, you might need to use '#notifications' to get your code to work.

@stianlp
Copy link

stianlp commented Oct 26, 2017

I tried with # and without, couldn't find out how to make it work, so I gave up.

Used requests instead, and it's working perfectly:

r = requests.post('https://slack.com/api/files.upload',
                          data={'token': self.bot_token, 'channels': [self.channel],
                                'title': 'Analysis Graph'},
                          files={'file': open(file_path, 'rb')})

Is anyone else have trouble, you can always just send a request like the code above.

@jonathan-s
Copy link
Author

jonathan-s commented Oct 26, 2017 via email

@tsando
Copy link

tsando commented Dec 4, 2017

also for me the only way it worked was by adding as_user=True to the api call as suggested by @alexandraj777. If you don't do this, then the call doesn't throw an error but the file is uploaded as private, so not visible in the channel to others

@nicolaskern
Copy link

The solution given by @alexandraj777 works like a charm.
However, having as_user or not makes the image always uploaded by an user, and not the slackbot.

@alexandraj777
Copy link

Huh, from @tsando's and @nicolaskern's responses I'm starting to think the as_user option might have a different outcome depending on the account/integration the SLACK_TOKEN is linked to. SLACK_TOKEN in my code snippet is for a bot user.

@qajay
Copy link

qajay commented Jul 5, 2018

Perhaps others were not making the silly mistake I was, but I saw the same issue (uploaded files were always private) and fixed it. It turns out I had copied my code from a chat.message call. So, I was using "channel" instead of "channels" so I wasn't actually posting the file to a channel. Once I realized my error and used "channels" it worked perfectly and the file was public. I'll swallow my pride and admit my dumb mistake in the hopes that it might help someone else.

@rampageai
Copy link

Some clarifications that helped me:

  1. I am using slackclient 1.2.1
  2. I am POSTing a file as a bot
  3. I am using an in-memory buffer with io.BytesIO that is generated from a PIL.Image drawn beforehand
# replace with your channel code or name
channel="C111111"

# Example of an image created beforehand using Python PIL.Image
content = io.BytesIO()
image.save(content, "PNG")

slack_client.api_call("files.upload",
  channels=channel,
  file=content.getvalue(),
  filename="mypicture.png",
  as_user=True)

@TaiLouis
Copy link

TaiLouis commented Dec 2, 2018

Thank you @alexandraj777 it save my day

@tauh33dkhan
Copy link

Thanks @alexandraj777.

To make that script work with bot just change as_user to as_bot

from slackclient import SlackClient
SLACK_TOKEN = "your bot token"
sc = SlackClient(SLACK_TOKEN)
sc.api_call(
  'files.upload', 
  channels='#slackchannel', 
  as_bot=True, 
  filename='mypicture.jpg', 
  file=open('mypicture.jpg', 'rb'),
)

c-goosen pushed a commit to c-goosen/python-slackclient that referenced this issue Jun 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests