Python For Mac Anaconda



Once you have created an application that you regard as useful to the larger public, you probably want to package it as a distributable. This enables users to simply install your program on their system without having the hassle of setting up an environment with all dependency libraries that your app requires to run. These should all be packaged together with your program in the distributable package. On the Mac distibutables are often provided as apps compressed in disk images (.dmg files), on Windows they often are a single-file installer (.exe, .msi, etc). Distributables can make the life of people (especially the less tech-savvy ones) who want to use your program a lot easier.

Conda install -c anaconda spyder Description Spyder is a powerful scientific environment written in Python, for Python, and designed by and for scientists, engineers and data analysts. Spyder is a powerful scientific environment written in Python, for Python, and designed by and for scientists, engineers and data analysts. It features a unique combination of the advanced editing, analysis, debugging, and profiling functionality of a comprehensive development tool with the data exploration, interactive execution, deep inspection, and beautiful visualization capabilities of a.

Many programming languages offer out-of-the-box tools for creating distributables, but not Python, which is in its essence not designed to be packaged. Programs such as py2exe (for windows), py2app (for Mac) or PyInstaller (for both) have been created to get this job done, and even though they often do it well, they also frequently break down, spitting out cryptical error messages that in no way helped me solving the problems that they were bumping into. Especially when your package needs to contain more complex libraries such as PyQt, the chance of breakage increases dramatically.

