Content and configuration for https://www.eamoncaddigan.net
git clone https://git.eamoncaddigan.net/www.eamoncaddigan.net.git
Log | Files | Refs | Submodules | README

commit 39faf5bf1d6067d165a97bff64adfa6c75af3ca3
parent 29f6c4f6b0ed778d75d899fa1b271dc42fe33008
Author: Eamon Caddigan <eamon.caddigan@gmail.com>
Date:   Tue,  1 Aug 2023 18:10:03 -0700

Short post with an Anaconda tip

Acontent/posts/conda-script/index.md | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+), 0 deletions(-)

diff --git a/content/posts/conda-script/index.md b/content/posts/conda-script/index.md @@ -0,0 +1,57 @@ +--- +title: "Running a Python script with Anaconda" +date: 2023-08-23T20:06:25-07:00 +draft: false +categories: +- Programming +- Data Science +--- + +I have a Python script that needs to be run from within a specific +[Anaconda](https://www.anaconda.com) environment (which I'll call +`environment_name`) for reasons that aren't relevant here. It was tricky to +get this working, so I figured it was worth a post. Here's what made this +challenging: + +* The script only works if it's actually run in a specific environment + (accessed by executing `conda activate environment_name`), it's not enough + to set the python path in the shebang[^shebang] +* I want to be able to run the script when I'm not in that environment, + or even when I'm not using Anaconda at all (which is usually the case) +* Activating an Anaconda environment in any shell script requires extra + steps + +The solution I landed on is to replace the typical shebang line with a block +of code that looks like this: + +```python +#! /bin/sh - +':' '''Describe the script here--this script just prints the Python version' +eval "$(conda shell.bash hook)" +conda activate environment_name +exec python3 -- "$0" "$@" +''' + +import sys +print("Hello from Python", sys.version) +``` + +This approach is not without weaknesses: + +* It (probably?) requires that `/bin/sh` be bash (or maybe just bash-like?), + which is not always the case; you might need to replace `/bin/sh` with the + full path to bash +* The script may need to be run as a specific user, I haven't checked +* The code looks ugly and interferes with code-highlighting +* It's certainly fragile in other ways I've yet to find + +I'm sharing it anyway because it did solve my problem, and I hope to save +somebody else the time it took me to figure this out. Or better yet, be told +the "right" way to do this from a Python/Anaconda expert. + +[^shebang]: The first line of most contemporary python scripts is +`#!/usr/bin/env python3`, which tells the shell to use python to execute the +rest of the script. Since Anaconda installs additional copies of Python, +sometimes it's enough to replace this with something like +`#!/home/username/anaconda3/envs/environment_name/bin/python3`, but that +didn't work here.