3333from os .path import abspath
3434from zipfile import ZipFile
3535
36- from comet_ml import API
37- from comet_ml .comet import format_url
36+ from comet_ml import API , get_comet_api_client
3837from comet_ml .config import get_api_key , get_config
39- from comet_ml .connection import Reporting , get_comet_api_client , url_join
38+ from comet_ml .connection import Reporting
4039from comet_ml .exceptions import CometRestApiException
4140from comet_ml .offline import upload_single_offline_experiment
41+ from comet_ml .utils import merge_url , url_join
4242from mlflow .entities .run_tag import RunTag
43+ from mlflow .exceptions import RestException
4344from mlflow .tracking import _get_store
4445from mlflow .tracking ._model_registry .utils import _get_store as get_model_registry_store
4546from mlflow .tracking .registry import UnsupportedModelRegistryStoreURIException
@@ -126,13 +127,70 @@ def __init__(
126127 output_dir = tempfile .mkdtemp ()
127128
128129 # MLFlow conversion
129- self .store = _get_store (mlflow_store_uri )
130+ try :
131+ self .store = _get_store (mlflow_store_uri )
132+ except RestException as e :
133+ # Check HTTP status code for authentication errors
134+ status_code = (
135+ e .get_http_status_code () if hasattr (e , "get_http_status_code" ) else None
136+ )
137+ error_msg = str (e )
138+ if (
139+ status_code == 401
140+ or "401" in error_msg
141+ or "Credential" in error_msg
142+ or "authentication" in error_msg .lower ()
143+ ):
144+ self ._log_authentication_error (
145+ mlflow_store_uri , "connecting to MLflow store"
146+ )
147+ raise
148+ except Exception as e :
149+ error_msg = str (e )
150+ if (
151+ "401" in error_msg
152+ or "Credential" in error_msg
153+ or "authentication" in error_msg .lower ()
154+ ):
155+ self ._log_authentication_error (
156+ mlflow_store_uri , "connecting to MLflow store"
157+ )
158+ raise
159+
130160 try :
131161 self .model_registry_store = get_model_registry_store (mlflow_store_uri )
132162 except UnsupportedModelRegistryStoreURIException :
133163 self .model_registry_store = None
134164
135- self .mlflow_experiments = search_mlflow_store_experiments (self .store )
165+ try :
166+ self .mlflow_experiments = search_mlflow_store_experiments (self .store )
167+ except RestException as e :
168+ # Check HTTP status code for authentication errors
169+ status_code = (
170+ e .get_http_status_code () if hasattr (e , "get_http_status_code" ) else None
171+ )
172+ error_msg = str (e )
173+ if (
174+ status_code == 401
175+ or "401" in error_msg
176+ or "Credential" in error_msg
177+ or "authentication" in error_msg .lower ()
178+ ):
179+ self ._log_authentication_error (
180+ mlflow_store_uri , "accessing MLflow experiments"
181+ )
182+ raise
183+ except Exception as e :
184+ error_msg = str (e )
185+ if (
186+ "401" in error_msg
187+ or "Credential" in error_msg
188+ or "authentication" in error_msg .lower ()
189+ ):
190+ self ._log_authentication_error (
191+ mlflow_store_uri , "accessing MLflow experiments"
192+ )
193+ raise
136194 self .len_experiments = len (self .mlflow_experiments ) # We start counting at 0
137195
138196 self .summary = {
@@ -206,7 +264,7 @@ def prepare(self):
206264 LOGGER .info (
207265 tabulate (
208266 table ,
209- headers = ["MLFlow name:" , "Comet.ml name:" , "Prepared count:" ],
267+ headers = ["MLFlow name:" , "Comet ML name:" , "Prepared count:" ],
210268 tablefmt = "presto" ,
211269 )
212270 )
@@ -217,7 +275,7 @@ def prepare(self):
217275 # Upload or not?
218276 print ("" )
219277 if self .answer is None :
220- upload = input ("Upload prepared data to Comet.ml ? [y/N] " ) in ("Y" , "y" )
278+ upload = input ("Upload prepared data to Comet ML ? [y/N] " ) in ("Y" , "y" )
221279 else :
222280 upload = self .answer
223281 print ("" )
@@ -232,8 +290,8 @@ def prepare(self):
232290
233291 LOGGER .info ("" )
234292 LOGGER .info (
235- """If you need support, you can contact us at http://chat.comet.ml /"""
236- """ or https://comet.ml /docs/quick-start/#getting-support"""
293+ """If you need support, you can contact us at http://chat.comet.com /"""
294+ """ or https://comet.com /docs/quick-start/#getting-support"""
237295 )
238296 LOGGER .info ("" )
239297
@@ -319,11 +377,11 @@ def prepare_single_mlflow_run(self, run, original_experiment_name):
319377 base_url = url_join (
320378 self .api_client .server_url , "/api/experiment/redirect"
321379 )
322- tags ["mlflow.parentRunUrl" ] = format_url (
323- base_url , experimentKey = tags ["mlflow.parentRunId" ]
380+ tags ["mlflow.parentRunUrl" ] = merge_url (
381+ base_url , { " experimentKey" : tags ["mlflow.parentRunId" ]}
324382 )
325383
326- # Save the original MLFlow experiment name too as Comet.ml project might
384+ # Save the original MLFlow experiment name too as Comet.com project might
327385 # get renamed
328386 tags ["mlflow.experimentName" ] = original_experiment_name
329387
@@ -449,7 +507,7 @@ def get_model_prefixes(self, artifact_list):
449507 return models
450508
451509 def upload (self , prepared_data ):
452- LOGGER .info ("# Start uploading data to Comet.ml " )
510+ LOGGER .info ("# Start uploading data to Comet ML " )
453511
454512 all_project_names = []
455513
@@ -494,7 +552,7 @@ def upload(self, prepared_data):
494552
495553 LOGGER .info ("" )
496554 LOGGER .info (
497- "Explore your experiment data on Comet.ml with the following links:" ,
555+ "Explore your experiment data on Comet ML with the following links:" ,
498556 )
499557 if len (all_project_names ) < 6 :
500558 for project_name in all_project_names :
@@ -516,7 +574,7 @@ def upload(self, prepared_data):
516574
517575 LOGGER .info (
518576 "Get deeper instrumentation by adding Comet SDK to your project:"
519- " https://comet.ml /docs/python-sdk/mlflow/"
577+ " https://comet.com /docs/python-sdk/mlflow/"
520578 )
521579 LOGGER .info ("" )
522580
@@ -593,7 +651,7 @@ def get_or_create_comet_project(self, exp):
593651
594652 def create_or_login (self ):
595653 auth_api_client = get_comet_api_client (None )
596- LOGGER .info ("Please create a free Comet account with your email." )
654+ LOGGER .info ("Please create a free Comet.com account with your email." )
597655 if self .email is None :
598656 email = input ("Email: " )
599657 print ("" )
@@ -627,23 +685,23 @@ def create_or_login(self):
627685 Reporting .report ("mlflow_new_user" , api_key = new_account ["apiKey" ])
628686
629687 LOGGER .info (
630- "A Comet.ml account has been created for you and an email was sent to"
688+ "A Comet.com account has been created for you and an email was sent to"
631689 " you to setup your password later."
632690 )
633691 save_api_key (new_account ["apiKey" ])
634692 LOGGER .info (
635- "Your Comet API Key has been saved to ~/.comet.ini , it is also"
636- " available on your Comet.ml dashboard."
693+ "Your Comet API Key has been saved to ~/.comet.config , it is also"
694+ " available on your Comet.com dashboard."
637695 )
638696 return (
639697 new_account ["apiKey" ],
640698 new_account ["token" ],
641699 )
642700 else :
643701 LOGGER .info (
644- "An account already exists for this account , please input your API Key"
702+ "An account already exists for this email , please input your API Key"
645703 " below (you can find it in your Settings page,"
646- " https://comet.ml /docs/quick-start/#getting-your-comet-api-key):"
704+ " https://comet.com /docs/quick-start/#getting-your-comet-api-key):"
647705 )
648706 api_key = input ("API Key: " )
649707
@@ -663,3 +721,29 @@ def get_api_key_or_login(self, api_key):
663721 Reporting .report ("mlflow_existing_user" , api_key = api_key )
664722
665723 return (api_key , None )
724+
725+ def _log_authentication_error (self , mlflow_store_uri , context ):
726+ """Log helpful error message for MLflow authentication errors."""
727+ LOGGER .error ("" )
728+ LOGGER .error ("MLflow authentication error detected when %s." , context )
729+ LOGGER .error ("" )
730+ if mlflow_store_uri and "databricks" in mlflow_store_uri .lower ():
731+ LOGGER .error (
732+ "For Databricks MLflow stores, you need to set the DATABRICKS_TOKEN environment variable:"
733+ )
734+ LOGGER .error (
735+ " export DATABRICKS_TOKEN=your_databricks_personal_access_token"
736+ )
737+ LOGGER .error ("" )
738+ LOGGER .error ("You can generate a token by:" )
739+ LOGGER .error (" 1. Click on your user profile icon in the top-right corner" )
740+ LOGGER .error (" 2. Select 'User Settings'" )
741+ LOGGER .error (" 3. Go to the 'Access Tokens' tab" )
742+ LOGGER .error (" 4. Click 'Generate New Token'" )
743+ else :
744+ LOGGER .error ("For authenticated MLflow stores, you may need to set:" )
745+ LOGGER .error (" - DATABRICKS_TOKEN (for Databricks token-based auth)" )
746+ LOGGER .error (
747+ " - MLFLOW_TRACKING_USERNAME and MLFLOW_TRACKING_PASSWORD (for basic auth)"
748+ )
749+ LOGGER .error ("" )
0 commit comments