Ipython: ¿Cómo averiguar la ruta del archivo ipynb actual desde IPython?

Creado en 5 ene. 2017  ·  15Comentarios  ·  Fuente: ipython/ipython

¿Hay alguna manera de averiguar el archivo ipynb actual desde iPython?

Caso de uso: quiero activar simulaciones desde IPython. Para mantener todo documentado, quiero copiar el cuaderno de IPython en la carpeta de resultados, idealmente desde dentro de IPython.

La búsqueda en la web con este problema mostró que parece haber mucho interés por tal característica, pero las soluciones presentadas en stackoverflow parecían ser un poco raras. ¿O esto ya está implementado?

Comentario más útil

Disculpe, pero con esto:

!echo %cd% # under windows
!pwd # under linux/mac

obtienes la información deseada.
Para reutilizarlo, solo haz lo siguiente:

myInfo01 = !echo %cd% # under windows
myInfo02 = !pwd # under linux/mac

Todos 15 comentarios

No es posible, no sin un truco que no funcionará (mostrando Javascript que ejecuta el código Python).

Aquí hay algunas razones por las que el kernel (en este caso IPython):

  • puede que no se esté ejecutando desde un solo archivo
  • incluso si es un archivo, es posible que el archivo no sea un cuaderno.
  • incluso si es una computadora portátil, es posible que la computadora portátil no esté en un sistema de archivos.
  • incluso si está en un sistema de archivos, es posible que no esté en la misma máquina.
  • incluso si en la misma máquina, la ruta al archivo puede no tener sentido en el contexto de IPython.
  • incluso si tiene sentido, el Protocolo Jupyter no ha sido diseñado para hacerlo. Y no tenemos ningún plan para cambiar esta abstracción a corto o largo plazo.

Sin embargo, puede ejecutar una computadora portátil sin un servidor de computadora portátil a través de un script externo y copiar la computadora portátil al mismo tiempo. Esa es una manera simple de jupyter nbconvert --execute --output-dir='results/'

Espero que ayude.

Tal vez el hecho de que haya cerrado este problema de inmediato indica que este tema se ha discutido a fondo en otro lugar. ¿Podría darme un enlace a la discusión, para que pueda entender mejor esa decisión?

De lo contrario, me pregunto: ¿Por qué el entorno de iPython no puede establecer una variable de python, por ejemplo, dentro del módulo de IPython tan pronto como se inicia un kernel? Esta variable podría contener información sobre cómo se inició el kernel, como la URL del cuaderno iPython.

No hay un lugar en particular donde se discuta esto a fondo, está en muchos lugares, pero reutilizaré otra metáfora que he visto antes.

Eres un escritor de libros. Su lector quiere una cosa regularmente. A medida que se identifican con los personajes, quieren que el personaje principal tenga el mismo color de ojos que ellos. Cómo haces eso ? Bueno, como escritor de libros no puedes. Para cada persona, la respuesta es obvia, pero para la mayoría de los usuarios no es posible.

Puede imprimir 10 versiones con 10 colores de ojos y pedirle al lector que elija. Pero el lector _tiene_ que hacerlo.

Lo mismo para el kernel de IPython.

El núcleo no sabe qué lo inició. Las cosas que comenzaron podrían _intentar_ establecer una variable env, pero es posible que ni siquiera tenga sentido en este contexto. Es posible que no tenga una computadora portátil conectada. Es posible que el proceso que inicie no sea python.

Tienes una cosa (tu núcleo) cuyo único propósito es ejecutar código. Puede o no tener acceso a un sistema de archivos, puede o no ser python. Puede o no estar conectado a una interfaz. puede o no estar conectado a múltiples clientes durante su vida, tal vez incluso simultáneamente.

Entonces, aunque en cada caso _probablemente_ puede dar una respuesta definitiva sobre si hay un documento adjunto a un núcleo y qué es, la respuesta general y cómo obtenerlo no está claro. La pregunta no tiene sentido, o al menos no hemos encontrado uno.

