回调¶
对于更细粒度的控制,libcurl允许与每个连接关联许多回调。在pycurl中,回调是使用 setopt()
具有选项的卷曲对象的方法 WRITEFUNCTION
, READFUNCTION
, HEADERFUNCTION
, PROGRESSFUNCTION
, XFERINFOFUNCTION
, IOCTLFUNCTION
或 DEBUGFUNCTION
. 这些选项对应于libcurl选项 CURLOPT_
前缀已删除。pycurl中的回调必须是常规的python函数、类方法或扩展类型函数。
与libcurl回调相比,可以与pycurl回调同时使用的某些选项存在一些限制。这是为了允许不同的回调函数与不同的curl对象相关联。更具体地说, WRITEDATA
不能与一起使用 WRITEFUNCTION
, READDATA
不能与一起使用 READFUNCTION
, WRITEHEADER
不能与一起使用 HEADERFUNCTION
. 在实践中,这些限制可以通过将回调函数作为类实例方法来克服,而不是使用类实例属性来存储每个对象的数据,例如回调中使用的文件。
下面记录了pycurl中使用的每个回调的签名。
错误报告¶
pycurl回调调用如下:
python应用程序-> perform()
->libcurl(C代码)->python回调
因为回调是由libcurl调用的,所以它们不应该在失败时引发异常,而是返回指示失败的适当值。下面单独回调的文档指定了预期的成功和失败返回值。
pycurl或python运行时将截获从python回调中传播的未处理异常。这将使回调失败,并具有一般的失败状态,反过来使 perform()
操作。失败 perform()
将提高 pycurl.error
,但使用的错误代码取决于特定的回调。
异常对象等丰富的上下文信息可以以各种方式存储,例如,下面的示例将opensocket回调异常存储在curl对象上:
import pycurl, random, socket
class ConnectionRejected(Exception):
pass
def opensocket(curl, purpose, curl_address):
# always fail
curl.exception = ConnectionRejected('Rejecting connection attempt in opensocket callback')
return pycurl.SOCKET_BAD
# the callback must create a socket if it does not fail,
# see examples/opensocketexception.py
c = pycurl.Curl()
c.setopt(c.URL, 'http://pycurl.io')
c.exception = None
c.setopt(c.OPENSOCKETFUNCTION,
lambda purpose, address: opensocket(c, purpose, address))
try:
c.perform()
except pycurl.error as e:
if e.args[0] == pycurl.E_COULDNT_CONNECT and c.exception:
print(c.exception)
else:
print(e)
WRITEFUNCTION¶
- WRITEFUNCTION(byte string) number of characters written ¶
用于写入数据的回调。相对应 CURLOPT_WRITEFUNCTION 在俚语中。
在python 3上,参数的类型为
bytes
.这个
WRITEFUNCTION
回调可能返回写入的字节数。如果此数字不等于字节字符串的大小,则表示有错误,libcurl将中止请求。返回None
是指示回调已消耗传递给它的所有字符串的另一种方法,因此成功了。write_test.py test 显示如何使用
WRITEFUNCTION
.
示例:文档标题和正文的回调¶
此示例将头数据打印到stderr,体数据打印到stdout。还要注意,回调都不会返回写入的字节数。对于writeFunction和headerFunction回调,返回none意味着写入的所有字节。
## Callback function invoked when body data is ready
def body(buf):
# Print body data to stdout
import sys
sys.stdout.write(buf)
# Returning None implies that all bytes were written
## Callback function invoked when header data is ready
def header(buf):
# Print header data to stderr
import sys
sys.stderr.write(buf)
# Returning None implies that all bytes were written
c = pycurl.Curl()
c.setopt(pycurl.URL, "http://www.python.org/")
c.setopt(pycurl.WRITEFUNCTION, body)
c.setopt(pycurl.HEADERFUNCTION, header)
c.perform()
HEADERFUNCTION¶
- HEADERFUNCTION(byte string) number of characters written ¶
用于写入接收头的回调。相对应 CURLOPT_HEADERFUNCTION 在俚语中。
在python 3上,参数的类型为
bytes
.这个
HEADERFUNCTION
回调可能返回写入的字节数。如果此数字不等于字节字符串的大小,则表示有错误,libcurl将中止请求。返回None
是指示回调已消耗传递给它的所有字符串的另一种方法,因此成功了。header_test.py test 显示如何使用
WRITEFUNCTION
.
READFUNCTION¶
- READFUNCTION(number of characters to read) byte string ¶
用于读取数据的回调。相对应 CURLOPT_READFUNCTION 在俚语中。
在Python3上,回调必须返回字节字符串或仅由ASCII码位组成的Unicode字符串。
此外,
READFUNCTION
可能返回READFUNC_ABORT
或READFUNC_PAUSE
. 有关这些值的说明,请参阅libcurl文档。这个 file_upload.py example 在发行版中包含用于
READFUNCTION
.
SEEKFUNCTION¶
- SEEKFUNCTION(offset, origin) status ¶
查找操作的回调。相对应 CURLOPT_SEEKFUNCTION 在俚语中。
IOCTLFUNCTION¶
- IOCTLFUNCTION(ioctl cmd) status ¶
用于I/O操作的回调。相对应 CURLOPT_IOCTLFUNCTION 在俚语中。
注: 此回调已被弃用。使用 SEEKFUNCTION 相反。
DEBUGFUNCTION¶
- DEBUGFUNCTION(debug message type, debug message byte string) None ¶
调试信息的回调。相对应 CURLOPT_DEBUGFUNCTION 在俚语中。
在7.19.5.2版中更改: 第二个论点
DEBUGFUNCTION
回调现在是类型bytes
在Python 3上。以前,参数的类型为str
.debug_test.py test 显示如何使用
DEBUGFUNCTION
.
示例:调试回调¶
此示例演示如何使用调试回调。调试消息类型是一个整数,指示调试消息的类型。必须启用verbose选项才能调用此回调。
def test(debug_type, debug_msg):
print "debug(%d): %s" % (debug_type, debug_msg)
c = pycurl.Curl()
c.setopt(pycurl.URL, "https://curl.haxx.se/")
c.setopt(pycurl.VERBOSE, 1)
c.setopt(pycurl.DEBUGFUNCTION, test)
c.perform()
PROGRESSFUNCTION¶
- PROGRESSFUNCTION(download total, downloaded, upload total, uploaded) status ¶
进度表的回调。相对应 CURLOPT_PROGRESSFUNCTION 在俚语中。
PROGRESSFUNCTION
接收作为回调浮点参数的金额。因为libcurl 7.32.0PROGRESSFUNCTION
被贬低;XFERINFOFUNCTION
应改为使用接收长度为整数的金额。NOPROGRESS
必须为false libcurl设置选项才能调用进度回调,默认情况下为pycurl设置NOPROGRESS
成真。
XFERINFOFUNCTION¶
- XFERINFOFUNCTION(download total, downloaded, upload total, uploaded) status ¶
进度表的回调。相对应 CURLOPT_XFERINFOFUNCTION 在俚语中。
XFERINFOFUNCTION
以长整数形式接收金额。NOPROGRESS
必须为false libcurl设置选项才能调用进度回调,默认情况下为pycurl设置NOPROGRESS
成真。
示例:下载/上载进度回调¶
此示例演示如何使用进度回调。下载文档时,与上载相关的参数为零,反之亦然。
## Callback function invoked when download/upload has progress
def progress(download_t, download_d, upload_t, upload_d):
print "Total to download", download_t
print "Total downloaded", download_d
print "Total to upload", upload_t
print "Total uploaded", upload_d
c = pycurl.Curl()
c.setopt(c.URL, "http://slashdot.org/")
c.setopt(c.NOPROGRESS, False)
c.setopt(c.XFERINFOFUNCTION, progress)
c.perform()
OPENSOCKETFUNCTION¶
- OPENSOCKETFUNCTION(purpose, address) int ¶
用于打开套接字的回调。相对应 CURLOPT_OPENSOCKETFUNCTION 在俚语中。
目的 是一个
SOCKTYPE_*
价值。地址 是一个 namedtuple 具有
family
,socktype
,protocol
和addr
每个字段 CURLOPT_OPENSOCKETFUNCTION 文档。addr 是表示地址的对象。目前支持以下地址系列:
AF_INET
: addr 是一个2元组(host, port)
.AF_INET6
: addr 是一个4元组(host, port, flow info, scope id)
.AF_UNIX
: addr 是包含Unix套接字路径的字节字符串。可用性:Unix。
此行为与Python的 socket module .
回调应该返回一个socket对象、一个socket文件描述符或一个具有
fileno
包含套接字文件描述符的属性。回调可以通过调用 setopt 具有
None
作为值或通过调用 unsetopt .open_socket_cb_test.py test 显示如何使用
OPENSOCKETFUNCTION
.在7.21.5版中更改: 以前,收到的回调
family
,socktype
,protocol
和addr
参数 (purpose
未通过address
被压扁了)。也,AF_INET6
地址被公开为(host, port)
而不是四元组。在7.19.3版中更改:
addr
参数已添加到回调。
CLOSESOCKETFUNCTION¶
- CLOSESOCKETFUNCTION(curlfd) int ¶
用于设置套接字选项的回调。相对应 CURLOPT_CLOSESOCKETFUNCTION 在俚语中。
库尔夫德 是要关闭的文件描述符。
回调应返回
int
.回调可以通过调用 setopt 具有
None
作为值或通过调用 unsetopt .close_socket_cb_test.py test 显示如何使用
CLOSESOCKETFUNCTION
.
SOCKOPTFUNCTION¶
- SOCKOPTFUNCTION(curlfd, purpose) int ¶
用于设置套接字选项的回调。相对应 CURLOPT_SOCKOPTFUNCTION 在俚语中。
库尔夫德 是新创建的套接字的文件描述符。
目的 是一个
SOCKTYPE_*
价值。回调应返回
int
.回调可以通过调用 setopt 具有
None
作为值或通过调用 unsetopt .sockopt_cb_test.py test 显示如何使用
SOCKOPTFUNCTION
.
SSH_KEYFUNCTION¶
- SSH_KEYFUNCTION(known_key, found_key, match) int ¶
已知主机匹配逻辑的回调。相对应 CURLOPT_SSH_KEYFUNCTION 在俚语中。
known_key 和 found_key 是的实例
KhKey
是一个 namedtuple 具有key
和keytype
字段,对应于libcurl的struct curl_khkey
::KhKey = namedtuple('KhKey', ('key', 'keytype'))
在python 2上, key 领域
KhKey
是一个str
. 在python 3上, key 字段是bytes
. 键入式 是一个int
.known_key 可能是
None
当没有已知匹配的主机密钥时。SSH_KEYFUNCTION
回调应返回KHSTAT_*
价值。回调可以通过调用 setopt 具有
None
作为值或通过调用 unsetopt .ssh_key_cb_test.py test 显示如何使用
SSH_KEYFUNCTION
.
TIMERFUNCTION¶
- TIMERFUNCTION(timeout_ms) None ¶
libcurl请求安装定时器的回调。对应于 CURLMOPT_TIMERFUNCTION 。
应用程序应该安排一个非重复计时器来触发
timeout_ms
毫秒,此时应用程序应调用 socket_action 或 perform 。看见
examples/multi-socket_action-select.py
用于使用计时器函数和套接字函数的示例程序。
SOCKETFUNCTION¶
- SOCKETFUNCTION(what, sock_fd, multi, socketp) None ¶
通知应用程序有关libcurl套接字上的活动的回调。对应于 CURLMOPT_SOCKETFUNCTION 。
请注意,PycURL回调使用
what
作为第一个参数,并且sock_fd
作为第二个参数,而libcurl回调采用sock_fd
作为第一个参数,并且what
作为第二个论点。这个
userp
(“私有回调指针”)参数,如CURLMOPT_SOCKETFUNCTION
文档)设置为CurlMulti
实例。这个
socketp
(“私有套接字指针”)参数,如CURLMOPT_SOCKETFUNCTION
文档)设置为提供给 assign 方法来创建相应的sock_fd
,或None
如果未赋值,则返回。看见
examples/multi-socket_action-select.py
用于使用计时器函数和套接字函数的示例程序。