.venv
,.vscode/
con settings.json
,
extensions.json
, tasks.json
,
launch.json
,streamlit
y verifica configuración, yAutomatiza el arranque del entorno de trabajo en VSCode para cursos de Python con despliegue en Streamlit y uso de GitHub y Copilot. Evita errores comunes de instalación, selección de intérprete y falta de extensiones.
Detección de SO y rutas.
Verificación de CLI de VSCode
(code
).
Instalación de extensiones: Python, Pylance, Jupyter, GitHub Pull Requests, Copilot, Copilot Chat.
Creación de entorno virtual .venv
con venv
.
Instalación de dependencias base:
streamlit
.
Carpeta .vscode
:
settings.json
: fija el intérprete del proyecto al de
.venv
y activa el entorno en la terminal.extensions.json
: recomendaciones para alumnos.tasks.json
: tarea para levantar Streamlit.launch.json
: depuración de un script Python y ejecución
de Streamlit.Archivo de ejemplo app.py
listo
para streamlit run
.
Diagnóstico: comprueba que el intérprete activo
apunta a .venv
, que existan extensiones críticas y que
streamlit
esté instaldo.
Guía para “reset UI” en VSCode mediante Paleta de Comandos.
subprocess
para invocar
code --install-extension ...
..venv
y usa su python
interno para
instalar streamlit
..vscode/
.setup_vscode_streamlit.py
)import json
import os
import platform
import shutil
import subprocess
import sys
from pathlib import Path
# -----------------------------
# Utilidades de consola
# -----------------------------
def run(cmd, check=False):
try:
return subprocess.run(cmd, check=check, capture_output=True, text=True)
except Exception as e:
return subprocess.CompletedProcess(cmd, 1, "", str(e))
def info(msg): print(f"[INFO] {msg}")
def warn(msg): print(f"[WARN] {msg}")
def err(msg): print(f"[ERROR] {msg}")
# -----------------------------
# Detección de plataforma y rutas
# -----------------------------
ROOT = Path.cwd() # raíz del proyecto
VENV_DIR = ROOT / ".venv"
IS_WINDOWS = platform.system() == "Windows"
# Ruta al python del venv
PYTHON_VENV = VENV_DIR / ("Scripts/python.exe" if IS_WINDOWS else "bin/python")
PIP_VENV = VENV_DIR / ("Scripts/pip.exe" if IS_WINDOWS else "bin/pip")
# -----------------------------
# 1) Verificar que VSCode CLI esté disponible
# -----------------------------
def find_code_cli():
# VSCode CLI suele ser "code"
code_cmd = "code.cmd" if IS_WINDOWS else "code"
path = shutil.which(code_cmd) or shutil.which("code")
return path
CODE = find_code_cli()
if not CODE:
warn("No se encontró la CLI de VSCode ('code').")
warn("Instale VSCode y habilite 'code' en PATH. En VSCode: Command Palette → 'Shell Command: Install 'code' command in PATH' (macOS).")
else:
info(f"CLI de VSCode detectada: {CODE}")
# -----------------------------
# 2) Instalar extensiones necesarias
# -----------------------------
EXTS = [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-toolsai.jupyter",
"ms-toolsai.jupyter-keymap",
"ms-toolsai.jupyter-renderers",
"github.vscode-pull-request-github",
"GitHub.copilot",
"GitHub.copilot-chat"
]
def install_extensions():
if not CODE:
return
info("Instalando extensiones de VSCode requeridas...")
for ext in EXTS:
r = run([CODE, "--install-extension", ext, "--force"])
if r.returncode == 0:
info(f"OK {ext}")
else:
warn(f"No se pudo instalar {ext}: {r.stderr.strip()}")
# -----------------------------
# 3) Crear entorno virtual y dependencias base
# -----------------------------
def ensure_venv_and_deps():
if not VENV_DIR.exists():
info("Creando entorno virtual .venv ...")
r = run([sys.executable, "-m", "venv", ".venv"])
if r.returncode != 0:
err("Fallo creando .venv.")
err(r.stderr)
sys.exit(1)
else:
info("Entorno virtual .venv ya existe.")
# Instalar streamlit en el venv
if not PIP_VENV.exists():
err("Pip en el venv no encontrado. El .venv parece estar corrupto.")
sys.exit(1)
info("Instalando 'streamlit' en el .venv ...")
r = run([str(PIP_VENV), "install", "--upgrade", "pip"])
if r.returncode != 0:
warn("No se pudo actualizar pip (continuo).")
r = run([str(PIP_VENV), "install", "streamlit"])
if r.returncode == 0:
info("OK streamlit instalado.")
else:
err("Fallo instalando streamlit.")
err(r.stderr)
# -----------------------------
# 4) Generar carpeta .vscode y archivos de configuración
# -----------------------------
VSCODE_DIR = ROOT / ".vscode"
SETTINGS = VSCODE_DIR / "settings.json"
EXT_REC = VSCODE_DIR / "extensions.json"
TASKS = VSCODE_DIR / "tasks.json"
LAUNCH = VSCODE_DIR / "launch.json"
def write_vscode_files():
VSCODE_DIR.mkdir(exist_ok=True)
# settings.json
python_path = str(PYTHON_VENV)
settings = {
"python.defaultInterpreterPath": python_path.replace("\\", "\\\\") if IS_WINDOWS else python_path,
"python.terminal.activateEnvironment": True,
"python.analysis.autoImportCompletions": True,
"python.analysis.typeCheckingMode": "basic",
# Terminal por defecto en Windows: PowerShell
**({"terminal.integrated.defaultProfile.windows": "PowerShell"} if IS_WINDOWS else {})
}
SETTINGS.write_text(json.dumps(settings, indent=4), encoding="utf-8")
info("Escrito .vscode/settings.json")
# extensions.json (recomendaciones)
ext_rec = {
"recommendations": EXTS
}
EXT_REC.write_text(json.dumps(ext_rec, indent=4), encoding="utf-8")
info("Escrito .vscode/extensions.json")
# tasks.json: tarea para ejecutar streamlit run app.py
tasks = {
"version": "2.0.0",
"tasks": [
{
"label": "Run Streamlit",
"type": "shell",
"command": f"\"{python_path}\" -m streamlit run app.py" if IS_WINDOWS else f"{python_path} -m streamlit run app.py",
"problemMatcher": [],
"group": "build",
"options": {
"cwd": "${workspaceFolder}"
}
}
]
}
TASKS.write_text(json.dumps(tasks, indent=4), encoding="utf-8")
info("Escrito .vscode/tasks.json")
# launch.json: depurar script Python y lanzar Streamlit
launch = {
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},
{
"name": "Streamlit: app.py",
"type": "python",
"request": "launch",
"module": "streamlit",
"args": ["run", "app.py"],
"console": "integratedTerminal"
}
]
}
LAUNCH.write_text(json.dumps(launch, indent=4), encoding="utf-8")
info("Escrito .vscode/launch.json")
# -----------------------------
# 5) App de ejemplo para Streamlit
# -----------------------------
APP = ROOT / "app.py"
def write_sample_app():
if APP.exists():
info("app.py ya existe. No se sobrescribe.")
return
APP.write_text(
"""import streamlit as st
st.set_page_config(page_title="Demo Streamlit", page_icon="🐍", layout="centered")
st.title("Demo Streamlit para Programación con Python")
st.write("Esta es una app de ejemplo. Modifique este archivo y guarde para recargar.")
with st.sidebar:
st.header("Parámetros")
nombre = st.text_input("Nombre", "Estudiante")
x = st.slider("x", 0, 100, 42)
st.success(f"Hola, {nombre}. x^2 = {x**2}")
""",
encoding="utf-8"
)
info("Escrito app.py de ejemplo.")
# -----------------------------
# 6) Diagnóstico rápido
# -----------------------------
def diagnose():
info("Diagnóstico rápido:")
# a) VSCode CLI
print(" - VSCode CLI:", "OK" if CODE else "NO DETECTADA")
# b) Extensiones clave
missing = []
if CODE:
r = run([CODE, "--list-extensions"])
if r.returncode == 0:
installed = set(e.strip().lower() for e in r.stdout.splitlines())
for ext in EXTS:
if ext.lower() not in installed:
missing.append(ext)
else:
warn("No pude listar extensiones de VSCode.")
if missing:
warn(f"Extensiones faltantes: {', '.join(missing)}")
else:
print(" - Extensiones clave: OK")
# c) Intérprete en settings.json
try:
s = json.loads(SETTINGS.read_text(encoding="utf-8"))
interp = s.get("python.defaultInterpreterPath", "")
if interp and Path(interp).exists():
print(" - Intérprete VSCode:", "OK (apunta a .venv)")
else:
warn("Intérprete en settings.json no existe o no apunta a .venv.")
except Exception:
warn("No se pudo leer .vscode/settings.json")
# d) Streamlit instalado
r = run([str(PYTHON_VENV), "-c", "import streamlit; print(streamlit.__version__)"])
if r.returncode == 0:
print(f" - Streamlit: OK ({r.stdout.strip()})")
else:
warn("Streamlit no está disponible en el .venv.")
# -----------------------------
# 7) Ejecución
# -----------------------------
def main():
info(f"Proyecto: {ROOT}")
install_extensions()
ensure_venv_and_deps()
write_vscode_files()
write_sample_app()
diagnose()
print("\nPasos finales sugeridos:")
print(" 1) Abra este proyecto en VSCode.")
print(" 2) Presione Ctrl+Shift+P → 'Python: Select Interpreter' y elija el de .venv si fuera necesario.")
print(" 3) Terminal nueva en VSCode debe abrir con '(.venv)'.")
print(" 4) Ejecute la tarea 'Run Streamlit' (Terminal → Run Task) o 'F5' con 'Streamlit: app.py'.")
print("\nReset de interfaz de VSCode (si la apariencia está alterada):")
print(" - Ctrl+Shift+P → 'View: Reset View Locations'")
print(" - Ctrl+Shift+P → 'View: Reset Layout'")
print(" - Ctrl+Shift+P → 'Developer: Reload Window'")
if __name__ == "__main__":
main()
Colocar setup_vscode_streamlit.py
en la
raíz del repo de cada equipo.
Ejecutar:
python setup_vscode_streamlit.py
Abrir el folder en VSCode. Confirmar intérprete
.venv
.
Correr Run Streamlit
desde Tasks o
F5
con la configuración “Streamlit: app.py”.
Si la interfaz está desordenada:
Ctrl+Shift+P
→ View: Reset View
LocationsCtrl+Shift+P
→ View: Reset LayoutCtrl+Shift+P
→ Developer: Reload
WindowWindows PowerShell: si no activa
.venv
por política de ejecución, abrir Windows
PowerShell como administrador y aplicar una vez:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Git: este script no toca credenciales ni
git
. Sugerir a estudiantes confirmar
git --version
y user.name/email
.
Copilot: requiere que los estudiantes inicien sesión con su cuenta de GitHub dentro de VSCode y acepten permisos de Copilot.
Salas de cómputo: si code
no está
en PATH, abrir VSCode manualmente y ejecutar el comando de instalar
code
en PATH desde la Paleta.