Forums

Folder created automatically on pythonanywhere source code directory

In my flask.cfg folder, I have the following setting:

MEDIA_ROOT = '/home/ujahdotpy/xy/xyz/project/static/img/images/'
MEDIA_URL = '/static/img/images/'

And my URL and Directory on my web tab as:

  /home/ujahdotpy/xyz/xyz/project/static/img/images/
 /static/img/images/

My problem is when I upload a new image file, a new 'images' folder is created and the newly uploaded image is stored in it making it inaccessible when I try to view it online.

How can I solve this?

do you mean the url is

/static/img/images/

and the directory is

/home/ujahdotpy/bulk/bulkieshare/project/static/img/images/

where is the new images folder created?

@Conrad, it is created inside the existing images folder so that I have something like this:

/home/ujahdotpy/bulk/bulkieshare/project/static/img/images/images/

I don't see a static file mapping setup on your webapp.

@conrad, @Dullong advise I remove it

if you want to serve static files the best way would be to setup a static file mapping.

please give the mapping url + directory, and sample image path on your file system, and the sample url endpoint that you are trying to access to see it the image online.

How to create a folder through of script?

r/engrish

I tried with os.mkdir() but it won't work.

What error are you getting? If you are getting a FileExistsError, you can safely ignore it:

try:
    os.mkdir(pathname)
except FileExistsError:
    pass

You can see errors from your Python code in the error log, which can be found in the web tab. You also have to remember to reload your web app whenever you make changes to code or static file mappings.

OSError: write error

Maybe you can try doing chmod +w command on one of the parent directories

Actually that probably won't work. I did some testing myself and got PermissionError instead of OSError

Actually my code snippet is like this:

dir_name = data["folder"]
if dir_name not in os.listdir(app.config["STATIC_PATH"]):
  os.chdir(app.config["STATIC_PATH"])
  os.mkdir(dir_name)

It's generally not a good idea to change the working directory when inside website code -- it just gives you one extra bit of global state to worry about it. It would also probably make things easier to debug if you print out the variables that specify the directory you're trying to create.

So I'd suggest reworking the code to be:

dir_name = data["folder"]
print("dir_name is {!r}".format(dir_name))
print("STATIC_PATH is {!r}".format(app.config["STATIC_PATH"]))
if dir_name not in os.listdir(app.config["STATIC_PATH"]):
    os.mkdir(os.path.join(app.config["STATIC_PATH"], dir_name))

The output from those print statements will appear in the website's server log, so you can check them out and see if they're what you expect them to be. If you're still confused, let us know what the variables' values are.

I changed but it still won't work, the same error. Where can I to see print() output?

In the server log, which you can find through the web tab.

There is no output for print(). SocketIO works well on pythonanywhere?

You could also try using sys.stderr.write() and find the output in the error log

@rjunior8 Are there any other error messages in our /var/log/rjunior8.pythonanywhere.com.error.log?

I figured out. The problem is that pythonanywhere doens't support websockets like SocketIO.

add_monitor.html

var socket = io.connect(document.location.origin + '/create_folder');

$(document).ready(function(){
  $('#create_dir').on('click', function(){
    $('#create_folder').modal('hide');
    socket.emit('/create/folder', {'folder' : $('#folder').val()});
  });
});

routes.py

@socketio.on("/create/folder", namespace="/create_folder")
def create_folder(data):
  try:
    dir_name = data["folder"]
    if dir_name not in os.listdir(app.config["STATIC_PATH"]):
      os.chdir(app.config["STATIC_PATH"])
      os.mkdir(dir_name)
      emit("created_folder", {"result" : "success"}, broadcast=False)
    else:
      emit("created_folder", {"result" : "failure"}, broadcast=False)
  except Exception as e:
    print("\n\n{}\nERROR ON LINE: {}\n".format(e, sys.exc_info()[-1].tb_lineno))
    emit("created_folder", {"result" : "failure"}, broadcast=False)

The create_folder() function is not called because the socket fails.

Ah. Ok. Glad you tracked it down.

Hey guys, I told you that pythonanywhere doens't support websockets like SocketIO but is lie. I just to test and it worked (SocketIO). Now I'll to try to figure out the trouble OSError: write error.

I think the two problems are related. We don't officially WebSockets, but SocketIO can fail over to using long-poll HTTP/HTTPS as an alternative. The way that works is that your JavaScript code will make a request to your website, and then keep the connection open -- the server will also keep it open, so it can then feed data back along that connection.

However, it's unlikely to work well. Your website has one worker process handling all requests (if you had a paid account you'd have two or more processes). When a request comes in, the worker starts handling it, and will continue to do so until the connection is closed.

What this means is that while your JavaScript code and the server are keeping a request open so that SocketIO can send data back and forth, your worker process is busy handling that one connection. Any further requests that come in for your site will be blocked until the connection is broken.

So while you might be able to get an experimental site up and running, it certainly would not work well in practice.

The OSError: write error that you're seeing is related. If our system detects that a worker process has spent more than five minutes processing a request, it assumes that it has crashed and restarts it. When that happens, the way that the connections are shut down will generate an error like that in the logs. So I think what's happening is that your JS code and the server are trying to keep the connection open, and then after five minutes the timeout cuts in.

Regardless of anything, when to use websockets like SocketIO? Because my system uses SocketIO for everything instead of ajax post or Flask post.

If that's how your site works, then unfortunately it won't work on PythonAnywhere right now.

If your question is more of a general one, that is, when is it best to use SocketIO instead of regular HTTP, I'd say that the answer is, when you need to push data from the server to the client. Normal GET/POST requests are good enough when you're sending data from the client to the server.

Got it. Thank you all for yours answers.

I'm trying to create folder through Flask app like this:

config.py

UPLOAD_ROOT = "static/files/"

routes.py

UPLOADS = os.path.join(app.root_path, app.config["UPLOAD_ROOT"])

@app.route("/add/process", methods=["GET", "POST"])
def add_process():
  if request.method == "POST":
    if "filesToUpload[]" in request.files:
      ref_dir = ref.replace('/', '-')
      if ref_dir not in os.listdir(UPLOADS):
        os.mkdir(UPLOADS + ref_dir)
      for f in request.files.getlist("filesToUpload[]"):
        file_path = os.path.join(UPLOADS, ref_dir, f.filename)
        f.save(file_path)

But it won't to create it. And no error message. No message on access.log nor error.log and nor server.log. PS: "static/files" already created. By the way... this application is running on my local machine and is working perfectly.

You need to add some logging to your code to see what happens.

It doesn't worked but I figured out. The problem is with Firefox. On Chrome it worked well without changes.

Good to hear that it works now.