Search code examples
pythonftpftplib

How do I use ftp.storbinary to upload a file?


I am just starting to learn Python. I'm trying to upload a file as follows:

import ftplib
myurl = 'ftp.example.com'
user = 'user'
password = 'password'
myfile = '/Users/mnewman/Desktop/requested.txt'
ftp = ftplib.FTP(myurl, user, password)
ftp.encoding = "utf-8"
ftp.cwd('/public_html/')
ftp.storbinary('STOR '+myfile, open(myfile, 'rb'))

But get the following error:

Traceback (most recent call last):
  File "/Users/mnewman/.spyder-py3/temp.py", line 39, in <module>
    ftp.storbinary('STOR '+myfile, open(myfile, 'rb'))
  File "ftplib.pyc", line 487, in storbinary
  File "ftplib.pyc", line 382, in transfercmd
  File "ftplib.pyc", line 348, in ntransfercmd
  File "ftplib.pyc", line 275, in sendcmd
  File "ftplib.pyc", line 248, in getresp
error_perm: 553 Can't open that file: No such file or directory

What does "that file" refer to and what do I need to do to fix this?


Solution

  • Reading the traceback, the error is deep in the ftp stack processing a response from the server. FTP server messages aren't standardized, but from the text its clear that the FTP server is unable to write the file on the remote side. This can happen for a variety of reasons - perhaps there is a permissions problem (the identity of the FTP server process does not have rights to a target), the write is outside of a sandbox setup on the server, or even that its already open in another program.

    But in your case, you are using the full source file name in the "STOR" command when it wants the target path. Depending on whether you want to write subdirectories on the server, calculating the target name can get complicated. If you just want the server's current working directory, you could

    ftp.storbinary(f'STOR {os.path.split(myfile)[1]}', open(myfile, 'rb'))