【问题标题】:How to close requests.Session()?如何关闭 requests.Session()?
【发布时间】:2018-03-13 18:20:50
【问题描述】:

我正在尝试关闭 requests.Session(),但它没有关闭。

s = requests.Session()
s.verify = 'cert.pem'
res1 = s.get("https://<ip>:<port>/<route>")
s.close() #Not working
res2 = s.get("https://<ip>:<port>/<route>") # this is still working which means s.close() didn't work.

如何关闭会话? s.close() 没有抛出任何错误,这也意味着它是一个有效的语法,但我不明白它到底在做什么。

【问题讨论】:

    标签: python session https get python-requests


    【解决方案1】:

    requests的源代码中,Session.close只关闭所有底层Adapter。进一步关闭Adapter 正在清除底层PoolManager。那么所有的 在此PoolManager 中建立的连接将被关闭。但是如果没有可用的连接,PoolManager 会创建一个新的连接。

    关键代码:

    # requests.Session
    def close(self):
        """Closes all adapters and as such the session"""
        for v in self.adapters.values():
            v.close()
    
    # requests.adapters.HTTPAdapter
    def close(self):
        """Disposes of any internal state.
    
        Currently, this closes the PoolManager and any active ProxyManager,
        which closes any pooled connections.
        """
        self.poolmanager.clear()
        for proxy in self.proxy_manager.values():
            proxy.clear()
    
    # urllib3.poolmanager.PoolManager
    def connection_from_pool_key(self, pool_key, request_context=None):
        """
        Get a :class:`ConnectionPool` based on the provided pool key.
    
        ``pool_key`` should be a namedtuple that only contains immutable
        objects. At a minimum it must have the ``scheme``, ``host``, and
        ``port`` fields.
        """
        with self.pools.lock:
            # If the scheme, host, or port doesn't match existing open
            # connections, open a new ConnectionPool.
            pool = self.pools.get(pool_key)
            if pool:
                return pool
    
            # Make a fresh ConnectionPool of the desired type
            scheme = request_context['scheme']
            host = request_context['host']
            port = request_context['port']
            pool = self._new_pool(scheme, host, port, request_context=request_context)
            self.pools[pool_key] = pool
    
        return pool
    

    所以如果我很好理解它的结构,当你关闭一个Session 时,你几乎和创建一个新的Session 并把它分配给旧的一样。所以你仍然可以使用它来发送请求。

    或者如果我有什么误解,欢迎指正:D

    【讨论】:

    • 但是PoolManager会在没有可用连接的情况下创建一个新的连接 --> 什么时候会发生这种情况?
    • 当您创建一个新的PoolManager 时,它只包含一个空的pools。或者当你clear一个PoolManager,它会清除pools
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多