IPython in a standalone, executable zip file

[Contributed by Lisandro Dalcin of MPI4Py and Cython fame, thanks!].

With the code below, you can make a standalone executable zip file that contains all of IPython. The code as written is made for 0.10, but it's easy enough to adapt (we'll likely include it in IPython proper as a utility). If you update the library layout for the post-0.10 refactoring, please post an updated version below.

   1 ## Author:  Lisandro Dalcin
   2 ## Contact: dalcinl@gmail.com
   3 
   4 import sys, os
   5 import glob
   6 from zipfile import ZipFile
   7 from zipfile import ZIP_STORED
   8 from zipfile import ZIP_DEFLATED
   9 try:
  10     import zlib
  11 except ImportError:
  12     zlib = None
  13 
  14 origin = 'IPython'
  15 
  16 includes = [
  17 'IPython/*.py',
  18 'IPython/config/*.py',
  19 'IPython/Extensions/*.py',
  20 'IPython/external/*.py',
  21 'IPython/frontend/*.py',
  22 'IPython/frontend/*/*.py',
  23 'IPython/gui/*.py',
  24 'IPython/gui/*/*.py',
  25 'IPython/kernel/*.py',
  26 'IPython/kernel/*/*.py',
  27 'IPython/testing/*.py',
  28 'IPython/testing/*/*.py',
  29 'IPython/tools/*.py',
  30 'IPython/UserConfig/*.py',
  31 ]
  32 
  33 target = 'ipython.zip'
  34 
  35 header = """\
  36 #!/bin/sh
  37 exec python -c "
  38 import sys, os
  39 sys.path.insert(0, os.path.abspath('$0'))
  40 import IPython.Shell
  41 IPython.Shell.start().mainloop()
  42 " $@
  43 """
  44 
  45 header_win = '\r\n'.join("""\
  46 @echo off
  47 setlocal
  48 set _cmd=%_cmd%import sys, os;
  49 set _cmd=%_cmd%sys.path.insert(0,os.path.abspath('%0'));
  50 set _cmd=%_cmd%import IPython.Shell;
  51 set _cmd=%_cmd%IPython.Shell.start().mainloop();
  52 python.exe -c "%_cmd%" %*
  53 goto :eof
  54 """.split('\n'))
  55 
  56 if 'win' in sys.platform:
  57     target = os.path.splitext(target)[0]+'.bat'
  58     header = header_win
  59 
  60 script = ("ipython.py", """\
  61 #!/usr/bin/env python
  62 import IPython.Shell
  63 IPython.Shell.start().mainloop()
  64 """)
  65 
  66 try:
  67     prefix = sys.argv[1]
  68     prefix = os.path.expanduser(prefix)
  69     prefix = os.path.normpath(prefix)
  70 except IndexError:
  71     package = __import__(origin)
  72     pkgroot = os.path.dirname(package.__file__)
  73     prefix = os.path.dirname(pkgroot)
  74 assert os.path.isdir(prefix)
  75 
  76 filelist = []
  77 for pattern in includes:
  78     files = glob.glob(os.path.join(prefix, pattern))
  79     filelist += sorted(files, key=str.lower)
  80 assert filelist
  81 
  82 # white shell-script header
  83 fobj = open(target, 'wb')
  84 fobj.write(header.encode('ascii'))
  85 fobj.close()
  86 
  87 # add files to the ZIP archive
  88 if zlib is not None:
  89     compression = ZIP_DEFLATED
  90 else:
  91     compression = ZIP_STORED
  92 fobj = ZipFile(target, 'a', compression)
  93 fobj.writestr(script[0], script[1])
  94 for filename in filelist:
  95     arcname = filename[len(prefix)+1:]
  96     fobj.write(filename, arcname)
  97 fobj.close()
  98 
  99 # make the ZIP file executable
 100 try:
 101     try:
 102         mode = eval('0o755')
 103     except SyntaxError:
 104         mode = eval('0755')
 105     os.chmod(target, mode)
 106 except:
 107     pass

Cookbook/StandaloneZip (last edited 2010-04-10 04:02:41 by FernandoPerez)