Quickstart¶
The goal of Tiamat is to simplify the process of building Python projects as a single frozen binary. For that reason, setting up Tiamat only takes a few steps, as explained in the following sections.
Prerequisites¶
This quickstart assumes:
- You are working with an existing Python application
- Your Python project has standard
setup.pyandrequirements.txtfiles
The only other thing that most projects will need is a run.py.
Create the run.py¶
Since Tiamat creates a single binary, it needs a single entry point. This entry point is defined in the file run.py. This is a Python script that is used to start your application. The contents of the run.py is typically the same code that is used in your setuptools entry point or the startup script used in distutils. There is nothing special about the run.py; Tiamat just needs an entry point that is clean Python.
Note
Setuptools creates a startup script that dynamically discovers part of how the application starts up. This makes sense when the application is started in an environment with many python libs and apps. But Tiamat creates an isolated python environment which does not satisfy the needs of setuptools.
A typical run.py looks similar to the following example:
import myapp
def main():
myapp.start()
main()
Just some good old Python! If you are building a pop project, pop-seed creates the run.py for you.
Run Tiamat build¶
That’s right! All you need outside of pop is a run.py that your Python project likely already has! Tiamat uses the setup.py and requirements.txt files to build the necessary environments.
Assuming you have a standard Python project defined, to run a Tiamat build:
Navigate to the project directory.
Run the
tiamat buildcommand.For example, if you were running Tiamat for an application is called
foo, the command would be:tiamat build -n foo
This command kicks off the build process and places the resulting binary in a directory called dist/foo. Now that the binary is available, you can call it directly.
Using pop-seed for an in-action example¶
pop-seed can create an example project that can be easily compiled into a binary with tiamat:
pip install pop tiamat
mkdir poptest
cd poptest
pop-seed poptest
# Test pop-seed generated run.py
python3 run.py # Output: "poptest works!"
# Build binary with tiamat
tiamat build -n poptest
# Test resulting binary
./dist/poptest # Output: "poptest works!"
What Happened?¶
Tiamat starts with the same version of Python that you used to execute the tiamat build command. This version of Python is now embedded in your binary.
Next, it creates a virtual environment (venv) for your application. Tiamat then populates the venv with the dependencies that are defined as requirements for the main application, including the application itself.
Once the venv is set up, it triggers PyInstaller to create a binary from the run.py. PyInstaller builds a binary from all of the imports that come from the run.py. This is done to build a small binary and include only the most required code. Note that this is not the case for many applications; it is typical that things are late imported and for the application to assume a larger Python environment is available. It is also typical that extra files are needed by the application and are typically added via the setup.py.
Instead of following the imports, Tiamat bundles the venv into the binary created by PyInstaller. This means that you have a strong assurance that the full, needed environment is available. While this does create a slightly larger binary, it allows for a much easier and reliable build.
Using the Build Addon¶
Many Python projects require C libraries. For that reason, you might wonder how dynamic libraries can be added to the final binary. Tiamat has an answer to this.
When running tiamat build, we can use a configuration file. This file allows you to define any option that would be passed on the CLI. It also allows you to define the routines for external builds.
For example, a Tiamat config that needs to add the library libsodium would look like the following example:
build:
libsodium:
make:
- wget https://download.libsodium.org/libsodium/releases/LATEST.tar.gz
- tar xvf LATEST.tar.gz
- cd libsodium-stable && ./configure && make
src: libsodium-stable/src/libsodium/.libs/libsodium.so
dest: lib/
This example defines how a library will download and build. Then, it indicates the src is relative to the root of the build and that the dest is relative to the root of the venv.
The src can be a directory or a list of files and the dest can be a single directory to store the files.