金字塔调用子请求

5 投票
3 回答
1910 浏览
提问于 2025-04-18 06:42

我正在尝试在Pyramid框架中实现一个批量请求的方法。我在文档中看到是通过

subrequest = Request.blank('/relative/url')
request.invoke_subrequest(subrequest)

来完成的。我只是想知道,如何传递头信息和 cookies 呢?这些是自动处理的吗,还是需要我自己来做

request.invoke_subrequest(subrequest, cookies=request.cookies, headers=request.headers)

那不同方法的参数呢?文档中只有一个 POST 的关键字参数。

我觉得文档有点模糊,或者我找不到正确的文档来了解该怎么做。谢谢

3 个回答

1

虽然有点晚了,但根据上面两个回答,我来分享一下我是怎么做的。我不太喜欢上面的回答,只是简单地复制所有内容。查看blank()方法的文档,里面有一个kw参数,它提到:

所有必要的键会被添加到环境中,但你传入的值会优先使用。如果你传入了base_url,那么wsgi.url_scheme、HTTP_HOST和SCRIPT_NAME会根据这个值来填充。

假设视图的请求包含了你需要的正确的头信息和cookies,你可以使用以下代码:

@view_config( ... )
def something(request):
    ...
    kwargs = { "cookies": request.cookies,                                  
               "host"   : request.host,                                     
             }                                                              
    req = Request.blank("/relative/url", **kwargs)
    resp = request.invoke_subrequest(req)                                   

其他的头信息(比如acceptaccept_encoding等)都是pyramid.request对象的属性,可以像上面的代码片段那样添加到kwargs字典中。

通过invoke_subrequest()返回的对象是一个响应对象,详细信息可以在这里找到。

3

下面的代码对我来说是有效的。它可以复制所有内容(包括头部信息、cookies、查询字符串、POST参数等等):

def subrequest(request, path):
    subreq = request.copy()
    subreq.path_info = path
    response = request.invoke_subrequest(subreq)
    return response
3

我只是想知道,如何传递头信息和 cookies 呢?

根据 这个链接

pyramid.request.Request.invoke_subrequest() 这个接口需要两个参数:一个是必须提供的请求对象,另一个是可选的 use_tweens 参数,默认值是 False。

这说明构造函数只需要一个 Request 对象,另外可以选择性地提供 use_tweens 的值,所以,不,这个

request.invoke_subrequest(subrequest, cookies=request.cookies, headers=request.headers)

是行不通的。

接下来,根据 这个链接

把原始请求对象作为参数传给 invoke_subrequest() 是个糟糕的主意。你应该像上面的例子那样构造一个新的请求,使用 pyramid.request.Request.blank()。一旦你构造了请求对象,你需要调整它,以匹配你希望在子请求中执行的视图函数。这可以通过调整子请求的 URL、头信息、请求方法和其他属性来完成。pyramid.request.Request 的文档中列出了你应该调用的方法和在创建请求时应该设置的属性,以便将其调整为实际匹配你希望通过子请求调用的视图。

所以基本上,你需要在把请求传给 invoke_subrequest() 之前先配置好它。

幸运的是,有 一个完整的页面记录了 Request 类。在这里你可以找到很多配置选项等等。


不同方法的参数呢?文档里只有一个 POST 的关键字参数。

在 Request 类的文档页面上,还有这个

method

获取和设置环境中的 REQUEST_METHOD 键。

这个链接上,我发现了

request_method 这个值可以是一个字符串(通常是 "GET"、"POST"、"PUT"、"DELETE" 或 "HEAD"),表示一个 HTTP REQUEST_METHOD。

我同意你的看法,文档在某些地方确实有点模糊,但我想你可以这样使用

request.method = 'POST'
# Or
request.method = 'GET'
# Etc.

总结

你应该这样做

subrequest = Request.blank('/relative/url')
# Configure the subrequest object
# set headers and other options you need.
request.invoke_subrequest(subrequest)

注意

我知道这不是一个 100% 完整的答案,没有一些可以直接复制粘贴的代码(特别是在配置请求对象方面),但我认为这个回答至少包含了一些信息,可以让你走上正确的道路,希望对你有所帮助。

撰写回答