Does anybody know if there is any tool for packing a Python project that uses several files and modules into a single script?
You can also automatically compile all Python files using the compileall module. You can do it from the shell prompt by running compileall.py and providing the path of the directory containing the Python files to compile: monty@python:~/python$ python -m compileall .
Save this as python_header.py:
#!/bin/env/python
# -*- coding: ascii -*-
import os
import sys
import imp
import tarfile
import tempfile
RUN_MODULE = "__run__"
SENTINEL = 'RzlBTXhya3ljIzl6PFFkQiRKLntEdHF+c2hvWid0IX5NVlxWd' \
           'FxcJ0NWQ2xKVUI0TVEuNl0rWUtnKiRr'.decode('base64')
class FileOffset(object):
    def __init__(self, fileobj, offset=0):
        self._fileobj = fileobj
        self._offset = offset
        self._fileobj.seek(offset)
    def tell(self):
        return self._fileobj.tell() - self._offset
    def seek(self, position, whence=os.SEEK_SET):
        if whence == os.SEEK_SET:
            if position < 0: raise IOErrror("Negative seek")
            self._fileobj.seek(position + self._offset)
        else:
            oldposition = self._fileobj.tell()
            self._fileobj.seek(position, whence)
            if self._fileobj.tell() < self._offset:
                self._fileobj.seek(oldposition, os.SEEK_SET)
                raise IOError("Negative seek")
    def __getattr__(self, attrname):
        return getattr(self._fileobj, attrname)
    def __enter__(self, *args):
        return self._fileobj.__enter__(*args)
    def __exit__(self, *args):
        return self._fileobj.__exit__(*args)
class TarImport(object):
    def __init__(self, tarobj, tarname=None):
        if tarname is None:
            tarname = '<tarfile>'
        self._tarname = tarname
        self._tarobj = tarobj
    def find_module(self, name, path=None):
        module_path = os.path.join(*name.split('.'))
        package_path = os.path.join(module_path, '__init__')
        for path in [module_path, package_path]:
            for suffix, mode, module_type in imp.get_suffixes():
                if module_type != imp.PY_SOURCE:
                    continue
                member = os.path.join(path) + suffix
                try:
                    modulefileobj = self._tarobj.extractfile(member)
                except KeyError:
                    pass
                else:
                    return Loader(name, modulefileobj,
                                  "%s/%s" % (self._tarname, member),
                                  (suffix, mode, module_type))
class Loader(object):
    def __init__(self, name, fileobj, filename, description):
        self._name = name
        self._fileobj = fileobj
        self._filename = filename
        self._description = description
    def load_module(self, name):
        imp.acquire_lock()
        try:
            module = sys.modules.get(name)
            if module is None:
                module = imp.new_module(name)
            module_script = self._fileobj.read()
            module.__file__ = self._filename
            module.__path__ = []
            sys.modules[name] = module
            exec(module_script, module.__dict__, module.__dict__)
        finally:
            imp.release_lock()
        return module
def find_offset(fileobj, sentinel):
    read_bytes = 0
    for line in fileobj:
        try:
            offset = line.index(sentinel)
        except ValueError:
            read_bytes += len(line)
        else:
            return read_bytes + offset + len(sentinel)
    raise ValueError("sentinel not found in %r" % (fileobj, ))
if __name__ == "__main__":
    sys.argv[:] = sys.argv[1:]
    archive_path = os.path.abspath(sys.argv[0])
    archive_offset = find_offset(open(archive_path), SENTINEL)
    archive = FileOffset(open(archive_path), archive_offset)
    tarobj = tarfile.TarFile(fileobj=archive)
    importer = TarImport(tarobj, archive_path)
    sys.meta_path.insert(0, importer)
    importer.find_module(RUN_MODULE).load_module(RUN_MODULE)
Save this as sh_header.sh:
#!/bin/sh
head -n @@TO@@ "$0" | tail -n +@@FROM@@ | python - "$0"
exit $?
Save this as create_tarred_program.py:
#!/usr/bin/env python
# -*- coding: latin-1 -*-
import sys
import imp
import shutil
sh_filename, runner_filename, tar_archive, dst_filename = sys.argv[1:]
runner = imp.load_module("tarfile_runner",
                        open(runner_filename, 'U'),
                        runner_filename,
                        ('.py', 'U', imp.PY_SOURCE))
sh_lines = open(sh_filename, 'r').readlines()
runner_lines = open(runner_filename, 'r').readlines()
sh_block = ''.join(sh_lines)
runner_block = ''.join(runner_lines)
if runner.SENTINEL in runner_block or runner.SENTINEL in sh_block:
    raise ValueError("Can't have the sentinel inside the runner module")
if not runner_block.endswith('\n') or not sh_block.endswith('\n'):
    raise ValueError("Trailing newline required in both headers")
to_pos = len(sh_lines) + len(runner_lines)
from_pos = len(sh_lines) + 1
sh_block = sh_block.replace("@@TO@@", str(to_pos))
sh_block = sh_block.replace("@@FROM@@", str(from_pos))
dst = open(dst_filename, 'wb')
dst.write(sh_block)
dst.write(runner_block)
dst.write(runner.SENTINEL)
shutil.copyfileobj(open(tar_archive, 'rb'), dst)
dst.flush()
dst.close()    
Create a tar archive with your packages named packages.tar. The main module should be called __run__.py, you should never import __main__. Run:
create_tarred_program.py sh_header.sh python_header.py packages.tar program.sh
Distrubute program.sh.
It's possible to avoid dependency on /bin/sh by an extended first line, but it still won't work on anything but *nix, so there's no point in it.
make the .egg file and install it or put it on pythonpath may solve your problem.
similar fellow 
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With