Two years ago

What’s new in HTTPie for Terminal 3.0

Nested JSON in HTTPie

It’s hard to believe it’s been almost ten years since HTTPie for Terminal’s initial commit. Seeing the result of scratching our own API itch getting adopted by developers across the world and becoming the most popular API tool GitHub with 50K+ stars has been an incredible experience.

Since then, we have been working enthusiastically to provide the best user experience for anyone working with APIs and, as of recently, growing HTTPie into a comprehensive API development platform accessible from Terminal, Web & Desktop, and Mobile. Today, we are thrilled to announce the 3.0 release of HTTPie for Terminal.

Our fantastic community has been providing thoughtful feedback over the years. And for 3.0, we focused on some of the most requested features of all time. Let us take you on a tour of the new features 👇

Summary

🌲 Nested JSON HTTPie language extended for crafting complex JSON structures.

🔌 Plugin manager robust handling of plugin installation.

⏱️ Response metadata a new built-in way to display response metrics.

🚀 Speed-ups 30–250% speed-ups over different areas.

🎨 Improved UI/UX unified Pie theme, improved stdin handling, and better errors.

Other features bearer auth, repeated headers, prompted session passwords, headers & params from files, effortless URL-to-command conversion, JSON types with forms, and auto-streaming.

🪲 Bug fixes extinguished and regression-test-covered.

♥️ Community contributions dozens of amazing people have contributed to making this the best HTTPie release ever.


💡 For the complete adventure, don’t forget to hover over the code blocks and press the ‘Run’ button to see their actual results. We created a Docker environment for you, so it’s the real thing. Feel free to modify the commands and explore the new functionality.

🌲 Nested JSON

Have you ever wondered whether the simplicity of the existing HTTPie request language could meet with the power of nesting? This was a long journey, but ultimately, we embedded our mini path nesting format into the request language.

We designed it to offer the highest functionality with the best user experience possible. For that, we took an existing format (namely, HTML JSON form), and built our specification on top of it:

$ http pie.dev/post \
  platform[name]=HTTPie \
  platform[mission]='Make APIs simple and intuitive' \
  platform[homepage]=httpie.io \
  platform[stars]:=54000 \
  platform[apps][]=Terminal \
  platform[apps][]=Desktop \
  platform[apps][]=Web \
  platform[apps][]=Mobile
Run
{
    "platform": {
        "name": "HTTPie",
        "mission": "Make APIs simple and intuitive",
        "homepage": "httpie.io",
        "stars": 54000,
        "apps": [
            "Terminal",
            "Desktop",
            "Web",
            "Mobile"
        ]
    }
}

We focused on keeping the experience pleasant even when the user makes errors, which made us treat this as a complete language and implement small productivity boosters all around.

For example, when typing all these structures on the terminal, if you happen to make a typo, not only do we show you where it occurs, but we also tell you how to possibly fix it:

