import json from pathlib import Path from typing import Optional, Union from requests.structures import CaseInsensitiveDict from ytmusicapi.auth.oauth import OAuthToken from ytmusicapi.auth.types import AuthType from ytmusicapi.exceptions import YTMusicUserError def parse_auth_str(auth: Union[str, dict]) -> tuple[CaseInsensitiveDict, Optional[Path]]: """ :param auth: user-provided auth string or dict :return: parsed header dict based on auth, optionally path to file if it auth was a path to a file """ auth_path: Optional[Path] = None if isinstance(auth, str): auth_str: str = auth if auth.startswith("{"): input_json = json.loads(auth_str) elif (auth_path := Path(auth_str)).is_file(): with open(auth_path) as json_file: input_json = json.load(json_file) else: raise YTMusicUserError("Invalid auth JSON string or file path provided.") return CaseInsensitiveDict(input_json), auth_path else: return CaseInsensitiveDict(auth), auth_path def determine_auth_type(auth_headers: CaseInsensitiveDict) -> AuthType: """ Determine the type of auth based on auth headers. :param auth_headers: auth headers dict :return: AuthType enum """ auth_type = AuthType.OAUTH_CUSTOM_CLIENT if OAuthToken.is_oauth(auth_headers): auth_type = AuthType.OAUTH_CUSTOM_CLIENT if authorization := auth_headers.get("authorization"): if "SAPISIDHASH" in authorization: auth_type = AuthType.BROWSER elif authorization.startswith("Bearer"): auth_type = AuthType.OAUTH_CUSTOM_FULL return auth_type