How to Get Ftp File's Modify Time Using Python Ftplib

How to get FTP file's modify time using Python ftplib

MLST or MDTM

While you can retrieve a timestamp of an individual file over FTP with MLST or MDTM commands, neither is supported by ftplib.

Of course you can implement the MLST or MDTM on your own using FTP.voidcmd.

For details, refer to RFC 3659, particularly the:

  • 3. File Modification Time (MDTM)
  • 7. Listings for Machine Processing (MLST and MLSD)

A simple example for MDTM:

from ftplib import FTP
from dateutil import parser

# ... (connection to FTP)

timestamp = ftp.voidcmd("MDTM /remote/path/file.txt")[4:].strip()

time = parser.parse(timestamp)

print(time)


MLSD

The only command explicitly supported by the ftplib library that can return standardized file timestamp is MLSD via FTP.mlsd method. Though its use makes sense only if you want to retrieve timestamps for more files.

  • Retrieve a complete directory listing using MLSD
  • Search the returned collection for the file(s) you want
  • Retrieve modify fact
  • Parse it according to the specification, YYYYMMDDHHMMSS[.sss]

For details, refer to RFC 3659 again, particularly the:

  • 7.5.3. The modify Fact section
  • 2.3. Times section
from ftplib import FTP
from dateutil import parser

# ... (connection to FTP)

files = ftp.mlsd("/remote/path")

for file in files:
name = file[0]
timestamp = file[1]['modify']
time = parser.parse(timestamp)
print(name + ' - ' + str(time))

Note that times returned by MLST, MLSD and MDTM are in UTC (unless the server is broken). So you may need to correct them for your local timezone.

Again, refer to RFC 3659 2.3. Times section:

Time values are always represented in UTC (GMT), and in the Gregorian
calendar regardless of what calendar may have been in use at the date
and time indicated at the location of the server-PI.



LIST

If the FTP server does not support any of MLST, MLSD and MDTM, all you can do is to use an obsolete LIST command. That involves parsing a proprietary listing it returns.

A common *nix listing is like:

-rw-r--r-- 1 user group           4467 Mar 27  2018 file1.zip
-rw-r--r-- 1 user group 124529 Jun 18 15:31 file2.zip

With a listing like this, this code will do:

from ftplib import FTP
from dateutil import parser

# ... (connection to FTP)

lines = []
ftp.dir("/remote/path", lines.append)

for line in lines:
tokens = line.split(maxsplit = 9)
name = tokens[8]
time_str = tokens[5] + " " + tokens[6] + " " + tokens[7]
time = parser.parse(time_str)
print(name + ' - ' + str(time))


Finding the latest file

See also Python FTP get the most recent file by date.

Python FTP get the most recent file by date

With NLST, like shown in Martin Prikryl's response,
you should use sorted method:

ftp = FTP(host="127.0.0.1", user="u",passwd="p")
ftp.cwd("/data")
file_name = sorted(ftp.nlst(), key=lambda x: ftp.voidcmd(f"MDTM {x}"))[-1]

Getting last modified date of file on FTP server using urlopen not working

The documentation of urlopen does not claim that it returns last-modified for FTP URLs.

Note that there are no headers in FTP protocol. The urlopen just fakes few HTTP-like headers for some kind of compatibility of the interface across protocols.

To retrieve timestamp using FTP, use the ftplib. See How to get FTP file's modify time using Python ftplib.

Download only yesterday's file with FTP in Python

Based on Python Datetime: All Items From Yesterday, this should do:

yesterday = date.today() - timedelta(days=1)

for file_data in ftp.mlsd():
file_name,meta = file_data
last_modified = datetime.strptime(meta.get("modify"), "%Y%m%d%H%M%S")
if last_modified.date() == yesterday:
ftp.retrbinary("RETR " + file_name, open(file_name, 'wb').write)

If the server does not support MLSD command, you will have to use less efficient options with LIST or MDTM. See:

  • Python to download file from FTP Server if file has been added into FTP server in last N hour ago?
  • How to get FTP file's modify time using Python ftplib

How to get FTP file's modify time using Python ftplib

MLST or MDTM

While you can retrieve a timestamp of an individual file over FTP with MLST or MDTM commands, neither is supported by ftplib.

Of course you can implement the MLST or MDTM on your own using FTP.voidcmd.

For details, refer to RFC 3659, particularly the:

  • 3. File Modification Time (MDTM)
  • 7. Listings for Machine Processing (MLST and MLSD)

A simple example for MDTM:

from ftplib import FTP
from dateutil import parser

# ... (connection to FTP)

timestamp = ftp.voidcmd("MDTM /remote/path/file.txt")[4:].strip()

time = parser.parse(timestamp)

print(time)


MLSD

The only command explicitly supported by the ftplib library that can return standardized file timestamp is MLSD via FTP.mlsd method. Though its use makes sense only if you want to retrieve timestamps for more files.

  • Retrieve a complete directory listing using MLSD
  • Search the returned collection for the file(s) you want
  • Retrieve modify fact
  • Parse it according to the specification, YYYYMMDDHHMMSS[.sss]

For details, refer to RFC 3659 again, particularly the:

  • 7.5.3. The modify Fact section
  • 2.3. Times section
from ftplib import FTP
from dateutil import parser

# ... (connection to FTP)

files = ftp.mlsd("/remote/path")

for file in files:
name = file[0]
timestamp = file[1]['modify']
time = parser.parse(timestamp)
print(name + ' - ' + str(time))

Note that times returned by MLST, MLSD and MDTM are in UTC (unless the server is broken). So you may need to correct them for your local timezone.

Again, refer to RFC 3659 2.3. Times section:

Time values are always represented in UTC (GMT), and in the Gregorian
calendar regardless of what calendar may have been in use at the date
and time indicated at the location of the server-PI.



LIST

If the FTP server does not support any of MLST, MLSD and MDTM, all you can do is to use an obsolete LIST command. That involves parsing a proprietary listing it returns.

A common *nix listing is like:

-rw-r--r-- 1 user group           4467 Mar 27  2018 file1.zip
-rw-r--r-- 1 user group 124529 Jun 18 15:31 file2.zip

With a listing like this, this code will do:

from ftplib import FTP
from dateutil import parser

# ... (connection to FTP)

lines = []
ftp.dir("/remote/path", lines.append)

for line in lines:
tokens = line.split(maxsplit = 9)
name = tokens[8]
time_str = tokens[5] + " " + tokens[6] + " " + tokens[7]
time = parser.parse(time_str)
print(name + ' - ' + str(time))


Finding the latest file

See also Python FTP get the most recent file by date.

What is the way to know how any file is updated in ftp location using Python?

You can use the dir method to get the last modified timestamps from the file listing, and parse the 6th to 8th fields on your own. Note that the 8th field can be either a year or a time of the day, in which case the year is the current year. But then again you don't necessarily have to parse the date/time at all since all you need is to detect change.

>>> from ftplib import FTP
>>> ftp = FTP('ftp.redhat.com')
>>> ftp.login()
'230 Login successful.'
>>> ftp.dir()
lrwxrwxrwx 1 ftp ftp 1 Dec 19 2009 pub -> .
drwxr-xr-x 45 ftp ftp 4096 Jul 05 16:46 redhat
>>> l=[]
>>> ftp.dir(lambda x: l.append(x))
>>> l
['lrwxrwxrwx 1 ftp ftp 1 Dec 19 2009 pub -> .', 'drwxr-xr-x 45 ftp ftp 4096 Jul 05 16:46 redhat']
>>>


Related Topics



Leave a reply



Submit