httpx/advanced/extensions/index.html
2025-09-11 12:02:38 +01:00

1458 lines
47 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="A next-generation HTTP client for Python.">
<link rel="canonical" href="https://www.python-httpx.org/advanced/extensions/">
<link rel="prev" href="../text-encodings/">
<link rel="next" href="../../async/">
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.5.47">
<title>Extensions - HTTPX</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.6f8fc17f.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.06af60db.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<link rel="stylesheet" href="../../css/custom.css">
<script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#extensions" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../.." title="HTTPX" class="md-header__button md-logo" aria-label="HTTPX" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
HTTPX
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Extensions
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="(prefers-color-scheme: light)" data-md-color-scheme="default" data-md-color-primary="indigo" data-md-color-accent="indigo" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2a7 7 0 0 0-7 7c0 2.38 1.19 4.47 3 5.74V17a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-2.26c1.81-1.27 3-3.36 3-5.74a7 7 0 0 0-7-7M9 21a1 1 0 0 0 1 1h4a1 1 0 0 0 1-1v-1H9z"/></svg>
</label>
<input class="md-option" data-md-color-media="(prefers-color-scheme: dark)" data-md-color-scheme="slate" data-md-color-primary="blue" data-md-color-accent="indigo" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2a7 7 0 0 1 7 7c0 2.38-1.19 4.47-3 5.74V17a1 1 0 0 1-1 1H9a1 1 0 0 1-1-1v-2.26C6.19 13.47 5 11.38 5 9a7 7 0 0 1 7-7M9 21v-1h6v1a1 1 0 0 1-1 1h-4a1 1 0 0 1-1-1m3-17a5 5 0 0 0-5 5c0 2.05 1.23 3.81 3 4.58V16h4v-2.42c1.77-.77 3-2.53 3-4.58a5 5 0 0 0-5-5"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://github.com/encode/httpx/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg>
</div>
<div class="md-source__repository">
encode/httpx
</div>
</a>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<!-- Determine class according to configuration -->
<!-- Main navigation -->
<nav
class="md-nav md-nav--primary"
aria-label="nav.title"
data-md-level="0"
>
<!-- Site title -->
<label class="md-nav__title" for="__drawer">
<a
href="../.."
title="HTTPX"
class="md-nav__button md-logo"
aria-label="HTTPX"
data-md-component="logo"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
HTTPX
</label>
<!-- Repository information -->
<div class="md-nav__source">
<a href="https://github.com/encode/httpx/" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc.--><path d="M439.55 236.05 244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81"/></svg>
</div>
<div class="md-source__repository">
encode/httpx
</div>
</a>
</div>
<!-- Navigation list -->
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." class="md-nav__link">
<span class="md-ellipsis">
Introduction
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../quickstart/" class="md-nav__link">
<span class="md-ellipsis">
QuickStart
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" checked>
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
<span class="md-ellipsis">
Advanced
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
Advanced
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../clients/" class="md-nav__link">
<span class="md-ellipsis">
Clients
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../authentication/" class="md-nav__link">
<span class="md-ellipsis">
Authentication
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../ssl/" class="md-nav__link">
<span class="md-ellipsis">
SSL
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../proxies/" class="md-nav__link">
<span class="md-ellipsis">
Proxies
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../timeouts/" class="md-nav__link">
<span class="md-ellipsis">
Timeouts
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../resource-limits/" class="md-nav__link">
<span class="md-ellipsis">
Resource Limits
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../event-hooks/" class="md-nav__link">
<span class="md-ellipsis">
Event Hooks
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../transports/" class="md-nav__link">
<span class="md-ellipsis">
Transports
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../text-encodings/" class="md-nav__link">
<span class="md-ellipsis">
Text Encodings
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Extensions
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Extensions
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#request-extensions" class="md-nav__link">
<span class="md-ellipsis">
Request Extensions
</span>
</a>
<nav class="md-nav" aria-label="Request Extensions">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#trace" class="md-nav__link">
<span class="md-ellipsis">
"trace"
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#sni_hostname" class="md-nav__link">
<span class="md-ellipsis">
"sni_hostname"
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#timeout" class="md-nav__link">
<span class="md-ellipsis">
"timeout"
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#target" class="md-nav__link">
<span class="md-ellipsis">
"target"
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#response-extensions" class="md-nav__link">
<span class="md-ellipsis">
Response Extensions
</span>
</a>
<nav class="md-nav" aria-label="Response Extensions">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#http_version" class="md-nav__link">
<span class="md-ellipsis">
"http_version"
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#reason_phrase" class="md-nav__link">
<span class="md-ellipsis">
"reason_phrase"
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#stream_id" class="md-nav__link">
<span class="md-ellipsis">
"stream_id"
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#network_stream" class="md-nav__link">
<span class="md-ellipsis">
"network_stream"
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_4" >
<label class="md-nav__link" for="__nav_4" id="__nav_4_label" tabindex="0">
<span class="md-ellipsis">
Guides
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_4_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_4">
<span class="md-nav__icon md-icon"></span>
Guides
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../async/" class="md-nav__link">
<span class="md-ellipsis">
Async Support
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../http2/" class="md-nav__link">
<span class="md-ellipsis">
HTTP/2 Support
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../logging/" class="md-nav__link">
<span class="md-ellipsis">
Logging
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../compatibility/" class="md-nav__link">
<span class="md-ellipsis">
Requests Compatibility
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../troubleshooting/" class="md-nav__link">
<span class="md-ellipsis">
Troubleshooting
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
<span class="md-ellipsis">
API Reference
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_5">
<span class="md-nav__icon md-icon"></span>
API Reference
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../api/" class="md-nav__link">
<span class="md-ellipsis">
Developer Interface
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../exceptions/" class="md-nav__link">
<span class="md-ellipsis">
Exceptions
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../environment_variables/" class="md-nav__link">
<span class="md-ellipsis">
Environment Variables
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_6" >
<label class="md-nav__link" for="__nav_6" id="__nav_6_label" tabindex="0">
<span class="md-ellipsis">
Community
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_6">
<span class="md-nav__icon md-icon"></span>
Community
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../third_party_packages/" class="md-nav__link">
<span class="md-ellipsis">
Third Party Packages
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../contributing/" class="md-nav__link">
<span class="md-ellipsis">
Contributing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../code_of_conduct/" class="md-nav__link">
<span class="md-ellipsis">
Code of Conduct
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
<ul class="md-nav__list" data-md-scrollfix style="padding-top: 15px; padding-left: 10px">
<div>
<a href="https://speakeasy.com"><img src="/img/speakeasy.png" width=150px style=></img></a>
</div>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#request-extensions" class="md-nav__link">
<span class="md-ellipsis">
Request Extensions
</span>
</a>
<nav class="md-nav" aria-label="Request Extensions">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#trace" class="md-nav__link">
<span class="md-ellipsis">
"trace"
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#sni_hostname" class="md-nav__link">
<span class="md-ellipsis">
"sni_hostname"
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#timeout" class="md-nav__link">
<span class="md-ellipsis">
"timeout"
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#target" class="md-nav__link">
<span class="md-ellipsis">
"target"
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#response-extensions" class="md-nav__link">
<span class="md-ellipsis">
Response Extensions
</span>
</a>
<nav class="md-nav" aria-label="Response Extensions">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#http_version" class="md-nav__link">
<span class="md-ellipsis">
"http_version"
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#reason_phrase" class="md-nav__link">
<span class="md-ellipsis">
"reason_phrase"
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#stream_id" class="md-nav__link">
<span class="md-ellipsis">
"stream_id"
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#network_stream" class="md-nav__link">
<span class="md-ellipsis">
"network_stream"
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="extensions">Extensions</h1>
<p>Request and response extensions provide a untyped space where additional information may be added.</p>
<p>Extensions should be used for features that may not be available on all transports, and that do not fit neatly into <a href="https://www.encode.io/httpcore/extensions/">the simplified request/response model</a> that the underlying <code>httpcore</code> package uses as its API.</p>
<p>Several extensions are supported on the request:</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Request timeouts actually implemented as an extension on</span>
<span class="c1"># the request, ensuring that they are passed throughout the</span>
<span class="c1"># entire call stack.</span>
<span class="n">client</span> <span class="o">=</span> <span class="n">httpx</span><span class="o">.</span><span class="n">Client</span><span class="p">()</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
<span class="s2">&quot;https://www.example.com&quot;</span><span class="p">,</span>
<span class="n">extensions</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;timeout&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;connect&quot;</span><span class="p">:</span> <span class="mf">5.0</span><span class="p">}}</span>
<span class="p">)</span>
<span class="n">response</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">extensions</span><span class="p">[</span><span class="s2">&quot;timeout&quot;</span><span class="p">]</span>
<span class="p">{</span><span class="s2">&quot;connect&quot;</span><span class="p">:</span> <span class="mf">5.0</span><span class="p">}</span>
</code></pre></div>
<p>And on the response:</p>
<div class="highlight"><pre><span></span><code><span class="n">client</span> <span class="o">=</span> <span class="n">httpx</span><span class="o">.</span><span class="n">Client</span><span class="p">()</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;https://www.example.com&quot;</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">extensions</span><span class="p">[</span><span class="s2">&quot;http_version&quot;</span><span class="p">])</span> <span class="c1"># b&quot;HTTP/1.1&quot;</span>
<span class="c1"># Other server responses could have been</span>
<span class="c1"># b&quot;HTTP/0.9&quot;, b&quot;HTTP/1.0&quot;, or b&quot;HTTP/1.1&quot;</span>
</code></pre></div>
<h2 id="request-extensions">Request Extensions</h2>
<h3 id="trace"><code>"trace"</code></h3>
<p>The trace extension allows a callback handler to be installed to monitor the internal
flow of events within the underlying <code>httpcore</code> transport.</p>
<p>The simplest way to explain this is with an example:</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span><span class="w"> </span><span class="nn">httpx</span>
<span class="k">def</span><span class="w"> </span><span class="nf">log</span><span class="p">(</span><span class="n">event_name</span><span class="p">,</span> <span class="n">info</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="n">event_name</span><span class="p">,</span> <span class="n">info</span><span class="p">)</span>
<span class="n">client</span> <span class="o">=</span> <span class="n">httpx</span><span class="o">.</span><span class="n">Client</span><span class="p">()</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;https://www.example.com/&quot;</span><span class="p">,</span> <span class="n">extensions</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;trace&quot;</span><span class="p">:</span> <span class="n">log</span><span class="p">})</span>
<span class="c1"># connection.connect_tcp.started {&#39;host&#39;: &#39;www.example.com&#39;, &#39;port&#39;: 443, &#39;local_address&#39;: None, &#39;timeout&#39;: None}</span>
<span class="c1"># connection.connect_tcp.complete {&#39;return_value&#39;: &lt;httpcore.backends.sync.SyncStream object at 0x1093f94d0&gt;}</span>
<span class="c1"># connection.start_tls.started {&#39;ssl_context&#39;: &lt;ssl.SSLContext object at 0x1093ee750&gt;, &#39;server_hostname&#39;: b&#39;www.example.com&#39;, &#39;timeout&#39;: None}</span>
<span class="c1"># connection.start_tls.complete {&#39;return_value&#39;: &lt;httpcore.backends.sync.SyncStream object at 0x1093f9450&gt;}</span>
<span class="c1"># http11.send_request_headers.started {&#39;request&#39;: &lt;Request [b&#39;GET&#39;]&gt;}</span>
<span class="c1"># http11.send_request_headers.complete {&#39;return_value&#39;: None}</span>
<span class="c1"># http11.send_request_body.started {&#39;request&#39;: &lt;Request [b&#39;GET&#39;]&gt;}</span>
<span class="c1"># http11.send_request_body.complete {&#39;return_value&#39;: None}</span>
<span class="c1"># http11.receive_response_headers.started {&#39;request&#39;: &lt;Request [b&#39;GET&#39;]&gt;}</span>
<span class="c1"># http11.receive_response_headers.complete {&#39;return_value&#39;: (b&#39;HTTP/1.1&#39;, 200, b&#39;OK&#39;, [(b&#39;Age&#39;, b&#39;553715&#39;), (b&#39;Cache-Control&#39;, b&#39;max-age=604800&#39;), (b&#39;Content-Type&#39;, b&#39;text/html; charset=UTF-8&#39;), (b&#39;Date&#39;, b&#39;Thu, 21 Oct 2021 17:08:42 GMT&#39;), (b&#39;Etag&#39;, b&#39;&quot;3147526947+ident&quot;&#39;), (b&#39;Expires&#39;, b&#39;Thu, 28 Oct 2021 17:08:42 GMT&#39;), (b&#39;Last-Modified&#39;, b&#39;Thu, 17 Oct 2019 07:18:26 GMT&#39;), (b&#39;Server&#39;, b&#39;ECS (nyb/1DCD)&#39;), (b&#39;Vary&#39;, b&#39;Accept-Encoding&#39;), (b&#39;X-Cache&#39;, b&#39;HIT&#39;), (b&#39;Content-Length&#39;, b&#39;1256&#39;)])}</span>
<span class="c1"># http11.receive_response_body.started {&#39;request&#39;: &lt;Request [b&#39;GET&#39;]&gt;}</span>
<span class="c1"># http11.receive_response_body.complete {&#39;return_value&#39;: None}</span>
<span class="c1"># http11.response_closed.started {}</span>
<span class="c1"># http11.response_closed.complete {&#39;return_value&#39;: None}</span>
</code></pre></div>
<p>The <code>event_name</code> and <code>info</code> arguments here will be one of the following:</p>
<ul>
<li><code>{event_type}.{event_name}.started</code>, <code>&lt;dictionary of keyword arguments&gt;</code></li>
<li><code>{event_type}.{event_name}.complete</code>, <code>{"return_value": &lt;...&gt;}</code></li>
<li><code>{event_type}.{event_name}.failed</code>, <code>{"exception": &lt;...&gt;}</code></li>
</ul>
<p>Note that when using async code the handler function passed to <code>"trace"</code> must be an <code>async def ...</code> function.</p>
<p>The following event types are currently exposed...</p>
<p><strong>Establishing the connection</strong></p>
<ul>
<li><code>"connection.connect_tcp"</code></li>
<li><code>"connection.connect_unix_socket"</code></li>
<li><code>"connection.start_tls"</code></li>
</ul>
<p><strong>HTTP/1.1 events</strong></p>
<ul>
<li><code>"http11.send_request_headers"</code></li>
<li><code>"http11.send_request_body"</code></li>
<li><code>"http11.receive_response"</code></li>
<li><code>"http11.receive_response_body"</code></li>
<li><code>"http11.response_closed"</code></li>
</ul>
<p><strong>HTTP/2 events</strong></p>
<ul>
<li><code>"http2.send_connection_init"</code></li>
<li><code>"http2.send_request_headers"</code></li>
<li><code>"http2.send_request_body"</code></li>
<li><code>"http2.receive_response_headers"</code></li>
<li><code>"http2.receive_response_body"</code></li>
<li><code>"http2.response_closed"</code></li>
</ul>
<p>The exact set of trace events may be subject to change across different versions of <code>httpcore</code>. If you need to rely on a particular set of events it is recommended that you pin installation of the package to a fixed version.</p>
<h3 id="sni_hostname"><code>"sni_hostname"</code></h3>
<p>The server's hostname, which is used to confirm the hostname supplied by the SSL certificate.</p>
<p>If you want to connect to an explicit IP address rather than using the standard DNS hostname lookup, then you'll need to use this request extension.</p>
<p>For example:</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Connect to &#39;185.199.108.153&#39; but use &#39;www.encode.io&#39; in the Host header,</span>
<span class="c1"># and use &#39;www.encode.io&#39; when SSL verifying the server hostname.</span>
<span class="n">client</span> <span class="o">=</span> <span class="n">httpx</span><span class="o">.</span><span class="n">Client</span><span class="p">()</span>
<span class="n">headers</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;Host&quot;</span><span class="p">:</span> <span class="s2">&quot;www.encode.io&quot;</span><span class="p">}</span>
<span class="n">extensions</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;sni_hostname&quot;</span><span class="p">:</span> <span class="s2">&quot;www.encode.io&quot;</span><span class="p">}</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
<span class="s2">&quot;https://185.199.108.153/path&quot;</span><span class="p">,</span>
<span class="n">headers</span><span class="o">=</span><span class="n">headers</span><span class="p">,</span>
<span class="n">extensions</span><span class="o">=</span><span class="n">extensions</span>
<span class="p">)</span>
</code></pre></div>
<h3 id="timeout"><code>"timeout"</code></h3>
<p>A dictionary of <code>str: Optional[float]</code> timeout values.</p>
<p>May include values for <code>'connect'</code>, <code>'read'</code>, <code>'write'</code>, or <code>'pool'</code>.</p>
<p>For example:</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Timeout if a connection takes more than 5 seconds to established, or if</span>
<span class="c1"># we are blocked waiting on the connection pool for more than 10 seconds.</span>
<span class="n">client</span> <span class="o">=</span> <span class="n">httpx</span><span class="o">.</span><span class="n">Client</span><span class="p">()</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">client</span><span class="o">.</span><span class="n">get</span><span class="p">(</span>
<span class="s2">&quot;https://www.example.com&quot;</span><span class="p">,</span>
<span class="n">extensions</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;timeout&quot;</span><span class="p">:</span> <span class="p">{</span><span class="s2">&quot;connect&quot;</span><span class="p">:</span> <span class="mf">5.0</span><span class="p">,</span> <span class="s2">&quot;pool&quot;</span><span class="p">:</span> <span class="mf">10.0</span><span class="p">}}</span>
<span class="p">)</span>
</code></pre></div>
<p>This extension is how the <code>httpx</code> timeouts are implemented, ensuring that the timeout values are associated with the request instance and passed throughout the stack. You shouldn't typically be working with this extension directly, but use the higher level <code>timeout</code> API instead.</p>
<h3 id="target"><code>"target"</code></h3>
<p>The target that is used as <a href="https://datatracker.ietf.org/doc/html/rfc2616#section-5.1.2">the HTTP target instead of the URL path</a>.</p>
<p>This enables support constructing requests that would otherwise be unsupported.</p>
<ul>
<li>URL paths with non-standard escaping applied.</li>
<li>Forward proxy requests using an absolute URI.</li>
<li>Tunneling proxy requests using <code>CONNECT</code> with hostname as the target.</li>
<li>Server-wide <code>OPTIONS *</code> requests.</li>
</ul>
<p>Some examples:</p>
<p>Using the 'target' extension to send requests without the standard path escaping rules...</p>
<div class="highlight"><pre><span></span><code><span class="c1"># Typically a request to &quot;https://www.example.com/test^path&quot; would</span>
<span class="c1"># connect to &quot;www.example.com&quot; and send an HTTP/1.1 request like...</span>
<span class="c1">#</span>
<span class="c1"># GET /test%5Epath HTTP/1.1</span>
<span class="c1">#</span>
<span class="c1"># Using the target extension we can include the literal &#39;^&#39;...</span>
<span class="c1">#</span>
<span class="c1"># GET /test^path HTTP/1.1</span>
<span class="c1">#</span>
<span class="c1"># Note that requests must still be valid HTTP requests.</span>
<span class="c1"># For example including whitespace in the target will raise a `LocalProtocolError`.</span>
<span class="n">extensions</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;target&quot;</span><span class="p">:</span> <span class="sa">b</span><span class="s2">&quot;/test^path&quot;</span><span class="p">}</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">httpx</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;https://www.example.com&quot;</span><span class="p">,</span> <span class="n">extensions</span><span class="o">=</span><span class="n">extensions</span><span class="p">)</span>
</code></pre></div>
<p>The <code>target</code> extension also allows server-wide <code>OPTIONS *</code> requests to be constructed...</p>
<div class="highlight"><pre><span></span><code><span class="c1"># This will send the following request...</span>
<span class="c1">#</span>
<span class="c1"># CONNECT * HTTP/1.1</span>
<span class="n">extensions</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&quot;target&quot;</span><span class="p">:</span> <span class="sa">b</span><span class="s2">&quot;*&quot;</span><span class="p">}</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">httpx</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="s2">&quot;CONNECT&quot;</span><span class="p">,</span> <span class="s2">&quot;https://www.example.com&quot;</span><span class="p">,</span> <span class="n">extensions</span><span class="o">=</span><span class="n">extensions</span><span class="p">)</span>
</code></pre></div>
<h2 id="response-extensions">Response Extensions</h2>
<h3 id="http_version"><code>"http_version"</code></h3>
<p>The HTTP version, as bytes. Eg. <code>b"HTTP/1.1"</code>.</p>
<p>When using HTTP/1.1 the response line includes an explicit version, and the value of this key could feasibly be one of <code>b"HTTP/0.9"</code>, <code>b"HTTP/1.0"</code>, or <code>b"HTTP/1.1"</code>.</p>
<p>When using HTTP/2 there is no further response versioning included in the protocol, and the value of this key will always be <code>b"HTTP/2"</code>.</p>
<h3 id="reason_phrase"><code>"reason_phrase"</code></h3>
<p>The reason-phrase of the HTTP response, as bytes. For example <code>b"OK"</code>. Some servers may include a custom reason phrase, although this is not recommended.</p>
<p>HTTP/2 onwards does not include a reason phrase on the wire.</p>
<p>When no key is included, a default based on the status code may be used.</p>
<h3 id="stream_id"><code>"stream_id"</code></h3>
<p>When HTTP/2 is being used the <code>"stream_id"</code> response extension can be accessed to determine the ID of the data stream that the response was sent on.</p>
<h3 id="network_stream"><code>"network_stream"</code></h3>
<p>The <code>"network_stream"</code> extension allows developers to handle HTTP <code>CONNECT</code> and <code>Upgrade</code> requests, by providing an API that steps outside the standard request/response model, and can directly read or write to the network.</p>
<p>The interface provided by the network stream:</p>
<ul>
<li><code>read(max_bytes, timeout = None) -&gt; bytes</code></li>
<li><code>write(buffer, timeout = None)</code></li>
<li><code>close()</code></li>
<li><code>start_tls(ssl_context, server_hostname = None, timeout = None) -&gt; NetworkStream</code></li>
<li><code>get_extra_info(info) -&gt; Any</code></li>
</ul>
<p>This API can be used as the foundation for working with HTTP proxies, WebSocket upgrades, and other advanced use-cases.</p>
<p>See the <a href="https://www.encode.io/httpcore/network-backends/">network backends documentation</a> for more information on working directly with network streams.</p>
<p><strong>Extra network information</strong></p>
<p>The network stream abstraction also allows access to various low-level information that may be exposed by the underlying socket:</p>
<div class="highlight"><pre><span></span><code><span class="n">response</span> <span class="o">=</span> <span class="n">httpx</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;https://www.example.com&quot;</span><span class="p">)</span>
<span class="n">network_stream</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">extensions</span><span class="p">[</span><span class="s2">&quot;network_stream&quot;</span><span class="p">]</span>
<span class="n">client_addr</span> <span class="o">=</span> <span class="n">network_stream</span><span class="o">.</span><span class="n">get_extra_info</span><span class="p">(</span><span class="s2">&quot;client_addr&quot;</span><span class="p">)</span>
<span class="n">server_addr</span> <span class="o">=</span> <span class="n">network_stream</span><span class="o">.</span><span class="n">get_extra_info</span><span class="p">(</span><span class="s2">&quot;server_addr&quot;</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Client address&quot;</span><span class="p">,</span> <span class="n">client_addr</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Server address&quot;</span><span class="p">,</span> <span class="n">server_addr</span><span class="p">)</span>
</code></pre></div>
<p>The socket SSL information is also available through this interface, although you need to ensure that the underlying connection is still open, in order to access it...</p>
<div class="highlight"><pre><span></span><code><span class="k">with</span> <span class="n">httpx</span><span class="o">.</span><span class="n">stream</span><span class="p">(</span><span class="s2">&quot;GET&quot;</span><span class="p">,</span> <span class="s2">&quot;https://www.example.com&quot;</span><span class="p">)</span> <span class="k">as</span> <span class="n">response</span><span class="p">:</span>
<span class="n">network_stream</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">extensions</span><span class="p">[</span><span class="s2">&quot;network_stream&quot;</span><span class="p">]</span>
<span class="n">ssl_object</span> <span class="o">=</span> <span class="n">network_stream</span><span class="o">.</span><span class="n">get_extra_info</span><span class="p">(</span><span class="s2">&quot;ssl_object&quot;</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;TLS version&quot;</span><span class="p">,</span> <span class="n">ssl_object</span><span class="o">.</span><span class="n">version</span><span class="p">())</span>
</code></pre></div>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "../..", "features": [], "search": "../../assets/javascripts/workers/search.6ce7567c.min.js", "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}}</script>
<script src="../../assets/javascripts/bundle.83f73b43.min.js"></script>
</body>
</html>