Select to view content in your preferred language

Retrbindary code not working ?

7121
6
03-15-2015 09:43 AM
PROBERT68
Honored Contributor
# Use the FTP Directory to retrieve KMZ
try:
    f.retrbinary('RETR %s' % FILE, open(FILE, 'wb').write)
except ftplib.error_perm:
    print 'ERROR: cannot read file "%s"' % FILE
    os.unlink(FILE)
else:
    print '*** Downloaded "%s" to CWD' % FILE

Do they seem right to you ? This is from the book Programming ArcGIS 10.1 with Python cookbook. When I ran it in Pyscripter 2.5.3.0 and it gave me the error :

Traceback (most recent call last):

  File "C:\ArcpyBook\Appendix2\ftp.py", line 45, in <module>

    f.retrbinary('RETR %s' % FILE, open(FILE, 'wb').write)

  File "C:\Python27\ArcGIS10.1\lib\ftplib.py", line 398, in retrbinary

    self.voidcmd('TYPE I')

  File "C:\Python27\ArcGIS10.1\lib\ftplib.py", line 248, in voidcmd

    self.putcmd(cmd)

  File "C:\Python27\ArcGIS10.1\lib\ftplib.py", line 178, in putcmd

    self.putline(line)

  File "C:\Python27\ArcGIS10.1\lib\ftplib.py", line 173, in putline

    self.sock.sendall(line)

AttributeError: 'NoneType' object has no attribute 'sendall'

Tags (2)
0 Kudos
6 Replies
DanPatterson_Retired
MVP Emeritus

makes no sense, since the whole script can't be seen in context, but whatever your self.sock object is, it is not the correct object type since it doesn't have an attribute called "sendall"  the object being returned is "None"  and its type is as follows

>>> a = None
>> type(a)
<type 'NoneType'>
>>>
0 Kudos
PROBERT68
Honored Contributor
# Import moduels
import ftplib
import os.path
from ftplib import FTP


HOST = 'ftp.nifc.gov'
DIRN = '/incident_Specific_Data/ALASKA/Fire_Perimeters/20090805_1500'
FILE = 'FirePerimeters_20090805_1500.kmz'


# Create a block to connection or not


try:
    f = ftplib.FTP(HOST)
except (socket.error, socket.gaierror), e:
        print 'ERROR: cannot reach "%s"' % HOST
        print '*** Connected to host "%s"' % HOST


# to log in anonymously
try:
    f.login()
except ftplib.error_perm:
    print 'ERROR: cannot login anonymously'
    f.quit()
    print '*** Logged in as "anonymous"'


# To change to the directory in DIRN
try:
    f.cwd(DIRN)
except ftplib.error_perm:
    print 'ERROR: cannot CD to "%s"'  % DIRN
    f.quit()
    print '*** Changed to "%s" folder' % DIRN


# Use the FTP Directory to retrieve KMZ
try:
    f.retrbinary('RETR %s' % FILE, open(FILE, 'wb').write)
except ftplib.error_perm:
    print 'ERROR: cannot read file "%s"' % FILE
    os.unlink(FILE)
else:
    print '*** Downloaded "%s" to CWD' % FILE


# Disconnect from FTP
f.quit()

Here is the full code  Thanks.

0 Kudos
DanPatterson_Retired
MVP Emeritus

The only thing remotely similar to 'sock' is 'socket' hmmm

0 Kudos
OwenEarley
Frequent Contributor

The issue with your script is that it keeps processing after an error condition.

The sock object is invoked as soon as your create your FTP object (see the __init__ function in the ftplib.py file). This means that the sock object is not a NoneType at this point.

However, as Dan mentions, the sock object is a NoneType when you attempt to execute the f.retrbinary() function. This is because the previous code block has an error condition and you call the f.quit() function.

  • The issue is that the FTP directory does not exist.
  • The error is the f.quit() function explicitly sets the sock object to None, then your code attempts to use it in the next block.

You should modify your code to exit if an error occurs or place conditional statements around code blocks to ensure that any pre-conditions are met.

Also, there are a few missing else statements that will when messages are printed, for example:

try: 
    f.cwd(DIRN) 
except ftplib.error_perm: 
    print 'ERROR: cannot CD to "%s"'  % DIRN 
    f.quit() 
else: # <-- missing
    print '*** Changed to "%s" folder' % DIRN
PROBERT68
Honored Contributor

Thank you.

0 Kudos
PROBERT68
Honored Contributor

Thank you all.

First of all,

The file for the FTP server I have checked is no longer there or may have been moved; however, I tweaked and change to a different file to test it. The script is working now . If you compare the scripts I post earlier and the change I made....

I would like to Thank to Owen Earley for pointing me to the missing "else".  That worked !

# Import modules
import ftplib
import os
import socket
from ftplib import FTP


HOST = "ftp.nifc.gov"
DIRN = "Incident_Specific_Data/ALASKA/DataRequests/"
FILE = "AK_UIA_polygon_data.gdb.zip"


# Create a block to connection or not


try:
    f = ftplib.FTP(HOST)
except (socket.error, socket.gaierror), e:
        print "ERROR: cannot reach" % HOST
else:
        print '"***Connected to host "%s"' % HOST


# to log in anonymously
try:
    f.login()
except ftplib.error_perm:
    print "ERROR: cannot login anonymously"
    f.quit()
else:
    print '***Logged in as anonymous'


# To change to the directory in DIRN
try:
    f.cwd(DIRN)
except ftplib.error_perm:
    print 'ERROR: cannot CD to" "%s'  % DIRN
    f.quit()
else:
    print '***Changed to "%s" folder' % DIRN


# Use the FTP Directory to retrieve KMZ
try:
    f.retrbinary('RETR %s' % FILE, open(FILE, 'wb').write)
except ftplib.error_perm:
    print "ERROR: cannot read file" % FILE
    os.unlink(FILE)
else:
    print "***Downloaded %s to CWD" % FILE


# Disconnect from FTP
f.quit()
0 Kudos