本文作者:admin

PycURL 7.45.3文档介绍,你了解多少?

PycURL 7.45.3文档介绍,你了解多少?摘要: 回调对于更细粒度的控制,libcurl允许与每个连接关联许多回调。在pycurl中,回调是使用 setopt() 具有选项的Curl对象的方法 WRITEFUNCTION...

[id_700861631]id_239187423]

为了实现更精密的操作,libcurl能够为各个连接绑定多个回调函数,以此达成目的。在pycurl里,回调是通过setopt()这个Curl对象的方法来设置的,具体包括WRITEFUNCTION,READFUNCTION,HEADERFUNCTION,PROGRESSFUNCTION,XFERINFOFUNCTION,IOCTLFUNCTION以及DEBUGFUNCTION这些选项,它们分别对应于libcurl选项中CURLOPT_前缀被移除的部分。pycurl所要求的回调函数,必须是普通的Python函数,或者是类的成员方法,亦或是扩展类型定义的函数。

pycurl回调和libcurl回调之间,部分选项的兼容性存在差异,这种差异旨在使不同的回调函数能够分别绑定到各自的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(拒绝接受连接请求于开放套接字回调过程中)
    return pycurl.SOCKET_BAD
    回调函数需要建立套接字,前提是它没有出现错误
    查看示例中的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

写入函数处理字节字符串,返回已写入字符的总数

数据写入时调用的接口,与俗称的 CURLOPT_WRITEFUNCTION 对应。

在python 3上,参数的类型为 bytes .

这个回调函数 WRITEFUNCTION 可能有返回值,代表写入的字节量。若这个值与字节字符串的长度不一致,就说明出现了问题,libcurl会终止当前请求。当回调函数返回 None 时,也意味着它已经处理完所有传入的字符串,这种情况表示操作成功。

编写测试代码时,可以了解运用 WRITEFUNCTION 的方法,具体实例在名为 write_test.py 的文件中呈现,该文件展示了其使用方式。

示例:文档标题和正文的回调

这个范例把头部信息输出到标准错误,把主体信息输出到标准输出,必须留意,所有回调都不会返回写入的字符量。针对writeFunction和headerFunction回调,返回空值表示所有字符已写入完成。

调用回调函数时,表示主体数据已经获取完毕
def body(buf):
    # Print body data to stdout
    import sys
    sys.stdout.write(buf)
    返回空表示所有字节均已写入
调用回调函数时,表明头部数据已经获取完毕
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

对字节字符串执行头部函数处理,能够生成对应的字符计数结果

用作填写接收头信息的函数,与俗称中的 CURLMOPT_WRITEFUNCTION 相对应。

在python 3上,参数的类型为 bytes .

这个回调函数 HEADERFUNCTION 可能会返回写入的字节数量。如果这个数量不等于字节字符串的体积,就意味着出现了问题,libcurl会终止当前请求。返回空值 None 也是一种成功的方式,它表明回调已经处理完了所有传递给它的数据。

头部测试文件测试展示了怎样运用写入功能函数。

READFUNCTION

读取指定数量的字符,转换成字节串

处理数据输入的函数,即人们常说的那个读取操作的回调函数。

在Python3环境中,回调函数的输出要求为字节字符串,或者是仅由ASCII码位构成的Unicode字符串。

另外,READFUNCTION函数或许会得出READFUNC_ABORT这个结果,或者给出READFUNC_PAUSE这个结果。想了解这些结果的详细情况,可以查阅libcurl的相关文档。

这个名为 file_upload.py 的范例包含在发行版里,其目的是用于 READFUNCTION 功能。

SEEKFUNCTION

查询函数以偏移量和原始值为参数,返回状态信息

搜索任务的处理函数,与民间说法中的 CURLOPT_SEEKFUNCTION 对应。

IOCTLFUNCTION

执行特定控制命令,返回操作结果

执行输入输出任务的回调函数,其功能等同 API 中名为 CURLOPT_IOCTLFUNCTION 的选项,在行话里俗称这一用法。

注: 此回调已被弃用。使用 相反。

DEBUGFUNCTION

调试功能调试信息类型,调试信息字节串,无返回值

调试信息的返回函数,这相当于配置选项中的调试功能回调地址。

在7.19.5.2版本里调整:第二个论点 DEBUGFUNCTION 回调现在其参数为 bytes 类型,在Python 3环境下。此前,该参数的类型是 str。

执行 debug_test.py 测试程序,可以了解 DEBUGFUNCTION 的具体应用方法。

示例:调试回调

这个例子说明怎样运用调试过程中的回调功能,调试信息的种类是一个数字,它表明了调试信息的性质,只有当详细输出模式被打开时,才能使用这个回调。

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

进度函数接收下载总数据量、已下载数据量、上传总数据量、已上传数据量四个参数,然后返回当前状态

进度更新的通知。这就是所谓的 CURL 设置中的回调函数。

PROGRESSFUNCTION 需要一个浮点数作为回调参数。由于libcurl 7.32.0版本中PROGRESSFUNCTION的功能被弱化,现在应该改为使用一个整数长度的参数,来替代XFERINFOFUNCTION。

调用进度回调前,必须将长句拆分成多个小分句,用逗号隔开,并设置 libcurl 的 NOPROGRESS 为假,因为 pycurl 默认将其设为真。

