Package: encode
HTTPCoreFeature supportHTTP/2andHTTP/1.1support.async/awaitsupport for non-blocking HTTP requests.Strict timeouts everywhere by default.Fully type annotated.100% test coverage.Plus all the standard features of requests...International Domains and URLsKeep-Alive & Connection PoolingSessions with Cookie PersistenceBrowser-style SSL VerificationBasic/Digest AuthenticationTODO - We have Basic, but not Digest yet.Elegant Key/Value CookiesAutomatic DecompressionAutomatic Content DecodingUnicode Response BodiesMultipart File UploadsTODO - Request content currently supports URL encoded data, JSON, bytes, or async byte iterators.HTTP(S) Proxy SupportTODOConnection TimeoutsStreaming Downloads.netrc SupportTODOChunked RequestsUsageMaking a request:>>>importhttpcore>>>client=httpcore.Client()>>>response=client.get('https://example.com')>>>response.status_code<HTTPStatus.OK:200>>>>response.protocol'HTTP/2'>>>response.text'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>\n...'Alternatively, async requests:Note: Useipythonto try this from the console, since it supportsawait.>>>importhttpcore>>>client=httpcore.AsyncClient()>>>response=awaitclient.get('https://example.com')>>>response.status_code<StatusCode.OK:200>>>>response.protocol'HTTP/2'>>>response.text'<!doctype html>\n<html>\n<head>\n<title>Example Domain</title>\n...'Dependenciesh2- HTTP/2 support.h11- HTTP/1.1 support.certifi- SSL certificates.chardet- Fallback auto-detection for response encoding.idna- Internationalized domain name support.rfc3986- URL parsing & normalization.brotlipy- Decoding for "brotli" compressed responses.(Optional)A huge amount of credit is due torequestsfor the API layout that
much of this work follows, as well as tourllib3for plenty of design
inspiration around the lower level networking details.API ReferenceClientAn HTTP client, with connection pooling, redirects, cookie persistence, etc.>>>client=Client()>>>response=client.get('https://example.org')def __init__([auth], [cookies], [verify], [cert], [timeout], [pool_limits], [max_redirects], [dispatch])def .request(method, url, [data], [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout])def .get(url, [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout])def .options(url, [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout])def .head(url, [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout])def .post(url, [data], [json], [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout])def .put(url, [data], [json], [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout])def .patch(url, [data], [json], [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout])def .delete(url, [data], [json], [params], [headers], [cookies], [auth], [stream], [allow_redirects], [verify], [cert], [timeout])def .prepare_request(request)def .send(request, [stream], [allow_redirects], [verify], [cert], [timeout])def .close()ResponseAn HTTP response.def __init__(...).status_code-int(Typically aStatusCodeIntEnum.).reason_phrase-str.protocol-"HTTP/2"or"HTTP/1.1".url-URL.headers-Headers.content-bytes.text-str.encoding-str.is_redirect-bool.request-Request.cookies-Cookies.history-List[Response]def .raise_for_status()-Nonedef .json()-Anydef .read()-bytesdef .stream()-bytes iteratordef .raw()-bytes iteratordef .close()-Nonedef .next()-ResponseRequestAn HTTP request. Can be constructed explicitly for more control over exactly
what gets sent over the wire.>>>request=Request("GET","https://example.org",headers={'host':'example.org'})>>>response=client.send(request)def __init__(method, url, [params], [data], [json], [headers], [cookies]).method-str.url-URL.content-byteorbyte async iterator.headers-Headers.cookies-CookiesURLA normalized, IDNA supporting URL.>>>url=URL("https://example.org/")>>>url.host'example.org'def __init__(url, allow_relative=False, params=None).scheme-str.authority-str.host-str.port-int.path-str.query-str.full_path-str.fragment-str.is_ssl-bool.origin-Origin.is_absolute_url-bool.is_relative_url-booldef .copy_with([scheme], [authority], [path], [query], [fragment])-URLdef .resolve_with(url)-URLOriginA normalized, IDNA supporting set of scheme/host/port info.>>>Origin('https://example.org')==Origin('HTTPS://EXAMPLE.ORG:443')Truedef __init__(url).is_ssl-bool.host-str.port-intHeadersA case-insensitive multi-dict.>>>headers=Headers({'Content-Type':'application/json'})>>>headers['content-type']'application/json'def __init__(self, headers)CookiesA dict-like cookie store.>>>cookies=Cookies()>>>cookies.set("name","value",domain="example.org")def __init__(cookies: [dict, Cookies, CookieJar]).jar-CookieJardef extract_cookies(response)def set_cookie_header(request)def set(name, value, [domain], [path])def get(name, [domain], [path])def delete(name, [domain], [path])def clear([domain], [path])Standard mutable mapping interfaceAlternate backendsAsyncClientAn asyncio client.TrioClientTODOThe StackThere are two main layers in the stack. The client handles redirection,
cookie persistence (TODO), and authentication (TODO). The dispatcher
handles sending the actual request and getting the response.Client- Redirect, authentication, cookies etc.ConnectionPool(Dispatcher)- Connection pooling & keep alive.HTTPConnection- A single connection.HTTP11Connection- A single HTTP/1.1 connection.HTTP2Connection- A single HTTP/2 connection, with multiple streams.