Fix Jupyter password might not be used in some protected Jupyterlab instances

This commit is contained in:
allegroai 2024-05-17 10:26:43 +03:00
parent 3012837bf3
commit 3377efe738
2 changed files with 61 additions and 18 deletions

View File

@ -700,28 +700,13 @@ class ScriptInfo(object):
cookies = None
password = None
if server_info and server_info.get("password"):
# we need to get the password
from ....config import config
password = config.get("development.jupyter_server_password", "")
password, cookies = cls._authenticate_jupyter(server_info)
if not password:
cls._get_logger().warning(
"Password protected Jupyter Notebook server was found! "
"Add `sdk.development.jupyter_server_password=<jupyter_password>` to ~/clearml.conf"
)
return os.path.join(os.getcwd(), "error_notebook_not_found.py")
r = requests.get(url=server_info["url"] + "login")
cookies = {"_xsrf": r.cookies.get("_xsrf", "")}
r = requests.post(
server_info["url"] + "login?next",
cookies=cookies,
data={"_xsrf": cookies["_xsrf"], "password": password},
)
cookies.update(r.cookies)
# get api token from ENV - if not defined then from server info
auth_token = os.getenv("JUPYTERHUB_API_TOKEN") or server_info.get("token") or ""
verify = True
try:
r = requests.get(
url=server_info["url"] + "api/sessions",
@ -729,8 +714,10 @@ class ScriptInfo(object):
headers={
"Authorization": "token {}".format(auth_token),
},
verify=verify
)
except requests.exceptions.SSLError:
verify = False
# disable SSL check warning
from urllib3.exceptions import InsecureRequestWarning
@ -743,13 +730,28 @@ class ScriptInfo(object):
headers={
"Authorization": "token {}".format(auth_token),
},
verify=False,
verify=verify,
)
# enable SSL check warning
import warnings
warnings.simplefilter("default", InsecureRequestWarning)
if r.status_code == 403 and server_info.get("password", False) is False:
# server info json might set password=False even tho that is not the case
# retry the request
password, cookies = cls._authenticate_jupyter(server_info)
if not password:
return os.path.join(os.getcwd(), "error_notebook_not_found.py")
r = requests.get(
url=server_info["url"] + "api/sessions",
cookies=cookies,
headers={
"Authorization": "token {}".format(auth_token),
},
verify=verify
)
# send request to the jupyter server
try:
r.raise_for_status()
@ -853,8 +855,47 @@ class ScriptInfo(object):
return script_entry_point
except Exception:
return None
@classmethod
def _authenticate_jupyter(cls, server_info):
"""
Authenticate to the Jupyter server using a password.
The password is fetched from `CLEARML_JUPYTER_PASSWORD` env var or the
`sdk.development.jupyter_server_password` configuration entry. The env var
has a higher priority than the configuration entry.
:param server_info: A dictionary containing Jupyter server information
:return: If the authentication succeded, return a tuple contain the password used
for authentication and the cookies obtained after authenticating. Otherwise,
return a tuple of Nones
"""
cookies = None
password = None
# we need to get the password
from ....config import config
from ....config.defs import JUPYTER_PASSWORD
password = JUPYTER_PASSWORD.get(default=config.get("development.jupyter_server_password", ""))
if not password:
cls._get_logger().warning(
"Password protected Jupyter Notebook server was found! "
"Add `sdk.development.jupyter_server_password=<jupyter_password>` to ~/clearml.conf"
)
return None, None
r = requests.get(url=server_info["url"] + "login")
cookies = {"_xsrf": r.cookies.get("_xsrf", "")}
r = requests.post(
server_info["url"] + "login?next",
cookies=cookies,
data={"_xsrf": cookies["_xsrf"], "password": password},
)
cookies.update(r.cookies)
return password, cookies
@classmethod
def is_sagemaker(cls):
return Path(cls._sagemaker_metadata_path).is_file()

View File

@ -28,6 +28,8 @@ SUPPRESS_UPDATE_MESSAGE_ENV_VAR = EnvEntry("CLEARML_SUPPRESS_UPDATE_MESSAGE", "T
MAX_SERIES_PER_METRIC = EnvEntry("CLEARML_MAX_SERIES_PER_METRIC", default=100, type=int)
JUPYTER_PASSWORD = EnvEntry("CLEARML_JUPYTER_PASSWORD")
# Repository detection
VCS_REPO_TYPE = EnvEntry("CLEARML_VCS_REPO_TYPE", "TRAINS_VCS_REPO_TYPE", default="git")
VCS_REPOSITORY_URL = EnvEntry("CLEARML_VCS_REPO_URL", "TRAINS_VCS_REPO_URL")