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
Diffstat:
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.