HTTPie: A cURL-like tool for humans
github.com
github.com
That said, there is a broader problem of "hard-to-remember command-line flags" which I have personally solved using snippet management (I use notational velocity or command history, whichever is handiest).
There is no doubt httpie's interface is a lot better, but it creates another problem (again, which is somewhat universal) of installing, learning and remembering to use a new tool. This is a non-trivial problem that is a key concern for anyone evaluating a new tool, and it's a problem that only really gets solved with ubiquity.
Finally, an observation that so many of our "traditional" command line tools pay no attention to usability because, at least back in the day, the problem they solved was hard. People had a choice: either put up with an (admittedly) bad interface or write their own version in C. The individual cost of learning a bad interface outweighed the cost of rewriting the tool, and so standard tools were born.
And now, decades later, new generations are stuck having to learn needlessly obtuse interfaces to standard tools. We have a situation where newcomers pay the cost of developer UI laziness in perpetuity. This is, of course, a terrible outcome and it's projects like this one that are trying to change it.
So I applaud the effort and hope it catches on, become ubiquitous, and I can take the curl and wget snippets out of NV.
This was a warning of a hazard to navigation, when a more diligent effort to remove the hazard is called for.
Ok, young one, here's the thing. If you see a problem like this then file a bug. Ideally write a test case. And if you're an overachiever, dig into the code and fix it. Any bug in an http client that reposts data is incredibly serious, and needs to be fixed.
The other value in doing this is that you don't spread Fear, Uncertainty, and Doubt - or FUD as it is often referred to. FUD is usually ascribed to big companies trying to discourage using a competitors product, but it can also be spread by the ignorant or misinformed inadvertantly. No offense, but I think that's the case in this case, because Python is not a niche language, it's used (and it's http libraries are used) by a lot of people, and the error mode you describe is very, very serious.
I did report this to the API maintainers, who couldn't make heads or tails of it. I didn't file a Python bug because I honestly don't think Python is the problem.
But you are right, it is more responsible to pursue this until fixed rather than raise warnings.
That's totally false. libwww-perl was created 17 years ago and predates curl by a few years. There's nothing new about capable scripting languages and Unix.
"Learn VIM essentials in this blog post!" "Never bother reading 'man curl'!" "Learn the basics of C in three easy steps!"
Sometimes HN feels like a lifestyle magazine for people who dream of being PG.
EDIT: Don't get me wrong, I too dream of having the same succes as PG. Why else would I be writing here?
In other words: this is a style change rather than a productivity gain. And the superiority of the style is not obvious - unless you just HATE the style of existing tools and need to be set apart.
Most humans don't operate the command line or write scripts to begin with. Those who do, usually can handle wget "http://foo/bar. It took me all of a few seconds to start using wget and all of 10 minutes to have access to fancier features. (But the truth is that a certain level of complexity really just wants a script rather than ad hoc commands).
So here is a new tool, and it looks nice. But it doesn't at all relieve me from having to learn syntax and conventions - I still have to go to a doc/manpage and read that same kind of technical prose. So the only effective difference is that now I am using different punctuation, like @filename and -b. But the use of this "@" character is not really consistent with anything else.
So the tool is fine and I am sure people will use it but the competitive advantage is incredibly thin and the project smacks of NIH.
If curl and wget are not for humans then what are they for? People who do not have that magical design sensibility. Lame code-monkeys without vision, who are not creative and different. Soulless agents of the man.
This emphasis on branding over substance irks me quite a bit.
I'm not a huge fan of cURL, but most people who use cURL don't use the command line either. They use the cURL library and access that functionality through a high level language (PHP, C, C++, whatever).
Here's some sample curl client code in PHP.
$c = curl_init("https://someurl/some/api");
$msg = /* some data here */
$opts = array(
CURLOPT_POST=>TRUE,
CURLOPT_USERPWD=>"<password string>",
CURLOPT_HTTPHEADER=>array("Content-type: application/json"),
CURLOPT_POSTFIELDS=>$msg,
CURLOPT_SSL_VERIFYPEER=>FALSE,
CURLOPT_RETURNTRANSFER=>TRUE
);
curl_setopt_array($c, $opts);
$d = curl_exec($c);
curl_close($c);
Every option in that ugly argument array corresponds directly to a commandline option.I completely agree on cURL's design though. It's painfully obvious when working with the cURL bindings in PHP that it didn't have much thought put in to adapting it to PHP's constraints and is essentially just the command line client in a "nice" wrapper. It ends up being a huge pain to work with.
Rather than admit that even incremental usability improvements are not only useful, but continue to pay dividends long after the tool is produced, you lambast the author and the effort.
Not cool.
P.S. You should watch Bret Victor again, talking about how much easier it is to crush an idea than to support it and nurture it. http://vimeo.com/36579366
If this tool actually didn't require me to go to a man page and read lots of flags (.... exactly like every other tool) then I might be more enthusiastic about its advantages. But I don't see advantages. I just see yet another tool. Well, that's fine... use what you want. But I don't agree that it is superior in any clear way, and that's really all I said.
People who are really capable can handle and learn from critique and don't require constant sugarcoating because their minds are more at the level of problem solving than ego defense.
http POST http://localhost:3000/person/create name="James"
The "for humans" bit signifies the author has taken care to simplify the interface for practical use, rather than for shell scripting.I have a text file with examples of testing different kinds of API calls w/ curl, and I have to refer to it all the time because the syntax is so easy to get wrong if I just type it out. I've also had to waste lots of time supporting other developers using our API, who got tangled up in the curl syntax in the examples I provide them.
That said, I think it's a stretch to call this mistake of mine an ad hominem attack. It doesn't fit my normal understanding of such an attack - there was no name calling, etc. And certainly I didn't accuse him of an ad hominem.
Thus the GP's point stands that this program offers little more than a stylistic change. And a bit of pretty printing, which you could (ideally) pipe into some syntax highlighting script or an editor to get the same effect.
Don't read the docs with this thing, for example, and you'd wonder why it defaults to JSON encoding and not the default HTTP POST format. And so the 'simple' version is now dependent on a trend and not the HTTP standard. In fact, even with a modern API I don't recall ever having to serialise my data before posting it. So why this?
That's a few minutes wasted on RTFM already. What else will there be?
JSON encoding is a sensible default these days for a tool to be used by humans, though I agree there's a good "principle of least surprise" argument for defaulting to plain HTTP POST. It would also be nice if it had a setting between "interpret response as JSON" and "uglify the response", but OTOH those additional formats are good opportunities for user-contributed patches.
Interestingly enough, people seem to search for curl tutorials much more than wget: http://www.google.com/trends/?q=curl+tutorial,+wget+tutorial...
Having something that makes life easier with less complication IS what tools are all about. That's called evolution. Why have the web when you could have gopher? Because it's _better_, even if you can 'accomplish the same things.'
If you are sending complex JSON, it's probably stored in a file or it's the output of another program:
http PUT httpbin.org/put @/data/test.json
http -b localhost:8888/couchdb/ | http PUT httpbin.org/put echo '{"foo": "bar"}' | http url
The reason for having the simplified one is that it's less verbose and usually doesn't even require you to quote it: http url foo=barcurl -X PUT -d @data/test.json httpbin.org/put
It also has the advantage that it supports all the options you might ever need, for example http authentication and proxies are often useful.
Requests and urllib3 have a long way to go to be complete competitors with cURL.
P.S. Good job nonetheless. Seems like a good idea to make a specialized HTTP CLI client for JSON/RESTful services.
[Edit: removed HN snarky comment]
(e.g. Stripe and others document their API in terms of curl commands: https://stripe.com/docs/api.)
I do wish the curl UI was better, but I can't see it being trivially replaced. (It's a similar issue with git: bad UI, but every git question and answer is described in terms of the CLI, so even if you prefer a GUI client, say, you still need to be able to formulate your problem in CLI terms for anyone on stackoverflow to understand you.)
It simply wraps curl(1), so all of the familiar arguments and recipes continue to work just fine, as well.
I tried to come up with syntax that would make the most common tasks (i.e., sending JSON objects, submitting forms, setting headers, etc) as easy as possible and also feel "natural". The reason for the chosen style is that it quite corresponds to the actual HTTP request being sent. For example, if you want to send a PATCH request with a custom header and a form field data:
PATCH /patch HTTP/1.1
X-API-Token: 123
Host: httpbin.org
Content-Type: application/x-www-form-urlencoded; charset=utf-8
foo=bar
You can simply copy the header (X-API-Token: 123) and the data (foo=bar) and paste it to the terminal: http --form PATCH httpbin.org/post X-API-Token:123 foo=bar
It's not as obvious as '--request PATCH --header X-API-Token:123 --form foo=bar', but on the other hand, the command doesn't include almost anything that wouldn't become part of the actual request, which makes it short and easy to focus on what's important.I suggest you add an option where you can start off with a bare request.
Is there a way to have it construct the query string when you are doing a GET request? Also is there a way to have it construct a query string when you have a JSON or form body? Might be something to add below the description of items, as something that doesn't fit into that list but is related. Perhaps -q page=2 -q rpp=20 would be a good way of saying it.
Good point, I'll add it to the README.
> Is there a way to have it construct the query string [...]
Not yet, but it's being already discussed here:
Apple discovered that words like "usability" and "human" are very powerful ways of framing competing products as unusable garbage not fit for human consumption. And they worked very hard and were very successful at fitting these words to their brand. This cuts the legs off any competing marketing. If you were a competitor the best you could say to this was something like "we have more games" or "we are cheaper" or "we have higher clock speeds" or even "you have more choice." Meanwhile the audience glazed over and felt threatened. Apple told the same audience that actually they were better than those hobbyist losers wasting all their time because they had bigger issues to worry about, they were discerning and frankly they were cooler.
Marketing is a high art and Apple is sitting on top of huge mountains of money after fighting Total War for decades. Good for them.
When it comes to evaluating libraries and command line tools, invoking the words 'human' and 'usable' still indicates that the developers and users of the old one are losers focused on irrelevancies, with huge amounts of time to waste on tools that are just plain unusable for anybody and unfit for human consumption.
Anyhow, there is more to this UX than just what is nice to use.
By the way, the "Power Users" term is used to marginalize people who are willing to learn to use their tools. The results of using this term in this way have IMHO slowed the growth of the computing industry.
https://chrome.google.com/webstore/detail/aejoelaoggembcahag...
I'm working on adding conversion to/from cURL and wget commands, which could be helpful when working with APIs that are documented with cURL examples.
It costs $2, but I'll give anyone who asks (well, up to 50 people at least) a free copy - my contact info is in my profile.
1. http://itunes.apple.com/us/app/graphicalhttpclient/id4330958...
This tool doesn't really solve any of my actual problems. YMMV. It's less a cURL replacement than a web API invocation tool.
#!/bin/sh
resource="$1"
shift
declare -a post
while [ "$1" ]; do
post=("${post[@]}" "-F" "$1")
shift
done
if [ -z "${API_BASE:=}" ]; then
API_BASE=http://localhost:3000/api/v1/
echo "No API_BASE set. Using $API_BASE."
fi
verbose=""
[ -n "$API_VERBOSE" ] && verbose="-v"
if [ -z "${API_COOKIES:=}" ]; then
cookies=~/.api.cookies
else
cookies="$API_COOKIES"
fi
curl -0 -k -s -S $verbose -b "$cookies" -c "$cookies" -X POST "${post[@]}" "${API_BASE}${resource}"OT: Is there an Emacs package that can do interactive invocation of http? Like having a text buffer to hold all the urls. Hitting Ctrl-E on a url to invoke it, and display the http response headers and result on separate buffers.
What are the use cases where curl is more suitable than phantomjs or selenium?
How about the various mail clients, office products, ftp clients, torrent clients & servers, programming languages, power drills, clothing lines, gasoline engines, kitchen knives and so on?
Tools are about innovation. Standards are about locking down feature sets so that tools can interact in a common way. The whole point of the xkcd comic is that too many standards makes it difficult to make tools, and adding yet another one-standard-to-rule-them-all usually backfires.
node -e require('request')('http://www.asdf.com/').pipe(process.stdout)