File: C:/Users/fred/anaconda3/Lib/site-packages/conda_token/repo_config.py
"""
Configure Conda to use Anaconda Commercial Edition.
"""
import os
import sys
import warnings
from os.path import abspath, expanduser, join
import conda
import conda.gateways.logging # noqa: F401
from conda.base.context import context, reset_context
from conda.cli.python_api import Commands, run_command
from conda.exceptions import CondaKeyError
from conda.gateways.anaconda_client import (
read_binstar_tokens,
remove_binstar_token,
set_binstar_token,
)
from conda.gateways.connection.session import CondaSession
from conda.models.channel import Channel
from packaging import version
if sys.version_info[0] < 3:
from urlparse import urljoin
else:
from urllib.parse import urljoin
CONDA_VERSION = version.parse(conda.__version__)
REPO_URL = os.getenv("CONDA_TOKEN_REPO_URL", "https://repo.anaconda.cloud/repo/")
MAIN_CHANNEL = "main"
ACTIVE_CHANNELS = ["r", "msys2"]
ARCHIVE_CHANNELS = ["free", "mro-archive", "pro"]
user_rc_path = abspath(expanduser("~/.condarc"))
escaped_user_rc_path = user_rc_path.replace("%", "%%")
escaped_sys_rc_path = abspath(join(sys.prefix, ".condarc")).replace("%", "%%")
class CondaTokenError(RuntimeError):
pass
class CondaVersionWarning(UserWarning):
pass
def can_restore_free_channel():
return CONDA_VERSION >= version.parse("4.7.0")
def get_ssl_verify():
context = reset_context()
return context.ssl_verify
def clean_index():
"""Runs conda clean -i.
It is important to remove index cache when
changing the condarc to ensure that the downloaded
repodata is correct.
"""
run_command(Commands.CLEAN, "-i")
def validate_token(token, no_ssl_verify=False):
"""Checks that token can be used with the repository."""
# Force ssl_verify: false
if no_ssl_verify:
context.ssl_verify = False # type: ignore
# Use CondaSession to be compatible with ssl_verify: truststore
# https://conda.io/projects/conda/en/latest/user-guide/configuration/settings.html#ssl-verify-ssl-verification
# Clear metaclass cache to create new session checking ssl_verify
if hasattr(CondaSession, "cache_clear"):
# not present in conda < January 2024
CondaSession.cache_clear()
else:
# what cache_clear() does
try:
CondaSession._thread_local.sessions.clear()
except AttributeError:
# AttributeError: thread's session cache has not been initialized
pass
session = CondaSession()
channel = Channel(urljoin(REPO_URL, "main/noarch/repodata.json"))
channel.token = token
token_url = str(channel.url(with_credentials=True))
r = session.head(token_url, verify=session.verify)
if r.status_code != 200:
raise CondaTokenError(
"The token could not be validated. Please check that you have typed it correctly."
)
def enable_extra_safety_checks(
condarc_system=False, condarc_env=False, condarc_file=None
):
"""Enable package signature verification.
This will set extra_safety_checks: True and
signing_metadata_url_base in the CondaRC file.
"""
if CONDA_VERSION < version.parse("4.10.1"):
warnings.warn(
"You need upgrade to at least Conda version 4.10.1 to enable package signature verification.",
CondaVersionWarning,
)
return
condarc_file_args = []
if condarc_system:
condarc_file_args.append("--system")
elif condarc_env:
condarc_file_args.append("--env")
elif condarc_file:
condarc_file_args.append("--file={}".format(condarc_file))
safety_check_args = ["--set", "extra_safety_checks", "true"]
safety_check_args.extend(condarc_file_args)
run_command(Commands.CONFIG, *safety_check_args)
metadata_url_args = ["--set", "signing_metadata_url_base", REPO_URL.rstrip("/")]
metadata_url_args.extend(condarc_file_args)
run_command(Commands.CONFIG, *metadata_url_args)
def disable_extra_safety_checks(
condarc_system=False, condarc_env=False, condarc_file=None
):
"""Disable package signature verification.
This will set extra_safety_checks: false and remove
signing_metadata_url_base in the CondaRC file.
"""
if CONDA_VERSION < version.parse("4.10.1"):
return
condarc_file_args = []
if condarc_system:
condarc_file_args.append("--system")
elif condarc_env:
condarc_file_args.append("--env")
elif condarc_file:
condarc_file_args.append("--file={}".format(condarc_file))
safety_check_args = ["--set", "extra_safety_checks", "false"]
safety_check_args.extend(condarc_file_args)
try:
run_command(Commands.CONFIG, *safety_check_args)
except CondaKeyError:
pass
metadata_url_args = ["--remove-key", "signing_metadata_url_base"]
metadata_url_args.extend(condarc_file_args)
try:
run_command(Commands.CONFIG, *metadata_url_args)
except CondaKeyError:
pass
def _set_add_anaconda_token(condarc_system=False, condarc_env=False, condarc_file=None):
"""Run conda config --set add_anaconda_token true.
Setting this parameter to true ensures that the token
is used when making requests to the repository.
"""
config_args = ["--set", "add_anaconda_token", "true"]
if condarc_system:
config_args.append("--system")
elif condarc_env:
config_args.append("--env")
elif condarc_file:
config_args.append("--file={}".format(condarc_file))
run_command(Commands.CONFIG, *config_args)
def _set_ssl_verify_false(condarc_system=False, condarc_env=False, condarc_file=None):
"""Run conda config --set ssl_verify false.
Setting this parameter to false disables all
SSL verification for conda activities
"""
config_args = ["--set", "ssl_verify", "false"]
if condarc_system:
config_args.append("--system")
elif condarc_env:
config_args.append("--env")
elif condarc_file:
config_args.append("--file={}".format(condarc_file))
run_command(Commands.CONFIG, *config_args)
def _unset_restore_free_channel(
condarc_system=False, condarc_env=False, condarc_file=None
):
"""Runs conda config --set restore_free_channel false.
The free channel is provided by Commercial Edition as
and should be added directly."""
config_args = ["--set", "restore_free_channel", "false"]
if condarc_system:
config_args.append("--system")
elif condarc_env:
config_args.append("--env")
elif condarc_file:
config_args.append("--file={}".format(condarc_file))
run_command(Commands.CONFIG, *config_args, use_exception_handler=True)
def _set_channel(
channel, prepend=True, condarc_system=False, condarc_env=False, condarc_file=None
):
"""Adds a named Commercial Edition channel to default_channels."""
channel_url = urljoin(REPO_URL, channel)
config_args = [
"--prepend" if prepend else "--append",
"default_channels",
channel_url,
]
if condarc_system:
config_args.append("--system")
elif condarc_env:
config_args.append("--env")
elif condarc_file:
config_args.append("--file={}".format(condarc_file))
run_command(Commands.CONFIG, *config_args)
def _remove_default_channels(
condarc_system=False, condarc_env=False, condarc_file=None
):
"""Runs conda config --remove-key default_channels
It is best to remove the default_channels in case they
are not set at the default values before configuring
Commercial Edition.
"""
config_args = ["--remove-key", "default_channels"]
if condarc_system:
config_args.append("--system")
elif condarc_env:
config_args.append("--env")
elif condarc_file:
config_args.append("--file={}".format(condarc_file))
try:
run_command(Commands.CONFIG, *config_args)
except CondaKeyError:
pass
def configure_default_channels(
condarc_system=False,
condarc_env=False,
condarc_file=None,
include_archive_channels=None,
):
"""Configure the default_channels to utilize only Commercial Edition.
This function performs the following actions
1. unset default_channels if it exists in the condarc
2. unset restore_free_channel if it exists in the condarc
3. Add the main, r, and msys2 channels to default_channels
4. Optionally add any of the archive channels:
free, pro, mro, mro-archive
"""
_remove_default_channels(condarc_system, condarc_env, condarc_file)
if can_restore_free_channel():
_unset_restore_free_channel(condarc_system, condarc_env, condarc_file)
_set_channel(
MAIN_CHANNEL,
prepend=True,
condarc_system=condarc_system,
condarc_env=condarc_env,
condarc_file=condarc_file,
)
for c in ACTIVE_CHANNELS:
_set_channel(
c,
prepend=False,
condarc_system=condarc_system,
condarc_env=condarc_env,
condarc_file=condarc_file,
)
if include_archive_channels is None:
return
for c in include_archive_channels:
if c in ARCHIVE_CHANNELS:
_set_channel(
c,
prepend=False,
condarc_system=condarc_system,
condarc_env=condarc_env,
condarc_file=condarc_file,
)
else:
raise ValueError(
"The archive channel %s is not one of %s"
% (c, ", ".join(ARCHIVE_CHANNELS))
)
def token_list():
"""Return a dictionary of tokens for all configured repository urls.
Note that this function will return tokens configured for non-Commercial Edition
urls."""
return read_binstar_tokens()
def token_remove(system=False, env=False, file=None):
"""Completely remove the Commercial Edition token and default_channels.
This function performs three actions.
1. Remove the token
2. Remove the custom default_channels in the condarc
3. Disable package signature verification
4. Run conda clean -i
"""
remove_binstar_token(REPO_URL)
_remove_default_channels(system, env, file)
disable_extra_safety_checks(system, env, file)
clean_index()
def token_set(
token,
system=False,
env=False,
file=None,
include_archive_channels=None,
no_ssl_verify=False,
enable_signature_verification=False,
):
"""Set the Commercial Edition token and configure default_channels.
This function performs 4 actions.
1. Remove previous Commercial Edition token if present.
2. Add token.
3. Configure default_channels in the condarc file.
4. Optionally enable Conda package signature verification
5. Run conda clean -i
"""
remove_binstar_token(REPO_URL)
set_binstar_token(REPO_URL, token)
_set_add_anaconda_token(system, env, file)
if no_ssl_verify:
_set_ssl_verify_false(system, env, file)
if enable_signature_verification:
enable_extra_safety_checks(system, env, file)
configure_default_channels(system, env, file, include_archive_channels)
clean_index()