์ฝ˜ํ…์ธ ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

์ฐธ์กฐ hub_sdk/base/auth.py

์ฐธ๊ณ 

์ด ํŒŒ์ผ์€ https://github.com/ultralytics/ hub-sdk/blob/main/ hub_sdk/base/auth .py์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ•˜๋ฉด ํ’€ ๋ฆฌํ€˜์ŠคํŠธ (๐Ÿ› ๏ธ)๋ฅผ ์ œ์ถœํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ฃผ์„ธ์š”. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ๐Ÿ™!



hub_sdk.base.auth.Auth

์ธ์ฆ ๊ด€๋ฆฌ์ž๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

์†์„ฑ:

์ด๋ฆ„ ์œ ํ˜• ์„ค๋ช…
api_key (str, None)

์ธ์ฆ์— ์‚ฌ์šฉ๋˜๋Š” API ํ‚ค์ž…๋‹ˆ๋‹ค.

id_token (str, None)

์ธ์ฆ ํ† ํฐ์ž…๋‹ˆ๋‹ค.

์˜ ์†Œ์Šค ์ฝ”๋“œ hub_sdk/base/auth.py
class Auth:
    """
    Represents an authentication manager.

    Attributes:
        api_key (str, None): The API key used for authentication.
        id_token (str, None): The authentication token.
    """

    def __init__(self):
        """Initializes the Auth class with default authentication settings."""
        self.api_key = None
        self.id_token = None

    def authenticate(self) -> bool:
        """
        Attempt to authenticate with the server using either id_token or API key.

        Returns:
            (bool): True if authentication is successful, False otherwise.

        Raises:
            (ConnectionError): If request response is hasn't success in json, raised connection error exception.
        """
        try:
            header = self.get_auth_header()
            if header:
                r = requests.post(f"{HUB_API_ROOT}/v1/auth", headers=header)
                if not r.json().get("success", False):
                    raise ConnectionError("Unable to authenticate.")
                return True
            raise ConnectionError("User has not authenticated locally.")
        except ConnectionError:
            logger.warning(f"{PREFIX} Invalid API key โš ๏ธ")
        except requests.exceptions.RequestException as e:
            status_code = None
            if hasattr(e, "response"):
                status_code = e.response.status_code

            error_msg = ErrorHandler(status_code).handle()
            logger.warning(f"{PREFIX} {error_msg}")

        self.id_token = self.api_key = False  # reset invalid
        return False

    def get_auth_header(self) -> Optional[dict]:
        """
        Get the authentication header for making API requests.

        Returns:
            (Optional[dict]): The authentication header if id_token or API key is set, None otherwise.
        """
        if self.id_token:
            return {"authorization": f"Bearer {self.id_token}"}
        elif self.api_key:
            return {"x-api-key": self.api_key}
        else:
            return None

    def get_state(self) -> bool:
        """
        Get the authentication state.

        Returns:
            (bool): True if either id_token or API key is set, False otherwise.
        """
        return self.id_token or self.api_key

    def set_api_key(self, key: str):
        """
        Set the API key for authentication.

        Args:
            key (str): The API key string.
        """
        self.api_key = key

    def authorize(self, email: str, password: str) -> bool:
        """
        Authorize the user by obtaining an idToken through a POST request with email and password.

        Args:
            email (str): User's email.
            password (str): User's password.

        Returns:
            (bool): True if authorization is successful, False otherwise.
        """
        try:
            headers = {"origin": HUB_WEB_ROOT}
            response = requests.post(FIREBASE_AUTH_URL, json={"email": email, "password": password}, headers=headers)
            if response.status_code == 200:
                self.id_token = response.json().get("idToken")
                return True
            else:
                raise ConnectionError("Authorization failed.")
        except ConnectionError:
            logger.warning(f"{PREFIX} Invalid API key โš ๏ธ")
        except requests.exceptions.RequestException as e:
            status_code = None
            if hasattr(e, "response"):
                status_code = e.response.status_code

            error_msg = ErrorHandler(status_code).handle()
            logger.warning(f"{PREFIX} {error_msg}")

__init__()

๊ธฐ๋ณธ ์ธ์ฆ ์„ค์ •์œผ๋กœ Auth ํด๋ž˜์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

์˜ ์†Œ์Šค ์ฝ”๋“œ hub_sdk/base/auth.py
def __init__(self):
    """Initializes the Auth class with default authentication settings."""
    self.api_key = None
    self.id_token = None

authenticate()

id_token ๋˜๋Š” API ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„์— ์ธ์ฆ์„ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค:

์œ ํ˜• ์„ค๋ช…
bool

์ธ์ฆ์— ์„ฑ๊ณตํ•˜๋ฉด ์ฐธ์ด๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๊ฑฐ์ง“์ž…๋‹ˆ๋‹ค.

์˜ฌ๋ฆฌ๊ธฐ:

์œ ํ˜• ์„ค๋ช…
ConnectionError

