Opened 4 years ago
Closed 3 years ago
#4762 closed enhancement (fixed)
Install PyPi packages with a ChimeraX command
Reported by: | Tom Goddard | Owned by: | Greg Couch |
---|---|---|---|
Priority: | moderate | Milestone: | 1.5 |
Component: | Core | Version: | |
Keywords: | Cc: | pett, Zach Pearson | |
Blocked By: | Blocking: | ||
Notify when closed: | Platform: | all | |
Project: | ChimeraX |
Description
For developers writing ChimeraX Python code it would be convenient if a ChimeraX command like "pip install pandas" could install extra PyPi packages they need.
Here is an email discussion of the trouble that arises trying to install PyPi packages into ChimeraX on Windows:
https://plato.cgl.ucsf.edu/pipermail/chimerax-users/2021-June/002297.html
While it seems like adding such command would be trivial, unfortunately I recall the Python pip module does not have a function API to install packages! Seem incredibly poorly designed only to work as a script for the pip shell command. But I also recall some additional PyPi packages adds the pip APIs.
Change History (20)
comment:1 by , 4 years ago
Milestone: | → 1.3 |
---|
comment:2 by , 4 years ago
Milestone: | 1.3 → 1.4 |
---|
Needs to many changes to internals to be done before 1.3 release.
comment:3 by , 3 years ago
I found if I opened the shell tool I was able to pip install --upgrade pip, but the original ticket references Windows. I'll try the same command on Windows and see if it puts files in the right place. If that's the case then that could be one way to script it.
comment:5 by , 3 years ago
Cc: | added |
---|
comment:6 by , 3 years ago
I found that it wasn't too hard to implement this with a subprocess based approach. The key is calling subprocess with sys.executable
rather than python3
, because the former will choose ChimeraX's Python and the latter will choose the system Python.
Tom suggested using pip-api, a package that claims to provide an importable pip API. I elected not to go this route because in the end, that package also just calls subprocess to invoke the pip command line. It also does some magic to divine where pip is installed using os.environ.get("PIPAPI_PYTHON_LOCATION"), falling back to sys.executable if that env var isn't acceptable.
I wanted more control over what a user could do, the behavior of pip, and a smaller code surface.
comment:7 by , 3 years ago
It would be an interesting experiment to distribute a very minimal ChimeraX on macOS and install those pesky platform specific dependencies on first start rather than trying to make a universal build.
follow-up: 9 comment:9 by , 3 years ago
Does it install the PyPi package in the ChimeraX application site-packages or in the user directory (ie with pip option "--user")? I'm not sure what we want it to do by default, but probably the user area since that is where Toolshed puts everything it installs I think.
comment:10 by , 3 years ago
From what I can tell it goes to the ChimeraX site-packages directory, but I agree with you that the user directory is probably better. Let me test inserting the "--user" flag and see what happens.
comment:12 by , 3 years ago
Nice! Is it a "toolshed" subcommand?
Also, "--user" is definitely the way to go because sometimes the app isn't writable by non-privileged users.
follow-up: 14 comment:14 by , 3 years ago
I kind of like "pip install pandas" as the ChimeraX command -- that was the original idea in the ticket description for the command name. The current "toolshed install" command syntax is toolshed install bundle-name [ version ] [ noDeps true | false ] It seems a bit strange to use "toolshed install" for PyPi since nothing is coming from Toolshed and it isn't installing a bundle with a bundle_info.xml. So I think the command "pip install" still makes more sense to me.
comment:15 by , 3 years ago
That's how it is now. You can do
pip {install, uninstall, list, check, show, search, debug}
, and you've got two flags: upgrade
and verbose
.
If you can think of anything else useful let me know.
comment:17 by , 3 years ago
In this case I agree. For Zach's benefit, the issues/advantages/disadvantages involved when choosing a new command vs. a subcommand are:
New command:
- Not closely related to an existing command
- Might be difficult to remember/discover as a subcommand of an existing command
Subcommand:
- Fewer top-level commands makes command index less unwieldy and can aid discovery
- Is something that users of the main command would frequently be interested in doing, and they would find out about by reading the main command help
- Is something users would naturally consider as part of the main command functionality
This new command has elements from both the above, but is probably distinct enough to justify its own command.
comment:18 by , 3 years ago
If it were going to be a subcommand, it would actually most naturally be a subcommand of "devel" rather than "toolshed". BTW, it is trivially easy to make it a subcommand of devel simply by naming the command "devel pip" rather than just "pip". I kind of favor "devel pip" actually, but wouldn't die if it remained "pip".
follow-up: 19 comment:19 by , 3 years ago
For a fair number of commands we make both a top level command and a subcommand, so both "pip install" and "devel pip install" where one is just an alias of the other. For example there is a "vr on" command and a "device vr on" command. In the documentation it is then grouped with other "device" commands, like "device webcam" or "device snav" (space navigator 3d mouse). I think probably "pip" and "devel pip" is a case where allowing both command names makes sense.
Plan to get this into 1.3.