HTTPie: human-friendly CLI HTTP client for the API era

Last update: Jun 27, 2022

HTTPie

HTTPie: human-friendly CLI HTTP client for the API era

HTTPie (pronounced aitch-tee-tee-pie) is a command-line HTTP client. Its goal is to make CLI interaction with web services as human-friendly as possible. HTTPie is designed for testing, debugging, and generally interacting with APIs & HTTP servers. The http & https commands allow for creating and sending arbitrary HTTP requests. They use simple and natural syntax and provide formatted and colorized output.

Docs Latest version Build Coverage Twitter Chat

HTTPie in action

Getting started

Features

  • Expressive and intuitive syntax
  • Formatted and colorized terminal output
  • Built-in JSON support
  • Forms and file uploads
  • HTTPS, proxies, and authentication
  • Arbitrary request data
  • Custom headers
  • Persistent sessions
  • wget-like downloads

See all features →

Examples

Hello World:

$ https httpie.io/hello

Custom HTTP method, HTTP headers and JSON data:

$ http PUT pie.dev/put X-API-Token:123 name=John

Build and print a request without sending it using offline mode:

$ http --offline pie.dev/post hello=offline

Use GitHub API to post a comment on an Issue with authentication:

$ http -a USERNAME POST https://api.github.com/repos/httpie/httpie/issues/83/comments body='HTTPie is awesome! :heart:'

See more examples →

Community & support

Contributing

Have a look through existing Issues and Pull Requests that you could help with. If you'd like to request a feature or report a bug, please create a GitHub Issue using one of the templates provided.

See contribution guide →

GitHub

