Skip to content

tlambert03/conda-bundler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

conda-bundler

This script creates Mac OS X apps from a pip- or conda-installable package. The resulting app includes a complete conda environment and is NOT frozen (as would be created with something like pyinstaller).

The inspiration (and all of the credit) for this strategy comes from this blog post by Daniel Schreij, where he describes using this approach to bundle the OpenSesame app. See also his scripts on github.

The main difference between this package and Daniel's is that this one has no project-specific code in it and does not depend on biplist or dmgbuild. It has been generalized so that it can bundle any package(s) that can be pip installed. For instance, the following will create a bundled version of napari, a fast n-dimensional image viewer:

python bundle_osx.py napari

It is also fully self-contained, and requires no pre-existing conda environment. As such, it can be run on continuous integration platforms and will download all necessary conda and pip resources to build a Mac app given the name of a pip package.

Pros & Cons of this approach

As Daniel points out in his blog post and script readme there are a few pros and cons to this approach:

Pros

  • The resulting app will not be frozen, making it easier to maintain, update, and extend (for instance, to add plugins or other packages after bundling)
  • The bundled environment will behave much more like your development environment. Whereas pyinstaller dynamically analyzes your program and includes only the compiled bytecode and libraries required to run the program, this approach literally copies a complete conda environment into the Mac .app/Contents/Resources folder.

Cons

  • This is a rather unconventional way of bundling an app, and probably would not comply with Apple's guidelines for app packges. As such, it would likely be difficult to get an app like this into the app store, and your users will probably always see the scary "This app cannot be opened because the developer cannot be verified" message. To open the program, they will need to go into Preferences > Security and explicitly allow the app.
  • This creates much larger apps than pyinstaller.

Usage

Examples

Basic usage:

python bundle_osx.py napari

Include an app icon:

python bundle_osx.py napari -i path/to/icon.icns

Bundle an app using something other than the main pip package, such as the default branch of a git repository:

python bundle_osx.py napari --pip-install git+https://github.com/napari/napari.git

Bundle an app then run a quick program or test prior to code signing and DMG formation

python bundle_osx.py napari --test "napari --info"

Bundle together multiple pip installable apps into a custom app package:

python bundle_osx.py myapp --pip-install numpy scipy matplotlib

⚠️ TODO: there still needs to be a main "entry point" script... so this particular example wouldn't be that useful. Will need to add an --entry-point argument to bundle_osx.py in order for this type of thing to be useful.

Help

$ python bundle_osx.py --help

usage: bundle_osx.py [-h] [-y] [-i] [--distpath] [--buildpath] [--py] [--nodmg]
    [--pip-install [[...]]] [--conda-include [[...]]] [--conda-exclude [[...]]]
    [--log-level] [--clean] app_name

positional arguments:
  app_name              Name of app to bundle. If '--pip-install' is not
                        specified, this name is also assumed to be a
                        pip-installable package.

optional arguments:
  -h, --help            show this help message and exit
  -y, --noconfirm       Replace existing app and resources without asking
                        for confirmation
  -d, --nodmg           Do not package app into .dmg file.  By default a
                        DMG will be created
  -i PATH, --icon PATH  Icon file (in .icns format) for the bundle.
  --distpath PATH       Where to put the bundled app (default: ./dist)
  --buildpath PATH      Where to put build resources (default: ./build)
  --py VERSION          Python version to bundle. (default 3.8)
  --pip-install [ ]     Install these pip packages. Multiple arguments
                        accepted as would be passed to pip install. If not
                        provided, will attempt to `pip install <app_name>`
                        using `app_name` argument. If '--pip-install' IS
                        provided, then 'app_name' will NOT be installed
                        unless explicitly included in this list.
  --conda-include [ ]   directories in conda environment to include when
                        bundling
  --conda-exclude [ ]   glob patterns (from base conda environment) to
                        exclude when bundling
  --cert-name KEY       Optional name of certificate in keychain with which
                        to sign app. By default, uses ad-hoc code signing.
                        Pass "" to skip signing altogether.
  --test [ [ ...]]      Optional test commands to run after app bundling,
                        but before code signing and dmg formation.
  --log-level LEVEL     Amount of detail in build-time console messages.
                        may be one of TRACE, DEBUG, INFO, WARN, ERROR,
                        CRITICAL (default: WARN)
  --clean               Delete all folders created by this bundler, then exit.
  --make-dmg APP_PATH   Bundle prebuilt .app into a DMG, then exit.

About

scripts to convert conda environments into bundled apps

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages