* New and improved asynchronous org-babel python blocks
:PROPERTIES:
:categories: emacs,python,orgmode
:date: 2016/11/09 11:00:01
:updated: 2016/11/09 11:00:01
:END:
About a year ago I posted some code to run org-babel python blocks [[http://kitchingroup.cheme.cmu.edu/blog/2015/11/20/Asynchronously-running-python-blocks-in-org-mode/][asynchronously]]. This year, my students asked for some enhancements related to debugging. Basically, they were frustrated by a few things when they got errors. First, they found it difficult to find the line number in the Traceback in the src block because there are no line numbers in the block, and it is annoying to do a special edit just for line numbers.
I thought about this, and figured out how to significantly improve the situation. The async python code in scimax now has the following features:
1. When you get a Traceback, it goes in the results, and each file listed in it is hyperlinked to the source file and line so it is easy to get to them.
2. The cursor jumps to the last line in the code block that is listed in the Traceback, and a beacon shines to show you the line
3. You can turn on temporary line numbers in the code block to see where the lines are in the block, and these disappear when you start typing. This is done in the variable `org-babel-async-python-show-line-numbers'.
4. You can control whether a buffer of the results shows or not via the variable `org-babel-async-python-show-results'.
5. When you run the block, you get a clickable link in the RESULTS section to kill the process.
6. You may also find the `autopep8' and `pylint' functions helpful.
The code for this is currently found here:
https://github.com/jkitchin/scimax/blob/org-9/scimax-org-babel-python.el
Eventually, I will merge this into master, after I am sure about all the changes needed for org 9.0. That is not likely to happen until the semester ends, so I do not mess up my students who use scimax in class. So, sometime mid-December it will make into master.
To make async the default way to run a python block use this code, so that you can use C-c C-c to run them:
#+BEGIN_SRC emacs-lisp :results silent
(require 'scimax-org-babel-python)
(add-to-list 'org-ctrl-c-ctrl-c-hook 'org-babel-async-execute:python)
#+END_SRC
As with the past few posts, this video will make it much more clear what the post is about:
#+BEGIN_EXPORT html
#+END_EXPORT
Here is a prototypical example that shows how it works. While it runs you can view the progress if you click on the link to show the results.
#+BEGIN_SRC python :results output org drawer
import time
for i in range(5):
print(i)
time.sleep(2)
#+END_SRC
#+RESULTS:
:RESULTS:
0
1
2
3
4
Traceback (most recent call last):
File "Org SRC", line 5, in
time.sleep(2)
KeyboardInterrupt
:END:
This block has a pretty obvious issue when we run it. The cursor jumps right to the problem!
#+BEGIN_SRC python :results output org drawer
print('This line is ok')
# 5 / 0
print('We will not see this')
#+END_SRC
#+RESULTS:
:RESULTS:
This line is ok
We will not see this
:END:
This block shows we can access any of the links in the Traceback. Here we have an error in calling a function that is raised in an external file.
#+BEGIN_SRC python :results output org drawer
import numpy as np
from scipy.integrate import odeint
Vspan = np.linspace(0, 2) # L
# dF/dV = F
def dFdV(F, V, v0):
return F
print(odeint(dFdV, 1.0, Vspan))
#+END_SRC
#+RESULTS:
:RESULTS:
Traceback (most recent call last):
File "Org SRC", line 11, in
print(odeint(dFdV, 1.0, Vspan))
File "/Users/jkitchin/anaconda3/lib/python3.5/site-packages/scipy/integrate/odepack.py", line 215, in odeint
ixpr, mxstep, mxhnil, mxordn, mxords)
TypeError: dFdV() missing 1 required positional argument: 'v0'
:END:
Here we show how nice it is to be able to kill a process. This block will not end on its own.
#+BEGIN_SRC python :results output org drawer
while True:
pass
#+END_SRC
#+RESULTS:
:RESULTS:
Traceback (most recent call last):
File "Org SRC", line 2, in
pass
KeyboardInterrupt
:END:
** autopep8
[[https://pypi.python.org/pypi/autopep8][autopep8]] is a tool for reformatting Python code. We wrapped this into an Emacs command so you can quickly reformat a Python code block.
#+BEGIN_SRC python :results output org drawer
a = 4
b = 5
c = a * b # comment
# another comment
def f(x):
return x
print(f(5))
#+END_SRC
** pylint
[[https://www.pylint.org][pylint]] is a great tool for checking your Python code for errors, style and conventions. We also wrapped this into an Emacs command so you can run it on a Python src block. The report that is generated had clickable links to help you get right to the lines in your code block with problems.
#+BEGIN_SRC python :results output org drawer
import numpy as np
a = np.array(5, 5)
def f(x): return x
print(f(6))
#+END_SRC