Search code examples
pythontwittertweepy

Upload media on Twitter using Tweepy with Python


I'm trying to catch a picture from an Url and post it on twitter But I got this error that makes me anxious.

TypeError: expected str, bytes or os.PathLike object, not JpegImageFile

from PIL import Image
import urllib.request
import tweepy

def get_picture(picture,file_path):
    full_path = file_path + '.jpg'
    urllib.request.urlretrieve(picture,full_path)



def twitter_api():
    consumer_key = 'XXXXXXXXXXXXXX'
    consumer_secret = 'XXXXXXXXXXXXXX'
    access_token = 'XXXXXXXXXXXXXXXXXXX'
    access_token_secret = 'XXXXXXXXXXXXXXXXXXXXXXX'
    auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
    auth.set_access_token(access_token, access_token_secret)
    api = tweepy.API(auth)
    return api



picture = (f"https://www.iheartradio.ca/image/policy:1.15731844:1627581512/rick.jpg?f=default&$p$f=20c1bb3")
path=r'C:\....\...\....\.......\images\.jpg'


text=("Youpi It works!")

get_picture(picture,"images/")
imageok=picture=Image.open(path)
twitter_api().update_status_with_media(text,imageok)

Will appreciate if anybody got a clue !


Solution

  • Forget Pillow. It needs path to image on disk (as str, bytes or os.PathLike object)

    twitter_api().update_status_with_media(text, path_to_image)
    

    but you put Pillow.Inage which is JpegImageFile and you have it in error message

    expected str, bytes or os.PathLike object, not JpegImageFile
    

    Full working code

    import urllib.request
    import tweepy
    import os
    
    def get_picture(url, full_path):
        urllib.request.urlretrieve(url, full_path)
    
    def twitter_api():
        consumer_key = os.getenv('TWITTER_CONSUMER_KEY')
        consumer_secret = os.getenv('TWITTER_CONSUMER_SECRET')
        access_token = os.getenv('TWITTER_ACCESS_TOKEN')
        access_token_secret = os.getenv('TWITTER_ACCESS_TOKEN_SECRET')
    
        auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
        auth.set_access_token(access_token, access_token_secret)
    
        api = tweepy.API(auth)
        
        return api
    
    # --- main ---
    
    url = f"https://www.iheartradio.ca/image/policy:1.15731844:1627581512/rick.jpg?f=default&$p$f=20c1bb3"
    #path = r'C:\....\...\....\.......\images.jpg'
    path = 'images.jpg'
    
    text = "Youpi It works!"
    
    get_picture(url, path)
    
    twitter_api().update_status_with_media(text, path)
    

    And if you want to send file without saving on disk or generated with Pillow then it has option file= which can get open file or object io.BytesIO - and then you can put data from internet directly to io.BytesIO and use it without saving on disk

    import urllib.request
    import tweepy
    import os
    import io
    
    def twitter_api():
        consumer_key = os.getenv('TWITTER_CONSUMER_KEY')
        consumer_secret = os.getenv('TWITTER_CONSUMER_SECRET')
        access_token = os.getenv('TWITTER_ACCESS_TOKEN')
        access_token_secret = os.getenv('TWITTER_ACCESS_TOKEN_SECRET')
    
        auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
        auth.set_access_token(access_token, access_token_secret)
    
        api = tweepy.API(auth)
        
        return api
    
    # --- main ---
    
    url = "https://www.iheartradio.ca/image/policy:1.15731844:1627581512/rick.jpg?f=default&$p$f=20c1bb3"
    
    text = "Testing module tweepy"
    
    data = urllib.request.urlopen(url).read()
    file_like_object = io.BytesIO(data)
                  
    twitter_api().update_status_with_media(text, 'fake_name.jpg', file=file_like_object)
    

    Example which use Pillow to convert image to grayscale and send to twitter - all without saving files on disk.

    from PIL import Image
    import urllib.request
    import tweepy
    import os
    import io
    
    def twitter_api():
        consumer_key = os.getenv('TWITTER_CONSUMER_KEY')
        consumer_secret = os.getenv('TWITTER_CONSUMER_SECRET')
        access_token = os.getenv('TWITTER_ACCESS_TOKEN')
        access_token_secret = os.getenv('TWITTER_ACCESS_TOKEN_SECRET')
    
        auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
        auth.set_access_token(access_token, access_token_secret)
    
        api = tweepy.API(auth)
        
        return api
    
    # --- main ---
    
    url = "https://www.iheartradio.ca/image/policy:1.15731844:1627581512/rick.jpg?f=default&$p$f=20c1bb3"
    
    text = "Testing module tweepy"
    
    data = urllib.request.urlopen(url).read()
    file_like_object = io.BytesIO(data)
    
    image = Image.open(file_like_object)
    #image.show()
    
    grayscale = image.convert('L')
    #grayscale.show()
    
    file_like_object = io.BytesIO()
    grayscale.save(file_like_object, 'jpeg')
    file_like_object.seek(0)  # move to the beginning of file
    
    twitter_api().update_status_with_media(text, 'fake_name.jpg', file=file_like_object)