Forums

How To Get Pillow To Work With PythonAnywhere

I'm stumped.

I would like to make an app using Pillow - but right now I just want to get it to work.

This code is supposed to grab an image from my static files folder and then save it back into the folder with a different name:

from flask import Flask
from PIL import Image

app = Flask(__name__)

@app.route('/')
def hello_world():
    image = Image.open('/static/180px-A_sunflower.jpg')
    image.save('/static/new_image.jpg')
    return 'Hello from Flask! <br> <img src="/static/180px-A_sunflower.jpg">'

The error log says no file or directory found for /static/180px-A_sunflower.jpg -- but when I put that file in the return html it does work and is displayed on the webpage. What do you think I'm missing here?

Remove the slash from the beginning of the paths (static/ instead of /static/). The slash at the beginning makes the path relative to the root of the whole filesystem.

But keep the slash in the img src thing

I removed the 2 slashes - but it still does not work. Maybe I have more than one thing going wrong here...

Do I need to do anything else to use Pillow? It's supposed to be part of the "batteries included" list - so all I did was what you see in the code. I did check it in the console and it does have a path that seems correct. I just want to be sure I have that ok - then I know the problem is with the code.

Updated code to this:

from flask import Flask
from PIL import Image
app = Flask(__name__)

@app.route('/')
def hello_world():
    image = Image.open('static/180px-A_sunflower.jpg')
    image.save('static/new_image.jpg')
    return 'Hello from Flask! <br> <img src="/static/180px-A_sunflower.jpg">'

Error log still says: No such file or directory: 'static/180px-A_sunflower.jpg'

If I have Pillow set up correctly and there is nothing wrong with the code - then maybe my static files are not set up correctly?

I@m just about to do the same thing, ie. try and get Pillow up and running here, I'll let you know how I progress,

Oh man! Got it to work!!! Give me a sec and I will type up what I was doing wrong -

ok , great, that would be really handy, thanks

here's my fairly basic site by the way, but it's growing slowly

http://madmartin.pythonanywhere.com/

So I think what was wrong is I have a 2 app account. When I went to set up the 2nd app I put everything in the same default "mysite" file. In mysite I had already set up a static folder with my sunflower .jpg.

To fix the problem I deleted the pillow app I was working on and created a new one - but this time I set it up in its own separate folder that I called "mysite2". Then I set up a new static directory and all that for just this one app.

I also had to change the path.

Here is the code that works:

from flask import Flask
from PIL import Image

app = Flask(__name__)

@app.route('/')
def hello_world():
    image = Image.open('mysite2/static/180px-A_sunflower.jpg')
    image.save('mysite2/static/new_image.jpg')
    return 'Hello from Flask! <br> <img src="/static/180px-A_sunflower.jpg">'

In hindsight, after I typed all of this up - perhaps I was just missing the "mysite/" at the beginning of my paths in my original code?

And I have to say - python is the strangest combination of "omg this is SO easy" and "omg I have no idea what is going on help"!

Anyway - Dull - thank you for your help!

And MadMartin - good luck with your project! Let me know how it goes for you!

Hey MadMartin - I like all of the horse pictures! Once you get pillow set up you can color them and add polka dots and hats and stuff - haha

at the moment, I can't get the animated gif to play on it's own -

I mean, I can save it, then play manually by clicking mouse on it, but it won't display via python

can it be made to work on the url?

thanks for looking at my site by the way

so, what I mean here is that I have this code which saves 3 pictures into a basic gif called 'anitest5'

from PIL import Image, ImageDraw, ImageFont


im = Image.open('lioness.jpg')

im.save('img01.gif')

im2 = Image.open('lioness-border.jpg')

im2.save('img02.gif')


im3 = Image.open('lioness-transpose.jpg')

im3.save('img03.gif')


print ('images to display now...')

images = [im, im2, im3]


images[0].save('anitest5.gif',
               save_all=True,
               append_images=images[1:],
               duration=5,
               loop=0)

this saves ok, but I want to get it online onto my site and 'flicker' like it does on Windows laptop when opened

actually, no worries - I've done it

I just put the gif in static and linked it to one of my pages, and it works ok

Glad to hear everyone worked it out! Here's a bit more detail about what was happening for you, @Leahstars -- basically an expanded version of what @dull was saying.

