def sftp_upload(client: paramiko.SFTPClient, filepath: str) -> Generator[TextIO, None, None]: """ Return context manager that can be used to upload to SFTP. This context manager writes to a NamedTemporaryFile and then uses the paramiko client `putfo` method to upload the file. >>> with sftp_upload(client, "path/to/file.csv) as fileobj: # noqa ... write_csv(fileobj, queryset, "col1", "col2") The client is not created inside the generator as it would have to then handle all of the various authentication mechanisms that SSH / paramiko support, and that is really up to the calling code. There is a convenience function, `write_csv_sftp` that handles the basic use case of a username and password auth. """ with tempfile.TemporaryFile() as fileobj: with io.TextIOWrapper( fileobj, encoding="utf-8", newline="", write_through=True, ) as buffer: yield buffer fileobj.seek(0) client.putfo(fileobj, filepath)