@@ -1301,6 +1301,14 @@ def _do_refresh():
13011301 style = ft .ButtonStyle (side = ft .BorderSide (1 , C_SECONDARY ), color = C_SECONDARY ),
13021302 visible = _venv_exists ,
13031303 )
1304+ # Manual Python path override for when auto-detection fails
1305+ _base_py_v = {"v" : "" }
1306+ tf_base_py = ft .TextField (
1307+ hint_text = "Python path (auto-detected, override if needed — e.g. /usr/bin/python3.12)" ,
1308+ expand = True , dense = True , bgcolor = C_OUTPUT_BG , border_color = C_PRIMARY ,
1309+ text_size = 11 , visible = False ,
1310+ on_change = lambda e : _base_py_v .update ({"v" : e .control .value }),
1311+ )
13041312
13051313 def _append_log (line : str ) -> None :
13061314 env_log .value = (env_log .value or "" ) + line + "\n "
@@ -1323,47 +1331,78 @@ def _worker():
13231331 # ── Find a Python that has SSL (required for pip HTTPS) ──────────
13241332 import shutil as _sh
13251333 home = Path .home ()
1326- _candidates = [
1327- # conda/mamba installs (have SSL bundled)
1328- str (home / "miniconda3/bin/python3" ),
1329- str (home / "miniconda3/bin/python" ),
1330- str (home / "anaconda3/bin/python3" ),
1331- str (home / "anaconda3/bin/python" ),
1332- str (home / "miniforge3/bin/python3" ),
1333- str (home / "miniforge3/bin/python" ),
1334- str (home / "mambaforge/bin/python3" ),
1335- str (home / "mambaforge/bin/python" ),
1336- str (home / ".local/share/mamba/bin/python3" ),
1337- # PATH lookup
1338- _sh .which ("python3" ) or "" ,
1339- _sh .which ("python" ) or "" ,
1340- "/usr/bin/python3" ,
1341- "/usr/local/bin/python3" ,
1342- ]
1343-
1344- base_py = ""
1345- for cand in _candidates :
1346- if not cand or not Path (cand ).exists ():
1347- continue
1348- r = subprocess .run (
1349- [cand , "-c" , "import ssl, venv" ],
1350- capture_output = True , timeout = 5 ,
1351- )
1352- if r .returncode == 0 :
1353- base_py = cand
1354- _append_log (f"► Using Python: { base_py } " )
1355- break
13561334
1335+ # 1) Manual override from the text field
1336+ base_py = _base_py_v ["v" ].strip ()
1337+
1338+ # 2) Login shell — respects .bashrc/.zshrc and conda init
1339+ if not base_py :
1340+ _append_log ("► Probing login shell for Python …" )
1341+ for shell_cmd in [
1342+ ["bash" , "-l" , "-c" ,
1343+ "python3 -c 'import ssl,venv,sys; print(sys.executable)'" ],
1344+ ["zsh" , "-l" , "-c" ,
1345+ "python3 -c 'import ssl,venv,sys; print(sys.executable)'" ],
1346+ ]:
1347+ try :
1348+ r = subprocess .run (shell_cmd , capture_output = True ,
1349+ text = True , timeout = 15 )
1350+ if r .returncode == 0 :
1351+ for line in reversed (r .stdout .strip ().splitlines ()):
1352+ line = line .strip ()
1353+ if line and Path (line ).exists ():
1354+ base_py = line
1355+ break
1356+ if base_py :
1357+ break
1358+ except Exception :
1359+ pass
1360+
1361+ # 3) Common install locations
13571362 if not base_py :
1358- _append_log ("ERROR: No Python 3 with SSL support found." )
1359- _append_log (" Install Miniconda or ensure python3 is built with SSL." )
1360- env_status .value = "✗ Setup failed — Python with SSL not found"
1363+ _candidates = [
1364+ str (home / "miniconda3/bin/python3" ),
1365+ str (home / "miniconda3/bin/python" ),
1366+ str (home / "anaconda3/bin/python3" ),
1367+ str (home / "anaconda3/bin/python" ),
1368+ str (home / "miniforge3/bin/python3" ),
1369+ str (home / "miniforge3/bin/python" ),
1370+ str (home / "mambaforge/bin/python3" ),
1371+ str (home / "mambaforge/bin/python" ),
1372+ str (home / ".local/share/mamba/bin/python3" ),
1373+ "/opt/conda/bin/python3" ,
1374+ "/opt/miniconda3/bin/python3" ,
1375+ "/opt/anaconda3/bin/python3" ,
1376+ _sh .which ("python3" ) or "" ,
1377+ _sh .which ("python" ) or "" ,
1378+ "/usr/bin/python3" ,
1379+ "/usr/local/bin/python3" ,
1380+ ]
1381+ for cand in _candidates :
1382+ if not cand or not Path (cand ).exists ():
1383+ continue
1384+ r = subprocess .run ([cand , "-c" , "import ssl, venv" ],
1385+ capture_output = True , timeout = 5 )
1386+ if r .returncode == 0 :
1387+ base_py = cand
1388+ break
1389+
1390+ if not base_py :
1391+ _append_log ("ERROR: Could not find a Python 3 with SSL support." )
1392+ _append_log ("" )
1393+ _append_log (" Paste the path to your conda/system Python below" )
1394+ _append_log (" (e.g. /home/user/miniconda3/bin/python3)" )
1395+ _append_log (" then click Install again." )
1396+ tf_base_py .visible = True
1397+ env_status .value = "✗ Python not found — enter path below"
13611398 env_status .color = C_ERROR
13621399 env_setup_btn .disabled = False
13631400 env_reinstall_btn .disabled = False
13641401 page .update ()
13651402 return
13661403
1404+ _append_log (f"► Using Python: { base_py } " )
1405+
13671406 # Step 1 — create venv (remove stale one first)
13681407 import shutil as _sh2
13691408 if ML_VENV_DIR .exists ():
@@ -1467,6 +1506,7 @@ def _worker():
14671506 env_status ,
14681507 ], spacing = 8 ),
14691508 ft .Row (controls = [env_setup_btn , env_reinstall_btn ], spacing = 10 ),
1509+ tf_base_py ,
14701510 env_log ,
14711511 ], spacing = 10 ))
14721512
0 commit comments