scp.py
scp.py copied to clipboard
Add getfo
There is a put method that takes paths and a putfo method that takes a file object instead. On the other hand there is only a get method and no getfo method. Could it be added?
I think this could be added, if there is a need for it. It is not trivial though, because of the way the SCP protocol works: we request something (usually files or folders, potentially with wildcards) and then the server sends multiple commands back (which can be a file, or file metadata, or recursing in a subdirectory). So we'd need to keep track of the fact that we expect a single file and fail if the server pushes multiple.
Or maybe something more generic than a file object could be passed in, an interface that could get files with their path and metadata.
class FileReceiver(object):
def open_file(self, pathname, atime, mtime, size):
"""Returns a file descriptor on which the server will write this file.
"""
raise NotImplementedError
An admittedly weird but theoretically working workaround for a recursive/dir scp would be to just put the resulting files in a tarfile object. If a parameter is added to a getfo() method like single_file = True, it'd be treated as a single object put into an io.BytesIO() object (for python 3; I think this is an io.StringIO() object in python 2?). If single_file is false, we can specify that we are expecting multiple files and these can either be accessed directly with tarfile methods or a compat layer (iterator of filenames, etc.) could be implemented.
I don't think anybody expects this to happen. This library has nothing to do with TAR files.
Inherently? No. But tarfile is in stdlib and provides a native stream-based interface/object for a container of files, which is what you'd need for handling a return of multiple files from the remote (specifically addressing the issues presented in https://github.com/jbardin/scp.py/issues/94#issuecomment-355606699) instead of just raising an exception if more than one file is returned.
I would rather raise an exception than do something completely different and unexpected.
just came across this "lack" on scp.py. Here is the use-case:
we do want to update a file on an appliance that only supports SCP. As the file contains sensitive data, ideal we would like to only have a copy "in-memory", hence a scp.getfo for a single file makes sense. I would also vote to raise an exception if more than one file is sent by the request.
Example:
[...] scp.getfo -> to retrieve the file in-memory [update the content] scp.putfo -> send back to SCP server
I thought I'd try to add this. A single file can be read into an object of io.BytesIO, or of a new subclass that can additionally hold metadata. As for the multiple-file cases, getfo() could return a data structure containing lists of such file-like objects, with dictionaries for directories and their contents. However, wouldn't it be more streamlined and consistent to limit the scope of getfo() to only single-file usage, just like putfo()?