Another promising candidate is pyqtdeploy but I found it really complex to set up when I gave it a try (although admittedly, I haven't really spent a lot of time on it yet). As I understand it, pyqtdeploy creates a distributable by building everything completely from source (even the python interpreter itself). It converts all python modules to C++ code, so that everything can be compiled to a native application. This makes it possible to also deploy your app to platforms such as Android and iOS. Of course, this is only useful if you use PyQt in your application to begin with, so for smaller, simpler apps using this method seems to be overkill.

I was curious if I could find another, very simple, solution for packaging Python apps and I found it in Anaconda (or Miniconda which is the slimmed down version). For those who don't know Anaconda: it is a science-focused Python distribution created by Continuum.io that has an extensive set of tools to install and manage Python packages (like pip, but better in my opinion). One of the other major strenghts of Anaconda is the easiness with which you can create and manage virtual environments. Each of these virtual environments should in fact be regarded as a small independent anaconda installation by itself. The biggest plus is that most of the libraries that Python apps depend on are contained in the environment; not only the Python interpreter itself, but also non-Python ones such as Qt, sqlite, OpenSSL, you name it. Anaconda environments are already isolated from the rest of the OS and only marginally depend on external libraries; often only low-level libraries that are provided by the OS itself. In a sense, Anaconda environments are already half-way being a distributable.

Below I describe how to perform the last step of transforming an Anaconda environment into a fully working Mac OS X app, and this is easier than you might think. As an example, I use my own experience of creating an app for the OpenSesame experiment builder with this method. Needless to say, you'll have to change all references to OpenSesame to ones applicable to your own project.

A small disclaimer before we start: This way of creating an app will work, but it probably violates all rules that Apple poses for an app to be allowed into the app store. If you want your app to eventually end up there, you will have to make sure it adheres to Apple's guidelines, regarding sandboxing, code signing, and so on. I have never tried passing the App Store review process with an app created the way I describe here, so I can't say at which points it violates the guidelines, but I highly doubt the app would be accepted without quite some extra work.

Create an Anaconda environment and add your app

When anaconda or miniconda is installed on your system, you should have access to the conda command from your terminal. You should be able to create a new environment like this:

Choose y when you are asked to install the listed packages. I am not going to dive into the specifics of creating virtual environments with conda (more about that can be found here), but suffice to say that the above command creates a new environment with the name OpenSesame (specified after the -n flag) and installs python and its dependencies as the only packages in it. If your program has more dependencies, this is how you can install them using conda.

The next step is to add your program/python module to the environment. You have two options for doing so.

The first option is to simply copy your home-cooked python module somewhere into the environment folder, preferably the root. Anaconda environments are located in the envs subfolder of your main anaconda folder, which in turn can usually be found inside your home folder. For example, if you have created an environment named MyEnv, you will find it at ~/anaconda/envs/MyEnv (or ~/miniconda/envs/MyEnv). Once you have copied the folder containing your program's files into this environment, you are done for this step.

The second option that is cleaner and more elegant (you wouldn't say I have a preference would you?) is to create a setup.py script for your app that, when run with python setup.py install, installs your program's componentes at the conventional places in the environment. Instructions on how to create such a setup script can be found in the Python documentation or here.

To get back to our OpenSesame example, a simplified version of its setup.py script looks like:

You can find the full version here if you'd rather see that.

The important variables here are packages, which contains the folders of your module that will be copied to the site-packages folder of python in your environment, and scripts which contains the files with which your program (or parts thereof) can be started (i.e. the entry point of your program). The files specified at scripts will be copied to the bin/ folder of the anaconda environment.

To give an example, the OpenSesame entry point script merely contains:

You might have noticed the .py extensions are missing from files that we specified at scripts. By specifying #!/usr/bin/env python at the very first line of the file, your OS recognizes it as a python file even if you leave away the .py extension.

Don't forget to activate your environment before you install your app. Otherwise your app will install into the main anaconda installation. You can activate environments by calling the source activate <environment-name> command. For example:

If all goes well, a [OpenSesame] label should be prepended in front of your terminal prompt. Now you can call:

to install everything. If you want to exit the virtual environment again, you can do so by simply calling

After this step, the environment plus your app are ready to be packaged into an OS X app.

Create the .app framework

You wouldn't know unless you are a (fanatic) terminal user, but a Mac OS X app is nothing more than a folder that has .app as extension. The internal structure and contents of this folder are bound to some specifications:

  1. One thing that always needs to be there is the Contents/MacOS folder which contains the script or executable file that starts your application. The name of this file should be the same as the one of your app, minus the .app extension.
  2. An Info.plist file, located at Contents/Info.plist, which contains extra information about the app (author, version, etc.), If this file is not present when the app is started for the first time, MacOS will create a default one for you, but it is so generic that it often leaves much to be desired.
  3. A Contents/Resources folder, which contains all other files your app depends on, such as images or sounds, but they can be virtually anything, such as a complete anaconda environment, as you will see.
Python For Mac Anaconda

So, the basic structure of our OpenSesame app looks like this:

We'll leave these two files (OpenSesame and Info.plist) empty for now.

Not to sound pedantic, but be sure to create the .app folder at a different location than inside the Anaconda environment you are going to package.

Copy the Anaconda environment

Now that you have the app skeleton all set up, you can copy the anaconda environment into it. You can copy the contents of the environment folder entirely to the Resources folder of your app. In our example case, I also named my virtual environment OpenSesame, which resulted in the command:

where app-output is the folder in which I created the app skeleton for the OpenSesame.app in this example. You can of course also just drag and drop all files using Finder if you like, although it skips hidden files and folders, so the safest way is to just copy everything using the cp command in the terminal (although hidden items are not really used in anaconda environments as far as I know).

If everything went ok, your app structure should look like this:

There might be some deviations, because a few conda packages can install some of their dependencies at the root level of the environment, or things have changed in conda versions that were released later than this article. Furthermore, the folder containing your apps modules should also be present if you have chosen option 1 of integrating your app into the environment (i.e. copy everything directly into the environment, instead of using setup script). Thus, if things look a little bit differently than shown above, don't fret: as long as you have copied all content of the target environment's folder, you should be ok.

Now everything is placed where it should be, there are two things left to do.

Create the app's entry script

Download Anaconda Mac

At this point, it is time to write the contents of the executable in Contents/MacOS, in this example case Contents/MacOS/OpenSesame. This will be a simple bash script that calls the Python interpreter inside the anaconda environment that you just copied, and passes it the path to the entry point of your program as an argument. So if you chose option one to integrate your program into the Anaconda environment, the contents should look (something) like this:

The second line simply saves the location of your Contents folder by going up a folder (we are in Contents/MacOS now). The third line calls the python interpreter inside the .app from this location, with your program's entry-point script as an argument. The $@ at the end of this line is supposed to pass all other command line arguments to your script as well, but this hasn't worked for me. Most likely OS X wraps extra arguments with a --args flag, but I'm not sure.

If you installed the app using a setup.py script, you should let this argument point to your entry script in the bin/ folder. In the context of our example OpenSesame app, this would become:

Of course you need to replace opensesame with the name of your program.

Don't forget to make the entry script executable by issuing the command

so in our example case that would be the command

from the folder in which OpenSesame.app is located.

You can already try out if it works, by double-clicking your app in finder, or starting the app from the command line by issuing the command

from the terminal, with the current working directory being te folder in which the .app is located. This is useful for debugging, for instance if your app seems to launch but closes shortly after with no further notification. When started from the terminal, any error output is printed there.

Python For Mac Anaconda

Create the contents of Info.plist

A Mac OS X app is required to have an Info.plist file, which contains extra information about the app, such as its version, author, and so on. There are a couple of fields that are mandatory, but a lot of them are optional. You'll do yourself a favor however to put as much information about your app in the Info.plist as you can. For instance, if you specify the file extensions that your app can handle (not mandatory), OS X will automatically let these filetypes be opened by your app if a user double clicks such files in Finder (although I have neither had much success with this: my app starts, but the file is not loaded. Probably this is because OS X works with events that signal a file needs to be opened, instead of passing the path simply as a command line argument on opening). If the extension is not unique to your app, it will appear in the list of apps that could open the file, if you click on it and select 'Open With' in Finder. Pretty neat.

Don't be fooled by the .plist extension; it is just an .xml file that you can open with any text editor. Here is what the one I generated for OpenSesame looks like:

Python For Mac Anaconda

Each configurable option consists of variable name between the <key> tags, and its value between the <string> tags. There are a lot of options (most of which have self-explanatory variable names), so I'm not going to elaborate on them any further here. You can find a full list of options and their descriptions at Apple's documentation site. The ones that you definitely want to specify are the entries that correctly identify your app (CFBundleName, CFBundleDisplayName, CFBundleVersion, CFBundleShortVersionString) and the ones that identify you as the author of the app (NSHumanReadableCopyright, CFBundleIdentifier). If you don't want the name of the executable to be the same as that of the app (I can't think of any reason), you can specify a different name with CFBundleExecutable. The final field that you probably want to specify is CFBundleIconFile, which specifies the path to your icon file (.icns) as resolved from the Resources folder. If you eventually want to get your app into the app store, it's a start to make sure that your icon has the required minimal resolution of 1024x1024px.

There is a python-based tool called biplist which makes generating and editing .plist files a lot easier, so that may be worth a look too.

Clean up (optional)

Of course, there are some files that we don't need when the anaconda environment is packaged inside our app, so the next step will be removing those files. This step is entirely optional. The risk of actually breaking things is quite large, because I'm not 100% certain that all files and folders I remove here are never needed (but this action never broke my apps though, so that might be regarded a small reassurance). Nevertheless, removing unnecessary item can reduce the size of your app quite a bit, so it is probably worth experimenting with.

Let's start with the /bin folder. If you navigate into this folder inside the Resources folder of the app, you will see that there are a lot of other apps and excutables there; some of which have a considerable file size. Generally you won't need the majority of the files you find here (except the ones necessary to run Python of course), but to be safe I usually leave most of them in there and just focus on the really large files which blow up the size of the app. If your app has Qt as a dependency, you are free to delete all the qt apps that you find in the bin folder (an .app inside in .app is completely useless), in addition to large non-app executables such as qmake, qdoc3, qt3to4.

Next, we are going to delete all files an folders that are only relevant when you are using anaconda to build Python modules or 'conda packages', which you probably are not going to do when the evironment is encapsulated in an app. Two of such folders are mkspecs (build information for qt) and include (C header files of modules present in the environment). The other one is conda-meta. If you remove these folders, you are left with

Possibly you could slim down your package even further, but that is up to you. The remaining files and folders probably are not really that large, so it's likely not the effort to spend too much time on this.

Le moment suprême

That's all there is to it. Double click the app in Finder and see if it works. If nothing happened, or you receive an error message, you can always start your app from the terminal and see if it prints any error message there:

Your app should now be up and running. I'm curious what you think of this transparent and easy, but very unconventional way of creating an app.

Why not create a script for all this?

Well, I have. You can find a (configurable and customizable) script that does everything described above (and more) on github. In the future, I hope to provide better documentation on its usage soon (famous last words...), but at the moment it is still evolving too quickly and changes a lot each time I work on it. You should therefore regard the script as a 'proof of concept' and working example than something that is directly ready to use.

Note

Using Anaconda in a commercial setting? You may need to use Anaconda Commercial Edition. If you have already purchased Commercial Edition, please proceed to the Authenticating Commercial Edition section after completing your installation here.

Haven’t purchased Commercial Edition yet? Visit https://anaconda.cloud/register to get started.

Python For Mac Anaconda

You can install Anaconda using either the graphical installer (“wizard”) or thecommand line (“manual”) instructions below. If you are unsure, choose the graphical install.

macOS graphical install¶

  1. Download the graphical macOS installer for your version of Python.

  2. RECOMMENDED: Verify data integrity with SHA-256.For more information on hashes, see What about cryptographic hash verification?

  3. Double-click the downloaded file and click continue to start the installation.

  4. Answer the prompts on the Introduction, Read Me, and License screens.

  5. Click the Install button to install Anaconda in your ~/opt directory (recommended):

  6. OR, click the Change Install Location button to install in another location (not recommended).

    On the Destination Select screen, select Install for me only.

    Note

    If you get the error message “You cannot install Anaconda in this location,” reselect Install for me only.

  7. Click the continue button.

  8. Optional: To install PyCharm for Anaconda, click on the link to https://www.anaconda.com/pycharm.

    Or to install Anaconda without PyCharm, click the Continue button.

  9. A successful installation displays the following screen:

  10. Verify your installation.

Using the command-line install¶

Use this method if you prefer to use a terminal window.

  1. In your browser, download the command-line version of themacOS installer for your system.

  2. RECOMMENDED: Verify data integrity with SHA-256.For more information on hash verification, see cryptographic hash validation.

    • Open a terminal and run the following:

    Note

    Replace /path/filename with your installation’s path and filename.

  3. Install for Python 3.7 or 2.7:

    • For Python 3.7 enter the following:

    • For Python 2.7, open the Terminal.app or iTerm2 terminal application and then enter the following:

    Note

    Include the bash command regardless of whether or not you are using the Bash shell.

    Note

    Replace ~/Downloads with your actual path and Anaconda3-2020.02-MacOSX-x86_64.sh with actual name of the file you downloaded.

  4. The installer prompts “In order to continue the installation process, please review the license agreement.”Click Enter to view the license terms.

  5. Scroll to the bottom of the license terms and enter yes to agree to them.

  6. The installer prompts you to Press Enter to confirm the location, Press CTRL-C to cancel the installationor specify an alternate installation directory. If you confirm the default location,it will display PREFIX=/home/<user>/anaconda<2or3> and continue the installation.

    Note

    Unlike the graphical install, installing the shell file will place it in ~/anaconda<2 or 3> by default,not ~/opt. This is due to limitations with installing .pkg files on macOS Catalina.

    Installation may take a few minutes to complete.

    Note

    We recommend you accept the default install location. Do not choose the path as /usr for theAnaconda/Miniconda installation.

  7. The installer prompts “Do you wish the installer to initialize Anaconda3by running conda init?” We recommend “yes”.

    Note

    If you enter “no”, then conda will not modify your shell scripts at all.In order to initialize after the installation process is done, first runsource<pathtoconda>/bin/activate and then run condainit.

    Note

    If you are on macOS Catalina, the new default shell is zsh.You will instead need to run source<pathtoconda>/bin/activatefollowed by condainitzsh.

  8. The installer displays “Thank you for installing Anaconda!”

  9. Optional: The installer describes the partnership between Anaconda and JetBrains andprovides a link to install PyCharm for Anaconda athttps://www.anaconda.com/pycharm.

  10. Close and open your terminal window for the Anaconda installation to take effect.

  11. To control whether or not each shell session has the base environmentactivated or not, run condaconfig--setauto_activate_baseFalseorTrue. To run conda from anywhere without having the base environmentactivated by default, use condaconfig--setauto_activate_baseFalse.This only works if you have run condainit first.

    Note

    condainit is available in conda versions 4.6.12 and later.

  12. Verify your installation.

What’s next?¶

Python Anaconda For Mac

Get started programming quickly with Anaconda in the Getting started with Anaconda guide.