In http://bugs.python.org/issue17552 me and a bunch of other devs are currently discussing what kind of API socket.sendfile() should have and because it seems there are different opinions about it I though I should have brought this up here for further discussion. With issue 17552 I'm proposing to provide a wrapper on top of os.sendfile(), socket.send() and possibly TransmitFile on Windows. AFAIK the modules which could immediately benefit from this addition are ftplib ( http://bugs.python.org/issue13564) and httplib ( http://bugs.python.org/issue13559).
This is the current function signature as of socket-sendfile5.patch:
def sendfile(self, file, blocksize=262144, offset=0, use_fallback=True): """sendfile(file[, blocksize[, offset[, use_fallback]]]) -> sent Send a file until EOF is reached attempting to use high-performance os.sendfile() in which case *file* must be a regular file object opened in binary mode; if not and *use_fallback* is True send() will be used instead. File position is updated on return or also in case of error in which case file.tell() can be used to figure out the number of bytes which were transmitted. *blocksize* is the maximum number of bytes to transmit at one time, *offset* tells from where to start reading the file. The socket must be of SOCK_STREAM type. Non-blocking sockets are not supported. Return the total number of bytes which were transmitted. """
Debatable questions which were raised during the discussion on the bug tracker are:
1 - whether to provide a "use_fallback" argument which when False raises an exception in case os.sendfile() could not be used
2 - whether to provide a custom exception in order to signal the number of bytes transmitted as opposed to use file.tell() afterwards; for the record, I'm -1 on this.
3 - whether to commit the patch as-is without including Windows support via TransmitFile() and post-pone that for a later time in a separate issue
4 - (extra) whether to provide a "callback" argument which gets called against each block of data before it is being sent. This would be useful to apply data transformation or to implement a progress bar or something. Note if this gets added it would sort of conflict with the "use_fallback=False" parameter because in order to apply data transformation socket.send() must be used instead of os.sendfile().
So far #1 appears to be the most debatable question.
-- Giampaolo - http://grodola.blogspot.com