์š”์ฒญ ์‘๋‹ต์ด json์—์„œ ์„ฑ๊ณตํ•˜์ง€ ๋ชปํ•˜๋ฉด ์—ฐ๊ฒฐ ์˜ค๋ฅ˜ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์˜ ์†Œ์Šค ์ฝ”๋“œ hub_sdk/base/auth.py
def authenticate(self) -> bool:
    """
    Attempt to authenticate with the server using either id_token or API key.

    Returns:
        (bool): True if authentication is successful, False otherwise.

    Raises:
        (ConnectionError): If request response is hasn't success in json, raised connection error exception.
    """
    try:
        header = self.get_auth_header()
        if header:
            r = requests.post(f"{HUB_API_ROOT}/v1/auth", headers=header)
            if not r.json().get("success", False):
                raise ConnectionError("Unable to authenticate.")
            return True
        raise ConnectionError("User has not authenticated locally.")
    except ConnectionError:
        logger.warning(f"{PREFIX} Invalid API key โš ๏ธ")
    except requests.exceptions.RequestException as e:
        status_code = None
        if hasattr(e, "response"):
            status_code = e.response.status_code

        error_msg = ErrorHandler(status_code).handle()
        logger.warning(f"{PREFIX} {error_msg}")

    self.id_token = self.api_key = False  # reset invalid
    return False

authorize(email, password)

์ด๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ํฌํ•จ๋œ POST ์š”์ฒญ์„ ํ†ตํ•ด idToken์„ ํš๋“ํ•˜์—ฌ ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜:

์ด๋ฆ„ ์œ ํ˜• ์„ค๋ช… ๊ธฐ๋ณธ๊ฐ’
email str

์‚ฌ์šฉ์ž์˜ ์ด๋ฉ”์ผ.

ํ•„์ˆ˜
password str

์‚ฌ์šฉ์ž์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ์ž…๋‹ˆ๋‹ค.

ํ•„์ˆ˜

๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค:

์œ ํ˜• ์„ค๋ช…
bool

์ธ์ฆ์— ์„ฑ๊ณตํ•˜๋ฉด ์ฐธ์ด๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๊ฑฐ์ง“์ž…๋‹ˆ๋‹ค.

์˜ ์†Œ์Šค ์ฝ”๋“œ hub_sdk/base/auth.py
def authorize(self, email: str, password: str) -> bool:
    """
    Authorize the user by obtaining an idToken through a POST request with email and password.

    Args:
        email (str): User's email.
        password (str): User's password.

    Returns:
        (bool): True if authorization is successful, False otherwise.
    """
    try:
        headers = {"origin": HUB_WEB_ROOT}
        response = requests.post(FIREBASE_AUTH_URL, json={"email": email, "password": password}, headers=headers)
        if response.status_code == 200:
            self.id_token = response.json().get("idToken")
            return True
        else:
            raise ConnectionError("Authorization failed.")
    except ConnectionError:
        logger.warning(f"{PREFIX} Invalid API key โš ๏ธ")
    except requests.exceptions.RequestException as e:
        status_code = None
        if hasattr(e, "response"):
            status_code = e.response.status_code

        error_msg = ErrorHandler(status_code).handle()
        logger.warning(f"{PREFIX} {error_msg}")

get_auth_header()

API ์š”์ฒญ์„ ์œ„ํ•œ ์ธ์ฆ ํ—ค๋”๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค:

์œ ํ˜• ์„ค๋ช…
Optional[dict]

id_token ๋˜๋Š” API ํ‚ค๊ฐ€ ์„ค์ •๋œ ๊ฒฝ์šฐ ์ธ์ฆ ํ—ค๋”, ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ ์—†์Œ์ž…๋‹ˆ๋‹ค.

์˜ ์†Œ์Šค ์ฝ”๋“œ hub_sdk/base/auth.py
def get_auth_header(self) -> Optional[dict]:
    """
    Get the authentication header for making API requests.

    Returns:
        (Optional[dict]): The authentication header if id_token or API key is set, None otherwise.
    """
    if self.id_token:
        return {"authorization": f"Bearer {self.id_token}"}
    elif self.api_key:
        return {"x-api-key": self.api_key}
    else:
        return None

get_state()

์ธ์ฆ ์ƒํƒœ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค:

์œ ํ˜• ์„ค๋ช…
bool

id_token ๋˜๋Š” API ํ‚ค๊ฐ€ ์„ค์ •๋œ ๊ฒฝ์šฐ True, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด False์ž…๋‹ˆ๋‹ค.

์˜ ์†Œ์Šค ์ฝ”๋“œ hub_sdk/base/auth.py
def get_state(self) -> bool:
    """
    Get the authentication state.

    Returns:
        (bool): True if either id_token or API key is set, False otherwise.
    """
    return self.id_token or self.api_key

set_api_key(key)

์ธ์ฆ์„ ์œ„ํ•œ API ํ‚ค๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜:

์ด๋ฆ„ ์œ ํ˜• ์„ค๋ช… ๊ธฐ๋ณธ๊ฐ’
key str

API ํ‚ค ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค.

ํ•„์ˆ˜
์˜ ์†Œ์Šค ์ฝ”๋“œ hub_sdk/base/auth.py
def set_api_key(self, key: str):
    """
    Set the API key for authentication.

    Args:
        key (str): The API key string.
    """
    self.api_key = key