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 Greg Couch, 4 years ago

Milestone: 1.3

Plan to get this into 1.3.

comment:2 by Greg Couch, 4 years ago

Milestone: 1.31.4

Needs to many changes to internals to be done before 1.3 release.

comment:3 by Zach Pearson, 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:4 by Greg Couch, 3 years ago

Milestone: 1.41.5

Won't make 1.4.

comment:5 by Tom Goddard, 3 years ago

Cc: Zach Pearson added

comment:6 by Zach Pearson, 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 Zach Pearson, 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.

comment:8 by Zach Pearson, 3 years ago

I've tested the module I made on macOS and Windows and it seems to work!

in reply to:  9 ; comment:9 by goddard@…, 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 Zach Pearson, 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:11 by Zach Pearson, 3 years ago

Yup, "--user" was the key.

comment:12 by pett, 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.

comment:13 by Zach Pearson, 3 years ago

No, but should it be?

"toolshed install --pip"?
vs
"pip install"?

in reply to:  14 ; comment:14 by goddard@…, 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 Zach Pearson, 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.

Last edited 3 years ago by Zach Pearson (previous) (diff)

in reply to:  16 ; comment:16 by goddard@…, 3 years ago

Fantastic!  Thanks!

comment:17 by pett, 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.

Last edited 3 years ago by pett (previous) (diff)

comment:18 by pett, 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".

in reply to:  19 ; comment:19 by goddard@…, 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.

comment:20 by Zach Pearson, 3 years ago

Resolution: fixed
Status: assignedclosed

Added a 'devel pip' alias

Note: See TracTickets for help on using tickets.