Wow there's a lot of SFTP crap.

This commit is contained in:
Jeff Forcier 2014-02-21 19:15:36 -08:00
parent 6d9b28c56c
commit 9ae62eb47a
7 changed files with 87 additions and 73 deletions

View File

@ -28,12 +28,13 @@ class SFTPAttributes (object):
client or server mode. It attemps to mirror the object returned by
`os.stat` as closely as possible, so it may have the following fields,
with the same meanings as those returned by an `os.stat` object:
- st_size
- st_uid
- st_gid
- st_mode
- st_atime
- st_mtime
- ``st_size``
- ``st_uid``
- ``st_gid``
- ``st_mode``
- ``st_atime``
- ``st_mtime``
Because SFTP allows flags to have other arbitrary named attributes, these
are stored in a dict named ``attr``. Occasionally, the filename is also
@ -61,10 +62,10 @@ class SFTPAttributes (object):
def from_stat(cls, obj, filename=None):
"""
Create an SFTPAttributes object from an existing ``stat`` object (an
object returned by ``os.stat``).
Create an `.SFTPAttributes` object from an existing ``stat`` object (an
object returned by `os.stat`).
:param obj: an object returned by ``os.stat`` (or equivalent).
:param obj: an object returned by `os.stat` (or equivalent).
:type obj: object
:param filename: the filename associated with this file.
:type filename: str

View File

@ -1,6 +1,6 @@
# Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com>
#
# This file is part of paramiko.
# This file is part of Paramiko.
#
# Paramiko is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free
@ -194,16 +194,17 @@ class SFTPClient(BaseSFTP):
def open(self, filename, mode='r', bufsize=-1):
"""
Open a file on the remote server. The arguments are the same as for
Python's built-in ``file`` (aka ``open``). A file-like object is
returned, which closely mimics the behavior of a normal Python file
object, including the ability to be used as a context manager.
Python's built-in `python:file` (aka `python:open`). A file-like
object is returned, which closely mimics the behavior of a normal
Python file object, including the ability to be used as a context
manager.
The mode indicates how the file is to be opened: ``'r'`` for reading,
``'w'`` for writing (truncating an existing file), ``'a'`` for appending,
``'r+'`` for reading/writing, ``'w+'`` for reading/writing (truncating an
existing file), ``'a+'`` for reading/appending. The Python ``'b'`` flag
is ignored, since SSH treats all files as binary. The ``'U'`` flag is
supported in a compatible way.
``'w'`` for writing (truncating an existing file), ``'a'`` for
appending, ``'r+'`` for reading/writing, ``'w+'`` for reading/writing
(truncating an existing file), ``'a+'`` for reading/appending. The
Python ``'b'`` flag is ignored, since SSH treats all files as binary.
The ``'U'`` flag is supported in a compatible way.
Since 1.5.2, an ``'x'`` flag indicates that the operation should only
succeed if the file was created and did not previously exist. This has
@ -222,7 +223,7 @@ class SFTPClient(BaseSFTP):
:param bufsize: desired buffering (-1 = default buffer size)
:type bufsize: int
:return: a file object representing the open file
:rtype: SFTPFile
:rtype: `.SFTPFile`
:raises IOError: if the file could not be opened.
"""
@ -319,16 +320,16 @@ class SFTPClient(BaseSFTP):
contains fewer fields. An SFTP server may return as much or as little
info as it wants, so the results may vary from server to server.
Unlike a Python ``stat`` object, the result may not be accessed as a
tuple. This is mostly due to the author's slack factor.
Unlike a Python `python:stat` object, the result may not be accessed as
a tuple. This is mostly due to the author's slack factor.
The fields supported are: ``st_mode``, ``st_size``, ``st_uid``, ``st_gid``,
``st_atime``, and ``st_mtime``.
The fields supported are: ``st_mode``, ``st_size``, ``st_uid``,
``st_gid``, ``st_atime``, and ``st_mtime``.
:param path: the filename to stat
:type path: str
:return: an object containing attributes about the given file
:rtype: SFTPAttributes
:rtype: `.SFTPAttributes`
"""
path = self._adjust_cwd(path)
self._log(DEBUG, 'stat(%r)' % path)
@ -346,7 +347,7 @@ class SFTPClient(BaseSFTP):
:param path: the filename to stat
:type path: str
:return: an object containing attributes about the given file
:rtype: SFTPAttributes
:rtype: `.SFTPAttributes`
"""
path = self._adjust_cwd(path)
self._log(DEBUG, 'lstat(%r)' % path)
@ -374,7 +375,7 @@ class SFTPClient(BaseSFTP):
def chmod(self, path, mode):
"""
Change the mode (permissions) of a file. The permissions are
unix-style and identical to those used by Python's ``os.chmod``
unix-style and identical to those used by Python's `os.chmod`
function.
:param path: path of the file to change the permissions of
@ -391,7 +392,7 @@ class SFTPClient(BaseSFTP):
def chown(self, path, uid, gid):
"""
Change the owner (``uid``) and group (``gid``) of a file. As with
Python's ``os.chown`` function, you must pass both arguments, so if you
Python's `os.chown` function, you must pass both arguments, so if you
only want to change one, use `stat` first to retrieve the current
owner and group.
@ -433,9 +434,9 @@ class SFTPClient(BaseSFTP):
def truncate(self, path, size):
"""
Change the size of the file specified by ``path``. This usually extends
or shrinks the size of the file, just like the ``truncate()`` method on
Python file objects.
Change the size of the file specified by ``path``. This usually
extends or shrinks the size of the file, just like the `~file.truncate`
method on Python file objects.
:param path: path of the file to modify
:type path: str
@ -498,9 +499,9 @@ class SFTPClient(BaseSFTP):
def chdir(self, path):
"""
Change the "current directory" of this SFTP session. Since SFTP
doesn't really have the concept of a current working directory, this
is emulated by paramiko. Once you use this method to set a working
directory, all operations on this SFTPClient object will be relative
doesn't really have the concept of a current working directory, this is
emulated by Paramiko. Once you use this method to set a working
directory, all operations on this `.SFTPClient` object will be relative
to that path. You can pass in ``None`` to stop using a current working
directory.
@ -521,7 +522,7 @@ class SFTPClient(BaseSFTP):
def getcwd(self):
"""
Return the "current working directory" for this SFTP session, as
emulated by paramiko. If no directory has been set with `chdir`,
emulated by Paramiko. If no directory has been set with `chdir`,
this method will return ``None``.
:return: the current working directory on the server, or ``None``
@ -534,7 +535,8 @@ class SFTPClient(BaseSFTP):
def putfo(self, fl, remotepath, file_size=0, callback=None, confirm=True):
"""
Copy the contents of an open file object (``fl``) to the SFTP server as
``remotepath``. Any exception raised by operations will be passed through.
``remotepath``. Any exception raised by operations will be passed
through.
The SFTP operations use pipelining for speed.
@ -555,7 +557,7 @@ class SFTPClient(BaseSFTP):
:return: an object containing attributes about the given file
(since 1.7.4)
:rtype: SFTPAttributes
:rtype: `.SFTPAttributes`
.. versionadded:: 1.4
"""
@ -603,7 +605,7 @@ class SFTPClient(BaseSFTP):
:return: an object containing attributes about the given file
(since 1.7.4)
:rtype: SFTPAttributes
:rtype: `.SFTPAttributes`
.. versionadded:: 1.4
"""

View File

@ -17,7 +17,7 @@
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
"""
`.SFTPFile`
SFTP file object
"""
from __future__ import with_statement
@ -64,6 +64,9 @@ class SFTPFile (BufferedFile):
self._close(async=True)
def close(self):
"""
Close the file.
"""
self._close(async=False)
def _close(self, async=False):
@ -183,10 +186,11 @@ class SFTPFile (BufferedFile):
Set a timeout on read/write operations on the underlying socket or
ssh `.Channel`.
.. seealso:: `Channel.settimeout`
:param timeout: seconds to wait for a pending read/write operation
before raising ``socket.timeout``, or ``None`` for no timeout
:type timeout: float
.. seealso:: `.Channel.settimeout`
"""
self.sftp.sock.settimeout(timeout)
@ -195,8 +199,9 @@ class SFTPFile (BufferedFile):
Returns the timeout in seconds (as a float) associated with the socket
or ssh `.Channel` used for this file.
.. seealso:: `Channel.gettimeout`
:rtype: float
.. seealso:: `.Channel.gettimeout`
"""
return self.sftp.sock.gettimeout()
@ -205,10 +210,11 @@ class SFTPFile (BufferedFile):
Set blocking or non-blocking mode on the underiying socket or ssh
`.Channel`.
.. seealso:: `Channel.setblocking`
:param blocking: 0 to set non-blocking mode; non-0 to set blocking
mode.
:param blocking:
0 to set non-blocking mode; non-0 to set blocking mode.
:type blocking: int
.. seealso:: `.Channel.setblocking`
"""
self.sftp.sock.setblocking(blocking)
@ -226,11 +232,11 @@ class SFTPFile (BufferedFile):
def stat(self):
"""
Retrieve information about this file from the remote system. This is
exactly like `SFTP.stat`, except that it operates on an already-open
file.
exactly like `.SFTPClient.stat`, except that it operates on an
already-open file.
:return: an object containing attributes about this file.
:rtype: SFTPAttributes
:rtype: `.SFTPAttributes`
"""
t, msg = self.sftp._request(CMD_FSTAT, self.handle)
if t != CMD_ATTRS:
@ -240,7 +246,7 @@ class SFTPFile (BufferedFile):
def chmod(self, mode):
"""
Change the mode (permissions) of this file. The permissions are
unix-style and identical to those used by Python's ``os.chmod``
unix-style and identical to those used by Python's `os.chmod`
function.
:param mode: new permissions
@ -254,7 +260,7 @@ class SFTPFile (BufferedFile):
def chown(self, uid, gid):
"""
Change the owner (``uid``) and group (``gid``) of this file. As with
Python's ``os.chown`` function, you must pass both arguments, so if you
Python's `os.chown` function, you must pass both arguments, so if you
only want to change one, use `stat` first to retrieve the current
owner and group.
@ -341,12 +347,12 @@ class SFTPFile (BufferedFile):
concatenated together
:rtype: str
.. note:: Many (most?) servers don't support this extension yet.
:raises IOError: if the server doesn't support the "check-file"
extension, or possibly doesn't support the hash algorithm
requested
.. note:: Many (most?) servers don't support this extension yet.
.. versionadded:: 1.4
"""
t, msg = self.sftp._request(CMD_EXTENDED, 'check-file', self.handle,
@ -360,11 +366,11 @@ class SFTPFile (BufferedFile):
"""
Turn on/off the pipelining of write operations to this file. When
pipelining is on, paramiko won't wait for the server response after
each write operation. Instead, they're collected as they come in.
At the first non-write operation (including `close`), all remaining
each write operation. Instead, they're collected as they come in. At
the first non-write operation (including `.close`), all remaining
server responses are collected. This means that if there was an error
with one of your later writes, an exception might be thrown from
within `close` instead of `write`.
with one of your later writes, an exception might be thrown from within
`.close` instead of `.write`.
By default, files are not pipelined.
@ -378,14 +384,14 @@ class SFTPFile (BufferedFile):
def prefetch(self):
"""
Pre-fetch the remaining contents of this file in anticipation of
future `read` calls. If reading the entire file, pre-fetching can
Pre-fetch the remaining contents of this file in anticipation of future
`.read` calls. If reading the entire file, pre-fetching can
dramatically improve the download speed by avoiding roundtrip latency.
The file's contents are incrementally buffered in a background thread.
The prefetched data is stored in a buffer until read via the `read`
The prefetched data is stored in a buffer until read via the `.read`
method. Once data has been read, it's removed from the buffer. The
data may be read in a random order (using `seek`); chunks of the
data may be read in a random order (using `.seek`); chunks of the
buffer that haven't been read will continue to be buffered.
.. versionadded:: 1.5.1
@ -404,7 +410,7 @@ class SFTPFile (BufferedFile):
def readv(self, chunks):
"""
Read a set of blocks from the file by (offset, length). This is more
efficient than doing a series of `seek` and `read` calls, since the
efficient than doing a series of `.seek` and `.read` calls, since the
prefetch machinery is used to retrieve all the requested blocks at
once.