When you specify a path like static/something.png, you're saying "the file called something.png inside the static subdirectory of the current working directory". Every process has a working directory; by default for a website's code, it's /home/yourusername, but if (for example) you're running code in Bash, it will be the directory you used the cd command to navigate to. A lot of people find this confusing when they're starting out, because it's reasonable to assume that the working directory is the one containing the script that contains the code that is currently running -- but that assumption is generally wrong, unless you happen to be running the code from a Bash console where you've already used cd to navigate to the directory. This is all made more confusing by the fact that when you're starting out, very frequently you do use cd to navigate to a script, then run something like python myscript.py, so things work -- but that's really just by chance.

It's normally good practice to write your code so that it's independent of what the current working directory is. This is because the working directory can be changed by other code, and if (say) some library that you import messes around with the working directory when you're not expecting it, your code will break if you make assumptions about what it is.

The easiest (but not the best) way to avoid problems like that is to always use absolute paths. Absolute paths start with "/", and specify the location of a file from the top of the filesystem hierarchy. For example, if your code is in the mysite subdirectory of your home directory, then the absolute path to that is /home/yourusername/mysite, if it there is a directory called static inside that directory, you can find that at /home/yourusername/mysite. So if you specify a path that starts with a "/" and goes all the way down to the location of your file, it will work. (And if you put a "/" at the start of a path that isn't an absolute one from the top of the filesystem hierarch, like in your original code, it won't find the file because it will be looking in the wrong place.)

Using absolute paths is easy to do, but hard to maintain, because of course it means that if you ever change the location of your files, everything will break until you've fixed all of your paths. You could have some constant string somewhere and then add that to the start of your files, but that still won't be easy to maintain if you're sometimes running your code on your own machine, and sometimes on PythonAnywhere.

So a slightly more complicated, but generally much more maintainable way to do it is to write some code to make the path resolution actually work the way that people naturally assume it would -- that is, to have paths that are relative to the script where the code is

In Python, there is a magic variable called __file__. It's always set (unless you're typing code into an interactive console), and it always reflects the location of the file that's currently running -- that is, inside /home/yourusername/something/somethingelse/myscript.py, it will be set to the string "/home/yourusername/something/somethingelse/myscript.py", and inside /home/yourusername/mysite/myscripts/myscript2.py if will be set to "/home/yourusername/mysite/myscripts/myscript2.py"

Given that, you can work out the location of a file relative to the currently running script by using the functions in os.path. Here's how to get the full path to the directory containing the code in which it appears:

my_dir = os.path.dirname(os.path.abspath(__file__))

The os.path.abspath is there to avoid some nasty complications that I'm not going to explain here because this post is already much too long :-) The os.path.dirname, like you would expect, takes the path to a file, and returns the path to the directory containing it.

Once you have your dirname, you can use os.path.join to create paths to files relative to it. For example, if you want to say "go up one directory, then down into a directory called static, then find the file myimage.png", you would have this:

my_image_file = os.path.join(my_dir, "..", "static", "myimage.png")

Plz visit my site too: https://dull.pythonanywhere.com

Hey Dull, thanks for sharing your site! I'm disappointed that I only received a 1% love score. Oh well!

giles, thank you for such a detailed answer - I really appreciate it!

Where/how did you guys learn all of this stuff? I can make websites with html, css, js and all that stuff - and python is not too bad - but as far as consoles, bash, setting up files and directories I'm lost. I would really like to understand how this stuff works and how to use it properly - can you point me in the right direction here? I don't even know what to google. All of the tutorials and books I've read have skipped over this part of it.

why are u using os x snow leopard?

these could be helpful for you:

The Linux command line for beginners

Flask Tutorial

Ha! My computer is just really old! But I have to say, for what it is it still works pretty great!

Thank you for the tutorials! I will go through them!

who is zenny?

Excellent link, @dull -- thanks for posting those!

@Leahstars no seriously tho, u put “zenny” into the love calc on my site

Hey dull - Zenny is just a made up name. Kind of like Lenny but with a Z. You have to be careful about your private information these days! haha

Thanks again for the links - I'm going through the first one and I have already learned so much! I really do appreciate it - you have no idea!

did u check out my youtube channel?