Entonces, como lector de libros, debe elegir y decirle al kernel el nombre de archivo que _usted_ cree que es el correcto.

Cuando el servidor del portátil se inicia, establece el nombre del archivo vinculado a él. Hay desafíos técnicos para hacerlo, principalmente no acoplar componentes, pero supongamos que podemos. Un par de preguntas desde la parte superior de mi cabeza.

Cuando ejecuta su computadora portátil a través de nbconvert, ¿qué nombre establece?

  • si la entrada es stdin?
  • si la entrada es red
  • si salida cuaderno =! cuaderno_de_entrada
  • en el modo "libro de libros" que toma múltiples cuadernos en la entrada.
    Al conectar una consola, ¿qué nombre establece?
    Si adjunta varios cuadernos, ¿qué nombre establece?

    • Si ejecuta varios cuadernos seguidos, ¿qué nombre establece?

    • Si ejecuta varios cuadernos en paralelo, ¿qué nombre establece?

      cuando se trabaja en un entorno sin sistema de archivos (postgres DB), ¿qué nombre?

      ¿Binario o ASCII? ¿Codificación definida?

      ¿Nombre del cuaderno de FullPath?

      ¿Qué pasa si no en la misma máquina?

      ¿Qué pasa si la ejecución es puramente en memoria porque el cuaderno se generó sobre la marcha?

      Incluso si tiene un nombre y print() ... ¿qué sucede si se cambia el nombre del archivo?

  • renombrado mientras el núcleo está apagado?
  • renombrado durante la ejecución del núcleo?
    Colaboración en tiempo real y enlaces duros cuando un archivo puede tener varios nombres, ¿cuál es el correcto?

Ninguna de las preguntas anteriores tiene respuestas claras para mí. Si hay un consenso sobre cómo hacerlo correctamente, sin arrinconarnos, lo pensaremos, y luego vendrán todas las dificultades técnicas.

Espero que eso aclare un poco las cosas. Puedes probar cosas como esta , pero verás que rara vez satisfacen a todos.

Disculpe, pero con esto:

!echo %cd% # under windows
!pwd # under linux/mac

obtienes la información deseada.
Para reutilizarlo, solo haz lo siguiente:

myInfo01 = !echo %cd% # under windows
myInfo02 = !pwd # under linux/mac

No funcionará porque el proceso CWD puede cambiar e incluso puede que no esté donde está almacenada la computadora portátil.

¿Está al menos garantizado que si abre una computadora portátil en un servidor de computadora portátil nuevo e implícitamente inicia un kernel ejecutando algún código, obtendrá pwd la carpeta en la que se encuentra el archivo ipynb?

El hecho de que ipython no pueda manejar mágicamente todos los casos extremos extraños, lo que creo que nadie esperaba, no debería impedir que tenga una regla _simple_ como esa para los casos _simples_ que a la gente realmente le importan (como entregar un cuaderno + archivos de datos en el mismo carpeta a los estudiantes)

¿Está al menos garantizado que si abre una computadora portátil en un servidor de computadora portátil nuevo e implícitamente inicia un kernel ejecutando algún código, obtendrá pwd la carpeta en la que se encuentra el archivo ipynb?

No.

No se garantiza que el núcleo esté en la misma máquina que ipynb, ni siquiera se garantiza que el archivo ipynb exista, exista, sea único o tenga una ruta única, o incluso sea/será un archivo. Ejemplo: colaboración en tiempo real en Google Drive.

