httpie/cli
Three console_scripts entry points converge on a single error-handling shell: `http`/`https` map to `httpie.__main__:main` and `httpie` maps to `httpie.manager.__main__:main`, both of which call `httpie.core.raw_main` with a different parser and main_program. The package splits into `cli/` (argparse spec, request-item parsing, nested-JSON), `client.py` (requests glue), `output/` (streams, formatters, Rich UI), `sessions.py`/`config.py` (JSON persistence under the config dir), `plugins/` (entry-point registry), `manager/` (the `httpie` admin subcommands), and `internal/` (background update daemon). There is no database -- all state is JSON files under `$HTTPIE_CONFIG_DIR` or the XDG config dir. External integrations are the `requests`/`urllib3` stack, Pygments, Rich, defusedxml, requests-toolbelt, and `pip` shelled out for plugin installation. Build/test is Makefile-driven (`make install`, `make test`, `make codestyle`) with GitHub Actions running a 3-OS x 6-Python x pyopenssl matrix.
- setup.cfg declares three console_scripts: `http` and `https` both point at `httpie.__main__:main`, while `httpie` points at `httpie.manager.__main__:main` -- the `https` alias is what makes `_process_url` default to the https:// scheme.
- `httpie/__main__.py:main()` is a thin wrapper that imports `httpie.core.main` lazily, catches KeyboardInterrupt into `ExitStatus.ERROR_CTRL_C`, and returns `exit_status.value` -- keeping import cost off the Ctrl-C path.
- `raw_main()` is the shared shell for both binaries: it sets `env.program_name`, decodes bytes argv via `decode_raw_args`, short-circuits into `run_daemon_task` when `--daemon` is present, loads installed plugins from `env.config.plugins_dir`, and prepends `config.default_options` to argv.
- The CLI surface is declared declaratively as a `ParserSpec` of named `Group`s in httpie/cli/definition.py (Positional arguments, Predefined content types, Content processing options, Output processing, Output options, Sessions, Authentication, Network, SSL, Troubleshooting) and only then converted to argparse by `to_argparse()`.
- `httpie/client.py:collect_messages()` is the transport boundary: it builds a `requests.Session` via `build_requests_session`, mounts `HTTPieHTTPAdapter` on http:// and `HTTPieHTTPSAdapter` on https://, plus any `TransportPlugin` prefixes, then yields PreparedRequest/Response pairs as a generator so output can stream.
- Storage is JSON-file based via `BaseConfigDict`, which subclasses `dict`, writes with `json.dumps(indent=4, sort_keys=True, ensure_ascii=True)` and creates the parent dir with mode 0o700; `Config` (config.json) and `Session` (sessions/<host>/<name>.json) both derive from it.
- Config-dir resolution is a four-step fallback: `$HTTPIE_CONFIG_DIR`, then `%APPDATA%/httpie` on Windows, then a legacy `~/.httpie` if it exists, then `$XDG_CONFIG_HOME/httpie` (default `~/.config/httpie`).
- The `httpie` manager binary owns a nested COMMANDS dict producing `httpie cli export-args`, `httpie cli check-updates`, `httpie cli sessions upgrade|upgrade-all`, and `httpie plugins install|upgrade|uninstall|list`; `generate_subparsers()` recursively materializes them into argparse subparsers.
- `Environment` is the injected runtime boundary for all I/O -- stdin/stdout/stderr, isatty flags, encodings, color depth (probed via `curses.tigetnum('colors')`), Windows colorama stream wrapping, and lazily constructed Rich consoles -- which is precisely what the test suite overrides with `MockEnvironment`.
- Build and test commands live in the Makefile: `make install` creates a venv and pip-installs `.[dev] .[test]` editable, `make test` runs pytest, `make test-cover` adds `--cov=httpie --cov=tests`, `make codestyle` runs flake8 over httpie/ tests/ extras/profiling/ docs/packaging/brew/, and `make build` swaps `__build_channel__.py` to `BUILD_CHANNEL = "pip"` before building the wheel.
- pytest configuration is split across two files: setup.cfg sets `testpaths = httpie tests` with `--doctest-modules` (so module docstrings such as `ensure_path_as_is` and `humanize_bytes` are executable tests), while pytest.ini registers the `requires_installation` and `requires_external_processes` markers.
- Deployment is many-target and workflow_dispatch-driven: release-pypi.yml publishes via `pypa/gh-action-pypi-publish`, release-linux-standalone.yml runs `extras/packaging/linux/get_release_artifacts.sh` to produce a PyInstaller `http` binary plus .deb/.rpm, and .packit.yaml proposes the Fedora rawhide downstream update on release.
- Generated content (man pages under extras/man/*.1 and the installation docs) is regenerated by `make content` and auto-PR'd by the content.yml workflow, using `extras/scripts/generate_man_pages.py` and `docs/installation/generate.py`.
- `httpie/compat.py` is the portability boundary: it pins `is_windows`/`is_frozen`, back-fills `cached_property` for Python <3.8, switches between `importlib.metadata` and the `importlib_metadata` backport, and globally patches `cookiejar.DefaultCookiePolicy` to HTTPie's own policy.