├── .gitattributes ├── .gitignore ├── stata_kernel ├── __init__.py ├── __main__.py ├── install.py └── stata_kernel.py ├── setup.py ├── README.md └── example.ipynb /.gitattributes: -------------------------------------------------------------------------------- 1 | *.ipynb binary -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb_checkpoints -------------------------------------------------------------------------------- /stata_kernel/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /stata_kernel/__main__.py: -------------------------------------------------------------------------------- 1 | from IPython.kernel.zmq.kernelapp import IPKernelApp 2 | from .stata_kernel import StataKernel 3 | IPKernelApp.launch_instance(kernel_class=StataKernel) -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | 3 | setup( 4 | name='Stata kernel', 5 | version='0.1', 6 | description='Stata kernel for IPython', 7 | author='James Fiedler', 8 | author_email='jrfiedler@gmail.com', 9 | url='https://github.com/jrfiedler/stata-kernel', 10 | packages=['stata_kernel'], 11 | ) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # stata-kernel 2 | A Stata kernel for IPython/Jupyter 3 | 4 | **This code is not actively maintained. If anyone is interested in taking over this project, with more active maintenance, please feel free to do so.** 5 | 6 | ## Setup 7 | This kernel currently only works in Windows. 8 | 9 | You need a recent version of Stata, 10 | and if you have not already used Stata automation, register its type library 11 | by following [these instructions](http://www.stata.com/automation/#createmsapp). 12 | 13 | You also need IPython 3. 14 | 15 | ## Installing 16 | You can install with 17 | 18 | pip install git+https://github.com/jrfiedler/stata-kernel 19 | python -m stata_kernel.install 20 | 21 | ## Using 22 | After installing, simply open an IPython notebook server 23 | 24 | ipython notebook 25 | 26 | and choose a new "Stata" notebook. 27 | -------------------------------------------------------------------------------- /stata_kernel/install.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | import json 4 | import os 5 | import sys 6 | 7 | from IPython.kernel.kernelspec import install_kernel_spec 8 | from IPython.utils.tempdir import TemporaryDirectory 9 | 10 | kernel_json = { 11 | "argv":[sys.executable, "-m", "stata_kernel", "-f", "{connection_file}"], 12 | "display_name": "Stata", 13 | "language": "stata" 14 | } 15 | 16 | 17 | def install_my_kernel_spec(user=True): 18 | with TemporaryDirectory() as td: 19 | os.chmod(td, 0o755) # Starts off as 700, not user readable 20 | with open(os.path.join(td, 'kernel.json'), 'w') as f: 21 | json.dump(kernel_json, f, sort_keys=True) 22 | 23 | print('Installing IPython kernel spec') 24 | install_kernel_spec(td, 'stata', user=user, replace=True) 25 | 26 | 27 | if __name__ == '__main__': 28 | install_my_kernel_spec() 29 | -------------------------------------------------------------------------------- /stata_kernel/stata_kernel.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import os 3 | import re 4 | import time 5 | import tempfile 6 | 7 | import win32com.client 8 | try: 9 | from ipykernel.kernelbase import Kernel 10 | except ImportError: 11 | from IPython.kernel.zmq.kernelbase import Kernel 12 | from IPython.core.magic import register_line_cell_magic 13 | 14 | 15 | class StataKernel(Kernel): 16 | implementation = 'StataKernel' 17 | implementation_version = '0.0.1' 18 | language = 'Stata Ado and Mata' 19 | language_version = 'any' 20 | banner = '' 21 | language_info = { 22 | 'name': 'stata', 23 | 'mimetype': 'text/x-stata', 24 | 'file_extension': 'do', 25 | } 26 | 27 | log_address = os.path.join(tempfile.gettempdir(), 'stata_kernel_log.txt') 28 | 29 | def __init__(self, *args, **kwargs): 30 | super(StataKernel, self).__init__(*args, **kwargs) 31 | self.stata = win32com.client.Dispatch("stata.StataOLEApp") 32 | self.stata_do = self.stata.DoCommandAsync 33 | self.stata_do('log using {} , text replace'.format(self.log_address)) 34 | self.stata_do('set more off') 35 | time.sleep(0.5) 36 | self.log_file = open(self.log_address) 37 | self.continuation = False 38 | 39 | print('init complete') 40 | 41 | def remove_continuations(self, code): 42 | return re.sub(r'\s*\\\\\\\s*\n', ' ', code) 43 | 44 | def get_log_line(self, ntries=10): 45 | UtilIsStataFree = self.stata.UtilIsStataFree 46 | log_file = self.log_file 47 | log_line = log_file.readline() 48 | try_num = 1 49 | while not log_line and not UtilIsStataFree(): 50 | time.sleep(0.05) 51 | log_line = log_file.readline() 52 | try_num += 1 53 | return log_line 54 | 55 | def ignore_output(self): 56 | get_log_line = self.get_log_line 57 | while get_log_line(): 58 | pass 59 | 60 | def respond(self): 61 | lines = [] 62 | UtilIsStataFree = self.stata.UtilIsStataFree 63 | log_file = self.log_file 64 | log_line = log_file.readline() 65 | while not log_line: 66 | time.sleep(0.05) 67 | log_line = log_file.readline() 68 | while log_line or not UtilIsStataFree(): 69 | if log_line: 70 | stream_content = {'name': 'stdout', 'text': log_line} 71 | self.send_response(self.iopub_socket, 'stream', stream_content) 72 | else: 73 | time.sleep(0.05) 74 | log_line = log_file.readline() 75 | 76 | def do_execute( 77 | self, 78 | code, 79 | silent, 80 | store_history=True, 81 | user_expressions=None, 82 | allow_stdin=False 83 | ): 84 | self.continuation = False 85 | self.ignore_output() 86 | code = self.remove_continuations(code.strip()) 87 | mata_magic = re.match(r'\s*%%mata\s+', code) 88 | if mata_magic: 89 | code = 'mata\n' + code[mata_magic.end():] + '\nend\n' 90 | try: 91 | self.stata_do(' ' + code + '\n') 92 | self.respond() 93 | except KeyboardInterrupt: 94 | self.stata.UtilSetStataBreak() 95 | self.respond() 96 | return {'status': 'abort', 'execution_count': self.execution_count} 97 | 98 | msg = { 99 | 'status': 'ok', 100 | 'execution_count': self.execution_count, 101 | 'payload': [], 102 | 'user_expressions': {} 103 | } 104 | return msg 105 | 106 | def do_shutdown(self, restart): 107 | self.stata_do(' exit, clear\n') 108 | 109 | 110 | if __name__ == '__main__': 111 | from IPython.kernel.zmq.kernelapp import IPKernelApp 112 | IPKernelApp.launch_instance(kernel_class=StataKernel) 113 | -------------------------------------------------------------------------------- /example.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [ 10 | { 11 | "name": "stdout", 12 | "output_type": "stream", 13 | "text": [ 14 | ". sysuse auto\n", 15 | "(1978 Automobile Data)\n", 16 | "\n" 17 | ] 18 | } 19 | ], 20 | "source": [ 21 | "sysuse auto" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": 2, 27 | "metadata": { 28 | "collapsed": false 29 | }, 30 | "outputs": [ 31 | { 32 | "name": "stdout", 33 | "output_type": "stream", 34 | "text": [ 35 | ". forv i=1(1)1e7 {\n", 36 | " 2. if mod(`i', 1e5) == 0 {\n", 37 | " 3. di %7.0f `i'\n", 38 | " 4. }\n", 39 | " 5. }\n", 40 | " 100000\n", 41 | " 200000\n", 42 | " 300000\n", 43 | " 400000\n", 44 | " 500000\n", 45 | " 600000\n", 46 | "--Break--\n", 47 | "r(1);\n", 48 | "\n" 49 | ] 50 | } 51 | ], 52 | "source": [ 53 | "forv i=1(1)1e7 {\n", 54 | " if mod(`i', 1e5) == 0 {\n", 55 | " di %7.0f `i'\n", 56 | " }\n", 57 | "}" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 3, 63 | "metadata": { 64 | "collapsed": false 65 | }, 66 | "outputs": [ 67 | { 68 | "name": "stdout", 69 | "output_type": "stream", 70 | "text": [ 71 | ". summ weight mpg\n", 72 | "\n", 73 | " Variable | Obs Mean Std. Dev. Min Max\n", 74 | "-------------+--------------------------------------------------------\n", 75 | " weight | 74 3019.459 777.1936 1760 4840\n", 76 | " mpg | 74 21.2973 5.785503 12 41\n", 77 | "\n" 78 | ] 79 | } 80 | ], 81 | "source": [ 82 | "summ \\\\\\\n", 83 | " weight mpg " 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 4, 89 | "metadata": { 90 | "collapsed": false 91 | }, 92 | "outputs": [ 93 | { 94 | "name": "stdout", 95 | "output_type": "stream", 96 | "text": [ 97 | ". summ\n", 98 | "\n", 99 | " Variable | Obs Mean Std. Dev. Min Max\n", 100 | "-------------+--------------------------------------------------------\n", 101 | " make | 0\n", 102 | " price | 74 6165.257 2949.496 3291 15906\n", 103 | " mpg | 74 21.2973 5.785503 12 41\n", 104 | " rep78 | 69 3.405797 .9899323 1 5\n", 105 | " headroom | 74 2.993243 .8459948 1.5 5\n", 106 | "-------------+--------------------------------------------------------\n", 107 | " trunk | 74 13.75676 4.277404 5 23\n", 108 | " weight | 74 3019.459 777.1936 1760 4840\n", 109 | " length | 74 187.9324 22.26634 142 233\n", 110 | " turn | 74 39.64865 4.399354 31 51\n", 111 | "displacement | 74 197.2973 91.83722 79 425\n", 112 | "-------------+--------------------------------------------------------\n", 113 | " gear_ratio | 74 3.014865 .4562871 2.19 3.89\n", 114 | " foreign | 74 .2972973 .4601885 0 1\n", 115 | "\n" 116 | ] 117 | } 118 | ], 119 | "source": [ 120 | "summ" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": 8, 126 | "metadata": { 127 | "collapsed": false 128 | }, 129 | "outputs": [ 130 | { 131 | "name": "stdout", 132 | "output_type": "stream", 133 | "text": [ 134 | ". mata\n", 135 | "------------------------------------------------- mata (type end to exit) -------\n", 136 | ": for (i=1; i<10; i++) {\n", 137 | "> i\n", 138 | "> }\n", 139 | " 1\n", 140 | " 2\n", 141 | " 3\n", 142 | " 4\n", 143 | " 5\n", 144 | " 6\n", 145 | " 7\n", 146 | " 8\n", 147 | " 9\n", 148 | "\n", 149 | ": end\n", 150 | "---------------------------------------------------------------------------------\n", 151 | "\n" 152 | ] 153 | } 154 | ], 155 | "source": [ 156 | "%%mata\n", 157 | "\n", 158 | "for (i=1; i<10; i++) {\n", 159 | " i\n", 160 | "}" 161 | ] 162 | } 163 | ], 164 | "metadata": { 165 | "kernelspec": { 166 | "display_name": "Stata", 167 | "language": "stata", 168 | "name": "stata" 169 | }, 170 | "language_info": { 171 | "file_extension": "do", 172 | "mimetype": "text/x-stata", 173 | "name": "stata" 174 | } 175 | }, 176 | "nbformat": 4, 177 | "nbformat_minor": 0 178 | } 179 | --------------------------------------------------------------------------------