$ http pie.dev/post data[foo][baar]]baz[:=2
HTTPie Syntax Error: Expecting '['
data[foo][baar]]baz[
               ^

Another time-saver is object-level type safety, which prevents you from implicitly creating an ill-formatted JSON object:

$ http pie.dev/post data[foo][bar]=object data[0][baz]="not an array"
Run
HTTPie Type Error: Can't perform 'index' based access on 'data' which has a type of 'object' but this operation requires a type of 'array'.
data[0][baz]
    ^^^

(If you happen to be a Python developer and these error messages look familiar, it’s because we took inspiration from improved errors in Python 3.10 / 3.11, that our very own @isidentical helped bring to life.)

There is a lot more to learn about this feature. We recommend taking a minute familiarizing yourself with it so that your API interactions become more enjoyable than ever.

📖 Nested JSON docs →

🔌 Plugin manager

HTTPie plugin manager

HTTPie shines with plugins, and, even though we never publicized the plugin API, developers and companies have written and open-sourced dozens of them.

Their functionality ranges from adding support for different authentication methods to changing how responses are displayed on the terminal; they serve various purposes and offer infinite possibilities to expand HTTPie itself.

For example, guardian/httpie-hmac-auth and akamai/httpie-edgegrid add custom auth protocols to HTTPie, which are then available to you through the --auth-type option:

$ http \
  --auth-type=edgegrid \
  --auth=default: \
  :/diagnostic-tools/v2/ghost-locations/available

In the past, however, it was impossible to reliably install plugins for some distribution methods of HTTPie that come with a bundled Python interpreter (e.g., brew and snap).

With 3.0, we make plugins first-class citizens. It is now possible to manage plugins directly by using the new httpie management command and its httpie plugins subcommands. This interface unifies plugin installation no matter how you installed HTTPie itself:

$ httpie plugins install your-favorite-plugin
Installing your-favorite-plugin...
[snip]
Installed your-favorite-plugin==1.0.0
$ httpie plugins list
httpie-edgegrid (1.0.6)
  httpie_oauth1 (httpie.plugins.auth.v1)
httpie-image (1.0.0)
  httpie_image (httpie.plugins.converter.v1)

If you’re curious what kind of plugins exist, you can find most of them on PyPI.

📖 Plugin manager docs →

⏱️ Response metadata

We created a new meta section in our universal request/response display format.

The section currently includes the total time elapsed. It’s the number of seconds between opening the network connection and downloading the last byte of the response body.

Surprisingly, this was one of the oldest and the most 👍’ed issue in our tracker, and we finally implemented it!

You can use -vv to display everything (whole request/response + meta section) or customize this display with our --print= option.

$ http --print=hm pie.dev/delay/0.5
Run
HTTP/1.1 200 OK
Content-Type: application/json

Elapsed time: 0.856867s

Or only display the meta section with --meta.

$ http --meta pie.dev/delay/1
Run
Elapsed time: 0.856867s

🐰 By the way, if you use one of the new Pie theme styles (e.g., --style=pie-dark), you’ll see the time information color-coded (green/yellow/orange/red) based on how long the exchange took:

Colorful response time

📖 Response meta docs →

🚀 Speed-ups

We believe that performance is a critical part of the overall user experience. And HTTPie is all about the user and how they feel when using our tools.

HTTPie for Terminal is designed with interactive API communication in mind. In this context, the top priority has always been making active tasks requiring user cognition, such as defining requests and understanding responses, as fast as possible. The human brain’s I/O is a more precious resource than the computer’s one, and the number of brain cells doesn’t double every two years, regrettably.

Having said that, we consider all forms of performance important and are working hard to reduce also the waiting time for developers, and this release includes multiple speed-ups over different areas:

HTTPie is now fast
  • Startup time is now ~30-50% faster (depending on the environment).
  • Decoding of streamed responses is ~30% faster.
  • Downloads (i.e., when using --download) are more than ~2.5× faster — for locally served files, the download speed went from ~320 MB/s to ~680 MB/s.

🐙 Benchmarking code →

🎨 Improved UI/UX

Pie theme

While we are continuously improving HTTPie for Terminal, it is now part of a bigger platform that brings the beauty and simplicity of HTTPie to Web & Desktop, and Mobile. Alongside consistent behavior, we work toward a unified style across these apps. This effort led us to create a new set of styles called the Pie theme:

Unified Pie theme

The theme comes in three flavors:

  • pie-dark — for terminals with dark background
  • pie-light — for terminals with light background
  • pie — for both, but slightly compromises text legibility
$ http -vv --style=pie-dark pie.dev/post hello=world foo:=42
Run

While auto is still the default style (which takes colors from your shell environment), we highly recommend making pie-dark your default style for the best experience:

$ cat ~/.config/httpie/config.json
Run
{
    "default_options": [
        "--style=pie-dark"
    ]
}

🐰 Just like the dynamically colored timings, we color the HTTP method and status code to match with our apps across the platform. You can try the examples below (just hover the code and click ‘Run’):

Status code colors

These colors are based on the degree of error/recoverability of each status class:

# 1xx informational – blue
$ http -h pie.dev/status/101
Run
# 2xx successful – green
$ http -h pie.dev/status/200
Run
# 3xx redirection – yellow
$ http -h pie.dev/status/301
Run
# 4xx client error – orange
$ http -h pie.dev/status/400
Run
# 5xx server error – red
$ http -h pie.dev/status/500
Run

Method colors

These colors are based on the potential severity of the impact of the request:

# HEAD, GET – green
$ http --print=H GET pie.dev/get
Run
# POST – yellow
$ http --print=H POST pie.dev/post
Run
# PUT, PATCH – orange
$ http --print=H PATCH pie.dev/patch
Run
# DELETE – red
$ http --print=H DELETE pie.dev/delete
Run

📖 Style docs →

Improved stdin handling

Something that will excite our users who like to use HTTPie for Terminal inside their scripts, workflow definitions, or cron jobs, are our new warnings about when there is no incoming data. If you happen to forget passing --ignore-stdin, instead of waiting indefinitely for a stream that will never yield anything, HTTPie will now complain and let you know about this situation.

📖 Scripting docs →

Better errors

We also focused on improving error messages. A typical example is a mistyped hostname:

$ http this.host.does.not.exist
Run
http: error: gaierror: [Errno -2] Name or service not known
Couldn’t resolve the given hostname. Please check the URL and try again.

✨ Various enhancements

Bearer authentication

bearer is now a natively supported authentication type:

$ http -A bearer -a token pie.dev/bearer
Run

📖 Bearer auth docs →

Non-unique header names

Sending and receiving multiple HTTP header lines with the same name is now fully supported. They’re now shown and sent exactly as specified, i.e., multiple headers lines as opposed to a single header with a comma-separated list of values:

$ http --offline pie.dev/get X-Pie:Apple X-Pie:Pumpkin
Run
GET /get HTTP/1.1
X-Pie: Apple
X-Pie: Pumpkin

📖 Repeated headers docs →

Prompted password in sessions

Prompted passwords are now stored in local sessions. Try typing 123 to the given prompt:

$ http -a user --session=./sess.json pie.dev/basic-auth/user/123
Run

And now try without passing the auth option:

$ http --session=./sess.json pie.dev/basic-auth/user/123
Run

Shout out to Sebastian Czech for contributing this feature.

📖 Password prompt docs →

Query params and headers from files

There are two new operators for reading query parameters and headers from files — ==@ and :@:

$ http --offline pie.dev/headers \
  Header-From-File:@files/text.txt \
  param-from-file==@files/text.txt
Run

📖 File loading docs →

Effortless URL-to-command conversion

Keep :// in the URL argument if you want to. Pasting URLs into HTTPie calls has never been easier: just add a space after the protocol name:

$ https ://pie.dev
# => https://pie.dev
Run

📖 URL docs →

JSON types with forms

We added support for basic JSON types with --form and --multipart when using the otherwise JSON-only operators := and :=@, which allows you to quickly toggle between form and JSON requests. This change doesn’t alter the existing behavior, but it makes what was previously implicit/undefined/buggy explicitly supported:

$ http --form pie.dev/post id:=10 'username:="httpie"'
Run

📖 Forms docs →

Auto-stream

If the response headers include Content-Type: text/event-stream, we now auto-stream the response body. So you no longer need to explicitly specify --stream when reading event streams.

📖 Streaming docs →

🪲 Bug fixes

  • An XML declaration was auto-added to the beginning of each formatted XML response, but not anymore. Now you'll only see it if it's already present in the raw response.

  • Broken plugins would crash the whole application, yikes! They no longer do.

  • Automatic syntax highlighting and formatting now works for complex Content-Type headers (e.g., when charset is specified).

  • Using --raw together with --chunked is now fixed.

🐙 Full changelog →

♥️ Community contributions

Last but not least we’d like to thank the amazing people who’ve contributed to this phenomenal release of HTTPie:

Aaron Miller, Alexander Bogdanov, András Czigány, Brad Crittenden, Chad, Ed Rooth, Gabriel Cruz, Gaurav, Jan Brašna, Jan Verbeek, Jesper Holmberg, Marco Seguri, Mark Rosenbaum, Mickaël Schoentgen, Mike DePalatis, Miro Hrončok, Nanashi., Patrick Taylor, Paul Laffitte, Russell Shurts, Sebastian Czech, Vivaan Verma, Vladimir Berkutov, arloan, blueray453, coldcoff, hosseingt, josephworks, peterpt, stonebig, whodidthis, zoulja.

🐙 How to contribute →

Happy API testing, and see you again soon!

But in the meantime…