title: Why is Paramiko raising EOFError() when the SFTP object is stored in a dictionary?
body: <p>I'm having trouble with an application I'm writing that downloads and uploads files to and from other boxes via SSH. The issue I'm experiencing is that I can get (download) files just fine but when I try to put (upload) them onto another server I get an EOFError() exception. When I looked at _write_all() in paramiko\sftp.py it seemed like the error was caused when it couldn't write any data to the stream? I have no network programming experience so if someone knows what it's trying to do and could communicate that to me I'd appreciate it.</p>
  
  <p>I wrote a simplified version of the function that handles my connections as ssh(). runCommand() shows how the upload is failing in my application while simpleTest() shows how sftp put does work, but I can't see any difference between runCommand() and simpleTest() other than how my SFTP objects are being stored. One is stored in a dictionary and the other by itself. It seems like if the dictionary was the problem that downloading files wouldn't work but that is not the case.</p>
  
  <p>Does anyone know what could cause this behavior or could recommend another way to manage my connections if this way is causing problems?</p>
  
  <p>I'm using Python 2.7 with Paramiko 1.7.6. I've tested this code on both Linux and Windows and got the same results.</p>
  
  <p><strong>EDIT: code included now.</strong></p>
  
  <pre><code>import os
  import paramiko
  
  class ManageSSH:
       """Manages ssh connections."""
      def __init__(self):
          self.hosts = {"testbox": ['testbox', 'test', 'test']}
          self.sshConnections = {}
          self.sftpConnections = {}
          self.localfile = "C:\\testfile"
          self.remotefile = "/tmp/tempfile"
          self.fetchedfile = "C:\\tempdl"
  
      def ssh(self):
          """Manages ssh connections."""
          for host in self.hosts.keys():
              try:
                  self.sshConnections[host]
                  print "ssh connection is already open for %s" % host
              except KeyError, e:         # if no ssh connection for the host exists then open one
                  # open ssh connection
                  ssh = paramiko.SSHClient()
                  ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                  ssh.connect(self.hosts[host][0], 22, self.hosts[host][1], self.hosts[host][2])
                  self.sshConnections[host] = ssh
                  print "ssh connection to %s opened" % host
              try:
                  self.sftpConnections[host]
                  print "sftp connection is already open for %s" % host
              except KeyError, e:
                  # open sftp connection
                  ssh = paramiko.SSHClient()
                  ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                  ssh.connect(self.hosts[host][0], 22, self.hosts[host][1], self.hosts[host][2])
                  self.sftpConnections[host] = ssh.open_sftp()
                  print "sftp connection to %s opened" % host
  
      def runCommand(self):
          """run commands and return output"""
          for host in self.hosts:
              command = "if [ -d /tmp ]; then echo -n 1; else echo -n 0; fi"
              stdin, stdout, stderr = self.sshConnections[host].exec_command(command)
              print "%s executed on %s" % (command, host)
              print "returned %s" % stdout.read()
              self.sftpConnections.get(self.remotefile, self.fetchedfile)
              print "downloaded %s from %s" % (self.remotefile, host)
              self.sftpConnections[host].put(self.localfile, self.remotefile)
              print "uploaded %s to %s" % (self.localfile, host)
              self.sftpConnections[host].close()
              self.sshConnections[host].close()
  
      def simpleTest(self):
          host = "testbox"
          ssh = paramiko.SSHClient()
          ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
          ssh.connect(host, 22, 'test', 'test')
          sftp = ssh.open_sftp()
          print "sftp connection to %s opened" % host
          sftp.get(self.remotefile, self.fetchedfile)
          print "downloaded %s from %s" % (self.localfile, host)
          sftp.put(self.localfile, self.remotefile)
          print "uploaded %s to %s" % (self.localfile, host)
          sftp.close()
  
  if __name__ == "__main__":
      test = ManageSSH()
      print "running test that works"
      test.simpleTest()
      print "running test that fails"
      test.ssh()
      test.runCommand()
  </code></pre>
  
  <p>output:</p>
  
  <pre><code>running test that works
  sftp connection to testbox opened
  downloaded C:\testfile from testbox
  uploaded C:\testfile to testbox
  running test that fails
  ssh connection to testbox opened
  sftp connection to testbox opened
  if [ -d /tmp ]; then echo -n 1; else echo -n 0; fi executed on testbox
  returned 1
  downloaded /tmp/tempfile from testbox
  Traceback (most recent call last):
    File "paramikotest.py", line 71, in &lt;module&gt;
      test.runCommand()
    File "paramikotest.py", line 47, in runCommand
      self.sftpConnections[host].put(self.localfile, self.remotefile)
    File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 561, in put
  
      fr = self.file(remotepath, 'wb')
    File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 245, in open
      t, msg = self._request(CMD_OPEN, filename, imode, attrblock)
    File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 627, in _request
      num = self._async_request(type(None), t, *arg)
    File "C:\Python27\lib\site-packages\paramiko\sftp_client.py", line 649, in _async_request
      self._send_packet(t, str(msg))
    File "C:\Python27\lib\site-packages\paramiko\sftp.py", line 172, in _send_packet
      self._write_all(out)
    File "C:\Python27\lib\site-packages\paramiko\sftp.py", line 138, in _write_all
  
      raise EOFError()
  EOFError
  </code></pre>