Package: httpy
Docs athttps://httpy.readthedocs.io/httpyA Python lightweight socket-based library to create HTTP(s) and
WebSocket connections.FeaturesCookies supportCaching supportEasy debuggingHTTP Basic and Digest authenticationForm supportKeep-Alive and Sessions supportJSON supportSessions supportRuns in PyPyIndependent of http.clientHTTP/2 SupportAsync IO supportRequirementsPython>=3.6InstallationAny platformGitgit clonehttps://github.com/jenca-adam/httpycd httpypython3 setup.py installThe Python version check will be performed automaticallyPippython3-mpip install httpyArch Linuxyay-ShttpyUsageREFERENCEHTTPIt’s easy.importhttpyresp=httpy.request("https://example.com/")# Do a requestresp.content#Access contentSpecifying a HTTP versionSet thehttp_versionargument, but keep in mind the followingYou can’t make an asynchronous request using HTTP/1.1HTTP/2 requests can’t be performed over insecure (http scheme)
connections.If you don’t set it, the HTTP version will be automatically detected
using ALPN <https://datatracker.ietf.org/doc/html/rfc7301>.Validhttp_versionvalues are"1.1"and"2".Non-blocking requestsimporthttpypending=httpy.request("https://example.com/",blocking=False)PendingRequest.responsereturns the result of the response. You can
check if the request is already done usingPendingRequest.finishedI want cookies!TheDirclass allows you to store httpy’s data (cache and cookies)
on the path of your choice. By default, the data is stored in~/.cache/httpy. If you want to store the data without using theDirclass, use theenable_cookiesorenable_cacheargument ofrequest.
.. code-block:: pythonimport httpy
directory = httpy.Dir(“your/path”)
directory.request(”https://example.com/”) # …Keep-Alive requestsIf you want to reuse a connection, it is highly recommended to use aSessionclass. It offers more control over connection closure than
the standardrequestimporthttpysession=httpy.Session()session.request("https://example.com/")HTTPy setsConnection: closeby default in non-Session requests. If
you want to keep the connection alive outside a session, you must
specify so in theheadersargument.Asynchronous requestsYou can perform async requests using theasync_requestmethod.The simplest use case:importhttpyasyncdefmy_function():returnawaithttpy.request("https://example.com/")If you want to perform multiple requests at once on the same connection
(i.e. withasyncio.gather), use theinitiate_http2_connectionmethod ofSession:importhttpyimportasyncioasyncdefmy_function():session=httpy.Session()awaitsession.initiate_http2_connection(host="example.com")returnawaitasyncio.gather(*(session.async_request("https://www.example.com/")for_inrange(69)))SessionandDirand everything with arequest()method has
anasync_request()equivalent.Responseclass attributesTheResponseclass returned byrequest()has some useful
attributes:Response.contentThe response content asbytes. Example:importhttpyresp=httpy.request("https://www.google.com/")print(resp.content)#b'!<doctype html>\n<html>...Response.statusThe response status as aStatusobject. Example:importhttpyresp=httpy.request("https://www.example.com/this_url_doesnt_exist")print(resp.status)# 404print(resp.status.reason)# NOT FOUNDprint(resp.status.description)# indicates that the origin server did not find a current representation for the target resource or is not willing to disclose that one exists.print(resp.status>400)# TrueStatussubclassesint.Response.historyAll the redirects on the way to this response aslist.Example:importhttpyresp=httpy.request("https://httpbin.org/redirect/1")print(resp.history)# [<Response GET [302 Found] (https://httpbin.org/redirect/1/)>, <Response GET [200 OK] (https://httpbin.org/get/)>]Response.historyis ordered from oldest to newestResponse.fromcacheIndicates whether the response was loaded from cache (bool).Example:importhttpyresp=httpy.request("https://example.com/")print(resp.fromcache)# Falseresp=httpy.request("https://example.com/")print(resp.fromcache)# TrueResponse.requestSome of the attributes of the request that produced this response, as aRequestobject.Request’s attributesRequest.url- the URL requested (str)Request.headers- the requests’ headers (Headers)Request.socket- the underlying connection (eithersocket.socketorhttpy.http2.connection.HTTP2Connection)Request.cache- the same asResponse.fromcache(bool)Request.http_version- the HTTP version used (str)Request.method- the HTTP method used (str)Example:importhttpyresp=httpy.request("https://example.com/")print(resp.request.url)# https://example.com/print(resp.request.headers)# {'Accept-Encoding': 'gzip, deflate, identity', 'Host': 'example.com', 'User-Agent': 'httpy/2.0.0', 'Connection': 'close', 'Accept': '*/*'}print(resp.request.method)# GETResponse.original_contentRaw content received from the server, not decoded with Content-Encoding
(bytes).Example:importhttpyresp=httpy.request("https://example.com/")print(resp.original_content)# b'\x1f\x8b\x08\x00\xc2 ...Response.time_elapsedTime the request took, in seconds. Only the loading time of this
particular request, doesn’t account for redirects. (float).Example:importhttpyresp=httpy.request("https://example.com/")print(resp.time_elapsed)# 0.2497Response.speedThe download speed for the response, in bytes per second. (float).
Might be different for HTTP/2 request. Example:importhttpyresp=httpy.request("https://example.com/")print(resp.speed)# 2594.79Response.content_typeThe response’sContent-Typeheader contents, with the charset
information stripped. If the headers lackContent-Type, it’stext/htmlby default.importhttpyresp=httpy.request("https://example.com/")print(resp.content_type)# text/htmlResponse.charset(property)Gets the charset of the response (strorNone):If a charset was specified in the response headers, return itIf a charset was not specified, butchardetis available, try to
detect the charset (Note that this still returnsNoneifchardetfails)If a charset was not specified, andchardetis not available,
returnNoneExample:importhttpyresp=httpy.request("https://example.com/")print(resp.charset)# UTF-8Response.string(property)Response.content, decoded usingResponse.charset(str)WarningDo not try to accessResponse.string, ifResponse.charsetisNone, unless you are absolutely sure the response data is
decodable by the default locale encoding.For ASCII responses this is probably harmless, but you have been
warned!Example:importhttpyresp=httpy.request("https://example.com/")print(resp.string)#<!doctype html>...Response.json(property)IfResponse.content_typeisapplication/json, try to parseResponse.stringusing JSON. Throw an error otherwise.WarningThe same as above applies.Example:importhttpyresp=httpy.request("https://httpbin.org/get")print(resp.json["url"])# https://httpbin.org/getResponse.methodThe same asResponse.request.methodWebSocketsEasy again…>>>importhttpy>>>sock=httpy.WebSocket("wss://echo.websocket.events/")# create a websocket client(echo server example)>>>sock.send("Hello, world!💥")# you can send also bytes>>>sock.recv()"Hello, world!💥"ExamplesPOST methodSimple Formimporthttpyresp=httpy.request("https://example.com/",method="POST",body={"foo":"bar"})# ...Sending filesimporthttpyresp=httpy.request("https://example.com/",method="POST",body={"foo":"bar","file":httpy.File.open("example.txt")})# ...Sending binary dataimporthttpyresp=httpy.request("https://example.com/",method="POST",body=b" Hello, World ! ")# ...Sending plain textresp=httpy.request("https://example.com/",method="POST",body="I support Ünicode !")# ...Sending JSONresp=httpy.request("https://example.com/",method="POST",body="{\"foo\":\"bar\"}",content_type="application/json")# ...DebuggingJust setdebugtoTrue:>>>importhttpy>>>httpy.request("https://example.com/",debug=True)[INFO][request](1266):request()called.[INFO][_raw_request](1112):_raw_request()called.[INFO][_raw_request](1113):Accessingcache.[INFO][_raw_request](1120):Nodataincache.[INFO][_raw_request](1151):Establishingconnection[INFO]Connection[__init__](778):CreatednewConnectionupon<socket.socketfd=3,family=AddressFamily.AF_INET,type=SocketKind.SOCK_STREAM,proto=6,laddr=('192.168.100.88',58998),raddr=('93.184.216.34',443)>send:GET/HTTP/1.1Accept-Encoding:gzip,deflate,identityHost:www.example.comUser-Agent:httpy/1.1.0Connection:keep-aliveresponse:HTTP/1.1200OKContent-Encoding:gzipAge:438765Cache-Control:max-age=604800Content-Type:text/html;charset=UTF-8Date:Wed,13Apr202212:59:07GMTEtag:"3147526947+gzip"Expires:Wed,20Apr202212:59:07GMTLast-Modified:Thu,17Oct201907:18:26GMTServer:ECS(dcb/7F37)Vary:Accept-EncodingX-Cache:HITContent-Length:648<Response[200OK](https://www.example.com/)>