{"id":1279,"library":"scp","title":"Python SCP Client","description":"The `scp.py` module, currently at version 0.15.0, provides a pure-Python implementation of the SCP1 (Secure Copy Protocol) client. It leverages the `paramiko` library for SSH transport, enabling secure file transfers over SSH connections, mirroring the functionality of the OpenSSH `scp` program. The library is actively maintained but follows an irregular release cadence.","status":"active","version":"0.15.0","language":"python","source_language":"en","source_url":"https://github.com/jbardin/scp.py","tags":["scp","ssh","sftp","paramiko","file transfer","secure copy"],"install":[{"cmd":"pip install scp","lang":"bash","label":"Install `scp`"},{"cmd":"pip install paramiko scp","lang":"bash","label":"Install with core dependency"}],"dependencies":[{"reason":"`scp.py` is built on top of `paramiko` for SSH transport and authentication. It is a mandatory dependency.","package":"paramiko","optional":false}],"imports":[{"note":"This is the primary class for SCP file transfer operations.","symbol":"SCPClient","correct":"from scp import SCPClient"},{"note":"While part of `paramiko`, `SSHClient` is essential for establishing the underlying SSH connection that `SCPClient` uses.","symbol":"SSHClient","correct":"from paramiko import SSHClient"}],"quickstart":{"code":"import os\nfrom paramiko import SSHClient, AutoAddPolicy\nfrom scp import SCPClient\n\n# Configuration from environment variables for security\nHOSTNAME = os.environ.get('SCP_HOSTNAME', 'your_remote_host')\nUSERNAME = os.environ.get('SCP_USERNAME', 'your_username')\nPASSWORD = os.environ.get('SCP_PASSWORD', '') # Use SSH keys in production\n\nlocal_file = 'local_test_file.txt'\nremote_path = '/tmp/remote_test_file.txt'\n\n# Create a dummy local file for the example\nwith open(local_file, 'w') as f:\n    f.write('Hello from scp.py!')\n\nssh = SSHClient()\n# Set policy to auto-add host keys for demo. In production, use ssh.load_system_host_keys() or HostKeys().add().\nssh.set_missing_host_key_policy(AutoAddPolicy()) \n\ntry:\n    # Connect to the remote server\n    ssh.connect(hostname=HOSTNAME, username=USERNAME, password=PASSWORD, port=22)\n    print(f\"Connected to {HOSTNAME}\")\n\n    # SCPCLient takes a paramiko transport as an argument\n    with SCPClient(ssh.get_transport()) as scp:\n        # Upload a file\n        scp.put(local_file, remote_path)\n        print(f\"Uploaded '{local_file}' to '{remote_path}'\")\n\n        # Download the file back to verify\n        downloaded_file = 'downloaded_test_file.txt'\n        scp.get(remote_path, downloaded_file)\n        print(f\"Downloaded '{remote_path}' to '{downloaded_file}'\")\n\nexcept Exception as e:\n    print(f\"An error occurred: {e}\")\nfinally:\n    ssh.close()\n    print(\"SSH connection closed.\")\n\n# Clean up dummy files\nimport os\nif os.path.exists(local_file):\n    os.remove(local_file)\nif os.path.exists(downloaded_file):\n    os.remove(downloaded_file)","lang":"python","description":"This quickstart demonstrates how to establish an SSH connection using `paramiko.SSHClient` and then use `scp.SCPClient` to upload and download a file. It includes important considerations for host key policy and proper connection closure."},"warnings":[{"fix":"Ensure `paramiko` is installed (`pip install paramiko`) and resolve any underlying `cryptography` installation errors, which might require system-level development packages.","message":"The `scp` library is a thin wrapper around `paramiko`. Therefore, `paramiko` and its dependencies (like `cryptography`, which might require compilation tools) must be correctly installed. Issues with `paramiko` often manifest as `scp` problems.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Prefer `ssh.load_system_host_keys()` or manually add host keys to a `paramiko.HostKeys` object. Implement strict host key checking and handle `paramiko.BadHostKeyException`.","message":"For security, always verify host keys. Using `paramiko.AutoAddPolicy()` in production is dangerous as it makes your client vulnerable to man-in-the-middle attacks.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For new projects or if advanced file transfer features are needed, consider using `paramiko`'s built-in SFTP client (`ssh.open_sftp()`) or higher-level libraries like `Fabric` that might use SFTP.","message":"The underlying SCP1 protocol has known security limitations and is considered deprecated by OpenSSH in favor of SFTP. While `scp.py` implements SCP1, be aware that future changes in OpenSSH servers might affect compatibility or expose vulnerabilities.","severity":"deprecated","affected_versions":"All versions"},{"fix":"Update your progress callback functions to match the 3-argument signature for `progress`, or use the `progress4` parameter if you require the `peername` argument. Review the `CHANGELOG.md` for specific details.","message":"The `progress` callback signature changed in version 0.13.0. It reverted to accepting 3 arguments (`path`, `total_size`, `sent_size`). A new `progress4` parameter was introduced to accept 4 arguments, including `peername`. Code using the 4-argument `progress` callback from pre-0.13.0 versions will break.","severity":"breaking","affected_versions":"<0.13.0 to 0.13.0"},{"fix":"Upgrade to `scp` version 0.13.6 or newer. If upgrading is not possible, ensure source directory paths passed to `put()` do not have trailing slashes if you intend to copy the directory itself rather than its contents.","message":"Prior to version 0.13.6, the `put()` method might have behaved unexpectedly when the source directory path had a trailing slash (e.g., `scp.put('my_dir/', remote_path)`).","severity":"gotcha","affected_versions":"<0.13.6"},{"fix":"Verify that the hostname or IP address specified for the remote SSH server is correct and accessible from the client's network environment. Ensure proper DNS configuration or use a direct IP address if DNS resolution is problematic.","message":"Attempts to establish an SCP connection can fail with `[Errno -2] Name does not resolve` if the provided hostname or IP address is invalid, misspelled, or cannot be resolved by the system's DNS configuration. This is an underlying network issue (e.g., DNS failure, incorrect host) rather than a library bug, but it will manifest during connection attempts.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'0.15.0':10 'activ':50 'cadenc':57 'client':3,23 'connect':38 'copi':21,65 'current':7 'enabl':32 'file':34,62 'follow':53 'function':41 'implement':16 'irregular':55 'leverag':25 'librari':28,48 'maintain':51 'mirror':39 'modul':6 'openssh':44 'paramiko':27,61 'program':46 'protocol':22 'provid':11 'pure':14 'pure-python':13 'python':1,15 'releas':56 'scp':2,45,58 'scp.py':5 'scp1':19 'secur':20,33,64 'sftp':60 'ssh':30,37,59 'transfer':35,63 'transport':31 'version':9","created_at":"2026-04-06T16:57:47.928515+00:00","updated_at":"2026-04-16T21:27:31.171968+00:00","problems":[{"fix":"Install the library using pip: `pip install scp`","cause":"The 'scp' library has not been installed in the current Python environment.","error":"ModuleNotFoundError: No module named 'scp'"},{"fix":"Double-check the username, password, SSH key path, and ensure the remote user has appropriate permissions for the connection and target directory.","cause":"The provided SSH credentials (username, password, or private key) are incorrect, or the user lacks necessary permissions on the remote server.","error":"paramiko.ssh_exception.AuthenticationException: Authentication failed."},{"fix":"Verify that the local source file path is correct and exists, and that the remote destination directory exists before attempting the transfer.","cause":"Either the specified local source file for 'put' does not exist, or the remote destination path for 'put'/'get' does not exist or is incorrect.","error":"SCPException: No such file or directory"},{"fix":"Pass the SSHClient's transport object to SCPClient using `ssh_client.get_transport()`. Example: `scp_client = SCPClient(ssh_client.get_transport())`","cause":"The 'SCPClient' constructor expects a 'paramiko.Transport' object, but a 'paramiko.SSHClient' object was passed directly instead.","error":"AttributeError: 'SSHClient' object has no attribute 'open_session'"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"0.16.1","cli_name":"scp","cli_version":"sh: 1: scp: not found","type":"library","homepage":null,"github":"https://github.com/jbardin/scp.py","docs":null,"changelog":null,"pypi":"https://pypi.org/project/scp/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["http-networking","auth-security"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-27","next_check":"2026-07-28","install_tag":"verified"}}