Normalmente suelo utilizar Windows Subsystem for Linux (WSL) a la hora de escribir libretas de Jupyter para cualquier tarea, pero en alguna ocasión también lo hago desde Windows.
En Linux suelo descargar archivos desde la libreta empleando el comando wget (anteponiendo el signo de exclamación «!» para indicar que ejecute el comando en el sistema operativo). Un ejemplo:
!wget https://filesamples.com/samples/document/txt/sample1.txt
Recientemente, escribiendo una libreta desde Windows, me he topado con la duda de ¿cómo puedo descargar un fichero directamente con el sistema operativo al igual que hago en Linux?
Se pueden descargar ficheros desde Windows tal y como lo hacemos desde Linux, pero el principal inconveniente es que en el cmd de Windows no existe ningún comando que nos permita descargar un fichero, tal como lo hacemos con wget en Linux. En cambio, en PowerShell (una shell mucho más moderna que también está disponible en Windows) si tenemos un comando que nos permite descargar un fichero de forma similar a wget: Invoke-WebRequest.
Este comando se ejecuta siguiendo la siguiente sintaxis:
Invoke-WebRequest url -outfile fichero_destino
Otro inconveniente es que en las libretas de Jupyter, en Windows, cuando queremos utilizar un comando del sistema operativo, estos se ejecutan sobre cmd. Pero para poder hacer uso de PowerShell en las libretas tenemos dos formas:
- Cambiar el valor de la variable «comspec» de Python para indicar que use PowerShell.
- Definir un comando mágico de IPython
1. Cambiar el valor de la variable «comspec» de Python
Esta opción es la más sencilla, solamente tenemos que cambiar el valor de la variable comspec por «powershell.exe», en el caso de Windows PowerShell (la versión que viene instalada con el sistema operativo), o por «pwsh.exe», en el caso de PowerShell Core (una versión más moderna, desarrollada en .NET Core). Si no tienes instalado PowerShell Core, puedes hacerlo desde la tienda de Windows (enlace).
Podemos cambiar el valor de comspec, en la libreta Jupyter, de la siguiente forma:
import os os.environ['comspec']='pwsh.exe'
A partir de la ejecución del código anterior, todos los comandos que ejecutemos en el sistema operativo desde el notebook se harán empleando PowerShell.
Por ejemplo, si quisiéramos descargar un archivo bastaría con:
!Invoke-WebRequest https://filesamples.com/samples/document/txt/sample1.txt -outfile sample1.txt
En mi caso, dentro de mi perfil de Powershell, me he creado un alias llamado wget para el comando Invoke-WebRequest. La línea que debemos agregar en el fichero del perfil de Powershell es la siguiente:
Set-Alias wget Invoke-WebRequest
De esta forma nos es más fácil llamar al comando, puesto que el nombre del alias es el mismo que el nombre del comando que empleamos en Linux, wget.
!wget https://filesamples.com/samples/document/txt/sample1.txt -outfile sample1.txt
Si no sabes dónde se encuentra el fichero con el perfil de Powershell, ejecuta el siguiente comando en una terminal y obtendrás la ruta donde se encuentra:
$profile
2. Definir un «magic command» en nuestro perfil de IPython
En este caso existen dos métodos:
- Definir el comando mágico en nuestro perfil de IPython
- Crear una función que defina un comando mágico y que se ejecute al iniciar un kernel
Creación de un comando mágico en nuestro perfil de IPython
Sí únicamente nos interesara utilizar PowerShell en una celda determinada, podemos definir un magic command en nuestro perfil de IPython. Este perfil se encuentra en un fichero, normalmente con el nombre ipython_config.py, dentro de nuestra carpeta de usuario bajo la ruta \.ipython\profile_default
C:\Users\nombre_usuario\.ipython\profile_default\ipython_config.py
En caso de no tener un fichero con la configuración de IPython, podemos crearlo mediante el siguiente comando (desde el terminal, no desde el notebook):
ipython profile create
Una vez abierto el fichero, añadimos al final las siguientes líneas y guardamos:
c.ScriptMagics.script_magics = ['powershell'] c.ScriptMagics.script_paths = { 'powershell':'pwsh.exe -noprofile -command -'}
Para ejecutar un comando PowerShell que hace uso del comando mágico que hemos creado, podemos hacerlo de la siguiente manera:
%%powershell Invoke-WebRequest https://filesamples.com/samples/document/txt/sample1.txt -outfile sample1.txt
Función para crear un comando mágico al iniciar un kernel
De esta otra forma, en caso de que también quisiéramos almacenar los resultados de la ejecución de un comando PowerShell en una variable Python, podemos definir una función que se ejecute cada vez que se inicia el kernel de IPython, de tal forma que podamos hacer uso del comando mágico. Para esto, debemos crear un fichero Python en la ruta:
C:\Users\nombre_usuario\.ipython\profile_default\startup
A continuación, definimos la función que contendrá dicho fichero y lo guardamos:
from IPython.core.magic import register_line_cell_magic from IPython import get_ipython ipython = get_ipython() @register_line_cell_magic def ps(line, cell=None): "Magic that works both as %ps and as %%ps" if cell is None: ipython.run_cell_magic('powershell', '--out posh_output' ,line) return posh_output.splitlines() else: return ipython.run_cell_magic('powershell', line, cell)
Debemos tener en cuenta que las funciones que contienen los ficheros dentro de la carpeta ~\.ipython\profile_default\startup se ejecutan en el orden alfabético, siguiendo el nombre del fichero. Por ejemplo, si tuviéramos estos ficheros dentro de la carpeta:
- 01-func1.py
- 02-func2.py
- 03-func3.py
Primero se ejecutaría el fichero 01-func1.py, luego 02-func2.py y por último 03-func3.py
En mi caso he llamado 01-powershell_magic.py al fichero, puesto que es la única función/fichero que tengo creado en la carpeta ~\.ipython\profile_default\startup
Una vez creado el fichero y reiniciado el kernel de IPython, si está en funcionamiento, para emplear el comando mágico que hemos creado lo haremos de la misma forma que el comando mágico que vimos anteriormente, salvo que si ahora queremos almacenar el resultado de la ejecución de un comando PowerShell podemos hacer lo siguiente:
ps_version = %ps $PSVersionTable.PSVersion.ToString() print(ps_version)
La celda anterior se encarga almacenar el resultado del comando PowerShell (en este caso obtenemos la versión en ejecución de PowerShell) en la variable ps_version
Fuentes: