同时使用会话上下文管理器和stream = True

时间:2017-12-08 01:25:34

标签: python session python-requests

我想知道这段代码是否安全:

import requests
with requests.Session() as s:
    response = s.get("http://google.com", stream=True)
content = response.content

例如这样简单,这不会失败(注意我不写“它工作”:p),因为池无论如何都不会立即关闭连接(这是会话/池的一个点吗?)

使用stream=True,响应对象应该具有包含连接的raw属性,但我不确定连接是否由会话拥有,然后在某些情况下如果我现在没有阅读内容,但稍后,它可能已被关闭。

我现在的2美分是它不安全,但我不是百分百肯定。

谢谢!

[阅读请求代码后编辑]

在详细阅读请求代码之后,似乎requests.get正在做什么:

https://github.com/requests/requests/blob/master/requests/api.py

def request(method, url, **kwargs):
    with sessions.Session() as session:
        return session.request(method=method, url=url, **kwargs)

因为kwargs可能包含stream

所以我猜答案是“这是安全的”。

1 个答案:

答案 0 :(得分:1)

好的,我通过挖掘requestsurllib3

得到了答案

Response对象拥有连接,直到显式调用close()方法:

https://github.com/requests/requests/blob/24092b11d74af0a766d9cc616622f38adb0044b9/requests/models.py#L937-L948

def close(self):
    """Releases the connection back to the pool. Once this method has been
    called the underlying ``raw`` object must not be accessed again.
    *Note: Should not normally need to be called explicitly.*
    """
    if not self._content_consumed:
        self.raw.close()

    release_conn = getattr(self.raw, 'release_conn', None)
    if release_conn is not None:
        release_conn()

release_conn()urllib3方法,这会释放连接并将其放回池中

def release_conn(self):
    if not self._pool or not self._connection:
        return

    self._pool._put_conn(self._connection)
    self._connection = None

如果Session被销毁(比如使用with),则游戏池被销毁,连接无法恢复,只是关闭。

TL; DR;这很安全。

请注意,这也意味着在stream模式下,在明确关闭响应或完全读取内容之前,连接不可用于池。