I am trying to connect SFTP server using pysftp. I receive below error on pysftp.Connection() in Jupyter notebook running in Kubernetes inside IBM Elyra. Python version is 3.7.6 and pysftp 0.2.9 with paramiko 3.0.0.
OS is 'VERSION="20.04 LTS (Focal Fossa)"'
---------------------------------------------------------------------------
OSError Traceback (most recent call last)
/usr/local/bin/kernel-launchers/python/scripts/launch_ipykernel.py in <module>
----> 1 sftp_conn = pysftp.Connection(host=sftp_info['host'],port= sftp_info['port'], username= sftp_info['login'], password=sftp_info['password'],cnopts=cnopts)
/opt/conda/lib/python3.7/site-packages/pysftp/__init__.py in __init__(self, host, username, private_key, password, port, private_key_pass, ciphers, log, cnopts, default_path)
138 # Begin the SSH transport.
139 self._transport = None
--> 140 self._start_transport(host, port)
141 self._transport.use_compression(self._cnopts.compression)
142 self._set_authentication(password, private_key, private_key_pass)
/opt/conda/lib/python3.7/site-packages/pysftp/__init__.py in _start_transport(self, host, port)
174 '''start the transport and set the ciphers if specified.'''
175 try:
--> 176 self._transport = paramiko.Transport((host, port))
177 # Set security ciphers if set
178 if self._cnopts.ciphers is not None:
/opt/conda/lib/python3.7/site-packages/paramiko/transport.py in __init__(self, sock, default_window_size, default_max_packet_size, gss_kex, gss_deleg_creds, disabled_algorithms, server_sig_algs)
428 reason = "No suitable address family"
429 addrinfos = socket.getaddrinfo(
--> 430 hostname, port, socket.AF_UNSPEC, socket.SOCK_STREAM
431 )
432 for family, socktype, proto, canonname, sockaddr in addrinfos:
/opt/conda/lib/python3.7/socket.py in getaddrinfo(host, port, family, type, proto, flags)
750 # and socket type values to enum constants.
751 addrlist = []
--> 752 for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
753 af, socktype, proto, canonname, sa = res
754 addrlist.append((_intenum_converter(af, AddressFamily),
OSError: Int or String expected
Connection should work and I should be be able to list directories. Current code is
import pysftp
cnopts = pysftp.CnOpts(knownhosts=None)
# cnopts.hostkeys = None
key = pysftp.RSAKey(data=decodebytes(keydata))
cnopts.hostkeys.add(sftp_info["host"], "ssh-rsa", key)
sfc = pysftp.Connection(
host=sftp_info["host"],
port=sftp_info["port"],
username=sftp_info["login"],
password=sftp_info["password"],
cnopts=cnopts,
)
sfc.listdir()
The host does not have ~/.ssh/known_hosts and it throws a warning
/opt/conda/lib/python3.7/site-packages/pysftp/__init__.py:61: UserWarning: Failed to load HostKeys from /home/jovyan/.ssh/known_hosts. You will need to explicitly load HostKeys (cnopts.hostkeys.load(filename)) or disableHostKey checking (cnopts.hostkeys = None).
warnings.warn(wmsg, UserWarning)
I have tried to emulate same python version and pysftp and paramiko libraries on local environment running in Docker environment and the code works. The last command generates
>>> sfc.listdir()
['data', 'fire']
Local OS is VERSION="10 (buster)" based on docker image used FROM python:3.7.6. I used the specific version to match what is available in kubernetes. But in docker environment 3.7.6 or latest 3.7.16 both work without issues. In docker environment by default OS has ~/.ssh/known_hosts file. I have tried connecting by removing this file and connection to SFTP server works in Docker.
I have also tried using paramiko directly as suggested in some threads on SO. But, it has exactly the same behaviour.
I am not sure, where should I start the investigation to isolate the problem.
Thanks to pointer from @Martin, what I need to change was the type of port, which was being returned by another library and was being returned as numpy.int64! Finally can continue with actual program :D