Skip to content

Instantly share code, notes, and snippets.

@balouf
Created December 2, 2020 07:35
Show Gist options
  • Save balouf/c9cc0e9fcb96f0ad2c609d37a31a778a to your computer and use it in GitHub Desktop.
Save balouf/c9cc0e9fcb96f0ad2c609d37a31a778a to your computer and use it in GitHub Desktop.
pyinstaller tutorial
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"cell_type": "markdown",
"source": "# Using Pyinstaller\n\n### Python workshop - Fabien Mathieu"
},
{
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"cell_type": "markdown",
"source": "# Goal"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "``pyinstaller`` creates standalone executables from Python. It is for situations where you cannot / don't want to install things on a computer:\n- Make a portable version of your program\n- Computer dedicated to a demo (USB thumb) / VPC (net drive)"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Resources:\n- https://pyinstaller.readthedocs.io/\n- https://realpython.com/pyinstaller-python/"
},
{
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"cell_type": "markdown",
"source": "# Example"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "- Hello world!\n- A simple plot-maker."
},
{
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"cell_type": "markdown",
"source": "# Disclaimer"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "This tutorial is for Windows 10 with Conda. The way to use pyinstaller may slightly differ on other os/Python distribs."
},
{
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"cell_type": "markdown",
"source": "# Step#1 Have a working Python code"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "You need a ``.py`` file! See the examples provided separately."
},
{
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"cell_type": "markdown",
"source": "# Hello world"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2020-12-01T14:55:03.285896Z",
"start_time": "2020-12-01T14:55:03.281888Z"
},
"cell_style": "split",
"trusted": true
},
"cell_type": "code",
"source": "def hello():\n while True:\n print(\"Hello world!\")\n rep = input('\\nDo you wish to do it one more time? ([Y]/N) ? ')\n if rep.upper() == 'N':\n break",
"execution_count": null,
"outputs": []
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2020-12-01T14:55:11.054807Z",
"start_time": "2020-12-01T14:55:05.026546Z"
},
"cell_style": "split",
"trusted": true
},
"cell_type": "code",
"source": "hello()",
"execution_count": null,
"outputs": []
},
{
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"cell_type": "markdown",
"source": "# Plotting tool"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2020-12-01T14:55:21.091918Z",
"start_time": "2020-12-01T14:55:21.084891Z"
},
"cell_style": "split",
"trusted": true
},
"cell_type": "code",
"source": "from numpy import *\nfrom matplotlib import pyplot as plt\n\ndef display(f):\n plt.close()\n x = linspace(-2, 2)\n plt.plot(x, eval(f), label=f)\n plt.xlabel('x')\n plt.legend()\n plt.xlim([-2, 2])\n plt.show(block=False)\n ",
"execution_count": null,
"outputs": []
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2020-12-01T14:55:21.810453Z",
"start_time": "2020-12-01T14:55:21.804413Z"
},
"cell_style": "split",
"trusted": true
},
"cell_type": "code",
"source": "def myplot():\n while True:\n f = input('Enter a function of x:')\n display(f)\n rep = input('\\nDo you wish to draw another function? ([Y]/N) ? ')\n if rep.upper() == 'N':\n break",
"execution_count": null,
"outputs": []
},
{
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"cell_type": "markdown",
"source": "# Plotting tool"
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2020-12-01T14:55:36.100768Z",
"start_time": "2020-12-01T14:55:27.201838Z"
},
"trusted": true
},
"cell_type": "code",
"source": "myplot()",
"execution_count": null,
"outputs": []
},
{
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"cell_type": "markdown",
"source": "# Step #2: virtual environment"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "You need to create a minimal environment. We call the one for the tutorial myplot_env\n- Check your environments with ``conda env list``\n- Create your environment with ``conda create --no-default-packages -n myplot_env python``\n - ``no-default-packages`` ensures you just have things like ``python``, ``pip``, and ``setuptools``\n - ``python`` will install the latest stable distribution\n- Enter your environment with ``conda activate myplot_env``\n- Tips:\n - Don't use the python native ``venv`` command to create a venv if you have a conda distribution. It didn't work for me (isolation issues)."
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Source: https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html"
},
{
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"cell_type": "markdown",
"source": "# Step #3: check your code in the venv"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Make your code run in the venv\n- Does ``python myplot.py`` work?\n - *hello world* should.\n - *plot* should miss ``numpy`` and ``matplotlib``.\n- Do ``pip install packagename`` until it does.\n - ``conda`` and ``pip`` have not the same way to install packages. ``numpy`` is much more compact with ``pip install`` than with ``conda install``.\n - This is why you do ``pip`` (smaller footprint) inside a ``conda`` venv (easy to set).\n- Note that some devs usually start writing their code (step #1) directly inside the venv to avoid the ``pip`` trial and error.\n - Pro: no trial and error\n - Con: high probability to pollute your venv with useless packages"
},
{
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"cell_type": "markdown",
"source": "# Step #4: Create your executable"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "Create you executable in the venv\n- ``pip install pyinstaller`` (to ensure pyinstaller stays inside the venv)\n- ``pyinstaller -F -i favicon.ico myplot.py``\n - ``F``: creates a one file executable\n - Pros: one ``.exe`` file only (a directory full of files otherwise), smaller size.\n - Cons: slower to launch (need to virtually decompress a directory full of files)\n - ``-i favicon.ico``: embeds your favorite icon in the program\n- result is in the ``dist`` directory."
},
{
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"cell_type": "markdown",
"source": "# Step #5: Clean up (optional)"
},
{
"metadata": {},
"cell_type": "markdown",
"source": "- Leave the venv: ``conda deactivate``\n- Remove the environment: ``conda remove --name myplot_env --all``\n- Remove the ``build`` dir"
},
{
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"cell_type": "markdown",
"source": "# That's it!"
}
],
"metadata": {
"celltoolbar": "Slideshow",
"kernelspec": {
"name": "python3",
"display_name": "Python 3",
"language": "python"
},
"language_info": {
"name": "python",
"version": "3.7.7",
"mimetype": "text/x-python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"pygments_lexer": "ipython3",
"nbconvert_exporter": "python",
"file_extension": ".py"
},
"toc": {
"nav_menu": {},
"number_sections": false,
"sideBar": true,
"skip_h1_title": true,
"base_numbering": 1,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": false
},
"gist": {
"id": "",
"data": {
"description": "pyinstaller tutorial",
"public": true
}
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment