cli: Brew installed version doesn't work with plugins
Brew is listed as the recommended way of installing httpie on macOS. However, it doesn’t work with auth plugins.
For example, if you pip3 install requests-hawk
and then run http --help
hawk will not show as an auth type. If you pip3 install httpie-oauth
it will install httpie via pip as a dependency and overwrite the brew installed link in /usr/local/bin/http
and now all the plugins will show because it isn’t using the brew installed version.
I suggest changing the documentation to read pip3 install httpie
as the recommended method of installing on macOS.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 8
- Comments: 19 (15 by maintainers)
Commits related to this issue
- Add extra_site_dirs config option to solve Homebrew installed HTTPie not finding pip installed plugins (#566). — committed to matthew16550/httpie by matthew16550 6 years ago
In the meantime, maybe a note in the documentation around plugins saying “brew doesn’t work with plugins and to pip install httpie for plugin functionality” would save some headaches.
For what it’s worth and perhaps other users googling for an answer, installing a plugin worked fine for me like this:
Thanks https://github.com/jakubroztocil/httpie/issues/566#issuecomment-285210693
@rshurts you’re right. Plugin installation for Homebrew-based installs doesn’t work out of the box.
There are advantages to keeping Homebrew as the recommended method, though. It makes updates easy and the main package can depend on Python 3 (improved SSL support, etc.).
The ideal world solution would be to have all plugins available as Homebrew packages (
brew install httpie-oauth
) . But that would mean extra work for maintainers so not all plugins would end up in Homebrew.Using
pip
to install plugins looks like the easier way to go. To make it work with Hombrew, it would mean instructingpip
to use (currently)/usr/local/Cellar/httpie/0.9.8_2/libexec/lib/python3.6/site-packages
as the installation directory.But plugins installed there won’t survive HTTPie upgrades.
Perhaps it would be possible to tweak the Homebrew formula to makeallow HTTPie load installed plugins from, for example, the Homebrew Python 3
site-packages
(not sure if it’s permanent). Or from another location.…or some sort of custom plugin installer.
🎉 This feature is now publicly available in HTTPie for Terminal 3.0:
👉🏻 https://httpie.io/docs/cli/plugin-manager
We have finally landed
httpie plugins
interface, though the initial QA on brew is not yet completed. I’ll probably try to complete it within today or tomorrow and then close this ticket.From an outsiders look, this issue seem like a problem for the people who are actually maintaing plugins rather than the httpie itself. If an X tool is installed through Y platform, then it is fair to expect to get all the plugins to be installed in the same manner. So if the plugin maintainers also package their plugins for brew to support those users, that would be the general and (somewhat) unconvient solution (which is what we currently have with all those
python-<xxx>
packages on distro indexes).Possible solutions
If we turn the other way around, and try to offer a more user friendly solution on the httpie side as far as I can tell there are 2 options that I can think of:
–interpreter (less human friendly & more error prone)
Since we don’t have any actual chance of knowing what is the primary python environment they have installed the plugin (we can only assume it is the global one, or whatever
python
resolves [which might python2 or python3] on the currentPATH
), we need an explicit way for the users to pass a Python environment.The general solution that I’ve seen (e.g on pyperf/pyperformance) for this sort of problem is that you pass an
--interpreter
option with the interpreter you wantpython3
or.venv/bin/python
and it resolves that name and find’s the executable (and then retrieves the site-packages to search through). Which is somewhat esoteric and very unfriendly. Though it might became a little bit less unfriendly by allowing this to be a global option:2 advantages over directly pointing to
site-packages
:interpreter.version_info == sys.version_info
)Advantages over #1108:
The implementation would be simple; and works by firing the new python interpreter, retrieving the location for the site-packages and temporarily include them on the entry-point search.
httpie plugin <cmd> <plugin> (more user friendly)
A more user friendlier, but rather complex solution is to
httpie
to manage it’s own plugins. It will be simply a wrapper around thepip
, and manage a custom plugin-base on it’s own. This can either install plugins globally to thehttpie
environment (so they be accessed outside ofhttpie
, e.grequests-hawk
) or it can install them to an isolated place so the normal site package loaders don’t have access to them. (both are fine options IMO)Being able to directly install plugins is something that this interface can delegate to
pip
under the hood (which is guaranteed to be bundled from 3.4+, but distros like debian is a bit problematic about it [can be solvable by explicitly depending on python-pip]).Example scenerio;
Advantages over the
--interpreter
:httpie plugins upgrade
)enable
/disable
specific pluginsIndeed. For regular installations, both options should work (
pip
+httpie plugins install
) withhttpie plugins install
being the preferred one on the documentation.What I meant by
md5(python-identifier)
was not exactly the python version, but rather themd5()
of the path to the site-packages, or to the python interpreter (sys.executable
). There are 2 reasons for that:httpie
’s installed accross multiple virtual environments with the same python version but different set of plugins, this way since they will all have different paths to their executables thepython-identifier
will be different and the isolation will stay in placeYep, this will be taken care of. Since
httpie
itself is actually a dependency ofhttpie
(as a package), we will already have it and I assume it should be possible for pip to recognize it as present so it won’t bother installing it. Since it is also recognizing it, and it’s metadatapip
will find the correct version of the plugin that fits all dependency constraints (e.ghttpie>=current_version
).Agreed.
What do you mean by
define lookup order
? If it is for the installation,pip
should do the ordering of dependency graph, but if it is something else not sure.As I mentioned in the proposal, we will temporarily make the
pkg_resources
to recognize the plugins directory as a location for site packages and remove it afterwards. It should not affect anything in terms of global state / other imports, only plugins.Makes sense (as well as
plugins enable
/plugins disable
).One important thing to note here is that, we will need to have
write
access to the followinghttpie
directory. If I am not mistaken, the defaulthome
interface forsnap
does not support dot-files (hidden):(from https://snapcraft.io/docs/home-interface)
There seems to be some discussions with workarounds, https://forum.snapcraft.io/t/accessing-xdg-config-home-of-the-host/9780/10, but I am not reliable are them (needs further research).
Managing plugins through an HTTPie-provided command looks like the best solution all things considered.
httpie
commandCurrently, the HTTPie package doesn’t come with a command called
httpie
(onlyhttp
andhttps
).At one point, I was going to add it for sessions management but then decided against it (https://github.com/httpie/httpie/commit/5cc5b13555f359712e0c5784bebdb091c34e6c82) to keep the project simple.
Now, however, with this plugin management use case (and possible upcoming integration with our new companion web & desktop app that we’re working on) it makes sense to revisit the idea.
A new command is much cleaner than trying to enrich the existing ones, where we already have quite complex args parsing logic due to our “DSL”, and as @isidentical pointed out, it doesn’t really belong there anyway.
The new command should only be used for management, not for making requests. When invoked without any args or with args that are invalid (or maybe even better — they look like the user is trying to make a request), we should instruct the user to use
http [args]
orhttps [args]
(this will actually improve the onboarding experience as well because the project/command name mismatch can be confusing and some users will inevitably typehttpie
post-installation, so this will give them a useful hint).So, with a custom plugin install command, we can continue to use
pip
for plugins + deps installation (under the hood) andpkg_resources
for installed plugin lookup and loading.Existing plugins won’t require any changes except for updating their installation instructions. That will be optional since I think we should continue to load plugins from the main
site-packages
as well.I really like the idea of generating a site-packages-like directory for plugins for each interpreter in
~/.config/httpie/plugins/<md5(python-identifier)>/...
. The isolation is important to keep httpie’s development simple, among other things.But I think a Python installation’s identity shouldn’t change when it’s just upgraded to a new version (e.g. Python 3.6.10 → 3.6.11). Because without that, the user will lose plugins after each Python upgrade. Not sure how to approach that, though.
We could also consider keeping the desired plugin list in the config file and allowing the user to quickly re-install the missing ones.
Some more thoughts:
site-packages
installation location.requests
are installed there it shouldn’t be touched by httpie).httpie plugins search
, etc. (plugin names correspond to their PyPi names).