embedding resources in python scripts
<p>I'd like to figure out how to embed binary content in a python script. For instance, I don't want to have any external files around (images, sound, ... ), I want all this content living inside of my python scripts.</p>

<p>Little example to clarify, let's say I got this small snippet:</p>

<pre><code>from StringIO import StringIO
from PIL import Image, ImageFilter

embedded_resource = StringIO(open("Lenna.png", "rb").read())
im = Image.open(embedded_resource)
im.show()

im_sharp = im.filter(ImageFilter.SHARPEN)
im_sharp.show()
</code></pre>

<p>As you can see, the example is reading the external file 'Lenna.png'</p>

<p><a href="http://i.stack.imgur.com/3p4GL.png" rel="nofollow"><img src="http://i.stack.imgur.com/3p4GL.png" alt="enter image description here"></a></p>

<p><strong>Question</strong></p>

<p>How to proceed to embed "Lenna.png" as a resource (variable) into my python script. What's the fastest way to achieve this simple task using python?</p>

<p>You might find the following class rather useful for embedding resources in your program. To use it, call the <code>package</code> method with paths to the files that you want to embed. The class will print out a <code>DATA</code> attribute that should be used to replace the one already found in the class. If you want to add files to your pre-built data, use the <code>add</code> method instead. To use the class in your program, make calls to the <code>load</code> method using context manager syntax. The returned value is a <code>Path</code> object that can be used as a filename argument to other functions or for the purpose of directly loading the reconstituted file. See this <a href="http://pastebin.com/bRZuq72L" rel="nofollow">SMTP Client</a> for example usage.</p>

<pre><code>import base64
import contextlib
import pathlib
import pickle
import pickletools
import sys
import zlib


class Resource:

    """Manager for resources that would normally be held externally."""

    WIDTH = 76
    __CACHE = None
    DATA = b''

    @classmethod
    def package(cls, *paths):
        """Creates a resource string to be copied into the class."""
        cls.__generate_data(paths, {})

    @classmethod
    def add(cls, *paths):
        """Include paths in the pre-generated DATA block up above."""
        cls.__preload()
        cls.__generate_data(paths, cls.__CACHE.copy())

    @classmethod
    def __generate_data(cls, paths, buffer):
        """Load paths into buffer and output DATA code for the class."""
        for path in map(pathlib.Path, paths):
            if not path.is_file():
                raise ValueError('{!r} is not a file'.format(path))
            key = path.name
            if key in buffer:
                raise KeyError('{!r} has already been included'.format(key))
            with path.open('rb') as file:
                buffer[key] = file.read()
        pickled = pickle.dumps(buffer, pickle.HIGHEST_PROTOCOL)
        optimized = pickletools.optimize(pickled)
        compressed = zlib.compress(optimized, zlib.Z_BEST_COMPRESSION)
        encoded = base64.b85encode(compressed)
        cls.__print("    DATA = b'''")
        for offset in range(0, len(encoded), cls.WIDTH):
            cls.__print("\\\n" + encoded[
                slice(offset, offset + cls.WIDTH)].decode('ascii'))
        cls.__print("'''")

    @staticmethod
    def __print(line):
        """Provides alternative printing interface for simplicity."""
        sys.stdout.write(line)
        sys.stdout.flush()

    @classmethod
    @contextlib.contextmanager
    def load(cls, name, delete=True):
        """Dynamically loads resources and makes them usable while needed."""
        cls.__preload()
        if name not in cls.__CACHE:
            raise KeyError('{!r} cannot be found'.format(name))
        path = pathlib.Path(name)
        with path.open('wb') as file:
            file.write(cls.__CACHE[name])
        yield path
        if delete:
            path.unlink()

    @classmethod
    def __preload(cls):
        """Warm up the cache if it does not exist in a ready state yet."""
        if cls.__CACHE is None:
            decoded = base64.b85decode(cls.DATA)
            decompressed = zlib.decompress(decoded)
            cls.__CACHE = pickle.loads(decompressed)

    def __init__(self):
        """Creates an error explaining class was used improperly."""
        raise NotImplementedError('class was not designed for instantiation')
</code></pre>

python embedded-resource