index.md (2200B)
1 --- 2 title: "Running a Python script with Anaconda" 3 date: 2023-08-23T20:06:25-07:00 4 draft: false 5 categories: 6 - Programming 7 - Data Science 8 --- 9 10 I have a Python script that needs to be run from within a specific 11 [Anaconda](https://www.anaconda.com) environment (which I'll call 12 `environment_name`) for reasons that aren't relevant here. It was tricky to 13 get this working, so I figured it was worth a post. Here's what made this 14 challenging: 15 16 * The script only works if it's actually run in a specific environment 17 (accessed by executing `conda activate environment_name`), it's not enough 18 to set the python path in the shebang[^shebang] 19 * I want to be able to run the script when I'm not in that environment, 20 or even when I'm not using Anaconda at all (which is usually the case) 21 * Activating an Anaconda environment in any shell script requires extra 22 steps 23 24 The solution I landed on is to replace the typical shebang line with a block 25 of code that looks like this: 26 27 ```python 28 #! /bin/sh - 29 ':' '''Describe the script here--this script just prints the Python version' 30 eval "$(conda shell.bash hook)" 31 conda activate environment_name 32 exec python3 -- "$0" "$@" 33 ''' 34 35 import sys 36 print("Hello from Python", sys.version) 37 ``` 38 39 This approach is not without weaknesses: 40 41 * It (probably?) requires that `/bin/sh` be bash (or maybe just bash-like?), 42 which is not always the case; you might need to replace `/bin/sh` with the 43 full path to bash 44 * The script may need to be run as a specific user, I haven't checked 45 * The code looks ugly and interferes with code-highlighting 46 * It's certainly fragile in other ways I've yet to find 47 48 I'm sharing it anyway because it did solve my problem, and I hope to save 49 somebody else the time it took me to figure this out. Or better yet, be told 50 the "right" way to do this from a Python/Anaconda expert. 51 52 [^shebang]: The first line of most contemporary python scripts is 53 `#!/usr/bin/env python3`, which tells the shell to use python to execute the 54 rest of the script. Since Anaconda installs additional copies of Python, 55 sometimes it's enough to replace this with something like 56 `#!/home/username/anaconda3/envs/environment_name/bin/python3`, but that 57 didn't work here.