scp.py icon indicating copy to clipboard operation
scp.py copied to clipboard

Add getfo

Open Overv opened this issue 7 years ago • 7 comments

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?

Overv avatar Jan 05 '18 09:01 Overv

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

remram44 avatar Jan 05 '18 16:01 remram44

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.

johnnybubonic avatar Apr 21 '19 09:04 johnnybubonic

I don't think anybody expects this to happen. This library has nothing to do with TAR files.

remram44 avatar Apr 21 '19 14:04 remram44

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.

johnnybubonic avatar Apr 21 '19 19:04 johnnybubonic

I would rather raise an exception than do something completely different and unexpected.

remram44 avatar Apr 21 '19 20:04 remram44

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

Yzed avatar Jul 31 '19 09:07 Yzed

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()?

sudhartion avatar Oct 31 '21 14:10 sudhartion