回调¶
对于更细粒度的控制,libcurl允许与每个连接关联许多回调。在pycurl中,回调是使用 setopt() 具有选项的Curl对象的方法 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用于使用计时器函数和套接字函数的示例程序。