View File

@ -41,7 +41,7 @@ class SFTPHandle (object):
SFTP. If ``flags`` is passed in, it's used to determine if the file
is open in append mode.
:param flags: optional flags as passed to `SFTPServerInterface.open`
:param flags: optional flags as passed to `.SFTPServerInterface.open`
:type flags: int
"""
self.__flags = flags
@ -149,7 +149,7 @@ class SFTPHandle (object):
def stat(self):
"""
Return an `.SFTPAttributes` object referring to this open file, or an
error code. This is equivalent to `SFTPServerInterface.stat`, except
error code. This is equivalent to `.SFTPServerInterface.stat`, except
it's called on an open file instead of a path.
:return: an attributes object for the given file, or an SFTP error

View File

@ -42,7 +42,7 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
"""
Server-side SFTP subsystem support. Since this is a `.SubsystemHandler`,
it can be (and is meant to be) set as the handler for ``"sftp"`` requests.
Use `Transport.set_subsystem_handler` to activate this class.
Use `.Transport.set_subsystem_handler` to activate this class.
"""
def __init__(self, channel, name, server, sftp_si=SFTPServerInterface, *largs, **kwargs):
@ -50,7 +50,7 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
The constructor for SFTPServer is meant to be called from within the
`.Transport` as a subsystem handler. ``server`` and any additional
parameters or keyword parameters are passed from the original call to
`Transport.set_subsystem_handler`.
`.Transport.set_subsystem_handler`.
:param channel: channel passed from the `.Transport`.
:type channel: `.Channel`
@ -128,7 +128,7 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
:param e: an errno code, as from ``OSError.errno``.
:type e: int
:return: an SFTP error code like `.SFTP_NO_SUCH_FILE`.
:return: an SFTP error code like ``SFTP_NO_SUCH_FILE``.
:rtype: int
"""
if e == errno.EACCES:

View File

@ -17,7 +17,7 @@
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
"""
`.SFTPServerInterface` is an interface to override for SFTP server support.
An interface to override for SFTP server support.
"""
import os
@ -64,7 +64,7 @@ class SFTPServerInterface (object):
"""
The SFTP server session has just ended, either cleanly or via an
exception. This method is meant to be overridden to perform any
necessary cleanup before this ``SFTPServerInterface`` object is
necessary cleanup before this `.SFTPServerInterface` object is
destroyed.
"""
pass
@ -105,7 +105,7 @@ class SFTPServerInterface (object):
:param attr: requested attributes of the file if it is newly created.
:type attr: `.SFTPAttributes`
:return: a new `.SFTPHandle` or error code.
:rtype `.SFTPHandle`
:rtype: `.SFTPHandle`
"""
return SFTP_OP_UNSUPPORTED
@ -120,7 +120,7 @@ class SFTPServerInterface (object):
``os.stat``. In addition, each object should have its ``filename``
field filled in, since this is important to a directory listing and
not normally present in ``os.stat`` results. The method
`SFTPAttributes.from_stat` will usually do what you want.
`.SFTPAttributes.from_stat` will usually do what you want.
In case of an error, you should return one of the ``SFTP_*`` error
codes, such as `.SFTP_PERMISSION_DENIED`.
@ -131,11 +131,13 @@ class SFTPServerInterface (object):
`.SFTPAttributes` objects.
:rtype: list of `.SFTPAttributes` or error code
.. note:: You should normalize the given ``path`` first (see the
``os.path`` module) and check appropriate permissions before returning
the list of files. Be careful of malicious clients attempting to use
relative paths to escape restricted folders, if you're doing a direct
translation from the SFTP server path to your local filesystem.
.. note::
You should normalize the given ``path`` first (see the `os.path`
module) and check appropriate permissions before returning the list
of files. Be careful of malicious clients attempting to use
relative paths to escape restricted folders, if you're doing a
direct translation from the SFTP server path to your local
filesystem.
"""
return SFTP_OP_UNSUPPORTED

View File

@ -6,5 +6,8 @@ SFTP
.. automodule:: paramiko.sftp_server
.. automodule:: paramiko.sftp_attr
.. automodule:: paramiko.sftp_file
:inherited-members:
:no-special-members:
:show-inheritance:
.. automodule:: paramiko.sftp_handle
.. automodule:: paramiko.sftp_si