Compare commits

...

24 Commits
3.0.1 ... 3.0.2

Author SHA1 Message Date
559134de0a Release 3.0.2 (#1281) 2022-01-24 21:20:17 +03:00
813e8864a1 Dont apply default options on the httpie command (#1280)
* Mark tests with requires_installation

* Dont apply default options on the httpie command

* lint
2022-01-24 10:13:47 -08:00
45fcd746d7 docs: format the benchmark docs 2022-01-24 18:20:03 +03:00
d5e3611e85 fix lint errors 2022-01-24 18:17:55 +03:00
378a1f513e Document the pyOpenSSL option 2022-01-24 18:17:55 +03:00
df6843b15a docs: add --{local, target}-{repo, branch} / format 2022-01-24 18:17:55 +03:00
640901146f docs: document the --fresh option 2022-01-24 18:17:55 +03:00
6b5d96da72 Describe the usage for benchmarks 2022-01-24 18:17:55 +03:00
97bd9c2a89 docs: add requirements 2022-01-24 18:17:55 +03:00
708608e1d4 docs: mention about the runners 2022-01-24 18:17:55 +03:00
d56a1f216e docs: give a brief description 2022-01-24 18:17:55 +03:00
738a6bea57 docs: fix the title to benchmarking infrastructure 2022-01-24 18:17:55 +03:00
ec521c461b docs: add initial benchmark docs 2022-01-24 18:17:55 +03:00
212000199e docs: fix the nested json example (#1278) 2022-01-24 18:00:54 +03:00
700dbeddb0 Typos 2022-01-24 01:51:53 +01:00
30a4d29f77 Update CHANGELOG.md 2022-01-23 15:15:16 -08:00
aedcad7e2a Update CHANGELOG.md 2022-01-23 15:14:31 -08:00
202f59e04a Tweak nested JSON docs 2022-01-23 18:36:18 +01:00
ba0c1ab258 Tweak auth docs 2022-01-23 17:24:29 +01:00
217cf8ddae Document auto-stream 2022-01-23 17:17:58 +01:00
859e442083 Docs 2022-01-23 16:59:07 +01:00
4e59bbfae6 Docs 2022-01-23 16:52:31 +01:00
caa8fb9058 Tweak response meta docs
- expand response meta section
- add examples
- interlink sections
2022-01-23 14:35:20 +01:00
2797b7244c Update cached brew formula 2022-01-23 14:11:09 +01:00
9 changed files with 191 additions and 43 deletions

View File

@ -3,12 +3,22 @@
This document records all notable changes to [HTTPie](https://httpie.io).
This project adheres to [Semantic Versioning](https://semver.org/).
## [3.0.2](https://github.com/httpie/httpie/compare/3.0.0...3.0.1) (2022-01-23)
[Whats new in HTTPie for Terminal 3.0 →](https://httpie.io/blog/httpie-3.0.0)
- Fixed usage of `httpie` when there is a presence of a config with `default_options` ([#1280](https://github.com/httpie/httpie/pull/1280)).
## [3.0.1](https://github.com/httpie/httpie/compare/3.0.0...3.0.1) (2022-01-23)
[Whats new in HTTPie for Terminal 3.0 →](https://httpie.io/blog/httpie-3.0.0)
- Changed the value shown as time elapsed from time-to-read-headers to total exchange time ([#1277](https://github.com/httpie/httpie/issues/1277))
## [3.0.0](https://github.com/httpie/httpie/compare/2.6.0...3.0.0) (2022-01-21)
[Whats new in HTTPie for Terminal 3.0 →](https://httpie.io/blog/httpie-3.0.0)
- Dropped support for Python 3.6. ([#1177](https://github.com/httpie/httpie/issues/1177))
- Improved startup time by 40%. ([#1211](https://github.com/httpie/httpie/pull/1211))
- Added support for nested JSON syntax. ([#1169](https://github.com/httpie/httpie/issues/1169))
@ -32,7 +42,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
## [2.6.0](https://github.com/httpie/httpie/compare/2.5.0...2.6.0) (2021-10-14)
[Whats new in HTTPie 2.6.0 →](https://httpie.io/blog/httpie-2.6.0)
[Whats new in HTTPie for Terminal 2.6.0 →](https://httpie.io/blog/httpie-2.6.0)
- Added support for formatting & coloring of JSON bodies preceded by non-JSON data (e.g., an XXSI prefix). ([#1130](https://github.com/httpie/httpie/issues/1130))
- Added charset auto-detection when `Content-Type` doesnt include it. ([#1110](https://github.com/httpie/httpie/issues/1110), [#1168](https://github.com/httpie/httpie/issues/1168))
@ -44,7 +54,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
## [2.5.0](https://github.com/httpie/httpie/compare/2.4.0...2.5.0) (2021-09-06)
[Whats new in HTTPie 2.5.0 →](https://httpie.io/blog/httpie-2.5.0)
[Whats new in HTTPie for Terminal 2.5.0 →](https://httpie.io/blog/httpie-2.5.0)
- Added `--raw` to allow specifying the raw request body without extra processing as
an alternative to `stdin`. ([#534](https://github.com/httpie/httpie/issues/534))

View File

@ -681,7 +681,40 @@ Other JSON types, however, are not allowed with `--form` or `--multipart`.
"about": {
"mission": "Make APIs simple and intuitive",
"homepage": "httpie.io",
}
"stars": 54000
},
"apps": [
"Terminal",
"Desktop",
"Web",
"Mobile"
]
}
}
```
#### Introduction
Lets start with a simple example, and build a simple search query:
```bash
$ http --offline --print=B pie.dev/post \
category=tools \
search[type]=id \
search[id]:=1
```
In the example above, the `search[type]` is an instruction for creating an object called `search`, and setting the `type` field of it to the given value (`"id"`).
Also note that, just as the regular syntax, you can use the `:=` operator to directly pass raw JSON values (e.g, numbers in the case above).
```json
{
"category": "tools",
"search": {
"id": 1,
"type": "id"
}
}
```
@ -739,7 +772,7 @@ $ http --offline --print=B pie.dev/post \
category=tools \
search[type]=platforms \
search[platforms][]=Terminal \
search[platforms][1]=Desktop \
search[platforms][1]=Desktop \
search[platforms][3]=Mobile
```
@ -1247,12 +1280,18 @@ https -A bearer -a token pie.dev/bearer
For example:
```bash
$ cat ~/.netrc
machine pie.dev
login httpie
password test
```
```bash
$ http pie.dev/basic-auth/httpie/test
HTTP/1.1 200 OK
[...]
```
This can be disabled with the `--ignore-netrc` option:
```bash
@ -1300,6 +1339,8 @@ Here are a few picks:
With `307 Temporary Redirect` and `308 Permanent Redirect`, the method and the body of the original request
are reused to perform the redirected request. Otherwise, a body-less `GET` request is performed.
### Showing intermediary redirect responses
If you wish to see the intermediary requests/responses,
then use the `--all` option:
@ -1442,7 +1483,7 @@ be printed via several options:
```bash
$ http --print=Hh PUT pie.dev/put hello=world
```
```
#### Response meta
@ -1453,13 +1494,13 @@ be printed via several options:
```bash
$ http --meta pie.dev/delay/1
### Verbose output
`--verbose` can often be useful for debugging the request and generating documentation examples:
```bash
$ http --verbose PUT pie.dev/put hello=world
PUT /put HTTP/1.1
```
```console
Elapsed time: 1.099171542s
```
The [extra verbose `-vv` output](#extra-verbose-output) includes the meta section by default. You can also show it in combination with other parts of the exchange via [`--print=m`](#what-parts-of-the-http-exchange-should-be-printed). For example, here we print it together with the response headers:
```bash
$ http --print=hm pie.dev/get
@ -1471,9 +1512,34 @@ $ http --print=Hh PUT pie.dev/put hello=world
```
Connection: keep-alive
Content-Type: application/json
Please note that it also includes time spent on formatting the output, which adds a small penalty. Also, if the body is not part of the output, [we dont spend time downloading it](#conditional-body-download).
If you [use `--style` with one of the Pie themes](#colors-and-formatting), youll see the time information color-coded (green/yellow/orange/red) based on how long the exchange took.
### Verbose output
`--verbose` can often be useful for debugging the request and generating documentation examples:
```bash
$ http --verbose PUT pie.dev/put hello=world
PUT /put HTTP/1.1
Accept: application/json, */*;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/json
Host: pie.dev
User-Agent: HTTPie/0.2.7dev
{
"hello": "world"
}
HTTP/1.1 200 OK
Connection: keep-alive
Content-Length: 477
Content-Type: application/json
Date: Sun, 05 Aug 2012 00:25:23 GMT
Server: gunicorn/0.13.4
{
@ -1505,9 +1571,9 @@ Server: gunicorn/0.13.4
```bash
# There will be no output, even in case of an unexpected response status code:
$ http -qq --check-status pie.dev/post enjoy='the silence without warnings'
$ http -qq --check-status pie.dev/post enjoy='the silence without warnings'
```
### Viewing intermediary requests/responses
To see all the HTTP communication, i.e. the final request/response as well as any possible intermediary requests/responses, use the `--all` option.
The intermediary HTTP communication include followed redirects (with `--follow`), the first unauthorized request when HTTP digest authentication is used (`--auth=digest`), etc.
@ -1927,6 +1993,8 @@ You can use the `--stream, -S` flag to make two things happen:
```bash
# Create a new session:
$ http --session=./session.json pie.dev/headers API-Token:123
```
```bash
# Inspect / edit the generated session file:
$ cat session.json
@ -2134,7 +2202,7 @@ However, it is not recommended modifying the default behavior in a way that woul
*) echo 'Other Error!' ;;
esac
fi
fi
```
### Best practices
@ -2175,9 +2243,10 @@ And since theres neither data nor `EOF`, it will get stuck. So unless your
By default, the plugins (and their missing dependencies) will be stored under the configuration directory,
but this can be modified through `plugins_dir` variable on the config.
#### `httpie plugins install`
#### `httpie plugins install`
For installing plugins from [PyPI](https://pypi.org/) or from local paths, `httpie plugins install`
For installing plugins from [PyPI](https://pypi.org/) or from local paths, `httpie plugins install`
can be used.
```bash
$ httpie plugins install httpie-plugin

View File

@ -3,19 +3,18 @@ class Httpie < Formula
desc "User-friendly cURL replacement (command-line HTTP client)"
homepage "https://httpie.io/"
url "https://files.pythonhosted.org/packages/64/ee/7b158899655231322f13ecd313d1a0546efe8b9e75167ec8b7fd9ddf7952/httpie-3.0.0.tar.gz"
sha256 "e719711aadf1ecd33278033b96dfef7f4e9e341d3a5d1f166785ac4b7fbdee29"
url "https://files.pythonhosted.org/packages/7b/f9/13070f19226b7db3641fb787df36bb715063abe1b8ca03fbaeca0f465d27/httpie-3.0.1.tar.gz"
sha256 "0e9bc93ebdcdd2d32ec24b8fa46cf7e4fde9eec7a6bd0c5d0ef224f25d7466b2"
license "BSD-3-Clause"
head "https://github.com/httpie/httpie.git", branch: "master"
bottle do
sha256 cellar: :any_skip_relocation, arm64_monterey: "83aab05ffbcd4c3baa6de6158d57ebdaa67c148bef8c872527d90bdaebff0504"
sha256 cellar: :any_skip_relocation, arm64_big_sur: "3c3a5c2458d0658e14b663495e115297c573aa3466d292f12d02c3ec13a24bdf"
sha256 cellar: :any_skip_relocation, monterey: "f860e7d3b77dca4928a2c5e10c4cbd50d792330dfb99f7d736ca0da9fb9dd0d0"
sha256 cellar: :any_skip_relocation, big_sur: "377b0643aa1f6d310ba4cfc70d66a94cc458213db8d134940d3b10a32defacf1"
sha256 cellar: :any_skip_relocation, catalina: "6d306c30f6f1d7a551d88415efe12b7c3f25d0602f3579dc632771a463f78fa5"
sha256 cellar: :any_skip_relocation, mojave: "f66b8cdff9cb7b44a84197c3e3d81d810f7ff8f2188998b977ccadfc7e2ec893"
sha256 cellar: :any_skip_relocation, x86_64_linux: "53f036b0114814c28982e8c022dcf494e7024de088641d7076fd73d12a45a0e9"
sha256 cellar: :any_skip_relocation, arm64_monterey: "9d285fcfb55ce8ed787d1b01966d51e6e07f7e77c44a204695a2d6eee9c8698d"
sha256 cellar: :any_skip_relocation, arm64_big_sur: "743a282b475e87a4eaf11e545f761aef1b8e4bfe49eaee47251d7629a35a8ced"
sha256 cellar: :any_skip_relocation, monterey: "5d63ea4f47b2028b2ba68abe12a4176934193e058edd869270221b41cc946c76"
sha256 cellar: :any_skip_relocation, big_sur: "5a53221a680a35d1aa00cbadde279dbe4f562d22ed207c15bd4221cb8c3180f1"
sha256 cellar: :any_skip_relocation, catalina: "5feadb6d76f55d6f9681682e221008c282dccf0e46ae22a959b4bad2efde204a"
sha256 cellar: :any_skip_relocation, x86_64_linux: "d530ddbec49588b0d481f156d35f7e5bb7d3b6427d203f04750e55cd3eecc303"
end
depends_on "python@3.10"
@ -36,8 +35,13 @@ class Httpie < Formula
end
resource "idna" do
url "https://files.pythonhosted.org/packages/cb/38/4c4d00ddfa48abe616d7e572e02a04273603db446975ab46bbcd36552005/idna-3.2.tar.gz"
sha256 "467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"
url "https://files.pythonhosted.org/packages/62/08/e3fc7c8161090f742f504f40b1bccbfc544d4a4e09eb774bf40aafce5436/idna-3.3.tar.gz"
sha256 "9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"
end
resource "multidict" do
url "https://files.pythonhosted.org/packages/8e/7c/e12a69795b7b7d5071614af2c691c97fbf16a2a513c66ec52dd7d0a115bb/multidict-5.2.0.tar.gz"
sha256 "0dd1c93edb444b33ba2274b66f63def8a327d607c6c790772f448a53b6ea59ce"
end
resource "Pygments" do
@ -65,20 +69,14 @@ class Httpie < Formula
sha256 "0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"
end
resource "multidict" do
url "https://files.pythonhosted.org/packages/8e/7c/e12a69795b7b7d5071614af2c691c97fbf16a2a513c66ec52dd7d0a115bb/multidict-5.2.0.tar.gz"
sha256 "0dd1c93edb444b33ba2274b66f63def8a327d607c6c790772f448a53b6ea59ce"
end
def install
virtualenv_install_with_resources
end
test do
# shell_output() already checks the status code
shell_output("#{bin}/httpie -v")
shell_output("#{bin}/https -v")
shell_output("#{bin}/http -v")
assert_match version.to_s, shell_output("#{bin}/httpie --version")
assert_match version.to_s, shell_output("#{bin}/https --version")
assert_match version.to_s, shell_output("#{bin}/http --version")
raw_url = "https://raw.githubusercontent.com/Homebrew/homebrew-core/HEAD/Formula/httpie.rb"
assert_match "PYTHONPATH", shell_output("#{bin}/http --ignore-stdin #{raw_url}")

View File

@ -0,0 +1,39 @@
# HTTPie Benchmarking Infrastructure
This directory includes the benchmarks we use for testing HTTPie's speed and the
infrastructure to automate this testing accross versions.
## Usage
Ensure the following requirements are satisfied:
- Python 3.7+
- `pyperf`
Then, run the `extras/benchmarks/run.py`:
```console
$ python extras/profiling/run.py
```
Without any options, this command will initially create an isolated environment
and install `httpie` from the latest commit. Then it will create a second
environment with the `master` of the current repository and run the benchmarks
on both of them. It will compare the results and print it as a markdown table:
| Benchmark | master | this_branch |
| -------------------------------------- | :----: | :------------------: |
| `http --version` (startup) | 201 ms | 174 ms: 1.16x faster |
| `http --offline pie.dev/get` (startup) | 200 ms | 174 ms: 1.15x faster |
| Geometric mean | (ref) | 1.10x faster |
If your `master` branch is not up-to-date, you can get a fresh clone by passing
`--fresh` option. This way, the benchmark runner will clone the `httpie/httpie`
repo from `GitHub` and use it as the baseline.
You can customize these branches by passing `--local-repo`/`--target-branch`,
and customize the repos by passing `--local-repo`/`--target-repo` (can either
take a URL or a path).
If you want to run a third enviroment with additional dependencies (such as
`pyOpenSSL`), you can pass `--complex`.

View File

@ -3,6 +3,6 @@ HTTPie: modern, user-friendly command-line HTTP client for the API era.
"""
__version__ = '3.0.1'
__version__ = '3.0.2'
__author__ = 'Jakub Roztocil'
__licence__ = 'BSD'

View File

@ -30,14 +30,15 @@ def raw_main(
parser: argparse.ArgumentParser,
main_program: Callable[[argparse.Namespace, Environment], ExitStatus],
args: List[Union[str, bytes]] = sys.argv,
env: Environment = Environment()
env: Environment = Environment(),
use_default_options: bool = True,
) -> ExitStatus:
program_name, *args = args
env.program_name = os.path.basename(program_name)
args = decode_raw_args(args, env.stdin_encoding)
plugin_manager.load_installed_plugins(env.config.plugins_dir)
if env.config.default_options:
if use_default_options and env.config.default_options:
args = env.config.default_options + args
include_debug_info = '--debug' in args

View File

@ -37,7 +37,8 @@ def main(args: List[Union[str, bytes]] = sys.argv, env: Environment = Environmen
parser=parser,
main_program=main_program,
args=args,
env=env
env=env,
use_default_options=False,
)
except argparse.ArgumentError:
program_args = args[1:]

3
pytest.ini Normal file
View File

@ -0,0 +1,3 @@
[pytest]
markers =
requires_installation

View File

@ -5,6 +5,7 @@ from tests.utils import httpie
from tests.utils.plugins_cli import parse_listing
@pytest.mark.requires_installation
def test_plugins_installation(httpie_plugins_success, interface, dummy_plugin):
lines = httpie_plugins_success('install', dummy_plugin.path)
assert lines[0].startswith(
@ -14,6 +15,20 @@ def test_plugins_installation(httpie_plugins_success, interface, dummy_plugin):
assert interface.is_installed(dummy_plugin.name)
@pytest.mark.requires_installation
def test_plugin_installation_with_custom_config(httpie_plugins_success, interface, dummy_plugin):
interface.environment.config['default_options'] = ['--session-read-only', 'some-path.json', 'other', 'args']
interface.environment.config.save()
lines = httpie_plugins_success('install', dummy_plugin.path)
assert lines[0].startswith(
f'Installing {dummy_plugin.path}'
)
assert f'Successfully installed {dummy_plugin.name}-{dummy_plugin.version}' in lines
assert interface.is_installed(dummy_plugin.name)
@pytest.mark.requires_installation
def test_plugins_listing(httpie_plugins_success, interface, dummy_plugin):
httpie_plugins_success('install', dummy_plugin.path)
data = parse_listing(httpie_plugins_success('list'))
@ -23,6 +38,7 @@ def test_plugins_listing(httpie_plugins_success, interface, dummy_plugin):
}
@pytest.mark.requires_installation
def test_plugins_listing_multiple(interface, httpie_plugins_success, dummy_plugins):
paths = [plugin.path for plugin in dummy_plugins]
httpie_plugins_success('install', *paths)
@ -34,12 +50,14 @@ def test_plugins_listing_multiple(interface, httpie_plugins_success, dummy_plugi
}
@pytest.mark.requires_installation
def test_plugins_uninstall(interface, httpie_plugins_success, dummy_plugin):
httpie_plugins_success('install', dummy_plugin.path)
httpie_plugins_success('uninstall', dummy_plugin.name)
assert not interface.is_installed(dummy_plugin.name)
@pytest.mark.requires_installation
def test_plugins_listing_after_uninstall(interface, httpie_plugins_success, dummy_plugin):
httpie_plugins_success('install', dummy_plugin.path)
httpie_plugins_success('uninstall', dummy_plugin.name)
@ -48,6 +66,7 @@ def test_plugins_listing_after_uninstall(interface, httpie_plugins_success, dumm
assert len(data) == 0
@pytest.mark.requires_installation
def test_plugins_uninstall_specific(interface, httpie_plugins_success):
new_plugin_1 = interface.make_dummy_plugin()
new_plugin_2 = interface.make_dummy_plugin()
@ -61,6 +80,7 @@ def test_plugins_uninstall_specific(interface, httpie_plugins_success):
assert not interface.is_installed(target_plugin.name)
@pytest.mark.requires_installation
def test_plugins_installation_failed(httpie_plugins, interface):
plugin = interface.make_dummy_plugin(build=False)
result = httpie_plugins('install', plugin.path)
@ -69,6 +89,7 @@ def test_plugins_installation_failed(httpie_plugins, interface):
assert result.stderr.splitlines()[-1].strip().startswith("Can't install")
@pytest.mark.requires_installation
def test_plugins_uninstall_non_existent(httpie_plugins, interface):
plugin = interface.make_dummy_plugin(build=False)
result = httpie_plugins('uninstall', plugin.name)
@ -80,6 +101,7 @@ def test_plugins_uninstall_non_existent(httpie_plugins, interface):
)
@pytest.mark.requires_installation
def test_plugins_double_uninstall(httpie_plugins, httpie_plugins_success, dummy_plugin):
httpie_plugins_success("install", dummy_plugin.path)
httpie_plugins_success("uninstall", dummy_plugin.name)
@ -93,6 +115,7 @@ def test_plugins_double_uninstall(httpie_plugins, httpie_plugins_success, dummy_
)
@pytest.mark.requires_installation
def test_plugins_upgrade(httpie_plugins, httpie_plugins_success, dummy_plugin):
httpie_plugins_success("install", dummy_plugin.path)
@ -105,6 +128,7 @@ def test_plugins_upgrade(httpie_plugins, httpie_plugins_success, dummy_plugin):
assert data[dummy_plugin.name]['version'] == '2.0.0'
@pytest.mark.requires_installation
def test_broken_plugins(httpie_plugins, httpie_plugins_success, dummy_plugin, broken_plugin):
httpie_plugins_success("install", dummy_plugin.path, broken_plugin.path)
@ -127,6 +151,7 @@ def test_broken_plugins(httpie_plugins, httpie_plugins_success, dummy_plugin, br
assert len(data) == 1
@pytest.mark.requires_installation
def test_plugins_cli_error_message_without_args():
# No arguments
result = httpie(no_debug=True)
@ -143,6 +168,7 @@ def test_plugins_cli_error_message_without_args():
'POST pie.dev/post header:value a=b header_2:value x:=1'
]
)
@pytest.mark.requires_installation
def test_plugins_cli_error_messages_with_example(example):
result = httpie(*example.split(), no_debug=True)
assert result.exit_status == ExitStatus.ERROR
@ -158,6 +184,7 @@ def test_plugins_cli_error_messages_with_example(example):
'unknown.com UNPARSABLE????SYNTAX',
]
)
@pytest.mark.requires_installation
def test_plugins_cli_error_messages_invalid_example(example):
result = httpie(*example.split(), no_debug=True)
assert result.exit_status == ExitStatus.ERROR