Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] update token retrieval logic #5541

Merged
merged 23 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
38eb64e
update token retrieval logic
not-lain Sep 25, 2024
efecd0b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 25, 2024
a138733
fix imports
not-lain Sep 25, 2024
b6c636d
Merge branch 'update-token-retrieval' of https://github.com/not-lain/…
not-lain Sep 25, 2024
5443ffd
fix colab runtime check
not-lain Sep 25, 2024
4bec8b4
better formatting for warning message
not-lain Sep 25, 2024
7cabbd9
Update argilla/src/argilla/_api/_token.py
not-lain Sep 26, 2024
9a3466c
Update argilla/src/argilla/_api/_token.py
not-lain Sep 26, 2024
a70d2bf
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 26, 2024
4ffd31b
update comments
not-lain Sep 27, 2024
d3325ae
Merge branch 'develop' into update-token-retrieval
not-lain Sep 27, 2024
c2d736d
update imports
not-lain Sep 27, 2024
3746fda
Update argilla/src/argilla/_api/_token.py
not-lain Sep 29, 2024
12420e9
Update argilla/src/argilla/_api/_token.py
not-lain Sep 29, 2024
bb92555
Update argilla/src/argilla/_api/_client.py
not-lain Sep 29, 2024
15af8a4
Update argilla/src/argilla/_api/_token.py
not-lain Sep 29, 2024
3f1e9d5
Update argilla/src/argilla/_api/_token.py
not-lain Sep 29, 2024
11375a0
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 29, 2024
9599750
Update argilla/src/argilla/_api/_token.py
not-lain Sep 29, 2024
203b58d
Update argilla/src/argilla/_api/_token.py
not-lain Sep 29, 2024
ccb51b5
Update argilla/src/argilla/_api/_token.py
not-lain Sep 29, 2024
0de7e5c
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Sep 29, 2024
63492dc
fix errors
not-lain Sep 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions argilla/src/argilla/_api/_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# limitations under the License.

import logging
import os
from typing import Optional

import httpx
Expand All @@ -29,13 +28,15 @@
from argilla._api._users import UsersAPI
from argilla._api._vectors import VectorsAPI
from argilla._api._workspaces import WorkspacesAPI
from argilla._constants import _DEFAULT_API_URL
from argilla._exceptions import ArgillaError
from argilla._constants import _DEFAULT_API_URL
from argilla._api._token import get_secret

__all__ = ["APIClient"]

ARGILLA_API_URL = os.getenv(key="ARGILLA_API_URL", default=_DEFAULT_API_URL)
ARGILLA_API_KEY = os.getenv(key="ARGILLA_API_KEY")

ARGILLA_API_URL = get_secret("ARGILLA_API_URL") or _DEFAULT_API_URL
ARGILLA_API_KEY = get_secret("ARGILLA_API_KEY")

DEFAULT_HTTP_CONFIG = HTTPClientConfig(api_url=ARGILLA_API_URL, api_key=ARGILLA_API_KEY)

Expand Down
105 changes: 105 additions & 0 deletions argilla/src/argilla/_api/_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Copyright 2024-present, Argilla, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import warnings
from threading import Lock
from typing import Optional
from huggingface_hub.utils._runtime import is_google_colab


_IS_GOOGLE_COLAB_CHECKED = False
_GOOGLE_COLAB_SECRET_LOCK = Lock()
_GOOGLE_COLAB_SECRET: Optional[dict] = None


def get_secret(name: str) -> Optional[str]:
"""
Get secret if present

Returns:
`str` or `None`: The secret value, `None` if it doesn't exist.
"""
return _get_secret_from_google_colab(name) or _get_secret_from_environment(name)


def _get_secret_from_environment(name: str) -> Optional[str]:
"""Get the secret from the environment"""
return _clean_secret_value(os.getenv(key=name))


def _get_secret_from_google_colab(name: str) -> Optional[str]:
"""Get token from Google Colab secrets vault using `google.colab.userdata.get(...)`.

Token is read from the vault only once per session and then stored in a global variable to avoid re-requesting
access to the vault.
"""
# If it's not a Google Colab, fallback to environment variable
if not is_google_colab():
return None

# `google.colab.userdata` is not thread-safe
# This can lead to a deadlock if multiple threads try to access it at the same time
# => use a lock
# See https://github.com/huggingface/huggingface_hub/issues/1952 for more details.
with _GOOGLE_COLAB_SECRET_LOCK:
global _IS_GOOGLE_COLAB_CHECKED

# we can add here some cache mechanism

try:
from google.colab import userdata
from google.colab.errors import Error as ColabError
except ImportError:
return None

try:
# initialize to None in case of errors we evoid returning an undefined variable
secret_value = None
secret_value = _clean_secret_value(userdata.get(name))

except userdata.NotebookAccessError:
# Means the user has a secret call `ARGILLA_API_URL` and `ARGILLA_API_URL` and got a popup "please grand access to ARGILLA_API_URL" and refused it
# => warn user but ignore error => do not re-request access to user
if not _IS_GOOGLE_COLAB_CHECKED:
warnings.warn(
f"\nAccess to the secret {name} has not been granted on this notebook."
"\nYou will not be requested again."
"\nPlease restart the session if you want to be prompted again."
)
except userdata.SecretNotFoundError:
# Means the user did not define a name secret => warn
warnings.warn(f"\nThe secrets {name} and does not exist in your Colab secrets.")
except ColabError as e:
# Something happen but we don't know what => recommend to open a GitHub issue
warnings.warn(
f"\nError while fetching {name} secret value from your vault: '{str(e)}'."
"\nYou are not authenticated with the Argilla in this notebook."
"\nIf the error persists, please let us know by opening an issue on GitHub "
"(https://github.com/argilla-io/argilla//issues/new)."
)

_IS_GOOGLE_COLAB_CHECKED = True

return secret_value


def _clean_secret_value(value: Optional[str]) -> Optional[str]:
"""Clean token by removing trailing and leading spaces and newlines.

If token is an empty string, return None.
"""
if value is None:
return None
return value.replace("\r", "").replace("\n", "").strip() or None