<p>I have a text file on my local machine that is generated by a daily Python script run in cron. </p>

<p>I would like to add a bit of code to have that file sent securely to my server over SSH.</p>

[{'answer_id': 68365, 'author': 'pdq', 'author_id': 8598, 'author_profile': 'https://Stackoverflow.com/users/8598', 'pm_score': 7, 'selected': True, 'text': '<p>You can call the <a href="https://en.wikipedia.org/wiki/Secure_copy" rel="noreferrer"><code>scp</code></a> bash command (it copies files over <a href="https://en.wikipedia.org/wiki/Secure_Shell" rel="noreferrer">SSH</a>) with <a href="https://docs.python.org/library/subprocess.html#subprocess.run" rel="noreferrer"><code>subprocess.run</code></a>:</p>\n\n<pre><code>import subprocess\nsubprocess.run(["scp", FILE, "USER@SERVER:PATH"])\n#e.g. subprocess.run(["scp", "foo.bar", "joe@srvr.net:/path/to/foo.bar"])\n</code></pre>\n\n<p>If you\'re creating the file that you want to send in the same Python program, you\'ll want to call <code>subprocess.run</code> command outside the <code>with</code> block you\'re using to open the file (or call <code>.close()</code> on the file first if you\'re not using a <code>with</code> block), so you know it\'s flushed to disk from Python.</p>\n\n<p>You need to generate (on the source machine) and install (on the destination machine) an ssh key beforehand so that the scp automatically gets authenticated with your public ssh key (in other words, so your script doesn\'t ask for a password).</p>\n'}, {'answer_id': 68377, 'author': 'Drew Olson', 'author_id': 9434, 'author_profile': 'https://Stackoverflow.com/users/9434', 'pm_score': -1, 'selected': False, 'text': '<p>Kind of hacky, but the following should work :)</p>\n\n<pre><code>import os\nfilePath = "/foo/bar/baz.py"\nserverPath = "/blah/boo/boom.py"\nos.system("scp "+filePath+" user@myserver.com:"+serverPath)\n</code></pre>\n'}, {'answer_id': 68382, 'author': 'Blair Conrad', 'author_id': 1199, 'author_profile': 'https://Stackoverflow.com/users/1199', 'pm_score': 5, 'selected': False, 'text': '<p>You\'d probably use the <a href="http://docs.python.org/lib/module-subprocess.html" rel="noreferrer">subprocess module</a>. Something like this:</p>\n\n<pre><code>import subprocess\np = subprocess.Popen(["scp", myfile, destination])\nsts = os.waitpid(p.pid, 0)\n</code></pre>\n\n<p>Where <code>destination</code> is probably of the form <code>user@remotehost:remotepath</code>. Thanks to\n@Charles Duffy for pointing out the weakness in my original answer, which used a single string argument to specify the scp operation <code>shell=True</code> - that wouldn\'t handle whitespace in paths.</p>\n\n<p>The module documentation has <a href="http://docs.python.org/lib/node536.html" rel="noreferrer">examples of error checking that you may want to perform in conjunction with this operation.</a></p>\n\n<p>Ensure that you\'ve set up proper credentials so that you can perform an <a href="http://www.debian.org/devel/passwordlessssh" rel="noreferrer">unattended, passwordless scp between the machines</a>. There is a <a href="https://stackoverflow.com/questions/7260/how-do-i-setup-public-key-authentication">stackoverflow question for this already</a>.</p>\n'}, {'answer_id': 68566, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 4, 'selected': False, 'text': '<p>There are a couple of different ways to approach the problem:</p>\n<ol>\n<li>Wrap command-line programs</li>\n<li>use a Python library that provides SSH capabilities (eg - <a href="https://www.paramiko.org/" rel="nofollow noreferrer">Paramiko</a> or <a href="https://twistedmatrix.com/trac/wiki/TwistedConch" rel="nofollow noreferrer">Twisted Conch</a>)</li>\n</ol>\n<p>Each approach has its own quirks. You will need to setup SSH keys to enable password-less logins if you are wrapping system commands like &quot;ssh&quot;, &quot;scp&quot; or &quot;rsync.&quot; You can embed a password in a script using Paramiko or some other library, but you might find the lack of documentation frustrating, especially if you are not familiar with the basics of the SSH connection (eg - key exchanges, agents, etc). It probably goes without saying that SSH keys are almost always a better idea than passwords for this sort of stuff.</p>\n<p>NOTE: its hard to beat rsync if you plan on transferring files via SSH, especially if the alternative is plain old scp.</p>\n<p>I\'ve used Paramiko with an eye towards replacing system calls but found myself drawn back to the wrapped commands due to their ease of use and immediate familiarity. You might be different. I gave Conch the once-over some time ago but it didn\'t appeal to me.</p>\n<p>If opting for the system-call path, Python offers an array of options such as os.system or the commands/subprocess modules. I\'d go with the subprocess module if using version 2.4+.</p>\n'}, {'answer_id': 69596, 'author': 'Tony Meyer', 'author_id': 4966, 'author_profile': 'https://Stackoverflow.com/users/4966', 'pm_score': 7, 'selected': False, 'text': '<p>To do this in Python (i.e. not wrapping scp through subprocess.Popen or similar) with the <a href="https://github.com/paramiko/paramiko" rel="noreferrer">Paramiko</a> library, you would do something like this:</p>\n\n<pre><code>import os\nimport paramiko\n\nssh = paramiko.SSHClient() \nssh.load_host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts")))\nssh.connect(server, username=username, password=password)\nsftp = ssh.open_sftp()\nsftp.put(localpath, remotepath)\nsftp.close()\nssh.close()\n</code></pre>\n\n<p>(You would probably want to deal with unknown hosts, errors, creating any directories necessary, and so on).</p>\n'}, {'answer_id': 22710513, 'author': 'jfs', 'author_id': 4279, 'author_profile': 'https://Stackoverflow.com/users/4279', 'pm_score': 2, 'selected': False, 'text': '<p><a href="http://fabfile.org" rel="nofollow"><code>fabric</code></a> could be used to upload files vis ssh:</p>\n\n<pre><code>#!/usr/bin/env python\nfrom fabric.api import execute, put\nfrom fabric.network import disconnect_all\n\nif __name__=="__main__":\n    import sys\n    # specify hostname to connect to and the remote/local paths\n    srcdir, remote_dirname, hostname = sys.argv[1:]\n    try:\n        s = execute(put, srcdir, remote_dirname, host=hostname)\n        print(repr(s))\n    finally:\n        disconnect_all()\n</code></pre>\n'}, {'answer_id': 22710752, 'author': 'jfs', 'author_id': 4279, 'author_profile': 'https://Stackoverflow.com/users/4279', 'pm_score': 0, 'selected': False, 'text': '<p>Calling <code>scp</code> command via subprocess doesn\'t allow to receive the progress report inside the script. <code>pexpect</code> could be used to extract that info:</p>\n\n<pre><code>import pipes\nimport re\nimport pexpect # $ pip install pexpect\n\ndef progress(locals):\n    # extract percents\n    print(int(re.search(br\'(\\d+)%$\', locals[\'child\'].after).group(1)))\n\ncommand = "scp %s %s" % tuple(map(pipes.quote, [srcfile, destination]))\npexpect.run(command, events={r\'\\d+%\': progress})\n</code></pre>\n\n<p>See <a href="https://stackoverflow.com/q/22687296/4279">python copy file in local network (linux -> linux)</a></p>\n'}, {'answer_id': 38556319, 'author': 'Maviles', 'author_id': 2653486, 'author_profile': 'https://Stackoverflow.com/users/2653486', 'pm_score': 4, 'selected': False, 'text': '<p>Reached the same problem, but instead of "hacking" or emulating command line:</p>\n\n<p>Found this answer <a href="https://pypi.python.org/pypi/scp" rel="noreferrer">here</a>.</p>\n\n<pre><code>from paramiko import SSHClient\nfrom scp import SCPClient\n\nssh = SSHClient()\nssh.load_system_host_keys()\nssh.connect(\'example.com\')\n\nwith SCPClient(ssh.get_transport()) as scp:\n    scp.put(\'test.txt\', \'test2.txt\')\n    scp.get(\'test2.txt\')\n</code></pre>\n'}, {'answer_id': 45047041, 'author': 'michael', 'author_id': 3055831, 'author_profile': 'https://Stackoverflow.com/users/3055831', 'pm_score': 2, 'selected': False, 'text': '<p>Using the external resource paramiko;</p>\n\n<pre class="lang-py prettyprint-override"><code>    from paramiko import SSHClient\n    from scp import SCPClient\n    import os\n\n    ssh = SSHClient() \n    ssh.load_host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts")))\n    ssh.connect(server, username=\'username\', password=\'password\')\n    with SCPClient(ssh.get_transport()) as scp:\n            scp.put(\'test.txt\', \'test2.txt\')\n</code></pre>\n'}, {'answer_id': 48098653, 'author': 'Roberto Marzocchi', 'author_id': 4903301, 'author_profile': 'https://Stackoverflow.com/users/4903301', 'pm_score': 1, 'selected': False, 'text': '<p>A very simple approach is the following: </p>\n\n<pre><code>import os\nos.system(\'sshpass -p "password" scp user@host:/path/to/file ./\')\n</code></pre>\n\n<p>No python library are required (only os), and it works, however using this method relies on another ssh client to be installed. This could result in undesired behavior if ran on another system.</p>\n'}, {'answer_id': 48634769, 'author': 'Jonno_FTW', 'author_id': 150851, 'author_profile': 'https://Stackoverflow.com/users/150851', 'pm_score': 1, 'selected': False, 'text': '<p>I used <a href="https://wiki.archlinux.org/index.php/SSHFS" rel="nofollow noreferrer">sshfs</a> to mount the remote directory via ssh, and <a href="https://docs.python.org/3/library/shutil.html" rel="nofollow noreferrer">shutil</a> to copy the files:</p>\n\n<pre><code>$ mkdir ~/sshmount\n$ sshfs user@remotehost:/path/to/remote/dst ~/sshmount\n</code></pre>\n\n<p>Then in python:</p>\n\n<pre><code>import shutil\nshutil.copy(\'a.txt\', \'~/sshmount\')\n</code></pre>\n\n<p>This method has the advantage that you can stream data over if you are generating data rather than caching locally and sending a single large file.</p>\n'}, {'answer_id': 53344419, 'author': 'Shawn', 'author_id': 7476764, 'author_profile': 'https://Stackoverflow.com/users/7476764', 'pm_score': 2, 'selected': False, 'text': '<p>You can use the vassal package, which is exactly designed for this.</p>\n\n<p>All you need is to install vassal and do</p>\n\n<pre><code>from vassal.terminal import Terminal\nshell = Terminal(["scp username@host:/home/foo.txt foo_local.txt"])\nshell.run()\n</code></pre>\n\n<p>Also, it will save you authenticate credential and don\'t need to type them again and again.</p>\n'}, {'answer_id': 53505120, 'author': 'JavDomGom', 'author_id': 10691828, 'author_profile': 'https://Stackoverflow.com/users/10691828', 'pm_score': 1, 'selected': False, 'text': "<p>Try this if you wan't to use SSL certificates:</p>\n\n<pre><code>import subprocess\n\ntry:\n    # Set scp and ssh data.\n    connUser = 'john'\n    connHost = 'my.host.com'\n    connPath = '/home/john/'\n    connPrivateKey = '/home/user/myKey.pem'\n\n    # Use scp to send file from local to host.\n    scp = subprocess.Popen(['scp', '-i', connPrivateKey, 'myFile.txt', '{}@{}:{}'.format(connUser, connHost, connPath)])\n\nexcept CalledProcessError:\n    print('ERROR: Connection to host failed!')\n</code></pre>\n"}, {'answer_id': 56850195, 'author': 'Pradeep Pathak', 'author_id': 8092005, 'author_profile': 'https://Stackoverflow.com/users/8092005', 'pm_score': 3, 'selected': False, 'text': '<p>You can do something like this, to handle the host key checking as well</p>\n\n<pre><code>import os\nos.system("sshpass -p password scp -o StrictHostKeyChecking=no local_file_path username@hostname:remote_path")\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/68335', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/10668/']