32

I have a simple script that has a dependency on dnspython for parsing zone files. I would like to distribute this script as a single .py that users can run just so long as they have 2.6/2.7 installed. I don't want to have the user install dependencies site-wide as there might be conflicts with existing packages/versions, nor do I want them to muck around with virtualenv. I was wondering if there was a way to embed a package like dnspython inside the script (gzip/base64) and have that script access that package at runtime. Perhaps unpack it into a dir in /tmp and add that to sys.path? I'm not concerned about startup overhead, I just want a single .py w/ all dependencies included that I can distribute.

Also, there would be no C dependencies to build, only pure python packages.

Edit: The script doesn't have to be a .py. Just so long as it is a single executable file.

Jason Keene
  • 1,085
  • 3
  • 10
  • 20
  • 3
    If you can relax the one file restriction, you can just package the dnspython library alongside your .py file, either as a zip file or just as a regular standalone file -- that would solve the dependency issue. Are you adamant about having just 1 file? – Mahmoud Abdelkader Jul 11 '12 at 16:10
  • 4
    The road to license hell is paved with embedding... – Ignacio Vazquez-Abrams Jul 11 '12 at 16:13
  • @MahmoudAbdelkader I suppose that would work. Python would look in the current directory for the package before looking elsewhere (though I think this order is changing in 3). Still wish there was a way to package all the dependencies up as one executable file that the user can run and not have any issues. I suppose it doesn't have to be a .py. – Jason Keene Jul 11 '12 at 16:28
  • There are things like `py2exe` and `freeze` invented specifically for the purpose of having one executable to distribute. These are platform-specific, though. – 9000 Jul 11 '12 at 16:44

3 Answers3

12

You can package multiple Python files up into a .egg. Egg files are essentially just zip archives with well defined metadata - look at the setuptools documentation to see how to do this. Per the docs you can make egg files directly executable by specifying the entry point. This would give you a single executable file that can contain your code + any other dependencies.

EDIT: Nowadays I would recommend building a pex to do this. pex is basically an executable zip file with non stdlib dependencies. It doesn't contain a python distribution (like py2app/py2exe) but holds everything else and can be built with a single command line invocation. https://pex.readthedocs.org/en/latest/

Simeon
  • 421
  • 2
  • 6
  • 1
    Thanks, I was trying to get an egg built with setuptools just now. Have never built an egg before as I have always heard they have fallen out of favor. – Jason Keene Jul 11 '12 at 17:00
3

The simplest way is just to put your python script named __main__.py with pure Python dependencies in a zip archive, example.

Otherwise PyInstaller could be used to produce a stand-alone executable.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670
1

please don't do this. If you do DO NOT make a habit of it.

  • pydns is BDS licensed but if you try to "embed" a gpl module in this way you could get in trouble
  • you can learn to use setuptools and you will be much happier in the long run
  • setuptools will handle the install of dependencies you identified (I'm not sure if the pydns you are using is pure python so you might create problems for your users if you try to add it yourself without knowing their environment)
  • you can set a url or pypi so that people could upgrade your script with easy_install -U
Phil Cooper
  • 5,747
  • 1
  • 25
  • 41
  • 1
    The package I am using is dnspython, not pydns. If setuptools can build me a single distributable executable that only requires python 2.6/2.7 I will use it. If you are saying to simply use it to install dependencies site wide then this isn't what I was asking for. dnspython is pure python and I don't see anything in it's license that would prevent me from embedding it. End users are not developers and know nothing about the python ecosystem (setuptools/easy_install/pip/virtaulenv/etc). – Jason Keene Jul 11 '12 at 16:54