XFERINFOFUNCTION

传输信息函数包含下载总量,已下载部分,上传总量,已上传部分,并返回状态

进度汇报的响应机制,等同那个叫作 XFERINFOFUNCTION 的选项在行话里的说法

XFERINFOFUNCTION 以长整数形式接收金额。

NOPROGRESS 必须为false libcurl设置选项才能调用进度回调,默认情况下为pycurl设置 NOPROGRESS 成真。

示例:下载/上载进度回调

这个例子说明怎样运用过程反馈功能,文件下载期间,涉及上传的那些数据都是空白,而当进行上传操作时,与此下载有关的数值则没有值。

回调函数在下载或上传过程中有进展时被调用
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

调用开放套接字功能,指定用途,目标地址,返回一个整数值

执行创建套接字的函数。这对应着配置选项名中的特定标识符。

目的 是一个 SOCKTYPE_* 价值。

地址由多个字段构成,其中包括 family, socktype, protocol, 以及 addr。这些字段都属于 CURLOPT_OPENSOCKETFUNCTION 文档。

addr 是表示地址的对象。目前支持以下地址系列:

此行为与Python的 socket module .

回调函数需要提供一个套接字实例、一个套接字文件标识号,或者一个属性,这个属性里包含着 fileno 字段,该字段存储着套接字的文件标识号。

回调可以通过调用 具有 None 作为值或通过调用 .

open_socket_cb_test.py 测试展示了怎样运用 OPENSOCKETFUNCTION 。

在7.21.5版本里做了调整:原先,接收到的回调参数包括 family, socktype, protocol 以及 addr,但 purpose 没有通过 address 被压缩成块。此外,AF_INET6 地址以 host 和 port 的形式公开,而不是四元组。

在7.19.3版中更改: addr 参数已添加到回调。

CLOSESOCKETFUNCTION

关闭套接字功能 curlfd,返回一个整数值

设置套接字参数的函数,与俗称中的 CLOSESOCKETFUNCTION 对应,用于回调操作。

库尔夫德 是要关闭的文件描述符。

回调应返回 int .

回调可以通过调用 具有 None 作为值或通过调用 .

该文件测试展示怎样运用 CLOSESOCKETFUNCTION 函数。

SOCKOPTFUNCTION

SOCKOPTFUNCTION调用curlfd参数, 执行purpose参数指定的功能, 返回一个整数值

设置套接字参数的函数,它对应着俚语中的 CURLOPT_SOCKOPTFUNCTION。

库尔夫德 是新创建的套接字的文件描述符。

目的 是一个 SOCKTYPE_* 价值。

回调应返回 int .

回调可以通过调用 具有 None 作为值或通过调用 .

这个文件名为sockopt_cb_test.py的测试展示了怎样运用SOCKOPTFUNCTION这个功能。

SSH_KEYFUNCTION

SSH密钥功能处理已知密钥,查找匹配密钥,返回比较结果,类型为整数值

识别设备符合规则的响应函数,这对应着所谓的 SSH 密钥回调选项

known_key 与 found_key 是 KhKey 的具体对象,KhKey 是一种结构体,包含 key 和 keytype 两个属性,这些属性与 libcurl 中的 curl_khkey 结构相对应

KhKey = namedtuple('KhKey', ('key', 'keytype'))

在python 2版本中,key字段名为KhKey,其数据类型为字符串类型。在python 3版本中,key字段名同样是KhKey,但数据类型变成了字节类型。键入式字段的数据类型为整型。

已知匹配的主机密钥不存在时,known_key 有可能为空值。

SSH_KEYFUNCTION 回调需要给出 KHSTAT_* 类型的结果。

回调可以通过调用 具有 None 作为值或通过调用 .

ssh_key_cb_test.py 测试展示 SSH_KEYFUNCTION 的应用方式。

TIMERFUNCTION

计时器函数接收超时毫秒数,不返回任何值

libcurl需要安装定时器的回调函数,这个选项叫做CURLMOPT_TIMERFUNCTION。

软件需设定一个独一无二的计时装置,在经过 timeout_ms 秒之后启动,届时软件须执行 或 的操作。

注意到 examples/multi-socket_action-select.py 这个示例程序,它展示了如何运用计时器函数和套接字函数。

SOCKETFUNCTION

创建函数处理参数what, 使用文件描述符sock_fd, 接收多路复用参数multi, 处理socket指针socketp, 不返回任何值

告知通知软件关于libcurl套接字活动的情况,这等同于CURLMOPT_SOCKETFUNCTION选项。

PycURL的回调函数以 what 为首个参数项,同时将 sock_fd 作为次序参数项,而 libcurl的回调函数则将 sock_fd 放在首位,what 放在后续位置。

这个名为 userp 的参数,其含义是“私有回调指针”,在 CurlMulti 实例中,应将其设定为 CURLMOPT_SOCKETFUNCTION 文档所描述的值

这个 socketp 参数,即“私有套接字指针”,依据 CURLMOPT_SOCKETFUNCTION 文档所述,若指定给方法,则用于生成相应的 sock_fd,若未指定,则返回 None。

看见 examples/multi-socket_action-select.py 用于使用计时器函数和套接字函数的示例程序。

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

阅读
分享

发表评论

快捷回复:

评论列表 (暂无评论,3人围观)参与讨论

还没有评论,来说两句吧...