Creo que no formulé mi pregunta lo suficientemente bien. 200 estudiantes tendrán una configuración de entorno python, la mayoría instalando anaconda en sus propias computadoras portátiles. Les entregaré el ejercicio de computadora como un cuaderno y los archivos de datos en una carpeta. Uno de ellos podría almacenar la computadora portátil en la base de datos postgres, dos podrían ejecutar el kernel en una máquina diferente a la computadora portátil donde tienen la computadora portátil. Tres estudiantes configurarán una colaboración en tiempo real en Google Drive juntos. Seis estudiantes harán algo más que quizás no hayas mencionado hasta ahora. Estoy pensando principalmente en los 190 estudiantes que razonablemente seguirán las instrucciones, descomprimirán la carpeta en su propia computadora portátil (Windows, OS X o Linux), iniciarán un servidor portátil en la _misma_ computadora portátil (ya sea por el explorador del servidor portátil o haciendo doble clic en el archivo del cuaderno) y déjelo iniciar implícitamente un nuevo núcleo (de nuevo en el mismo portátil) ejecutando la primera celda. La pregunta es si cwd funciona para _esos_ estudiantes. ¿Vendrán ~15 estudiantes a mi oficina porque os.getcwd() no funcionó o debo esperar cerca de 50-100?

Estoy pensando principalmente en los 190 estudiantes que razonablemente seguirán las instrucciones, descomprimirán la carpeta en su propia computadora portátil (Windows, OS X o Linux), iniciarán un servidor portátil en la misma computadora portátil (ya sea mediante el explorador del servidor portátil o haciendo doble clic en el archivo del cuaderno) y déjelo iniciar implícitamente un nuevo núcleo (de nuevo en el mismo portátil) ejecutando la primera celda.

Sí, usar os.cwd() o incluso c = !cwd funcionará para estos usuarios; y creo que en su contexto está bien pedirles que hagan eso. Pero como un caso de uso _general_ ese no es el caso. También trataremos de tener cuidado al indicar cosas en este rastreador de errores, ya que puede pasar como un respaldo explícito de este método. Y sabemos que la gente ted a no leer en profundidad.

Bastante justo, gracias por su preocupación por una comunicación precisa.

La primera vez que se ejecuta el script en un libro de trabajo y antes de cambiarlo, os.cwd() es el directorio del cuaderno.
Entonces, lo que uso a menudo en mi código es

if not 'workbookDir' in globals():
    workbookDir = os.getcwd()
print('workbookDir: ' + workbookDir)
os.chdir(workbookDir)  # If you changed the current working dir, this will take you back to the workbook dir.

Como parece, la mayoría de los usuarios aquí realmente no quieren acceder a la "ruta del portátil", sea lo que sea que eso signifique realmente en una implementación determinada, sino acceder a los recursos que están asociados con ese portátil, de tal manera que el los detalles del despliegue se abstraen.

Obviamente, distribuir cuadernos junto con datos asociados es un caso de uso general y amplio. ¿Tal vez sea necesario un mecanismo abstracto para acceder a los recursos desde dentro de un kernel? Entonces sería responsabilidad de la implementación (es decir, la instalación del servidor de la computadora portátil) configurar correctamente esa API de acceso a recursos, posiblemente con la ayuda de algunos metadatos de la computadora portátil. Entonces, el servidor de la computadora portátil local podría servir de forma predeterminada a estos recursos desde una ruta relativa a la computadora portátil. Otras implementaciones pueden proporcionar una interfaz separada (como un método de carga o una URL que apunta a los recursos), o simplemente no admitir la interfaz en absoluto.

Puede que ahora sea demasiado tarde, pero parece que Colaboratory podría ayudarte en tu trabajo aquí:
https://colab.research.google.com/notebooks/welcome.ipynb

Hay una variable llamada "_dh" insertada en los globales cuando se inicia el cuaderno. Parece que este es el directorio del cuaderno, aunque no he buscado ninguna documentación al respecto. Sin embargo, ahora mismo me está funcionando.

Similar a la solución de @SurealCereal de:

if not 'workbookDir' in globals():
    workbookDir = os.getcwd()

He estado usando esto justo después de mis importaciones:

try: ipynb_path
except NameError: ipynb_path = os.getcwd()

Algo sobre la palabra 'error' me hace pensar dos veces antes de jugar con su posición o existencia.

Alternativamente:

if 'workbookDir' not in globals():

es un poco más legible.

¿Fue útil esta página
0 / 5 - 0 calificaciones