I also faced the same question and went to the source code to find a suitable solution for me.
In my opinion Session class generally has various problems.
- It initializes the default HTTPAdapter in the constructor and leaks it if you mount another one to 'http' or 'https'.
 
- HTTPAdapter implementation maintains the connection pool, I think it is not something to create on each Session object instantiation.
 
- Session closes HTTPAdapter, thus you can't reuse the connection pool between different Session instances.
 
- Session class doesn't seem to be thread safe according to various discussions.
 
- HTTPAdapter internally uses the urlib3.PoolManager. And I didn't find any obvious problem related to the thread safety in the source code, so I would rather trust the documentation, which says that urlib3 is thread safe.
 
As the conclusion from the above list I didn't find anything better than overriding Session class
class HttpSession(Session):
    def __init__(self, adapter: HTTPAdapter):
        self.headers = default_headers()
        self.auth = None
        self.proxies = {}
        self.hooks = default_hooks()
        self.params = {}
        self.stream = False
        self.verify = True
        self.cert = None
        self.max_redirects = DEFAULT_REDIRECT_LIMIT
        self.trust_env = True
        self.cookies = cookiejar_from_dict({})
        self.adapters = OrderedDict()
        self.mount('https://', adapter)
        self.mount('http://', adapter)
    def close(self) -> None:
        pass
And creating the connection factory like:
class HttpSessionFactory:
    def __init__(self,
             pool_max_size: int = DEFAULT_CONNECTION_POOL_MAX_SIZE,
             retry: Retry = DEFAULT_RETRY_POLICY):
        self.__http_adapter = HTTPAdapter(pool_maxsize=pool_max_size, max_retries=retry)
    def session(self) -> Session:
        return HttpSession(self.__http_adapter)
    def close(self):
        self.__http_adapter.close()
Finally, somewhere in the code I can write:
with self.__session_factory.session() as session:
    response = session.get(request_url)
And all my session instances will reuse the same connection pool.
And somewhere at the end when the application stops I can close the HttpSessionFactory.
Hope this will help somebody.