Skip to main content

Automatic string encoding ofbinary files into python variables

Project description

Purpose

The stringify module allows you to easily include your project’s binary files as python base64 strings. This may not be useful for your little tkinter project until you try to bundle the project as an executable using pyinstaller. Suddenly, you get to spend lots of time thinking about how to best write your spec files so that they capture the current files and any future changes as well. Or you could use stringify.

Installation

Simply pip install stringify should do the trick. You could also download this repository and python setup.py install, but that isn’t as fun, is it?

Use Case

Somewhere - probably within your module - you have a file that has static, non-code data. You probably have a directory called images or bin that the python code references when building a GUI or executing a program… whatever. This works great when using python directly - such as when you install the package via pip and call it from the command-line. This doesn’t work so well when you try to bundle your package using pyinstaller, which doesn’t natively recognize your non-code dependencies.

This library allows you to read those binary files into python code and include that data as python variables in your code base.

A quick note, this library has only been tested on relatively modestly-sized files - such as images. Larger file packaging using this method has not been tested.

Quickstart

We will assume a project structure that starts begins as outlined below. Note that the image paths are explicitly called out as part of my_package/package_file_0.py.:

setup.py
my_package/
    __init__.py
    package_file_0.py
    images/
        img1.png
        img2.png

Exile Binary Files

Move your binary files outside of the package that you wish to include them within. We will put something in there to take their place, but dont worry about that for the moment. Our new project structure:

setup.py
images/
    img1.png
    img2.png
my_package/
    __init__.py
    package_file_0.py

Run stringify_py() Utility

Our files are now located within images and our desired location will be images.py within the package.:

from stringify import stringify_py

stringify_py(source_path='images', destination_file='my_package/images.py')

Note that dashes will be replaced with underscores and spaces will be replaced with underscores and that the extensions will be removed before the name of the python variable is created. For instance, green-dot one.png will become the variable green_dot_one.

The source tree as it existed earlier remains intact, but we have an extra file within my_package called images.py:

setup.py
images/
    img1.png
    img2.png
my_package/
    __init__.py
    package_file_0.py
    images.py

Feel free to have a look at images.py, you can’t hurt it and you can always regenerate it. You should see two variables located within called img1 and img2. Each of these has a long byte string assigned to it that can be easily referenced and mined for the data.

Reference the Image Strings

Recall that it was package_file_0.py that utilized the image data. Within package_file_0.py, import the new image strings:

from images import img1, img2

Replace any absolute function calls to those images with the variable. Note that some functions, such as tkinter.PhotoImage() can take image data directly in this format.:

# tkinter.PhotoImage(file='./images/img1.png')  # replace this call...
tkinter.PhotoImage(data=img1)                   # with this one

Depending on your use case, you may have to experiment with method of unpacking the data for use.

Lock it Down

To reduce the chances of messing this up later, you may wish to add this funcitonality to your workflow so that it is automatically completed as you are developing and distributing your package. Simply include stringify_py() in your setup.py script for my_package just before the call to setup().:

from setuptools import setup
from stringify import stringify_py

stringify_py(source_path='images', destination_file='my_package/images.py')

setup(
    name='my_package',
    version=__version__,
    setup_requires=['stringify', 'flake8']
    ...

As shown, you may also wish to add stringify to your setup_requires, but you will get an error on import if stringify isn’t installed, so it won’t mess up your packaging to skip this line.

Run your PyInstaller Script

Now that your files are simply bundled into your application, there should be nothing special about your package that requires MANIFEST.in or interferes with pyinstaller.

Simply pyinstaller my_package/package_file_0.py (assuming that is where your entry point is), and you are ready to rock!

Drink

Now that you aren’t spending all of your time trying to write customer pyinstaller scripts for your project, then you can celebrate by having a drink. Enjoy!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for stringify, version 0.1.1
Filename, size File type Python version Upload date Hashes
Filename, size stringify-0.1.1-py3.6.egg (7.3 kB) File type Egg Python version 3.6 Upload date Hashes View hashes
Filename, size stringify-0.1.1-py3-none-any.whl (8.0 kB) File type Wheel Python version py3 Upload date Hashes View hashes

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page