Compare commits

...

296 Commits

Author SHA1 Message Date
Jakub Roztocil
9e8e3691c8
Update README.md 2023-10-24 10:23:30 -07:00
github-actions[bot]
e52a60e67c
[automated] Update generated content (#1524)
Co-authored-by: jakubroztocil <jakubroztocil@users.noreply.github.com>
2023-08-06 14:35:57 +02:00
Jakub Roztocil
8aa654d1ef
Update README.md 2023-08-06 14:15:10 +02:00
Jakub Roztocil
011402152c Rename repo from httpie/httpie to httpie/cli 2023-08-06 14:04:32 +02:00
Rudolf Olah
30a6f73ec8
README.md: fix the file based separators internal link (#1510)
The link to "file based separators" in the "Reading headers from a file" section when rendered to HTML does not work. The link is now fixed by providing a URL and link text.
2023-05-24 08:22:56 -07:00
Boris Verkhovskiy
ec4fb84254
Document restriction on top-level JSON types explicitly (#1496)
* Document restriction on top-level JSON types explicitly

* Update docs/README.md

---------

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2023-05-23 05:11:41 -07:00
github-actions[bot]
c8c135ffff
[automated] Update generated content (#1509)
Co-authored-by: jakubroztocil <jakubroztocil@users.noreply.github.com>
2023-05-22 11:57:31 -07:00
Jakub Roztocil
2da955fb06
Man page clean-up (#1508)
Ensure we don’t include dynamic content in the static man pages.
2023-05-22 11:56:30 -07:00
github-actions[bot]
c2677eeccf
[automated] Update auto-generated files (#1507)
Co-authored-by: jakubroztocil <jakubroztocil@users.noreply.github.com>
2023-05-22 11:40:01 -07:00
Jakub Roztocil
5325a9bc07 Remove skipping
Always skipped
2023-05-22 19:01:36 +02:00
chrysle
2e3272b5ba
Fixed installation steps for Debian & Ubuntu (#1473) (#1475)
* Fixed installation steps for Debian & Ubuntu

* Fixed incorrect path
2023-05-22 09:50:25 -07:00
Jakub Roztocil
5dc30bc438 Ensure sudo for apt 2023-05-22 18:44:07 +02:00
Jakub Roztocil
442aa673ac Fix Choco changelog link 2023-05-22 18:04:06 +02:00
Jakub Roztocil
3e290e5dba Fix Snap publish action 2023-05-22 17:51:22 +02:00
Jakub Roztocil
2a9cd226aa Bump version for Chocolatey 2023-05-22 16:21:25 +02:00
Jakub Roztocil
3b58a4a4a2 Trigger docs deploy 2023-05-20 00:01:37 +02:00
Jakub Roztocil
7512ca7e47 Fix docs deploy 2023-05-20 00:01:10 +02:00
Jakub Roztocil
cc697db730 Add a changelog entry for #1502 2023-05-19 23:59:08 +02:00
Abdelhakim Qbaich
cbe53ed79a
Avoid override of headers by urllib3 when unset (#1502)
* Pass SKIP_HEADER const when header is unset

* Hide SKIP_HEADER constant when displaying headers

* Test that omits User-Agent
2023-05-19 23:53:26 +02:00
Jakub Roztocil
3664644722 Fix issue link 2023-05-19 23:44:52 +02:00
Jakub Roztocil
29de4ce115 v3.2.2 2023-05-19 23:41:26 +02:00
Jakub Roztocil
879fedc10a Flake8 2023-05-19 23:41:16 +02:00
Jakub Roztocil
18bb49b268 Skip a test failing in CI 2023-05-19 23:29:09 +02:00
Jakub Roztocil
fcd3f7ece6 Generate default ciphers using approach from #1501 2023-05-19 22:26:33 +02:00
Jakub Roztocil
8e56e9fc64 Fix a failing test 2023-05-19 21:51:52 +02:00
Jakub Roztocil
44d3cff03f Fix log level display on newer Python 2023-05-19 21:51:32 +02:00
Jakub Roztocil
d021b94b5d Clean up DEFAULT_SSL_CIPHERS comments 2023-05-19 21:50:58 +02:00
C-A de Salaberry
4e29a6d561
fix(urllib3): 🐛 could not find urllib3 DEFAULT_CIPHERS (#1505) 2023-05-19 21:18:55 +02:00
Sid
1ae4152e1e
docs: improve documentation for installation of unstable version (#1490)
* docs: improve documentation for installation of unstable version

I am trying to rephrase the instructions to make it clear, concise and beginner friendly.

Summary of changes:
* rephrased the instructions to install unstable version of HTTPie
* rephrased the instructions to verify the installation

* fix(docs): remove trailing spaces

* docs: fix 'pip' formatting

Enclosed 'pip' with backticks to display it as inline code

* docs: better description for pip installation (unstable version)

* Update docs/README.md

---------

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2023-05-09 11:23:29 +02:00
dependabot[bot]
47e9b99ba1
Bump actions/stale from 7 to 8 (#1492)
Bumps [actions/stale](https://github.com/actions/stale) from 7 to 8.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v7...v8)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-28 18:30:30 -07:00
Sid
265841f866
docs: improve clarity of sentences (#1489)
* docs: improve clarity of sentences

Improved clarity by rephrasing sentences in the best practices section.

* docs: improve best practices section

* use appropriate formatting for stdin
* include EOF in abbreviated form

* docs: clarify sentence

* change 'know that' -> 'note that'
* use neither nor for better clarity
2023-03-22 13:03:18 -07:00
Nishant Sikarwar
b16392fbb9
Remove redundant imports (#1466) 2023-01-15 11:35:36 -08:00
Jakub Roztocil
e73c3e6c24 Fix failing tests with responses ≥ 0.22.0
Close #1461
Close #1467

Thanks, @alexshpilkin!
2023-01-15 17:43:17 +01:00
dependabot[bot]
f0563deb7f
Bump mislav/bump-homebrew-formula-action from 1 to 2 (#1453)
Bumps [mislav/bump-homebrew-formula-action](https://github.com/mislav/bump-homebrew-formula-action) from 1 to 2.
- [Release notes](https://github.com/mislav/bump-homebrew-formula-action/releases)
- [Commits](https://github.com/mislav/bump-homebrew-formula-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: mislav/bump-homebrew-formula-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-04 03:18:15 -08:00
dependabot[bot]
4894b4c0fc
Bump actions/stale from 6 to 7 (#1459)
Bumps [actions/stale](https://github.com/actions/stale) from 6 to 7.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-04 03:17:54 -08:00
TAKAHASHI Shuuji
3a123c4125
Fix ci status badge error (#1464) 2023-01-04 03:17:18 -08:00
Jakub Roztocil
621042a048
Update README.md 2022-10-01 04:00:56 -07:00
Jakub Roztocil
0689b55e1d
Clean up and refactor nested JSON parsing & interpreting (#1440) 2022-10-01 03:38:19 -07:00
Ben Chatelain
a7321d8ac4
🔥 Remove $ from code fenced examples on readme (#1435)
* 🔥 Remove $ from code fenced examples on readme

* 🚨 FIx markdownlint errors

README.md:8: MD009 Trailing spaces
README.md:10: MD009 Trailing spaces
2022-10-01 03:37:50 -07:00
Kian-Meng Ang
d9a73cd8eb
Fix typos (#1431)
Found via `codespell -L datas`.
2022-10-01 03:34:41 -07:00
a1346054
930cd9081a
Use grep -E instead of egrep (#1436) 2022-10-01 03:32:17 -07:00
dependabot[bot]
3549ee8342
Bump actions/stale from 5 to 6 (#1437)
Bumps [actions/stale](https://github.com/actions/stale) from 5 to 6.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-01 03:31:54 -07:00
Jakub Roztocil
810bb1c77b
Update README.md 2022-08-10 09:13:49 -07:00
Jakub Roztocil
767f3c3a19
Update README.md 2022-08-10 07:58:09 -07:00
Jakub Roztocil
1236793272
Update README.md 2022-08-10 07:48:57 -07:00
Jakub Roztocil
c3a2f87dd2
Update README.md 2022-08-10 07:41:13 -07:00
Jakub Roztocil
1121d695a8
Update README.md 2022-08-10 07:38:40 -07:00
Motahhar Mokfi
5794a070e1
place the logo in the middle in README.md (#1393) 2022-07-12 08:33:57 -07:00
Tim Gates
4736a16698
docs: Fix a few typos (#1419) 2022-07-03 14:54:34 +02:00
Girish Sharma
3ad408add7
Fix paths to run benchmarking script (#1416) 2022-06-19 00:20:22 -07:00
Nate Prewitt
91cdb22a4b
Update Requests documentation links (#1414) 2022-06-17 14:04:42 -07:00
dependabot[bot]
c995fd9b24
Bump actions/setup-python from 3 to 4 (#1412)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 3 to 4.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-09 10:04:06 -07:00
Jakub Roztocil
418b12bbd6 Cleanup 2022-06-07 14:31:15 +02:00
Jakub Roztocil
ecff53f2d5 Have naked $ make list all tasks 2022-06-07 14:29:19 +02:00
Jakub Roztocil
41da87f7c8 Install .[test] reqs in make install-reqs 2022-06-07 14:26:48 +02:00
Jakub Roztocil
4f172a61b4 Fix installation 2022-06-07 14:23:52 +02:00
SADIK KUZU
542a2d35de
Fix typos in comment lines (#1405)
* httpie/internal/daemons.py
* httpie/utils.py
2022-05-19 16:22:50 +03:00
Batuhan Taskaya
d9e1dc08c9
Package man pages into the deb packages as well. (#1403) 2022-05-16 18:19:49 +03:00
Batuhan Taskaya
3b734fb0bc Fix a misput backtick 2022-05-16 10:10:51 +03:00
Jan Brasna
8abe47969e
Improve single-binary method wording (#1399) 2022-05-10 19:55:31 +03:00
Standa Opichal
8173cb0337
Typo fix (#1397) 2022-05-09 20:26:16 +03:00
Batuhan Taskaya
7fd34fc8ce
Fix-up standalone binary docs. (#1396) 2022-05-09 19:22:20 +03:00
Jannik Vieten
80ae644464
updated fish completions for httpie 3.2.1 (#1394) 2022-05-09 18:24:48 +03:00
Batuhan Taskaya
69fe5dbfd1
Update release-linux-standalone.yml 2022-05-09 11:46:19 +03:00
Batuhan Taskaya
f09e7564e7 Standalone binary documentation. 2022-05-09 09:01:59 +03:00
Batuhan Taskaya
dc5274e491
Use the proper directory name for the choco action. (#1392)
* Use the proper directory name for the choco action.

* Refresh the current environment to reflect the new installation.
2022-05-06 20:47:40 +03:00
Batuhan Taskaya
ad2b86ccf4
Update the chocolatey spec (#1391) 2022-05-06 19:47:55 +03:00
Batuhan Taskaya
11b2af0f59
Automatically attach debian packages and linux binaries to the release (#1390)
* Automatically attach debian packages and linux binaries to the release

* Use set-output syntax
2022-05-06 15:40:14 +03:00
Batuhan Taskaya
b54239b525 Changelog for 3.2.1 2022-05-06 10:08:16 +03:00
Batuhan Taskaya
b0b0f3dc53
Mask the stdout/stderr for the inner daemon process on MacOS (#1389) 2022-05-06 10:06:59 +03:00
Brian Egleston
9f7612cdeb
Checking headers to determine auto-streaming (#1383) 2022-05-06 09:59:22 +03:00
Batuhan Taskaya
5e76ebc5e1 Use make install to get the dependencies as well 2022-05-05 23:44:17 +03:00
Batuhan Taskaya
343a521673 Create the virtual env for the build action. 2022-05-05 23:40:39 +03:00
Batuhan Taskaya
2142ae60c3
Final release prep for 3.2.0 (#1387) 2022-05-05 23:32:35 +03:00
Batuhan Taskaya
0b6a9b23c2
Add missing changelog entries (#1386) 2022-05-05 23:18:00 +03:00
Batuhan Taskaya
9e1c0b98c7
Contributors for 3.2.0 (#1374) 2022-05-05 11:19:19 -07:00
Batuhan Taskaya
003f2095d4
Automatic release update warnings. (#1336)
* Hide pretty help

* Automatic release update warnings.

* `httpie cli check-updates`

* adapt to the new loglevel construct

* Don't make the pie-colors the bold

* Apply review feedback.

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2022-05-05 11:18:20 -07:00
Batuhan Taskaya
f9b5c2f696
Man page fixes (#1364)
- Highlighting for options (-x, --x) now doesn't strip the prefix (may be whitespace).
- Escape sequences are now cross-platform compatible (directly taken by groff/troff [man's renderer])
- Now we check for the section before displaying the man pages.
- On MacOS, there is HTTP(n) which is different from our HTTP(1). This used to conflict with it, and we showed the wrong page. Now we specifically ask foir HTTP(1).
- Errors that might happen (e.g non executable man command) is now suppressed. So in the worst case (if anything regarding man execution goes wrong), we'll always display the manual.
- Docs for man pages.
- HTTPie man pages.
- Epilog for the man pages (see also)
- Auto-generated comments.
2022-05-05 11:17:37 -07:00
Batuhan Taskaya
76495cbdec
Hide pretty help (#1384) 2022-05-05 11:17:24 -07:00
Batuhan Taskaya
c4d7d05f3b
Don't make bold the default for pie themes (#1385) 2022-05-05 11:17:12 -07:00
Batuhan Taskaya
7a4fb5d966
Update installation instructions for debian (#1373) 2022-05-05 08:40:52 -07:00
Batuhan Taskaya
f7c1bb269e
Refactor palette (#1378)
* Refactor palette

* Modifiers / change static strings to colors

* Colors...

* Error-based tests

* Styling linting

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2022-05-05 08:17:05 -07:00
Batuhan Taskaya
0f9fd76852
Deprecate --history-print (#1380) 2022-05-03 06:29:02 -07:00
Batuhan Taskaya
af1d6b1853
Use sentence case for the group names in the parser (#1381) 2022-05-03 06:28:46 -07:00
Batuhan Taskaya
419cc2c34a
Skip on pyOpenSSL (#1376) 2022-04-28 05:18:20 -07:00
Batuhan Taskaya
79a8ecd84b
Disable PackIt CI on the PRs (#1375) 2022-04-28 11:59:08 +03:00
luzpaz
d262181bed
Fix typos (user-facing and non-user-facing) (#1357)
* Fix typos (user-facing and non-user-facing

Found via `codespell -q 3 -L datas,medias,warmup`

* Fix source typo found in tests/
2022-04-16 02:06:34 +03:00
dependabot[bot]
732878f1b4
Bump peter-evans/create-pull-request from 3 to 4 (#1355)
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 3 to 4.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/v3...v4)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-15 23:35:46 +03:00
Jakub Roztocil
83803db14d Explain that we lost 54k stars in the README with a link to blog post 2022-04-14 18:27:18 +02:00
Batuhan Taskaya
dd2c9513f3
Single binary executables (#1330)
* Single binary executables / DEB packages.

* Attach single binary executables to the releases
2022-04-14 08:11:12 -07:00
Batuhan Taskaya
278dfc487d
Don't block users with the warning thread. (#1350)
Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2022-04-14 08:00:53 -07:00
Batuhan Taskaya
ff6f1887b0
[Major] UI Enhancements (#1321)
* Refactor tests to use a text-based standard output. (#1318)

* Implement new style `--help` (#1316)

* Implement man page generation (#1317)

* Implement rich progress bars. (#1324)

* Man page deployment & isolation. (#1325)

* Remove all unsorted usages in the CLI docs

* Implement isolated mode for man page generation

* Add a CI job for autogenerated files

* Distribute man pages through PyPI

* Pin the date for man pages. (#1326)

* Hide suppressed arguments from --help/man pages (#1329)

* Change download spinner to line (#1328)

* Regenerate autogenerated files when pushed against to master. (#1339)

* Highlight options (#1340)

* Additional man page enhancements (#1341)

* Group options by the parent category & highlight -o/--o

* Display (and underline) the METAVAR on man pages.

* Make help message processing more robust (#1342)

* Inherit `help` from `short_help`

* Don't mirror short_help directly.

* Fixup the serialization

* Use `pager` and `man` on `--manual` when applicable (#1343)

* Run `man $program` on --manual

* Page the output of `--manual` for systems that lack man pages

* Improvements over progress bars (separate bar, status line, etc.) (#1346)

* Redesign the --help layout.

* Make our usage of rich compatible with 9.10.0

* Add `HTTPIE_NO_MAN_PAGES`

* Make tests also patch os.get_terminal_size

* Generate CLI spec from HTTPie & Man Page Hook (#1354)

* Generate CLI spec from HTTPie & add man page hook

* Use the full command space for the option headers
2022-04-14 07:43:10 -07:00
Batuhan Taskaya
86f4bf4d0a
Add support for sending secure cookies over localhost (#1327)
* Add support for sending secure cookies over localhost

* Refactor

* Fix the CI

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2022-04-14 07:42:05 -07:00
Batuhan Taskaya
e6d0bfec7c
Use the raw request version when the original is not accessible (#1352) 2022-04-14 07:41:12 -07:00
Batuhan Taskaya
9f1ec6d5cc
Limit concurrency of our test workflow (#1353) 2022-04-14 07:38:28 -07:00
dependabot[bot]
85ba9ad8ea
Bump actions/stale from 4 to 5 (#1347)
Bumps [actions/stale](https://github.com/actions/stale) from 4 to 5.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/stale/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-11 12:14:51 +03:00
Batuhan Taskaya
d03e3f4e14
Implement support for multiple headers with the same name in sessions (#1335)
* Properly remove duplicate Cookie headers

* Implement support for multiple headers with the same name in sessions

* More testing

* Cleanup

* Remove duplicated test, cleanup

* Fix pycodestyle

* CHANGELOG

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2022-04-03 06:48:31 -07:00
Batuhan Taskaya
c157948531
Add httpie cli plugins in favor of the new cli namespace. (#1320)
* Add `httpie cli plugins` in favor of the new cli namespace.

* Separate each task to individual modules.

* Move httpie.manager.plugins to httpie.manager.tasks.plugins

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2022-04-03 06:06:42 -07:00
Batuhan Taskaya
33ea977b64
Don't send Content-Length for OPTIONS requests when there is no data. (#1319) 2022-04-03 06:02:41 -07:00
Batuhan Taskaya
d1596dde12
Ping werkzeug to <2.1.0 (#1345) 2022-04-01 14:28:59 +03:00
dependabot[bot]
af2ffb6999
Bump peter-evans/create-or-update-comment from 1 to 2 (#1332)
Bumps [peter-evans/create-or-update-comment](https://github.com/peter-evans/create-or-update-comment) from 1 to 2.
- [Release notes](https://github.com/peter-evans/create-or-update-comment/releases)
- [Commits](https://github.com/peter-evans/create-or-update-comment/compare/v1...v2)

---
updated-dependencies:
- dependency-name: peter-evans/create-or-update-comment
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-22 22:50:08 +03:00
dependabot[bot]
0632c4d614
Bump peter-evans/find-comment from 1 to 2 (#1333)
Bumps [peter-evans/find-comment](https://github.com/peter-evans/find-comment) from 1 to 2.
- [Release notes](https://github.com/peter-evans/find-comment/releases)
- [Commits](https://github.com/peter-evans/find-comment/compare/v1...v2)

---
updated-dependencies:
- dependency-name: peter-evans/find-comment
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-22 22:49:25 +03:00
Jakub Roztocil
6787a2bd29 Fix/tweak docs 2022-03-14 16:34:17 +01:00
Ethan Mills
9d2864b966
Fix broken docs link (#1322) 2022-03-12 15:09:01 -08:00
Batuhan Taskaya
a5288f0cd6
Integrate automatic releases. (#1315) 2022-03-09 15:26:51 +03:00
Batuhan Taskaya
8efa7cb04d
Add table headers for upgrade flags (#1314) 2022-03-08 16:43:09 +03:00
Batuhan Taskaya
baec1b2202 Update chocolatey for release 2022-03-08 02:29:21 +03:00
Batuhan Taskaya
266c6375c6
Release prep for 3.1.0 (#1313) 2022-03-08 01:50:09 +03:00
Batuhan Taskaya
77af4c7a5c
Decouple parser definition from argparse (#1293) 2022-03-08 01:34:04 +03:00
Batuhan Taskaya
7509dd4e6c Fix documentation styling errors. 2022-03-07 23:29:48 +03:00
Batuhan Taskaya
f08c1bee17 Change error messages to use a better format. 2022-03-07 23:29:48 +03:00
Jakub Roztocil
59d9e928f8 Tweak 2022-03-07 23:29:48 +03:00
Jakub Roztocil
0a873172c9 Tweak SECURITY and add a Security policy section to docs 2022-03-07 23:29:48 +03:00
Jakub Roztocil
614866eeb2 Polish sessions docs 2022-03-07 23:29:48 +03:00
Batuhan Taskaya
395914fb4d Apply suggestions from the review 2022-03-07 23:29:48 +03:00
Batuhan Taskaya
65ab7d5caa Implement new style cookies 2022-03-07 23:29:48 +03:00
Batuhan Taskaya
b5623ccc87 Fix the tests with the latest layout 2022-03-07 19:16:51 +03:00
Jakub Roztocil
ec203b1fac Tweak compact help 2022-03-07 19:16:51 +03:00
Batuhan Taskaya
350abe3033 Make the naked invocation display a compacted help 2022-03-07 19:16:51 +03:00
Batuhan Taskaya
9241a09360 Mention about interactive prompt on key passphrases 2022-03-07 16:09:07 +03:00
Batuhan Taskaya
15013fd609 Implement support for private key passphrases 2022-03-07 16:09:07 +03:00
Batuhan Taskaya
98688b2f2d Style fix on the changelog 2022-03-07 16:01:29 +03:00
Batuhan Taskaya
5ac05e9514 Add changelog entry 2022-03-07 16:01:29 +03:00
Jakub Roztocil
5c98253377 Update httpie/uploads.py 2022-03-07 16:01:29 +03:00
Batuhan Taskaya
b0f5b8ab26 Prevent data race happening between select.select and file.read() 2022-03-07 16:01:29 +03:00
Batuhan Taskaya
55087a901e
Introduce a mode to suppress all warnings (#1283) 2022-03-07 15:40:35 +03:00
Hoylen Sue
c901e70463
Replaced unmaintained OAuth plugin with new httpie-oauth1 plugin. (#1302) 2022-03-03 08:31:06 -08:00
Batuhan Taskaya
25bd817bb2
Fix displaying of status code without a status message. (#1301)
Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2022-03-03 08:28:04 -08:00
dependabot[bot]
6f77e144e4
Bump actions/checkout from 2 to 3 (#1311)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-03 08:16:56 -08:00
dependabot[bot]
6bf39e469f
Bump actions/setup-python from 2 to 3 (#1307)
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2 to 3.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-01 17:17:41 +03:00
Sebastian Stasiak
30cd862fc0
Update commands for Arch (#1306) 2022-03-01 00:57:23 +03:00
Batuhan Taskaya
ad613f29d2 Add a changelog entry for the top-level array regulation 2022-02-25 12:51:34 +03:00
Batuhan Taskaya
225dccb218
Regulate top-level arrays (#1292)
* Redesign the starting path

* Do not cast `:=[1,2,3]` to a top-level array
2022-02-08 15:18:40 -08:00
Batuhan Taskaya
cafa11665b Disable additional repos 2022-02-08 12:49:33 +03:00
Batuhan Taskaya
0a9d3d3c54 Fix the packit syntax 2022-02-08 12:49:33 +03:00
Batuhan Taskaya
e306667436 Leave a note for the local spec 2022-02-08 12:49:33 +03:00
Batuhan Taskaya
384d3869f6 Update the local copy fore 3.0.2 2022-02-08 12:49:33 +03:00
Batuhan Taskaya
5fd48e3137 Use the lastest fedora spec in the packit 2022-02-08 12:49:33 +03:00
Batuhan Taskaya
37ef670876 Update copyright year 2022-02-05 22:09:44 +03:00
Batuhan Taskaya
46e782bf75 Point package to 3.0.2 2022-02-05 22:09:44 +03:00
Batuhan Taskaya
42edb1eb76 Use 3.0.0 blog post as the changelog 2022-02-05 22:09:44 +03:00
Batuhan Taskaya
d45f413f12
Make the version point to 3.0.3.dev0 (#1291) 2022-02-03 01:47:06 -08:00
Batuhan Taskaya
f1ea486025
Fix escaping of integer indexes with multiple backslashes (#1288) 2022-02-01 02:10:55 -08:00
Batuhan Taskaya
7abddfe350
Mark stdin warning related tests with requires_external_processes (#1289)
* Mark test_stdin_read_warning with requires_installation

* Mark stdin tests with requires_external_processes

Co-authored-by: Nilushan Costa <19643850+nilushancosta@users.noreply.github.com>
2022-02-01 01:52:07 -08:00
Marcos Chicote
86ba995ad8
2022 (#1259) 2022-01-26 17:45:03 +03:00
Batuhan Taskaya
c03f081a7e Finish off the naming 2022-01-26 12:51:10 +03:00
Batuhan Taskaya
a7d8187b21 Proper naming for the release runs 2022-01-26 12:50:22 +03:00
Batuhan Taskaya
fc383e9b78 Add names to the CI runners 2022-01-26 12:49:27 +03:00
Batuhan Taskaya
770df02291
Add level parameter to the snap releaser (#1282) 2022-01-26 12:44:24 +03:00
Jakub Roztocil
f756cad58d
Update CHANGELOG.md 2022-01-24 16:54:50 -08:00
Jakub Roztocil
fde64d578d
Update CHANGELOG.md 2022-01-24 10:32:24 -08:00
Jakub Roztocil
c8404493e5
Update CHANGELOG.md 2022-01-24 10:32:07 -08:00
Batuhan Taskaya
559134de0a
Release 3.0.2 (#1281) 2022-01-24 21:20:17 +03:00
Batuhan Taskaya
813e8864a1
Dont apply default options on the httpie command (#1280)
* Mark tests with requires_installation

* Dont apply default options on the httpie command

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

* `requests.Response._headers_parsed_at` → `requests.Response._httpie_headers_parsed_at`

* Add `ELAPSED_TIME_LABEL` constant

* Tweak docs

* Tweak docs

* Allow multiple blank lines in Markdown files

* Add rudimentary tests for --meta with different --style’s

* Cleanup tests

* Cleanup tests

* Cleanup tests
2022-01-23 04:52:38 -08:00
Batuhan Taskaya
8a03b7a824
Update the contributors (#1275) 2022-01-22 17:25:00 -08:00
Batuhan Taskaya
b3f29c8d1e
Display the latest docs (#1274) 2022-01-21 22:15:55 +03:00
Jakub Roztocil
a88e44c284 Fix make brew-test
`brew test` is only usable for non-from-source installations.
2022-01-21 19:48:35 +01:00
Batuhan Taskaya
c97fe64a37
Update brew with 3.0 (#1273) 2022-01-21 21:08:33 +03:00
Batuhan Taskaya
88140422a9
3.0 release prep (#1272) 2022-01-21 20:34:38 +03:00
Jakub Roztocil
d2d40eb336
Finish docs for v3.0.0 (#1269)
* WIP

* Rewrite the introduction segment of the Nested JSON

Co-authored-by: Batuhan Taskaya <isidentical@gmail.com>
2022-01-21 20:24:07 +03:00
Batuhan Taskaya
cd877a5e08
Remove 3.6 support / discontinue less available platforms (#1267)
* Remove redundant systems

* Drop it from the docs

* Remove the packaging info about the legacy systems

* Fix some typos

* Drop support for python 3.6
2022-01-14 08:49:05 -08:00
Batuhan Taskaya
87629706c9
Change the default style for windows from fruity to auto (#1268) 2022-01-14 08:47:10 -08:00
Batuhan Taskaya
3856f94d3d Update the brew file 2022-01-14 13:27:19 +03:00
Batuhan Taskaya
dc30919893 use constants 2022-01-13 19:54:43 +03:00
Batuhan Taskaya
fb82f44cd1 Use enums 2022-01-13 19:54:43 +03:00
Batuhan Taskaya
eb4e32ca28 A few edits 2022-01-13 19:54:43 +03:00
Batuhan Taskaya
980bd59e29 Rewrite the docs 2022-01-13 19:54:43 +03:00
Batuhan Taskaya
2cda966384 Implement escaped integers 2022-01-13 19:54:43 +03:00
Batuhan Taskaya
7bf373751d Implement HTTPie Nested JSON v2 2022-01-13 19:54:43 +03:00
Batuhan Taskaya
21faddc4b9 Proper separation of meta/body 2022-01-13 15:04:44 +03:00
Batuhan Taskaya
c126bc11c7 Make the stdin wait tests more reliable 2022-01-13 15:04:30 +03:00
Batuhan Taskaya
00c859c51d
Add warnings when there is no incoming data from stdin (#1256)
* Add warnings when there is no incoming data from stdin

* Pass os.environ as well

* Apply suggestions
2022-01-12 06:07:34 -08:00
Greg Myers
508788ca56
Fix two typos in docs/README.md (#1261)
contaning  -> containing
overwriten -> overwritten

Co-authored-by: greg <gmyers@gitlab.com>
2022-01-10 02:48:42 -08:00
Batuhan Taskaya
4c56d894ba
Fix --raw with --chunked (#1254)
* Fix --raw with --chunked

* Better naming / annotations

* More annotations
2021-12-29 12:41:44 +03:00
Batuhan Taskaya
0e10e23dca Mention explicitly about prompted passwords are stored as raw in the docs 2021-12-29 12:03:44 +03:00
Batuhan Taskaya
06512c72a3 Include the original issue in the changelog 2021-12-29 12:02:24 +03:00
Batuhan Taskaya
8d84248ee3 Add the changelog entry 2021-12-29 12:01:49 +03:00
Sebastian Czech
17ed3bb8c5
Store prompted passwords in local sessions (#1239)
Co-authored-by: Batuhan Taskaya <isidentical@gmail.com>
2021-12-29 12:00:47 +03:00
Batuhan Taskaya
05c02f0f39 Update shortcuts as well 2021-12-24 11:53:31 +03:00
Batuhan Taskaya
0ebc9a7e09 Mention about levels in -v 2021-12-24 11:53:15 +03:00
Batuhan Taskaya
c692669526 Fix -v docs to include BASE_OUTPUT_OPTIONS 2021-12-24 11:51:11 +03:00
Batuhan Taskaya
747accc2ae Include response metadata in --print help 2021-12-24 11:50:19 +03:00
Batuhan Taskaya
f3b500119c
Implement basic metrics layout & total elapsed time (#1250)
* Initial metadata processing

* Dynamic coloring and other stuff

* Use -vv / --meta

* More testing

* Cleanup

* Tweek message

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-12-23 12:13:25 -08:00
Batuhan Taskaya
e0e03f3237
Better DNS error handling (#1249)
* Better DNS error handling

* Update httpie/core.py

Co-authored-by: Batuhan Taskaya <isidentical@gmail.com>

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-12-23 11:35:30 -08:00
Batuhan Taskaya
be87da8bbd
Formalize @ suffix for all operators (#1225)
* Formalize @ suffix for all operators

* Separate the section

* Address suggestions
2021-12-23 11:06:35 -08:00
Batuhan Taskaya
e09401b81a
Optimize encoding detection (#1243)
* Optimize encoding detection

* Use a threshold based system
2021-12-23 11:05:58 -08:00
Batuhan Taskaya
5a83a9ebc4 Test https as well 2021-12-21 20:33:23 +03:00
Batuhan Taskaya
c97ec93a19 Test httpie 2021-12-21 20:33:09 +03:00
Batuhan Taskaya
2d15659b16 Make brew action triggerable 2021-12-21 20:28:42 +03:00
Batuhan Taskaya
021b41c9e5 Make snap action triggerable 2021-12-21 20:28:23 +03:00
Batuhan Taskaya
8dc6c0df77
Implement new pie and pie-light styles (#1238)
* Implement new `pie` and `pie-light` styles

* Change some pallete

* Integrate the color palette

* some docs

* some docs

* Rework on code generation

* Apply suggestions from code review

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-12-19 02:41:42 -08:00
Batuhan Taskaya
1bd8422fb5
Improve startup time when pyOpenSSL is available on the environment (#1233) 2021-12-17 00:00:22 -08:00
Batuhan Taskaya
c237e15108
Faster downloads through bigger chunks / less buffering (#1236) 2021-12-17 00:00:03 -08:00
Batuhan Taskaya
a5d8b51e47
Implement httpie upgrade for upgrading plugins (#1241)
* Implement `httpie upgrade` for upgrading plugins

* Support upgrades for every installation type

* Fix decoding problems
2021-12-16 23:59:39 -08:00
Batuhan Taskaya
2b78d04410
Strip out extra variables from the actual mime type (#1244)
* Strip out extra variables from the actual mime type

* mention in changelog

* Update CHANGELOG.md

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-12-16 07:04:34 -08:00
Batuhan Taskaya
7bd7aa20d2 (stale action) bump operations per run to 300 2021-12-16 12:24:52 +03:00
Batuhan Taskaya
7ae44aefe2 (stale action) get rid of stale message, only comment on closing 2021-12-16 12:19:25 +03:00
Batuhan Taskaya
28e874535a (stale action) bump days to 30 2021-12-16 12:18:09 +03:00
Batuhan Taskaya
340fef6278 (stale action) Fix typo in closing message 2021-12-16 12:17:55 +03:00
Batuhan Taskaya
088b6cdb0c Move stale action from debug to actual run 2021-12-16 12:14:50 +03:00
Batuhan Taskaya
43462f8af0 Only configure with workflow_dispatch 2021-12-16 12:11:12 +03:00
Batuhan Taskaya
e4b2751a52 Set stale action to run on workflow dispatch 2021-12-16 12:09:31 +03:00
Batuhan Taskaya
f94c12d8ca
Close all stale PRs (#1245) 2021-12-16 12:06:00 +03:00
Batuhan Taskaya
3db1cdba4c
Don't inconsistently add XML declarations (#1227) 2021-12-14 07:15:19 -08:00
Batuhan Taskaya
4f7f59b990
Add initial benchmarking infrastructure (#1232)
* Add initial benchmarking infrastructure

* Add CI file

* Try to comment on commits

* Implement file download benchmarks!

* drop commit comments (they dont work)

* Allow running local binary

* Better action

* More docs!

* Better look?

* even better look

* add pretty=all, none benchmarks
2021-12-14 07:05:25 -08:00
Batuhan Taskaya
e30ec6be42
Remove unnecessary empty line in CHANGELOG 2021-12-09 12:46:19 +03:00
Batuhan Taskaya
207b970d94
Automatically enable --stream on server sent events (#1226)
* Automatically enable --stream when used chunked encoding

* try fix 3.6 mock issue

* Only enable on text/event-stream

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-12-08 07:49:12 -08:00
Batuhan Taskaya
62e43abc86
Ignore crashes that happen on the 3rd party plugins (#1228)
* Ignore crashes that happen on the 3rd party plugins

* Give a suggestion about how to uninstall
2021-12-08 07:45:07 -08:00
Batuhan Taskaya
ea8e22677a
Fix snapcraft packaging (#1235) 2021-12-08 01:20:58 -08:00
Batuhan Taskaya
df58ec683e
Add nested JSON syntax to the HTTPie DSL (#1224)
* Add support for nested JSON syntax (#1169)

Co-authored-by: Batuhan Taskaya <isidentical@gmail.com>
Co-authored-by: Jakub Roztocil <jakub@roztocil.co>

* minor improvements

* unpack top level lists

* Write more docs

* doc style changes

* fix double quotes

Co-authored-by: Mickaël Schoentgen <contact@tiger-222.fr>
Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-12-03 02:17:45 -08:00
Jakub Roztocil
8fe1f08a37 Changelog 2021-12-01 20:51:00 +01:00
Jakub Roztocil
521ddde4c5 CHANGELOG.md 2021-12-01 20:49:03 +01:00
Jakub Roztocil
3457806df1 CHANGELOG.md 2021-12-01 20:45:54 +01:00
Jakub Roztocil
840f77d2a8 Tweak changelog & 3.0.0.dev0 2021-12-01 20:44:04 +01:00
Batuhan Taskaya
6522ce06d0
Add plugin management changelog entry (#1223)
* Add plugin management changelog entry

* Update CHANGELOG.md

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-12-01 10:20:16 -08:00
Batuhan Taskaya
f927065416
brew: add multidict (#1222) 2021-12-01 10:19:38 -08:00
Batuhan Taskaya
151becec2b
Improve startup time with lazy loading some args (#1221)
* Improve startup time with lazy loading some args

* add some tests

* Add changelog entry

* Update CHANGELOG.md

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-12-01 10:15:59 -08:00
Batuhan Taskaya
ba8e4097e8
Support ==@ syntax for query parameter values from file (#1218)
Co-authored-by: Vladimir Berkutov <vladimir.berkutov@gmail.com>

Co-authored-by: Vladimir Berkutov <vladimir.berkutov@gmail.com>
2021-12-01 10:09:39 -08:00
Batuhan Taskaya
00b366a81f
Implement Bearer Auth (#1216) 2021-12-01 09:37:57 -08:00
Batuhan Taskaya
5bf696d113
Fix packit CI (#1219) 2021-11-30 13:49:38 +03:00
Batuhan Taskaya
3081fc1a3c
Add httpie --version (#1220) 2021-11-30 13:18:37 +03:00
Batuhan Taskaya
245cede2c2
cmd: Implement httpie plugins interface (#1200) 2021-11-30 11:12:51 +03:00
Batuhan Taskaya
6bdcdf1eba
Proper JSON handling for :=/:=@ (#1213)
* Proper JSON handling for :=/:=@

* document the behavior

* fixup docs
2021-11-26 03:45:46 -08:00
Vivaan Verma
0fc6331ee0
Change PyPi to PyPI (#1203)
* Change `PyPi` to `PyPI`

* fix: change `PyPi` to `PyPI` in method yaml file
2021-11-25 14:06:34 -08:00
Batuhan Taskaya
ef62fc11bf
core: support custom request/response classes (#1205)
* core: support custom request/response classes

* Move to `httpie.models`, prefix with `Requests`
2021-11-24 15:45:39 -08:00
Batuhan Taskaya
c000886546
Preserve individual headers with the same name on responses (#1208)
* Preserve individual headers with the same name on responses

* Rename RequestHeadersDict to HTTPHeadersDict

* Update tests/utils/http_server.py

* Update tests/utils/http_server.py

* Update httpie/adapters.py

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-11-24 15:41:37 -08:00
Jan Brašna
cfcd7413d1
Fix README broken links to old locations (#1209) 2021-11-21 02:38:05 -08:00
Jan Brašna
7dfa001d2c
Consistent userdir/name example (#1210) 2021-11-21 02:32:00 -08:00
Jakub Roztocil
06d9c14e7a Add $ http :// error handling test 2021-11-05 14:11:30 +01:00
Jakub Roztocil
861b8b36a8
Strip leading :// from URLs to allow quick conversion of a pasted URL to calls (#1197)
* Strip leading `://` from URLs to allow quick conversion of a pasted URL to calls

Closes #1195

* Markdown lint

* Cleanup

* Cleanup

* Drop extraneous space

* Fix example
2021-11-05 13:59:23 +01:00
Jakub Roztocil
434512e92f
Update bug_report.md 2021-11-04 23:20:46 +01:00
Jakub Roztocil
72735d9d59
Update config.json 2021-11-03 12:50:07 +01:00
Batuhan Taskaya
7cdd74fece
Support multiple headers sharing the same name (#1190)
* Support multiple headers sharing the same name

* Apply suggestions

* Don't normalize HTTP header names

* apply visual suggestions

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>

* bump down multidict to 4.7.0

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-10-31 15:04:39 +01:00
Jakub Roztocil
d40f06687f
Update README.md 2021-10-29 11:33:46 +02:00
Mickaël Schoentgen
0d9c8b88b3
Change Chocolatey owner 2021-10-25 17:18:53 +02:00
Gaurav
cff45276b5
Fix Snap autocompletion (#1189) 2021-10-25 16:36:34 +02:00
Mickaël Schoentgen
e75e0a0565
Change Void Linux maintainer 2021-10-25 16:25:59 +02:00
Mickaël Schoentgen
19e48ba901
Update Spack metadata 2021-10-25 16:19:49 +02:00
Mickaël Schoentgen
a9b8513f62
Update Gentoo metadata 2021-10-25 16:16:26 +02:00
Mickaël Schoentgen
7985cf60c8
Fix Gentoo example link 2021-10-25 16:15:27 +02:00
Mickaël Schoentgen
5dc4a26277
Remove myself from the HTTPie team 2021-10-25 14:55:45 +02:00
Mickaël Schoentgen
7775422afb
Add contributors list update to the release process 2021-10-25 14:54:59 +02:00
Jakub Roztocil
2be43e698a
Add HTTPie 2.6.0 blog post link
https://httpie.io/blog/httpie-2.6.0
2021-10-24 19:44:02 +02:00
Mickaël Schoentgen
3abc76f6d5 Tiny docstring clean-up 2021-10-19 10:24:01 +02:00
Mickaël Schoentgen
021eb651e0
Bump the version to 2.7.0.dev0 (#1188) 2021-10-19 10:21:45 +02:00
Mickaël Schoentgen
419427cfb6
Update downstream files for HTTPie 2.6.0 (#1186)
* Update Alpine package

* Add charset-normalizer deps for Alpine

It currently does not exist. We will need to add it ourselves.

* Update Gentoo package

* Update Brew formula

* Update MacPorts port

* Fix Gentoo deps

* Update examples

* Update Void Linux package

* Update Void Linux commands

* Update Chocolateur package

* Review DEbian packaging details

* Simplify Void Linux package

* Update more packages

* Update summary everywhere

* Remove temporary file

* Update Chocolatey package URL

* Updates

* Update Spack
2021-10-19 10:18:35 +02:00
hosseingt
7500912be1
Corrected command for installing development version on Windows (#1187) 2021-10-15 18:01:07 +02:00
Miro Hrončok
1b4048aefc
dnf/yum update is the same as dnf upgrade -- it updates all packages (#1184)
No reason to run it before installing or upgrading httpie.
This is not apt.
2021-10-15 15:29:06 +02:00
Miro Hrončok
7885f5cd66
Minor version changes in the Fedora packaging docs (#1185) 2021-10-15 15:24:21 +02:00
Mickaël Schoentgen
3e414d731c Update the awesome contributors list to HTTPie 2.6.0 2021-10-14 17:17:14 +02:00
Mickaël Schoentgen
d8f6a5fe52 Blank master_and_released_docs_differ_after 2021-10-14 11:30:13 +02:00
Jakub Roztocil
cee283a01a
Update setup.py 2021-10-14 11:27:12 +02:00
Jakub Roztocil
5c267003c7
Update links 2021-10-14 11:25:13 +02:00
Mickaël Schoentgen
cdab8e67cb Release workflow: fix 2021-10-14 10:56:13 +02:00
Mickaël Schoentgen
6c6093a46d Configure PyPi for the release workflow 2021-10-14 10:45:31 +02:00
Mickaël Schoentgen
42af2f786f
v2.6.0 (#1182)
[skip ci]
2021-10-14 10:36:39 +02:00
Mickaël Schoentgen
a65771e271
Add a script that lists all contributors to a release (#1181)
* Add a script that lists all contributors to a release

We will keep a contributors database (simple JSON file) where
each entry is a contributor (either a committer, either an issue reporter,
either both) with some nicknames (GitHub, and Twitter).
The file will be used to craft credits on our release blog posts and to ping
them on Twitter.

* Add templates

* Missing docstring

* Clean-up

* Tweak
2021-10-14 10:33:14 +02:00
Jakub Roztocil
7b683d4b57 Update CHANGELOG.md 2021-10-13 23:37:40 +02:00
Mickaël Schoentgen
a15fd6f966
Add --response=mime and --response=charset docs (#1179)
* Add the "display encoding" section in the docs

* Remove repetition

* `--response=mime` / `--response=charset` docs

* Cleanup

* Cleanup

* Cleanup

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-10-13 23:32:46 +02:00
Mickaël Schoentgen
19691bba68 Packaging documentation tweaks 2021-10-11 17:42:29 +02:00
Mickaël Schoentgen
344491ba8e Tweak the Chocolatey package installation file 2021-10-11 10:07:24 +02:00
jakubroztocil
9f6fa090df Auto-update install docs
Via .github/workflows/docs-update-install.yml
2021-10-10 18:58:57 +00:00
Jakub Roztocil
59f4ef03cc Remove macOS/Snap
snapd is not available on macOS yet
2021-10-10 20:58:05 +02:00
jakubroztocil
ef92e2a74a Auto-update install docs
Via .github/workflows/docs-update-install.yml
2021-10-10 18:46:46 +00:00
Jakub Roztocil
1171984ec2 Better links for snap on macos 2021-10-10 20:45:53 +02:00
jakubroztocil
ce9746b1f8 Auto-update install docs
Via .github/workflows/docs-update-install.yml
2021-10-10 18:25:59 +00:00
Jakub Roztocil
6b99e1c932 Link GitHub action file in generated commit 2021-10-10 20:25:12 +02:00
jakubroztocil
7d418aecd0 Auto-update installation instructions in the docs 2021-10-10 18:18:39 +00:00
Jakub Roztocil
459cdfcf53 Tweak install docs template
Shorten setup, add missing comma
2021-10-10 20:17:49 +02:00
Mickaël Schoentgen
ab8512f96c
Add --compress documentation (#1173)
* Add --compress documentation

* Apply suggestions from code review

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>

* Update docs/README.md

* Update docs/README.md

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
2021-10-08 18:38:40 +02:00
dkreeft
6befaf9067
Added the ability to silence warnings via double -q or --quiet (#1175)
* change behavior of '--quiet' to silence errors and warnings when passed twice together with '--check-status'

* Apply suggestions from code review

Co-authored-by: Jakub Roztocil <jakub@roztocil.co>

* remove header, trailing comma, rename constant and variable

* fix flags for tests

* [skip ci] Update ticket number

Co-authored-by: Dave <d.kreeft@outlook.com>
Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
Co-authored-by: Mickaël Schoentgen <contact@tiger-222.fr>
2021-10-08 14:18:11 +02:00
Mickaël Schoentgen
1b7f74c2b2
Add a workflow to control Snap publications (#1176) 2021-10-08 11:24:24 +02:00
217 changed files with 14567 additions and 2335 deletions

View File

@ -3,7 +3,7 @@ name: Bug report
about: Report a possible bug in HTTPie
title: ''
labels: "new, bug"
assignees: 'BoboTiG'
assignees: ''
---

52
.github/workflows/benchmark.yml vendored Normal file
View File

@ -0,0 +1,52 @@
name: Benchmark
on:
pull_request:
types: [ labeled ]
permissions:
issues: write
pull-requests: write
jobs:
test:
if: github.event.label.name == 'benchmark'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.9"
- id: benchmarks
name: Run Benchmarks
run: |
python -m pip install pyperf>=2.3.0
python extras/profiling/run.py --fresh --complex --min-speed=6 --file output.txt
body=$(cat output.txt)
body="${body//'%'/'%25'}"
body="${body//$'\n'/'%0A'}"
body="${body//$'\r'/'%0D'}"
echo "::set-output name=body::$body"
- name: Find Comment
uses: peter-evans/find-comment@v2
id: fc
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: '# Benchmarks'
- name: Create or update comment
uses: peter-evans/create-or-update-comment@v2
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body: |
# Benchmarks
${{ steps.benchmarks.outputs.body }}
edit-mode: replace
- uses: actions-ecosystem/action-remove-labels@v1
with:
labels: benchmark

View File

@ -1,3 +1,5 @@
name: Code Style Check
on:
pull_request:
paths:
@ -11,8 +13,8 @@ jobs:
code-style:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.9
- run: make venv

22
.github/workflows/content.yml vendored Normal file
View File

@ -0,0 +1,22 @@
name: Update Generated Content
on:
push:
branches:
- master
jobs:
update-content:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.9
- run: make content
- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@v4
with:
commit-message: "[automated] Update generated content"
title: "[automated] Update generated content"
delete-branch: true
token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,3 +1,5 @@
name: Coverage
on:
pull_request:
paths:
@ -10,8 +12,8 @@ jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.10"
- run: make install

View File

@ -1,3 +1,5 @@
name: Check Markdown Style
on:
pull_request:
paths:
@ -8,7 +10,7 @@ jobs:
doc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:

View File

@ -1,3 +1,5 @@
name: Deploy Documentation
on:
push:
branches:
@ -15,6 +17,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Install HTTPie
run: sudo snap install --edge httpie
run: sudo pip install httpie
- name: Trigger new documentation build
run: http --ignore-stdin POST ${{ secrets.DOCS_UPDATE_VERCEL_HOOK }}

View File

@ -1,26 +0,0 @@
on:
push:
branches:
- master
paths:
- docs/installation/*
# Allow to call the workflow manually
workflow_dispatch:
jobs:
doc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.9
- run: make install
- run: make doc-update-install
- uses: Automattic/action-commit-to-branch@master
with:
branch: master
commit_message: Auto-update installation instructions in the docs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

26
.github/workflows/release-brew.yml vendored Normal file
View File

@ -0,0 +1,26 @@
name: Release on Homebrew
on:
workflow_dispatch:
inputs:
branch:
description: "The branch, tag or SHA to release from"
required: true
default: "master"
jobs:
brew-release:
name: Release the Homebrew Package
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.inputs.branch }}
- uses: mislav/bump-homebrew-formula-action@v2
with:
formula-name: httpie
tag-name: ${{ github.events.inputs.branch }}
env:
COMMITTER_TOKEN: ${{ secrets.BREW_UPDATE_TOKEN }}

61
.github/workflows/release-choco.yml vendored Normal file
View File

@ -0,0 +1,61 @@
name: Release on Chocolatey
on:
workflow_dispatch:
inputs:
branch:
description: "The branch, tag or SHA to release from"
required: true
default: "master"
jobs:
brew-release:
name: Release the Chocolatey
runs-on: windows-2019
env:
package-dir: docs\packaging\windows-chocolatey
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.inputs.branch }}
# Chocolatey comes already installed on the Windows GHA image
- name: Build the Choco package
shell: cmd
run: choco pack -v
working-directory: ${{ env.package-dir }}
- name: Check the Choco package
run: choco info httpie -s .
working-directory: ${{ env.package-dir }}
- name: Local installation
run: |
choco install httpie -y -dv -s "'.;https://community.chocolatey.org/api/v2/'"
working-directory: ${{ env.package-dir }}
- name: Test the locally installed binaries
run: |
# Source: https://stackoverflow.com/a/46760714/15330941
# Make `refreshenv` available right away, by defining the $env:ChocolateyInstall
# variable and importing the Chocolatey profile module.
$env:ChocolateyInstall = Convert-Path "$((Get-Command choco).Path)\..\.."
Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1"
refreshenv
http --version
https --version
httpie --version
choco uninstall -y httpie
working-directory: ${{ env.package-dir }}
- name: Publish on Chocolatey
shell: bash
env:
CHOCO_API_KEY: ${{ secrets.CHOCO_API_KEY }}
run: |
choco apikey --key $CHOCO_API_KEY --source https://push.chocolatey.org/
choco push httpie*.nupkg --source https://push.chocolatey.org/
working-directory: ${{ env.package-dir }}

View File

@ -0,0 +1,77 @@
name: Release as Standalone Linux Package
on:
workflow_dispatch:
inputs:
branch:
description: "The branch, tag or SHA to release from"
required: true
default: "master"
tag_name:
description: "Which release to upload the artifacts to (e.g., 3.0)"
required: true
release:
types: [released, prereleased]
jobs:
binary-build-and-release:
name: Build and Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.inputs.branch }}
- uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Build Artifacts
run: |
cd extras/packaging/linux
./get_release_artifacts.sh
- uses: actions/upload-artifact@v3
with:
name: http
path: extras/packaging/linux/artifacts/dist/http
- uses: actions/upload-artifact@v3
with:
name: httpie.deb
path: extras/packaging/linux/artifacts/dist/*.deb
- uses: actions/upload-artifact@v3
with:
name: httpie.rpm
path: extras/packaging/linux/artifacts/dist/*.rpm
- name: Determine the release upload upload_url
id: release_id
run: |
pip install httpie
export API_URL="api.github.com/repos/httpie/cli/releases/tags/${{ github.event.inputs.tag_name }}"
export UPLOAD_URL=`https --ignore-stdin GET $API_URL | jq -r ".upload_url"`
echo "::set-output name=UPLOAD_URL::$UPLOAD_URL"
- name: Publish Debian Package
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.release_id.outputs.UPLOAD_URL }}
asset_path: extras/packaging/linux/artifacts/dist/httpie_${{ github.event.inputs.tag_name }}_amd64.deb
asset_name: httpie-${{ github.event.inputs.tag_name }}.deb
asset_content_type: binary/octet-stream
- name: Publish Single Executable
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.release_id.outputs.UPLOAD_URL }}
asset_path: extras/packaging/linux/artifacts/dist/http
asset_name: http
asset_content_type: binary/octet-stream

30
.github/workflows/release-pypi.yml vendored Normal file
View File

@ -0,0 +1,30 @@
name: Release on PyPI
on:
workflow_dispatch:
inputs:
branch:
description: "The branch, tag or SHA to release from"
required: true
default: "master"
jobs:
pypi-build-and-release:
name: Build and Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.inputs.branch }}
- uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Build a binary wheel and a source tarball
run: make install && make build
- name: Release on PyPI
uses: pypa/gh-action-pypi-publish@master
with:
password: ${{ secrets.PYPI_TOKEN }}

41
.github/workflows/release-snap.yml vendored Normal file
View File

@ -0,0 +1,41 @@
name: Release on Snap
on:
workflow_dispatch:
inputs:
branch:
description: "The branch, tag or SHA to release from"
required: true
default: "master"
jobs:
snap-build-and-release:
name: Build & Release the Snap Package
runs-on: ubuntu-latest
strategy:
# If any of the stages fail, then we'll stop the action
# to give release manager time to investigate the underlying
# issue.
fail-fast: true
matrix:
level: [edge, beta, candidate, stable]
# Set the concurrency level for this version, so
# that we'll release one by one.
concurrency: ${{ github.event.inputs.branch }}
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.inputs.branch }}
- uses: snapcore/action-build@v1
id: build
- uses: snapcore/action-publish@v1
env:
SNAPCRAFT_STORE_CREDENTIALS: ${{ secrets.SNAP_STORE_LOGIN }}
with:
snap: ${{ steps.build.outputs.snap }}
release: ${{ matrix.level }}

View File

@ -1,26 +0,0 @@
on:
# Add a "Trigger" button to manually start the workflow.
workflow_dispatch:
inputs:
branch:
description: "The branch, tag or SHA to release from"
required: true
default: "master"
# It could be fully automated by uncommenting following lines.
# Let's see later if we are confident enough to try it :)
# release:
# types:
# - published
jobs:
new-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.9
- run: make publish
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}

26
.github/workflows/stale.yml vendored Normal file
View File

@ -0,0 +1,26 @@
name: Mark stale pull requests
on: workflow_dispatch
permissions:
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v8
with:
close-pr-message: 'Thanks for the pull request, but since it was stale for more than a 30 days we are closing it. If you want to work back on it, feel free to re-open it or create a new one.'
stale-pr-label: 'stale'
days-before-stale: -1
days-before-issue-stale: -1
days-before-pr-stale: 30
days-before-close: -1
days-before-issue-close: -1
days-before-pr-close: 0
operations-per-run: 300

View File

@ -1,14 +1,18 @@
name: Test Snap Package (Linux)
on:
pull_request:
paths:
- .github/workflows/test-package-linux-snap.yml
- snapcraft.yaml
workflow_dispatch:
jobs:
snap:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Build
uses: snapcore/action-build@v1
id: snapcraft
@ -18,6 +22,7 @@ jobs:
run: |
httpie.http --version
httpie.https --version
httpie --version
# Auto-aliases cannot be tested when installing a snap outside the store.
# http --version
# https --version

View File

@ -1,14 +1,17 @@
name: Test Brew Package (MacOS)
on:
pull_request:
paths:
- .github/workflows/test-package-mac-brew.yml
- docs/packaging/brew/httpie.rb
workflow_dispatch:
jobs:
brew:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Setup brew
run: |
brew developer on

View File

@ -1,3 +1,8 @@
name: Tests
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
on:
push:
branches:
@ -20,12 +25,12 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: [3.6, 3.7, 3.8, 3.9, "3.10"]
python-version: [3.7, 3.8, 3.9, "3.10"]
pyopenssl: [0, 1]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Windows setup

4
.gitignore vendored
View File

@ -43,8 +43,8 @@ MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
*.manifest
# Installer logs
pip-log.txt
@ -151,3 +151,5 @@ dmypy.json
# Windows Chocolatey
*.nupkg
artifacts/

View File

@ -4,14 +4,9 @@ specfile_path: httpie.spec
actions:
# get the current Fedora Rawhide specfile:
post-upstream-clone: "wget https://src.fedoraproject.org/rpms/httpie/raw/rawhide/f/httpie.spec -O httpie.spec"
# Use this when the latest spec is not up-to-date.
# post-upstream-clone: "cp docs/packaging/linux-fedora/httpie.spec.txt httpie.spec"
jobs:
- job: copr_build
trigger: pull_request
metadata:
targets:
- fedora-all
additional_repos:
- "https://kojipkgs.fedoraproject.org/repos/f$releasever-build/latest/$basearch/"
- job: propose_downstream
trigger: release
metadata:

View File

@ -4,7 +4,7 @@
## Patches, features, ideas
[Complete list of contributors on GitHub](https://github.com/httpie/httpie/graphs/contributors)
[Complete list of contributors on GitHub](https://github.com/httpie/cli/graphs/contributors)
- [Cláudia T. Delgado](https://github.com/claudiatd)
- [Hank Gay](https://github.com/gthank)

View File

@ -3,72 +3,151 @@
This document records all notable changes to [HTTPie](https://httpie.io).
This project adheres to [Semantic Versioning](https://semver.org/).
## [2.6.0.dev0](https://github.com/httpie/httpie/compare/2.5.0...master) (unreleased)
## [3.3.0-dev](https://github.com/httpie/cli/compare/3.2.2...master) (unreleased)
- Added support for formatting & coloring of JSON bodies preceded by non-JSON data (e.g., an XXSI prefix). ([#1130](https://github.com/httpie/httpie/issues/1130))
- Added `--response-charset` to allow overriding the response encoding for terminal display purposes. ([#1168](https://github.com/httpie/httpie/issues/1168))
- Added `--response-mime` to allow overriding the response mime type for coloring and formatting for the terminal. ([#1168](https://github.com/httpie/httpie/issues/1168))
- Improved handling of responses with incorrect `Content-Type`. ([#1110](https://github.com/httpie/httpie/issues/1110), [#1168](https://github.com/httpie/httpie/issues/1168))
- Installed plugins are now listed in `--debug` output. ([#1165](https://github.com/httpie/httpie/issues/1165))
- Fixed duplicate keys preservation of JSON data. ([#1163](https://github.com/httpie/httpie/issues/1163))
- Make it possible to [unset](https://httpie.io/docs/cli/default-request-headers) the `User-Agent`, `Accept-Encoding`, and `Host` request headers. ([#1502](https://github.com/httpie/cli/issues/1502))
## [2.5.0](https://github.com/httpie/httpie/compare/2.4.0...2.5.0) (2021-09-06)
## [3.2.2](https://github.com/httpie/cli/compare/3.2.1...3.2.2) (2022-05-19)
Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
- Fixed compatibility with urllib3 2.0.0. ([#1499](https://github.com/httpie/cli/issues/1499))
## [3.2.1](https://github.com/httpie/cli/compare/3.1.0...3.2.1) (2022-05-06)
- Improved support for determining auto-streaming when the `Content-Type` header includes encoding information. ([#1383](https://github.com/httpie/cli/pull/1383))
- Fixed the display of the crash happening in the secondary process for update checks. ([#1388](https://github.com/httpie/cli/issues/1388))
## [3.2.0](https://github.com/httpie/cli/compare/3.1.0...3.2.0) (2022-05-05)
- Added a warning for notifying the user about the new updates. ([#1336](https://github.com/httpie/cli/pull/1336))
- Added support for single binary executables. ([#1330](https://github.com/httpie/cli/pull/1330))
- Added support for man pages (and auto generation of them from the parser declaration). ([#1317](https://github.com/httpie/cli/pull/1317))
- Added `http --manual` for man pages & regular manual with pager. ([#1343](https://github.com/httpie/cli/pull/1343))
- Added support for session persistence of repeated headers with the same name. ([#1335](https://github.com/httpie/cli/pull/1335))
- Added support for sending `Secure` cookies to the `localhost` (and `.local` suffixed domains). ([#1308](https://github.com/httpie/cli/issues/1308))
- Improved UI for the progress bars. ([#1324](https://github.com/httpie/cli/pull/1324))
- Fixed redundant creation of `Content-Length` header on `OPTIONS` requests. ([#1310](https://github.com/httpie/cli/issues/1310))
- Fixed blocking of warning thread on some use cases. ([#1349](https://github.com/httpie/cli/issues/1349))
- Changed `httpie plugins` to the new `httpie cli` namespace as `httpie cli plugins` (`httpie plugins` continues to work as a hidden alias). ([#1320](https://github.com/httpie/cli/issues/1320))
- Soft deprecated the `--history-print`. ([#1380](https://github.com/httpie/cli/pull/1380))
## [3.1.0](https://github.com/httpie/cli/compare/3.0.2...3.1.0) (2022-03-08)
- **SECURITY** Fixed the [vulnerability](https://github.com/httpie/cli/security/advisories/GHSA-9w4w-cpc8-h2fq) that caused exposure of cookies on redirects to third party hosts. ([#1312](https://github.com/httpie/cli/pull/1312))
- Fixed escaping of integer indexes with multiple backslashes in the nested JSON builder. ([#1285](https://github.com/httpie/cli/issues/1285))
- Fixed displaying of status code without a status message on non-`auto` themes. ([#1300](https://github.com/httpie/cli/issues/1300))
- Fixed redundant issuance of stdin detection warnings on some rare cases due to underlying implementation. ([#1303](https://github.com/httpie/cli/pull/1303))
- Fixed double `--quiet` so that it will now suppress all python level warnings. ([#1271](https://github.com/httpie/cli/issues/1271))
- Added support for specifying certificate private key passphrases through `--cert-key-pass` and prompts. ([#946](https://github.com/httpie/cli/issues/946))
- Added `httpie cli export-args` command for exposing the parser specification for the `http`/`https` commands. ([#1293](https://github.com/httpie/cli/pull/1293))
- Improved regulation of top-level arrays. ([#1292](https://github.com/httpie/cli/commit/225dccb2186f14f871695b6c4e0bfbcdb2e3aa28))
- Improved UI layout for standalone invocations. ([#1296](https://github.com/httpie/cli/pull/1296))
## [3.0.2](https://github.com/httpie/cli/compare/3.0.1...3.0.2) (2022-01-24)
[Whats new in HTTPie for Terminal 3.0 →](https://httpie.io/blog/httpie-3.0.0)
- Fixed usage of `httpie` when there is a presence of a config with `default_options`. ([#1280](https://github.com/httpie/cli/pull/1280))
## [3.0.1](https://github.com/httpie/cli/compare/3.0.0...3.0.1) (2022-01-23)
[Whats new in HTTPie for Terminal 3.0 →](https://httpie.io/blog/httpie-3.0.0)
- Changed the value shown as time elapsed from time-to-read-headers to total exchange time. ([#1277](https://github.com/httpie/cli/issues/1277))
## [3.0.0](https://github.com/httpie/cli/compare/2.6.0...3.0.0) (2022-01-21)
[Whats new in HTTPie for Terminal 3.0 →](https://httpie.io/blog/httpie-3.0.0)
- Dropped support for Python 3.6. ([#1177](https://github.com/httpie/cli/issues/1177))
- Improved startup time by 40%. ([#1211](https://github.com/httpie/cli/pull/1211))
- Added support for nested JSON syntax. ([#1169](https://github.com/httpie/cli/issues/1169))
- Added `httpie plugins` interface for plugin management. ([#566](https://github.com/httpie/cli/issues/566))
- Added support for Bearer authentication via `--auth-type=bearer` ([#1215](https://github.com/httpie/cli/issues/1215)).
- Added support for quick conversions of pasted URLs into HTTPie calls by adding a space after the protocol name (`$ https ://pie.dev` → `https://pie.dev`). ([#1195](https://github.com/httpie/cli/issues/1195))
- Added support for _sending_ multiple HTTP header lines with the same name. ([#130](https://github.com/httpie/cli/issues/130))
- Added support for _receiving_ multiple HTTP headers lines with the same name. ([#1207](https://github.com/httpie/cli/issues/1207))
- Added support for basic JSON types on `--form`/`--multipart` when using JSON only operators (`:=`/`:=@`). ([#1212](https://github.com/httpie/cli/issues/1212))
- Added support for automatically enabling `--stream` when `Content-Type` is `text/event-stream`. ([#376](https://github.com/httpie/cli/issues/376))
- Added support for displaying the total elapsed time through `--meta`/`-vv` or `--print=m`. ([#243](https://github.com/httpie/cli/issues/243))
- Added new `pie-dark`/`pie-light` (and `pie`) styles that match with [HTTPie for Web and Desktop](https://httpie.io/product). ([#1237](https://github.com/httpie/cli/issues/1237))
- Added support for better error handling on DNS failures. ([#1248](https://github.com/httpie/cli/issues/1248))
- Added support for storing prompted passwords in the local sessions. ([#1098](https://github.com/httpie/cli/issues/1098))
- Added warnings about the `--ignore-stdin`, when there is no incoming data from stdin. ([#1255](https://github.com/httpie/cli/issues/1255))
- Fixed crashing due to broken plugins. ([#1204](https://github.com/httpie/cli/issues/1204))
- Fixed auto addition of XML declaration to every formatted XML response. ([#1156](https://github.com/httpie/cli/issues/1156))
- Fixed highlighting when `Content-Type` specifies `charset`. ([#1242](https://github.com/httpie/cli/issues/1242))
- Fixed an unexpected crash when `--raw` is used with `--chunked`. ([#1253](https://github.com/httpie/cli/issues/1253))
- Changed the default Windows theme from `fruity` to `auto`. ([#1266](https://github.com/httpie/cli/issues/1266))
## [2.6.0](https://github.com/httpie/cli/compare/2.5.0...2.6.0) (2021-10-14)
[Whats new in HTTPie for Terminal 2.6.0 →](https://httpie.io/blog/httpie-2.6.0)
- Added support for formatting & coloring of JSON bodies preceded by non-JSON data (e.g., an XXSI prefix). ([#1130](https://github.com/httpie/cli/issues/1130))
- Added charset auto-detection when `Content-Type` doesnt include it. ([#1110](https://github.com/httpie/cli/issues/1110), [#1168](https://github.com/httpie/cli/issues/1168))
- Added `--response-charset` to allow overriding the response encoding for terminal display purposes. ([#1168](https://github.com/httpie/cli/issues/1168))
- Added `--response-mime` to allow overriding the response mime type for coloring and formatting for the terminal. ([#1168](https://github.com/httpie/cli/issues/1168))
- Added the ability to silence warnings through using `-q` or `--quiet` twice (e.g. `-qq`) ([#1175](https://github.com/httpie/cli/issues/1175))
- Added installed plugin list to `--debug` output. ([#1165](https://github.com/httpie/cli/issues/1165))
- Fixed duplicate keys preservation in JSON data. ([#1163](https://github.com/httpie/cli/issues/1163))
## [2.5.0](https://github.com/httpie/cli/compare/2.4.0...2.5.0) (2021-09-06)
[Whats new in HTTPie for Terminal 2.5.0 →](https://httpie.io/blog/httpie-2.5.0)
- Added `--raw` to allow specifying the raw request body without extra processing as
an alternative to `stdin`. ([#534](https://github.com/httpie/httpie/issues/534))
- Added support for XML formatting. ([#1129](https://github.com/httpie/httpie/issues/1129))
- Added internal support for file-like object responses to improve adapter plugin support. ([#1094](https://github.com/httpie/httpie/issues/1094))
- Fixed `--continue --download` with a single byte to be downloaded left. ([#1032](https://github.com/httpie/httpie/issues/1032))
- Fixed `--verbose` HTTP 307 redirects with streamed request body. ([#1088](https://github.com/httpie/httpie/issues/1088))
- Fixed handling of session files with `Cookie:` followed by other headers. ([#1126](https://github.com/httpie/httpie/issues/1126))
an alternative to `stdin`. ([#534](https://github.com/httpie/cli/issues/534))
- Added support for XML formatting. ([#1129](https://github.com/httpie/cli/issues/1129))
- Added internal support for file-like object responses to improve adapter plugin support. ([#1094](https://github.com/httpie/cli/issues/1094))
- Fixed `--continue --download` with a single byte to be downloaded left. ([#1032](https://github.com/httpie/cli/issues/1032))
- Fixed `--verbose` HTTP 307 redirects with streamed request body. ([#1088](https://github.com/httpie/cli/issues/1088))
- Fixed handling of session files with `Cookie:` followed by other headers. ([#1126](https://github.com/httpie/cli/issues/1126))
## [2.4.0](https://github.com/httpie/httpie/compare/2.3.0...2.4.0) (2021-02-06)
## [2.4.0](https://github.com/httpie/cli/compare/2.3.0...2.4.0) (2021-02-06)
- Added support for `--session` cookie expiration based on `Set-Cookie: max-age=<n>`. ([#1029](https://github.com/httpie/httpie/issues/1029))
- Show a `--check-status` warning with `--quiet` as well, not only when the output is redirected. ([#1026](https://github.com/httpie/httpie/issues/1026))
- Fixed upload with `--session` ([#1020](https://github.com/httpie/httpie/issues/1020)).
- Fixed a missing blank line between request and response ([#1006](https://github.com/httpie/httpie/issues/1006)).
- Added support for `--session` cookie expiration based on `Set-Cookie: max-age=<n>`. ([#1029](https://github.com/httpie/cli/issues/1029))
- Show a `--check-status` warning with `--quiet` as well, not only when the output is redirected. ([#1026](https://github.com/httpie/cli/issues/1026))
- Fixed upload with `--session` ([#1020](https://github.com/httpie/cli/issues/1020)).
- Fixed a missing blank line between request and response ([#1006](https://github.com/httpie/cli/issues/1006)).
## [2.3.0](https://github.com/httpie/httpie/compare/2.2.0...2.3.0) (2020-10-25)
## [2.3.0](https://github.com/httpie/cli/compare/2.2.0...2.3.0) (2020-10-25)
- Added support for streamed uploads ([#201](https://github.com/httpie/httpie/issues/201)).
- Added support for multipart upload streaming ([#684](https://github.com/httpie/httpie/issues/684)).
- Added support for streamed uploads ([#201](https://github.com/httpie/cli/issues/201)).
- Added support for multipart upload streaming ([#684](https://github.com/httpie/cli/issues/684)).
- Added support for body-from-file upload streaming (`http pie.dev/post @file`).
- Added `--chunked` to enable chunked transfer encoding ([#753](https://github.com/httpie/httpie/issues/753)).
- Added `--chunked` to enable chunked transfer encoding ([#753](https://github.com/httpie/cli/issues/753)).
- Added `--multipart` to allow `multipart/form-data` encoding for non-file `--form` requests as well.
- Added support for preserving field order in multipart requests ([#903](https://github.com/httpie/httpie/issues/903)).
- Added support for preserving field order in multipart requests ([#903](https://github.com/httpie/cli/issues/903)).
- Added `--boundary` to allow a custom boundary string for `multipart/form-data` requests.
- Added support for combining cookies specified on the CLI and in a session file ([#932](https://github.com/httpie/httpie/issues/932)).
- Added out of the box SOCKS support with no extra installation ([#904](https://github.com/httpie/httpie/issues/904)).
- Added support for combining cookies specified on the CLI and in a session file ([#932](https://github.com/httpie/cli/issues/932)).
- Added out of the box SOCKS support with no extra installation ([#904](https://github.com/httpie/cli/issues/904)).
- Added `--quiet, -q` flag to enforce silent behaviour.
- Fixed the handling of invalid `expires` dates in `Set-Cookie` headers ([#963](https://github.com/httpie/httpie/issues/963)).
- Removed Tox testing entirely ([#943](https://github.com/httpie/httpie/issues/943)).
- Fixed the handling of invalid `expires` dates in `Set-Cookie` headers ([#963](https://github.com/httpie/cli/issues/963)).
- Removed Tox testing entirely ([#943](https://github.com/httpie/cli/issues/943)).
## [2.2.0](https://github.com/httpie/httpie/compare/2.1.0...2.2.0) (2020-06-18)
## [2.2.0](https://github.com/httpie/cli/compare/2.1.0...2.2.0) (2020-06-18)
- Added support for custom content types for uploaded files ([#668](https://github.com/httpie/httpie/issues/668)).
- Added support for `$XDG_CONFIG_HOME` ([#920](https://github.com/httpie/httpie/issues/920)).
- Added support for `Set-Cookie`-triggered cookie expiration ([#853](https://github.com/httpie/httpie/issues/853)).
- Added `--format-options` to allow disabling sorting, etc. ([#128](https://github.com/httpie/httpie/issues/128))
- Added `--sorted` and `--unsorted` shortcuts for (un)setting all sorting-related `--format-options`. ([#128](https://github.com/httpie/httpie/issues/128))
- Added `--ciphers` to allow configuring OpenSSL ciphers ([#870](https://github.com/httpie/httpie/issues/870)).
- Added support for custom content types for uploaded files ([#668](https://github.com/httpie/cli/issues/668)).
- Added support for `$XDG_CONFIG_HOME` ([#920](https://github.com/httpie/cli/issues/920)).
- Added support for `Set-Cookie`-triggered cookie expiration ([#853](https://github.com/httpie/cli/issues/853)).
- Added `--format-options` to allow disabling sorting, etc. ([#128](https://github.com/httpie/cli/issues/128))
- Added `--sorted` and `--unsorted` shortcuts for (un)setting all sorting-related `--format-options`. ([#128](https://github.com/httpie/cli/issues/128))
- Added `--ciphers` to allow configuring OpenSSL ciphers ([#870](https://github.com/httpie/cli/issues/870)).
- Added `netrc` support for auth plugins. Enabled for `--auth-type=basic`
and `digest`, 3rd parties may opt in ([#718](https://github.com/httpie/httpie/issues/718), [#719](https://github.com/httpie/httpie/issues/719), [#852](https://github.com/httpie/httpie/issues/852), [#934](https://github.com/httpie/httpie/issues/934)).
- Fixed built-in plugins-related circular imports ([#925](https://github.com/httpie/httpie/issues/925)).
and `digest`, 3rd parties may opt in ([#718](https://github.com/httpie/cli/issues/718), [#719](https://github.com/httpie/cli/issues/719), [#852](https://github.com/httpie/cli/issues/852), [#934](https://github.com/httpie/cli/issues/934)).
- Fixed built-in plugins-related circular imports ([#925](https://github.com/httpie/cli/issues/925)).
## [2.1.0](https://github.com/httpie/httpie/compare/2.0.0...2.1.0) (2020-04-18)
## [2.1.0](https://github.com/httpie/cli/compare/2.0.0...2.1.0) (2020-04-18)
- Added `--path-as-is` to bypass dot segment (`/../` or `/./`)
URL squashing ([#895](https://github.com/httpie/httpie/issues/895)).
URL squashing ([#895](https://github.com/httpie/cli/issues/895)).
- Changed the default `Accept` header value for JSON requests from
`application/json, */*` to `application/json, */*;q=0.5`
to clearly indicate preference ([#488](https://github.com/httpie/httpie/issues/488)).
to clearly indicate preference ([#488](https://github.com/httpie/cli/issues/488)).
- Fixed `--form` file upload mixed with redirected `stdin` error handling
([#840](https://github.com/httpie/httpie/issues/840)).
([#840](https://github.com/httpie/cli/issues/840)).
## [2.0.0](https://github.com/httpie/httpie/compare/1.0.3...2.0.0) (2020-01-12)
## [2.0.0](https://github.com/httpie/cli/compare/1.0.3...2.0.0) (2020-01-12)
- Removed Python 2.7 support ([EOL Jan 2020](https://www.python.org/doc/sunset-python-2/).
- Added `--offline` to allow building an HTTP request and printing it but not
@ -91,7 +170,7 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
- Fixed an error when `stdin` was a closed fd.
- Improved `--debug` output formatting.
## [1.0.3](https://github.com/httpie/httpie/compare/1.0.2...1.0.3) (2019-08-26)
## [1.0.3](https://github.com/httpie/cli/compare/1.0.2...1.0.3) (2019-08-26)
- Fixed CVE-2019-10751 — the way the output filename is generated for
`--download` requests without `--output` resulting in a redirect has
@ -117,15 +196,15 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
Reported by Raul Onitza and Giulio Comi.
## [1.0.2](https://github.com/httpie/httpie/compare/1.0.1...1.0.2) (2018-11-14)
## [1.0.2](https://github.com/httpie/cli/compare/1.0.1...1.0.2) (2018-11-14)
- Fixed tests for installation with pyOpenSSL.
## [1.0.1](https://github.com/httpie/httpie/compare/1.0.0...1.0.1) (2018-11-14)
## [1.0.1](https://github.com/httpie/cli/compare/1.0.0...1.0.1) (2018-11-14)
- Removed external URL calls from tests.
## [1.0.0](https://github.com/httpie/httpie/compare/0.9.9...1.0.0) (2018-11-02)
## [1.0.0](https://github.com/httpie/cli/compare/0.9.9...1.0.0) (2018-11-02)
- Added `--style=auto` which follows the terminal ANSI color styles.
- Added support for selecting TLS 1.3 via `--ssl=tls1.3`
@ -136,11 +215,11 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
- Fixed default headers being incorrectly case-sensitive.
- Removed Python 2.6 support.
## [0.9.9](https://github.com/httpie/httpie/compare/0.9.8...0.9.9) (2016-12-08)
## [0.9.9](https://github.com/httpie/cli/compare/0.9.8...0.9.9) (2016-12-08)
- Fixed README.
## [0.9.8](https://github.com/httpie/httpie/compare/0.9.6...0.9.8) (2016-12-08)
## [0.9.8](https://github.com/httpie/cli/compare/0.9.6...0.9.8) (2016-12-08)
- Extended auth plugin API.
- Added exit status code `7` for plugin errors.
@ -149,7 +228,7 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
- Improved `CTRL-C` interrupt handling.
- Added the standard exit status code `130` for keyboard interrupts.
## [0.9.6](https://github.com/httpie/httpie/compare/0.9.4...0.9.6) (2016-08-13)
## [0.9.6](https://github.com/httpie/cli/compare/0.9.4...0.9.6) (2016-08-13)
- Added Python 3 as a dependency for Homebrew installations
to ensure some of the newer HTTP features work out of the box
@ -168,7 +247,7 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
- Changed the pre-processing of request HTTP headers so that any leading
and trailing whitespace is removed.
## [0.9.4](https://github.com/httpie/httpie/compare/0.9.3...0.9.4) (2016-07-01)
## [0.9.4](https://github.com/httpie/cli/compare/0.9.3...0.9.4) (2016-07-01)
- Added `Content-Type` of files uploaded in `multipart/form-data` requests
- Added `--ssl=<PROTOCOL>` to specify the desired SSL/TLS protocol version
@ -192,7 +271,7 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
- Fixed the handling of `Content-Type` with multiple `+subtype` parts
- Removed the XML formatter as the implementation suffered from multiple issues
## [0.9.3](https://github.com/httpie/httpie/compare/0.9.2...0.9.3) (2016-01-01)
## [0.9.3](https://github.com/httpie/cli/compare/0.9.2...0.9.3) (2016-01-01)
- Changed the default color `--style` from `solarized` to `monokai`
- Added basic Bash autocomplete support (need to be installed manually)
@ -202,19 +281,19 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
- Fixed colors and formatting on Windows
- Fixed `--auth` prompt on Windows
## [0.9.2](https://github.com/httpie/httpie/compare/0.9.1...0.9.2) (2015-02-24)
## [0.9.2](https://github.com/httpie/cli/compare/0.9.1...0.9.2) (2015-02-24)
- Fixed compatibility with Requests 2.5.1
- Changed the default JSON `Content-Type` to `application/json` as UTF-8
is the default JSON encoding
## [0.9.1](https://github.com/httpie/httpie/compare/0.9.0...0.9.1) (2015-02-07)
## [0.9.1](https://github.com/httpie/cli/compare/0.9.0...0.9.1) (2015-02-07)
- Added support for Requests transport adapter plugins
(see [httpie-unixsocket](https://github.com/httpie/httpie-unixsocket)
and [httpie-http2](https://github.com/httpie/httpie-http2))
## [0.9.0](https://github.com/httpie/httpie/compare/0.8.0...0.9.0) (2015-01-31)
## [0.9.0](https://github.com/httpie/cli/compare/0.8.0...0.9.0) (2015-01-31)
- Added `--cert` and `--cert-key` parameters to specify a client side
certificate and private key for SSL
@ -233,7 +312,7 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
- Fixed `--output=/dev/null` on Linux
- Miscellaneous bugfixes
## [0.8.0](https://github.com/httpie/httpie/compare/0.7.1...0.8.0) (2014-01-25)
## [0.8.0](https://github.com/httpie/cli/compare/0.7.1...0.8.0) (2014-01-25)
- Added `field=@file.txt` and `field:=@file.json` for embedding
the contents of text and JSON files into request data
@ -241,7 +320,7 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
- Fixed request `Host` header value output so that it doesn't contain
credentials, if included in the URL
## [0.7.1](https://github.com/httpie/httpie/compare/0.6.0...0.7.1) (2013-09-24)
## [0.7.1](https://github.com/httpie/cli/compare/0.6.0...0.7.1) (2013-09-24)
- Added `--ignore-stdin`
- Added support for auth plugins
@ -249,27 +328,27 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
- Improved `Content-Disposition` parsing for `--download` mode
- Update to Requests 2.0.0
## [0.6.0](https://github.com/httpie/httpie/compare/0.5.1...0.6.0) (2013-06-03)
## [0.6.0](https://github.com/httpie/cli/compare/0.5.1...0.6.0) (2013-06-03)
- XML data is now formatted
- `--session` and `--session-read-only` now also accept paths to
session files (eg. `http --session=/tmp/session.json example.org`)
## [0.5.1](https://github.com/httpie/httpie/compare/0.5.0...0.5.1) (2013-05-13)
## [0.5.1](https://github.com/httpie/cli/compare/0.5.0...0.5.1) (2013-05-13)
- `Content-*` and `If-*` request headers are not stored in sessions
anymore as they are request-specific
## [0.5.0](https://github.com/httpie/httpie/compare/0.4.1...0.5.0) (2013-04-27)
## [0.5.0](https://github.com/httpie/cli/compare/0.4.1...0.5.0) (2013-04-27)
- Added a download mode via `--download`
- Fixes miscellaneous bugs
## [0.4.1](https://github.com/httpie/httpie/compare/0.4.0...0.4.1) (2013-02-26)
## [0.4.1](https://github.com/httpie/cli/compare/0.4.0...0.4.1) (2013-02-26)
- Fixed `setup.py`
## [0.4.0](https://github.com/httpie/httpie/compare/0.3.0...0.4.0) (2013-02-22)
## [0.4.0](https://github.com/httpie/cli/compare/0.3.0...0.4.0) (2013-02-22)
- Added Python 3.3 compatibility
- Added Requests >= v1.0.4 compatibility
@ -278,7 +357,7 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
- Mutually exclusive arguments can be specified multiple times. The
last value is used
## [0.3.0](https://github.com/httpie/httpie/compare/0.2.7...0.3.0) (2012-09-21)
## [0.3.0](https://github.com/httpie/cli/compare/0.2.7...0.3.0) (2012-09-21)
- Allow output redirection on Windows
- Added configuration file
@ -293,7 +372,7 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
(`--pretty=all`, `--pretty=colors` and `--pretty=format`)
`--ugly` has bee removed in favor of `--pretty=none`
## [0.2.7](https://github.com/httpie/httpie/compare/0.2.5...0.2.7) (2012-08-07)
## [0.2.7](https://github.com/httpie/cli/compare/0.2.5...0.2.7) (2012-08-07)
- Added compatibility with Requests 0.13.6
- Added streamed terminal output. `--stream, -S` can be used to enable
@ -310,7 +389,7 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
- Fixed printing of `multipart/form-data` requests
- Renamed `--traceback` to `--debug`
## [0.2.6](https://github.com/httpie/httpie/compare/0.2.5...0.2.6) (2012-07-26)
## [0.2.6](https://github.com/httpie/cli/compare/0.2.5...0.2.6) (2012-07-26)
- The short option for `--headers` is now `-h` (`-t` has been
removed, for usage use `--help`)
@ -325,7 +404,7 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
- Added query string parameters (`param==value`)
- Added support for terminal colors under Windows
## [0.2.5](https://github.com/httpie/httpie/compare/0.2.2...0.2.5) (2012-07-17)
## [0.2.5](https://github.com/httpie/cli/compare/0.2.2...0.2.5) (2012-07-17)
- Unicode characters in prettified JSON now don't get escaped for
improved readability
@ -336,20 +415,20 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
`--verbose`
- Fixed Content-Type for requests with no data
## [0.2.2](https://github.com/httpie/httpie/compare/0.2.1...0.2.2) (2012-06-24)
## [0.2.2](https://github.com/httpie/cli/compare/0.2.1...0.2.2) (2012-06-24)
- The `METHOD` positional argument can now be omitted (defaults to
`GET`, or to `POST` with data)
- Fixed --verbose --form
- Added support for Tox
## [0.2.1](https://github.com/httpie/httpie/compare/0.2.0...0.2.1) (2012-06-13)
## [0.2.1](https://github.com/httpie/cli/compare/0.2.0...0.2.1) (2012-06-13)
- Added compatibility with `requests-0.12.1`
- Dropped custom JSON and HTTP lexers in favor of the ones newly included
in `pygments-1.5`
## [0.2.0](https://github.com/httpie/httpie/compare/0.1.6...0.2.0) (2012-04-25)
## [0.2.0](https://github.com/httpie/cli/compare/0.1.6...0.2.0) (2012-04-25)
- Added Python 3 support
- Added the ability to print the HTTP request as well as the response
@ -361,18 +440,18 @@ Blog post: [Whats new in HTTPie 2.5.0](https://httpie.io/blog/httpie-2.5.0)
- Added support for field name escaping
- Many bug fixes
## [0.1.6](https://github.com/httpie/httpie/compare/0.1.5...0.1.6) (2012-03-04)
## [0.1.6](https://github.com/httpie/cli/compare/0.1.5...0.1.6) (2012-03-04)
- Fixed `setup.py`
## [0.1.5](https://github.com/httpie/httpie/compare/0.1.4...0.1.5) (2012-03-04)
## [0.1.5](https://github.com/httpie/cli/compare/0.1.4...0.1.5) (2012-03-04)
- Many improvements and bug fixes
## [0.1.4](https://github.com/httpie/httpie/compare/b966efa...0.1.4) (2012-02-28)
## [0.1.4](https://github.com/httpie/cli/compare/b966efa...0.1.4) (2012-02-28)
- Many improvements and bug fixes
## [0.1.0](https://github.com/httpie/httpie/commit/b966efa) (2012-02-25)
## [0.1.0](https://github.com/httpie/cli/commit/b966efa) (2012-02-25)
- Initial public release

View File

@ -19,7 +19,7 @@ $ http --debug <COMPLETE ARGUMENT LIST THAT TRIGGERS THE ERROR>
## 2. Contributing Code and Docs
Before working on a new feature or a bug, please browse [existing issues](https://github.com/httpie/httpie/issues)
Before working on a new feature or a bug, please browse [existing issues](https://github.com/httpie/cli/issues)
to see whether it has previously been discussed.
If your change alters HTTPies behaviour or interface, it's a good idea to
@ -38,13 +38,13 @@ for existing-yet-previously-untested behavior will very likely be merged.
Therefore, docs and tests improvements are a great candidate for your first
contribution.
Consider also adding a [CHANGELOG](https://github.com/httpie/httpie/blob/master/CHANGELOG.md) entry for your changes.
Consider also adding a [CHANGELOG](https://github.com/httpie/cli/blob/master/CHANGELOG.md) entry for your changes.
### Development Environment
#### Getting the code
Go to <https://github.com/httpie/httpie> and fork the project repository.
Go to <https://github.com/httpie/cli> and fork the project repository.
```bash
# Clone your fork
@ -59,8 +59,10 @@ $ git checkout -b my_topical_branch
#### Setup
The [Makefile](https://github.com/httpie/httpie/blob/master/Makefile) contains a bunch of tasks to get you started. Just run
the following command, which:
The [Makefile](https://github.com/httpie/cli/blob/master/Makefile) contains a bunch of tasks to get you started.
You can run `$ make` to see all the available tasks.
To get started, run the command below, which:
- Creates an isolated Python virtual environment inside `./venv`
(via the standard library [venv](https://docs.python.org/3/library/venv.html) tool);
@ -70,7 +72,7 @@ the following command, which:
- and runs tests (It is the same as running `make install test`).
```bash
$ make
$ make all
```
#### Python virtual environment
@ -110,7 +112,7 @@ and that `make pycodestyle` passes.
Please add tests for any new features and bug fixes.
When you open a Pull Request, [GitHub Actions](https://github.com/httpie/httpie/actions) will automatically run HTTPies [test suite](https://github.com/httpie/httpie/tree/master/tests) against your code, so please make sure all checks pass.
When you open a Pull Request, [GitHub Actions](https://github.com/httpie/cli/actions) will automatically run HTTPies [test suite](https://github.com/httpie/cli/tree/master/tests) against your code, so please make sure all checks pass.
#### Running tests locally
@ -142,13 +144,27 @@ $ python -m pytest tests/test_uploads.py::TestMultipartFormDataFileUpload
$ python -m pytest tests/test_uploads.py::TestMultipartFormDataFileUpload::test_upload_ok
```
See [Makefile](https://github.com/httpie/httpie/blob/master/Makefile) for additional development utilities.
See [Makefile](https://github.com/httpie/cli/blob/master/Makefile) for additional development utilities.
#### Running benchmarks
If you are trying to work on speeding up HTTPie and want to verify your results, you
can run the benchmark suite. The suite will compare the last commit of your branch
with the master branch of your repository (or a fresh checkout of HTTPie master, through
`--fresh`) and report the results back.
```bash
$ python extras/profiling/run.py
```
The benchmarks can also be run on the CI. Since it is a long process, it requires manual
oversight. Ping one of the maintainers to get a `benchmark` label on your branch.
#### Windows
If you are on a Windows machine and not able to run `make`,
follow the next steps for a basic setup. As a prerequisite, you need to have
Python 3.6+ installed.
Python 3.7+ installed.
Create a virtual environment and activate it:
@ -160,7 +176,7 @@ C:\> venv\Scripts\activate
Install HTTPie in editable mode with all the dependencies:
```powershell
C:\> python -m pip install --upgrade -e . -r requirements-dev.txt
C:\> python -m pip install --upgrade -e .[dev]
```
You should now see `(httpie)` next to your shell prompt, and
@ -168,19 +184,19 @@ the `http` command should point to your development copy:
```powershell
# In PowerShell:
(httpie) PS C:\Users\ovezovs\httpie> Get-Command http
(httpie) PS C:\Users\<user>\httpie> Get-Command http
CommandType Name Version Source
----------- ---- ------- ------
Application http.exe 0.0.0.0 C:\Users\ovezovs\httpie\venv\Scripts\http.exe
Application http.exe 0.0.0.0 C:\Users\<user>\httpie\venv\Scripts\http.exe
```
```bash
# In CMD:
(httpie) C:\Users\ovezovs\httpie> where http
C:\Users\ovezovs\httpie\venv\Scripts\http.exe
C:\Users\ovezovs\AppData\Local\Programs\Python\Python38-32\Scripts\http.exe
(httpie) C:\Users\<user>\httpie> where http
C:\Users\<user>\httpie\venv\Scripts\http.exe
C:\Users\<user>\AppData\Local\Programs\Python\Python38-32\Scripts\http.exe
(httpie) C:\Users\ovezovs\httpie> http --version
(httpie) C:\Users\<user>\httpie> http --version
2.3.0-dev
```
@ -193,4 +209,4 @@ $ python -m pytest
______________________________________________________________________
Finally, feel free to add yourself to [AUTHORS](https://github.com/httpie/httpie/blob/master/AUTHORS.md)!
Finally, feel free to add yourself to [AUTHORS](https://github.com/httpie/cli/blob/master/AUTHORS.md)!

View File

@ -1,4 +1,4 @@
Copyright © 2012-2021 Jakub Roztocil <jakub@roztocil.co>
Copyright © 2012-2022 Jakub Roztocil <jakub@roztocil.co>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

View File

@ -4,5 +4,5 @@ include CHANGELOG.md
include AUTHORS.md
include docs/README.md
# <https://github.com/httpie/httpie/issues/182>
# <https://github.com/httpie/cli/issues/182>
recursive-include tests/ *

View File

@ -22,6 +22,26 @@ VENV_PYTHON=$(VENV_BIN)/python
export PATH := $(VENV_BIN):$(PATH)
default: list-tasks
###############################################################################
# Default task to get a list of tasks when `make' is run without args.
# <https://stackoverflow.com/questions/4219255>
###############################################################################
list-tasks:
@echo Available tasks:
@echo ----------------
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | grep -E -v -e '^[^[:alnum:]]' -e '^$@$$'
@echo
###############################################################################
# Installation
###############################################################################
all: uninstall-httpie install test
@ -30,10 +50,10 @@ install: venv install-reqs
install-reqs:
@echo $(H1)Updating package tools$(H1END)
$(VENV_PIP) install --upgrade pip wheel
$(VENV_PIP) install --upgrade pip wheel build
@echo $(H1)Installing dev requirements$(H1END)
$(VENV_PIP) install --upgrade --editable '.[dev]'
$(VENV_PIP) install --upgrade '.[dev]' '.[test]'
@echo $(H1)Installing HTTPie$(H1END)
$(VENV_PIP) install --upgrade --editable .
@ -130,7 +150,7 @@ pycodestyle: codestyle
codestyle:
@echo $(H1)Running flake8$(H1END)
@[ -f $(VENV_BIN)/flake8 ] || $(VENV_PIP) install --upgrade --editable '.[dev]'
$(VENV_BIN)/flake8 httpie/ tests/ docs/packaging/brew/ *.py
$(VENV_BIN)/flake8 httpie/ tests/ extras/profiling/ docs/packaging/brew/ *.py
@echo
@ -147,19 +167,17 @@ doc-check:
mdl --git-recurse --style docs/markdownlint.rb .
doc-update-install:
@echo $(H1)Updating installation instructions in the docs$(H1END)
$(VENV_PYTHON) docs/installation/generate.py
###############################################################################
# Publishing to PyPi
###############################################################################
build:
rm -rf build/
$(VENV_PYTHON) setup.py sdist bdist_wheel
rm -rf build/ dist/
mv httpie/internal/__build_channel__.py httpie/internal/__build_channel__.py.original
echo 'BUILD_CHANNEL = "pip"' > httpie/internal/__build_channel__.py
$(VENV_PYTHON) -m build --sdist --wheel --outdir dist/
mv httpie/internal/__build_channel__.py.original httpie/internal/__build_channel__.py
publish: test-all publish-no-test
@ -203,10 +221,25 @@ brew-test:
- brew uninstall httpie
@echo $(H1)Building from source…$(H1END)
- brew install --build-from-source ./docs/packaging/brew/httpie.rb
- brew install --HEAD --build-from-source ./docs/packaging/brew/httpie.rb
@echo $(H1)Verifying…$(H1END)
brew test httpie
http --version
https --version
@echo $(H1)Auditing…$(H1END)
brew audit --strict httpie
###############################################################################
# Generated content
###############################################################################
content: man installation-docs
man: install
@echo $(H1)Regenerate man pages$(H1END)
$(VENV_PYTHON) extras/scripts/generate_man_pages.py
installation-docs:
@echo $(H1)Updating installation instructions in the docs$(H1END)
$(VENV_PYTHON) docs/installation/generate.py

View File

@ -1,10 +1,31 @@
<br/>
<a href="https://httpie.io" target="blank_">
<img height="100" alt="HTTPie" src="https://raw.githubusercontent.com/httpie/httpie/master/docs/httpie-logo.svg" />
</a>
<br/>
<h2 align="center">
<a href="https://httpie.io" target="blank_">
<img height="100" alt="HTTPie" src="https://raw.githubusercontent.com/httpie/cli/master/docs/httpie-logo.svg" />
</a>
<br>
HTTPie CLI: human-friendly HTTP client for the API era
</h2>
# HTTPie: human-friendly CLI HTTP client for the API era
<div align="center">
[![HTTPie for Desktop](https://img.shields.io/static/v1?label=HTTPie&message=Desktop&color=4B78E6)](https://httpie.io/product)
[![](https://img.shields.io/static/v1?label=HTTPie&message=Web%20%26%20Mobile&color=73DC8C)](https://httpie.io/app)
[![](https://img.shields.io/static/v1?label=HTTPie&message=CLI&color=FA9BFA)](https://httpie.io/cli)
[![Twitter](https://img.shields.io/twitter/follow/httpie?style=flat&color=%234B78E6&logoColor=%234B78E6)](https://twitter.com/httpie)
[![Chat](https://img.shields.io/discord/725351238698270761?style=flat&label=Chat%20on%20Discord&color=%23FA9BFA)](https://httpie.io/discord)
</div>
<div align="center">
[![Docs](https://img.shields.io/badge/stable%20docs-httpie.io%2Fdocs%2Fcli-brightgreen?style=flat&color=%2373DC8C&label=Docs)](https://httpie.org/docs/cli)
[![Latest version](https://img.shields.io/pypi/v/httpie.svg?style=flat&label=Latest&color=%234B78E6&logo=&logoColor=white)](https://pypi.python.org/pypi/httpie)
[![Build](https://img.shields.io/github/actions/workflow/status/httpie/cli/tests.yml?branch=master&color=%23FA9BFA&label=Build)](https://github.com/httpie/cli/actions)
[![Coverage](https://img.shields.io/codecov/c/github/httpie/cli?style=flat&label=Coverage&color=%2373DC8C)](https://codecov.io/gh/httpie/cli)
[![PyPi downloads](https://img.shields.io/pepy/dt/httpie?style=flat&label=Downloads%20from%20PyPi%20only&color=4B78E6)](https://www.pepy.tech/projects/httpie)
</div>
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.
@ -12,14 +33,22 @@ HTTPie is designed for testing, debugging, and generally interacting with APIs &
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](https://img.shields.io/badge/stable%20docs-httpie.io%2Fdocs-brightgreen?style=flat&color=%2373DC8C&label=Docs)](https://httpie.org/docs)
[![Latest version](https://img.shields.io/pypi/v/httpie.svg?style=flat&label=Latest&color=%234B78E6&logo=&logoColor=white)](https://pypi.python.org/pypi/httpie)
[![Build](https://img.shields.io/github/workflow/status/httpie/httpie/Build?color=%23FA9BFA&label=Build)](https://github.com/httpie/httpie/actions)
[![Coverage](https://img.shields.io/codecov/c/github/httpie/httpie?style=flat&label=Coverage&color=%2373DC8C)](https://codecov.io/gh/httpie/httpie)
[![Twitter](https://img.shields.io/twitter/follow/httpie?style=flat&color=%234B78E6&logoColor=%234B78E6)](https://twitter.com/httpie)
[![Chat](https://img.shields.io/badge/chat-Discord-brightgreen?style=flat&label=Chat%20on&color=%23FA9BFA)](https://httpie.io/discord)
<div align="center">
<img src="https://raw.githubusercontent.com/httpie/cli/master/docs/httpie-animation.gif" alt="HTTPie in action" width="100%"/>
</div>
## We lost 54k GitHub stars
Please note we recently accidentally made this repo private for a moment, and GitHub deleted our community that took a decade to build. Read the full story here: https://httpie.io/blog/stardust
![](docs/stardust.png)
<img src="https://raw.githubusercontent.com/httpie/httpie/master/docs/httpie-animation.gif" alt="HTTPie in action" width="100%"/>
## Getting started
@ -45,25 +74,25 @@ They use simple and natural syntax and provide formatted and colorized output.
Hello World:
```bash
$ https httpie.io/hello
https httpie.io/hello
```
Custom [HTTP method](https://httpie.io/docs#http-method), [HTTP headers](https://httpie.io/docs#http-headers) and [JSON](https://httpie.io/docs#json) data:
```bash
$ http PUT pie.dev/put X-API-Token:123 name=John
http PUT pie.dev/put X-API-Token:123 name=John
```
Build and print a request without sending it using [offline mode](https://httpie.io/docs#offline-mode):
```bash
$ http --offline pie.dev/post hello=offline
http --offline pie.dev/post hello=offline
```
Use [GitHub API](https://developer.github.com/v3/issues/comments/#create-a-comment) to post a comment on an [Issue](https://github.com/httpie/httpie/issues/83) with [authentication](https://httpie.io/docs#authentication):
Use [GitHub API](https://developer.github.com/v3/issues/comments/#create-a-comment) to post a comment on an [Issue](https://github.com/httpie/cli/issues/83) with [authentication](https://httpie.io/docs#authentication):
```bash
$ http -a USERNAME POST https://api.github.com/repos/httpie/httpie/issues/83/comments body='HTTPie is awesome! :heart:'
http -a USERNAME POST https://api.github.com/repos/httpie/cli/issues/83/comments body='HTTPie is awesome! :heart:'
```
[See more examples →](https://httpie.io/docs#examples)
@ -74,11 +103,11 @@ $ http -a USERNAME POST https://api.github.com/repos/httpie/httpie/issues/83/com
- Join our [Discord server](https://httpie.io/discord) is to ask questions, discuss features, and for general API chat.
- Tweet at [@httpie](https://twitter.com/httpie) on Twitter.
- Use [StackOverflow](https://stackoverflow.com/questions/tagged/httpie) to ask questions and include a `httpie` tag.
- Create [GitHub Issues](https://github.com/httpie/httpie/issues) for bug reports and feature requests.
- Create [GitHub Issues](https://github.com/httpie/cli/issues) for bug reports and feature requests.
- Subscribe to the [HTTPie newsletter](https://httpie.io) for occasional updates.
## Contributing
Have a look through existing [Issues](https://github.com/httpie/httpie/issues) and [Pull Requests](https://github.com/httpie/httpie/pulls) that you could help with. If you'd like to request a feature or report a bug, please [create a GitHub Issue](https://github.com/httpie/httpie/issues) using one of the templates provided.
Have a look through existing [Issues](https://github.com/httpie/cli/issues) and [Pull Requests](https://github.com/httpie/cli/pulls) that you could help with. If you'd like to request a feature or report a bug, please [create a GitHub Issue](https://github.com/httpie/cli/issues) using one of the templates provided.
[See contribution guide →](https://github.com/httpie/httpie/blob/master/CONTRIBUTING.md)
[See contribution guide →](https://github.com/httpie/cli/blob/master/CONTRIBUTING.md)

14
SECURITY.md Normal file
View File

@ -0,0 +1,14 @@
# Security policy
## Reporting a vulnerability
When you identify a vulnerability in HTTPie, please report it privately using one of the following channels:
- Email to [`security@httpie.io`](mailto:security@httpie.io)
- Report on [huntr.dev](https://huntr.dev/)
In addition to the description of the vulnerability, include the following information:
- A short reproducer to verify it (it can be a small HTTP server, shell script, docker image, etc.)
- Your deemed severity level of the vulnerability (`LOW`/`MEDIUM`/`HIGH`/`CRITICAL`)
- [CWE](https://cwe.mitre.org/) ID, if available.

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
{
"website": {
"master_and_released_docs_differ_after": "8f8851f1dbd511d3bc0ea0f6da7459045610afce"
"master_and_released_docs_differ_after": null
}
}

View File

@ -0,0 +1,3 @@
Here we maintain a database of contributors, from which we generate credits on release blog posts and social media.
For the HTTPie blog see: <https://httpie.io/blog>.

281
docs/contributors/fetch.py Normal file
View File

@ -0,0 +1,281 @@
"""
Generate the contributors database.
FIXME: replace `requests` calls with the HTTPie API, when available.
"""
import json
import os
import re
import sys
from copy import deepcopy
from datetime import datetime
from pathlib import Path
from subprocess import check_output
from time import sleep
from typing import Any, Dict, Optional, Set
import requests
FullNames = Set[str]
GitHubLogins = Set[str]
Person = Dict[str, str]
People = Dict[str, Person]
UserInfo = Dict[str, Any]
CO_AUTHORS = re.compile(r'Co-authored-by: ([^<]+) <').finditer
API_URL = 'https://api.github.com'
REPO = OWNER = 'httpie'
REPO_URL = f'{API_URL}/repos/{REPO}/{OWNER}'
HERE = Path(__file__).parent
DB_FILE = HERE / 'people.json'
DEFAULT_PERSON: Person = {'committed': [], 'reported': [], 'github': '', 'twitter': ''}
SKIPPED_LABELS = {'invalid'}
GITHUB_TOKEN = os.getenv('GITHUB_TOKEN')
assert GITHUB_TOKEN, 'GITHUB_TOKEN envar is missing'
class FinishedForNow(Exception):
"""Raised when remaining GitHub rate limit is zero."""
def main(previous_release: str, current_release: str) -> int:
since = release_date(previous_release)
until = release_date(current_release)
contributors = load_awesome_people()
try:
committers = find_committers(since, until)
reporters = find_reporters(since, until)
except Exception as exc:
# We want to save what we fetched so far. So pass.
print(' !! ', exc)
try:
merge_all_the_people(current_release, contributors, committers, reporters)
fetch_missing_users_details(contributors)
except FinishedForNow:
# We want to save what we fetched so far. So pass.
print(' !! Committers:', committers)
print(' !! Reporters:', reporters)
exit_status = 1
else:
exit_status = 0
save_awesome_people(contributors)
return exit_status
def find_committers(since: str, until: str) -> FullNames:
url = f'{REPO_URL}/commits'
page = 1
per_page = 100
params = {
'since': since,
'until': until,
'per_page': per_page,
}
committers: FullNames = set()
while 'there are commits':
params['page'] = page
data = fetch(url, params=params)
for item in data:
commit = item['commit']
committers.add(commit['author']['name'])
debug(' >>> Commit', item['html_url'])
for co_author in CO_AUTHORS(commit['message']):
name = co_author.group(1)
committers.add(name)
if len(data) < per_page:
break
page += 1
return committers
def find_reporters(since: str, until: str) -> GitHubLogins:
url = f'{API_URL}/search/issues'
page = 1
per_page = 100
params = {
'q': f'repo:{REPO}/{OWNER} is:issue closed:{since}..{until}',
'per_page': per_page,
}
reporters: GitHubLogins = set()
while 'there are issues':
params['page'] = page
data = fetch(url, params=params)
for item in data['items']:
# Filter out unwanted labels.
if any(label['name'] in SKIPPED_LABELS for label in item['labels']):
continue
debug(' >>> Issue', item['html_url'])
reporters.add(item['user']['login'])
if len(data['items']) < per_page:
break
page += 1
return reporters
def merge_all_the_people(release: str, contributors: People, committers: FullNames, reporters: GitHubLogins) -> None:
"""
>>> contributors = {'Alice': new_person(github='alice', twitter='alice')}
>>> merge_all_the_people('2.6.0', contributors, {}, {})
>>> contributors
{'Alice': {'committed': [], 'reported': [], 'github': 'alice', 'twitter': 'alice'}}
>>> contributors = {'Bob': new_person(github='bob', twitter='bob')}
>>> merge_all_the_people('2.6.0', contributors, {'Bob'}, {'bob'})
>>> contributors
{'Bob': {'committed': ['2.6.0'], 'reported': ['2.6.0'], 'github': 'bob', 'twitter': 'bob'}}
>>> contributors = {'Charlotte': new_person(github='charlotte', twitter='charlotte', committed=['2.5.0'], reported=['2.5.0'])}
>>> merge_all_the_people('2.6.0', contributors, {'Charlotte'}, {'charlotte'})
>>> contributors
{'Charlotte': {'committed': ['2.5.0', '2.6.0'], 'reported': ['2.5.0', '2.6.0'], 'github': 'charlotte', 'twitter': 'charlotte'}}
"""
# Update known contributors.
for name, details in contributors.items():
if name in committers:
if release not in details['committed']:
details['committed'].append(release)
committers.remove(name)
if details['github'] in reporters:
if release not in details['reported']:
details['reported'].append(release)
reporters.remove(details['github'])
# Add new committers.
for name in committers:
user_info = user(fullname=name)
contributors[name] = new_person(
github=user_info['login'],
twitter=user_info['twitter_username'],
committed=[release],
)
if user_info['login'] in reporters:
contributors[name]['reported'].append(release)
reporters.remove(user_info['login'])
# Add new reporters.
for github_username in reporters:
user_info = user(github_username=github_username)
contributors[user_info['name'] or user_info['login']] = new_person(
github=github_username,
twitter=user_info['twitter_username'],
reported=[release],
)
def release_date(release: str) -> str:
date = check_output(['git', 'log', '-1', '--format=%ai', release], text=True).strip()
return datetime.strptime(date, '%Y-%m-%d %H:%M:%S %z').isoformat()
def load_awesome_people() -> People:
try:
with DB_FILE.open(encoding='utf-8') as fh:
return json.load(fh)
except (FileNotFoundError, ValueError):
return {}
def fetch(url: str, params: Optional[Dict[str, str]] = None) -> UserInfo:
headers = {
'Accept': 'application/vnd.github.v3+json',
'Authentication': f'token {GITHUB_TOKEN}'
}
for retry in range(1, 6):
debug(f'[{retry}/5]', f'{url = }', f'{params = }')
with requests.get(url, params=params, headers=headers) as req:
try:
req.raise_for_status()
except requests.exceptions.HTTPError as exc:
if exc.response.status_code == 403:
# 403 Client Error: rate limit exceeded for url: ...
now = int(datetime.utcnow().timestamp())
xrate_limit_reset = int(exc.response.headers['X-RateLimit-Reset'])
wait = xrate_limit_reset - now
if wait > 20:
raise FinishedForNow()
debug(' !', 'Waiting', wait, 'seconds before another try ...')
sleep(wait)
continue
return req.json()
assert ValueError('Rate limit exceeded')
def new_person(**kwargs: str) -> Person:
data = deepcopy(DEFAULT_PERSON)
data.update(**kwargs)
return data
def user(fullname: Optional[str] = '', github_username: Optional[str] = '') -> UserInfo:
if github_username:
url = f'{API_URL}/users/{github_username}'
return fetch(url)
url = f'{API_URL}/search/users'
for query in (f'fullname:{fullname}', f'user:{fullname}'):
params = {
'q': f'repo:{REPO}/{OWNER} {query}',
'per_page': 1,
}
user_info = fetch(url, params=params)
if user_info['items']:
user_url = user_info['items'][0]['url']
return fetch(user_url)
def fetch_missing_users_details(people: People) -> None:
for name, details in people.items():
if details['github'] and details['twitter']:
continue
user_info = user(github_username=details['github'], fullname=name)
if not details['github']:
details['github'] = user_info['login']
if not details['twitter']:
details['twitter'] = user_info['twitter_username']
def save_awesome_people(people: People) -> None:
with DB_FILE.open(mode='w', encoding='utf-8') as fh:
json.dump(people, fh, indent=4, sort_keys=True)
fh.write("\n")
def debug(*args: Any) -> None:
if os.getenv('DEBUG') == '1':
print(*args)
if __name__ == '__main__':
ret = 1
try:
ret = main(*sys.argv[1:])
except TypeError:
ret = 2
print(f'''
Fetch contributors to a release.
Usage:
python {sys.argv[0]} {sys.argv[0]} <RELEASE N-1> <RELEASE N>
Example:
python {sys.argv[0]} 2.4.0 2.5.0
Define the DEBUG=1 environment variable to enable verbose output.
''')
except KeyboardInterrupt:
ret = 255
sys.exit(ret)

View File

@ -0,0 +1,53 @@
"""
Generate snippets to copy-paste.
"""
import sys
from jinja2 import Template
from fetch import HERE, load_awesome_people
TPL_FILE = HERE / 'snippet.jinja2'
HTTPIE_TEAM = {
'claudiatd',
'jakubroztocil',
'jkbr',
'isidentical'
}
BOT_ACCOUNTS = {
'dependabot-sr'
}
IGNORE_ACCOUNTS = HTTPIE_TEAM | BOT_ACCOUNTS
def generate_snippets(release: str) -> str:
people = load_awesome_people()
contributors = {
name: details
for name, details in people.items()
if details['github'] not in IGNORE_ACCOUNTS
and (release in details['committed'] or release in details['reported'])
}
template = Template(source=TPL_FILE.read_text(encoding='utf-8'))
output = template.render(contributors=contributors, release=release)
print(output)
return 0
if __name__ == '__main__':
ret = 1
try:
ret = generate_snippets(sys.argv[1])
except (IndexError, TypeError):
ret = 2
print(f'''
Generate snippets for contributors to a release.
Usage:
python {sys.argv[0]} {sys.argv[0]} <RELEASE>
''')
sys.exit(ret)

View File

@ -0,0 +1,691 @@
{
"Aaron Miller": {
"committed": [],
"github": "aaronhmiller",
"reported": [
"3.0.0"
],
"twitter": "aaronmiller8"
},
"Alexander Bogdanov": {
"committed": [],
"github": "ab-kily",
"reported": [
"3.0.0"
],
"twitter": null
},
"Almad": {
"committed": [
"2.5.0"
],
"github": "Almad",
"reported": [
"2.6.0",
"3.0.0"
],
"twitter": "almadcz"
},
"Andr\u00e1s Czig\u00e1ny": {
"committed": [],
"github": "andrascz",
"reported": [
"3.0.0"
],
"twitter": null
},
"Annette Wilson": {
"committed": [],
"github": "annettejanewilson",
"reported": [
"2.6.0",
"3.0.0"
],
"twitter": null
},
"Anton Emelyanov": {
"committed": [
"2.5.0"
],
"github": "king-menin",
"reported": [],
"twitter": null
},
"Batuhan Taskaya": {
"committed": [
"3.0.0",
"3.2.0"
],
"github": "isidentical",
"reported": [
"3.0.0",
"3.2.0"
],
"twitter": "isidentical"
},
"Brad Crittenden": {
"committed": [],
"github": "bac",
"reported": [
"3.0.0"
],
"twitter": null
},
"Chad": {
"committed": [],
"github": "cythrawll",
"reported": [
"3.0.0"
],
"twitter": null
},
"D8ger": {
"committed": [],
"github": "caofanCPU",
"reported": [
"2.5.0"
],
"twitter": null
},
"Dave": {
"committed": [
"2.6.0",
"3.0.0"
],
"github": "davecheney",
"reported": [],
"twitter": "davecheney"
},
"Dawid Ferenczy Rogo\u017ean": {
"committed": [],
"github": "ferenczy",
"reported": [
"2.5.0"
],
"twitter": "DawidFerenczy"
},
"Ed Rooth": {
"committed": [],
"github": "sym3tri",
"reported": [
"3.0.0"
],
"twitter": null
},
"Elena Lape": {
"committed": [
"2.5.0"
],
"github": "elenalape",
"reported": [],
"twitter": "elena_lape"
},
"Ethan Mills": {
"committed": [
"3.2.0"
],
"github": "ethanmills",
"reported": [],
"twitter": null
},
"Fabio Peruzzo": {
"committed": [],
"github": "peruzzof",
"reported": [
"2.6.0",
"3.0.0"
],
"twitter": null
},
"F\u00fash\u0113ng": {
"committed": [],
"github": "lienide",
"reported": [
"2.5.0"
],
"twitter": null
},
"Gabriel Cruz": {
"committed": [],
"github": "gmelodie",
"reported": [
"3.0.0"
],
"twitter": "gmelodiecruz"
},
"Gaurav": {
"committed": [
"3.0.0"
],
"github": "gkcs",
"reported": [],
"twitter": null
},
"Giampaolo Rodola": {
"committed": [],
"github": "giampaolo",
"reported": [
"2.5.0"
],
"twitter": null
},
"Greg Myers": {
"committed": [
"3.0.0"
],
"github": "myersg86",
"reported": [],
"twitter": null
},
"Hugh Williams": {
"committed": [],
"github": "hughpv",
"reported": [
"2.5.0"
],
"twitter": null
},
"Ilya Sukhanov": {
"committed": [
"2.5.0"
],
"github": "IlyaSukhanov",
"reported": [
"2.5.0"
],
"twitter": null
},
"Jakub Roztocil": {
"committed": [
"2.5.0",
"2.6.0",
"3.0.0",
"3.2.0"
],
"github": "jakubroztocil",
"reported": [
"2.5.0",
"2.6.0",
"3.0.0"
],
"twitter": "jakubroztocil"
},
"Jan Bra\u0161na": {
"committed": [
"3.0.0"
],
"github": "janbrasna",
"reported": [],
"twitter": "janbrasna"
},
"Jan Verbeek": {
"committed": [
"2.5.0"
],
"github": "blyxxyz",
"reported": [
"3.0.0",
"3.2.0"
],
"twitter": null
},
"Jannik Vieten": {
"committed": [
"2.5.0"
],
"github": "exploide",
"reported": [],
"twitter": null
},
"Jesper Holmberg": {
"committed": [],
"github": "strindberg",
"reported": [
"3.0.0"
],
"twitter": null
},
"Kirill Krasnov": {
"committed": [],
"github": "Kirill",
"reported": [
"3.0.0"
],
"twitter": null
},
"Marcel St\u00f6r": {
"committed": [
"2.5.0"
],
"github": "marcelstoer",
"reported": [],
"twitter": "frightanic"
},
"Marco Seguri": {
"committed": [],
"github": "seguri",
"reported": [
"3.0.0"
],
"twitter": null
},
"Mariano Ruiz": {
"committed": [],
"github": "mrsarm",
"reported": [
"2.5.0"
],
"twitter": "mrsarm82"
},
"Mark Rosenbaum": {
"committed": [],
"github": "markrosenbaum",
"reported": [
"3.0.0"
],
"twitter": null
},
"Micka\u00ebl Schoentgen": {
"committed": [
"2.5.0",
"2.6.0",
"3.0.0"
],
"github": "BoboTiG",
"reported": [
"2.5.0",
"2.6.0",
"3.0.0"
],
"twitter": "__tiger222__"
},
"Mike DePalatis": {
"committed": [],
"github": "mivade",
"reported": [
"3.0.0"
],
"twitter": null
},
"Miro Hron\u010dok": {
"committed": [
"2.5.0",
"2.6.0",
"3.0.0"
],
"github": "hroncok",
"reported": [],
"twitter": "hroncok"
},
"Mohamed Daahir": {
"committed": [],
"github": "ducaale",
"reported": [
"2.5.0",
"3.2.0"
],
"twitter": null
},
"Nanashi.": {
"committed": [],
"github": "sevenc-nanashi",
"reported": [
"3.0.0"
],
"twitter": "sevenc_nanashi"
},
"Nicklas Ansman Giertz": {
"committed": [],
"github": "ansman",
"reported": [
"3.2.0"
],
"twitter": null
},
"Oliver Fish": {
"committed": [],
"github": "Oliver-Fish",
"reported": [
"3.2.0"
],
"twitter": null
},
"Omer Akram": {
"committed": [
"2.6.0",
"3.0.0"
],
"github": "om26er",
"reported": [
"2.6.0",
"3.0.0"
],
"twitter": "om26er"
},
"Patrick Taylor": {
"committed": [],
"github": "pmeister",
"reported": [
"3.0.0"
],
"twitter": null
},
"Paul Laffitte": {
"committed": [],
"github": "paullaffitte",
"reported": [
"3.0.0"
],
"twitter": "plaffitt"
},
"Pavel Alexeev aka Pahan-Hubbitus": {
"committed": [],
"github": "Hubbitus",
"reported": [
"2.5.0"
],
"twitter": null
},
"Roberto L\u00f3pez L\u00f3pez": {
"committed": [],
"github": "robertolopezlopez",
"reported": [
"3.2.0"
],
"twitter": null
},
"Russell Shurts": {
"committed": [],
"github": "rshurts",
"reported": [
"3.0.0"
],
"twitter": null
},
"Samuel Marks": {
"committed": [],
"github": "SamuelMarks",
"reported": [
"2.5.0"
],
"twitter": null
},
"Sebastian Czech": {
"committed": [
"3.0.0"
],
"github": "sebastianczech",
"reported": [],
"twitter": "sebaczech"
},
"Sullivan SENECHAL": {
"committed": [],
"github": "soullivaneuh",
"reported": [
"2.5.0"
],
"twitter": null
},
"Thomas Klinger": {
"committed": [],
"github": "mosesontheweb",
"reported": [
"2.5.0"
],
"twitter": null
},
"Vincent van \u2019t Zand": {
"committed": [],
"github": "vovtz",
"reported": [
"2.6.0",
"3.0.0"
],
"twitter": null
},
"Vivaan Verma": {
"committed": [
"3.0.0"
],
"github": "doublevcodes",
"reported": [],
"twitter": "doublevcodes"
},
"Vladimir Berkutov": {
"committed": [
"3.0.0"
],
"github": "dair-targ",
"reported": [],
"twitter": null
},
"Will Rogers": {
"committed": [],
"github": "wjrogers",
"reported": [
"3.0.0"
],
"twitter": null
},
"Yannic Schneider": {
"committed": [],
"github": "cynay",
"reported": [
"2.5.0"
],
"twitter": null
},
"a1346054": {
"committed": [
"2.5.0"
],
"github": "a1346054",
"reported": [],
"twitter": null
},
"arloan": {
"committed": [],
"github": "arloan",
"reported": [
"3.0.0"
],
"twitter": null
},
"bl-ue": {
"committed": [
"2.5.0"
],
"github": "FiReBlUe45",
"reported": [],
"twitter": null
},
"blueray453": {
"committed": [],
"github": "blueray453",
"reported": [
"3.0.0"
],
"twitter": null
},
"claudiatd": {
"committed": [
"2.6.0",
"3.0.0"
],
"github": "claudiatd",
"reported": [],
"twitter": null
},
"coldcoff": {
"committed": [],
"github": "coldcoff",
"reported": [
"3.0.0"
],
"twitter": null
},
"dependabot[bot]": {
"committed": [
"3.2.0"
],
"github": "dependabot-sr",
"reported": [],
"twitter": null
},
"dkreeft": {
"committed": [
"2.6.0",
"3.0.0"
],
"github": "dkreeft",
"reported": [],
"twitter": null
},
"greg": {
"committed": [
"3.0.0"
],
"github": "gregkh",
"reported": [],
"twitter": null
},
"henryhu712": {
"committed": [
"2.5.0"
],
"github": "henryhu712",
"reported": [],
"twitter": null
},
"hosseingt": {
"committed": [
"3.0.0"
],
"github": "hosseingt",
"reported": [],
"twitter": null
},
"jakubroztocil": {
"committed": [
"2.6.0",
"3.0.0"
],
"github": "jkbr",
"reported": [],
"twitter": null
},
"josephworks": {
"committed": [],
"github": "josephworks",
"reported": [
"3.0.0"
],
"twitter": null
},
"jungle-boogie": {
"committed": [],
"github": "jungle-boogie",
"reported": [
"2.5.0"
],
"twitter": null
},
"luisuimi": {
"committed": [],
"github": "luisuimi",
"reported": [
"3.0.0"
],
"twitter": null
},
"luzpaz": {
"committed": [
"3.2.0"
],
"github": "luzpaz",
"reported": [],
"twitter": null
},
"nixbytes": {
"committed": [
"2.5.0"
],
"github": "nixbytes",
"reported": [],
"twitter": "linuxbyte3"
},
"peterpt": {
"committed": [],
"github": "peterpt",
"reported": [
"3.0.0"
],
"twitter": null
},
"qiulang": {
"committed": [],
"github": "qiulang",
"reported": [
"2.5.0"
],
"twitter": null
},
"stonebig": {
"committed": [],
"github": "stonebig",
"reported": [
"3.0.0"
],
"twitter": null
},
"whodidthis": {
"committed": [],
"github": "whodidthis",
"reported": [
"3.0.0"
],
"twitter": null
},
"zhaohanqing95": {
"committed": [],
"github": "zhaohanqing95",
"reported": [
"3.2.0"
],
"twitter": null
},
"zoulja": {
"committed": [],
"github": "zoulja",
"reported": [
"3.0.0"
],
"twitter": null
},
"zwx00": {
"committed": [],
"github": "zwx00",
"reported": [
"2.5.0"
],
"twitter": null
},
"\u5d14\u5c0f\u4e8c": {
"committed": [],
"github": "rogerdehe",
"reported": [
"2.6.0",
"3.0.0"
],
"twitter": null
},
"\u9ec4\u6d77": {
"committed": [],
"github": "hh-in-zhuzhou",
"reported": [
"2.6.0",
"3.0.0"
],
"twitter": null
}
}

View File

@ -0,0 +1,14 @@
<!-- Blog post -->
## Community contributions
Wed like to thank these amazing people for their contributions to this release:
{% for name, details in contributors.items() -%}
- [{{ name }}](https://github.com/{{ details.github }}){{ '' if loop.last else '\n' }}
{%- endfor %}
<!-- Twitter -->
Wed like to thank these amazing people for their contributions to HTTPie {{ release }}: {% for name, details in contributors.items() if details.twitter -%}
@{{ details.twitter }}{{ '' if loop.last else ', ' }}
{%- endfor %} 🥧

View File

@ -55,7 +55,7 @@ def build_docs_structure(database: Database):
tree = database[KEY_DOC_STRUCTURE]
structure = []
for platform, tools_ids in tree.items():
assert platform.isalnum(), f'{platform=} must be alpha-numeric for generated links to work'
assert platform.isalnum(), f'{platform=} must be alphanumeric for generated links to work'
platform_tools = [tools[tool_id] for tool_id in tools_ids]
structure.append((platform, platform_tools))
return structure

View File

@ -19,16 +19,16 @@ Do not edit here, but in docs/installation/.
{% endif %}
{% if tool.links.setup %}
To install [{{ tool.name }}]({{ tool.links.homepage }}) follow [installation instructions]({{ tool.links.setup }}).
To install [{{ tool.name }}]({{ tool.links.homepage }}), see [its installation]({{ tool.links.setup }}).
{% endif %}
```bash
# Install
# Install httpie
$ {{ tool.commands.install|join('\n$ ') }}
```
```bash
# Upgrade
# Upgrade httpie
$ {{ tool.commands.upgrade|join('\n$ ') }}
```
{% endfor %}

View File

@ -14,39 +14,20 @@ docs-structure:
macOS:
- brew-mac
- port
- snap-mac
- spack-mac
Windows:
- chocolatey
Linux:
- snap-linux
- brew-linux
- apt
- dnf
- yum
- apk
- emerge
- single-binary
- snap-linux
- brew-linux
- pacman
- xbps-install
- spack-linux
FreeBSD:
- pkg
tools:
apk:
title: Alpine Linux
name: apk
links:
homepage: https://wiki.alpinelinux.org/wiki/Alpine_Linux_package_management
package: https://pkgs.alpinelinux.org/package/edge/community/x86/httpie
commands:
install:
- apk update
- apk add httpie
upgrade:
- apk update
- apk add --upgrade httpie
apt:
title: Debian and Ubuntu
note: Also works for other Debian-derived distributions like MX Linux, Linux Mint, deepin, Pop!_OS, KDE neon, Zorin OS, elementary OS, Kubuntu, Devuan, Linux Lite, Peppermint OS, Lubuntu, antiX, Xubuntu, etc.
@ -56,11 +37,13 @@ tools:
package: https://packages.debian.org/sid/web/httpie
commands:
install:
- apt update
- apt install httpie
- curl -SsL https://packages.httpie.io/deb/KEY.gpg | sudo gpg --dearmor -o /usr/share/keyrings/httpie.gpg
# - curl -SsL -o /etc/apt/sources.list.d/httpie.list https://packages.httpie.io/deb/httpie.list
- sudo echo "deb [arch=amd64 signed-by=/usr/share/keyrings/httpie.gpg] https://packages.httpie.io/deb ./" > /etc/apt/sources.list.d/httpie.list
- sudo apt update
- sudo apt install httpie
upgrade:
- apt update
- apt upgrade httpie
- sudo apt update && sudo apt upgrade httpie
brew-mac:
title: Homebrew
@ -113,26 +96,10 @@ tools:
package: https://src.fedoraproject.org/rpms/httpie
commands:
install:
- dnf update
- dnf install httpie
upgrade:
- dnf update
- dnf upgrade httpie
emerge:
title: Gentoo
name: Portage
links:
homepage: https://wiki.gentoo.org/wiki/Portage
package: https://packages.gentoo.org/packages/net-misc/httpie
commands:
install:
- emerge --sync
- emerge httpie
upgrade:
- emerge --sync
- emerge --update httpie
pacman:
title: Arch Linux
name: pacman
@ -142,9 +109,9 @@ tools:
package: https://archlinux.org/packages/community/any/httpie/
commands:
install:
- pacman -Sy httpie
upgrade:
- pacman -Syu httpie
upgrade:
- pacman -Syu
pkg:
title: FreshPorts
@ -174,9 +141,9 @@ tools:
- port upgrade httpie
pypi:
title: PyPi
title: PyPI
name: pip
note: Please make sure you have Python 3.6 or newer (`python --version`).
note: Please make sure you have Python 3.7 or newer (`python --version`).
links:
homepage: https://pypi.org/
# setup: https://pip.pypa.io/en/stable/installation/
@ -202,56 +169,6 @@ tools:
upgrade:
- snap refresh httpie
snap-mac:
title: Snapcraft (macOS)
name: Snapcraft
links:
homepage: https://snapcraft.io/
setup: https://snapcraft.io/docs/installing-snapd
package: https://snapcraft.io/httpie
commands:
install:
- snap install httpie
upgrade:
- snap refresh httpie
spack-linux:
title: Spack (Linux)
name: Spack
links:
homepage: https://spack.readthedocs.io/en/latest/index.html
setup: https://spack.readthedocs.io/en/latest/getting_started.html#installation
commands:
install:
- spack install httpie
upgrade:
- spack install httpie
spack-mac:
title: Spack (macOS)
name: Spack
links:
homepage: https://spack.readthedocs.io/en/latest/index.html
setup: https://spack.readthedocs.io/en/latest/getting_started.html#installation
commands:
install:
- spack install httpie
upgrade:
- spack install httpie
xbps-install:
title: Void Linux
name: XBPS
links:
homepage: https://docs.voidlinux.org/xbps/index.html
commands:
install:
- xbps-install -Su
- xbps-install -S httpie
upgrade:
- xbps-install -Su
- xbps-install -Su httpie
yum:
title: CentOS and RHEL
name: Yum
@ -261,9 +178,20 @@ tools:
package: https://src.fedoraproject.org/rpms/httpie
commands:
install:
- yum update
- yum install epel-release
- yum install httpie
upgrade:
- yum update
- yum upgrade httpie
single-binary:
title: Single binary executables
name: Single binary executables
note: Get the standalone HTTPie Linux executables when you don't want to go through the full installation process.
links:
commands:
install:
- https --download packages.httpie.io/binaries/linux/http-latest -o http
- ln -ls ./http ./https
- chmod +x ./http ./https
upgrade:
- https --download packages.httpie.io/binaries/linux/http-latest -o http

View File

@ -11,12 +11,21 @@ all
# Because we use HTML to hide them on the website.
exclude_rule 'MD002'
# MD007 Allow unordered list indentation
exclude_rule 'MD007'
# MD013 Line length
exclude_rule 'MD013'
# MD014 Dollar signs used before commands without showing output
exclude_rule 'MD014'
# MD028 Blank line inside blockquote
exclude_rule 'MD028'
# MD012 Multiple consecutive blank lines
exclude_rule 'MD012'
# Tell the linter to use ordered lists:
# 1. Foo
# 2. Bar

View File

@ -3,7 +3,7 @@
Welcome on the documentation part of the **HTTPie release process**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions, then you can find all you need for your OS on [that page](https://httpie.io/docs#installation). In the case you do not find your OS, [let us know](https://github.com/httpie/httpie/issues/).
- If you are looking for HTTPie installation or upgrade instructions, then you can find all you need for your OS on [that page](https://httpie.io/docs#installation). In the case you do not find your OS, [let us know](https://github.com/httpie/cli/issues/).
- If you are looking for technical information about the HTTPie packaging, then you are at the good place.
## About
@ -12,18 +12,22 @@ You are looking at the HTTPie packaging documentation, where you will find valua
The overall release process starts simple:
1. Do the [PyPi](https://pypi.org/project/httpie/) publication.
2. Then, handle company-related tasks.
3. Finally, follow OS-specific steps, described in documents below, to send patches downstream.
1. Bump the version identifiers in the following places:
- `httpie/__init__.py`
- `docs/packaging/windows-chocolatey/httpie.nuspec`
- `CHANGELOG.md`
2. Commit your changes and make a PR against the `master`.
3. Merge the PR, and tag the last commit with your version identifier.
4. Make a GitHub release (by copying the text in `CHANGELOG.md`)
5. Push that release to PyPI (dispatch the `Release PyPI` GitHub action).
6. Once PyPI is ready, push the release to the Snap, Homebrew and Chocolatey with their respective actions.
7. Go to the [`httpie/debian.httpie.io`](https://github.com/httpie/debian.httpie.io) repo and trigger the package index workflow.
## First, PyPi
## Company-specific tasks
Let's do the release on [PyPi](https://pypi.org/project/httpie/).
That is done quite easily by manually triggering the [release workflow](https://github.com/httpie/httpie/actions/workflows/release.yml).
## Then, company-specific tasks
- Update the HTTPie version bundled into termible ([example](https://github.com/httpie/termible/pull/1)).
- Blank the `master_and_released_docs_differ_after` value in [config.json](https://github.com/httpie/cli/blob/master/docs/config.json).
- Update the [contributors list](../contributors).
- Update the HTTPie version bundled into [Termible](https://termible.io/) ([example](https://github.com/httpie/termible/pull/1)).
## Finally, spread dowstream
@ -32,18 +36,12 @@ A more complete state of deployment can be found on [repology](https://repology.
| OS | Maintainer |
| -------------------------------------------: | -------------- |
| [Alpine](linux-alpine/) | **HTTPie** |
| [Arch Linux, and derived](linux-arch/) | trusted person |
| :construction: [AOSC OS](linux-aosc/) | **HTTPie** |
| [CentOS, RHEL, and derived](linux-centos/) | trusted person |
| [Debian, Ubuntu, and derived](linux-debian/) | trusted person |
| [Fedora](linux-fedora/) | trusted person |
| [Gentoo](linux-gentoo/) | **HTTPie** |
| :construction: [Homebrew, Linuxbrew](brew/) | **HTTPie** |
| :construction: [MacPorts](mac-ports/) | **HTTPie** |
| [Debian, Ubuntu, and derived](linux-debian/) | **HTTPie** |
| [Homebrew, Linuxbrew](brew/) | **HTTPie** |
| [Snapcraft](snapcraft/) | **HTTPie** |
| [Spack](spack/) | **HTTPie** |
| [Void Linux](linux-void/) | **HTTPie** |
| [Windows — Chocolatey](windows-chocolatey/) | **HTTPie** |
:new: You do not find your system or you would like to see HTTPie supported on another OS? Then [let us know](https://github.com/httpie/httpie/issues/).
:new: You do not find your system or you would like to see HTTPie supported on another OS? Then [let us know](https://github.com/httpie/cli/issues/).

View File

@ -13,21 +13,19 @@ We will discuss setting up the environment, installing development tools, instal
## Overall process
:construction: Work in progress.
The brew deployment is completely automated, and only requires a trigger to [`Release on Homebrew`](https://github.com/httpie/cli/actions/workflows/release-brew.yml) action
from the release manager.
First, update the current Formula:
If it is needed to be done manually, the following command can be used:
```bash
make brew-deps
# Copy-paste content into downstream/mac/brew/httpie.rb
git add downstream/mac/brew/httpie.rb
git commit -s -m 'Update brew formula to XXX'
```console
$ brew bump-formula-pr httpie --version={TARGET_VERSION}
```
That [GitHub workflow](https://github.com/httpie/httpie/actions/workflows/test-package-mac-brew.yml) will test the formula when `downstream/mac/brew/httpie.rb` is changed in a pull request.
Then, open a pull request with those changes to the [downstream file]([ file](https://github.com/Homebrew/homebrew-core/blob/master/Formula/httpie.rb)).
which will bump the formula, and create a PR against the package index.
## Hacking
:construction: Work in progress.
Make your changes, test the formula through the [`Test Brew Package`](https://github.com/httpie/cli/actions/workflows/test-package-mac-brew.yml) action
and then finally submit your patch to [`homebrew-core`](https://github.com/Homebrew/homebrew-core`)

View File

@ -1,80 +0,0 @@
#!/usr/bin/env python3
"""
Generate Ruby code with URLs and file hashes for packages from PyPi
(i.e., httpie itself as well as its dependencies) to be included
in the Homebrew formula after a new release of HTTPie has been published
on PyPi.
<https://github.com/Homebrew/homebrew-core/blob/master/Formula/httpie.rb>
"""
import hashlib
import requests
VERSIONS = {
# By default, we use the latest packages. But sometimes Requests has a maximum supported versions.
# Take a look here before making a release: <https://github.com/psf/requests/blob/master/setup.py>
'idna': '3.2',
}
# Note: Keep that list sorted.
PACKAGES = [
'certifi',
'charset-normalizer',
'defusedxml',
'httpie',
'idna',
'Pygments',
'PySocks',
'requests',
'requests-toolbelt',
'urllib3',
]
def get_package_meta(package_name):
api_url = f'https://pypi.org/pypi/{package_name}/json'
resp = requests.get(api_url).json()
hasher = hashlib.sha256()
version = VERSIONS.get(package_name)
if package_name not in VERSIONS:
# Latest version
release_bundle = resp['urls']
else:
release_bundle = resp['releases'][version]
for release in release_bundle:
download_url = release['url']
if download_url.endswith('.tar.gz'):
hasher.update(requests.get(download_url).content)
return {
'name': package_name,
'url': download_url,
'sha256': hasher.hexdigest(),
}
else:
raise RuntimeError(f'{package_name}: download not found: {resp}')
def main():
package_meta_map = {
package_name: get_package_meta(package_name)
for package_name in PACKAGES
}
httpie_meta = package_meta_map.pop('httpie')
print()
print(' url "{url}"'.format(url=httpie_meta['url']))
print(' sha256 "{sha256}"'.format(sha256=httpie_meta['sha256']))
print()
for dep_meta in package_meta_map.values():
print(' resource "{name}" do'.format(name=dep_meta['name']))
print(' url "{url}"'.format(url=dep_meta['url']))
print(' sha256 "{sha256}"'.format(sha256=dep_meta['sha256']))
print(' end')
print('')
if __name__ == '__main__':
main()

View File

@ -3,29 +3,30 @@ class Httpie < Formula
desc "User-friendly cURL replacement (command-line HTTP client)"
homepage "https://httpie.io/"
url "https://files.pythonhosted.org/packages/90/64/7ea8066309970f787653bdc8c5328272a5c4d06cbce3a07a6a5c3199c3d7/httpie-2.5.0.tar.gz"
sha256 "fe6a8bc50fb0635a84ebe1296a732e39357c3e1354541bf51a7057b4877e47f9"
url "https://files.pythonhosted.org/packages/32/85/bb095699be20cc98731261cb80884e9458178f8fef2a38273530ce77c0a5/httpie-3.1.0.tar.gz"
sha256 "2e4a2040b84a912e65c01fb34f7aafe88cad2a3af2da8c685ca65080f376feda"
license "BSD-3-Clause"
head "https://github.com/httpie/httpie.git"
head "https://github.com/httpie/cli.git", branch: "master"
bottle do
sha256 cellar: :any_skip_relocation, arm64_big_sur: "01115f69aff0399b3f73af09899a42a14343638a4624a35749059cc732c49cdc"
sha256 cellar: :any_skip_relocation, big_sur: "53f07157f00edf8193b7d4f74f247f53e1796fbc3e675cd2fbaa4b9dc2bad62c"
sha256 cellar: :any_skip_relocation, catalina: "7cf216fdee98208856d654060fdcad3968623d7ed27fcdeba27d3120354c9a9f"
sha256 cellar: :any_skip_relocation, mojave: "28adb5aed8c1c2b39c51789f242ff0dffde39073e161deb379c79184d787d063"
sha256 cellar: :any_skip_relocation, x86_64_linux: "91cb8c332c643bd8b1d0a8f3ec0acd4770b407991f6de1fd320d675f2b2e95ec"
sha256 cellar: :any_skip_relocation, arm64_monterey: "9bb6e8c1ef5ba8b019ddedd7e908dd2174da695351aa9a238dfb28b0f57ef005"
sha256 cellar: :any_skip_relocation, arm64_big_sur: "47ffccd3241155d863e1b4f6259d538a34d42a0cdeed8152bda257ee607b51be"
sha256 cellar: :any_skip_relocation, monterey: "dc4a04cb05a9cd1bfa6a632a0e4a21975905954af54ece41f9050c52474267be"
sha256 cellar: :any_skip_relocation, big_sur: "ae469e37864e967e0fd99fba15a78e719dcb351b462f98f3843c78ed1473df6d"
sha256 cellar: :any_skip_relocation, catalina: "291a3eaecb2a2cc845c1652686a9a14b21053d7e3a7d0115245b2150ca2e199e"
sha256 cellar: :any_skip_relocation, x86_64_linux: "710836e27c44c8e3ad181d668f4a9f78c4cb4c355d7b148a397599a7cd42713d"
end
depends_on "python@3.9"
depends_on "python@3.10"
resource "certifi" do
url "https://files.pythonhosted.org/packages/6d/78/f8db8d57f520a54f0b8a438319c342c61c22759d8f9a1cd2e2180b5e5ea9/certifi-2021.5.30.tar.gz"
sha256 "2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"
url "https://files.pythonhosted.org/packages/6c/ae/d26450834f0acc9e3d1f74508da6df1551ceab6c2ce0766a593362d6d57f/certifi-2021.10.8.tar.gz"
sha256 "78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"
end
resource "charset-normalizer" do
url "https://files.pythonhosted.org/packages/e7/4e/2af0238001648ded297fb54ceb425ca26faa15b341b4fac5371d3938666e/charset-normalizer-2.0.4.tar.gz"
sha256 "f23667ebe1084be45f6ae0538e4a5a865206544097e4e8bbcacf42cd02a348f3"
url "https://files.pythonhosted.org/packages/56/31/7bcaf657fafb3c6db8c787a865434290b726653c912085fbd371e9b92e1c/charset-normalizer-2.0.12.tar.gz"
sha256 "2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"
end
resource "defusedxml" do
@ -34,13 +35,18 @@ class Httpie < Formula
end
resource "idna" do
url "https://files.pythonhosted.org/packages/cb/38/4c4d00ddfa48abe616d7e572e02a04273603db446975ab46bbcd36552005/idna-3.2.tar.gz"
sha256 "467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"
url "https://files.pythonhosted.org/packages/62/08/e3fc7c8161090f742f504f40b1bccbfc544d4a4e09eb774bf40aafce5436/idna-3.3.tar.gz"
sha256 "9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"
end
resource "multidict" do
url "https://files.pythonhosted.org/packages/fa/a7/71c253cdb8a1528802bac7503bf82fe674367e4055b09c28846fdfa4ab90/multidict-6.0.2.tar.gz"
sha256 "5ff3bd75f38e4c43f1f470f2df7a4d430b821c4ce22be384e1459cb57d6bb013"
end
resource "Pygments" do
url "https://files.pythonhosted.org/packages/b7/b3/5cba26637fe43500d4568d0ee7b7362de1fb29c0e158d50b4b69e9a40422/Pygments-2.10.0.tar.gz"
sha256 "f398865f7eb6874156579fdf36bc840a03cab64d1cde9e93d68f46a425ec52c6"
url "https://files.pythonhosted.org/packages/94/9c/cb656d06950268155f46d4f6ce25d7ffc51a0da47eadf1b164bbf23b718b/Pygments-2.11.2.tar.gz"
sha256 "4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a"
end
resource "PySocks" do
@ -49,8 +55,8 @@ class Httpie < Formula
end
resource "requests" do
url "https://files.pythonhosted.org/packages/e7/01/3569e0b535fb2e4a6c384bdbed00c55b9d78b5084e0fb7f4d0bf523d7670/requests-2.26.0.tar.gz"
sha256 "b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7"
url "https://files.pythonhosted.org/packages/60/f3/26ff3767f099b73e0efa138a9998da67890793bfa475d8278f84a30fec77/requests-2.27.1.tar.gz"
sha256 "68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"
end
resource "requests-toolbelt" do
@ -59,8 +65,8 @@ class Httpie < Formula
end
resource "urllib3" do
url "https://files.pythonhosted.org/packages/4f/5a/597ef5911cb8919efe4d86206aa8b2658616d676a7088f0825ca08bd7cb8/urllib3-1.26.6.tar.gz"
sha256 "f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f"
url "https://files.pythonhosted.org/packages/b0/b1/7bbf5181f8e3258efae31702f5eab87d8a74a72a0aa78bc8c08c1466e243/urllib3-1.26.8.tar.gz"
sha256 "0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"
end
def install
@ -68,6 +74,10 @@ class Httpie < Formula
end
test do
assert_match version.to_s, shell_output("#{bin}/httpie --version")
assert_match version.to_s, shell_output("#{bin}/https --version")
assert_match version.to_s, shell_output("#{bin}/http --version")
raw_url = "https://raw.githubusercontent.com/Homebrew/homebrew-core/HEAD/Formula/httpie.rb"
assert_match "PYTHONPATH", shell_output("#{bin}/http --ignore-stdin #{raw_url}")
end

6
docs/packaging/brew/update.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
set -xe
rm -f httpie.rb
http --download https://raw.githubusercontent.com/Homebrew/homebrew-core/master/Formula/httpie.rb

View File

@ -1,33 +0,0 @@
# Contributor: Fabian Affolter <fabian@affolter-engineering.ch>
# Maintainer: Fabian Affolter <fabian@affolter-engineering.ch>
# Contributor: Daniel Isaksen <d@duniel.no>
# Contributor: Mickaël Schoentgen <mickael@apible.io>
pkgname=httpie
pkgver=2.5.0
pkgrel=0
pkgdesc="CLI, cURL-like tool"
url="https://httpie.org/"
arch="noarch"
license="BSD-3-Clause"
depends="python3 py3-setuptools py3-requests py3-pygments py3-requests-toolbelt py3-pysocks py3-defusedxml"
makedepends="py3-setuptools"
checkdepends="py3-pytest py3-pytest-httpbin py3-responses"
source="https://files.pythonhosted.org/packages/source/h/httpie/httpie-$pkgver.tar.gz"
# secfixes:
# 1.0.3-r0:
# - CVE-2019-10751
build() {
python3 setup.py build
}
check() {
python3 -m pytest ./httpie ./tests
}
package() {
python3 setup.py install --prefix=/usr --root="$pkgdir"
}
sha512sums="3bfe572b03bfde87d5a02f9ba238f9493b32e587c33fd30600a4dd6a45082eedcb2b507c7f1e3e75a423cbdcc1ff0556138897dffb7888d191834994eae9a2aa httpie-2.5.0.tar.gz"

View File

@ -1,67 +0,0 @@
# HTTPie on Alpine Linux
Welcome to the documentation about **packaging HTTPie for Alpine Linux**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on Alpine Linux, then you can find them on [that page](https://httpie.io/docs#alpine-linux).
- If you are looking for technical information about the HTTPie packaging on Alpine Linux, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Alpine Linux.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
## Overall process
Open a pull request to update the [downstream file](https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/community/httpie/APKBUILD) ([example](https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/25075)).
Notes:
- The `pkgrel` value must be set to `0`.
- The commit message must be `community/httpie: upgrade to XXX`.
- The commit must be signed-off (`git commit -s`).
## Hacking
Launch the docker image:
```bash
docker pull alpine
docker run -it --rm alpine
```
From inside the container:
```bash
# Install tools
apk add alpine-sdk sudo
# Add a user (password required)
adduser me
addgroup me abuild
echo "me ALL=(ALL) ALL" >> /etc/sudoers
# Switch user
su - me
# Create a private key (not used but required)
abuild-keygen -a -i
# Clone
git clone --depth=1 https://gitlab.alpinelinux.org/alpine/aports.git
cd aports/community/httpie
# Retrieve the patch of the latest HTTPie version
curl https://raw.githubusercontent.com/httpie/httpie/master/docs/packaging/linux-alpine/APKBUILD \
-o APKBUILD
# Build the package
abuild -r
# Install the package
sudo apk add --repository ~/packages/community httpie
# And test it!
http --version
https --version
```

View File

@ -1,24 +0,0 @@
# HTTPie on AOSC OS
Welcome to the documentation about **packaging HTTPie for AOSC OS**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for technical information about the HTTPie packaging on AOSC OS, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for AOSC OS.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
## Overall process
Open a pull request to update the [downstream file](https://github.com/AOSC-Dev/aosc-os-abbs/blob/stable/extra-web/httpie/spec) ([example](https://github.com/AOSC-Dev/aosc-os-abbs/commit/d0d3ba0bcea347387bb582a1b0b1b4e518720c80)).
Notes:
- The commit message must be `httpie: update to XXX`.
- The commit must be signed-off (`git commit -s`).
## Hacking
:construction: Work in progress.

View File

@ -1,5 +0,0 @@
VER=2.5.0
SRCS="tbl::https://github.com/httpie/httpie/archive/$VER.tar.gz"
CHKSUMS="sha256::66af56e0efc1ca6237323f1186ba34bca1be24e67a4319fd5df7228ab986faea"
REL=1
CHKUPDATE="anitya::id=1337"

View File

@ -4,15 +4,16 @@
# Contributor: Thomas Weißschuh <thomas_weissschuh lavabit com>
pkgname=httpie
pkgver=2.5.0
pkgver=2.6.0
pkgrel=1
pkgdesc="human-friendly CLI HTTP client for the API era"
url="https://github.com/httpie/httpie"
url="https://github.com/httpie/cli"
depends=('python-defusedxml'
'python-pygments'
'python-pysocks'
'python-requests'
'python-requests-toolbelt')
'python-requests-toolbelt'
'python-charset-normalizer')
makedepends=('python-setuptools')
checkdepends=('python-pytest'
'python-pytest-httpbin'
@ -21,8 +22,8 @@ conflicts=(python-httpie)
replaces=(python-httpie python2-httpie)
license=('BSD')
arch=('any')
source=($pkgname-$pkgver.tar.gz::"https://github.com/httpie/httpie/archive/$pkgver.tar.gz")
sha256sums=('66af56e0efc1ca6237323f1186ba34bca1be24e67a4319fd5df7228ab986faea')
source=($pkgname-$pkgver.tar.gz::"https://github.com/httpie/cli/archive/$pkgver.tar.gz")
sha256sums=('3bcd9a8cb2b11299da12d3af36c095c6d4b665e41c395898a07f1ae4d99fc14a')
build() {
cd $pkgname-$pkgver
@ -42,5 +43,5 @@ package() {
check() {
cd $pkgname-$pkgver
PYTHONDONTWRITEBYTECODE=1 python3 setup.py test
PYTHONDONTWRITEBYTECODE=1 pytest tests
}

View File

@ -11,19 +11,16 @@ Welcome to the documentation about **packaging HTTPie for Debian GNU/Linux**.
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Debian GNU/Linux. They apply to Ubuntu as well, and any Debian-derived distributions like MX Linux, Linux Mint, deepin, Pop!_OS, KDE neon, Zorin OS, elementary OS, Kubuntu, Devuan, Linux Lite, Peppermint OS, Lubuntu, antiX, Xubuntu, etc.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
The current maintainer is Bartosz Fenski.
We create the standalone binaries (see this [for more details](../../../extras/packaging/linux/)) and package them with
[FPM](https://github.com/jordansissel/fpm)'s `dir` mode. The core `http`/`https` commands don't have any dependencies, but the `httpie`
command (due to the underlying `httpie cli plugins` interface) explicitly depends to the system Python (through `python3`/`python3-pip`).
## Overall process
Open a new bug on the Debian Bug Tracking System by sending an email:
The [`Release as Standalone Linux Binary`](https://github.com/httpie/cli/actions/workflows/release-linux-standalone.yml) will be automatically
triggered when a new release is created, and it will submit the `.deb` package as a release asset.
- To: `Debian Bug Tracking System <submit@bugs.debian.org>`
- Subject: `httpie: Version XXX available`
- Message template ([example](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=993937)):
```email
Package: httpie
Severity: wishlist
<MESSAGE>
```
For making that asset available for all debian users, the release manager needs to go to the [`httpie/debian.httpie.io`](https://github.com/httpie/debian.httpie.io) repo
and trigger the [`Update Index`](https://github.com/httpie/debian.httpie.io/actions/workflows/update-index.yml) action. It will automatically
scrape all new debian packages from the release assets, properly update the indexes and create a new PR ([an example](https://github.com/httpie/debian.httpie.io/pull/1))
which then will become active when merged.

View File

@ -15,7 +15,7 @@ The current maintainer is [Miro Hrončok](https://github.com/hroncok).
## Overall process
We added the [.packit.yaml](https://github.com/httpie/httpie/blob/master/.packit.yaml) local file.
We added the [.packit.yaml](https://github.com/httpie/cli/blob/master/.packit.yaml) local file.
It unlocks real-time Fedora checks on pull requests and new releases.
So there is nothing to do on our side: `Packit` will see the new release and open a pull request [there](https://src.fedoraproject.org/rpms/httpie). Then, the Fedora maintainer will review and merge.
@ -42,7 +42,7 @@ Q: Are new versions backported automatically?
A: No. The process is:
1. A new HTTPie release is created on Github.
2. A pull request for Fedora `rawhide` (the development version of Fedora, currently Fedora 35) is created.
2. A pull request for Fedora `rawhide` (the development version of Fedora, currently Fedora 36) is created.
3. A Fedora packager (usually Miro) sanity checks the pull request and merges, builds. HTTPie is updated in `rawhide` within 24 hours (sometimes more, for unrelated issues).
4. A Fedora packager decides whether the upgrade is suitable for stable Fedora releases (currently 34, 33), if so, merges the changes there.
4. A Fedora packager decides whether the upgrade is suitable for stable Fedora releases (currently 35, 34, 33), if so, merges the changes there.
5. (if the above is yes) The new version of HTTPie lands in `updates-testing` repo where it waits for user feedback and lands within ~1 week for broad availability.

View File

@ -0,0 +1,270 @@
Name: httpie
Version: 3.1.0
Release: 1%{?dist}
Summary: A Curl-like tool for humans
License: BSD
URL: https://httpie.org/
Source0: https://github.com/httpie/cli/archive/%{version}/%{name}-%{version}.tar.gz
BuildArch: noarch
BuildRequires: python3-devel
BuildRequires: pyproject-rpm-macros
BuildRequires: help2man
%description
HTTPie is a CLI HTTP utility built out of frustration with existing tools. The
goal is to make CLI interaction with HTTP-based services as human-friendly as
possible.
HTTPie does so by providing an http command that allows for issuing arbitrary
HTTP requests using a simple and natural syntax and displaying colorized
responses.
%prep
%autosetup -p1
%generate_buildrequires
%pyproject_buildrequires -rx test
%build
%pyproject_wheel
%install
%pyproject_install
%pyproject_save_files httpie
# Bash completion
mkdir -p %{buildroot}%{_datadir}/bash-completion/completions
cp -a extras/httpie-completion.bash %{buildroot}%{_datadir}/bash-completion/completions/http
ln -s ./http %{buildroot}%{_datadir}/bash-completion/completions/https
# Fish completion
mkdir -p %{buildroot}%{_datadir}/fish/vendor_completions.d/
cp -a extras/httpie-completion.fish %{buildroot}%{_datadir}/fish/vendor_completions.d/http.fish
ln -s ./http.fish %{buildroot}%{_datadir}/fish/vendor_completions.d/https.fish
# Generate man pages for everything
export PYTHONPATH=%{buildroot}%{python3_sitelib}
mkdir -p %{buildroot}%{_mandir}/man1
help2man %{buildroot}%{_bindir}/http > %{buildroot}%{_mandir}/man1/http.1
help2man %{buildroot}%{_bindir}/https > %{buildroot}%{_mandir}/man1/https.1
help2man %{buildroot}%{_bindir}/httpie > %{buildroot}%{_mandir}/man1/httpie.1
%check
%pytest -v
%files -f %{pyproject_files}
%doc README.md
%license LICENSE
%{_bindir}/http
%{_bindir}/https
%{_bindir}/httpie
%{_mandir}/man1/http.1*
%{_mandir}/man1/https.1*
%{_mandir}/man1/httpie.1*
# we co-own the entire directory structures for bash/fish completion to avoid a dependency
%{_datadir}/bash-completion/
%{_datadir}/fish/
%changelog
* Tue Mar 08 2022 Miro Hrončok <mhroncok@redhat.com> - 3.1.0-1
- Update to 3.1.0
- Fixes: rhbz#2061597
* Mon Jan 24 2022 Miro Hrončok <mhroncok@redhat.com> - 3.0.2-1
- Update to 3.0.2
- Fixes: rhbz#2044572
* Mon Jan 24 2022 Miro Hrončok <mhroncok@redhat.com> - 3.0.1-1
- Update to 3.0.1
- Fixes: rhbz#2044058
* Fri Jan 21 2022 Miro Hrončok <mhroncok@redhat.com> - 3.0.0-1
- Update to 3.0.0
- Fixes: rhbz#2043680
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 2.6.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
* Fri Oct 15 2021 Miro Hrončok <mhroncok@redhat.com> - 2.6.0-1
- Update to 2.6.0
- Fixes: rhbz#2014022
* Tue Sep 07 2021 Miro Hrončok <mhroncok@redhat.com> - 2.5.0-1
- Update to 2.5.0
- Fixes: rhbz#2001693
* Thu Jul 22 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2.4.0-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
* Fri Jun 04 2021 Python Maint <python-maint@redhat.com> - 2.4.0-3
- Rebuilt for Python 3.10
* Thu May 27 2021 Miro Hrončok <mhroncok@redhat.com> - 2.4.0-2
- Add Bash and Fish completion
- Fixes rhbz#1834441
- Run tests on build time
* Wed Mar 24 2021 Mikel Olasagasti Uranga <mikel@olasagasti.info> - 2.4.0-1
- Update to 2.4.0
- Use pypi_source macro
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2.3.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Thu Jan 21 2021 Nils Philippsen <nils@tiptoe.de> - 2.3.0-2
- use macros for Python dependencies
- add missing Python dependencies needed for running help2man
- remove manual Python dependencies
- discard stderr when running help2man
* Thu Dec 24 2020 Nils Philippsen <nils@tiptoe.de> - 2.3.0-1
- version 2.3.0
- Python 2 is no more
- use %%autosetup and Python build macros
- remove EL7-isms
- explicitly require sed for building
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.0.3-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Tue May 26 2020 Miro Hrončok <mhroncok@redhat.com> - 1.0.3-3
- Rebuilt for Python 3.9
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.0.3-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Mon Sep 30 2019 Rick Elrod <relrod@redhat.com> - 1.0.3-1
- Latest upstream
* Mon Aug 19 2019 Miro Hrončok <mhroncok@redhat.com> - 0.9.4-15
- Rebuilt for Python 3.8
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.4-14
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.4-13
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.4-12
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Tue Jun 19 2018 Miro Hrončok <mhroncok@redhat.com> - 0.9.4-11
- Rebuilt for Python 3.7
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.4-10
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.4-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
* Fri Mar 10 2017 Ralph Bean <rbean@redhat.com> - 0.9.4-8
- Fix help2man usage with python3.
https://bugzilla.redhat.com/show_bug.cgi?id=1430733
* Mon Feb 27 2017 Ralph Bean <rbean@redhat.com> - 0.9.4-7
- Fix missing Requires. https://bugzilla.redhat.com/show_bug.cgi?id=1417730
* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.4-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
* Mon Jan 2 2017 Ricky Elrod <relrod@redhat.com> - 0.9.4-5
- Add missing Obsoletes.
* Mon Jan 2 2017 Ricky Elrod <relrod@redhat.com> - 0.9.4-4
- Nuke python-version-specific subpackages. Just use py3 if we can.
* Mon Dec 19 2016 Miro Hrončok <mhroncok@redhat.com> - 0.9.4-3
- Rebuild for Python 3.6
* Tue Jul 19 2016 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.9.4-2
- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages
* Tue Jul 05 2016 Ricky Elrod <relrod@redhat.com> - 0.9.4-1
- Update to latest upstream.
* Fri Jun 03 2016 Ricky Elrod <relrod@redhat.com> - 0.9.3-4
- Add proper Obsoletes for rhbz#1329226.
* Wed Feb 03 2016 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.3-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
* Mon Jan 04 2016 Ralph Bean <rbean@redhat.com> - 0.9.3-2
- Modernize python macros and subpackaging.
- Move LICENSE to %%license macro.
- Make python3 the default on modern Fedora.
* Mon Jan 04 2016 Ralph Bean <rbean@redhat.com> - 0.9.3-1
- new version
* Tue Nov 10 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.9.2-3
- Rebuilt for https://fedoraproject.org/wiki/Changes/python3.5
* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.9.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
* Thu Mar 26 2015 Ricky Elrod <relrod@redhat.com> - 0.9.2-1
- Latest upstream release.
* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.8.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
* Wed May 28 2014 Kalev Lember <kalevlember@gmail.com> - 0.8.0-2
- Rebuilt for https://fedoraproject.org/wiki/Changes/Python_3.4
* Fri Jan 31 2014 Ricky Elrod <codeblock@fedoraproject.org> - 0.8.0-1
- Latest upstream release.
* Fri Oct 4 2013 Ricky Elrod <codeblock@fedoraproject.org> - 0.7.2-2
- Add in patch to work without having python-requests 2.0.0.
* Sat Sep 28 2013 Ricky Elrod <codeblock@fedoraproject.org> - 0.7.2-1
- Latest upstream release.
* Thu Sep 5 2013 Ricky Elrod <codeblock@fedoraproject.org> - 0.6.0-7
- Only try building the manpage on Fedora, since RHEL's help2man doesn't
have the --no-discard-stderr flag.
* Thu Sep 5 2013 Ricky Elrod <codeblock@fedoraproject.org> - 0.6.0-6
- Loosen the requirement on python-pygments.
* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.6.0-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
* Tue Jul 2 2013 Ricky Elrod <codeblock@fedoraproject.org> - 0.6.0-4
- python-requests 1.2.3 exists in rawhide now.
* Sun Jun 30 2013 Ricky Elrod <codeblock@fedoraproject.org> - 0.6.0-3
- Patch to use python-requests 1.1.0 for now.
* Sat Jun 29 2013 Ricky Elrod <codeblock@fedoraproject.org> - 0.6.0-2
- Update to latest upstream release.
* Mon Apr 29 2013 Ricky Elrod <codeblock@fedoraproject.org> - 0.5.0-2
- Fix changelog messup.
* Mon Apr 29 2013 Ricky Elrod <codeblock@fedoraproject.org> - 0.5.0-1
- Update to latest upstream release.
* Mon Apr 8 2013 Ricky Elrod <codeblock@fedoraproject.org> - 0.4.1-3
- Fix manpage generation by exporting PYTHONPATH.
* Tue Mar 26 2013 Ricky Elrod <codeblock@fedoraproject.org> - 0.4.1-2
- Include Python3 support, and fix other review blockers.
* Mon Mar 11 2013 Ricky Elrod <codeblock@fedoraproject.org> - 0.4.1-1
- Update to latest upstream release
* Thu Jul 19 2012 Ricky Elrod <codeblock@fedoraproject.org> - 0.2.5-1
- Initial build.

View File

@ -0,0 +1,6 @@
#!/bin/bash
set -xe
rm -f httpie.spec.txt
https --download src.fedoraproject.org/rpms/httpie/raw/rawhide/f/httpie.spec -o httpie.spec.txt

View File

@ -1,2 +0,0 @@
DIST httpie-2.4.0.tar.gz 1772537 BLAKE2B 111451cc7dc353d5b586554f98ac715a3198f03e74d261944a5f021d2dcc948455500800222b323d182a2a067d0549bda7c318ab3a6c934b9a9beec64aff2db2 SHA512 44cc7ff4fe0f3d8c53a7dd750465f6b56c36f5bbac06d22b760579bd60949039e82313845699669a659ec91adc69dbeac22c06ddd63af64e6f2e0edecf3e732a
DIST httpie-2.5.0.tar.gz 1105177 BLAKE2B 6e16868c81522d4e6d2fc0a4e093c190f18ced720b35217930865ae3f8e168193cc33dfecc13c5d310f52647d6e79d17b247f56e56e8586d633a2d9502be66a7 SHA512 f14aa23fea7578181b9bd6ededea04de9ddf0b2f697b23f76d2d96e2c17b95617318c711750bad6af550400dbc03732ab17fdf84e59d577f33f073e600a55330

View File

@ -1,78 +0,0 @@
# HTTPie on Gentoo
Welcome to the documentation about **packaging HTTPie for Gentoo**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on Gentoo, then you can find them on [that page](https://httpie.io/docs#gentoo).
- If you are looking for technical information about the HTTPie packaging on Gentoo, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Gentoo.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
## Overall process
Open a pull request to create `httpie-XXX.ebuild` and update `Manifest`.
- Here is how to calculate the size and checksum (replace `2.5.0` with the correct version):
```bash
# Download
$ wget https://github.com/httpie/httpie/archive/2.5.0.tar.gz
# Size
$ stat --printf="%s\n" 2.5.0.tar.gz
1105177
# Checksum
$ openssl dgst -blake2b512 2.5.0.tar.gz
BLAKE2b512(2.5.0.tar.gz)= 6e16868c81522d4e6d2fc0a4e093c190f18ced720b35217930865ae3f8e168193cc33dfecc13c5d310f52647d6e79d17b247f56e56e8586d633a2d9502be66a7
```
- The commit message must be `net-misc/httpie: version bump to XXX`.
- The commit must be signed-off (`git commit -s`).
## Hacking
Launch the docker image:
```bash
docker pull gentoo/stage3
docker run -it --rm gentoo/stage3
```
From inside the container:
```bash
# Install tools
emerge --sync
emerge pkgcheck repoman
# Go to the package location
cd /var/db/repos/gentoo/net-misc/httpie
# Retrieve the patch of the latest HTTPie version
# (only files that were modified since the previous release)
curl https://raw.githubusercontent.com/httpie/httpie/master/docs/packaging/linux-gentoo/httpie-XXX.ebuild \
-o httpie-XXX.ebuild
curl https://raw.githubusercontent.com/httpie/httpie/master/docs/packaging/linux-gentoo/Manifest \
-o Manifest
curl https://raw.githubusercontent.com/httpie/httpie/master/docs/packaging/linux-gentoo/metadata.xml \
-o metadata.xml
# Basic checks
repoman manifest
repoman full -d -x
pkgcheck scan
# Build and install the package
emerge --with-test-deps httpie-XXX.ebuild
# Run the tests suite
ebuild httpie-XXX.ebuild clean test
# And test it!
http --version
https --version
```

View File

@ -1,42 +0,0 @@
# Copyright 1999-2021 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
EAPI=7
DISTUTILS_USE_SETUPTOOLS=rdepend
PYTHON_COMPAT=( python3_{8,9,10} )
PYTHON_REQ_USE="ssl(+)"
inherit bash-completion-r1 distutils-r1
DESCRIPTION="Modern command line HTTP client"
HOMEPAGE="https://httpie.io/ https://pypi.org/project/httpie/"
SRC_URI="https://github.com/httpie/httpie/archive/${PV}.tar.gz -> ${P}.tar.gz"
LICENSE="BSD"
SLOT="0"
KEYWORDS="~amd64 ~x86"
RDEPEND="
dev-python/defusedxml[${PYTHON_USEDEP}]
dev-python/pygments[${PYTHON_USEDEP}]
>=dev-python/requests-2.22.0[${PYTHON_USEDEP}]
>=dev-python/requests-toolbelt-0.9.1[${PYTHON_USEDEP}]
"
BDEPEND="
test? (
${RDEPEND}
dev-python/pyopenssl[${PYTHON_USEDEP}]
dev-python/pytest-httpbin[${PYTHON_USEDEP}]
dev-python/responses[${PYTHON_USEDEP}]
)
"
distutils_enable_tests pytest
python_install_all() {
newbashcomp extras/httpie-completion.bash http
insinto /usr/share/fish/vendor_completions.d
newins extras/httpie-completion.fish http.fish
distutils-r1_python_install_all
}

View File

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE pkgmetadata SYSTEM "https://www.gentoo.org/dtd/metadata.dtd">
<pkgmetadata>
<maintainer type="person" proxied="yes">
<email>mickael@apible.io</email>
<name>Mickaël Schoentgen</name>
</maintainer>
<maintainer type="project" proxied="proxy">
<email>proxy-maint@gentoo.org</email>
<name>Proxy Maintainers</name>
</maintainer>
<longdescription lang="en">
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. It provides a simple http command
that allows for sending arbitrary HTTP requests using a simple
and natural syntax, and displays colorized output. HTTPie can be
used for testing, debugging, and generally interacting with HTTP
servers.
</longdescription>
<upstream>
<bugs-to>https://github.com/httpie/httpie/issues</bugs-to>
<changelog>https://raw.githubusercontent.com/httpie/httpie/master/CHANGELOG.md</changelog>
<doc>https://httpie.io/docs</doc>
<remote-id type="github">httpie/httpie</remote-id>
<remote-id type="pypi">httpie</remote-id>
</upstream>
</pkgmetadata>

View File

@ -1,68 +0,0 @@
# HTTPie on Void Linux
Welcome to the documentation about **packaging HTTPie for Void Linux**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on Void Linux, then you can find them on [that page](https://httpie.io/docs#void-linux).
- If you are looking for technical information about the HTTPie packaging on Void Linux, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Void Linux.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
## Overall process
Open a pull request to update the [downstream file](https://github.com/void-linux/void-packages/blob/master/srcpkgs/httpie/template) ([example](https://github.com/void-linux/void-packages/pull/32905)).
- The commit message must be `httpie: update to XXX.`.
- The commit must be signed-off (`git commit -s`).
## Hacking
Launch the docker image:
```bash
docker pull voidlinux/voidlinux
docker run -it --rm voidlinux/voidlinux
```
From inside the container:
```bash
# Sync and upgrade once, assume error comes from xbps update
xbps-install -Syu
# Install tools
xbps-install -y git xtools file util-linux binutils bsdtar coreutils
# Clone
git clone --depth=1 git://github.com/void-linux/void-packages.git void-packages-src
cd void-packages-src
# Retrieve the patch of the latest HTTPie version
curl https://raw.githubusercontent.com/httpie/httpie/master/docs/packaging/linux-void/template \
-o srcpkgs/httpie/template
# Check the package
xlint srcpkgs/httpie/template
# Link / to /masterdir
ln -s / masterdir
# Enable ethereal chroot-style
export XBPS_ALLOW_CHROOT_BREAKOUT=yes
./xbps-src binary-bootstrap
./xbps-src chroot
# Build the package
cd void-packages
export SOURCE_DATE_EPOCH=0
./xbps-src pkg httpie
# Install the package
xbps-install --repository=hostdir/binpkgs httpie
# And finally test it!
http --version
https --version
```

View File

@ -1,28 +0,0 @@
# Template file for 'httpie'
pkgname=httpie
version=2.5.0
revision=1
build_style=python3-module
hostmakedepends="python3-setuptools"
depends="python3-setuptools python3-requests python3-requests-toolbelt
python3-Pygments python3-pysocks python3-defusedxml"
short_desc="Human-friendly command line HTTP client"
maintainer="Mickaël Schoentgen <mickael@apible.io>"
license="BSD-3-Clause"
homepage="https://httpie.io/"
changelog="https://raw.githubusercontent.com/httpie/httpie/${version}/CHANGELOG.md"
distfiles="https://github.com/httpie/httpie/archive/${version}.tar.gz"
checksum=66af56e0efc1ca6237323f1186ba34bca1be24e67a4319fd5df7228ab986faea
make_check=no # needs pytest_httpbin which is not packaged
post_install() {
vcompletion extras/httpie-completion.bash bash http
vcompletion extras/httpie-completion.fish fish http
vlicense LICENSE
}
python3-httpie_package() {
build_style=meta
short_desc+=" (transitional dummy package)"
depends="httpie>=${version}_${revision}"
}

View File

@ -4,11 +4,11 @@ PortSystem 1.0
PortGroup github 1.0
PortGroup python 1.0
github.setup httpie httpie 2.5.0
github.setup httpie httpie 2.6.0
maintainers {g5pw @g5pw} openmaintainer
categories net
description HTTPie is a command line HTTP client, a user-friendly cURL replacement.
description Modern, user-friendly command-line HTTP client for the API era
long_description HTTPie (pronounced aych-tee-tee-pie) is a command line HTTP \
client. Its goal is to make CLI interaction with web \
services as human-friendly as possible. It provides a simple \
@ -20,17 +20,17 @@ platforms darwin
license BSD
homepage https://httpie.io/
variant python36 conflicts python37 python38 python39 description "Use Python 3.6" {}
variant python37 conflicts python36 python38 python39 description "Use Python 3.7" {}
variant python38 conflicts python36 python37 python39 description "Use Python 3.8" {}
variant python39 conflicts python36 python37 python38 description "Use Python 3.9" {}
variant python37 conflicts python36 python38 python39 python310 description "Use Python 3.7" {}
variant python38 conflicts python36 python37 python39 python310 description "Use Python 3.8" {}
variant python39 conflicts python36 python37 python38 python310 description "Use Python 3.9" {}
variant python310 conflicts python36 python37 python38 python39 description "Use Python 3.10" {}
if {[variant_isset python36]} {
python.default_version 36
} elseif {[variant_isset python37]} {
if {[variant_isset python37]} {
python.default_version 37
} elseif {[variant_isset python39]} {
python.default_version 39
} elseif {[variant_isset python310]} {
python.default_version 310
} else {
default_variants +python38
python.default_version 38
@ -40,10 +40,11 @@ depends_lib-append port:py${python.version}-requests \
port:py${python.version}-requests-toolbelt \
port:py${python.version}-pygments \
port:py${python.version}-socks \
port:py${python.version}-charset-normalizer \
port:py${python.version}-defusedxml
checksums rmd160 88d227d52199c232c0ddf704a219d1781b1e77ee \
sha256 00c4b7bbe7f65abe1473f37b39d9d9f8f53f44069a430ad143a404c01c2179fc \
size 1105185
checksums rmd160 07b1d1592da1c505ed3ee4ef3b6056215e16e9ff \
sha256 63cf104bf3552305c68a74f16494a90172b15296610a875e17918e5e36373c0b \
size 1133491
python.link_binaries_suffix

View File

@ -13,13 +13,13 @@ We will discuss setting up the environment, installing development tools, instal
## Overall process
Open a pull request to update the [downstream file](https://github.com/macports/macports-ports/blob/master/net/httpie/Portfile) ([example](https://github.com/macports/macports-ports/pull/12167)).
Open a pull request to update the [downstream file](https://github.com/macports/macports-ports/blob/master/net/httpie/Portfile) ([example](https://github.com/macports/macports-ports/pull/12583)).
- Here is how to calculate the size and checksums (replace `2.5.0` with the correct version):
```bash
# Download the archive
$ wget https://api.github.com/repos/httpie/httpie/tarball/2.5.0
$ wget https://api.github.com/repos/httpie/cli/tarball/2.5.0
# Size
$ stat --printf="%s\n" 2.5.0

View File

@ -13,7 +13,16 @@ We will discuss setting up the environment, installing development tools, instal
## Overall process
Trigger a new [build](https://snapcraft.io/httpie/builds), then [promote it](https://snapcraft.io/httpie/releases). If more management is needed: [revisions supervision](https://dashboard.snapcraft.io/snaps/httpie/revisions/).
Trigger the [`Release on Snap`](https://github.com/httpie/cli/actions/workflows/release-snap.yml) action, which will
create a snap package for HTTPie and then push it to Snap Store in the following channels:
- Edge
- Beta
- Candidate
- Stable
If a push to any of them fail, all the release tasks for the following channels will be cancelled so that the
release manager can look into the underlying cause.
## Hacking
@ -28,7 +37,7 @@ From inside the container:
```bash
# Clone
git clone --depth=1 https://github.com/httpie/httpie.git
git clone --depth=1 https://github.com/httpie/cli.git
cd httpie
# Build

View File

@ -1,54 +0,0 @@
# HTTPie on Spack
Welcome to the documentation about **packaging HTTPie for Spack**.
- If you do not know HTTPie, have a look [here](https://httpie.io/cli).
- If you are looking for HTTPie installation or upgrade instructions on Spack, then you can find them on [that page](https://httpie.io/docs#spack-linux) ([that one](https://httpie.io/docs#spack-macos) for macOS).
- If you are looking for technical information about the HTTPie packaging on Spack, then you are in a good place.
## About
This document contains technical details, where we describe how to create a patch for the latest HTTPie version for Spack. They apply to Spack on Linux, and macOS.
We will discuss setting up the environment, installing development tools, installing and testing changes before submitting a patch downstream.
## Overall process
Open a pull request to update the [downstream file](https://github.com/spack/spack/blob/develop/var/spack/repos/builtin/packages/httpie/package.py) ([example](https://github.com/spack/spack/pull/25888)).
- The commit message must be `httpie: add vXXX`.
- The commit must be signed-off (`git commit -s`).
## Hacking
Launch the docker image:
```bash
docker pull spack/centos7
docker run -it --rm spack/centos7
```
From inside the container:
```bash
# Clone
git clone --depth=1 https://github.com/spack/spack.git
cd spack
# Retrieve the patch of the latest HTTPie version
curl https://raw.githubusercontent.com/httpie/httpie/master/docs/packaging/spack/package.py \
-o var/spack/repos/builtin/packages/httpie/package.py
# Check the package
spack spec httpie
# Check available versions (it should show the new version)
spack versions httpie
# Install the package
spack install httpie@XXX
spack load httpie
# And test it!
http --version
https --version
```

View File

@ -1,32 +0,0 @@
# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from spack import *
class Httpie(PythonPackage):
"""Modern command line HTTP client."""
homepage = "https://httpie.io/"
pypi = "httpie/httpie-2.5.0.tar.gz"
version('2.5.0', sha256='fe6a8bc50fb0635a84ebe1296a732e39357c3e1354541bf51a7057b4877e47f9')
version('0.9.9', sha256='f1202e6fa60367e2265284a53f35bfa5917119592c2ab08277efc7fffd744fcb')
version('0.9.8', sha256='515870b15231530f56fe2164190581748e8799b66ef0fe36ec9da3396f0df6e1')
variant('socks', default=True,
description='Enable SOCKS proxy support')
depends_on('py-setuptools', type=('build', 'run'))
depends_on('py-defusedxml', type=('build', 'run'))
depends_on('py-pygments', type=('build', 'run'))
depends_on('py-requests', type=('build', 'run'))
depends_on('py-requests-toolbelt', type=('build', 'run'))
depends_on('py-pysocks', type=('build', 'run'), when="+socks")
# Concretization problem breaks this. Unconditional for now...
# https://github.com/spack/spack/issues/3628
# depends_on('py-argparse@1.2.1:', type=('build', 'run'),
# when='^python@:2.6,3.0:3.1')
depends_on('py-argparse@1.2.1:', type=('build', 'run'), when='^python@:2.6')

View File

@ -13,18 +13,23 @@ We will discuss setting up the environment, installing development tools, instal
## Overall process
After having successfully [built and tested](#hacking) the package, push it:
After having successfully [built and tested](#hacking) the package, either trigger the
[`Release on Chocolatey`](https://github.com/httpie/cli/actions/workflows/release-choco.yml) action
to push it to the `Chocolatey` store or use the CLI:
```bash
# Replace 2.5.0 with the correct version
choco push httpie.2.5.0.nupkg -s https://push.chocolatey.org/ --api-key=API_KEY
```
Be aware that it might take multiple days until the release is approved, sine it goes through multiple
sets of reviews (some of them are done manually).
## Hacking
```bash
# Clone
git clone --depth=1 https://github.com/httpie/httpie.git
git clone --depth=1 https://github.com/httpie/cli.git
cd httpie/docs/packaging/windows-chocolatey
# Build

View File

@ -2,8 +2,8 @@
<package xmlns="http://schemas.microsoft.com/packaging/2015/06/nuspec.xsd">
<metadata>
<id>httpie</id>
<version>2.5.0</version>
<summary>Modern, user-friendly command-line HTTP client for the API era.</summary>
<version>3.2.2</version>
<summary>Modern, user-friendly command-line HTTP client for the API era</summary>
<description>
HTTPie *aitch-tee-tee-pie* is a user-friendly command-line HTTP client for the API era.
It comes with JSON support, syntax highlighting, persistent sessions, wget-like downloads, plugins, and more.
@ -28,20 +28,20 @@ Main features:
</description>
<title>HTTPie</title>
<authors>HTTPie</authors>
<owners>Tiger-222</owners>
<copyright>2012-2021 Jakub Roztocil</copyright>
<licenseUrl>https://raw.githubusercontent.com/httpie/httpie/master/LICENSE</licenseUrl>
<owners>jakubroztocil</owners>
<copyright>2012-2022 Jakub Roztocil</copyright>
<licenseUrl>https://raw.githubusercontent.com/httpie/cli/master/LICENSE</licenseUrl>
<iconUrl>https://pie-assets.s3.eu-central-1.amazonaws.com/LogoIcons/GB.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<releaseNotes>See the [changelog](https://github.com/httpie/httpie/blob/2.5.0/CHANGELOG.md).</releaseNotes>
<releaseNotes>See the [changelog](https://github.com/httpie/cli/releases/tag/3.2.2).</releaseNotes>
<tags>httpie http https rest api client curl python ssl cli foss oss url</tags>
<projectUrl>https://httpie.io</projectUrl>
<packageSourceUrl>https://github.com/httpie/httpie</packageSourceUrl>
<projectSourceUrl>https://github.com/httpie/httpie</projectSourceUrl>
<packageSourceUrl>https://github.com/httpie/cli/tree/master/docs/packaging/windows-chocolatey</packageSourceUrl>
<projectSourceUrl>https://github.com/httpie/cli</projectSourceUrl>
<docsUrl>https://httpie.io/docs</docsUrl>
<bugTrackerUrl>https://github.com/httpie/httpie/issues</bugTrackerUrl>
<bugTrackerUrl>https://github.com/httpie/cli/issues</bugTrackerUrl>
<dependencies>
<dependency id="python3" version="3.6" />
<dependency id="python3" version="3.7" />
</dependencies>
</metadata>
<files>

View File

@ -1,6 +1,2 @@
$ErrorActionPreference = 'Stop';
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
$nuspecPath = "$(Join-Path (Split-Path -parent $toolsDir) ($env:ChocolateyPackageName + ".nuspec"))"
[XML]$nuspec = Get-Content $nuspecPath
$pipVersion = $nuspec.package.metadata.version
py -m pip install "$($env:ChocolateyPackageName)==$($pipVersion)" --disable-pip-version-check
py -m pip install $env:ChocolateyPackageName==$env:ChocolateyPackageVersion --disable-pip-version-check

BIN
docs/stardust.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@ -7,7 +7,7 @@ _http_complete() {
fi
}
complete -o default -F _http_complete http
complete -o default -F _http_complete http httpie.http httpie.https https
_http_complete_options() {
local cur_word=$1

View File

@ -1,52 +1,24 @@
function __fish_httpie_styles
echo "
abap
algol
algol_nu
arduino
auto
autumn
borland
bw
colorful
default
emacs
friendly
fruity
gruvbox-dark
gruvbox-light
igor
inkpot
lovelace
manni
material
monokai
murphy
native
paraiso-dark
paraiso-light
pastie
perldoc
rainbow_dash
rrt
sas
solarized
solarized-dark
solarized-light
stata
stata-dark
stata-light
tango
trac
vim
vs
xcode
zenburn"
printf '%s\n' abap algol algol_nu arduino auto autumn borland bw colorful default emacs friendly fruity gruvbox-dark gruvbox-light igor inkpot lovelace manni material monokai murphy native paraiso-dark paraiso-light pastie perldoc pie pie-dark pie-light rainbow_dash rrt sas solarized solarized-dark solarized-light stata stata-dark stata-light tango trac vim vs xcode zenburn
end
function __fish_httpie_mime_types
test -r /usr/share/mime/types && cat /usr/share/mime/types
end
function __fish_httpie_print_args
set -l arg (commandline -t)
string match -qe H "$arg" || echo -e $arg"H\trequest headers"
string match -qe B "$arg" || echo -e $arg"B\trequest body"
string match -qe h "$arg" || echo -e $arg"h\tresponse headers"
string match -qe b "$arg" || echo -e $arg"b\tresponse body"
string match -qe m "$arg" || echo -e $arg"m\tresponse metadata"
end
function __fish_httpie_auth_types
echo -e "basic\tBasic HTTP auth"
echo -e "digest\tDigest HTTP auth"
echo -e "bearer\tBearer HTTP Auth"
end
function __fish_http_verify_options
@ -54,6 +26,7 @@ function __fish_http_verify_options
echo -e "no\tDisable cert verification"
end
# Predefined Content Types
complete -c http -s j -l json -d 'Data items are serialized as a JSON object'
@ -70,26 +43,28 @@ complete -c http -s x -l compress -d 'Content compressed with Deflate algorithm'
# Output Processing
complete -c http -l pretty -xa "all colors format none" -d 'Controls output processing'
complete -c http -s s -l style -xa "(__fish_httpie_styles)" -d 'Output coloring style'
complete -c http -l unsorted -d 'Disables all sorting while formatting output'
complete -c http -l sorted -d 'Re-enables all sorting options while formatting output'
complete -c http -l format-options -x -d 'Controls output formatting'
complete -c http -l pretty -xa "all colors format none" -d 'Controls output processing'
complete -c http -s s -l style -xa "(__fish_httpie_styles)" -d 'Output coloring style'
complete -c http -l unsorted -d 'Disables all sorting while formatting output'
complete -c http -l sorted -d 'Re-enables all sorting options while formatting output'
complete -c http -l response-charset -x -d 'Override the response encoding'
complete -c http -l response-mime -xa "(__fish_httpie_mime_types)" -d 'Override the response mime type for coloring and formatting'
complete -c http -l format-options -x -d 'Controls output formatting'
# Output Options
complete -c http -s p -l print -x -d 'String specifying what the output should contain'
complete -c http -s h -l headers -d 'Print only the response headers'
complete -c http -s b -l body -d 'Print only the response body'
complete -c http -s v -l verbose -d 'Print the whole request as well as the response'
complete -c http -l all -d 'Show any intermediary requests/responses'
complete -c http -s P -l history-print -x -d 'The same as --print but applies only to intermediary requests/responses'
complete -c http -s S -l stream -d 'Always stream the response body by line'
complete -c http -s o -l output -F -d 'Save output to FILE'
complete -c http -s d -l download -d 'Download a file'
complete -c http -s c -l continue -d 'Resume an interrupted download'
complete -c http -s q -l quiet -d 'Do not print to stdout or stderr'
complete -c http -s p -l print -xa "(__fish_httpie_print_args)" -d 'String specifying what the output should contain'
complete -c http -s h -l headers -d 'Print only the response headers'
complete -c http -s m -l meta -d 'Print only the response metadata'
complete -c http -s b -l body -d 'Print only the response body'
complete -c http -s v -l verbose -d 'Print the whole request as well as the response'
complete -c http -l all -d 'Show any intermediary requests/responses'
complete -c http -s S -l stream -d 'Always stream the response body by line'
complete -c http -s o -l output -F -d 'Save output to FILE'
complete -c http -s d -l download -d 'Download a file'
complete -c http -s c -l continue -d 'Resume an interrupted download'
complete -c http -s q -l quiet -d 'Do not print to stdout or stderr'
# Sessions
@ -115,22 +90,24 @@ complete -c http -l max-headers -x -d 'Maximum number of response headers
complete -c http -l timeout -x -d 'Connection timeout in seconds'
complete -c http -l check-status -d 'Error with non-200 HTTP status code'
complete -c http -l path-as-is -d 'Bypass dot segment URL squashing'
complete -c http -l chunked -d ''
complete -c http -l chunked -d 'Enable streaming via chunked transfer encoding'
# SSL
complete -c http -l verify -xa "(__fish_http_verify_options)" -d 'Enable/disable cert verification'
complete -c http -l ssl -x -d 'Desired protocol version to use'
complete -c http -l ciphers -x -d 'String in the OpenSSL cipher list format'
complete -c http -l cert -F -d 'Client side SSL certificate'
complete -c http -l cert-key -F -d 'Private key to use with SSL'
complete -c http -l verify -xa "(__fish_http_verify_options)" -d 'Enable/disable cert verification'
complete -c http -l ssl -x -d 'Desired protocol version to use'
complete -c http -l ciphers -x -d 'String in the OpenSSL cipher list format'
complete -c http -l cert -F -d 'Client side SSL certificate'
complete -c http -l cert-key -F -d 'Private key to use with SSL'
complete -c http -l cert-key-pass -x -d 'Passphrase for the given private key'
# Troubleshooting
complete -c http -s I -l ignore-stdin -d 'Do not attempt to read stdin'
complete -c http -l help -d 'Show help'
complete -c http -l manual -d 'Show the full manual'
complete -c http -l version -d 'Show version'
complete -c http -l traceback -d 'Prints exception traceback should one occur'
complete -c http -l default-scheme -x -d 'The default scheme to use'

600
extras/man/http.1 Normal file
View File

@ -0,0 +1,600 @@
.\" This file is auto-generated from the parser declaration in httpie/cli/definition.py by extras/scripts/generate_man_pages.py.
.TH http 1 "2022-05-06" "HTTPie 3.2.2" "HTTPie Manual"
.SH NAME
http
.SH SYNOPSIS
http [METHOD] URL [REQUEST_ITEM ...]
.SH DESCRIPTION
HTTPie: modern, user-friendly command-line HTTP client for the API era. <https://httpie.io>
.SH Positional arguments
These arguments come after any flags and in the order they are listed here.
Only URL is required.
.IP "\fB\,METHOD\/\fR"
The HTTP method to be used for the request (GET, POST, PUT, DELETE, ...).
This argument can be omitted in which case HTTPie will use POST if there
is some data to be sent, otherwise GET:
$ http example.org # => GET
$ http example.org hello=world # => POST
.IP "\fB\,URL\/\fR"
The request URL. Scheme defaults to \[aq]http://\[aq] if the URL
does not include one. (You can override this with: \fB\,--default-scheme\/\fR=http/https)
You can also use a shorthand for localhost
$ http :3000 # => http://localhost:3000
$ http :/foo # => http://localhost/foo
.IP "\fB\,REQUEST_ITEM\/\fR"
Optional key-value pairs to be included in the request. The separator used
determines the type:
\[aq]:\[aq] HTTP headers:
Referer:https://httpie.io Cookie:foo=bar User-Agent:bacon/1.0
\[aq]==\[aq] URL parameters to be appended to the request URI:
search==httpie
\[aq]=\[aq] Data fields to be serialized into a JSON object (with \fB\,--json\/\fR, \fB\,-j\/\fR)
or form data (with \fB\,--form\/\fR, \fB\,-f\/\fR):
name=HTTPie language=Python description=\[aq]CLI HTTP client\[aq]
\[aq]:=\[aq] Non-string JSON data fields (only with \fB\,--json\/\fR, \fB\,-j\/\fR):
awesome:=true amount:=42 colors:=\[aq][\[dq]red\[dq], \[dq]green\[dq], \[dq]blue\[dq]]\[aq]
\[aq]@\[aq] Form file fields (only with \fB\,--form\/\fR or \fB\,--multipart\/\fR):
cv@\(ti/Documents/CV.pdf
cv@\[aq]\(ti/Documents/CV.pdf;type=application/pdf\[aq]
\[aq]=@\[aq] A data field like \[aq]=\[aq], but takes a file path and embeds its content:
essay=@Documents/essay.txt
\[aq]:=@\[aq] A raw JSON field like \[aq]:=\[aq], but takes a file path and embeds its content:
package:=@./package.json
You can use a backslash to escape a colliding separator in the field name:
field-name-with\e:colon=value
.PP
.SH Predefined content types
.IP "\fB\,--json\/\fR, \fB\,-j\/\fR"
(default) Data items from the command line are serialized as a JSON object.
The Content-Type and Accept headers are set to application/json
(if not specified).
.IP "\fB\,--form\/\fR, \fB\,-f\/\fR"
Data items from the command line are serialized as form fields.
The Content-Type is set to application/x-www-form-urlencoded (if not
specified). The presence of any file fields results in a
multipart/form-data request.
.IP "\fB\,--multipart\/\fR"
Similar to \fB\,--form\/\fR, but always sends a multipart/form-data request (i.e., even without files).
.IP "\fB\,--boundary\/\fR"
Specify a custom boundary string for multipart/form-data requests. Only has effect only together with \fB\,--form\/\fR.
.IP "\fB\,--raw\/\fR"
This option allows you to pass raw request data without extra processing
(as opposed to the structured request items syntax):
$ http \fB\,--raw\/\fR=\[aq]data\[aq] pie.dev/post
You can achieve the same by piping the data via stdin:
$ echo data | http pie.dev/post
Or have HTTPie load the raw data from a file:
$ http pie.dev/post @data.txt
.PP
.SH Content processing options
.IP "\fB\,--compress\/\fR, \fB\,-x\/\fR"
Content compressed (encoded) with Deflate algorithm.
The Content-Encoding header is set to deflate.
Compression is skipped if it appears that compression ratio is
negative. Compression can be forced by repeating the argument.
.PP
.SH Output processing
.IP "\fB\,--pretty\/\fR"
Controls output processing. The value can be \[dq]none\[dq] to not prettify
the output (default for redirected output), \[dq]all\[dq] to apply both colors
and formatting (default for terminal output), \[dq]colors\[dq], or \[dq]format\[dq].
.IP "\fB\,--style\/\fR, \fB\,-s\/\fR \fI\,STYLE\/\fR"
Output coloring style (default is \[dq]auto\[dq]). It can be one of:
auto, pie, pie-dark, pie-light, solarized
For finding out all available styles in your system, try:
$ http \fB\,--style\/\fR
The \[dq]auto\[dq] style follows your terminal\[aq]s ANSI color styles.
For non-auto styles to work properly, please make sure that the
$TERM environment variable is set to \[dq]xterm-256color\[dq] or similar
(e.g., via `export TERM=xterm-256color\[aq] in your \(ti/.bashrc).
.IP "\fB\,--unsorted\/\fR"
Disables all sorting while formatting output. It is a shortcut for:
\fB\,--format-options\/\fR=headers.sort:false,json.sort_keys:false
.IP "\fB\,--sorted\/\fR"
Re-enables all sorting options while formatting output. It is a shortcut for:
\fB\,--format-options\/\fR=headers.sort:true,json.sort_keys:true
.IP "\fB\,--response-charset\/\fR \fI\,ENCODING\/\fR"
Override the response encoding for terminal display purposes, e.g.:
\fB\,--response-charset\/\fR=utf8
\fB\,--response-charset\/\fR=big5
.IP "\fB\,--response-mime\/\fR \fI\,MIME_TYPE\/\fR"
Override the response mime type for coloring and formatting for the terminal, e.g.:
\fB\,--response-mime\/\fR=application/json
\fB\,--response-mime\/\fR=text/xml
.IP "\fB\,--format-options\/\fR"
Controls output formatting. Only relevant when formatting is enabled
through (explicit or implied) \fB\,--pretty\/\fR=all or \fB\,--pretty\/\fR=format.
The following are the default options:
headers.sort:true
json.format:true
json.indent:4
json.sort_keys:true
xml.format:true
xml.indent:2
You may use this option multiple times, as well as specify multiple
comma-separated options at the same time. For example, this modifies the
settings to disable the sorting of JSON keys, and sets the indent size to 2:
\fB\,--format-options\/\fR json.sort_keys:false,json.indent:2
This is something you will typically put into your config file.
.PP
.SH Output options
.IP "\fB\,--print\/\fR, \fB\,-p\/\fR \fI\,WHAT\/\fR"
String specifying what the output should contain:
\[aq]H\[aq] request headers
\[aq]B\[aq] request body
\[aq]h\[aq] response headers
\[aq]b\[aq] response body
\[aq]m\[aq] response metadata
The default behaviour is \[aq]hb\[aq] (i.e., the response
headers and body is printed), if standard output is not redirected.
If the output is piped to another program or to a file, then only the
response body is printed by default.
.IP "\fB\,--headers\/\fR, \fB\,-h\/\fR"
Print only the response headers. Shortcut for \fB\,--print\/\fR=h.
.IP "\fB\,--meta\/\fR, \fB\,-m\/\fR"
Print only the response metadata. Shortcut for \fB\,--print\/\fR=m.
.IP "\fB\,--body\/\fR, \fB\,-b\/\fR"
Print only the response body. Shortcut for \fB\,--print\/\fR=b.
.IP "\fB\,--verbose\/\fR, \fB\,-v\/\fR"
Verbose output. For the level one (with single `\fB\,-v\/\fR`/`\fB\,--verbose\/\fR`), print
the whole request as well as the response. Also print any intermediary
requests/responses (such as redirects). For the second level and higher,
print these as well as the response metadata.
Level one is a shortcut for: \fB\,--all\/\fR \fB\,--print\/\fR=BHbh
Level two is a shortcut for: \fB\,--all\/\fR \fB\,--print\/\fR=BHbhm
.IP "\fB\,--all\/\fR"
By default, only the final request/response is shown. Use this flag to show
any intermediary requests/responses as well. Intermediary requests include
followed redirects (with \fB\,--follow\/\fR), the first unauthorized request when
Digest auth is used (\fB\,--auth\/\fR=digest), etc.
.IP "\fB\,--stream\/\fR, \fB\,-S\/\fR"
Always stream the response body by line, i.e., behave like `tail \fB\,-f\/\fR\[aq].
Without \fB\,--stream\/\fR and with \fB\,--pretty\/\fR (either set or implied),
HTTPie fetches the whole response before it outputs the processed data.
Set this option when you want to continuously display a prettified
long-lived response, such as one from the Twitter streaming API.
It is useful also without \fB\,--pretty\/\fR: It ensures that the output is flushed
more often and in smaller chunks.
.IP "\fB\,--output\/\fR, \fB\,-o\/\fR \fI\,FILE\/\fR"
Save output to FILE instead of stdout. If \fB\,--download\/\fR is also set, then only
the response body is saved to FILE. Other parts of the HTTP exchange are
printed to stderr.
.IP "\fB\,--download\/\fR, \fB\,-d\/\fR"
Do not print the response body to stdout. Rather, download it and store it
in a file. The filename is guessed unless specified with \fB\,--output\/\fR
[filename]. This action is similar to the default behaviour of wget.
.IP "\fB\,--continue\/\fR, \fB\,-c\/\fR"
Resume an interrupted download. Note that the \fB\,--output\/\fR option needs to be
specified as well.
.IP "\fB\,--quiet\/\fR, \fB\,-q\/\fR"
Do not print to stdout or stderr, except for errors and warnings when provided once.
Provide twice to suppress warnings as well.
stdout is still redirected if \fB\,--output\/\fR is specified.
Flag doesn\[aq]t affect behaviour of download beyond not printing to terminal.
.PP
.SH Sessions
.IP "\fB\,--session\/\fR \fI\,SESSION_NAME_OR_PATH\/\fR"
Create, or reuse and update a session. Within a session, custom headers,
auth credential, as well as any cookies sent by the server persist between
requests.
Session files are stored in:
[HTTPIE_CONFIG_DIR]/<HOST>/<SESSION_NAME>.json.
See the following page to find out your default HTTPIE_CONFIG_DIR:
https://httpie.io/docs/cli/config-file-directory
.IP "\fB\,--session-read-only\/\fR \fI\,SESSION_NAME_OR_PATH\/\fR"
Create or read a session without updating it form the request/response
exchange.
.PP
.SH Authentication
.IP "\fB\,--auth\/\fR, \fB\,-a\/\fR \fI\,USER[:PASS] | TOKEN\/\fR"
For username/password based authentication mechanisms (e.g
basic auth or digest auth) if only the username is provided
(\fB\,-a\/\fR username), HTTPie will prompt for the password.
.IP "\fB\,--auth-type\/\fR, \fB\,-A\/\fR"
The authentication mechanism to be used. Defaults to \[dq]basic\[dq].
\[dq]basic\[dq]: Basic HTTP auth
\[dq]digest\[dq]: Digest HTTP auth
\[dq]bearer\[dq]: Bearer HTTP Auth
To see all available auth types on your system, including ones installed via plugins, run:
$ http \fB\,--auth-type\/\fR
.IP "\fB\,--ignore-netrc\/\fR"
Ignore credentials from .netrc.
.PP
.SH Network
.IP "\fB\,--offline\/\fR"
Build the request and print it but don\(gat actually send it.
.IP "\fB\,--proxy\/\fR \fI\,PROTOCOL:PROXY_URL\/\fR"
String mapping protocol to the URL of the proxy
(e.g. http:http://foo.bar:3128). You can specify multiple proxies with
different protocols. The environment variables $ALL_PROXY, $HTTP_PROXY,
and $HTTPS_proxy are supported as well.
.IP "\fB\,--follow\/\fR, \fB\,-F\/\fR"
Follow 30x Location redirects.
.IP "\fB\,--max-redirects\/\fR"
By default, requests have a limit of 30 redirects (works with \fB\,--follow\/\fR).
.IP "\fB\,--max-headers\/\fR"
The maximum number of response headers to be read before giving up (default 0, i.e., no limit).
.IP "\fB\,--timeout\/\fR \fI\,SECONDS\/\fR"
The connection timeout of the request in seconds.
The default value is 0, i.e., there is no timeout limit.
This is not a time limit on the entire response download;
rather, an error is reported if the server has not issued a response for
timeout seconds (more precisely, if no bytes have been received on
the underlying socket for timeout seconds).
.IP "\fB\,--check-status\/\fR"
By default, HTTPie exits with 0 when no network or other fatal errors
occur. This flag instructs HTTPie to also check the HTTP status code and
exit with an error if the status indicates one.
When the server replies with a 4xx (Client Error) or 5xx (Server Error)
status code, HTTPie exits with 4 or 5 respectively. If the response is a
3xx (Redirect) and \fB\,--follow\/\fR hasn\[aq]t been set, then the exit status is 3.
Also an error message is written to stderr if stdout is redirected.
.IP "\fB\,--path-as-is\/\fR"
Bypass dot segment (/../ or /./) URL squashing.
.IP "\fB\,--chunked\/\fR"
Enable streaming via chunked transfer encoding. The Transfer-Encoding header is set to chunked.
.PP
.SH SSL
.IP "\fB\,--verify\/\fR"
Set to \[dq]no\[dq] (or \[dq]false\[dq]) to skip checking the host\[aq]s SSL certificate.
Defaults to \[dq]yes\[dq] (\[dq]true\[dq]). You can also pass the path to a CA_BUNDLE file
for private certs. (Or you can set the REQUESTS_CA_BUNDLE environment
variable instead.)
.IP "\fB\,--ssl\/\fR"
The desired protocol version to use. This will default to
SSL v2.3 which will negotiate the highest protocol that both
the server and your installation of OpenSSL support. Available protocols
may vary depending on OpenSSL installation (only the supported ones
are shown here).
.IP "\fB\,--ciphers\/\fR"
A string in the OpenSSL cipher list format.
See `http \fB\,--help\/\fR` for the default ciphers list on you system.
.IP "\fB\,--cert\/\fR"
You can specify a local cert to use as client side SSL certificate.
This file may either contain both private key and certificate or you may
specify \fB\,--cert-key\/\fR separately.
.IP "\fB\,--cert-key\/\fR"
The private key to use with SSL. Only needed if \fB\,--cert\/\fR is given and the
certificate file does not contain the private key.
.IP "\fB\,--cert-key-pass\/\fR"
The passphrase to be used to with the given private key. Only needed if \fB\,--cert-key\/\fR
is given and the key file requires a passphrase.
If not provided, you\(gall be prompted interactively.
.PP
.SH Troubleshooting
.IP "\fB\,--ignore-stdin\/\fR, \fB\,-I\/\fR"
Do not attempt to read stdin
.IP "\fB\,--help\/\fR"
Show this help message and exit.
.IP "\fB\,--manual\/\fR"
Show the full manual.
.IP "\fB\,--version\/\fR"
Show version and exit.
.IP "\fB\,--traceback\/\fR"
Prints the exception traceback should one occur.
.IP "\fB\,--default-scheme\/\fR"
The default scheme to use if not specified in the URL.
.IP "\fB\,--debug\/\fR"
Prints the exception traceback should one occur, as well as other
information useful for debugging HTTPie itself and for reporting bugs.
.PP
.SH SEE ALSO
For every \fB\,--OPTION\/\fR there is also a \fB\,--no-OPTION\/\fR that reverts OPTION
to its default value.
Suggestions and bug reports are greatly appreciated:
https://github.com/httpie/cli/issues

100
extras/man/httpie.1 Normal file
View File

@ -0,0 +1,100 @@
.\" This file is auto-generated from the parser declaration in httpie/manager/cli.py by extras/scripts/generate_man_pages.py.
.TH httpie 1 "2022-05-06" "HTTPie 3.2.2" "HTTPie Manual"
.SH NAME
httpie
.SH SYNOPSIS
httpie
.SH DESCRIPTION
Managing interface for the HTTPie itself. <https://httpie.io/docs#manager>
Be aware that you might be looking for http/https commands for sending
HTTP requests. This command is only available for managing the HTTTPie
plugins and the configuration around it.
If you are looking for the man pages of http/https commands, try one of the following:
$ man http
$ man https
.SH httpie cli export-args
Export available options for the CLI
.IP "\fB\,-f\/\fR, \fB\,--format\/\fR"
Format to export in.
.PP
.SH httpie cli check-updates
Check for updates
.PP
.SH httpie cli sessions upgrade
Upgrade the given HTTPie session with the latest layout. A list of changes between different session versions can be found in the official documentation.
.IP "\fB\,HOSTNAME\/\fR"
The host this session belongs.
.IP "\fB\,SESSION_NAME_OR_PATH\/\fR"
The name or the path for the session that will be upgraded.
.IP "\fB\,--bind-cookies\/\fR"
Bind domainless cookies to the host that session belongs.
.PP
.SH httpie cli sessions upgrade-all
Upgrade all named sessions with the latest layout. A list of changes between different session versions can be found in the official documentation.
.IP "\fB\,--bind-cookies\/\fR"
Bind domainless cookies to the host that session belongs.
.PP
.SH httpie cli plugins install
Install the given targets from PyPI or from a local paths.
.IP "\fB\,TARGET\/\fR"
targets to install
.PP
.SH httpie cli plugins upgrade
Upgrade the given plugins
.IP "\fB\,TARGET\/\fR"
targets to upgrade
.PP
.SH httpie cli plugins uninstall
Uninstall the given HTTPie plugins.
.IP "\fB\,TARGET\/\fR"
targets to install
.PP
.SH httpie cli plugins list
List all installed HTTPie plugins.
.PP
.SH httpie plugins install
Install the given targets from PyPI or from a local paths.
.IP "\fB\,TARGET\/\fR"
targets to install
.PP
.SH httpie plugins upgrade
Upgrade the given plugins
.IP "\fB\,TARGET\/\fR"
targets to upgrade
.PP
.SH httpie plugins uninstall
Uninstall the given HTTPie plugins.
.IP "\fB\,TARGET\/\fR"
targets to install
.PP
.SH httpie plugins list
List all installed HTTPie plugins.
.PP

600
extras/man/https.1 Normal file
View File

@ -0,0 +1,600 @@
.\" This file is auto-generated from the parser declaration in httpie/cli/definition.py by extras/scripts/generate_man_pages.py.
.TH https 1 "2022-05-06" "HTTPie 3.2.2" "HTTPie Manual"
.SH NAME
https
.SH SYNOPSIS
https [METHOD] URL [REQUEST_ITEM ...]
.SH DESCRIPTION
HTTPie: modern, user-friendly command-line HTTP client for the API era. <https://httpie.io>
.SH Positional arguments
These arguments come after any flags and in the order they are listed here.
Only URL is required.
.IP "\fB\,METHOD\/\fR"
The HTTP method to be used for the request (GET, POST, PUT, DELETE, ...).
This argument can be omitted in which case HTTPie will use POST if there
is some data to be sent, otherwise GET:
$ http example.org # => GET
$ http example.org hello=world # => POST
.IP "\fB\,URL\/\fR"
The request URL. Scheme defaults to \[aq]http://\[aq] if the URL
does not include one. (You can override this with: \fB\,--default-scheme\/\fR=http/https)
You can also use a shorthand for localhost
$ http :3000 # => http://localhost:3000
$ http :/foo # => http://localhost/foo
.IP "\fB\,REQUEST_ITEM\/\fR"
Optional key-value pairs to be included in the request. The separator used
determines the type:
\[aq]:\[aq] HTTP headers:
Referer:https://httpie.io Cookie:foo=bar User-Agent:bacon/1.0
\[aq]==\[aq] URL parameters to be appended to the request URI:
search==httpie
\[aq]=\[aq] Data fields to be serialized into a JSON object (with \fB\,--json\/\fR, \fB\,-j\/\fR)
or form data (with \fB\,--form\/\fR, \fB\,-f\/\fR):
name=HTTPie language=Python description=\[aq]CLI HTTP client\[aq]
\[aq]:=\[aq] Non-string JSON data fields (only with \fB\,--json\/\fR, \fB\,-j\/\fR):
awesome:=true amount:=42 colors:=\[aq][\[dq]red\[dq], \[dq]green\[dq], \[dq]blue\[dq]]\[aq]
\[aq]@\[aq] Form file fields (only with \fB\,--form\/\fR or \fB\,--multipart\/\fR):
cv@\(ti/Documents/CV.pdf
cv@\[aq]\(ti/Documents/CV.pdf;type=application/pdf\[aq]
\[aq]=@\[aq] A data field like \[aq]=\[aq], but takes a file path and embeds its content:
essay=@Documents/essay.txt
\[aq]:=@\[aq] A raw JSON field like \[aq]:=\[aq], but takes a file path and embeds its content:
package:=@./package.json
You can use a backslash to escape a colliding separator in the field name:
field-name-with\e:colon=value
.PP
.SH Predefined content types
.IP "\fB\,--json\/\fR, \fB\,-j\/\fR"
(default) Data items from the command line are serialized as a JSON object.
The Content-Type and Accept headers are set to application/json
(if not specified).
.IP "\fB\,--form\/\fR, \fB\,-f\/\fR"
Data items from the command line are serialized as form fields.
The Content-Type is set to application/x-www-form-urlencoded (if not
specified). The presence of any file fields results in a
multipart/form-data request.
.IP "\fB\,--multipart\/\fR"
Similar to \fB\,--form\/\fR, but always sends a multipart/form-data request (i.e., even without files).
.IP "\fB\,--boundary\/\fR"
Specify a custom boundary string for multipart/form-data requests. Only has effect only together with \fB\,--form\/\fR.
.IP "\fB\,--raw\/\fR"
This option allows you to pass raw request data without extra processing
(as opposed to the structured request items syntax):
$ http \fB\,--raw\/\fR=\[aq]data\[aq] pie.dev/post
You can achieve the same by piping the data via stdin:
$ echo data | http pie.dev/post
Or have HTTPie load the raw data from a file:
$ http pie.dev/post @data.txt
.PP
.SH Content processing options
.IP "\fB\,--compress\/\fR, \fB\,-x\/\fR"
Content compressed (encoded) with Deflate algorithm.
The Content-Encoding header is set to deflate.
Compression is skipped if it appears that compression ratio is
negative. Compression can be forced by repeating the argument.
.PP
.SH Output processing
.IP "\fB\,--pretty\/\fR"
Controls output processing. The value can be \[dq]none\[dq] to not prettify
the output (default for redirected output), \[dq]all\[dq] to apply both colors
and formatting (default for terminal output), \[dq]colors\[dq], or \[dq]format\[dq].
.IP "\fB\,--style\/\fR, \fB\,-s\/\fR \fI\,STYLE\/\fR"
Output coloring style (default is \[dq]auto\[dq]). It can be one of:
auto, pie, pie-dark, pie-light, solarized
For finding out all available styles in your system, try:
$ http \fB\,--style\/\fR
The \[dq]auto\[dq] style follows your terminal\[aq]s ANSI color styles.
For non-auto styles to work properly, please make sure that the
$TERM environment variable is set to \[dq]xterm-256color\[dq] or similar
(e.g., via `export TERM=xterm-256color\[aq] in your \(ti/.bashrc).
.IP "\fB\,--unsorted\/\fR"
Disables all sorting while formatting output. It is a shortcut for:
\fB\,--format-options\/\fR=headers.sort:false,json.sort_keys:false
.IP "\fB\,--sorted\/\fR"
Re-enables all sorting options while formatting output. It is a shortcut for:
\fB\,--format-options\/\fR=headers.sort:true,json.sort_keys:true
.IP "\fB\,--response-charset\/\fR \fI\,ENCODING\/\fR"
Override the response encoding for terminal display purposes, e.g.:
\fB\,--response-charset\/\fR=utf8
\fB\,--response-charset\/\fR=big5
.IP "\fB\,--response-mime\/\fR \fI\,MIME_TYPE\/\fR"
Override the response mime type for coloring and formatting for the terminal, e.g.:
\fB\,--response-mime\/\fR=application/json
\fB\,--response-mime\/\fR=text/xml
.IP "\fB\,--format-options\/\fR"
Controls output formatting. Only relevant when formatting is enabled
through (explicit or implied) \fB\,--pretty\/\fR=all or \fB\,--pretty\/\fR=format.
The following are the default options:
headers.sort:true
json.format:true
json.indent:4
json.sort_keys:true
xml.format:true
xml.indent:2
You may use this option multiple times, as well as specify multiple
comma-separated options at the same time. For example, this modifies the
settings to disable the sorting of JSON keys, and sets the indent size to 2:
\fB\,--format-options\/\fR json.sort_keys:false,json.indent:2
This is something you will typically put into your config file.
.PP
.SH Output options
.IP "\fB\,--print\/\fR, \fB\,-p\/\fR \fI\,WHAT\/\fR"
String specifying what the output should contain:
\[aq]H\[aq] request headers
\[aq]B\[aq] request body
\[aq]h\[aq] response headers
\[aq]b\[aq] response body
\[aq]m\[aq] response metadata
The default behaviour is \[aq]hb\[aq] (i.e., the response
headers and body is printed), if standard output is not redirected.
If the output is piped to another program or to a file, then only the
response body is printed by default.
.IP "\fB\,--headers\/\fR, \fB\,-h\/\fR"
Print only the response headers. Shortcut for \fB\,--print\/\fR=h.
.IP "\fB\,--meta\/\fR, \fB\,-m\/\fR"
Print only the response metadata. Shortcut for \fB\,--print\/\fR=m.
.IP "\fB\,--body\/\fR, \fB\,-b\/\fR"
Print only the response body. Shortcut for \fB\,--print\/\fR=b.
.IP "\fB\,--verbose\/\fR, \fB\,-v\/\fR"
Verbose output. For the level one (with single `\fB\,-v\/\fR`/`\fB\,--verbose\/\fR`), print
the whole request as well as the response. Also print any intermediary
requests/responses (such as redirects). For the second level and higher,
print these as well as the response metadata.
Level one is a shortcut for: \fB\,--all\/\fR \fB\,--print\/\fR=BHbh
Level two is a shortcut for: \fB\,--all\/\fR \fB\,--print\/\fR=BHbhm
.IP "\fB\,--all\/\fR"
By default, only the final request/response is shown. Use this flag to show
any intermediary requests/responses as well. Intermediary requests include
followed redirects (with \fB\,--follow\/\fR), the first unauthorized request when
Digest auth is used (\fB\,--auth\/\fR=digest), etc.
.IP "\fB\,--stream\/\fR, \fB\,-S\/\fR"
Always stream the response body by line, i.e., behave like `tail \fB\,-f\/\fR\[aq].
Without \fB\,--stream\/\fR and with \fB\,--pretty\/\fR (either set or implied),
HTTPie fetches the whole response before it outputs the processed data.
Set this option when you want to continuously display a prettified
long-lived response, such as one from the Twitter streaming API.
It is useful also without \fB\,--pretty\/\fR: It ensures that the output is flushed
more often and in smaller chunks.
.IP "\fB\,--output\/\fR, \fB\,-o\/\fR \fI\,FILE\/\fR"
Save output to FILE instead of stdout. If \fB\,--download\/\fR is also set, then only
the response body is saved to FILE. Other parts of the HTTP exchange are
printed to stderr.
.IP "\fB\,--download\/\fR, \fB\,-d\/\fR"
Do not print the response body to stdout. Rather, download it and store it
in a file. The filename is guessed unless specified with \fB\,--output\/\fR
[filename]. This action is similar to the default behaviour of wget.
.IP "\fB\,--continue\/\fR, \fB\,-c\/\fR"
Resume an interrupted download. Note that the \fB\,--output\/\fR option needs to be
specified as well.
.IP "\fB\,--quiet\/\fR, \fB\,-q\/\fR"
Do not print to stdout or stderr, except for errors and warnings when provided once.
Provide twice to suppress warnings as well.
stdout is still redirected if \fB\,--output\/\fR is specified.
Flag doesn\[aq]t affect behaviour of download beyond not printing to terminal.
.PP
.SH Sessions
.IP "\fB\,--session\/\fR \fI\,SESSION_NAME_OR_PATH\/\fR"
Create, or reuse and update a session. Within a session, custom headers,
auth credential, as well as any cookies sent by the server persist between
requests.
Session files are stored in:
[HTTPIE_CONFIG_DIR]/<HOST>/<SESSION_NAME>.json.
See the following page to find out your default HTTPIE_CONFIG_DIR:
https://httpie.io/docs/cli/config-file-directory
.IP "\fB\,--session-read-only\/\fR \fI\,SESSION_NAME_OR_PATH\/\fR"
Create or read a session without updating it form the request/response
exchange.
.PP
.SH Authentication
.IP "\fB\,--auth\/\fR, \fB\,-a\/\fR \fI\,USER[:PASS] | TOKEN\/\fR"
For username/password based authentication mechanisms (e.g
basic auth or digest auth) if only the username is provided
(\fB\,-a\/\fR username), HTTPie will prompt for the password.
.IP "\fB\,--auth-type\/\fR, \fB\,-A\/\fR"
The authentication mechanism to be used. Defaults to \[dq]basic\[dq].
\[dq]basic\[dq]: Basic HTTP auth
\[dq]digest\[dq]: Digest HTTP auth
\[dq]bearer\[dq]: Bearer HTTP Auth
To see all available auth types on your system, including ones installed via plugins, run:
$ http \fB\,--auth-type\/\fR
.IP "\fB\,--ignore-netrc\/\fR"
Ignore credentials from .netrc.
.PP
.SH Network
.IP "\fB\,--offline\/\fR"
Build the request and print it but don\(gat actually send it.
.IP "\fB\,--proxy\/\fR \fI\,PROTOCOL:PROXY_URL\/\fR"
String mapping protocol to the URL of the proxy
(e.g. http:http://foo.bar:3128). You can specify multiple proxies with
different protocols. The environment variables $ALL_PROXY, $HTTP_PROXY,
and $HTTPS_proxy are supported as well.
.IP "\fB\,--follow\/\fR, \fB\,-F\/\fR"
Follow 30x Location redirects.
.IP "\fB\,--max-redirects\/\fR"
By default, requests have a limit of 30 redirects (works with \fB\,--follow\/\fR).
.IP "\fB\,--max-headers\/\fR"
The maximum number of response headers to be read before giving up (default 0, i.e., no limit).
.IP "\fB\,--timeout\/\fR \fI\,SECONDS\/\fR"
The connection timeout of the request in seconds.
The default value is 0, i.e., there is no timeout limit.
This is not a time limit on the entire response download;
rather, an error is reported if the server has not issued a response for
timeout seconds (more precisely, if no bytes have been received on
the underlying socket for timeout seconds).
.IP "\fB\,--check-status\/\fR"
By default, HTTPie exits with 0 when no network or other fatal errors
occur. This flag instructs HTTPie to also check the HTTP status code and
exit with an error if the status indicates one.
When the server replies with a 4xx (Client Error) or 5xx (Server Error)
status code, HTTPie exits with 4 or 5 respectively. If the response is a
3xx (Redirect) and \fB\,--follow\/\fR hasn\[aq]t been set, then the exit status is 3.
Also an error message is written to stderr if stdout is redirected.
.IP "\fB\,--path-as-is\/\fR"
Bypass dot segment (/../ or /./) URL squashing.
.IP "\fB\,--chunked\/\fR"
Enable streaming via chunked transfer encoding. The Transfer-Encoding header is set to chunked.
.PP
.SH SSL
.IP "\fB\,--verify\/\fR"
Set to \[dq]no\[dq] (or \[dq]false\[dq]) to skip checking the host\[aq]s SSL certificate.
Defaults to \[dq]yes\[dq] (\[dq]true\[dq]). You can also pass the path to a CA_BUNDLE file
for private certs. (Or you can set the REQUESTS_CA_BUNDLE environment
variable instead.)
.IP "\fB\,--ssl\/\fR"
The desired protocol version to use. This will default to
SSL v2.3 which will negotiate the highest protocol that both
the server and your installation of OpenSSL support. Available protocols
may vary depending on OpenSSL installation (only the supported ones
are shown here).
.IP "\fB\,--ciphers\/\fR"
A string in the OpenSSL cipher list format.
See `http \fB\,--help\/\fR` for the default ciphers list on you system.
.IP "\fB\,--cert\/\fR"
You can specify a local cert to use as client side SSL certificate.
This file may either contain both private key and certificate or you may
specify \fB\,--cert-key\/\fR separately.
.IP "\fB\,--cert-key\/\fR"
The private key to use with SSL. Only needed if \fB\,--cert\/\fR is given and the
certificate file does not contain the private key.
.IP "\fB\,--cert-key-pass\/\fR"
The passphrase to be used to with the given private key. Only needed if \fB\,--cert-key\/\fR
is given and the key file requires a passphrase.
If not provided, you\(gall be prompted interactively.
.PP
.SH Troubleshooting
.IP "\fB\,--ignore-stdin\/\fR, \fB\,-I\/\fR"
Do not attempt to read stdin
.IP "\fB\,--help\/\fR"
Show this help message and exit.
.IP "\fB\,--manual\/\fR"
Show the full manual.
.IP "\fB\,--version\/\fR"
Show version and exit.
.IP "\fB\,--traceback\/\fR"
Prints the exception traceback should one occur.
.IP "\fB\,--default-scheme\/\fR"
The default scheme to use if not specified in the URL.
.IP "\fB\,--debug\/\fR"
Prints the exception traceback should one occur, as well as other
information useful for debugging HTTPie itself and for reporting bugs.
.PP
.SH SEE ALSO
For every \fB\,--OPTION\/\fR there is also a \fB\,--no-OPTION\/\fR that reverts OPTION
to its default value.
Suggestions and bug reports are greatly appreciated:
https://github.com/httpie/cli/issues

View File

@ -0,0 +1,33 @@
# Use the oldest (but still supported) Ubuntu as the base for PyInstaller
# packages. This will prevent stuff like glibc from conflicting.
FROM ubuntu:18.04
RUN apt-get update
RUN apt-get install -y software-properties-common binutils
RUN apt-get install -y ruby-dev
RUN gem install fpm
# Use deadsnakes for the latest Pythons (e.g 3.9)
RUN add-apt-repository ppa:deadsnakes/ppa
RUN apt-get update && apt-get install -y python3.9 python3.9-dev python3.9-venv
# Install rpm as well, since we are going to build fedora dists too
RUN apt-get install -y rpm
ADD . /app
WORKDIR /app/extras/packaging/linux
ENV VIRTUAL_ENV=/opt/venv
RUN python3.9 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
# Ensure that pip is renewed, otherwise we would be using distro-provided pip
# which strips vendored packages and doesn't work with PyInstaller.
RUN python -m pip install /app
RUN python -m pip install pyinstaller wheel
RUN python -m pip install --force-reinstall --upgrade pip
RUN echo 'BUILD_CHANNEL="pypi"' > /app/httpie/internal/__build_channel__.py
RUN python build.py
ENTRYPOINT ["mv", "/app/extras/packaging/linux/dist/", "/artifacts"]

View File

@ -0,0 +1,52 @@
# Standalone Linux Packages
![packaging.png](https://user-images.githubusercontent.com/47358913/159950478-2d090d1b-69b9-4914-a1b4-d3e3d8e25fe0.png)
This directory contains the build scripts for creating:
- A self-contained binary executable for the HTTPie itself
- `httpie.deb` and `httpie.rpm` packages for Debian and Fedora.
The process of constructing them are fully automated, and can be easily done through the [`Release as Standalone Linux Package`](https://github.com/httpie/cli/actions/workflows/release-linux-standalone.yml)
action. Once it finishes, the release artifacts will be attached in the summary page of the triggered run.
## Hacking
The main entry point for the package builder is the [`build.py`](https://github.com/httpie/cli/blob/master/extras/packaging/linux/build.py). It
contains 2 major methods:
- `build_binaries`, for the self-contained executables
- `build_packages`, for the OS-specific packages (which wrap the binaries)
### `build_binaries`
We use [PyInstaller](https://pyinstaller.readthedocs.io/en/stable/) for the binaries. Normally pyinstaller offers two different modes:
- Single directory (harder to distribute, low redundancy. Library files are shared across different executables)
- Single binary (easier to distribute, higher redundancy. Same libraries are statically linked to different executables, so higher total size)
Since our binary size (in total 20 MiBs) is not that big, we have decided to choose the single binary mode for the sake of easier distribution.
We also disable `UPX`, which is a runtime decompression method since it adds some startup cost.
### `build_packages`
We build our OS-specific packages with [FPM](https://github.com/jordansissel/fpm) which offers a really nice abstraction. We use the `dir` mode,
and package `http`, `https` and `httpie` commands. More can be added to the `files` option.
Since the `httpie` depends on having a pip executable, we explicitly depend on the system Python even though the core does not use it.
### Docker Image
This directory also contains a [docker image](https://github.com/httpie/cli/blob/master/extras/packaging/linux/Dockerfile) which helps
building our standalone binaries in an isolated environment with the lowest possible library versions. This is important, since even though
the executables are standalone they still depend on some main system C libraries (like `glibc`) so we need to create our executables inside
an environment with a very old (but not deprecated) glibc version. It makes us soundproof for all active Ubuntu/Debian versions.
It also contains the Python version we package our HTTPie with, so it is the place if you need to change it.
### `./get_release_artifacts.sh`
If you make a change in the `build.py`, run the following script to test it out. It will return multiple files under `artifacts/dist` which
then you can test out and ensure their quality (it is also the script that we use in our automation).

View File

@ -0,0 +1,109 @@
import stat
import subprocess
from pathlib import Path
from typing import Iterator, Tuple
BUILD_DIR = Path(__file__).parent
HTTPIE_DIR = BUILD_DIR.parent.parent.parent
EXTRAS_DIR = HTTPIE_DIR / 'extras'
MAN_PAGES_DIR = EXTRAS_DIR / 'man'
SCRIPT_DIR = BUILD_DIR / Path('scripts')
HOOKS_DIR = SCRIPT_DIR / 'hooks'
DIST_DIR = BUILD_DIR / 'dist'
TARGET_SCRIPTS = {
SCRIPT_DIR / 'http_cli.py': [],
SCRIPT_DIR / 'httpie_cli.py': ['--hidden-import=pip'],
}
def build_binaries() -> Iterator[Tuple[str, Path]]:
for target_script, extra_args in TARGET_SCRIPTS.items():
subprocess.check_call(
[
'pyinstaller',
'--onefile',
'--noupx',
'-p',
HTTPIE_DIR,
'--additional-hooks-dir',
HOOKS_DIR,
*extra_args,
target_script,
]
)
for executable_path in DIST_DIR.iterdir():
if executable_path.suffix:
continue
stat_r = executable_path.stat()
executable_path.chmod(stat_r.st_mode | stat.S_IEXEC)
yield executable_path.stem, executable_path
def build_packages(http_binary: Path, httpie_binary: Path) -> None:
import httpie
# Mapping of src_file -> dst_file
files = [
(http_binary, '/usr/bin/http'),
(http_binary, '/usr/bin/https'),
(httpie_binary, '/usr/bin/httpie'),
]
files.extend(
(man_page, f'/usr/share/man/man1/{man_page.name}')
for man_page in MAN_PAGES_DIR.glob('*.1')
)
# A list of additional dependencies
deps = [
'python3 >= 3.7',
'python3-pip'
]
processed_deps = [
f'--depends={dep}'
for dep in deps
]
processed_files = [
'='.join([str(src.resolve()), dst]) for src, dst in files
]
for target in ['deb', 'rpm']:
subprocess.check_call(
[
'fpm',
'--force',
'-s',
'dir',
'-t',
target,
'--name',
'httpie',
'--version',
httpie.__version__,
'--description',
httpie.__doc__.strip(),
'--license',
httpie.__licence__,
*processed_deps,
*processed_files,
],
cwd=DIST_DIR,
)
def main():
binaries = dict(build_binaries())
build_packages(binaries['http_cli'], binaries['httpie_cli'])
# Rename http_cli/httpie_cli to http/httpie
binaries['http_cli'].rename(DIST_DIR / 'http')
binaries['httpie_cli'].rename(DIST_DIR / 'httpie')
if __name__ == '__main__':
main()

View File

@ -0,0 +1,22 @@
#!/bin/bash
set -xe
REPO_ROOT=../../../
ARTIFACTS_DIR=$(pwd)/artifacts
# Reset the ARTIFACTS_DIR.
rm -rf $ARTIFACTS_DIR
mkdir -p $ARTIFACTS_DIR
# Operate on the repository root to have the proper
# docker context.
pushd $REPO_ROOT
# Build the PyInstaller image
docker build -t pyinstaller-httpie -f extras/packaging/linux/Dockerfile .
# Copy the artifacts to the designated directory.
docker run --rm -i -v $ARTIFACTS_DIR:/artifacts pyinstaller-httpie:latest
popd

View File

@ -0,0 +1,14 @@
from pathlib import Path
from PyInstaller.utils.hooks import collect_all
def hook(hook_api):
for pkg in [
'pip',
'setuptools',
'distutils',
'pkg_resources'
]:
datas, binaries, hiddenimports = collect_all(pkg)
hook_api.add_datas(datas)
hook_api.add_binaries(binaries)
hook_api.add_imports(*hiddenimports)

View File

@ -0,0 +1,5 @@
from httpie.__main__ import main
if __name__ == '__main__':
import sys
sys.exit(main())

View File

@ -0,0 +1,5 @@
from httpie.manager.__main__ import main
if __name__ == '__main__':
import sys
sys.exit(main())

View File

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

View File

@ -0,0 +1,202 @@
"""
This file is the declaration of benchmarks for HTTPie. It
is also used to run them with the current environment.
Each instance of BaseRunner class will be an individual
benchmark. And if run without any arguments, this file
will execute every benchmark instance and report the
timings.
The benchmarks are run through 'pyperf', which allows to
do get very precise results. For micro-benchmarks like startup,
please run `pyperf system tune` to get even more accurate results.
Examples:
# Run everything as usual, the default is that we do 3 warm-up runs
# and 5 actual runs.
$ python extras/profiling/benchmarks.py
# For retrieving results faster, pass --fast
$ python extras/profiling/benchmarks.py --fast
# For verify everything works as expected, pass --debug-single-value.
# It will only run everything once, so the resuls are not reliable. But
# very useful when iterating on a benchmark
$ python extras/profiling/benchmarks.py --debug-single-value
# If you want to run with a custom HTTPie command (for example with
# and HTTPie instance installed in another virtual environment),
# pass HTTPIE_COMMAND variable.
$ HTTPIE_COMMAND="/my/python /my/httpie" python extras/profiling/benchmarks.py
"""
from __future__ import annotations
import os
import shlex
import subprocess
import sys
import threading
from contextlib import ExitStack, contextmanager
from dataclasses import dataclass, field
from functools import cached_property, partial
from http.server import HTTPServer, SimpleHTTPRequestHandler
from tempfile import TemporaryDirectory
from typing import ClassVar, Final, List
import pyperf
# For download benchmarks, define a set of files.
# file: (block_size, count) => total_size = block_size * count
PREDEFINED_FILES: Final = {'3G': (3 * 1024 ** 2, 1024)}
class QuietSimpleHTTPServer(SimpleHTTPRequestHandler):
def log_message(self, *args, **kwargs):
pass
@contextmanager
def start_server():
"""Create a server to serve local files. It will create the
PREDEFINED_FILES through dd."""
with TemporaryDirectory() as directory:
for file_name, (block_size, count) in PREDEFINED_FILES.items():
subprocess.check_call(
[
'dd',
'if=/dev/zero',
f'of={file_name}',
f'bs={block_size}',
f'count={count}',
],
cwd=directory,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
handler = partial(QuietSimpleHTTPServer, directory=directory)
server = HTTPServer(('localhost', 0), handler)
thread = threading.Thread(target=server.serve_forever)
thread.start()
yield '{}:{}'.format(*server.socket.getsockname())
server.shutdown()
thread.join(timeout=0.5)
@dataclass
class Context:
benchmarks: ClassVar[List[BaseRunner]] = []
stack: ExitStack = field(default_factory=ExitStack)
runner: pyperf.Runner = field(default_factory=pyperf.Runner)
def run(self) -> pyperf.BenchmarkSuite:
results = [benchmark.run(self) for benchmark in self.benchmarks]
return pyperf.BenchmarkSuite(results)
@property
def cmd(self) -> List[str]:
if cmd := os.getenv('HTTPIE_COMMAND'):
return shlex.split(cmd)
http = os.path.join(os.path.dirname(sys.executable), 'http')
assert os.path.exists(http)
return [sys.executable, http]
@cached_property
def server(self) -> str:
return self.stack.enter_context(start_server())
def __enter__(self):
return self
def __exit__(self, *exc_info):
self.stack.close()
@dataclass
class BaseRunner:
"""
An individual benchmark case. By default it has the category
(e.g like startup or download) and a name.
"""
category: str
title: str
def __post_init__(self):
Context.benchmarks.append(self)
def run(self, context: Context) -> pyperf.Benchmark:
raise NotImplementedError
@property
def name(self) -> str:
return f'{self.title} ({self.category})'
@dataclass
class CommandRunner(BaseRunner):
"""
Run a single command, and benchmark it.
"""
args: List[str]
def run(self, context: Context) -> pyperf.Benchmark:
return context.runner.bench_command(self.name, [*context.cmd, *self.args])
@dataclass
class DownloadRunner(BaseRunner):
"""
Benchmark downloading a single file from the
remote server.
"""
file_name: str
def run(self, context: Context) -> pyperf.Benchmark:
return context.runner.bench_command(
self.name,
[
*context.cmd,
'--download',
'GET',
f'{context.server}/{self.file_name}',
],
)
CommandRunner('startup', '`http --version`', ['--version'])
CommandRunner('startup', '`http --offline pie.dev/get`', ['--offline', 'pie.dev/get'])
for pretty in ['all', 'none']:
CommandRunner(
'startup',
f'`http --pretty={pretty} pie.dev/stream/1000`',
[
'--print=HBhb',
f'--pretty={pretty}',
'httpbin.org/stream/1000'
]
)
DownloadRunner('download', '`http --download :/big_file.txt` (3GB)', '3G')
def main() -> None:
# PyPerf will bring it's own argument parser, so configure the script.
# The somewhat fast and also precise enough configuration is this. We run
# benchmarks 3 times to warm up (e.g especially for download benchmark, this
# is important). And then 5 actual runs where we record.
sys.argv.extend(
['--worker', '--loops=1', '--warmup=3', '--values=5', '--processes=2']
)
with Context() as context:
context.run()
if __name__ == '__main__':
main()

287
extras/profiling/run.py Normal file
View File

@ -0,0 +1,287 @@
"""
Run the HTTPie benchmark suite with multiple environments.
This script is configured in a way that, it will create
two (or more) isolated environments and compare the *last
commit* of this repository with it's master.
> If you didn't commit yet, it won't be showing results.
You can also pass --fresh, which would test the *last
commit* of this repository with a fresh copy of HTTPie
itself. This way even if you don't have an up-to-date
master branch, you can still compare it with the upstream's
master.
You can also pass --complex to add 2 additional environments,
which would include additional dependencies like pyOpenSSL.
Examples:
# Run everything as usual, and compare last commit with master
$ python extras/profiling/run.py
# Include complex environments
$ python extras/profiling/run.py --complex
# Compare against a fresh copy
$ python extras/profiling/run.py --fresh
# Compare against a custom branch of a custom repo
$ python extras/profiling/run.py --target-repo my_repo --target-branch my_branch
# Debug changes made on this script (only run benchmarks once)
$ python extras/profiling/run.py --debug
"""
import dataclasses
import shlex
import subprocess
import sys
import tempfile
import venv
from argparse import ArgumentParser, FileType
from contextlib import contextmanager
from dataclasses import dataclass
from pathlib import Path
from typing import (IO, Dict, Generator, Iterable, List, Optional,
Tuple)
BENCHMARK_SCRIPT = Path(__file__).parent / 'benchmarks.py'
CURRENT_REPO = Path(__file__).parent.parent.parent
GITHUB_URL = 'https://github.com/httpie/cli.git'
TARGET_BRANCH = 'master'
# Additional dependencies for --complex
ADDITIONAL_DEPS = ('pyOpenSSL',)
def call(*args, **kwargs):
kwargs.setdefault('stdout', subprocess.DEVNULL)
return subprocess.check_call(*args, **kwargs)
class Environment:
"""
Each environment defines how to create an isolated instance
where we could install HTTPie and run benchmarks without any
environmental factors.
"""
@contextmanager
def on_repo(self) -> Generator[Tuple[Path, Dict[str, str]], None, None]:
"""
Return the path to the python interpreter and the
environment variables (e.g HTTPIE_COMMAND) to be
used on the benchmarks.
"""
raise NotImplementedError
@dataclass
class HTTPieEnvironment(Environment):
repo_url: str
branch: Optional[str] = None
dependencies: Iterable[str] = ()
@contextmanager
def on_repo(self) -> Generator[Path, None, None]:
with tempfile.TemporaryDirectory() as directory_path:
directory = Path(directory_path)
# Clone the repo
repo_path = directory / 'httpie'
call(
['git', 'clone', self.repo_url, repo_path],
stderr=subprocess.DEVNULL,
)
if self.branch is not None:
call(
['git', 'checkout', self.branch],
cwd=repo_path,
stderr=subprocess.DEVNULL,
)
# Prepare the environment
venv_path = directory / '.venv'
venv.create(venv_path, with_pip=True)
# Install basic dependencies
python = venv_path / 'bin' / 'python'
call(
[
python,
'-m',
'pip',
'install',
'wheel',
'pyperf==2.3.0',
*self.dependencies,
]
)
# Create a wheel distribution of HTTPie
call([python, 'setup.py', 'bdist_wheel'], cwd=repo_path)
# Install httpie
distribution_path = next((repo_path / 'dist').iterdir())
call(
[python, '-m', 'pip', 'install', distribution_path],
cwd=repo_path,
)
http = venv_path / 'bin' / 'http'
yield python, {'HTTPIE_COMMAND': shlex.join([str(python), str(http)])}
@dataclass
class LocalCommandEnvironment(Environment):
local_command: str
@contextmanager
def on_repo(self) -> Generator[Path, None, None]:
yield sys.executable, {'HTTPIE_COMMAND': self.local_command}
def dump_results(
results: List[str],
file: IO[str],
min_speed: Optional[str] = None
) -> None:
for result in results:
lines = result.strip().splitlines()
if min_speed is not None and "hidden" in lines[-1]:
lines[-1] = (
'Some benchmarks were hidden from this list '
'because their timings did not change in a '
'significant way (change was within the error '
'margin ±{margin}%).'
).format(margin=min_speed)
result = '\n'.join(lines)
print(result, file=file)
print("\n---\n", file=file)
def compare(*args, directory: Path, min_speed: Optional[str] = None):
compare_args = ['pyperf', 'compare_to', '--table', '--table-format=md', *args]
if min_speed:
compare_args.extend(['--min-speed', min_speed])
return subprocess.check_output(
compare_args,
cwd=directory,
text=True,
)
def run(
configs: List[Dict[str, Environment]],
file: IO[str],
debug: bool = False,
min_speed: Optional[str] = None,
) -> None:
result_directory = Path(tempfile.mkdtemp())
results = []
current = 1
total = sum(1 for config in configs for _ in config.items())
def iterate(env_name, status):
print(
f'Iteration: {env_name} ({current}/{total}) ({status})' + ' ' * 10,
end='\r',
flush=True,
)
for config in configs:
for env_name, env in config.items():
iterate(env_name, 'setting up')
with env.on_repo() as (python, env_vars):
iterate(env_name, 'running benchmarks')
args = [python, BENCHMARK_SCRIPT, '-o', env_name]
if debug:
args.append('--debug-single-value')
call(
args,
cwd=result_directory,
env=env_vars,
)
current += 1
results.append(compare(
*config.keys(),
directory=result_directory,
min_speed=min_speed
))
dump_results(results, file=file, min_speed=min_speed)
print('Results are available at:', result_directory)
def main() -> None:
parser = ArgumentParser()
parser.add_argument('--local-repo', default=CURRENT_REPO)
parser.add_argument('--local-branch', default=None)
parser.add_argument('--target-repo', default=CURRENT_REPO)
parser.add_argument('--target-branch', default=TARGET_BRANCH)
parser.add_argument(
'--fresh',
action='store_const',
const=GITHUB_URL,
dest='target_repo',
help='Clone the target repo from upstream GitHub URL',
)
parser.add_argument(
'--complex',
action='store_true',
help='Add a second run, with a complex python environment.',
)
parser.add_argument(
'--local-bin',
help='Run the suite with the given local binary in addition to'
' existing runners. (E.g --local-bin $(command -v xh))',
)
parser.add_argument(
'--file',
type=FileType('w'),
default=sys.stdout,
help='File to print the actual results',
)
parser.add_argument(
'--min-speed',
help='Minimum of speed in percent to consider that a '
'benchmark is significant'
)
parser.add_argument(
'--debug',
action='store_true',
)
options = parser.parse_args()
configs = []
base_config = {
options.target_branch: HTTPieEnvironment(options.target_repo, options.target_branch),
'this_branch': HTTPieEnvironment(options.local_repo, options.local_branch),
}
configs.append(base_config)
if options.complex:
complex_config = {
env_name
+ '-complex': dataclasses.replace(env, dependencies=ADDITIONAL_DEPS)
for env_name, env in base_config.items()
}
configs.append(complex_config)
if options.local_bin:
base_config['binary'] = LocalCommandEnvironment(options.local_bin)
run(configs, file=options.file, debug=options.debug, min_speed=options.min_speed)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,188 @@
import os
import re
from contextlib import contextmanager
from pathlib import Path
from typing import Optional, Iterator, Iterable
# So that httpie.cli.definition can provide man-page-specific output. Must be set before importing httpie.
os.environ['HTTPIE_BUILDING_MAN_PAGES'] = '1'
import httpie
from httpie.cli.definition import options as core_options, IS_MAN_PAGE
from httpie.cli.options import ParserSpec
from httpie.manager.cli import options as manager_options
from httpie.output.ui.rich_help import OptionsHighlighter, to_usage
from httpie.output.ui.rich_utils import render_as_string
assert IS_MAN_PAGE, 'CLI definition does not understand were building man pages'
# Escape certain characters, so they are rendered properly on all terminals.
# <https://man7.org/linux/man-pages/man7/groff_char.7.html>
ESCAPE_MAP = {
'"': '\[dq]',
"'": '\[aq]',
'~': '\(ti',
'': "\(ga",
'\\': '\e',
}
ESCAPE_MAP = {ord(key): value for key, value in ESCAPE_MAP.items()}
EXTRAS_DIR = Path(__file__).parent.parent
MAN_PAGE_PATH = EXTRAS_DIR / 'man'
PROJECT_ROOT = EXTRAS_DIR.parent
OPTION_HIGHLIGHT_RE = re.compile(
OptionsHighlighter.highlights[0]
)
class ManPageBuilder:
def __init__(self):
self.source = []
def title_line(
self,
full_name: str,
program_name: str,
program_version: str,
last_edit_date: str,
) -> None:
self.source.append(
f'.TH {program_name} 1 "{last_edit_date}" '
f'"{full_name} {program_version}" "{full_name} Manual"'
)
def set_name(self, program_name: str) -> None:
with self.section('NAME'):
self.write(program_name)
def write(self, text: str, *, bold: bool = False) -> None:
if bold:
text = '.B ' + text
self.source.append(text)
def separate(self) -> None:
self.source.append('.PP')
def format_desc(self, desc: str) -> str:
description = _escape_and_dedent(desc)
description = OPTION_HIGHLIGHT_RE.sub(
# Boldify the option part, but don't remove the prefix (start of the match).
lambda match: match[1] + self.boldify(match['option']),
description
)
return description
def add_comment(self, comment: str) -> None:
self.source.append(f'.\\" {comment}')
def add_options(self, options: Iterable[str], *, metavar: Optional[str] = None) -> None:
text = ", ".join(map(self.boldify, options))
if metavar:
text += f' {self.underline(metavar)}'
self.write(f'.IP "{text}"')
def build(self) -> str:
return '\n'.join(self.source)
@contextmanager
def section(self, section_name: str) -> Iterator[None]:
self.write(f'.SH {section_name}')
self.in_section = True
yield
self.in_section = False
def underline(self, text: str) -> str:
return r'\fI\,{}\/\fR'.format(text)
def boldify(self, text: str) -> str:
return r'\fB\,{}\/\fR'.format(text)
def _escape_and_dedent(text: str) -> str:
lines = []
for should_act, line in enumerate(text.splitlines()):
# Only dedent after the first line.
if should_act:
if line.startswith(' '):
line = line[4:]
lines.append(line)
return '\n'.join(lines).translate(ESCAPE_MAP)
def to_man_page(program_name: str, spec: ParserSpec, *, is_top_level_cmd: bool = False) -> str:
builder = ManPageBuilder()
builder.add_comment(
f"This file is auto-generated from the parser declaration "
+ (f"in {Path(spec.source_file).relative_to(PROJECT_ROOT)} " if spec.source_file else "")
+ f"by {Path(__file__).relative_to(PROJECT_ROOT)}."
)
builder.title_line(
full_name='HTTPie',
program_name=program_name,
program_version=httpie.__version__,
last_edit_date=httpie.__date__,
)
builder.set_name(program_name)
with builder.section('SYNOPSIS'):
# `http` and `https` are commands that can be directly used, so they can have
# a valid usage. But `httpie` is a top-level command with multiple sub commands,
# so for the synopsis we'll only reference the `httpie` name.
if is_top_level_cmd:
synopsis = program_name
else:
synopsis = render_as_string(to_usage(spec, program_name=program_name))
builder.write(synopsis)
with builder.section('DESCRIPTION'):
builder.write(spec.description)
if spec.man_page_hint:
builder.write(spec.man_page_hint)
for index, group in enumerate(spec.groups, 1):
with builder.section(group.name):
if group.description:
builder.write(group.description)
for argument in group.arguments:
if argument.is_hidden:
continue
raw_arg = argument.serialize(isolation_mode=True)
metavar = raw_arg.get('metavar')
if raw_arg.get('is_positional'):
# In case of positional arguments, metavar is always equal
# to the list of options (e.g `METHOD`).
metavar = None
builder.add_options(raw_arg['options'], metavar=metavar)
desc = builder.format_desc(raw_arg.get('description', ''))
builder.write('\n' + desc + '\n')
builder.separate()
if spec.epilog:
with builder.section('SEE ALSO'):
builder.write(builder.format_desc(spec.epilog))
return builder.build()
def main() -> None:
for program_name, spec, config in [
('http', core_options, {}),
('https', core_options, {}),
('httpie', manager_options, {'is_top_level_cmd': True}),
]:
with open((MAN_PAGE_PATH / program_name).with_suffix('.1'), 'w') as stream:
stream.write(to_man_page(program_name, spec, **config))
if __name__ == '__main__':
main()

View File

@ -1,8 +1,9 @@
"""
HTTPie: command-line HTTP client for the API era.
HTTPie: modern, user-friendly command-line HTTP client for the API era.
"""
__version__ = '2.6.0.dev0'
__version__ = '3.2.2'
__date__ = '2022-05-06'
__author__ = 'Jakub Roztocil'
__licence__ = 'BSD'

13
httpie/adapters.py Normal file
View File

@ -0,0 +1,13 @@
from httpie.cli.dicts import HTTPHeadersDict
from requests.adapters import HTTPAdapter
class HTTPieHTTPAdapter(HTTPAdapter):
def build_response(self, req, resp):
"""Wrap the original headers with the `HTTPHeadersDict`
to preserve multiple headers that have the same name"""
response = super().build_response(req, resp)
response.headers = HTTPHeadersDict(getattr(resp, 'headers', {}))
return response

View File

@ -10,12 +10,13 @@ from urllib.parse import urlsplit
from requests.utils import get_netrc_auth
from .argtypes import (
AuthCredentials, KeyValueArgType, PARSED_DEFAULT_FORMAT_OPTIONS,
AuthCredentials, SSLCredentials, KeyValueArgType,
PARSED_DEFAULT_FORMAT_OPTIONS,
parse_auth,
parse_format_options,
)
from .constants import (
HTTP_GET, HTTP_POST, OUTPUT_OPTIONS, OUTPUT_OPTIONS_DEFAULT,
HTTP_GET, HTTP_POST, BASE_OUTPUT_OPTIONS, OUTPUT_OPTIONS, OUTPUT_OPTIONS_DEFAULT,
OUTPUT_OPTIONS_DEFAULT_OFFLINE, OUTPUT_OPTIONS_DEFAULT_STDOUT_REDIRECTED,
OUT_RESP_BODY, PRETTY_MAP, PRETTY_STDOUT_TTY_ONLY, RequestType,
SEPARATOR_CREDENTIALS,
@ -47,20 +48,39 @@ class HTTPieHelpFormatter(RawDescriptionHelpFormatter):
text = dedent(text).strip() + '\n\n'
return text.splitlines()
def add_usage(self, usage, actions, groups, prefix=None):
# Only display the positional arguments
displayed_actions = [
action
for action in actions
if not action.option_strings
]
_, exception, _ = sys.exc_info()
if (
isinstance(exception, argparse.ArgumentError)
and len(exception.args) >= 1
and isinstance(exception.args[0], argparse.Action)
):
# add_usage path is also taken when you pass an invalid option,
# e.g --style=invalid. If something like that happens, we want
# to include to action that caused to the invalid usage into
# the list of actions we are displaying.
displayed_actions.insert(0, exception.args[0])
super().add_usage(
usage,
displayed_actions,
groups,
prefix="usage:\n "
)
# TODO: refactor and design type-annotated data structures
# for raw args + parsed args and keep things immutable.
class HTTPieArgumentParser(argparse.ArgumentParser):
"""Adds additional logic to `argparse.ArgumentParser`.
Handles all input (CLI args, file args, stdin), applies defaults,
and performs extra validation.
"""
def __init__(self, *args, formatter_class=HTTPieHelpFormatter, **kwargs):
kwargs['add_help'] = False
super().__init__(*args, formatter_class=formatter_class, **kwargs)
class BaseHTTPieArgumentParser(argparse.ArgumentParser):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.env = None
self.args = None
self.has_stdin_data = False
@ -74,6 +94,68 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
namespace=None
) -> argparse.Namespace:
self.env = env
self.args, no_options = self.parse_known_args(args, namespace)
if self.args.debug:
self.args.traceback = True
self.has_stdin_data = (
self.env.stdin
and not getattr(self.args, 'ignore_stdin', False)
and not self.env.stdin_isatty
)
self.has_input_data = self.has_stdin_data or getattr(self.args, 'raw', None) is not None
return self.args
# noinspection PyShadowingBuiltins
def _print_message(self, message, file=None):
# Sneak in our stderr/stdout.
if hasattr(self, 'root'):
env = self.root.env
else:
env = self.env
if env is not None:
file = {
sys.stdout: env.stdout,
sys.stderr: env.stderr,
None: env.stderr
}.get(file, file)
if not hasattr(file, 'buffer') and isinstance(message, str):
message = message.encode(env.stdout_encoding)
super()._print_message(message, file)
class HTTPieManagerArgumentParser(BaseHTTPieArgumentParser):
def parse_known_args(self, args=None, namespace=None):
try:
return super().parse_known_args(args, namespace)
except SystemExit as exc:
if not hasattr(self, 'root') and exc.code == 2: # Argument Parser Error
raise argparse.ArgumentError(None, None)
raise
class HTTPieArgumentParser(BaseHTTPieArgumentParser):
"""Adds additional logic to `argparse.ArgumentParser`.
Handles all input (CLI args, file args, stdin), applies defaults,
and performs extra validation.
"""
def __init__(self, *args, formatter_class=HTTPieHelpFormatter, **kwargs):
kwargs.setdefault('add_help', False)
super().__init__(*args, formatter_class=formatter_class, **kwargs)
# noinspection PyMethodOverriding
def parse_args(
self,
env: Environment,
args=None,
namespace=None
) -> argparse.Namespace:
self.env = env
self.env.args = namespace = namespace or argparse.Namespace()
self.args, no_options = super().parse_known_args(args, namespace)
if self.args.debug:
self.args.traceback = True
@ -95,6 +177,7 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
self._parse_items()
self._process_url()
self._process_auth()
self._process_ssl_cert()
if self.args.raw is not None:
self._body_from_input(self.args.raw)
@ -120,6 +203,9 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
}
def _process_url(self):
if self.args.url.startswith('://'):
# Paste URL & add space shortcut: `http ://pie.dev` → `http://pie.dev`
self.args.url = self.args.url[3:]
if not URL_SCHEME_RE.match(self.args.url):
if os.path.basename(self.env.program_name) == 'https':
scheme = 'https://'
@ -138,18 +224,6 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
else:
self.args.url = scheme + self.args.url
# noinspection PyShadowingBuiltins
def _print_message(self, message, file=None):
# Sneak in our stderr/stdout.
file = {
sys.stdout: self.env.stdout,
sys.stderr: self.env.stderr,
None: self.env.stderr
}.get(file, file)
if not hasattr(file, 'buffer') and isinstance(message, str):
message = message.encode(self.env.stdout_encoding)
super()._print_message(message, file)
def _setup_standard_streams(self):
"""
Modify `env.stdout` and `env.stdout_isatty` based on args, if needed.
@ -186,9 +260,24 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
self.env.stdout_isatty = False
if self.args.quiet:
self.env.quiet = self.args.quiet
self.env.stderr = self.env.devnull
if not (self.args.output_file_specified and not self.args.download):
self.env.stdout = self.env.devnull
self.env.apply_warnings_filter()
def _process_ssl_cert(self):
from httpie.ssl_ import _is_key_file_encrypted
if self.args.cert_key_pass is None:
self.args.cert_key_pass = SSLCredentials(None)
if (
self.args.cert_key is not None
and self.args.cert_key_pass.value is None
and _is_key_file_encrypted(self.args.cert_key)
):
self.args.cert_key_pass.prompt_password(self.args.cert_key)
def _process_auth(self):
# TODO: refactor & simplify this method.
@ -252,6 +341,10 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
' --ignore-stdin is set.'
)
credentials.prompt_password(url.netloc)
if (credentials.key and credentials.value):
plugin.raw_auth = credentials.key + ":" + credentials.value
self.args.auth = plugin.get_auth(
username=credentials.key,
password=credentials.value,
@ -361,7 +454,7 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
try:
request_items = RequestItems.from_args(
request_item_args=self.args.request_items,
as_form=self.args.form,
request_type=self.args.request_type,
)
except ParseError as e:
if self.args.traceback:
@ -412,8 +505,10 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
self.args.all = True
if self.args.output_options is None:
if self.args.verbose:
if self.args.verbose >= 2:
self.args.output_options = ''.join(OUTPUT_OPTIONS)
elif self.args.verbose == 1:
self.args.output_options = ''.join(BASE_OUTPUT_OPTIONS)
elif self.args.offline:
self.args.output_options = OUTPUT_OPTIONS_DEFAULT_OFFLINE
elif not self.env.stdout_isatty:
@ -462,3 +557,57 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
for options_group in format_options:
parsed_options = parse_format_options(options_group, defaults=parsed_options)
self.args.format_options = parsed_options
def print_manual(self):
from httpie.output.ui import man_pages
if man_pages.is_available(self.env.program_name):
man_pages.display_for(self.env, self.env.program_name)
return None
text = self.format_help()
with self.env.rich_console.pager():
self.env.rich_console.print(
text,
highlight=False
)
def print_usage(self, file):
from rich.text import Text
from httpie.output.ui import rich_help
whitelist = set()
_, exception, _ = sys.exc_info()
if (
isinstance(exception, argparse.ArgumentError)
and len(exception.args) >= 1
and isinstance(exception.args[0], argparse.Action)
and exception.args[0].option_strings
):
# add_usage path is also taken when you pass an invalid option,
# e.g --style=invalid. If something like that happens, we want
# to include to action that caused to the invalid usage into
# the list of actions we are displaying.
whitelist.add(exception.args[0].option_strings[0])
usage_text = Text('usage', style='bold')
usage_text.append(':\n ')
usage_text.append(rich_help.to_usage(self.spec, whitelist=whitelist))
self.env.rich_error_console.print(usage_text)
def error(self, message):
"""Prints a usage message incorporating the message to stderr and
exits."""
self.print_usage(sys.stderr)
self.env.rich_error_console.print(
dedent(
f'''
[bold]error[/bold]:
{message}
[bold]for more information[/bold]:
run '{self.prog} --help' or visit https://httpie.io/docs/cli
'''.rstrip()
)
)
self.exit(2)

View File

@ -57,12 +57,12 @@ class KeyValueArgType:
def __init__(self, *separators: str):
self.separators = separators
self.special_characters = set('\\')
self.special_characters = set()
for separator in separators:
self.special_characters.update(separator)
def __call__(self, s: str) -> KeyValueArg:
"""Parse raw string arg and return `self.key_value_class` instance.
"""Parse raw string arg and return `self.key_value_class` instance.
The best of `self.separators` is determined (first found, longest).
Back slash escaped characters aren't considered as separators
@ -113,7 +113,7 @@ class KeyValueArgType:
There are only two token types - strings and escaped characters:
>>> KeyValueArgType('=').tokenize(r'foo\=bar\\baz')
['foo', Escaped('='), 'bar', Escaped('\\'), 'baz']
['foo', Escaped('='), 'bar\\\\baz']
"""
tokens = ['']
@ -130,16 +130,11 @@ class KeyValueArgType:
return tokens
class AuthCredentials(KeyValueArg):
"""Represents parsed credentials."""
def has_password(self) -> bool:
return self.value is not None
def prompt_password(self, host: str):
prompt_text = f'http: password for {self.key}@{host}: '
class PromptMixin:
def _prompt_password(self, prompt: str) -> str:
prompt_text = f'http: {prompt}: '
try:
self.value = self._getpass(prompt_text)
return self._getpass(prompt_text)
except (EOFError, KeyboardInterrupt):
sys.stderr.write('\n')
sys.exit(0)
@ -150,6 +145,26 @@ class AuthCredentials(KeyValueArg):
return getpass.getpass(str(prompt))
class SSLCredentials(PromptMixin):
"""Represents the passphrase for the certificate's key."""
def __init__(self, value: Optional[str]) -> None:
self.value = value
def prompt_password(self, key_file: str) -> None:
self.value = self._prompt_password(f'passphrase for {key_file}')
class AuthCredentials(KeyValueArg, PromptMixin):
"""Represents parsed credentials."""
def has_password(self) -> bool:
return self.value is not None
def prompt_password(self, host: str) -> None:
self.value = self._prompt_password(f'password for {self.key}@{host}:')
class AuthCredentialsArgType(KeyValueArgType):
"""A key-value arg type that parses credentials."""

View File

@ -9,12 +9,14 @@ URL_SCHEME_RE = re.compile(r'^[a-z][a-z0-9.+-]*://', re.IGNORECASE)
HTTP_POST = 'POST'
HTTP_GET = 'GET'
HTTP_OPTIONS = 'OPTIONS'
# Various separators used in args
SEPARATOR_HEADER = ':'
SEPARATOR_HEADER_EMPTY = ';'
SEPARATOR_CREDENTIALS = ':'
SEPARATOR_PROXY = ':'
SEPARATOR_HEADER_EMBED = ':@'
SEPARATOR_DATA_STRING = '='
SEPARATOR_DATA_RAW_JSON = ':='
SEPARATOR_FILE_UPLOAD = '@'
@ -22,6 +24,7 @@ SEPARATOR_FILE_UPLOAD_TYPE = ';type=' # in already parsed file upload path only
SEPARATOR_DATA_EMBED_FILE_CONTENTS = '=@'
SEPARATOR_DATA_EMBED_RAW_JSON_FILE = ':=@'
SEPARATOR_QUERY_PARAM = '=='
SEPARATOR_QUERY_EMBED_FILE = '==@'
# Separators that become request data
SEPARATOR_GROUP_DATA_ITEMS = frozenset({
@ -40,13 +43,17 @@ SEPARATORS_GROUP_MULTIPART = frozenset({
# Separators for items whose value is a filename to be embedded
SEPARATOR_GROUP_DATA_EMBED_ITEMS = frozenset({
SEPARATOR_HEADER_EMBED,
SEPARATOR_QUERY_EMBED_FILE,
SEPARATOR_DATA_EMBED_FILE_CONTENTS,
SEPARATOR_DATA_EMBED_RAW_JSON_FILE,
})
# Separators for raw JSON items
SEPARATOR_GROUP_RAW_JSON_ITEMS = frozenset([
# Separators for nested JSON items
SEPARATOR_GROUP_NESTED_JSON_ITEMS = frozenset([
SEPARATOR_DATA_STRING,
SEPARATOR_DATA_RAW_JSON,
SEPARATOR_DATA_EMBED_FILE_CONTENTS,
SEPARATOR_DATA_EMBED_RAW_JSON_FILE,
])
@ -54,7 +61,9 @@ SEPARATOR_GROUP_RAW_JSON_ITEMS = frozenset([
SEPARATOR_GROUP_ALL_ITEMS = frozenset({
SEPARATOR_HEADER,
SEPARATOR_HEADER_EMPTY,
SEPARATOR_HEADER_EMBED,
SEPARATOR_QUERY_PARAM,
SEPARATOR_QUERY_EMBED_FILE,
SEPARATOR_DATA_STRING,
SEPARATOR_DATA_RAW_JSON,
SEPARATOR_FILE_UPLOAD,
@ -67,22 +76,34 @@ OUT_REQ_HEAD = 'H'
OUT_REQ_BODY = 'B'
OUT_RESP_HEAD = 'h'
OUT_RESP_BODY = 'b'
OUT_RESP_META = 'm'
OUTPUT_OPTIONS = frozenset({
BASE_OUTPUT_OPTIONS = frozenset({
OUT_REQ_HEAD,
OUT_REQ_BODY,
OUT_RESP_HEAD,
OUT_RESP_BODY
OUT_RESP_BODY,
})
OUTPUT_OPTIONS = frozenset({
*BASE_OUTPUT_OPTIONS,
OUT_RESP_META,
})
# Pretty
class PrettyOptions(enum.Enum):
STDOUT_TTY_ONLY = enum.auto()
PRETTY_MAP = {
'all': ['format', 'colors'],
'colors': ['colors'],
'format': ['format'],
'none': []
}
PRETTY_STDOUT_TTY_ONLY = object()
PRETTY_STDOUT_TTY_ONLY = PrettyOptions.STDOUT_TTY_ONLY
DEFAULT_FORMAT_OPTIONS = [

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,51 @@
from collections import OrderedDict
from requests.structures import CaseInsensitiveDict
from multidict import MultiDict, CIMultiDict
class RequestHeadersDict(CaseInsensitiveDict):
class BaseMultiDict(MultiDict):
"""
Headers are case-insensitive and multiple values are currently not supported.
Base class for all MultiDicts.
"""
class HTTPHeadersDict(CIMultiDict, BaseMultiDict):
"""
Headers are case-insensitive and multiple values are supported
through the `add()` API.
"""
def add(self, key, value):
"""
Add or update a new header.
If the given `value` is `None`, then all the previous
values will be overwritten and the value will be set
to `None`.
"""
if value is None:
self[key] = value
return None
# If the previous value for the given header is `None`
# then discard it since we are explicitly giving a new
# value for it.
if key in self and self.getone(key) is None:
self.popone(key)
super().add(key, value)
def remove_item(self, key, value):
"""
Remove a (key, value) pair from the dict.
"""
existing_values = self.popall(key)
existing_values.remove(value)
for value in existing_values:
self.add(key, value)
class RequestJSONDataDict(OrderedDict):
pass

View File

@ -0,0 +1,20 @@
"""
A library for parsing the HTTPie nested JSON key syntax and constructing the resulting objects.
<https://httpie.io/docs/cli/nested-json>
It has no dependencies.
"""
from .interpret import interpret_nested_json, unwrap_top_level_list_if_needed
from .errors import NestedJSONSyntaxError
from .tokens import EMPTY_STRING, NestedJSONArray
__all__ = [
'interpret_nested_json',
'unwrap_top_level_list_if_needed',
'EMPTY_STRING',
'NestedJSONArray',
'NestedJSONSyntaxError'
]

View File

@ -0,0 +1,27 @@
from typing import Optional
from .tokens import Token, HIGHLIGHTER
class NestedJSONSyntaxError(ValueError):
def __init__(
self,
source: str,
token: Optional[Token],
message: str,
message_kind: str = 'Syntax',
) -> None:
self.source = source
self.token = token
self.message = message
self.message_kind = message_kind
def __str__(self):
lines = [f'HTTPie {self.message_kind} Error: {self.message}']
if self.token is not None:
lines.append(self.source)
lines.append(
' ' * self.token.start
+ HIGHLIGHTER * (self.token.end - self.token.start)
)
return '\n'.join(lines)

View File

@ -0,0 +1,129 @@
from typing import Type, Union, Any, Iterable, Tuple
from .parse import parse, assert_cant_happen
from .errors import NestedJSONSyntaxError
from .tokens import EMPTY_STRING, TokenKind, Token, PathAction, Path, NestedJSONArray
__all__ = [
'interpret_nested_json',
'unwrap_top_level_list_if_needed',
]
JSONType = Type[Union[dict, list, int, float, str]]
JSON_TYPE_MAPPING = {
dict: 'object',
list: 'array',
int: 'number',
float: 'number',
str: 'string',
}
def interpret_nested_json(pairs: Iterable[Tuple[str, str]]) -> dict:
context = None
for key, value in pairs:
context = interpret(context, key, value)
return wrap_with_dict(context)
def interpret(context: Any, key: str, value: Any) -> Any:
cursor = context
paths = list(parse(key))
paths.append(Path(PathAction.SET, value))
# noinspection PyShadowingNames
def type_check(index: int, path: Path, expected_type: JSONType):
if not isinstance(cursor, expected_type):
if path.tokens:
pseudo_token = Token(
kind=TokenKind.PSEUDO,
value='',
start=path.tokens[0].start,
end=path.tokens[-1].end,
)
else:
pseudo_token = None
cursor_type = JSON_TYPE_MAPPING.get(type(cursor), type(cursor).__name__)
required_type = JSON_TYPE_MAPPING[expected_type]
message = f'Cannot perform {path.kind.to_string()!r} based access on '
message += repr(''.join(path.reconstruct() for path in paths[:index]))
message += f' which has a type of {cursor_type!r} but this operation'
message += f' requires a type of {required_type!r}.'
raise NestedJSONSyntaxError(
source=key,
token=pseudo_token,
message=message,
message_kind='Type',
)
def object_for(kind: PathAction) -> Any:
if kind is PathAction.KEY:
return {}
elif kind in {PathAction.INDEX, PathAction.APPEND}:
return []
else:
assert_cant_happen()
for index, (path, next_path) in enumerate(zip(paths, paths[1:])):
# If there is no context yet, set it.
if cursor is None:
context = cursor = object_for(path.kind)
if path.kind is PathAction.KEY:
type_check(index, path, dict)
if next_path.kind is PathAction.SET:
cursor[path.accessor] = next_path.accessor
break
cursor = cursor.setdefault(path.accessor, object_for(next_path.kind))
elif path.kind is PathAction.INDEX:
type_check(index, path, list)
if path.accessor < 0:
raise NestedJSONSyntaxError(
source=key,
token=path.tokens[1],
message='Negative indexes are not supported.',
message_kind='Value',
)
cursor.extend([None] * (path.accessor - len(cursor) + 1))
if next_path.kind is PathAction.SET:
cursor[path.accessor] = next_path.accessor
break
if cursor[path.accessor] is None:
cursor[path.accessor] = object_for(next_path.kind)
cursor = cursor[path.accessor]
elif path.kind is PathAction.APPEND:
type_check(index, path, list)
if next_path.kind is PathAction.SET:
cursor.append(next_path.accessor)
break
cursor.append(object_for(next_path.kind))
cursor = cursor[-1]
else:
assert_cant_happen()
return context
def wrap_with_dict(context):
if context is None:
return {}
elif isinstance(context, list):
return {
EMPTY_STRING: NestedJSONArray(context),
}
else:
assert isinstance(context, dict)
return context
def unwrap_top_level_list_if_needed(data: dict):
"""
Propagate the top-level list, if thats what we got.
"""
if len(data) == 1:
key, value = list(data.items())[0]
if isinstance(value, NestedJSONArray):
assert key == EMPTY_STRING
return value
return data

View File

@ -0,0 +1,193 @@
from typing import Iterator
from .errors import NestedJSONSyntaxError
from .tokens import (
EMPTY_STRING,
BACKSLASH,
TokenKind,
OPERATORS,
SPECIAL_CHARS,
LITERAL_TOKENS,
Token,
PathAction,
Path,
)
__all__ = [
'parse',
'assert_cant_happen',
]
def parse(source: str) -> Iterator[Path]:
"""
start: root_path path*
root_path: (literal | index_path | append_path)
literal: TEXT | NUMBER
path:
key_path
| index_path
| append_path
key_path: LEFT_BRACKET TEXT RIGHT_BRACKET
index_path: LEFT_BRACKET NUMBER RIGHT_BRACKET
append_path: LEFT_BRACKET RIGHT_BRACKET
"""
tokens = list(tokenize(source))
cursor = 0
def can_advance():
return cursor < len(tokens)
# noinspection PyShadowingNames
def expect(*kinds):
nonlocal cursor
assert kinds
if can_advance():
token = tokens[cursor]
cursor += 1
if token.kind in kinds:
return token
elif tokens:
token = tokens[-1]._replace(
start=tokens[-1].end + 0,
end=tokens[-1].end + 1,
)
else:
token = None
if len(kinds) == 1:
suffix = kinds[0].to_name()
else:
suffix = ', '.join(kind.to_name() for kind in kinds[:-1])
suffix += ' or ' + kinds[-1].to_name()
message = f'Expecting {suffix}'
raise NestedJSONSyntaxError(source, token, message)
# noinspection PyShadowingNames
def parse_root():
tokens = []
if not can_advance():
return Path(
kind=PathAction.KEY,
accessor=EMPTY_STRING,
is_root=True
)
# (literal | index_path | append_path)?
token = expect(*LITERAL_TOKENS, TokenKind.LEFT_BRACKET)
tokens.append(token)
if token.kind in LITERAL_TOKENS:
action = PathAction.KEY
value = str(token.value)
elif token.kind is TokenKind.LEFT_BRACKET:
token = expect(TokenKind.NUMBER, TokenKind.RIGHT_BRACKET)
tokens.append(token)
if token.kind is TokenKind.NUMBER:
action = PathAction.INDEX
value = token.value
tokens.append(expect(TokenKind.RIGHT_BRACKET))
elif token.kind is TokenKind.RIGHT_BRACKET:
action = PathAction.APPEND
value = None
else:
assert_cant_happen()
else:
assert_cant_happen()
# noinspection PyUnboundLocalVariable
return Path(
kind=action,
accessor=value,
tokens=tokens,
is_root=True
)
yield parse_root()
# path*
while can_advance():
path_tokens = [expect(TokenKind.LEFT_BRACKET)]
token = expect(TokenKind.TEXT, TokenKind.NUMBER, TokenKind.RIGHT_BRACKET)
path_tokens.append(token)
if token.kind is TokenKind.RIGHT_BRACKET:
path = Path(PathAction.APPEND, tokens=path_tokens)
elif token.kind is TokenKind.TEXT:
path = Path(PathAction.KEY, token.value, tokens=path_tokens)
path_tokens.append(expect(TokenKind.RIGHT_BRACKET))
elif token.kind is TokenKind.NUMBER:
path = Path(PathAction.INDEX, token.value, tokens=path_tokens)
path_tokens.append(expect(TokenKind.RIGHT_BRACKET))
else:
assert_cant_happen()
# noinspection PyUnboundLocalVariable
yield path
def tokenize(source: str) -> Iterator[Token]:
cursor = 0
backslashes = 0
buffer = []
def send_buffer() -> Iterator[Token]:
nonlocal backslashes
if not buffer:
return None
value = ''.join(buffer)
kind = TokenKind.TEXT
if not backslashes:
for variation, kind in [
(int, TokenKind.NUMBER),
(check_escaped_int, TokenKind.TEXT),
]:
try:
value = variation(value)
except ValueError:
continue
else:
break
yield Token(
kind=kind,
value=value,
start=cursor - (len(buffer) + backslashes),
end=cursor,
)
buffer.clear()
backslashes = 0
def can_advance() -> bool:
return cursor < len(source)
while can_advance():
index = source[cursor]
if index in OPERATORS:
yield from send_buffer()
yield Token(OPERATORS[index], index, cursor, cursor + 1)
elif index == BACKSLASH and can_advance():
if source[cursor + 1] in SPECIAL_CHARS:
backslashes += 1
else:
buffer.append(index)
buffer.append(source[cursor + 1])
cursor += 1
else:
buffer.append(index)
cursor += 1
yield from send_buffer()
def check_escaped_int(value: str) -> str:
if not value.startswith(BACKSLASH):
raise ValueError('Not an escaped int')
try:
int(value[1:])
except ValueError as exc:
raise ValueError('Not an escaped int') from exc
else:
return value[1:]
def assert_cant_happen():
raise ValueError('Unexpected value')

View File

@ -0,0 +1,80 @@
from enum import Enum, auto
from typing import NamedTuple, Union, Optional, List
EMPTY_STRING = ''
HIGHLIGHTER = '^'
OPEN_BRACKET = '['
CLOSE_BRACKET = ']'
BACKSLASH = '\\'
class TokenKind(Enum):
TEXT = auto()
NUMBER = auto()
LEFT_BRACKET = auto()
RIGHT_BRACKET = auto()
PSEUDO = auto() # Not a real token, use when representing location only.
def to_name(self) -> str:
for key, value in OPERATORS.items():
if value is self:
return repr(key)
else:
return 'a ' + self.name.lower()
OPERATORS = {
OPEN_BRACKET: TokenKind.LEFT_BRACKET,
CLOSE_BRACKET: TokenKind.RIGHT_BRACKET,
}
SPECIAL_CHARS = OPERATORS.keys() | {BACKSLASH}
LITERAL_TOKENS = [
TokenKind.TEXT,
TokenKind.NUMBER,
]
class Token(NamedTuple):
kind: TokenKind
value: Union[str, int]
start: int
end: int
class PathAction(Enum):
KEY = auto()
INDEX = auto()
APPEND = auto()
# Pseudo action, used by the interpreter
SET = auto()
def to_string(self) -> str:
return self.name.lower()
class Path:
def __init__(
self,
kind: PathAction,
accessor: Optional[Union[str, int]] = None,
tokens: Optional[List[Token]] = None,
is_root: bool = False,
):
self.kind = kind
self.accessor = accessor
self.tokens = tokens or []
self.is_root = is_root
def reconstruct(self) -> str:
if self.kind is PathAction.KEY:
if self.is_root:
return str(self.accessor)
return OPEN_BRACKET + self.accessor + CLOSE_BRACKET
elif self.kind is PathAction.INDEX:
return OPEN_BRACKET + str(self.accessor) + CLOSE_BRACKET
elif self.kind is PathAction.APPEND:
return OPEN_BRACKET + CLOSE_BRACKET
class NestedJSONArray(list):
"""Denotes a top-level JSON array."""

249
httpie/cli/options.py Normal file
View File

@ -0,0 +1,249 @@
import argparse
import textwrap
import typing
from dataclasses import dataclass, field
from enum import Enum, auto
from typing import Any, Optional, Dict, List, Tuple, Type, TypeVar
from httpie.cli.argparser import HTTPieArgumentParser
from httpie.cli.utils import Manual, LazyChoices
class Qualifiers(Enum):
OPTIONAL = auto()
ZERO_OR_MORE = auto()
ONE_OR_MORE = auto()
SUPPRESS = auto()
def map_qualifiers(
configuration: Dict[str, Any], qualifier_map: Dict[Qualifiers, Any]
) -> Dict[str, Any]:
return {
key: qualifier_map[value] if isinstance(value, Qualifiers) else value
for key, value in configuration.items()
}
def drop_keys(
configuration: Dict[str, Any], key_blacklist: Tuple[str, ...]
):
return {
key: value
for key, value in configuration.items()
if key not in key_blacklist
}
PARSER_SPEC_VERSION = '0.0.1a0'
@dataclass
class ParserSpec:
program: str
description: Optional[str] = None
epilog: Optional[str] = None
groups: List['Group'] = field(default_factory=list)
man_page_hint: Optional[str] = None
source_file: Optional[str] = None
def finalize(self) -> 'ParserSpec':
if self.description:
self.description = textwrap.dedent(self.description)
if self.epilog:
self.epilog = textwrap.dedent(self.epilog)
for group in self.groups:
group.finalize()
return self
def add_group(self, name: str, **kwargs) -> 'Group':
group = Group(name, **kwargs)
self.groups.append(group)
return group
def serialize(self) -> Dict[str, Any]:
return {
'name': self.program,
'description': self.description,
'groups': [group.serialize() for group in self.groups],
}
@dataclass
class Group:
name: str
description: str = ''
is_mutually_exclusive: bool = False
arguments: List['Argument'] = field(default_factory=list)
def finalize(self) -> None:
if self.description:
self.description = textwrap.dedent(self.description)
def add_argument(self, *args, **kwargs):
argument = Argument(list(args), kwargs.copy())
argument.post_init()
self.arguments.append(argument)
return argument
def serialize(self) -> Dict[str, Any]:
return {
'name': self.name,
'description': self.description or None,
'is_mutually_exclusive': self.is_mutually_exclusive,
'args': [argument.serialize() for argument in self.arguments],
}
class Argument(typing.NamedTuple):
aliases: List[str]
configuration: Dict[str, Any]
def post_init(self):
"""Run a bunch of post-init hooks."""
# If there is a short help, then create the longer version from it.
short_help = self.configuration.get('short_help')
if (
short_help
and 'help' not in self.configuration
and self.configuration.get('action') != 'lazy_choices'
):
self.configuration['help'] = f'\n{short_help}\n\n'
def serialize(self, *, isolation_mode: bool = False) -> Dict[str, Any]:
configuration = self.configuration.copy()
# Unpack the dynamically computed choices, since we
# will need to store the actual values somewhere.
action = configuration.pop('action', None)
short_help = configuration.pop('short_help', None)
nested_options = configuration.pop('nested_options', None)
if action == 'lazy_choices':
choices = LazyChoices(
self.aliases,
**{'dest': None, **configuration},
isolation_mode=isolation_mode
)
configuration['choices'] = list(choices.load())
configuration['help'] = choices.help
result = {}
if self.aliases:
result['options'] = self.aliases.copy()
else:
result['options'] = [configuration['metavar']]
result['is_positional'] = True
qualifiers = JSON_QUALIFIER_TO_OPTIONS[configuration.get('nargs', Qualifiers.SUPPRESS)]
result.update(qualifiers)
description = configuration.get('help')
if description and description is not Qualifiers.SUPPRESS:
result['short_description'] = short_help
result['description'] = description
if nested_options:
result['nested_options'] = nested_options
python_type = configuration.get('type')
if python_type is not None:
if hasattr(python_type, '__name__'):
type_name = python_type.__name__
else:
type_name = type(python_type).__name__
result['python_type_name'] = type_name
result.update({
key: value
for key, value in configuration.items()
if key in JSON_DIRECT_MIRROR_OPTIONS
if value is not Qualifiers.SUPPRESS
})
return result
@property
def is_positional(self):
return len(self.aliases) == 0
@property
def is_hidden(self):
return self.configuration.get('help') is Qualifiers.SUPPRESS
def __getattr__(self, attribute_name):
if attribute_name in self.configuration:
return self.configuration[attribute_name]
else:
raise AttributeError(attribute_name)
ParserType = TypeVar('ParserType', bound=Type[argparse.ArgumentParser])
ARGPARSE_QUALIFIER_MAP = {
Qualifiers.OPTIONAL: argparse.OPTIONAL,
Qualifiers.SUPPRESS: argparse.SUPPRESS,
Qualifiers.ZERO_OR_MORE: argparse.ZERO_OR_MORE,
Qualifiers.ONE_OR_MORE: argparse.ONE_OR_MORE
}
ARGPARSE_IGNORE_KEYS = ('short_help', 'nested_options')
def to_argparse(
abstract_options: ParserSpec,
parser_type: ParserType = HTTPieArgumentParser,
) -> ParserType:
concrete_parser = parser_type(
prog=abstract_options.program,
description=abstract_options.description,
epilog=abstract_options.epilog,
)
concrete_parser.spec = abstract_options
concrete_parser.register('action', 'lazy_choices', LazyChoices)
concrete_parser.register('action', 'manual', Manual)
for abstract_group in abstract_options.groups:
concrete_group = concrete_parser.add_argument_group(
title=abstract_group.name, description=abstract_group.description
)
if abstract_group.is_mutually_exclusive:
concrete_group = concrete_group.add_mutually_exclusive_group(required=False)
for abstract_argument in abstract_group.arguments:
concrete_group.add_argument(
*abstract_argument.aliases,
**drop_keys(map_qualifiers(
abstract_argument.configuration, ARGPARSE_QUALIFIER_MAP
), ARGPARSE_IGNORE_KEYS)
)
return concrete_parser
JSON_DIRECT_MIRROR_OPTIONS = (
'choices',
'metavar'
)
JSON_QUALIFIER_TO_OPTIONS = {
Qualifiers.OPTIONAL: {'is_optional': True},
Qualifiers.ZERO_OR_MORE: {'is_optional': True, 'is_variadic': True},
Qualifiers.ONE_OR_MORE: {'is_optional': False, 'is_variadic': True},
Qualifiers.SUPPRESS: {}
}
def to_data(abstract_options: ParserSpec) -> Dict[str, Any]:
return {'version': PARSER_SPEC_VERSION, 'spec': abstract_options.serialize()}
def parser_to_parser_spec(parser: argparse.ArgumentParser, **kwargs) -> ParserSpec:
"""Take an existing argparse parser, and create a spec from it."""
return ParserSpec(
program=parser.prog,
description=parser.description,
epilog=parser.epilog,
**kwargs
)

View File

@ -1,28 +1,33 @@
import os
import functools
from typing import Callable, Dict, IO, List, Optional, Tuple, Union
from .argtypes import KeyValueArg
from .constants import (
SEPARATORS_GROUP_MULTIPART, SEPARATOR_DATA_EMBED_FILE_CONTENTS,
SEPARATOR_DATA_EMBED_RAW_JSON_FILE,
SEPARATOR_DATA_EMBED_RAW_JSON_FILE, SEPARATOR_GROUP_NESTED_JSON_ITEMS,
SEPARATOR_DATA_RAW_JSON, SEPARATOR_DATA_STRING, SEPARATOR_FILE_UPLOAD,
SEPARATOR_FILE_UPLOAD_TYPE, SEPARATOR_HEADER, SEPARATOR_HEADER_EMPTY,
SEPARATOR_QUERY_PARAM,
SEPARATOR_HEADER_EMBED, SEPARATOR_QUERY_PARAM,
SEPARATOR_QUERY_EMBED_FILE, RequestType
)
from .dicts import (
MultipartRequestDataDict, RequestDataDict, RequestFilesDict,
RequestHeadersDict, RequestJSONDataDict,
BaseMultiDict, MultipartRequestDataDict, RequestDataDict,
RequestFilesDict, HTTPHeadersDict, RequestJSONDataDict,
RequestQueryParamsDict,
)
from .exceptions import ParseError
from ..utils import get_content_type, load_json_preserve_order_and_dupe_keys
from .nested_json import interpret_nested_json
from ..utils import get_content_type, load_json_preserve_order_and_dupe_keys, split_iterable
class RequestItems:
def __init__(self, as_form=False):
self.headers = RequestHeadersDict()
self.data = RequestDataDict() if as_form else RequestJSONDataDict()
def __init__(self, request_type: Optional[RequestType] = None):
self.headers = HTTPHeadersDict()
self.request_type = request_type
self.is_json = request_type is None or request_type is RequestType.JSON
self.data = RequestJSONDataDict() if self.is_json else RequestDataDict()
self.files = RequestFilesDict()
self.params = RequestQueryParamsDict()
# To preserve the order of fields in file upload multipart requests.
@ -32,9 +37,9 @@ class RequestItems:
def from_args(
cls,
request_item_args: List[KeyValueArg],
as_form=False,
request_type: Optional[RequestType] = None,
) -> 'RequestItems':
instance = cls(as_form=as_form)
instance = cls(request_type=request_type)
rules: Dict[str, Tuple[Callable, dict]] = {
SEPARATOR_HEADER: (
process_header_arg,
@ -44,10 +49,18 @@ class RequestItems:
process_empty_header_arg,
instance.headers,
),
SEPARATOR_HEADER_EMBED: (
process_embed_header_arg,
instance.headers,
),
SEPARATOR_QUERY_PARAM: (
process_query_param_arg,
instance.params,
),
SEPARATOR_QUERY_EMBED_FILE: (
process_embed_query_param_arg,
instance.params,
),
SEPARATOR_FILE_UPLOAD: (
process_file_upload_arg,
instance.files,
@ -60,24 +73,50 @@ class RequestItems:
process_data_embed_file_contents_arg,
instance.data,
),
SEPARATOR_GROUP_NESTED_JSON_ITEMS: (
process_data_nested_json_embed_args,
instance.data,
),
SEPARATOR_DATA_RAW_JSON: (
process_data_raw_json_embed_arg,
convert_json_value_to_form_if_needed(
in_json_mode=instance.is_json,
processor=process_data_raw_json_embed_arg
),
instance.data,
),
SEPARATOR_DATA_EMBED_RAW_JSON_FILE: (
process_data_embed_raw_json_file_arg,
convert_json_value_to_form_if_needed(
in_json_mode=instance.is_json,
processor=process_data_embed_raw_json_file_arg,
),
instance.data,
),
}
if instance.is_json:
json_item_args, request_item_args = split_iterable(
iterable=request_item_args,
key=lambda arg: arg.sep in SEPARATOR_GROUP_NESTED_JSON_ITEMS
)
if json_item_args:
pairs = [(arg.key, rules[arg.sep][0](arg)) for arg in json_item_args]
processor_func, target_dict = rules[SEPARATOR_GROUP_NESTED_JSON_ITEMS]
value = processor_func(pairs)
target_dict.update(value)
# Then handle all other items.
for arg in request_item_args:
processor_func, target_dict = rules[arg.sep]
value = processor_func(arg)
target_dict[arg.key] = value
if arg.sep in SEPARATORS_GROUP_MULTIPART:
instance.multipart_data[arg.key] = value
if isinstance(target_dict, BaseMultiDict):
target_dict.add(arg.key, value)
else:
target_dict[arg.key] = value
return instance
@ -88,6 +127,10 @@ def process_header_arg(arg: KeyValueArg) -> Optional[str]:
return arg.value or None
def process_embed_header_arg(arg: KeyValueArg) -> str:
return load_text_file(arg).rstrip('\n')
def process_empty_header_arg(arg: KeyValueArg) -> str:
if not arg.value:
return arg.value
@ -100,6 +143,10 @@ def process_query_param_arg(arg: KeyValueArg) -> str:
return arg.value
def process_embed_query_param_arg(arg: KeyValueArg) -> str:
return load_text_file(arg).rstrip('\n')
def process_file_upload_arg(arg: KeyValueArg) -> Tuple[str, IO, str]:
parts = arg.value.split(SEPARATOR_FILE_UPLOAD_TYPE)
filename = parts[0]
@ -115,6 +162,30 @@ def process_file_upload_arg(arg: KeyValueArg) -> Tuple[str, IO, str]:
)
def convert_json_value_to_form_if_needed(in_json_mode: bool, processor: Callable[[KeyValueArg], JSONType]) -> Callable[[], str]:
"""
We allow primitive values to be passed to forms via JSON key/value syntax.
But complex values lead to an error because theres no clear way to serialize them.
"""
if in_json_mode:
return processor
@functools.wraps(processor)
def wrapper(*args, **kwargs) -> str:
try:
output = processor(*args, **kwargs)
except ParseError:
output = None
if isinstance(output, (str, int, float)):
return str(output)
else:
raise ParseError('Cannot use complex JSON value types with --form/--multipart.')
return wrapper
def process_data_item_arg(arg: KeyValueArg) -> str:
return arg.value
@ -134,6 +205,10 @@ def process_data_raw_json_embed_arg(arg: KeyValueArg) -> JSONType:
return value
def process_data_nested_json_embed_args(pairs) -> Dict[str, JSONType]:
return interpret_nested_json(pairs)
def load_text_file(item: KeyValueArg) -> str:
path = item.value
try:

79
httpie/cli/utils.py Normal file
View File

@ -0,0 +1,79 @@
import argparse
from typing import Any, Callable, Generic, Iterator, Iterable, Optional, TypeVar
T = TypeVar('T')
class Manual(argparse.Action):
def __init__(
self,
option_strings,
dest=argparse.SUPPRESS,
default=argparse.SUPPRESS,
help=None
):
super().__init__(
option_strings=option_strings,
dest=dest,
default=default,
nargs=0,
help=help
)
def __call__(self, parser, namespace, values, option_string=None):
parser.print_manual()
parser.exit()
class LazyChoices(argparse.Action, Generic[T]):
def __init__(
self,
*args,
getter: Callable[[], Iterable[T]],
help_formatter: Optional[Callable[[T, bool], str]] = None,
sort: bool = False,
cache: bool = True,
isolation_mode: bool = False,
**kwargs
) -> None:
self.getter = getter
self.help_formatter = help_formatter
self.sort = sort
self.cache = cache
self.isolation_mode = isolation_mode
self._help: Optional[str] = None
self._obj: Optional[Iterable[T]] = None
super().__init__(*args, **kwargs)
self.choices = self
def load(self) -> T:
if self._obj is None or not self.cache:
self._obj = self.getter()
assert self._obj is not None
return self._obj
@property
def help(self) -> str:
if self._help is None and self.help_formatter is not None:
self._help = self.help_formatter(
self.load(),
isolation_mode=self.isolation_mode
)
return self._help
@help.setter
def help(self, value: Any) -> None:
self._help = value
def __contains__(self, item: Any) -> bool:
return item in self.load()
def __iter__(self) -> Iterator[T]:
if self.sort:
return iter(sorted(self.load()))
else:
return iter(self.load())
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, values)

View File

@ -3,19 +3,26 @@ import http.client
import json
import sys
from contextlib import contextmanager
from pathlib import Path
from typing import Callable, Iterable, Union
from time import monotonic
from typing import Any, Dict, Callable, Iterable
from urllib.parse import urlparse, urlunparse
import requests
# noinspection PyPackageRequirements
import urllib3
from urllib3.util import SKIP_HEADER, SKIPPABLE_HEADERS
from . import __version__
from .cli.dicts import RequestHeadersDict
from .adapters import HTTPieHTTPAdapter
from .cli.constants import HTTP_OPTIONS
from .cli.dicts import HTTPHeadersDict
from .cli.nested_json import unwrap_top_level_list_if_needed
from .context import Environment
from .encoding import UTF8
from .models import RequestsMessage
from .plugins.registry import plugin_manager
from .sessions import get_httpie_session
from .ssl import AVAILABLE_SSL_VERSION_ARG_MAPPING, HTTPieHTTPSAdapter
from .ssl_ import AVAILABLE_SSL_VERSION_ARG_MAPPING, HTTPieCertificate, HTTPieHTTPSAdapter
from .uploads import (
compress_request, prepare_request_body,
get_multipart_data_and_content_type,
@ -30,17 +37,20 @@ JSON_CONTENT_TYPE = 'application/json'
JSON_ACCEPT = f'{JSON_CONTENT_TYPE}, */*;q=0.5'
DEFAULT_UA = f'HTTPie/{__version__}'
IGNORE_CONTENT_LENGTH_METHODS = frozenset([HTTP_OPTIONS])
def collect_messages(
env: Environment,
args: argparse.Namespace,
config_dir: Path,
request_body_read_callback: Callable[[bytes], None] = None,
) -> Iterable[Union[requests.PreparedRequest, requests.Response]]:
) -> Iterable[RequestsMessage]:
httpie_session = None
httpie_session_headers = None
if args.session or args.session_read_only:
httpie_session = get_httpie_session(
config_dir=config_dir,
env=env,
config_dir=env.config.directory,
session_name=args.session or args.session_read_only,
host=args.headers.get('Host'),
url=args.url,
@ -48,6 +58,7 @@ def collect_messages(
httpie_session_headers = httpie_session.headers
request_kwargs = make_request_kwargs(
env,
args=args,
base_headers=httpie_session_headers,
request_body_read_callback=request_body_read_callback
@ -79,6 +90,7 @@ def collect_messages(
request = requests.Request(**request_kwargs)
prepared_request = requests_session.prepare_request(request)
transform_headers(request, prepared_request)
if args.path_as_is:
prepared_request.url = ensure_path_as_is(
orig_url=args.url,
@ -104,7 +116,7 @@ def collect_messages(
**send_kwargs_merged,
**send_kwargs,
)
response._httpie_headers_parsed_at = monotonic()
expired_cookies += get_expired_cookies(
response.headers.get('Set-Cookie', '')
)
@ -124,17 +136,14 @@ def collect_messages(
if httpie_session:
if httpie_session.is_new() or not args.session_read_only:
httpie_session.cookies = requests_session.cookies
httpie_session.remove_cookies(
# TODO: take path & domain into account?
cookie['name'] for cookie in expired_cookies
)
httpie_session.remove_cookies(expired_cookies)
httpie_session.save()
# noinspection PyProtectedMember
@contextmanager
def max_headers(limit):
# <https://github.com/httpie/httpie/issues/802>
# <https://github.com/httpie/cli/issues/802>
# noinspection PyUnresolvedReferences
orig = http.client._MAXHEADERS
http.client._MAXHEADERS = limit or float('Inf')
@ -152,6 +161,7 @@ def build_requests_session(
requests_session = requests.Session()
# Install our adapter.
http_adapter = HTTPieHTTPAdapter()
https_adapter = HTTPieHTTPSAdapter(
ciphers=ciphers,
verify=verify,
@ -160,6 +170,7 @@ def build_requests_session(
if ssl_version else None
),
)
requests_session.mount('http://', http_adapter)
requests_session.mount('https://', https_adapter)
# Install adapters from plugins.
@ -178,8 +189,8 @@ def dump_request(kwargs: dict):
f'\n>>> requests.request(**{repr_dict(kwargs)})\n\n')
def finalize_headers(headers: RequestHeadersDict) -> RequestHeadersDict:
final_headers = RequestHeadersDict()
def finalize_headers(headers: HTTPHeadersDict) -> HTTPHeadersDict:
final_headers = HTTPHeadersDict()
for name, value in headers.items():
if value is not None:
# “leading or trailing LWS MAY be removed without
@ -188,14 +199,69 @@ def finalize_headers(headers: RequestHeadersDict) -> RequestHeadersDict:
# Also, requests raises `InvalidHeader` for leading spaces.
value = value.strip()
if isinstance(value, str):
# See <https://github.com/httpie/httpie/issues/212>
# See <https://github.com/httpie/cli/issues/212>
value = value.encode()
final_headers[name] = value
elif name.lower() in SKIPPABLE_HEADERS:
# Some headers get overwritten by urllib3 when set to `None`
# and should be replaced with the `SKIP_HEADER` constant.
value = SKIP_HEADER
final_headers.add(name, value)
return final_headers
def make_default_headers(args: argparse.Namespace) -> RequestHeadersDict:
default_headers = RequestHeadersDict({
def transform_headers(
request: requests.Request,
prepared_request: requests.PreparedRequest
) -> None:
"""Apply various transformations on top of the `prepared_requests`'s
headers to change the request prepreation behavior."""
# Remove 'Content-Length' when it is misplaced by requests.
if (
prepared_request.method in IGNORE_CONTENT_LENGTH_METHODS
and prepared_request.headers.get('Content-Length') == '0'
and request.headers.get('Content-Length') != '0'
):
prepared_request.headers.pop('Content-Length')
apply_missing_repeated_headers(
request.headers,
prepared_request
)
def apply_missing_repeated_headers(
original_headers: HTTPHeadersDict,
prepared_request: requests.PreparedRequest
) -> None:
"""Update the given `prepared_request`'s headers with the original
ones. This allows the requests to be prepared as usual, and then later
merged with headers that are specified multiple times."""
new_headers = HTTPHeadersDict(prepared_request.headers)
for prepared_name, prepared_value in prepared_request.headers.items():
if prepared_name not in original_headers:
continue
original_keys, original_values = zip(*filter(
lambda item: item[0].casefold() == prepared_name.casefold(),
original_headers.items()
))
if prepared_value not in original_values:
# If the current value is not among the initial values
# set for this field, then it means that this field got
# overridden on the way, and we should preserve it.
continue
new_headers.popone(prepared_name)
new_headers.update(zip(original_keys, original_values))
prepared_request.headers = new_headers
def make_default_headers(args: argparse.Namespace) -> HTTPHeadersDict:
default_headers = HTTPHeadersDict({
'User-Agent': DEFAULT_UA
})
@ -224,7 +290,14 @@ def make_send_kwargs_mergeable_from_env(args: argparse.Namespace) -> dict:
if args.cert:
cert = args.cert
if args.cert_key:
cert = cert, args.cert_key
# Having a client certificate key passphrase is not supported
# by requests. So we are using our own transportation structure
# which is compatible with their format (a tuple of minimum two
# items).
#
# See: https://github.com/psf/requests/issues/2519
cert = HTTPieCertificate(cert, args.cert_key, args.cert_key_pass.value)
return {
'proxies': {p.key: p.value for p in args.proxy},
'stream': True,
@ -238,9 +311,21 @@ def make_send_kwargs_mergeable_from_env(args: argparse.Namespace) -> dict:
}
def json_dict_to_request_body(data: Dict[str, Any]) -> str:
data = unwrap_top_level_list_if_needed(data)
if data:
data = json.dumps(data)
else:
# We need to set data to an empty string to prevent requests
# from assigning an empty list to `response.request.data`.
data = ''
return data
def make_request_kwargs(
env: Environment,
args: argparse.Namespace,
base_headers: RequestHeadersDict = None,
base_headers: HTTPHeadersDict = None,
request_body_read_callback=lambda chunk: chunk
) -> dict:
"""
@ -252,12 +337,7 @@ def make_request_kwargs(
data = args.data
auto_json = data and not args.form
if (args.json or auto_json) and isinstance(data, dict):
if data:
data = json.dumps(data)
else:
# We need to set data to an empty string to prevent requests
# from assigning an empty list to `response.request.data`.
data = ''
data = json_dict_to_request_body(data)
# Finalize headers.
headers = make_default_headers(args)
@ -282,7 +362,8 @@ def make_request_kwargs(
'url': args.url,
'headers': headers,
'data': prepare_request_body(
body=data,
env,
data,
body_read_callback=request_body_read_callback,
chunked=args.chunked,
offline=args.offline,
@ -300,7 +381,7 @@ def ensure_path_as_is(orig_url: str, prepped_url: str) -> str:
untouched because other (welcome) processing on the URL might have
taken place.
<https://github.com/httpie/httpie/issues/895>
<https://github.com/httpie/cli/issues/895>
<https://ec.haxx.se/http/http-basics#path-as-is>

Some files were not shown because too many files have changed in this diff Show More