This guide is the deep reference for administrators, platform engineers, and developers working with or extending HTTPie — the command-line HTTP client (http, https, and the httpie management interface). It covers the codebase architecture, the request/response pipeline, the plugin API, configuration internals, a security analysis, and contribution guidance.
It is the companion to the HTTPie User Guide (which covers day-to-day command usage). Everything here is derived from the HTTPie source tree at version 3.2.4 (commit 5b604c3). HTTPie is licensed BSD-3-Clause and is implemented in Python, requiring Python 3.7 or newer.
Table of contents
- Executive summary
- Architecture overview
- The request/response pipeline
- Repository structure
- Module reference
- Component inventory
- The plugin API
- Configuration and state on disk
- Sessions: format and lifecycle
- The update-check subsystem
- Security analysis
- Requirements and dependencies
- Code quality and conventions
- Testing strategy
- Building and packaging
- Potential improvements
- Contributing
- Quick reference
Executive summary
HTTPie is a single-purpose, user-facing CLI: it turns a concise command line into an HTTP request, sends it via the Requests library, and renders a colorized, formatted response with Pygments. Its defining design choice is that the command-line syntax mirrors the HTTP message — the order and shape of arguments map directly onto the request that goes over the wire.
Architecturally, HTTPie is a thin, well-factored layer over Requests/urllib3:
- A custom argument layer (
httpie/cli/) parses both--flagsand a small request-item DSL (Header:value,field=value,field:=json,param==value,field@file, …). - A client layer (
httpie/client.py) translates parsed arguments into arequests.Request, mounts HTTPie's own transport adapters, and yields request/response message objects. - An output layer (
httpie/output/) selects a stream class and a chain of formatter plugins to decode, prettify, and write each message. - A plugin system (
httpie/plugins/) exposes four extension points (auth, transport, converter, formatter) loaded from Python entry points. - A management binary (
httpie/manager/) handles plugin install/list/uninstall and session upgrades, distinct from the request commands.
There is no server, no daemon (except a short-lived update fetcher), and no persistent process. State lives in a config directory: config.json, session files, and a cached version-info file.
Architecture overview
┌─────────────────────────────────────────┐
argv ($ http / https / │ ENTRY POINTS │
httpie ...) ───────────► │ __main__.py → core.raw_main() │
│ (program_name basename → default scheme)│
└───────────────┬─────────────────────────┘
│
┌─────────────────────────▼──────────────────────────┐
│ CLI / PARSING LAYER │
│ cli/definition.py ParserSpec → to_argparse() │
│ cli/argparser.py HTTPieArgumentParser │
│ cli/requestitems.py RequestItems.from_args() │
│ cli/argtypes.py KeyValueArgType, auth, SSL │
│ cli/nested_json/ interpret_nested_json() │
└─────────────────────────┬──────────────────────────┘
│ argparse.Namespace
┌─────────────────────────▼──────────────────────────┐
│ CLIENT LAYER │
│ client.collect_messages() │
│ ├─ get_httpie_session() (sessions.py) │
│ ├─ build_requests_session() │
│ │ mount HTTPieHTTPAdapter / HTTPieHTTPSAdapter │
│ │ + TransportPlugin adapters │
│ ├─ make_request_kwargs / make_send_kwargs │
│ └─ yields PreparedRequest / Response objects │
└─────────────────────────┬──────────────────────────┘
│ RequestsMessage stream
┌─────────────────────────▼──────────────────────────┐
│ OUTPUT LAYER │
│ output/writer.py write_message() │
│ output/streams.py Raw/Encoded/Pretty/Buffered │
│ output/processing.py Formatting, Conversion │
│ output/formatters/ Headers/JSON/XML/Colors │
└─────────────────────────┬──────────────────────────┘
│
stdout / stderr / file
(Downloader for --download; Rich for progress)
PLUGINS (entry points) CONFIG / STATE (~/.config/httpie)
├─ httpie.plugins.auth.v1 ├─ config.json
├─ httpie.plugins.transport.v1 ├─ sessions/<host>/<name>.json
├─ httpie.plugins.converter.v1 ├─ version_info.json
└─ httpie.plugins.formatter.v1 └─ plugins/ (isolated install dir)
Two request binaries, one codebase
http and https are the same program. The only difference is the basename of argv[0]: core.raw_main() sets env.program_name = os.path.basename(program_name), and argparser._process_url() chooses the default scheme — when invoked as https, the scheme defaults to https://; otherwise it uses --default-scheme (default http). The httpie binary is a separate entry point (httpie/manager/__main__.py) with its own parser.
The request/response pipeline
The full path from command line to printed response, with the responsible functions:
- Entry —
httpie/__main__.py::main()callscore.main(), which callsraw_main(parser, program, args, env). - Pre-flight —
raw_main()decodes raw byte args, detects daemon mode, loads installed plugins (plugin_manager.load_installed_plugins), prependsconfig.default_options, and handles--debug/--traceback. - Parse —
HTTPieArgumentParser.parse_args()runs a sequence of private processors:_process_request_type,_process_download_options,_process_output_options,_process_pretty_options,_process_format_options,_guess_method,_parse_items,_process_url,_process_auth,_process_ssl_cert. - Request items —
RequestItems.from_args()dispatches each item by its separator to a processor function, populatingheaders,data,params,files, andmultipart_data. JSON nesting is resolved bycli/nested_json/interpret_nested_json(). - Method inference —
_guess_method()defaults toPOSTif there is input data, elseGET. - Build & send —
client.collect_messages()builds arequests.Session, mounts the HTTPie adapters and any transport plugins, prepares the request, applies--path-as-is/--compress, and yields eachPreparedRequestandResponse. Redirects are followed manually (response.next) governed by--follow/--max-redirects. - Output —
core.program()iterates the yielded messages and callsoutput/writer.write_message(), which picks a stream class (get_stream_type_and_kwargs) and writes it toenv.stdout. - Download — when
--downloadis set,Downloader(indownloads.py) handles filename resolution, resume (Range/206), and progress display. - Exit —
coremaps outcomes toExitStatuscodes and HTTPie exits.
Output stream selection
output/writer.py::get_stream_type_and_kwargs() chooses one of four stream classes based on whether output is a TTY, whether prettification is enabled, and whether streaming is active:
| Stream class | Used when |
|---|---|
RawStream |
Output is redirected and not prettified — bytes pass through untouched. |
EncodedStream |
TTY output without formatting — re-encodes to the terminal encoding, suppresses binary. |
PrettyStream |
Prettified and streaming — formats line by line, flushed immediately. |
BufferedPrettyStream |
Prettified, non-streaming — buffers the whole body, then formats once. |
Auto-streaming kicks in for Content-Type: text/event-stream.
Repository structure
httpie/
├── __init__.py Package metadata (__version__ = '3.2.4')
├── __main__.py `http` / `https` entry point
├── core.py raw_main(), main(), program() — orchestration
├── client.py Request building, Requests session, redirects
├── models.py HTTPMessage / HTTPRequest / HTTPResponse, OutputOptions
├── sessions.py Persistent JSON sessions
├── config.py Config + BaseConfigDict, config dir resolution
├── context.py Environment (streams, config, Rich consoles)
├── downloads.py Download mode (Downloader, DownloadStatus)
├── uploads.py Streaming uploads, chunked & compressed bodies
├── ssl_.py HTTPieHTTPSAdapter, TLS version / cipher handling
├── adapters.py HTTPieHTTPAdapter (multi-value header preservation)
├── cookies.py HTTPieCookiePolicy (localhost-as-secure)
├── encoding.py Charset detection / smart decode/encode
├── compat.py Python version shims, importlib_metadata helpers
├── status.py ExitStatus IntEnum, http_status_to_exit_status()
├── utils.py JSON dup-key dict, cookie parsing, lockfiles
├── cli/ Argument parsing & request-item DSL
│ ├── definition.py The `http`/`https` parser spec (every flag)
│ ├── argparser.py HTTPieArgumentParser + processing pipeline
│ ├── argtypes.py KeyValueArgType, AuthCredentials, SSLCredentials
│ ├── constants.py Separator constants, output option chars, enums
│ ├── requestitems.py RequestItems — separator → processor dispatch
│ ├── options.py ParserSpec / Group / Argument abstraction
│ ├── dicts.py HTTPHeadersDict (multidict), multi-value dicts
│ ├── exceptions.py ParseError
│ ├── utils.py Manual / LazyChoices argparse actions
│ └── nested_json/ Nested JSON path parser (tokens, parse, interpret)
├── output/ Response rendering
│ ├── writer.py write_message(), stream selection
│ ├── streams.py Raw/Encoded/Pretty/BufferedPretty streams
│ ├── processing.py Formatting + Conversion delegates
│ ├── models.py ProcessingOptions
│ ├── formatters/ colors, headers, json, xml formatter plugins
│ ├── lexers/ Pygments lexers (http, json, metadata)
│ └── ui/ Rich help, palette, progress, man pages
├── plugins/ Plugin system
│ ├── base.py BasePlugin + Auth/Transport/Converter/Formatter
│ ├── builtin.py Basic / Digest / Bearer auth
│ ├── manager.py PluginManager (entry-point loading)
│ └── registry.py Global plugin_manager + built-in registration
├── manager/ The `httpie` management binary
│ ├── __main__.py Entry point + http/https confusion detection
│ ├── cli.py COMMANDS tree (cli, plugins, sessions)
│ ├── core.py Dispatch to tasks
│ ├── compat.py pip discovery / subprocess (run_pip)
│ └── tasks/ check_updates, export_args, plugins, sessions
├── internal/ Update-check daemon
│ ├── update_warnings.py Version fetch + warning logic
│ ├── daemons.py Detached process spawning (double-fork / Windows)
│ └── daemon_runner.py Daemon task runner
└── legacy/ Session-format back-compat shims (v3.1.0, v3.2.0)
Module reference
Core orchestration — core.py
raw_main() is the universal entry: it is shared by http/https (with the http parser) and httpie (with the manager parser, use_default_options=False). It centralizes error handling, mapping exceptions to exit codes:
| Exception | Exit status |
|---|---|
requests.Timeout |
ERROR_TIMEOUT (2) |
requests.TooManyRedirects |
ERROR_TOO_MANY_REDIRECTS (6) |
requests.ConnectionError (DNS) |
ERROR (1), with a DNS-specific hint |
NestedJSONSyntaxError |
ERROR (1) |
KeyboardInterrupt |
ERROR_CTRL_C (130) |
program() drives the actual request/response loop, message separation, and the download finalization.
Client — client.py
collect_messages() is the generator at the heart of request execution. Key responsibilities:
- Loads/updates the HTTPie session when
--session/--session-read-onlyis set. - Builds default headers (
make_default_headers):User-Agent: HTTPie/<version>, plus JSON or formContent-Type/Acceptbased on data and--form. - Manually preserves repeated headers across Requests' preparation (
apply_missing_repeated_headers) — Requests collapses duplicate headers, so HTTPie re-applies them. - Wraps
http.client._MAXHEADERSvia themax_headers()context manager for--max-headers. - Streams the request body through
uploads.prepare_request_body()for chunked/compressed/file uploads.
Models — models.py
HTTPMessage/HTTPRequest/HTTPResponse wrap Requests' objects to expose a uniform headers/metadata/iter_body/iter_lines interface for the output layer. OutputOptions is a NamedTuple describing which parts (headers/body/meta) of a given message to print, derived from the --print string.
Headers dict — cli/dicts.py
HTTPHeadersDict (a case-insensitive multidict.CIMultiDict) is central to HTTPie's correct handling of multi-valued headers — a behavior plain Requests does not preserve. Setting a header value to None unsets it; add() supports multiple values per name.
Component inventory
| Component | Class / location | Role |
|---|---|---|
| Argument parser | HTTPieArgumentParser (cli/argparser.py) |
Parse args + request items; multi-stage processing. |
| Manager parser | HTTPieManagerArgumentParser |
Parser for the httpie binary. |
| Parser spec | ParserSpec/Group/Argument (cli/options.py) |
Declarative parser definition, serializable to JSON (export-args). |
| Request items | RequestItems (cli/requestitems.py) |
Separator-based item classification. |
| HTTP adapters | HTTPieHTTPAdapter, HTTPieHTTPSAdapter |
Header preservation; custom TLS context. |
| Session | Session (sessions.py) |
Persistent headers/auth/cookies per host. |
| Config | Config (config.py) |
config.json loader + computed paths. |
| Environment | Environment (context.py) |
Streams, config, Rich consoles, TTY detection. |
| Downloader | Downloader, DownloadStatus (downloads.py) |
wget-style download with resume. |
| Plugin manager | PluginManager (plugins/manager.py) |
Entry-point discovery and registration. |
| Output streams | BaseStream and subclasses (output/streams.py) |
Encoding/formatting/binary suppression. |
| Exit status | ExitStatus (status.py) |
Process exit-code constants. |
The plugin API
HTTPie's extensibility is built on Python entry points. PluginManager.iter_entry_points() scans four groups and registers each discovered class:
| Entry-point group | Base class | Extends |
|---|---|---|
httpie.plugins.auth.v1 |
AuthPlugin |
New authentication mechanisms. |
httpie.plugins.transport.v1 |
TransportPlugin |
Requests transport adapters mounted on a URL prefix. |
httpie.plugins.converter.v1 |
ConverterPlugin |
Convert binary bodies to text for display. |
httpie.plugins.formatter.v1 |
FormatterPlugin |
Post-process headers/body/metadata for display. |
Warning
The plugin API carries an explicit in-source disclaimer: "The plugin API is still work in progress and will probably be completely reworked in the future." Pin HTTPie versions when depending on plugin internals.
Writing an auth plugin
from httpie.plugins import AuthPlugin
import requests
class MyTokenAuth(requests.auth.AuthBase):
def __init__(self, token):
self.token = token
def __call__(self, request):
request.headers['X-Token'] = self.token
return request
class MyAuthPlugin(AuthPlugin):
name = 'My token auth'
auth_type = 'my-token' # value passed to --auth-type / -A
description = 'Sends an X-Token header'
# Tunable class attributes:
auth_require = True # require --auth, -a
auth_parse = False # don't split -a as username:password
netrc_parse = False # don't fall back to ~/.netrc
prompt_password = False # don't prompt when password is missing
def get_auth(self, username=None, password=None):
return MyTokenAuth(self.raw_auth)
Register it in your package's setup.cfg/pyproject.toml:
[options.entry_points]
httpie.plugins.auth.v1 =
my_token = my_package:MyAuthPlugin
The other three extension points
| Base class | Override | Purpose |
|---|---|---|
TransportPlugin |
prefix, get_adapter() |
Mount a Requests adapter for a custom URL scheme (e.g. http+unix://). |
ConverterPlugin |
supports(mime), convert(body) |
Turn a binary MIME type into displayable text. |
FormatterPlugin |
format_headers/body/metadata |
Transform output; group_name = 'format'. |
Built-in plugins
Registered in plugins/registry.py:
- Auth:
BasicAuthPlugin(basic),DigestAuthPlugin(digest),BearerAuthPlugin(bearer). - Formatters:
HeadersFormatter,JSONFormatter,XMLFormatter,ColorFormatter.
Plugin installation internals
httpie cli plugins install does not use a normal pip install into HTTPie's environment. Instead, manager/compat.py::run_pip() invokes pip (the bundled interpreter's -m pip, or a discovered system pip when running as a frozen binary) to install into an isolated plugins_dir (default: <config_dir>/plugins). At runtime, plugin_manager.load_installed_plugins() temporarily adds that directory to sys.path (enable_plugins) before scanning entry points. This is why plugins installed this way must also be uninstalled this way — see the warning emitted on load failure.
Configuration and state on disk
Config directory resolution
config.py::get_default_config_dir() resolves the directory in this order:
$HTTPIE_CONFIG_DIRif set.- On Windows:
%APPDATA%\httpie. - Legacy
~/.httpieif it already exists. $XDG_CONFIG_HOME/httpie(defaulting to~/.config/httpie).
config.json
A simple JSON file (created on demand). Recognized keys:
| Key | Default | Meaning |
|---|---|---|
default_options |
[] |
Options prepended to every http/https invocation. |
plugins_dir |
<config_dir>/plugins |
Isolated plugin install location. |
version_info_file |
<config_dir>/version_info.json |
Cache for the update checker. |
developer_mode |
false |
Surfaces normally suppressed errors (for HTTPie development). |
disable_update_warnings |
false |
Disables the new-release check entirely. |
default_options is prepended only for the request commands (use_default_options=True); the httpie manager binary ignores it.
On-disk layout
$HTTPIE_CONFIG_DIR/ (default ~/.config/httpie)
├── config.json
├── version_info.json Cached latest-version data (update checker)
├── plugins/ Isolated plugin install dir
└── sessions/
└── <host>/
└── <name>.json Named session files
Sessions: format and lifecycle
A session (sessions.py::Session, a BaseConfigDict subclass) is a JSON document persisting three things between requests to the same host:
- headers — except names prefixed with
Content-orIf-(SESSION_IGNORED_HEADER_PREFIXES), which are request-specific. - auth —
{type, raw_auth}(or legacy{type, username, password}). - cookies — with
name/value/domain/path/expires/securefields.
Session resolution
get_httpie_session() decides between named and anonymous sessions: if the session name contains a path separator it is treated as an anonymous file path; otherwise it is a named session stored at sessions/<host>/<name>.json under the config directory. Session names are validated against ^[a-zA-Z0-9_.-]+$.
Cookie domain binding
Cookies carry a domain field that binds them to a host and its subdomains. A null domain makes a cookie unbound (sent to any host, including across cross-domain redirects). The legacy upgrade path and the --bind-cookies flag exist to remediate previously unbound cookies — see Security analysis.
Format upgrades
When HTTPie detects an obsolete session format it warns and offers upgrade commands:
httpie cli sessions upgrade-all
httpie cli sessions upgrade <host> <session-name-or-path> [--bind-cookies]
The legacy/ package (v3_1_0_session_cookie_format, v3_2_0_session_header_format) implements the format migrations applied during pre_process_data/post_process_data.
The update-check subsystem
HTTPie periodically checks whether a newer release is available (internal/update_warnings.py). Operators should understand its behavior:
- On each request,
check_updates()runs (unlessdisable_update_warningsis set). - At most every 2 weeks (
FETCH_INTERVAL), it spawns a detached background daemon (internal/daemons.py, via double-fork on POSIX or a hidden process on Windows) that fetcheshttps://packages.httpie.io/latest.json. - Results are cached in
version_info.json(written under a lockfile to avoid races between concurrenthttpprocesses). - A warning is shown at most once per week (
WARN_INTERVAL), pointing to the install method recorded inBUILD_CHANNEL.
Caution
The update fetch uses
requests.get(PACKAGE_INDEX_LINK, verify=False)— TLS certificate verification is disabled for the version-check request. In hardened or air-gapped environments, setdisable_update_warnings: trueinconfig.jsonto stop the network call entirely.
Security analysis
HTTPie is a client tool that runs with the invoking user's privileges. The threat surface is mostly about credential handling, TLS, and untrusted servers.
Credential storage
Caution
Sessions store secrets in plain text. Authentication credentials, prompted passwords, cookies, and custom headers are all written to session JSON files in cleartext. Anyone with read access to the file can recover them. Treat session files like private keys: restrict filesystem permissions and avoid committing them.
- Basic-auth credentials are base64-encoded (not encrypted) into the
Authorizationheader — standard HTTP basic auth. .netrccredentials are honored by default; disable per-request with--ignore-netrc.
TLS / SSL
--verify=nodisables certificate verification (cert_reqs=CERT_NONE), enabling man-in-the-middle attacks. Use a CA bundle (--verify=/pathorREQUESTS_CA_BUNDLE) instead where possible.urllib3insecure-request warnings are globally disabled (urllib3.disable_warnings()inclient.py) — so HTTPie won't nag about--verify=no, which means the operator must self-enforce verification.- TLS version (
--ssl) and ciphers (--ciphers) are configurable; defaults negotiate the highest mutually supported protocol. - Client certificates with encrypted keys prompt for a passphrase (or accept
--cert-key-pass). - The update check disables verification (see above).
Cookie scoping
HTTPieCookiePolicy(cookies.py) treatslocalhostand*.localhostas secure hosts, matching modern browser behavior — secure cookies are returned to localhost over plain HTTP.- Unbound session cookies (
domain: null) are sent across hosts and redirect chains. This was the subject of security advisory GHSA-9w4w-cpc8-h2fq; the--bind-cookiesupgrade flag binds such cookies to their session host as mitigation.
Untrusted input handling
- Binary response bodies are suppressed in the terminal (
BinarySuppressedError) to prevent terminal-escape injection from hostile servers. - XML formatting uses defused parsing to avoid XML entity-expansion attacks (the
output/formatters/xml.pyformatter; the test suite includes XML-bomb fixtures undertests/fixtures/xmldata/invalid/). - File uploads and large bodies are streamed, bounding memory use against large inputs.
Operational hardening checklist
- [ ] Set restrictive permissions on the config directory and session files (
chmod 700 ~/.config/httpie). - [ ] Prefer
--verify=<ca-bundle>over--verify=no; never disable verification against untrusted networks. - [ ] Set
disable_update_warnings: truein locked-down/air-gapped environments. - [ ] Review and pin community plugins — they execute arbitrary code and are not vetted by the HTTPie project.
- [ ] Run
httpie cli sessions upgrade-all --bind-cookiesto remediate legacy unbound cookies. - [ ] In scripts, always use
--ignore-stdinand--timeout.
Requirements and dependencies
| Requirement | Detail |
|---|---|
| Python | 3.7 or newer (MIN_SUPPORTED_PY_VERSION = (3, 7)). |
| Platforms | Linux, macOS, Windows, FreeBSD. |
| License | BSD-3-Clause. |
Runtime dependency stack
HTTPie is a thin layer over a small set of mature libraries, evident from its imports:
| Library | Used for |
|---|---|
| requests | The HTTP transport (sessions, adapters, auth base classes). |
| Pygments | Syntax highlighting of headers and bodies. |
| charset-normalizer | Response encoding detection (encoding.py). |
| requests-toolbelt | Streaming multipart encoding (MultipartEncoder). |
| multidict | Case-insensitive, multi-valued header dict (HTTPHeadersDict). |
| rich | Help rendering, progress bars, and colorized error consoles. |
| colorama | ANSI color translation on Windows. |
Note
On Windows, output streams are wrapped with
coloramafor ANSI handling. On non-Windows systems,curses(when available) is used to detect terminal color support.
Code quality and conventions
- Layered, single-responsibility modules. Parsing, client, output, and plugins are cleanly separated. The CLI definition (
cli/definition.py) is declarative and serializable, which is what powershttpie cli export-args. - Declarative parser spec. Rather than calling argparse directly, HTTPie builds an abstract
ParserSpecof groups and arguments, then renders it to argparse (to_argparse) — and can also serialize it to JSON for external tooling. - Type hints throughout, with
typing.NamedTuplefor immutable value objects (OutputOptions,ProcessingOptions,Argument). - Compatibility shims isolated in
compat.py(cached_property backport,importlib_metadatadifferences across 3.7–3.10). - Custom exceptions map cleanly to user-facing errors:
ParseError,ConfigFileError,ContentRangeError,NestedJSONSyntaxError,PipError. - Known maintainability notes acknowledged in-source: the parsing pipeline (
HTTPieArgumentParser.parse_args) is a long ordered sequence of_process_*methods withTODOmarkers calling for refactor;core.program()is flagged for simplification of its separator logic.
Testing strategy
The tests/ directory holds a broad suite (40+ test modules) covering each feature area, runnable with pytest:
| Test area | Modules |
|---|---|
| CLI & parsing | test_cli.py, test_cli_ui.py, test_cli_utils.py, test_parser_schema.py, test_tokens.py |
| Requests/responses | test_httpie.py, test_redirects.py, test_stream.py, test_output.py |
| Auth | test_auth.py, test_auth_plugins.py |
| Data & encoding | test_json.py, test_xml.py, test_encoding.py, test_binary.py, test_uploads.py, test_compress.py |
| Sessions & cookies | test_sessions.py, test_cookie.py, test_cookie_on_redirects.py |
| SSL | test_ssl.py |
| Management | test_httpie_cli.py, test_plugins_cli.py, test_transport_plugin.py |
| Behavior | test_exit_status.py, test_errors.py, test_defaults.py, test_offline.py, test_meta.py, test_downloads.py, test_regressions.py, test_update_warnings.py, test_windows.py |
Test infrastructure (tests/utils/) provides MockEnvironment, an embedded http_server, a plugins-CLI fixture harness, and a response-matching DSL (tests/utils/matching/).
Building and packaging
- PyPI is the canonical distribution (
python -m pip install httpie);setup.pydelegates tosetup.cfg. - OS packages are maintained for APT, DNF/Yum, pacman, Homebrew, MacPorts, Chocolatey, Snap, and FreshPorts (see
docs/installation/methods.yml— the single source of truth for the documented install commands). - Standalone Linux binaries are built (PyInstaller-style) and published at
packages.httpie.io/binaries/. Frozen builds setis_frozen, which changes plugin pip discovery and Python-version site-path handling. - Man pages for
http,https, andhttpieare generated at release time (extras/scripts/generate_man_pages.py); theHTTPIE_BUILDING_MAN_PAGESenv var suppresses system-specific content (like the default cipher list) so man pages are reproducible. __build_channel__.pyrecords the packaging method per build; the update checker uses it to point users at the right upgrade instructions.
Potential improvements
Drawn from in-source TODO/FIXME markers and observed structure:
- Refactor the argument-processing pipeline.
HTTPieArgumentParser.parse_args()runs a long, order-sensitive chain of_process_*methods with severalTODOs requesting type-annotated, immutable arg structures. - Simplify
core.program(). An in-sourceTODOcalls out the message-separator logic as needing extraction. - Stabilize the plugin API. The package docstring warns it "will probably be completely reworked" — versioned entry-point groups (
.v1) anticipate this, but a documented stability contract would help the plugin ecosystem. - Reconsider
--chunkedopt-in for stdin. ATODOinuploads.pynotes that chunked transfer for stdin could become opt-out (a breaking change deferred to a future major version). - Verify the update check over TLS. The
verify=Falsefetch inupdate_warnings.pyis a hardening gap worth closing. - Resolve open community issues, e.g. JSON
Content-Typenot being set when a single header is present (#1640 / #1834) and argument-parsing differences on Python 3.13+ (#1838).
Contributing
- Repository: github.com/httpie/cli — see
CONTRIBUTING.md. - Docs are source-controlled: the user manual lives in
docs/README.md; the installation section is generated fromdocs/installation/methods.ymlviadocs/installation/generate.py(don't edit the generated block by hand). - Run the tests:
pytestfrom the repo root. - Security policy: github.com/httpie/cli/security/policy.
- License: BSD-3-Clause. Created by Jakub Roztocil and contributors.
Tip
Because the parser spec is serializable (
httpie cli export-args), external tools (shells, editors) can build autocomplete from HTTPie's own definition rather than re-implementing the flag list. If you add a flag incli/definition.py, it automatically appears in the exported schema.
Quick reference
Entry points
| Binary | Module | Purpose |
|---|---|---|
http |
httpie/__main__.py |
Send requests (default scheme http://). |
https |
same | Send requests (default scheme https://). |
httpie |
httpie/manager/__main__.py |
Manage plugins, config, sessions. |
Plugin entry-point groups
| Group | Base class |
|---|---|
httpie.plugins.auth.v1 |
AuthPlugin |
httpie.plugins.transport.v1 |
TransportPlugin |
httpie.plugins.converter.v1 |
ConverterPlugin |
httpie.plugins.formatter.v1 |
FormatterPlugin |
Management commands
| Command | Purpose |
|---|---|
httpie cli check-updates |
Check for a newer release. |
httpie cli export-args [-f json] |
Export the parser spec. |
httpie cli plugins install/list/upgrade/uninstall |
Manage plugins. |
httpie cli sessions upgrade <host> <session> [--bind-cookies] |
Upgrade one session. |
httpie cli sessions upgrade-all [--bind-cookies] |
Upgrade all named sessions. |
Exit status codes
| Code | Meaning | Code | Meaning |
|---|---|---|---|
0 |
Success | 5 |
HTTP 5xx |
1 |
Error | 6 |
Too many redirects |
2 |
Timeout | 7 |
Plugin error |
3 |
HTTP 3xx | 130 |
Ctrl-C |
4 |
HTTP 4xx |
Key files on disk
| Path | Purpose |
|---|---|
$HTTPIE_CONFIG_DIR/config.json |
User configuration. |
.../sessions/<host>/<name>.json |
Named sessions. |
.../version_info.json |
Update-check cache. |
.../plugins/ |
Isolated plugin installs. |