Problem
The pattern load_cookies() → is_authenticated() → build headers → ssl.create_default_context() → urllib.request.Request() → urlopen() → parse response → handle errors is repeated 15+ times across the codebase.
Concrete numbers:
- 18 calls to
load_cookies()
- 15
ssl.create_default_context() instantiations
- 10 hardcoded
User-Agent: Mozilla/5.0... strings
- 18
urllib.request.Request constructions
This accounts for roughly 400 lines of duplicated boilerplate.
Proposed Solution
Extract a CookidooClient class or a simple api_request() helper:
class CookidooClient:
def __init__(self):
self.cookies = load_cookies()
self.ctx = ssl.create_default_context()
self._headers = {
"User-Agent": "Mozilla/5.0 ...",
"Accept": "application/json",
}
@property
def is_authenticated(self) -> bool:
return "v-authenticated" in self.cookies or "_oauth2_proxy" in self.cookies
def request(self, url, method="GET", data=None, accept="application/json"):
"""Single point for all authenticated Cookidoo API calls."""
if not self.is_authenticated:
return CookidooResult(ok=False, error="Nicht eingeloggt")
headers = {**self._headers, "Cookie": format_cookie_header(self.cookies)}
if accept:
headers["Accept"] = accept
# ... single implementation of request + error handling
This would:
- Eliminate ~400 lines of duplication
- Create a single point for auth checking
- Make error handling consistent
- Enable future improvements (retry logic, connection reuse)
Effort
Medium — requires touching all API functions but is mechanical refactoring.
Problem
The pattern
load_cookies()→is_authenticated()→ build headers →ssl.create_default_context()→urllib.request.Request()→urlopen()→ parse response → handle errors is repeated 15+ times across the codebase.Concrete numbers:
load_cookies()ssl.create_default_context()instantiationsUser-Agent: Mozilla/5.0...stringsurllib.request.RequestconstructionsThis accounts for roughly 400 lines of duplicated boilerplate.
Proposed Solution
Extract a
CookidooClientclass or a simpleapi_request()helper:This would:
Effort
Medium — requires touching all API functions but is mechanical refactoring.