@technige interesting. Have you ever looked into httpx?
@pythoneer No, not in any depth. What's its angle over the other options?
@technige Requests-like but not a wrapper around urllib3, provides async and HTTP/2 support, more modern design generally - e.g. using type annotations throughout the API.
@pythoneer @technige The pre release of urllib3 is fully type annotated too! I think the main value proposition of httpx is async support (including Trio ) because HTTP/2 is just barely supported without any support for multiplexing.
urllib3 is instead more battle-tested and supports advanced features like HTTPS proxies (those are not even properly supported by requests yet)
@technige Thanks! Great comparison.
One nitpick is that there is slight confusion around Python imports: you can just use `requests.post` and `urllib3.make_headers` without any extra imports.
Another is that requests recently switched from chardet to charset-normalizer for licensing reasons.
@quentinpradet Excellent point. I tend to use the "from MODULE import X" style everywhere, but just for subjective reasons. If using "import MODULE" then any pros/cons around imports melt away.
And I hadn't noticed the chardet detail. What's the difference between the two?
@technige The style guides I’ve seen advise "import MODULE". Example: https://google.github.io/styleguide/pyguide.html#22-imports. And arguably `requests.post` is much clearer than just `post`.
The main difference is that chardet is licensed under the LGPL, which prevents bundling closed source with requests with tools such as PyOxidizer: https://github.com/psf/requests/issues/4848
@quentinpradet I think it depends on the module, as they can be inconsistently designed for imports. So I really dislike the repetition of e.g. `d = datetime.datetime(...)`. But then `json.dumps` is obviously much clearer than just `dumps`, so I usually `from json import dumps and json_dumps`.
@quentinpradet Another factor is trying to avoid dots that need to be evaluated at runtime. Probably a negligible performance overhead in practice, but at this point, it's really just more of a habit to do it this way :)
@quentinpradet I'll read up on the chardet issue, thank you :)
And I'll probably hop in to make a few tweaks to the article in light of your comments.
@technige If you’re interested, see https://github.com/python-trio/hip/issues/124 for a full list of things that requests supports. The hooks/adapter feature is the main one as it’s not just syntactic sugar and means for example that I could not trivially port pip to use urllib3.
@technige I switched to HTTPX a few years ago and I absolutely love it.
It's similar to requests in regular mode, but it also has superb support for async Python: https://www.python-httpx.org/
@technige nice comparison. Looking forward to those new shortcuts in urllib3 v2. I might just rip requests out of a project or two :)
@adamchainz Thanks for reading! I'd be interested to hear how easy (or hard) that turns out to be in a real-world project. My use cases were obviously a tad simplistic, but there really didn't seem to be much in it.
@technige first project that I will try is ec2-metadata, a wrapper for an AWS internal API, which tbh is quite simple too. https://github.com/adamchainz/ec2-metadata