borisbabic / browser_cookie3

This is a fork of browser_cookie
GNU Lesser General Public License v3.0
854 stars 144 forks source link

Add BrowserCookieJar class and get_browser function #186

Open ReK42 opened 1 year ago

ReK42 commented 1 year ago

Adds the following methods to get cookies:

BrowserCookieJar is a subclass of http.cookiejar.CookieJar which will take the browser name as a string:

Python 3.11.4 (tags/v3.11.4:d2340ef, Jun  7 2023, 05:45:37) [MSC v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from browser_cookie3 import BrowserCookieJar
>>> cookiejar = BrowserCookieJar("firefox", domain_name="bandcamp.com")
>>> for cookie in cookiejar:
...     print(cookie)
...     break
...
<Cookie client_id=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX for .bandcamp.com/>

get_browser is a function which will return the browser-specific function based on the browser name as a string:

Python 3.11.4 (tags/v3.11.4:d2340ef, Jun  7 2023, 05:45:37) [MSC v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from browser_cookie3 import get_browser
>>> cookies = get_browser("firefox")(domain_name="bandcamp.com")
>>> for cookie in cookies:
...     print(cookie)
...     break
...
<Cookie client_id=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX for .bandcamp.com/>

To support these, I update the type annotations on the existing browser-specific functions, including adding the key_file argument to those which didn't have it, for consistency. Additionally, both methods use a new SUPPORTED_BROWSERS dictionary, and the load method was updated to use it as well:

Python 3.11.4 (tags/v3.11.4:d2340ef, Jun  7 2023, 05:45:37) [MSC v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from browser_cookie3 import load
>>> cookies = load("bandcamp.com")
>>> for cookie in cookies:
...     print(cookie)
...     break
...
<Cookie client_id=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX for .bandcamp.com/>
ReK42 commented 1 year ago

I added these because I'm currently using the following method to pull cookies from a specific browser in bcamp-dl, where self.browser is a string argument from the user:

func = getattr(browser_cookie3, self.browser)
self.cookies = func(domain_name="bandcamp.com")

This seems a little fragile to me, as I need to validate the string against a list of supported browsers that isn't easily available from upstream, and it can produce some unhelpful exceptions if it goes wrong. Adding a subclass of http.cookiejar.CookieJar which will raise a helpful exception if the browser is not supported makes this a lot cleaner. I can now rely on upstream to validate for me, and it's a lot more clear that the result is a standard CookieJar object.

The load function is useful but doesn't quite do what I want: I want to load a cookie from a specific browser, not from all available browsers. I did add get_browser as an alternative method to get the specific function, as opposed to getattr.