Problem / Goal
pysftp 0.2.9 (last released 2016, effectively unmaintained) imports DSSKey from paramiko at module load time.
Paramiko 4.0 removed DSSKey entirely, so any environment that resolves paramiko>=4 fails immediately with ImportError: cannot import name 'DSSKey' from 'paramiko'.
This blocks dependabot's attempt to raise the paramiko ceiling (PR #678) and keeps a known CVE-bearing package pinned.
Context
Reproduction
pip install "paramiko>=4"
python -c "import pysftp"
# ImportError: cannot import name 'DSSKey' from 'paramiko'
Considerations
Is a paramiko 5 upgrade feasible without a major overhaul?
Yes — the rewrite is self-contained in one strategy file (~25 lines of logic) and one test file.
No other file in the codebase imports paramiko or pysftp.
Chosen approach: replace pysftp with direct paramiko calls
oteapi/strategies/download/sftp.py currently uses:
pysftp.CnOpts() with hostkeys = None — replaced by paramiko.SSHClient + AutoAddPolicy
pysftp.Connection(host, username, password, port, cnopts) — replaced by client.connect() + client.open_sftp()
sftp.get(remotepath, localpath=...) — replaced by sftp.get(remotepath, str(localpath))
pyproject.toml changes:
- Remove
pysftp~=0.2.9
- Change
paramiko<4 → paramiko<6
- Remove the filterwarnings entry for pysftp
HostKeys warning
Alternative: vendor/patch pysftp
No maintained fork exists on PyPI; vendoring a patched copy adds maintenance burden for a library whose entire role is now a thin wrapper around a three-line paramiko call sequence.
Acceptance Criteria
Problem / Goal
pysftp 0.2.9(last released 2016, effectively unmaintained) importsDSSKeyfrom paramiko at module load time.Paramiko 4.0 removed
DSSKeyentirely, so any environment that resolvesparamiko>=4fails immediately withImportError: cannot import name 'DSSKey' from 'paramiko'.This blocks dependabot's attempt to raise the paramiko ceiling (PR #678) and keeps a known CVE-bearing package pinned.
Context
paramiko<4→<6, installs paramiko 5, breaks CItests/strategies/download/test_sftp.py::test_sftpandtests/strategies/test_strategies_general.py::test_registered_entry_point_importabilityoteapi/strategies/download/sftp.py,tests/strategies/download/test_sftp.py,pyproject.tomlpysftpis the only consumer of paramiko in the codebase —sftp.pyhas zero directimport paramikostatementspip-auditon PR Pin RabbitMQ broker image to 3.x in Celery tests #681; pinning<4is the root causeReproduction
Considerations
Is a paramiko 5 upgrade feasible without a major overhaul?
Yes — the rewrite is self-contained in one strategy file (~25 lines of logic) and one test file.
No other file in the codebase imports paramiko or pysftp.
Chosen approach: replace pysftp with direct paramiko calls
oteapi/strategies/download/sftp.pycurrently uses:pysftp.CnOpts()withhostkeys = None— replaced byparamiko.SSHClient+AutoAddPolicypysftp.Connection(host, username, password, port, cnopts)— replaced byclient.connect()+client.open_sftp()sftp.get(remotepath, localpath=...)— replaced bysftp.get(remotepath, str(localpath))pyproject.tomlchanges:pysftp~=0.2.9paramiko<4→paramiko<6HostKeyswarningAlternative: vendor/patch pysftp
No maintained fork exists on PyPI; vendoring a patched copy adds maintenance burden for a library whose entire role is now a thin wrapper around a three-line paramiko call sequence.
Acceptance Criteria
pysftpis removed from all dependenciesparamiko<4constraint is lifted to<6oteapi/strategies/download/sftp.pyusesparamikodirectly