1328 lines
51 KiB
HTML
1328 lines
51 KiB
HTML
|
|
<!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/authentication/">
|
|
|
|
|
|
<link rel="prev" href="../clients/">
|
|
|
|
|
|
<link rel="next" href="../ssl/">
|
|
|
|
|
|
<link rel="icon" href="../../assets/images/favicon.png">
|
|
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.5.47">
|
|
|
|
|
|
|
|
<title>Authentication - 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="#basic-authentication" 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">
|
|
|
|
Authentication
|
|
|
|
</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 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">
|
|
Authentication
|
|
</span>
|
|
|
|
|
|
<span class="md-nav__icon md-icon"></span>
|
|
</label>
|
|
|
|
<a href="./" class="md-nav__link md-nav__link--active">
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
Authentication
|
|
</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="#basic-authentication" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
Basic authentication
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#digest-authentication" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
Digest authentication
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#netrc-authentication" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
NetRC authentication
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#custom-authentication-schemes" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
Custom authentication schemes
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</nav>
|
|
|
|
</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">
|
|
<a href="../extensions/" class="md-nav__link">
|
|
|
|
|
|
<span class="md-ellipsis">
|
|
Extensions
|
|
</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_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="#basic-authentication" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
Basic authentication
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#digest-authentication" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
Digest authentication
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#netrc-authentication" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
NetRC authentication
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
<li class="md-nav__item">
|
|
<a href="#custom-authentication-schemes" class="md-nav__link">
|
|
<span class="md-ellipsis">
|
|
Custom authentication schemes
|
|
</span>
|
|
</a>
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="md-content" data-md-component="content">
|
|
<article class="md-content__inner md-typeset">
|
|
|
|
|
|
|
|
|
|
<h1>Authentication</h1>
|
|
|
|
<p>Authentication can either be included on a per-request basis...</p>
|
|
<div class="highlight"><pre><span></span><code><span class="gp">>>> </span><span class="n">auth</span> <span class="o">=</span> <span class="n">httpx</span><span class="o">.</span><span class="n">BasicAuth</span><span class="p">(</span><span class="n">username</span><span class="o">=</span><span class="s2">"username"</span><span class="p">,</span> <span class="n">password</span><span class="o">=</span><span class="s2">"secret"</span><span class="p">)</span>
|
|
<span class="gp">>>> </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="gp">>>> </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">"https://www.example.com/"</span><span class="p">,</span> <span class="n">auth</span><span class="o">=</span><span class="n">auth</span><span class="p">)</span>
|
|
</code></pre></div>
|
|
|
|
<p>Or configured on the client instance, ensuring that all outgoing requests will include authentication credentials...</p>
|
|
<div class="highlight"><pre><span></span><code><span class="gp">>>> </span><span class="n">auth</span> <span class="o">=</span> <span class="n">httpx</span><span class="o">.</span><span class="n">BasicAuth</span><span class="p">(</span><span class="n">username</span><span class="o">=</span><span class="s2">"username"</span><span class="p">,</span> <span class="n">password</span><span class="o">=</span><span class="s2">"secret"</span><span class="p">)</span>
|
|
<span class="gp">>>> </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">auth</span><span class="o">=</span><span class="n">auth</span><span class="p">)</span>
|
|
<span class="gp">>>> </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">"https://www.example.com/"</span><span class="p">)</span>
|
|
</code></pre></div>
|
|
|
|
<h2 id="basic-authentication">Basic authentication</h2>
|
|
<p>HTTP basic authentication is an unencrypted authentication scheme that uses a simple encoding of the username and password in the request <code>Authorization</code> header. Since it is unencrypted it should typically only be used over <code>https</code>, although this is not strictly enforced.</p>
|
|
<div class="highlight"><pre><span></span><code><span class="gp">>>> </span><span class="n">auth</span> <span class="o">=</span> <span class="n">httpx</span><span class="o">.</span><span class="n">BasicAuth</span><span class="p">(</span><span class="n">username</span><span class="o">=</span><span class="s2">"finley"</span><span class="p">,</span> <span class="n">password</span><span class="o">=</span><span class="s2">"secret"</span><span class="p">)</span>
|
|
<span class="gp">>>> </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">auth</span><span class="o">=</span><span class="n">auth</span><span class="p">)</span>
|
|
<span class="gp">>>> </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">"https://httpbin.org/basic-auth/finley/secret"</span><span class="p">)</span>
|
|
<span class="gp">>>> </span><span class="n">response</span>
|
|
<span class="go"><Response [200 OK]></span>
|
|
</code></pre></div>
|
|
|
|
<h2 id="digest-authentication">Digest authentication</h2>
|
|
<p>HTTP digest authentication is a challenge-response authentication scheme. Unlike basic authentication it provides encryption, and can be used over unencrypted <code>http</code> connections. It requires an additional round-trip in order to negotiate the authentication. </p>
|
|
<div class="highlight"><pre><span></span><code><span class="gp">>>> </span><span class="n">auth</span> <span class="o">=</span> <span class="n">httpx</span><span class="o">.</span><span class="n">DigestAuth</span><span class="p">(</span><span class="n">username</span><span class="o">=</span><span class="s2">"olivia"</span><span class="p">,</span> <span class="n">password</span><span class="o">=</span><span class="s2">"secret"</span><span class="p">)</span>
|
|
<span class="gp">>>> </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">auth</span><span class="o">=</span><span class="n">auth</span><span class="p">)</span>
|
|
<span class="gp">>>> </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">"https://httpbin.org/digest-auth/auth/olivia/secret"</span><span class="p">)</span>
|
|
<span class="gp">>>> </span><span class="n">response</span>
|
|
<span class="go"><Response [200 OK]></span>
|
|
<span class="gp">>>> </span><span class="n">response</span><span class="o">.</span><span class="n">history</span>
|
|
<span class="go">[<Response [401 UNAUTHORIZED]>]</span>
|
|
</code></pre></div>
|
|
|
|
<h2 id="netrc-authentication">NetRC authentication</h2>
|
|
<p>HTTPX can be configured to use <a href="https://everything.curl.dev/usingcurl/netrc">a <code>.netrc</code> config file</a> for authentication.</p>
|
|
<p>The <code>.netrc</code> config file allows authentication credentials to be associated with specified hosts. When a request is made to a host that is found in the netrc file, the username and password will be included using HTTP basic authentication.</p>
|
|
<p>Example <code>.netrc</code> file:</p>
|
|
<div class="highlight"><pre><span></span><code>machine example.org
|
|
login example-username
|
|
password example-password
|
|
|
|
machine python-httpx.org
|
|
login other-username
|
|
password other-password
|
|
</code></pre></div>
|
|
|
|
<p>Some examples of configuring <code>.netrc</code> authentication with <code>httpx</code>.</p>
|
|
<p>Use the default <code>.netrc</code> file in the users home directory:</p>
|
|
<div class="highlight"><pre><span></span><code><span class="gp">>>> </span><span class="n">auth</span> <span class="o">=</span> <span class="n">httpx</span><span class="o">.</span><span class="n">NetRCAuth</span><span class="p">()</span>
|
|
<span class="gp">>>> </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">auth</span><span class="o">=</span><span class="n">auth</span><span class="p">)</span>
|
|
</code></pre></div>
|
|
|
|
<p>Use an explicit path to a <code>.netrc</code> file:</p>
|
|
<div class="highlight"><pre><span></span><code><span class="gp">>>> </span><span class="n">auth</span> <span class="o">=</span> <span class="n">httpx</span><span class="o">.</span><span class="n">NetRCAuth</span><span class="p">(</span><span class="n">file</span><span class="o">=</span><span class="s2">"/path/to/.netrc"</span><span class="p">)</span>
|
|
<span class="gp">>>> </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">auth</span><span class="o">=</span><span class="n">auth</span><span class="p">)</span>
|
|
</code></pre></div>
|
|
|
|
<p>Use the <code>NETRC</code> environment variable to configure a path to the <code>.netrc</code> file,
|
|
or fallback to the default.</p>
|
|
<div class="highlight"><pre><span></span><code><span class="gp">>>> </span><span class="n">auth</span> <span class="o">=</span> <span class="n">httpx</span><span class="o">.</span><span class="n">NetRCAuth</span><span class="p">(</span><span class="n">file</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"NETRC"</span><span class="p">))</span>
|
|
<span class="gp">>>> </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">auth</span><span class="o">=</span><span class="n">auth</span><span class="p">)</span>
|
|
</code></pre></div>
|
|
|
|
<p>The <code>NetRCAuth()</code> class uses <a href="https://docs.python.org/3/library/netrc.html">the <code>netrc.netrc()</code> function from the Python standard library</a>. See the documentation there for more details on exceptions that may be raised if the <code>.netrc</code> file is not found, or cannot be parsed.</p>
|
|
<h2 id="custom-authentication-schemes">Custom authentication schemes</h2>
|
|
<p>When issuing requests or instantiating a client, the <code>auth</code> argument can be used to pass an authentication scheme to use. The <code>auth</code> argument may be one of the following...</p>
|
|
<ul>
|
|
<li>A two-tuple of <code>username</code>/<code>password</code>, to be used with basic authentication.</li>
|
|
<li>An instance of <code>httpx.BasicAuth()</code>, <code>httpx.DigestAuth()</code>, or <code>httpx.NetRCAuth()</code>.</li>
|
|
<li>A callable, accepting a request and returning an authenticated request instance.</li>
|
|
<li>An instance of subclasses of <code>httpx.Auth</code>.</li>
|
|
</ul>
|
|
<p>The most involved of these is the last, which allows you to create authentication flows involving one or more requests. A subclass of <code>httpx.Auth</code> should implement <code>def auth_flow(request)</code>, and yield any requests that need to be made...</p>
|
|
<div class="highlight"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="nc">MyCustomAuth</span><span class="p">(</span><span class="n">httpx</span><span class="o">.</span><span class="n">Auth</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">token</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">token</span> <span class="o">=</span> <span class="n">token</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">auth_flow</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
|
|
<span class="c1"># Send the request, with a custom `X-Authentication` header.</span>
|
|
<span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s1">'X-Authentication'</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">token</span>
|
|
<span class="k">yield</span> <span class="n">request</span>
|
|
</code></pre></div>
|
|
|
|
<p>If the auth flow requires more than one request, you can issue multiple yields, and obtain the response in each case...</p>
|
|
<div class="highlight"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="nc">MyCustomAuth</span><span class="p">(</span><span class="n">httpx</span><span class="o">.</span><span class="n">Auth</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">token</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">token</span> <span class="o">=</span> <span class="n">token</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">auth_flow</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
|
|
<span class="n">response</span> <span class="o">=</span> <span class="k">yield</span> <span class="n">request</span>
|
|
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="o">==</span> <span class="mi">401</span><span class="p">:</span>
|
|
<span class="c1"># If the server issues a 401 response then resend the request,</span>
|
|
<span class="c1"># with a custom `X-Authentication` header.</span>
|
|
<span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s1">'X-Authentication'</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">token</span>
|
|
<span class="k">yield</span> <span class="n">request</span>
|
|
</code></pre></div>
|
|
|
|
<p>Custom authentication classes are designed to not perform any I/O, so that they may be used with both sync and async client instances. If you are implementing an authentication scheme that requires the request body, then you need to indicate this on the class using a <code>requires_request_body</code> property.</p>
|
|
<p>You will then be able to access <code>request.content</code> inside the <code>.auth_flow()</code> method.</p>
|
|
<div class="highlight"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="nc">MyCustomAuth</span><span class="p">(</span><span class="n">httpx</span><span class="o">.</span><span class="n">Auth</span><span class="p">):</span>
|
|
<span class="n">requires_request_body</span> <span class="o">=</span> <span class="kc">True</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">token</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">token</span> <span class="o">=</span> <span class="n">token</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">auth_flow</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
|
|
<span class="n">response</span> <span class="o">=</span> <span class="k">yield</span> <span class="n">request</span>
|
|
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="o">==</span> <span class="mi">401</span><span class="p">:</span>
|
|
<span class="c1"># If the server issues a 401 response then resend the request,</span>
|
|
<span class="c1"># with a custom `X-Authentication` header.</span>
|
|
<span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s1">'X-Authentication'</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sign_request</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
|
|
<span class="k">yield</span> <span class="n">request</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">sign_request</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
|
|
<span class="c1"># Create a request signature, based on `request.method`, `request.url`,</span>
|
|
<span class="c1"># `request.headers`, and `request.content`.</span>
|
|
<span class="o">...</span>
|
|
</code></pre></div>
|
|
|
|
<p>Similarly, if you are implementing a scheme that requires access to the response body, then use the <code>requires_response_body</code> property. You will then be able to access response body properties and methods such as <code>response.content</code>, <code>response.text</code>, <code>response.json()</code>, etc.</p>
|
|
<div class="highlight"><pre><span></span><code><span class="k">class</span><span class="w"> </span><span class="nc">MyCustomAuth</span><span class="p">(</span><span class="n">httpx</span><span class="o">.</span><span class="n">Auth</span><span class="p">):</span>
|
|
<span class="n">requires_response_body</span> <span class="o">=</span> <span class="kc">True</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">access_token</span><span class="p">,</span> <span class="n">refresh_token</span><span class="p">,</span> <span class="n">refresh_url</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">access_token</span> <span class="o">=</span> <span class="n">access_token</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">refresh_token</span> <span class="o">=</span> <span class="n">refresh_token</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">refresh_url</span> <span class="o">=</span> <span class="n">refresh_url</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">auth_flow</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
|
|
<span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s2">"X-Authentication"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">access_token</span>
|
|
<span class="n">response</span> <span class="o">=</span> <span class="k">yield</span> <span class="n">request</span>
|
|
|
|
<span class="k">if</span> <span class="n">response</span><span class="o">.</span><span class="n">status_code</span> <span class="o">==</span> <span class="mi">401</span><span class="p">:</span>
|
|
<span class="c1"># If the server issues a 401 response, then issue a request to</span>
|
|
<span class="c1"># refresh tokens, and resend the request.</span>
|
|
<span class="n">refresh_response</span> <span class="o">=</span> <span class="k">yield</span> <span class="bp">self</span><span class="o">.</span><span class="n">build_refresh_request</span><span class="p">()</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">update_tokens</span><span class="p">(</span><span class="n">refresh_response</span><span class="p">)</span>
|
|
|
|
<span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s2">"X-Authentication"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">access_token</span>
|
|
<span class="k">yield</span> <span class="n">request</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">build_refresh_request</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="c1"># Return an `httpx.Request` for refreshing tokens.</span>
|
|
<span class="o">...</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">update_tokens</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">response</span><span class="p">):</span>
|
|
<span class="c1"># Update the `.access_token` and `.refresh_token` tokens</span>
|
|
<span class="c1"># based on a refresh response.</span>
|
|
<span class="n">data</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
|
<span class="o">...</span>
|
|
</code></pre></div>
|
|
|
|
<p>If you <em>do</em> need to perform I/O other than HTTP requests, such as accessing a disk-based cache, or you need to use concurrency primitives, such as locks, then you should override <code>.sync_auth_flow()</code> and <code>.async_auth_flow()</code> (instead of <code>.auth_flow()</code>). The former will be used by <code>httpx.Client</code>, while the latter will be used by <code>httpx.AsyncClient</code>.</p>
|
|
<div class="highlight"><pre><span></span><code><span class="kn">import</span><span class="w"> </span><span class="nn">asyncio</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">threading</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">httpx</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">MyCustomAuth</span><span class="p">(</span><span class="n">httpx</span><span class="o">.</span><span class="n">Auth</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_sync_lock</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">RLock</span><span class="p">()</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_async_lock</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">Lock</span><span class="p">()</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">sync_get_token</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">_sync_lock</span><span class="p">:</span>
|
|
<span class="o">...</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">sync_auth_flow</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
|
|
<span class="n">token</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sync_get_token</span><span class="p">()</span>
|
|
<span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s2">"Authorization"</span><span class="p">]</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Token </span><span class="si">{</span><span class="n">token</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="k">yield</span> <span class="n">request</span>
|
|
|
|
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">async_get_token</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">async</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">_async_lock</span><span class="p">:</span>
|
|
<span class="o">...</span>
|
|
|
|
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">async_auth_flow</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
|
|
<span class="n">token</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">async_get_token</span><span class="p">()</span>
|
|
<span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s2">"Authorization"</span><span class="p">]</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Token </span><span class="si">{</span><span class="n">token</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="k">yield</span> <span class="n">request</span>
|
|
</code></pre></div>
|
|
|
|
<p>If you only want to support one of the two methods, then you should still override it, but raise an explicit <code>RuntimeError</code>.</p>
|
|
<div class="highlight"><pre><span></span><code><span class="kn">import</span><span class="w"> </span><span class="nn">httpx</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">sync_only_library</span>
|
|
|
|
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">MyCustomAuth</span><span class="p">(</span><span class="n">httpx</span><span class="o">.</span><span class="n">Auth</span><span class="p">):</span>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">sync_auth_flow</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
|
|
<span class="n">token</span> <span class="o">=</span> <span class="n">sync_only_library</span><span class="o">.</span><span class="n">get_token</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
|
|
<span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s2">"Authorization"</span><span class="p">]</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"Token </span><span class="si">{</span><span class="n">token</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="k">yield</span> <span class="n">request</span>
|
|
|
|
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="nf">async_auth_flow</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Cannot use a sync authentication class with httpx.AsyncClient"</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> |