-1

In ipython cells you can execute shell commands as follows:

ipython:

print("asdf")
!echo asdf

However, if you try to import this code from file,

asdf.py:

def asdf():
  print("asdf")
  !echo asdf

ipython:

from asdf import asdf

it results in an error.

!echo asdf
^
SyntaxError: invalid syntax

The use case for that is repetative massive scripts in google colab utilizing ffmpeg, wget, mount, e.t.c.
While you can use os.system or subprocess, they are not as interactive in providing real-time stdout.

Entrack
  • 51
  • 1
  • 1
  • 10
  • This is an ipython feature. You cannot use the `!` syntax in Python in general. – mkrieger1 May 22 '20 at 09:13
  • And what exactly is your question, actually? – mkrieger1 May 22 '20 at 09:15
  • Imo this might be impossible, since Ipython magic happens only in the interactive shell, before the input is passed to python interpreter. That's not the case with import statements. – RafalS May 22 '20 at 09:15
  • @mkrieger1, I wonder how can I reuse (e.g. by importing) code that uses ipython magic. I prefer to use it because of the fact that os.system and subprocess methods of executing shell commands do not provide interactive/real-time output. – Entrack May 22 '20 at 10:56
  • Maybe this helps: https://stackoverflow.com/questions/10361206/how-to-run-an-ipython-magic-from-a-script-or-timing-a-python-script – mkrieger1 May 22 '20 at 11:06
  • But I don't think that using `subprocess` would be a problem, if done properly. – mkrieger1 May 22 '20 at 11:07
  • @mkrieger1, thank you for the provided link, I did a little bit of research and came up with solution to my problem. – Entrack May 23 '20 at 12:03

1 Answers1

1

Use case solution

If you want to reuse code that has ipython magic functions in it, simply use %run instead of the import.

ipython:

%run utils.ipynb

utils.ipynb:

def asdf():
  print("asdf")
  !echo asdf

Example above works fine.
Taken from this answer.


On reusing ipython code

Why the original question was an A-B problem of some kind? The reason is that you should not really drag ipython additional functionality to the pure python execution.

  • If you have a, let's say, google colab notebook with useful utils, then just !wget it from the public link and %run it.
  • If you have a python script to execute, do a regular import on .py files.

Sure, there are ways to import .ipynb files to python code: Jupyter notebook's Notebook Loader, ipynb package, nbimporter package (but even the nbimporter's author says you should not really do that. Just convert your notebook to .py using VSCode or another tool).

So, if you use ipython research environment and features, just stick with it. Or switch to pure python environment with proper modules, testing, e.t.c.


Also, if you're struggling with doing wget:

file_id = "1xE8Db1zvQ7v-z13CO2qc3F6wJmtr3YHu" # can be extracted from public link
file_out_name = "utils.ipynb"
!wget "https://docs.google.com/uc?export=download&id=""$file_id" -O "$file_out_name"

However, on the problem of calling cmd, I see no way of executing shell commands interactively in python with one line. While subprocess can do that, it takes multiple lines to achieve.

Entrack
  • 51
  • 1
  • 1
  • 10