Skip to content

Add option to disable cookie persistence in Client/AsyncClient #2992

Open

Description

@fastily

Initially raised as discussion #1533

I've been using httpx's AsyncClient as a web spider, however I have noticed that cookies are automatically persisted and there's no easy way to disable this. My workaround has been to subclass python's http.cookiejar.CookieJar like so:

from http.cookiejar import CookieJar

class NullCookieJar(CookieJar):
    """A CookieJar that rejects all cookies."""

    def extract_cookies(self, *_):
        """For extracting and saving cookies.  This implementation does nothing"""
        pass

    def set_cookie(self, _):
        """Normally for setting a cookie.  This implementation does nothing"""
        pass

Would it be possible to:

  1. add an option to disable cookie persistence to Client/AsyncClient or
  2. include this implementation of NullCookieJar in httpx as a utility class?

Thanks!

Activity

  1. karpetrosyan commented on Dec 18, 2023

    @karpetrosyan
    Contributor

    Hi!
    Perhaps you could remove the Set-Cookie header before it reaches the client instance?

    Example:

    import httpx
    
    
    class DisableCookieTransport(httpx.BaseTransport):
        def __init__(self, transport: httpx.BaseTransport):
            self.transport = transport
    
        def handle_request(self, request: httpx.Request) -> httpx.Response:
            response = self.transport.handle_request(request)
            del response.headers["set-cookie"]
            return response
    
    
    client = httpx.Client(transport=DisableCookieTransport(httpx.HTTPTransport()))
    
    response = client.get("https://httpbin.org/cookies/set?foo=bar")
  2. idrissbellil commented on May 27, 2024

    @idrissbellil

    For AsyncClient I am guessing the workaround is:

    class AsyncDisableCookieTransport(httpx.AsyncBaseTransport):
        def __init__(self, transport: httpx.AsyncBaseTransport):
            self.transport = transport
    
        async def handle_async_request(self, request: httpx.Request) -> httpx.Response:
            response = await self.transport.handle_async_request(request)
            response.headers.pop("set-cookie", None)
            return response
    
    client = httpx.AsyncClient(transport=AsyncDisableCookieTransport(httpx.AsyncHTTPTransport()))
  3. lovelydinosaur commented on Aug 27, 2024

    @lovelydinosaur
    Member

    Perhaps this is a common enough use-case that we should add cookies = httpx.NoCookies(), in line with @fastily's suggestion?

  4. sobolevn commented on Dec 9, 2024

    @sobolevn

    I would love to see something like #3065 merged. I consider merging cookies by default to be a possible attack vector, so I would love to turn this off, when not needed.

  5. jschlyter commented on Dec 18, 2024

    @jschlyter

    +1 for #3065

  6. BlackCloud37 commented on Sep 15, 2025

    @BlackCloud37

    For AsyncClient I am guessing the workaround is:

    class AsyncDisableCookieTransport(httpx.AsyncBaseTransport):
    def init(self, transport: httpx.AsyncBaseTransport):
    self.transport = transport

    async def handle_async_request(self, request: httpx.Request) -> httpx.Response:
        response = await self.transport.handle_async_request(request)
        response.headers.pop("set-cookie", None)
        return response
    

    client = httpx.AsyncClient(transport=AsyncDisableCookieTransport(httpx.AsyncHTTPTransport()))

    For anyone use this, you might also want add a aclose impl that calls await self.transport.aclose() or derive the custom transport from AsyncHTTPTransport which has correct impl of aclose

    Otherwise the custom transport won't be closed correctly since it's aclose does nothing.

  7. scratchmex commented on Oct 3, 2025

    @scratchmex

    I think the best approach is NoopCookies(). the #3065 approach pollutes the api too much. see how many new arguments are added to cascade it

  8. wRAR commented on Feb 10, 2026

    @wRAR

    Perhaps you could remove the Set-Cookie header before it reaches the client instance?

    Unfortunately this doesn't seem like a good idea if you want the user code to process the Set-Cookie headers itself (I guess you could reinstate the header somewhere down the line but I'm not sure what would you need to subclass for that).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions