Python Forum
dnload/upload with FTP - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: dnload/upload with FTP (/thread-38132.html)



dnload/upload with FTP - ebolisa - Sep-06-2022

Hi,

What's the right syntax to connect to a ftp server and download a file?
The following code cannot find the file however, I can with a ftp client app.

TIA

ftp_server = "192.168.1.10"
url_username = "user"
url_pass = "pass"

session = ftplib.FTP_TLS(ftp_server, url_username, url_pass)
file = open('/home/pi/myip.php', 'rb')                  # file to download
print(file)
Error:
Traceback (most recent call last): File "C:\SharedFiles\Python\practice\json_read_from_url.py", line 17, in <module> file = open('/192.168.1.10t/myip.php', 'rb') # file to send FileNotFoundError: [Errno 2] No such file or directory: '/192.168.1.10/myip.php'



RE: dnload/upload with FTP - deanhystad - Sep-07-2022

https://docs.python.org/3/library/ftplib.html
https://www.tutorialspoint.com/python_network_programming/python_ftp.htm


RE: dnload/upload with FTP - Gribouillis - Sep-07-2022

If it doesn't work with ftplib, you could perhaps install the lftp command line utility and invoke it through subprocess.
Output:
sudo apt install lftp
Then something like (untested)
import subprocess
ftp_server = "192.168.1.10"
url_username = "user"
url_pass = "pass"
filename = '/home/pi/myip.php'

subprocess.run([
    'lftp', '-u', f'{url_username},{url_pass}',
    '-c', f'open -e "get {filename}" {ftp_server}'])
I found this utility quite convenient in the past to automate file transfers. Another interesting way of using it is
subprocess.run(['lftp', '-f', command_file])
where 'command_file' is a file where you write a sequence of lftp commands, such as get or put such file or mirror such directory etc.


RE: dnload/upload with FTP - ebolisa - Sep-07-2022

Thank you much! I'm progressing.

This code downloads a file in my directory but, because I'm working with a microprocessor I'd like to download the file into the memories, make changes and upload it again into the ftp server.

How do I go by doing it?
Thank you.

from ftplib import FTP

ftp_server = "192.168.1.10"
url_username = "pi"
url_pass = "mypi"
filepath = "home/pi/iot"
filename = "blynk.json"

ftp = FTP(ftp_server)
print(ftp.login(url_username, url_pass))  # 230 User pi logged in
print(ftp.cwd(filepath))  # 250 CWD command successful
print(ftp.retrlines('LIST'))  # 226 Transfer complete

with open(filename, "wb") as fp:
    # use FTP's RETR command to download the file
    ftp.retrbinary(f"RETR {filename}", fp.write)

print(ftp.quit())  # 221 Goodbye
EDIT:
This' what I tried:

from ftplib import FTP
from io import BytesIO
import json

ftp_server = "192.168.1.10"
url_username = "pi"
url_pass = "mypi"
filepath = "home/pi/iot"
filename = "blynk.json"
data = []

def getFile(ftp, filename):
    try:
        ftp.retrbinary("RETR " + filename, open(filename, 'wb').write)
    except:
        print("Error")

ftp = FTP(ftp_server)
ftp.login(url_username, url_pass)
ftp.cwd(filepath)
data.append(getFile(ftp, filename))
print(data)  # [None]
ftp.quit()
EDIT 2:

from ftplib import FTP
from io import BytesIO
import json


def getFile(fp, fname):
    try:
        r = BytesIO()
        fp.retrbinary("RETR " + fname, r.write)
        data = r.getvalue().decode("utf-8")
        data = json.loads(data)  # convert str to json
        return data
    except:
        print("ftp read error")


def postFile(fp, fname, file):
    try:
        fp.storbinary("STOR" + fname, file)
    except:
        print("ftp post error")

# open ftp connection
ftp = FTP(ftp_server)

# login
ftp.login(url_username, url_pass)  # 230 User pi logged in

# change directory
ftp.cwd(filepath)  # 250 CWD command successful

# list dir
# print(ftp.retrlines('LIST'))  # 226 Transfer complete

# retrieve json data
js_data = getFile(ftp, filename)

print(js_data)

# update json data
js_data["relay3"] = "5555"

print(js_data)  # shows updated data

# upload file
postFile(ftp, filename, js_data)

# close ftp connection
ftp.quit()  # 221 Goodbye
Error:
ftp post error



RE: dnload/upload with FTP SOLVED - ebolisa - Sep-07-2022

Solved!

Here's my new code (which I'm sure it can be improved):

# open ftp connection
ftp = FTP(ftp_server)

# login
ftp.login(url_username, url_pass)  # 230 User user-7092639 logged in

# change directory
ftp.cwd(filepath)  # 250 CWD command successful

# list dir
# print(ftp.retrlines('LIST'))  # 226 Transfer complete

s = StringIO()

# retrieve file
ftp.retrlines("RETR " + filename, s.write)  # 226 Transfer complete

# parse file
js_temp = json.loads(s.getvalue())

# close file
s.close()

# update json data
js_temp["relay3"] = 5555

# upload updated file
dump = bytes(json.dumps(js_temp), 'utf-8')
ftp.storbinary("STOR " + filename, BytesIO(dump))

# close connection
ftp.quit()