https://github.com/httpie/httpie
Comments
  • 1. Issue for Testing

    Test httpie advanced usage by posting a comment on this issue:

    http -a <username> https://api.github.com/repos/httpie/httpie/issues/83/comments body='Your Comment'
    
    Reviewed by jakubroztocil at 2012-08-04 22:27
  • 2. Option to allow pretty print without alpha sorting

    Right now, the options are colors, format, and all, but often the order of the json returned is intentional and for clarify. It would be nice to be able to pretty print the json without having it's keys sorted :)

    Awesome tool, and thanks very much for everything!

    Reviewed by patcon at 2013-02-10 21:56
  • 3. httpie changing the json fields order in the output

    Wondering how can I force httpie to not change the json fields order?

    curl -i http://localhost:8080/v1/notes/569766aed4c661fba8d85a12
    
    {
      "id": "569766aed4c661fba8d85a12",
      "content": "hi"
    }
    

    with httpie

    http get :8080/v1/notes/569766aed4c661fba8d85a12 
    
    {
      "content": "hi",
      "id": "569766aed4c661fba8d85a12"
    }
    

    I prefer the id field to be always the first. Any thoughts?

    Reviewed by altfatterz at 2016-01-14 09:49
  • 4. Multiple test failures in tox py34

    Multiple test failures in test_sessions.py.

    When I run:

    tox -e py34 -- tests/test_sessions.py
    

    I get 1, 2, or 3 test failures out of the 7 total tests in that module.

    tests/test_sessions.py::TestSessionFlow::test_session_created_and_reused PASSED
    tests/test_sessions.py::TestSessionFlow::test_session_update FAILED
    tests/test_sessions.py::TestSessionFlow::test_session_read_only FAILED
    tests/test_sessions.py::TestSession::test_session_ignored_header_prefixes PASSED
    tests/test_sessions.py::TestSession::test_session_by_path PASSED
    tests/test_sessions.py::TestSession::test_session_unicode FAILED
    tests/test_sessions.py::TestSession::test_session_default_header_value_overwritten PASSED
    

    More info:

    TestSessionFlow.test_session_update fails with:

    ...
    requests.exceptions.ConnectionError: (
    'Connection aborted.', ConnectionResetError(54, 'Connection reset by peer'))
    

    pdb for above error shows:

    > /Users/marca/dev/git-repos/httpie/.tox/py34/lib/python3.4/site-packages/requests/adapters.py(407)send()
    -> raise ConnectionError(err, request=request)
    (Pdb) up
    > /Users/marca/dev/git-repos/httpie/.tox/py34/lib/python3.4/site-packages/requests/sessions.py(569)send()
    -> r = adapter.send(request, **kwargs)
    (Pdb) request.method
    'GET'
    (Pdb) request.url
    'http://127.0.0.1:56308/cookies'
    (Pdb) request.headers
    {'Accept-Encoding': 'gzip, deflate', 'Hello': b'World2', 'Cookie': 'hello=world; hello=world2', 'Connection': 'keep-alive', 'Authorization': b'Basic dXNlcm5hbWU6cGFzc3dvcmQy', 'Accept': '*/*', 'User-Agent': b'HTTPie/0.9.0-dev'}
    (Pdb) kwargs
    {'timeout': 30, 'cert': None, 'proxies': {}, 'stream': True, 'verify': True}
    

    TestSessionFlow.test_session_read_only fails with

    ...
    requests.exceptions.ConnectionError: ('Connection aborted.', BadStatusLine("''",))
    

    pdb for above error shows:

    > /Users/marca/dev/git-repos/httpie/.tox/py34/lib/python3.4/site-packages/requests/adapters.py(407)send()
    -> raise ConnectionError(err, request=request)
    (Pdb) up
    > /Users/marca/dev/git-repos/httpie/.tox/py34/lib/python3.4/site-packages/requests/sessions.py(569)send()
    -> r = adapter.send(request, **kwargs)
    (Pdb) request.method
    'GET'
    (Pdb) request.url
    'http://127.0.0.1:56276/cookies'
    (Pdb) request.headers
    {'User-Agent': b'HTTPie/0.9.0-dev', 'Hello': b'World2', 'Accept-Encoding': 'gzip, deflate', 'Cookie': 'hello=world; hello=world2', 'Connection': 'keep-alive', 'Authorization': b'Basic dXNlcm5hbWU6cGFzc3dvcmQy', 'Accept': '*/*'}
    (Pdb) kwargs
    {'cert': None, 'proxies': {}, 'verify': True, 'timeout': 30, 'stream': True}
    

    TestSession.test_session_unicode fails with:

    ...
    Traceback (most recent call last):
      File ".../httpie/tests/test_sessions.py", line 148, in test_session_unicode
        assert (r2.json['headers']['Authorization']
    KeyError: 'Authorization'
    

    Pertaining to this last error, there is a comment in the test saying:

    147             # FIXME: Authorization *sometimes* is not present on Python3
    
    (Pdb) pprint.pprint(r2.json)
    {'args': {},
     'headers': {'Content-Length': '',
                 'Host': '127.0.0.1:56230',
                 'Test': '[one line of UTF8-encoded unicode text] Ï\x87Ï\x81Ï'},
     'origin': '127.0.0.1',
     'url': 'http://127.0.0.1:56230/get'}
    

    In py33 I also see 1 to 2 test failures -- I have not yet observed TestSession.test_session_unicode failing on py33.

    Most of the time, all these tests pass on py27, though I am seeing test_session_read_only fail occasionally with:

    ____________________________________________________________________ TestSessionFlow.test_session_read_only ____________________________________________________________________
    Traceback (most recent call last):
      File "/Users/marca/dev/git-repos/httpie/tests/test_sessions.py", line 82, in test_session_read_only
        self.start_session(httpbin)
      File "/Users/marca/dev/git-repos/httpie/tests/test_sessions.py", line 48, in start_session
        env=self.env())
      File "/Users/marca/dev/git-repos/httpie/tests/utils.py", line 136, in http
        exit_status = main(args=args, **kwargs)
      File "/Users/marca/dev/git-repos/httpie/.tox/py27/lib/python2.7/site-packages/httpie/core.py", line 112, in main
        response = get_response(args, config_dir=env.config.directory)
      File "/Users/marca/dev/git-repos/httpie/.tox/py27/lib/python2.7/site-packages/httpie/client.py", line 31, in get_response
        read_only=bool(args.session_read_only),
      File "/Users/marca/dev/git-repos/httpie/.tox/py27/lib/python2.7/site-packages/httpie/sessions.py", line 65, in get_response
        response = requests_session.request(**requests_kwargs)
      File "/Users/marca/dev/git-repos/httpie/.tox/py27/lib/python2.7/site-packages/requests/sessions.py", line 457, in request
        resp = self.send(prep, **send_kwargs)
      File "/Users/marca/dev/git-repos/httpie/.tox/py27/lib/python2.7/site-packages/requests/sessions.py", line 595, in send
        history = [resp for resp in gen] if allow_redirects else []
      File "/Users/marca/dev/git-repos/httpie/.tox/py27/lib/python2.7/site-packages/requests/sessions.py", line 189, in resolve_redirects
        allow_redirects=False,
      File "/Users/marca/dev/git-repos/httpie/.tox/py27/lib/python2.7/site-packages/requests/sessions.py", line 569, in send
        r = adapter.send(request, **kwargs)
      File "/Users/marca/dev/git-repos/httpie/.tox/py27/lib/python2.7/site-packages/requests/adapters.py", line 407, in send
        raise ConnectionError(err, request=request)
    ConnectionError: ('Connection aborted.', error(54, 'Connection reset by peer'))
    
    Reviewed by msabramo at 2014-11-28 21:12
  • 5. Add support for unix domain sockets

    To issue HTTP requests to a UNIX domain socket:

    • Use new "http+unix://" scheme in URL.

    • Use urlencoded socket path as the hostname part of the URL. e.g.: for a socket at /tmp/profilesvc.sock, you could do:

      http http+unix://%2Ftmp%2Fprofilesvc.sock/status/pid
      

    This uses https://pypi.python.org/pypi/requests-unixsocket

    Fixes: GH-209 (https://github.com/jakubroztocil/httpie/issues/209)

    Screenshot

    screen shot 2014-11-24 at 6 35 24 pm

    Cc: @shin-, @jakubroztocil, @monsanto, @np, @nuxlli, @matrixise, @remmelt

    Reviewed by msabramo at 2014-11-25 02:29
  • 6. requests.exceptions.SSLError: [Errno 8] _ssl.c:507: EOF occurred in violation of protocol

    HTTPie 1.0.0-dev
    HTTPie data: /Users/kaji/.httpie
    Requests 2.5.3
    Pygments 2.0.2
    Python 2.7.6 (default, Sep  9 2014, 15:04:36)
    [GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] darwin
    Not every SSL website shows though. So, it is tricky. From browser , it is working fine.
    
    >>> requests.request({'allow_redirects': False,
     'auth': None,
     'cert': None,
     'data': OrderedDict(),
     'files': DataDict(),
     'headers': {'User-Agent': 'HTTPie/1.0.0-dev'},
     'method': 'get',
     'params': ParamsDict(),
     'proxies': {},
     'stream': True,
     'timeout': 30,
     'url': u'https://apissl.example.com',
     'verify': True})
    
    Traceback (most recent call last):
      File "/usr/local/bin/http", line 9, in <module>
        load_entry_point('httpie==1.0.0-dev', 'console_scripts', 'http')()
      File "/Library/Python/2.7/site-packages/httpie/core.py", line 112, in main
        response = get_response(args, config_dir=env.config.directory)
      File "/Library/Python/2.7/site-packages/httpie/client.py", line 41, in get_response
        response = requests_session.request(**kwargs)
      File "/Library/Python/2.7/site-packages/requests/sessions.py", line 461, in request
        resp = self.send(prep, **send_kwargs)
      File "/Library/Python/2.7/site-packages/requests/sessions.py", line 573, in send
        r = adapter.send(request, **kwargs)
      File "/Library/Python/2.7/site-packages/requests/adapters.py", line 431, in send
        raise SSLError(e, request=request)
    requests.exceptions.SSLError: [Errno 8] _ssl.c:507: EOF occurred in violation of protocol
    
    Reviewed by kaji-bikash at 2015-02-28 10:15
  • 7. Syntax for nested JSON

    The simple examples work, but what about nested data? In curl I do something like this:

    -d
    '"credentials": { "username": "me", "key": "my-key"} }'

    How can I do this with httpie?

    Reviewed by sym3tri at 2012-07-26 23:52
  • 8. Request to add `-d, --data` option for raw body like curl

    The request is simple, just to add an option to pass raw data like curl does:

    http :/api/user -d 'MyRawData...'
    

    I know that in mostly cases if you are sending JSON or form data, it can be achieved with the "request items", like:

    http :/api/hey say=Hello to=me …
    

    And it will converted to the proper format depending of the content type, that is awesome! And if you have something that is not a JSON or form data to send, you can do something like:

    echo 'MyRawData...' | http :/api/hey
    

    But this is impractical, the main idea of HTTPie is cURL-like tool for humans , and this case is far of that principle, in fact, curl is more practical than HTTPie for the previous example. Adding more than one command and pipe them with ugly characters like | < just because a simple option is missing doesn't sound human-friendly.

    What's wrong with add the -d option to http?

    Reviewed by mrsarm at 2016-10-31 15:41
  • 9. httpie output has lots of additional characters on windows

    Running http GET httpie.org on windows results in a load of extra characters being printed out:

    HTTP/1.1 ←[39;49;00m←[34m302←[39;49;00m←[33m Found←[39;49;00m
    Date:←[39;49;00m←[33m Mon, 19 Mar 2012 15:13:17 GMT←[39;49;00m
    Server:←[39;49;00m←[33m Apache←[39;49;00m
    X-Awesome:←[39;49;00m←[33m Thanks for trying HTTPie :)←[39;49;00m
    Location:←[39;49;00m←[33m https://github.com/jkbr/httpie←[39;49;00m
    Cache-Control:←[39;49;00m←[33m max-age=1800←[39;49;00m
    Expires:←[39;49;00m←[33m Mon, 19 Mar 2012 15:43:17 GMT←[39;49;00m
    Content-Length:←[39;49;00m←[33m 214←[39;49;00m
    Content-Type:←[39;49;00m←[33m text/html; charset=iso-8859-1←[39;49;00m
    
    ←[36m<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">←[39;49;00m
    ←[34;01m<html←[39;49;00m←[34;01m>←[39;49;00m←[34;01m<head←[39;49;00m←[34;01m>←[39;49;00m
    ←[34;01m<title←[39;49;00m←[34;01m>←[39;49;00m302 Found←[39;49;00m←[34;01m</title>←[39;49;00m
    ←[34;01m</head>←[39;49;00m←[34;01m<body←[39;49;00m←[34;01m>←[39;49;00m
    ←[34;01m<h1←[39;49;00m←[34;01m>←[39;49;00mFound←[39;49;00m←[34;01m</h1>←[39;49;00m
    ←[34;01m<p←[39;49;00m←[34;01m>←[39;49;00mThe document has moved ←[39;49;00m←[34;01m<a←[39;49;00m ←[39;49;00m←[36mhref=←[39;49;00m←[33m"https://github.com/jkbr/httpie"←[39;49;00m←[34;01m>←[39;49;00mhere←[39;49;00m←[34;01m</a>←[39;49;00m.←[39;49;00m←[34;01m</p>←[39;49;00m
    

    I'm guessing that these are escape codes that provide the colored output on other operating systems. Running http -u GET httpie.org results in correct (though monochrome) output.

    It'd be nice to get cross platform colored output like provided by clint.

    Reviewed by obmarg at 2012-03-19 15:26
  • 10. 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.

    Reviewed by rshurts at 2017-03-08 20:53
  • 11. Not working on OS X Mavericks

    When I tried to run a command on OS X Mavericks, I get the following error:

    batuhanicoz at batuhanicoz-mbp2 in ~
    ○ http GET https://api.testapps.local.bt.hn/sdfdssad/dasa
    Traceback (most recent call last):
      File "/usr/local/bin/http", line 5, in <module>
        from pkg_resources import load_entry_point
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources.py", line 2603, in <module>
        working_set.require(__requires__)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources.py", line 666, in require
        needed = self.resolve(parse_requirements(requirements))
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/pkg_resources.py", line 565, in resolve
        raise DistributionNotFound(req)  # XXX put more info here
    pkg_resources.DistributionNotFound: httpie==0.6.0
    
    Reviewed by batuhan at 2013-06-19 07:27
  • 12. --help fails with a traceback

    Checklist

    • [x] I've searched for similar issues.
    • [x] I'm using the latest version of HTTPie.

    Minimal reproduction code and steps

    1. http --help or https --help

    Current result

    output with traceback
    $ http --help
    Traceback (most recent call last):
      File "/usr/bin/http", line 33, in <module>
        sys.exit(load_entry_point('httpie==3.2.1', 'console_scripts', 'http')())
      File "/usr/lib/python3.10/site-packages/httpie/__main__.py", line 9, in main
        exit_status = main()
      File "/usr/lib/python3.10/site-packages/httpie/core.py", line 162, in main
        return raw_main(
      File "/usr/lib/python3.10/site-packages/httpie/core.py", line 77, in raw_main
        parsed_args = parser.parse_args(
      File "/usr/lib/python3.10/site-packages/httpie/cli/argparser.py", line 159, in parse_args
        self.args, no_options = super().parse_known_args(args, namespace)
      File "/usr/lib/python3.10/argparse.py", line 1859, in parse_known_args
        namespace, args = self._parse_known_args(args, namespace)
      File "/usr/lib/python3.10/argparse.py", line 2068, in _parse_known_args
        start_index = consume_optional(start_index)
      File "/usr/lib/python3.10/argparse.py", line 2008, in consume_optional
        take_action(action, args, option_string)
      File "/usr/lib/python3.10/argparse.py", line 1936, in take_action
        action(self, namespace, argument_values, option_string)
      File "/usr/lib/python3.10/argparse.py", line 1099, in __call__
        parser.print_help()
      File "/usr/lib/python3.10/argparse.py", line 2556, in print_help
        self._print_message(self.format_help(), file)
      File "/usr/lib/python3.10/argparse.py", line 2533, in format_help
        formatter.add_arguments(action_group._group_actions)
      File "/usr/lib/python3.10/argparse.py", line 277, in add_arguments
        self.add_argument(action)
      File "/usr/lib/python3.10/argparse.py", line 258, in add_argument
        if action.help is not SUPPRESS:
      File "/usr/lib/python3.10/site-packages/httpie/cli/utils.py", line 60, in help
        self.load(),
      File "/usr/lib/python3.10/site-packages/httpie/cli/utils.py", line 51, in load
        self._obj = self.getter()
      File "/usr/lib/python3.10/site-packages/httpie/output/formatters/colors.py", line 37, in get_available_styles
        return sorted(BUNDLED_STYLES | set(pygments.styles.get_all_styles()))
      File "/usr/lib/python3.10/site-packages/pygments/styles/__init__.py", line 92, in get_all_styles
        for name, _ in find_plugin_styles():
      File "/usr/lib/python3.10/site-packages/pygments/plugin.py", line 63, in find_plugin_styles
        for entrypoint in iter_entry_points(STYLE_ENTRY_POINT):
      File "/usr/lib/python3.10/site-packages/pygments/plugin.py", line 45, in iter_entry_points
        import pkg_resources
      File "/usr/lib/python3.10/site-packages/pkg_resources/__init__.py", line 3260, in <module>
        def _initialize_master_working_set():
      File "/usr/lib/python3.10/site-packages/pkg_resources/__init__.py", line 3234, in _call_aside
        f(*args, **kwargs)
      File "/usr/lib/python3.10/site-packages/pkg_resources/__init__.py", line 3272, in _initialize_master_working_set
        working_set = WorkingSet._build_master()
      File "/usr/lib/python3.10/site-packages/pkg_resources/__init__.py", line 581, in _build_master
        ws.require(__requires__)
      File "/usr/lib/python3.10/site-packages/pkg_resources/__init__.py", line 909, in require
        needed = self.resolve(parse_requirements(requirements))
      File "/usr/lib/python3.10/site-packages/pkg_resources/__init__.py", line 795, in resolve
        raise DistributionNotFound(req, requirers)
    pkg_resources.DistributionNotFound: The 'pip' distribution was not found and is required by httpie
    

    Expected result

    The help message


    Debug output

    Please re-run the command with --debug, then copy the entire command & output and paste both below:

    debug output
    http --debug --help
    HTTPie 3.2.1
    Requests 2.27.1
    Pygments 2.12.0
    Python 3.10.5 (main, Jun  8 2022, 02:00:39) [GCC 10.2.1 20201203]
    /usr/bin/python3
    Linux 5.15.45_1
    
    <Environment {'apply_warnings_filter': <function Environment.apply_warnings_filter at 0x7f46416fc160>,
     'args': Namespace(),
     'as_silent': <function Environment.as_silent at 0x7f46416fc040>,
     'colors': 256,
     'config': {'default_options': []},
     'config_dir': PosixPath('/home/abby/.config/httpie'),
     'devnull': <property object at 0x7f46416e8310>,
     'is_windows': False,
     'log_error': <function Environment.log_error at 0x7f46416fc0d0>,
     'program_name': 'http',
     'quiet': 0,
     'rich_console': <functools.cached_property object at 0x7f46416c8f10>,
     'rich_error_console': <functools.cached_property object at 0x7f46416caa40>,
     'show_displays': True,
     'stderr': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>,
     'stderr_isatty': True,
     'stdin': <_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'>,
     'stdin_encoding': 'utf-8',
     'stdin_isatty': True,
     'stdout': <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>,
     'stdout_encoding': 'utf-8',
     'stdout_isatty': True}>
    
    <PluginManager {'adapters': [],
     'auth': [<class 'httpie.plugins.builtin.BasicAuthPlugin'>,
              <class 'httpie.plugins.builtin.DigestAuthPlugin'>,
              <class 'httpie.plugins.builtin.BearerAuthPlugin'>],
     'converters': [],
     'formatters': [<class 'httpie.output.formatters.headers.HeadersFormatter'>,
                    <class 'httpie.output.formatters.json.JSONFormatter'>,
                    <class 'httpie.output.formatters.xml.XMLFormatter'>,
                    <class 'httpie.output.formatters.colors.ColorFormatter'>]}>
    Traceback (most recent call last):
      File "/usr/bin/http", line 33, in <module>
        sys.exit(load_entry_point('httpie==3.2.1', 'console_scripts', 'http')())
      File "/usr/lib/python3.10/site-packages/httpie/__main__.py", line 9, in main
        exit_status = main()
      File "/usr/lib/python3.10/site-packages/httpie/core.py", line 162, in main
        return raw_main(
      File "/usr/lib/python3.10/site-packages/httpie/core.py", line 77, in raw_main
        parsed_args = parser.parse_args(
      File "/usr/lib/python3.10/site-packages/httpie/cli/argparser.py", line 159, in parse_args
        self.args, no_options = super().parse_known_args(args, namespace)
      File "/usr/lib/python3.10/argparse.py", line 1859, in parse_known_args
        namespace, args = self._parse_known_args(args, namespace)
      File "/usr/lib/python3.10/argparse.py", line 2068, in _parse_known_args
        start_index = consume_optional(start_index)
      File "/usr/lib/python3.10/argparse.py", line 2008, in consume_optional
        take_action(action, args, option_string)
      File "/usr/lib/python3.10/argparse.py", line 1936, in take_action
        action(self, namespace, argument_values, option_string)
      File "/usr/lib/python3.10/argparse.py", line 1099, in __call__
        parser.print_help()
      File "/usr/lib/python3.10/argparse.py", line 2556, in print_help
        self._print_message(self.format_help(), file)
      File "/usr/lib/python3.10/argparse.py", line 2533, in format_help
        formatter.add_arguments(action_group._group_actions)
      File "/usr/lib/python3.10/argparse.py", line 277, in add_arguments
        self.add_argument(action)
      File "/usr/lib/python3.10/argparse.py", line 258, in add_argument
        if action.help is not SUPPRESS:
      File "/usr/lib/python3.10/site-packages/httpie/cli/utils.py", line 60, in help
        self.load(),
      File "/usr/lib/python3.10/site-packages/httpie/cli/utils.py", line 51, in load
        self._obj = self.getter()
      File "/usr/lib/python3.10/site-packages/httpie/output/formatters/colors.py", line 37, in get_available_styles
        return sorted(BUNDLED_STYLES | set(pygments.styles.get_all_styles()))
      File "/usr/lib/python3.10/site-packages/pygments/styles/__init__.py", line 92, in get_all_styles
        for name, _ in find_plugin_styles():
      File "/usr/lib/python3.10/site-packages/pygments/plugin.py", line 63, in find_plugin_styles
        for entrypoint in iter_entry_points(STYLE_ENTRY_POINT):
      File "/usr/lib/python3.10/site-packages/pygments/plugin.py", line 45, in iter_entry_points
        import pkg_resources
      File "/usr/lib/python3.10/site-packages/pkg_resources/__init__.py", line 3260, in <module>
        def _initialize_master_working_set():
      File "/usr/lib/python3.10/site-packages/pkg_resources/__init__.py", line 3234, in _call_aside
        f(*args, **kwargs)
      File "/usr/lib/python3.10/site-packages/pkg_resources/__init__.py", line 3272, in _initialize_master_working_set
        working_set = WorkingSet._build_master()
      File "/usr/lib/python3.10/site-packages/pkg_resources/__init__.py", line 581, in _build_master
        ws.require(__requires__)
      File "/usr/lib/python3.10/site-packages/pkg_resources/__init__.py", line 909, in require
        needed = self.resolve(parse_requirements(requirements))
      File "/usr/lib/python3.10/site-packages/pkg_resources/__init__.py", line 795, in resolve
        raise DistributionNotFound(req, requirers)
    pkg_resources.DistributionNotFound: The 'pip' distribution was not found and is required by httpie
    

    Additional information, screenshots, or code examples

    This was done using void linux's httpie package

    Reviewed by classabbyamp at 2022-06-22 16:16
  • 13. some issues with the copy button

    when i click on the copy button . this what I get copied "# Install httpie choco install httpie" so I think i will be be helpful if i can just copy the "choco install httpie"

    Reviewed by alidauda at 2022-06-20 09:26
  • 14. Multiple response headers with same name combined to a single comma-separated list

    Checklist

    • [x] I've searched for similar issues.
    • [x] I'm using the latest version of HTTPie.

    Minimal reproduction code and steps

    1. Request from any endpoint which produces multiple response headers with the same name

    Current result

    HTTP/1.1 200 OK Connection: keep-alive Content-Length: 2 Content-Type: text/plain Date: Mon, 13 Jun 2022 11:17:01 GMT Server: nginx/1.22.0 edge-cache-tag: origin.stuartmacleod.net-2022-06-13T11-17-01.933Z not-edge-cache-tag: origin.stuartmacleod.net-2022-06-13T11-17-01.933Z testheader: 1, 2, 3

    Expected result

    HTTP/1.1 200 OK Connection: keep-alive Content-Length: 2 Content-Type: text/plain Date: Mon, 13 Jun 2022 11:17:01 GMT Server: nginx/1.22.0 edge-cache-tag: origin.stuartmacleod.net-2022-06-13T11-17-01.933Z not-edge-cache-tag: origin.stuartmacleod.net-2022-06-13T11-17-01.933Z testheader: 1 testheader: 2 testheader: 3

    Debug output

    PS C:\code> http https://origin.stuartmacleod.net/httpie --debug HTTPie 3.2.1 Requests 2.27.1 Pygments 2.11.2 Python 3.8.10 (tags/v3.8.10:3d8993a, May 3 2021, 11:48:03) [MSC v.1928 64 bit (AMD64)] C:\code\Python\Python38\python.exe Windows 10

    <Environment {'apply_warnings_filter': <function Environment.apply_warnings_filter at 0x000001EC361D6310>, 'args': Namespace(), 'as_silent': <function Environment.as_silent at 0x000001EC361D61F0>, 'colors': 256, 'config': {'default_options': ['--style=xcode']}, 'config_dir': WindowsPath('C:/Users/Stuart/AppData/Roaming/httpie'), 'devnull': <property object at 0x000001EC3616B4A0>, 'is_windows': True, 'log_error': <function Environment.log_error at 0x000001EC361D6280>, 'program_name': 'http', 'quiet': 0, 'rich_console': <functools.cached_property object at 0x000001EC36168E20>, 'rich_error_console': <functools.cached_property object at 0x000001EC361764C0>, 'show_displays': True, 'stderr': <colorama.ansitowin32.StreamWrapper object at 0x000001EC36148E50>, 'stderr_isatty': True, 'stdin': <_io.TextIOWrapper name='' mode='r' encoding='utf-8'>, 'stdin_encoding': 'utf-8', 'stdin_isatty': True, 'stdout': <colorama.ansitowin32.StreamWrapper object at 0x000001EC3612FFA0>, 'stdout_encoding': 'utf-8', 'stdout_isatty': True}>

    <PluginManager {'adapters': [], 'auth': [<class 'httpie.plugins.builtin.BasicAuthPlugin'>, <class 'httpie.plugins.builtin.DigestAuthPlugin'>, <class 'httpie.plugins.builtin.BearerAuthPlugin'>], 'converters': [], 'formatters': [<class 'httpie.output.formatters.headers.HeadersFormatter'>, <class 'httpie.output.formatters.json.JSONFormatter'>, <class 'httpie.output.formatters.xml.XMLFormatter'>, <class 'httpie.output.formatters.colors.ColorFormatter'>]}>

    requests.request(**{'auth': None, 'data': RequestJSONDataDict(), 'headers': <HTTPHeadersDict('User-Agent': b'HTTPie/3.2.1')>, 'method': 'get', 'params': <generator object MultiValueOrderedDict.items at 0x000001EC36543200>, 'url': 'https://origin.stuartmacleod.net/httpie'})

    HTTP/1.1 200 OK Connection: keep-alive Content-Length: 2 Content-Type: text/plain Date: Mon, 13 Jun 2022 11:18:15 GMT Server: nginx/1.22.0 edge-cache-tag: origin.stuartmacleod.net-2022-06-13T11-18-15.040Z not-edge-cache-tag: origin.stuartmacleod.net-2022-06-13T11-18-15.040Z testheader: 1, 2, 3

    ok

    Additional information, screenshots, or code examples

    This behaviour was changed after version 2.4.0. With 2.4.0 and earlier it outputs as expected, so I assume this was a deliberate move. If so, is there an option to use the previous output behaviour I could add to my config.json?

    Reviewed by stuartio at 2022-06-13 11:27
  • 15. Help option crash

    Checklist

    • [X] I've searched for similar issues.
    • [X] I'm using the latest version of HTTPie.

    Minimal reproduction code and steps

    1. install httpie latest version on debian
    2. run the command http --help

    Current result

    Traceback (most recent call last):
      File "http_cli.py", line 5, in <module>
      File "httpie/__main__.py", line 9, in main
      File "httpie/core.py", line 162, in main
      File "httpie/core.py", line 77, in raw_main
      File "httpie/cli/argparser.py", line 159, in parse_args
      File "argparse.py", line 1869, in parse_known_args
      File "argparse.py", line 2078, in _parse_known_args
      File "argparse.py", line 2018, in consume_optional
      File "argparse.py", line 1946, in take_action
      File "argparse.py", line 1110, in __call__
      File "argparse.py", line 2566, in print_help
      File "httpie/cli/argparser.py", line 125, in _print_message
      File "argparse.py", line 2572, in _print_message
    UnicodeEncodeError: 'ascii' codec can't encode character '\u2019' in position 10678: ordinal not in range(128)
    [19189] Failed to execute script 'http_cli' due to unhandled exception!
    

    Expected result

    The help menu from httpie.


    Debug output

    Please re-run the command with --debug, then copy the entire command & output and paste both below:

    $ http --debug --help
    HTTPie 3.2.1
    Requests 2.27.1
    Pygments 2.12.0
    Python 3.9.12 (main, Apr 16 2022, 19:31:36)
    [GCC 7.5.0]
    /usr/bin/http
    Linux 4.19.0-16-cloud-amd64
    
    <Environment {'apply_warnings_filter': <function Environment.apply_warnings_filter at 0x7f1a16b09a60>,
     'args': Namespace(),
     'as_silent': <function Environment.as_silent at 0x7f1a16b09940>,
     'colors': 256,
     'config': {'__meta__': {'about': 'HTTPie configuration file',
                             'help': 'https://httpie.org/docs#config',
                             'httpie': '0.9.8'},
                'default_options': []},
     'config_dir': PosixPath('/home/debian/.httpie'),
     'devnull': <property object at 0x7f1a16b0c1d0>,
     'is_windows': False,
     'log_error': <function Environment.log_error at 0x7f1a16b099d0>,
     'program_name': 'http',
     'quiet': 0,
     'rich_console': <functools.cached_property object at 0x7f1a16b02a00>,
     'rich_error_console': <functools.cached_property object at 0x7f1a16af5400>,
     'show_displays': True,
     'stderr': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='ascii'>,
     'stderr_isatty': True,
     'stdin': <_io.TextIOWrapper name='<stdin>' mode='r' encoding='ascii'>,
     'stdin_encoding': 'ascii',
     'stdin_isatty': True,
     'stdout': <_io.TextIOWrapper name='<stdout>' mode='w' encoding='ascii'>,
     'stdout_encoding': 'ascii',
     'stdout_isatty': True}>
    
    <PluginManager {'adapters': [],
     'auth': [<class 'httpie.plugins.builtin.BasicAuthPlugin'>,
              <class 'httpie.plugins.builtin.DigestAuthPlugin'>,
              <class 'httpie.plugins.builtin.BearerAuthPlugin'>],
     'converters': [],
     'formatters': [<class 'httpie.output.formatters.headers.HeadersFormatter'>,
                    <class 'httpie.output.formatters.json.JSONFormatter'>,
                    <class 'httpie.output.formatters.xml.XMLFormatter'>,
                    <class 'httpie.output.formatters.colors.ColorFormatter'>]}>
    Traceback (most recent call last):
      File "http_cli.py", line 5, in <module>
      File "httpie/__main__.py", line 9, in main
      File "httpie/core.py", line 162, in main
      File "httpie/core.py", line 77, in raw_main
      File "httpie/cli/argparser.py", line 159, in parse_args
      File "argparse.py", line 1869, in parse_known_args
      File "argparse.py", line 2078, in _parse_known_args
      File "argparse.py", line 2018, in consume_optional
      File "argparse.py", line 1946, in take_action
      File "argparse.py", line 1110, in __call__
      File "argparse.py", line 2566, in print_help
      File "httpie/cli/argparser.py", line 125, in _print_message
      File "argparse.py", line 2572, in _print_message
    UnicodeEncodeError: 'ascii' codec can't encode character '\u2019' in position 10678: ordinal not in range(128)
    [19180] Failed to execute script 'http_cli' due to unhandled exception!
    

    Additional information, screenshots, or code examples

    I am on a cloud linux vps with debian 10. I used the pip version before but I uninstalled it to be sure.

    Reviewed by troplolBE at 2022-06-08 12:13
  • 16. Python 3.11 test failures: Different enum reprs and different cookie order

    Checklist

    • [x] I've searched for similar issues.
    • [x] I'm using the latest version of HTTPie.

    Minimal reproduction code and steps

    The tests are failing with Python 3.11.0b3.

    1. git clone httpie and cd into it, this is on the master branch @ 418b12bbd6072585118c06c5c4e17996d7f0b085
    2. python3.11 -m venv __venv__ and . __venv__/bin/activate
    3. pip install '.[test]'
    4. pytest tests/

    Current result

    ============================= test session starts ==============================
    platform linux -- Python 3.11.0b3, pytest-7.1.2, pluggy-1.0.0
    rootdir: .../httpie, configfile: pytest.ini
    plugins: mock-3.7.0, lazy-fixture-0.6.3, httpbin-1.0.2, forked-1.4.0, xdist-2.5.0
    collected 1026 items
    
    tests/test_auth.py ..........                                            [  0%]
    tests/test_compress.py .......                                           [  1%]
    tests/test_downloads.py ......                                           [  2%]
    tests/test_errors.py ....                                                [  2%]
    tests/test_httpie.py ...........s...............                         [  5%]
    tests/test_json.py .                                                     [  5%]
    tests/test_auth.py ..........                                            [  6%]
    tests/test_compress.py .......                                           [  7%]
    tests/test_downloads.py ......                                           [  7%]
    tests/test_errors.py ....                                                [  7%]
    tests/test_httpie.py ...........s...............                         [ 10%]
    tests/test_json.py .                                                     [ 10%]
    tests/test_auth.py .........                                             [ 11%]
    tests/test_auth_plugins.py ....                                          [ 11%]
    tests/test_binary.py ......                                              [ 12%]
    tests/test_cli.py ..............F.......................                 [ 16%]
    tests/test_cli_ui.py ....                                                [ 16%]
    tests/test_cli_utils.py ..                                               [ 16%]
    tests/test_compress.py ..                                                [ 17%]
    tests/test_config.py ........s                                           [ 17%]
    tests/test_cookie.py .                                                   [ 18%]
    tests/test_cookie_on_redirects.py .....................                  [ 20%]
    tests/test_defaults.py .................                                 [ 21%]
    tests/test_downloads.py ....................                             [ 23%]
    tests/test_encoding.py ................................................. [ 28%]
    ....                                                                     [ 28%]
    tests/test_errors.py ....                                                [ 29%]
    tests/test_exit_status.py .........                                      [ 30%]
    tests/test_httpie.py ......................                              [ 32%]
    tests/test_httpie_cli.py .....................................           [ 35%]
    tests/test_json.py ..................................................... [ 41%]
    ........................................................................ [ 48%]
    ........................................................................ [ 55%]
    ........................................................................ [ 62%]
    .......................                                                  [ 64%]
    tests/test_meta.py ......                                                [ 64%]
    tests/test_offline.py .........                                          [ 65%]
    tests/test_output.py ......FF.FxXX...................................... [ 70%]
    ........................................................................ [ 77%]
    .                                                                        [ 77%]
    tests/test_parser_schema.py .                                            [ 77%]
    tests/test_plugins_cli.py ......FFFF..F.F                                [ 79%]
    tests/test_redirects.py ...x......                                       [ 80%]
    tests/test_regressions.py ...                                            [ 80%]
    tests/test_sessions.py .........................FF.F.................... [ 85%]
    ............                                                             [ 86%]
    tests/test_ssl.py .ss.....pytest-httpbin server hit an exception serving request: EOF occurred in violation of protocol (_ssl.c:992)
    attempting to ignore so the rest of the tests can run
    ............pytest-httpbin server hit an exception serving request: EOF occurred in violation of protocol (_ssl.c:992)
    attempting to ignore so the rest of the tests can run
    ...                                [ 88%]
    tests/test_stream.py ................                                    [ 90%]
    tests/test_tokens.py ...................                                 [ 92%]
    tests/test_transport_plugin.py .                                         [ 92%]
    tests/test_update_warnings.py ............                               [ 93%]
    tests/test_uploads.py ...........................                        [ 96%]
    tests/test_windows.py s.                                                 [ 96%]
    tests/test_xml.py .................                                      [ 98%]
    tests/utils/matching/test_matching.py ....................               [100%]
    
    =================================== FAILURES ===================================
    _______________________ test_url_colon_slash_slash_only ________________________
    
        def test_url_colon_slash_slash_only():
            r = http('://', tolerate_error_exit_status=True)
    >       assert r.stderr.strip() == "http: error: InvalidURL: Invalid URL 'http://': No host supplied"
    E       AssertionError: assert 'http: LogLev...host supplied' == 'http: error:...host supplied'
    E         - http: error: InvalidURL: Invalid URL 'http://': No host supplied
    E         ?        ^^^^
    E         + http: LogLevel.ERROR: InvalidURL: Invalid URL 'http://': No host supplied
    E         ?       ++++ ^^^^^^^^^
    
    tests/test_cli.py:192: AssertionError
    ----------------------------- Captured stderr call -----------------------------
    
    http: LogLevel.ERROR: InvalidURL: Invalid URL 'http://': No host supplied
    
    
    _____________ TestQuietFlag.test_quiet_with_check_status_non_zero ______________
    
    self = <tests.test_output.TestQuietFlag object at 0x7ff4dcbdfe90>
    httpbin = <pytest_httpbin.serve.Server object at 0x7ff4dcb5a4d0>
    
        def test_quiet_with_check_status_non_zero(self, httpbin):
            r = http(
                '--quiet', '--check-status', httpbin + '/status/500',
                tolerate_error_exit_status=True,
            )
    >       assert 'http: warning: HTTP 500' in r.stderr
    E       AssertionError: assert 'http: warning: HTTP 500' in '\nhttp: LogLevel.WARNING: HTTP 500 INTERNAL SERVER ERROR\n\n\n'
    E        +  where '\nhttp: LogLevel.WARNING: HTTP 500 INTERNAL SERVER ERROR\n\n\n' = ''.stderr
    
    tests/test_output.py:69: AssertionError
    ----------------------------- Captured stderr call -----------------------------
    127.0.0.1 - - [07/Jun/2022 16:23:54] "GET /status/500 HTTP/1.1" 500 0
    
    http: LogLevel.WARNING: HTTP 500 INTERNAL SERVER ERROR
    
    
    ___________ TestQuietFlag.test_quiet_with_check_status_non_zero_pipe ___________
    
    self = <tests.test_output.TestQuietFlag object at 0x7ff4dcbe4650>
    httpbin = <pytest_httpbin.serve.Server object at 0x7ff4dcb5a4d0>
    
        def test_quiet_with_check_status_non_zero_pipe(self, httpbin):
            r = http(
                '--quiet', '--check-status', httpbin + '/status/500',
                tolerate_error_exit_status=True,
                env=MockEnvironment(stdout_isatty=False)
            )
    >       assert 'http: warning: HTTP 500' in r.stderr
    E       AssertionError: assert 'http: warning: HTTP 500' in '\nhttp: LogLevel.WARNING: HTTP 500 INTERNAL SERVER ERROR\n\n\n'
    E        +  where '\nhttp: LogLevel.WARNING: HTTP 500 INTERNAL SERVER ERROR\n\n\n' = ''.stderr
    
    tests/test_output.py:77: AssertionError
    ----------------------------- Captured stderr call -----------------------------
    127.0.0.1 - - [07/Jun/2022 16:23:54] "GET /status/500 HTTP/1.1" 500 0
    
    http: LogLevel.WARNING: HTTP 500 INTERNAL SERVER ERROR
    
    
    ________ TestQuietFlag.test_quiet_quiet_with_check_status_non_zero_pipe ________
    
    self = <tests.test_output.TestQuietFlag object at 0x7ff4dcbe5550>
    httpbin = <pytest_httpbin.serve.Server object at 0x7ff4dcb5a4d0>
    
        def test_quiet_quiet_with_check_status_non_zero_pipe(self, httpbin):
            r = http(
                '--quiet', '--quiet', '--check-status', httpbin + '/status/500',
                tolerate_error_exit_status=True,
                env=MockEnvironment(stdout_isatty=False)
            )
    >       assert 'http: warning: HTTP 500' in r.stderr
    E       AssertionError: assert 'http: warning: HTTP 500' in '\nhttp: LogLevel.WARNING: HTTP 500 INTERNAL SERVER ERROR\n\n\n'
    E        +  where '\nhttp: LogLevel.WARNING: HTTP 500 INTERNAL SERVER ERROR\n\n\n' = ''.stderr
    
    tests/test_output.py:92: AssertionError
    ----------------------------- Captured stderr call -----------------------------
    127.0.0.1 - - [07/Jun/2022 16:23:54] "GET /status/500 HTTP/1.1" 500 0
    
    http: LogLevel.WARNING: HTTP 500 INTERNAL SERVER ERROR
    
    
    _________________________ test_plugins_uninstall[True] _________________________
    
    interface = Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uninstall_True_0/interface'), environment=<...out': <tempfile._TemporaryFileWrapper object at 0x7ff4d5c78410>,
     'stdout_encoding': 'utf-8',
     'stdout_isatty': True}>)
    httpie_plugins_success = <function httpie_plugins_success.<locals>.runner at 0x7ff4d5cbe0c0>
    dummy_plugin = Plugin(interface=Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uninstall_True_0/interface...ue}>), name='httpie-4bef7587', version='1.0.0', entry_points=[EntryPoint(name='test', group='httpie.plugins.auth.v1')])
    cli_mode = True
    
        @pytest.mark.requires_installation
        @pytest.mark.parametrize('cli_mode', [True, False])
        def test_plugins_uninstall(interface, httpie_plugins_success, dummy_plugin, cli_mode):
            httpie_plugins_success('install', dummy_plugin.path, cli_mode=cli_mode)
            httpie_plugins_success('uninstall', dummy_plugin.name, cli_mode=cli_mode)
    >       assert not interface.is_installed(dummy_plugin.name)
    E       AssertionError: assert not True
    E        +  where True = <bound method Interface.is_installed of Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uni...ut': <tempfile._TemporaryFileWrapper object at 0x7ff4d5c78410>,\n 'stdout_encoding': 'utf-8',\n 'stdout_isatty': True}>)>('httpie-4bef7587')
    E        +    where <bound method Interface.is_installed of Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uni...ut': <tempfile._TemporaryFileWrapper object at 0x7ff4d5c78410>,\n 'stdout_encoding': 'utf-8',\n 'stdout_isatty': True}>)> = Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uninstall_True_0/interface'), environment=<...out': <tempfile._TemporaryFileWrapper object at 0x7ff4d5c78410>,\n 'stdout_encoding': 'utf-8',\n 'stdout_isatty': True}>).is_installed
    E        +    and   'httpie-4bef7587' = Plugin(interface=Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uninstall_True_0/interface...ue}>), name='httpie-4bef7587', version='1.0.0', entry_points=[EntryPoint(name='test', group='httpie.plugins.auth.v1')]).name
    
    tests/test_plugins_cli.py:59: AssertionError
    ________________________ test_plugins_uninstall[False] _________________________
    
    interface = Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uninstall_False_0/interface'), environment=...out': <tempfile._TemporaryFileWrapper object at 0x7ff4d5c811d0>,
     'stdout_encoding': 'utf-8',
     'stdout_isatty': True}>)
    httpie_plugins_success = <function httpie_plugins_success.<locals>.runner at 0x7ff4d5cac220>
    dummy_plugin = Plugin(interface=Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uninstall_False_0/interfac...ue}>), name='httpie-300cc8fa', version='1.0.0', entry_points=[EntryPoint(name='test', group='httpie.plugins.auth.v1')])
    cli_mode = False
    
        @pytest.mark.requires_installation
        @pytest.mark.parametrize('cli_mode', [True, False])
        def test_plugins_uninstall(interface, httpie_plugins_success, dummy_plugin, cli_mode):
            httpie_plugins_success('install', dummy_plugin.path, cli_mode=cli_mode)
            httpie_plugins_success('uninstall', dummy_plugin.name, cli_mode=cli_mode)
    >       assert not interface.is_installed(dummy_plugin.name)
    E       AssertionError: assert not True
    E        +  where True = <bound method Interface.is_installed of Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uni...ut': <tempfile._TemporaryFileWrapper object at 0x7ff4d5c811d0>,\n 'stdout_encoding': 'utf-8',\n 'stdout_isatty': True}>)>('httpie-300cc8fa')
    E        +    where <bound method Interface.is_installed of Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uni...ut': <tempfile._TemporaryFileWrapper object at 0x7ff4d5c811d0>,\n 'stdout_encoding': 'utf-8',\n 'stdout_isatty': True}>)> = Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uninstall_False_0/interface'), environment=...out': <tempfile._TemporaryFileWrapper object at 0x7ff4d5c811d0>,\n 'stdout_encoding': 'utf-8',\n 'stdout_isatty': True}>).is_installed
    E        +    and   'httpie-300cc8fa' = Plugin(interface=Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uninstall_False_0/interfac...ue}>), name='httpie-300cc8fa', version='1.0.0', entry_points=[EntryPoint(name='test', group='httpie.plugins.auth.v1')]).name
    
    tests/test_plugins_cli.py:59: AssertionError
    _____________________ test_plugins_listing_after_uninstall _____________________
    
    interface = Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_listing_after_uni0/interface'), environment...out': <tempfile._TemporaryFileWrapper object at 0x7ff4d5dbc410>,
     'stdout_encoding': 'utf-8',
     'stdout_isatty': True}>)
    httpie_plugins_success = <function httpie_plugins_success.<locals>.runner at 0x7ff4d5cd2200>
    dummy_plugin = Plugin(interface=Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_listing_after_uni0/interfa...ue}>), name='httpie-99a195f1', version='1.0.0', entry_points=[EntryPoint(name='test', group='httpie.plugins.auth.v1')])
    
        @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)
        
            data = parse_listing(httpie_plugins_success('list'))
    >       assert len(data) == 0
    E       AssertionError: assert 1 == 0
    E        +  where 1 = len({'httpie-99a195f1': {'entry_points': [{'group': 'httpie.plugins.auth.v1', 'name': 'test'}], 'version': '1.0.0'}})
    
    tests/test_plugins_cli.py:68: AssertionError
    _______________________ test_plugins_uninstall_specific ________________________
    
    interface = Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uninstall_specifi0/interface'), environment...out': <tempfile._TemporaryFileWrapper object at 0x7ff4d5cc8950>,
     'stdout_encoding': 'utf-8',
     'stdout_isatty': True}>)
    httpie_plugins_success = <function httpie_plugins_success.<locals>.runner at 0x7ff4d5cd3560>
    
        @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()
            target_plugin = interface.make_dummy_plugin()
        
            httpie_plugins_success('install', new_plugin_1.path, new_plugin_2.path, target_plugin.path)
            httpie_plugins_success('uninstall', target_plugin.name)
        
            assert interface.is_installed(new_plugin_1.name)
            assert interface.is_installed(new_plugin_2.name)
    >       assert not interface.is_installed(target_plugin.name)
    E       AssertionError: assert not True
    E        +  where True = <bound method Interface.is_installed of Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uni...ut': <tempfile._TemporaryFileWrapper object at 0x7ff4d5cc8950>,\n 'stdout_encoding': 'utf-8',\n 'stdout_isatty': True}>)>('httpie-79b6b9b0')
    E        +    where <bound method Interface.is_installed of Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uni...ut': <tempfile._TemporaryFileWrapper object at 0x7ff4d5cc8950>,\n 'stdout_encoding': 'utf-8',\n 'stdout_isatty': True}>)> = Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uninstall_specifi0/interface'), environment...out': <tempfile._TemporaryFileWrapper object at 0x7ff4d5cc8950>,\n 'stdout_encoding': 'utf-8',\n 'stdout_isatty': True}>).is_installed
    E        +    and   'httpie-79b6b9b0' = Plugin(interface=Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_uninstall_specifi0/interfa...ue}>), name='httpie-79b6b9b0', version='1.0.0', entry_points=[EntryPoint(name='test', group='httpie.plugins.auth.v1')]).name
    
    tests/test_plugins_cli.py:82: AssertionError
    ________________________ test_plugins_double_uninstall _________________________
    
    httpie_plugins = <function httpie_plugins.<locals>.runner at 0x7ff4d5cfa160>
    httpie_plugins_success = <function httpie_plugins_success.<locals>.runner at 0x7ff4d5cfa3e0>
    dummy_plugin = Plugin(interface=Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_plugins_double_uninstall0/interfac...ue}>), name='httpie-6d157572', version='1.0.0', entry_points=[EntryPoint(name='test', group='httpie.plugins.auth.v1')])
    
        @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)
        
            result = httpie_plugins("uninstall", dummy_plugin.name)
        
    >       assert result.exit_status == ExitStatus.ERROR
    E       AssertionError: assert <ExitStatus.SUCCESS: 0> == <ExitStatus.ERROR: 1>
    E        +  where <ExitStatus.SUCCESS: 0> = 'Successfully uninstalled httpie-6d157572\n'.exit_status
    E        +  and   <ExitStatus.ERROR: 1> = ExitStatus.ERROR
    
    tests/test_plugins_cli.py:113: AssertionError
    _____________________________ test_broken_plugins ______________________________
    
    httpie_plugins = <function httpie_plugins.<locals>.runner at 0x7ff4d6d29300>
    httpie_plugins_success = <function httpie_plugins_success.<locals>.runner at 0x7ff4d76eb920>
    dummy_plugin = Plugin(interface=Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_broken_plugins0/interface'), envir...ue}>), name='httpie-8972797e', version='1.0.0', entry_points=[EntryPoint(name='test', group='httpie.plugins.auth.v1')])
    broken_plugin = Plugin(interface=Interface(path=PosixPath('/tmp/pytest-of-.../pytest-31/test_broken_plugins0/interface'), envir...ue}>), name='httpie-4cd7d933', version='1.0.0', entry_points=[EntryPoint(name='test', group='httpie.plugins.auth.v1')])
    
        @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)
        
            with pytest.warns(
                UserWarning,
                match=(
                    f'While loading "{broken_plugin.name}", an error'
                    ' occurred: broken plugin'
                )
            ):
                data = parse_listing(httpie_plugins_success('list'))
                assert len(data) == 2
        
            # We load before the uninstallation, so it will warn again.
            with pytest.warns(UserWarning):
                httpie_plugins_success("uninstall", broken_plugin.name)
        
            # No warning now, since it is uninstalled.
            data = parse_listing(httpie_plugins_success('list'))
    >       assert len(data) == 1
    E       AssertionError: assert 2 == 1
    E        +  where 2 = len({'httpie-4cd7d933': {'entry_points': [{'group': 'httpie.plugins.auth.v1', 'name': 'test'}], 'version': '1.0.0'}, 'httpie-8972797e': {'entry_points': [{'group': 'httpie.plugins.auth.v1', 'name': 'test'}], 'version': '1.0.0'}})
    
    tests/test_plugins_cli.py:153: AssertionError
    _ TestCookieStorage.test_existing_and_new_cookies_sent_in_request[new=bar;chocolate=milk-new_cookies_dict1-chocolate=milk; cookie1=foo; cookie2=foo; new=bar] _
    
    self = <tests.test_sessions.TestCookieStorage object at 0x7ff4dca91c10>
    new_cookies = 'new=bar;chocolate=milk'
    new_cookies_dict = {'chocolate': 'milk', 'new': 'bar'}
    expected = 'chocolate=milk; cookie1=foo; cookie2=foo; new=bar'
    httpbin = <pytest_httpbin.serve.Server object at 0x7ff4dcb5a4d0>
    
        @pytest.mark.parametrize(
            'new_cookies, new_cookies_dict, expected',
            [(
                'new=bar',
                {'new': 'bar'},
                'cookie1=foo; cookie2=foo; new=bar'
            ),
                (
                'new=bar;chocolate=milk',
                {'new': 'bar', 'chocolate': 'milk'},
                'chocolate=milk; cookie1=foo; cookie2=foo; new=bar'
            ),
                (
                'new=bar; chocolate=milk',
                {'new': 'bar', 'chocolate': 'milk'},
                'chocolate=milk; cookie1=foo; cookie2=foo; new=bar'
            ),
                (
                'new=bar;; chocolate=milk;;;',
                {'new': 'bar', 'chocolate': 'milk'},
                'cookie1=foo; cookie2=foo; new=bar'
            ),
                (
                'new=bar; chocolate=milk;;;',
                {'new': 'bar', 'chocolate': 'milk'},
                'chocolate=milk; cookie1=foo; cookie2=foo; new=bar'
            )
            ]
        )
        def test_existing_and_new_cookies_sent_in_request(self, new_cookies, new_cookies_dict, expected, httpbin):
            r = http(
                '--session', str(self.session_path),
                '--print=H',
                httpbin.url,
                'Cookie:' + new_cookies,
            )
            # Note: cookies in response are in alphabetical order
    >       assert f'Cookie: {expected}' in r
    E       AssertionError: assert 'Cookie: chocolate=milk; cookie1=foo; cookie2=foo; new=bar' in 'GET / HTTP/1.1\r\nAccept: */*\r\nAccept-Encoding: gzip, deflate, br\r\nConnection: keep-alive\r\nCookie: cookie1=foo; cookie2=foo; new=bar; chocolate=milk\r\nHost: 127.0.0.1:38085\r\nUser-Agent: HTTPie/3.2.1\r\n\r\n'
    
    tests/test_sessions.py:485: AssertionError
    ----------------------------- Captured stderr call -----------------------------
    127.0.0.1 - - [07/Jun/2022 16:24:20] "GET / HTTP/1.1" 200 12144
    _ TestCookieStorage.test_existing_and_new_cookies_sent_in_request[new=bar; chocolate=milk-new_cookies_dict2-chocolate=milk; cookie1=foo; cookie2=foo; new=bar] _
    
    self = <tests.test_sessions.TestCookieStorage object at 0x7ff4dca91e90>
    new_cookies = 'new=bar; chocolate=milk'
    new_cookies_dict = {'chocolate': 'milk', 'new': 'bar'}
    expected = 'chocolate=milk; cookie1=foo; cookie2=foo; new=bar'
    httpbin = <pytest_httpbin.serve.Server object at 0x7ff4dcb5a4d0>
    
        @pytest.mark.parametrize(
            'new_cookies, new_cookies_dict, expected',
            [(
                'new=bar',
                {'new': 'bar'},
                'cookie1=foo; cookie2=foo; new=bar'
            ),
                (
                'new=bar;chocolate=milk',
                {'new': 'bar', 'chocolate': 'milk'},
                'chocolate=milk; cookie1=foo; cookie2=foo; new=bar'
            ),
                (
                'new=bar; chocolate=milk',
                {'new': 'bar', 'chocolate': 'milk'},
                'chocolate=milk; cookie1=foo; cookie2=foo; new=bar'
            ),
                (
                'new=bar;; chocolate=milk;;;',
                {'new': 'bar', 'chocolate': 'milk'},
                'cookie1=foo; cookie2=foo; new=bar'
            ),
                (
                'new=bar; chocolate=milk;;;',
                {'new': 'bar', 'chocolate': 'milk'},
                'chocolate=milk; cookie1=foo; cookie2=foo; new=bar'
            )
            ]
        )
        def test_existing_and_new_cookies_sent_in_request(self, new_cookies, new_cookies_dict, expected, httpbin):
            r = http(
                '--session', str(self.session_path),
                '--print=H',
                httpbin.url,
                'Cookie:' + new_cookies,
            )
            # Note: cookies in response are in alphabetical order
    >       assert f'Cookie: {expected}' in r
    E       AssertionError: assert 'Cookie: chocolate=milk; cookie1=foo; cookie2=foo; new=bar' in 'GET / HTTP/1.1\r\nAccept: */*\r\nAccept-Encoding: gzip, deflate, br\r\nConnection: keep-alive\r\nCookie: cookie1=foo; cookie2=foo; new=bar; chocolate=milk\r\nHost: 127.0.0.1:38085\r\nUser-Agent: HTTPie/3.2.1\r\n\r\n'
    
    tests/test_sessions.py:485: AssertionError
    ----------------------------- Captured stderr call -----------------------------
    127.0.0.1 - - [07/Jun/2022 16:24:20] "GET / HTTP/1.1" 200 12144
    _ TestCookieStorage.test_existing_and_new_cookies_sent_in_request[new=bar; chocolate=milk;;;-new_cookies_dict4-chocolate=milk; cookie1=foo; cookie2=foo; new=bar] _
    
    self = <tests.test_sessions.TestCookieStorage object at 0x7ff4dca925d0>
    new_cookies = 'new=bar; chocolate=milk;;;'
    new_cookies_dict = {'chocolate': 'milk', 'new': 'bar'}
    expected = 'chocolate=milk; cookie1=foo; cookie2=foo; new=bar'
    httpbin = <pytest_httpbin.serve.Server object at 0x7ff4dcb5a4d0>
    
        @pytest.mark.parametrize(
            'new_cookies, new_cookies_dict, expected',
            [(
                'new=bar',
                {'new': 'bar'},
                'cookie1=foo; cookie2=foo; new=bar'
            ),
                (
                'new=bar;chocolate=milk',
                {'new': 'bar', 'chocolate': 'milk'},
                'chocolate=milk; cookie1=foo; cookie2=foo; new=bar'
            ),
                (
                'new=bar; chocolate=milk',
                {'new': 'bar', 'chocolate': 'milk'},
                'chocolate=milk; cookie1=foo; cookie2=foo; new=bar'
            ),
                (
                'new=bar;; chocolate=milk;;;',
                {'new': 'bar', 'chocolate': 'milk'},
                'cookie1=foo; cookie2=foo; new=bar'
            ),
                (
                'new=bar; chocolate=milk;;;',
                {'new': 'bar', 'chocolate': 'milk'},
                'chocolate=milk; cookie1=foo; cookie2=foo; new=bar'
            )
            ]
        )
        def test_existing_and_new_cookies_sent_in_request(self, new_cookies, new_cookies_dict, expected, httpbin):
            r = http(
                '--session', str(self.session_path),
                '--print=H',
                httpbin.url,
                'Cookie:' + new_cookies,
            )
            # Note: cookies in response are in alphabetical order
    >       assert f'Cookie: {expected}' in r
    E       AssertionError: assert 'Cookie: chocolate=milk; cookie1=foo; cookie2=foo; new=bar' in 'GET / HTTP/1.1\r\nAccept: */*\r\nAccept-Encoding: gzip, deflate, br\r\nConnection: keep-alive\r\nCookie: cookie1=foo; cookie2=foo; new=bar; chocolate=milk\r\nHost: 127.0.0.1:38085\r\nUser-Agent: HTTPie/3.2.1\r\n\r\n'
    
    tests/test_sessions.py:485: AssertionError
    ----------------------------- Captured stderr call -----------------------------
    127.0.0.1 - - [07/Jun/2022 16:24:20] "GET / HTTP/1.1" 200 12144
    =============================== warnings summary ===============================
    ...
    =========================== short test summary info ============================
    FAILED tests/test_cli.py::test_url_colon_slash_slash_only - AssertionError: a...
    FAILED tests/test_output.py::TestQuietFlag::test_quiet_with_check_status_non_zero
    FAILED tests/test_output.py::TestQuietFlag::test_quiet_with_check_status_non_zero_pipe
    FAILED tests/test_output.py::TestQuietFlag::test_quiet_quiet_with_check_status_non_zero_pipe
    FAILED tests/test_plugins_cli.py::test_plugins_uninstall[True] - AssertionErr...
    FAILED tests/test_plugins_cli.py::test_plugins_uninstall[False] - AssertionEr...
    FAILED tests/test_plugins_cli.py::test_plugins_listing_after_uninstall - Asse...
    FAILED tests/test_plugins_cli.py::test_plugins_uninstall_specific - Assertion...
    FAILED tests/test_plugins_cli.py::test_plugins_double_uninstall - AssertionEr...
    FAILED tests/test_plugins_cli.py::test_broken_plugins - AssertionError: asser...
    FAILED tests/test_sessions.py::TestCookieStorage::test_existing_and_new_cookies_sent_in_request[new=bar;chocolate=milk-new_cookies_dict1-chocolate=milk; cookie1=foo; cookie2=foo; new=bar]
    FAILED tests/test_sessions.py::TestCookieStorage::test_existing_and_new_cookies_sent_in_request[new=bar; chocolate=milk-new_cookies_dict2-chocolate=milk; cookie1=foo; cookie2=foo; new=bar]
    FAILED tests/test_sessions.py::TestCookieStorage::test_existing_and_new_cookies_sent_in_request[new=bar; chocolate=milk;;;-new_cookies_dict4-chocolate=milk; cookie1=foo; cookie2=foo; new=bar]
    = 13 failed, 1003 passed, 6 skipped, 2 xfailed, 2 xpassed, 351 warnings in 56.38s =
    

    Expected result

    Tests pass.

    Debug output

    Please re-run the command with --debug, then copy the entire command & output and paste both below:

    Not relevant.

    Additional information, screenshots, or code examples

    We are about to update to Python 3.11 in Fedora 37 (the development version of Fedora). This is not yet blocking our users, but getting it sorted out will be eventually required. Fedora 37 Beta is to be released in September 2022.

    I believe that most of the test failures observed, if not all, are bad test expectations rather than actual problems in httpie.

    Reviewed by hroncok at 2022-06-07 14:30
rh: user-friendly command-line HTTP client

Rust HTTP Cli The command name in your terminal is rh. rh: user-friendly command-line HTTP client rh is a user-friendly, lightweight and performant co

May 29, 2022
A more modern http framework benchmarker supporting HTTP/1 and HTTP/2 benchmarks.

rewrk A more modern http framework benchmark utility.

Jun 17, 2022
Fast and friendly HTTP server framework for async Rust
Fast and friendly HTTP server framework for async Rust

Tide Serve the web API Docs | Contributing | Chat Tide is a minimal and pragmatic Rust web application framework built for rapid development. It comes

Jun 22, 2022
An easy and powerful Rust HTTP Client

reqwest An ergonomic, batteries-included HTTP Client for Rust. Plain bodies, JSON, urlencoded, multipart Customizable redirect policy HTTP Proxies HTT

Jun 26, 2022
FeignHttp is a declarative HTTP client. Based on rust macros.

FeignHttp is a declarative HTTP client. Based on rust macros. Features Easy to use Asynchronous request Configurable timeout settings Suppor

Jun 8, 2022
Pretend is a macros-based declarative Rust HTTP client

pretend is a modular, Feign-inspired HTTP, client based on macros. It's goal is to decouple the definition of a REST API from it's implementation.

Apr 18, 2022
Minimal Rust HTTP client for both native and WASM

ehttp: a minimal Rust HTTP client for both native and WASM If you want to do HTTP requests and are targetting both native and web (WASM), then this is

Jun 17, 2022
An HTTP library for Rust

hyper A fast and correct HTTP implementation for Rust. HTTP/1 and HTTP/2 Asynchronous design Leading in performance Tested and correct Extensive produ

Jun 24, 2022
🐱‍👤 Drop-in HTTP replacement module for Garry's Mod

??‍?? gmsv_reqwest This module is a drop-in replacement for Garry's Mod's HTTP function, inspired by gmsv_chttp created by timschumi. The module uses

Jun 12, 2022
Multi-stream HTTP downloader using range requests

chooch - An Amazing Project Downloads files faster than wget/curl (in theory) using multiple connections. Chooch recycles the slowest connection and r

Dec 20, 2021
Pyre - A fast python HTTP server inspired by japronto written in rust.

Pyre - A fast python HTTP server inspired by japronto written in rust.

Jun 17, 2022
ratpack: a simpleton's HTTP framework (for rust-lang)

ratpack: a simpleton's HTTP framework (for rust-lang) ratpack is idealized in the simplicity of the sinatra (ruby) framework in its goal, and attempts

Jun 9, 2022
A backend providing a HTTP REST like interface for uploading files written in rust.

UploadServer A backend providing a HTTP REST like interface for uploading files written in rust. API Documentation License This project is licensed un

Jun 5, 2022
Wrapper around reqwest to allow for client middleware chains.

reqwest-middleware A crate implementing a wrapper around reqwest to allow for client middleware chains. Overview The reqwest-middleware client exposes

Jun 7, 2022
xh is a friendly and fast tool for sending HTTP requests. It reimplements as much as possible of HTTPie's excellent design, with a focus on improved performance.
xh is a friendly and fast tool for sending HTTP requests. It reimplements as much as possible of HTTPie's excellent design, with a focus on improved performance.

xh is a friendly and fast tool for sending HTTP requests. It reimplements as much as possible of HTTPie's excellent design, with a focus on improved performance

Jun 24, 2022
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

Jun 24, 2022
This is choose, a human-friendly and fast alternative to cut and (sometimes) awk
This is choose, a human-friendly and fast alternative to cut and (sometimes) awk

Choose This is choose, a human-friendly and fast alternative to cut and (sometimes) awk Features terse field selection syntax similar to Python's list

Jun 18, 2022
Grep with human-friendly search output
Grep with human-friendly search output

hgrep: Human-friendly GREP hgrep is a grep tool to search files with given pattern and print the matched code snippets with human-friendly syntax high

Jun 20, 2022
A simple, human-friendly, embeddable scripting language

Mica Language reference · Rust API A simple, human-friendly scripting language, developed one feature at a time. Human-friendly syntax inspired by Rub

Jun 10, 2022
rh: user-friendly command-line HTTP client

Rust HTTP Cli The command name in your terminal is rh. rh: user-friendly command-line HTTP client rh is a user-friendly, lightweight and performant co

May 29, 2022