Files
docs/libs/mail-intake/site/mail_intake/credentials/index.html
Vishesh 'ironeagle' Bangotra 9191de9dff
All checks were successful
continuous-integration/drone/push Build is passing
Build: 0.1.8
2026-03-08 01:01:39 +05:30

2136 lines
61 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. 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">
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.23">
<title>Credentials - mail_intake</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.84d31ad4.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=Inter:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Inter";--md-code-font:"JetBrains Mono"}</style>
<link rel="stylesheet" href="../../assets/_mkdocstrings.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="slate" data-md-color-primary="deep-purple" data-md-color-accent="cyan">
<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="#credentials" 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="mail_intake" class="md-header__button md-logo" aria-label="mail_intake" 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">
mail_intake
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Credentials
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="cyan" aria-hidden="true" type="radio" name="__palette" id="__palette_0">
</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">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
</a>
<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>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</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>
</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">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="mail_intake" class="md-nav__button md-logo" aria-label="mail_intake" 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>
mail_intake
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2" >
<div class="md-nav__link md-nav__container">
<a href="../../ingestion/" class="md-nav__link ">
<span class="md-ellipsis">
Core API
</span>
</a>
<label class="md-nav__link " for="__nav_2" id="__nav_2_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
Core API
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../ingestion/reader/" class="md-nav__link">
<span class="md-ellipsis">
Reader
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_3" >
<div class="md-nav__link md-nav__container">
<a href="../../models/" class="md-nav__link ">
<span class="md-ellipsis">
Domain Models
</span>
</a>
<label class="md-nav__link " for="__nav_3" id="__nav_3_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3">
<span class="md-nav__icon md-icon"></span>
Domain Models
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../models/message/" class="md-nav__link">
<span class="md-ellipsis">
Message
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../models/thread/" class="md-nav__link">
<span class="md-ellipsis">
Thread
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_4" >
<div class="md-nav__link md-nav__container">
<a href="../../adapters/" class="md-nav__link ">
<span class="md-ellipsis">
Provider Adapters
</span>
</a>
<label class="md-nav__link " for="__nav_4" id="__nav_4_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<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>
Provider Adapters
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../adapters/base/" class="md-nav__link">
<span class="md-ellipsis">
Base
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../adapters/gmail/" class="md-nav__link">
<span class="md-ellipsis">
Gmail
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_5" >
<div class="md-nav__link md-nav__container">
<a href="../../auth/" class="md-nav__link ">
<span class="md-ellipsis">
Authentication & Storage
</span>
</a>
<label class="md-nav__link " for="__nav_5" id="__nav_5_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<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>
Authentication & Storage
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../auth/base/" class="md-nav__link">
<span class="md-ellipsis">
Base
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../auth/google/" class="md-nav__link">
<span class="md-ellipsis">
Google
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../credentials/" class="md-nav__link">
<span class="md-ellipsis">
Credentials
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../credentials/store/" class="md-nav__link">
<span class="md-ellipsis">
Store
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../credentials/pickle/" class="md-nav__link">
<span class="md-ellipsis">
Pickle
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../credentials/redis/" class="md-nav__link">
<span class="md-ellipsis">
Redis
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_6" >
<div class="md-nav__link md-nav__container">
<a href="../../parsers/" class="md-nav__link ">
<span class="md-ellipsis">
Normalization & Parsing
</span>
</a>
<label class="md-nav__link " for="__nav_6" id="__nav_6_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<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>
Normalization & Parsing
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../parsers/body/" class="md-nav__link">
<span class="md-ellipsis">
Body
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../parsers/headers/" class="md-nav__link">
<span class="md-ellipsis">
Headers
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../parsers/subject/" class="md-nav__link">
<span class="md-ellipsis">
Subject
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_7" >
<label class="md-nav__link" for="__nav_7" id="__nav_7_label" tabindex="">
<span class="md-ellipsis">
Configuration & Errors
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_7_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_7">
<span class="md-nav__icon md-icon"></span>
Configuration & Errors
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../config/" class="md-nav__link">
<span class="md-ellipsis">
Config
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../exceptions/" class="md-nav__link">
<span class="md-ellipsis">
Exceptions
</span>
</a>
</li>
</ul>
</nav>
</li>
</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="#mail_intake.credentials" class="md-nav__link">
<span class="md-ellipsis">
credentials
</span>
</a>
<nav class="md-nav" aria-label="credentials">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#mail_intake.credentials--summary" class="md-nav__link">
<span class="md-ellipsis">
Summary
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#mail_intake.credentials--public-api" class="md-nav__link">
<span class="md-ellipsis">
Public API
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#mail_intake.credentials-classes" class="md-nav__link">
<span class="md-ellipsis">
Classes
</span>
</a>
<nav class="md-nav" aria-label="Classes">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#mail_intake.credentials.CredentialStore" class="md-nav__link">
<span class="md-ellipsis">
CredentialStore
</span>
</a>
<nav class="md-nav" aria-label="CredentialStore">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#mail_intake.credentials.CredentialStore-functions" class="md-nav__link">
<span class="md-ellipsis">
Functions
</span>
</a>
<nav class="md-nav" aria-label="Functions">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#mail_intake.credentials.CredentialStore.clear" class="md-nav__link">
<span class="md-ellipsis">
clear
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#mail_intake.credentials.CredentialStore.load" class="md-nav__link">
<span class="md-ellipsis">
load
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#mail_intake.credentials.CredentialStore.save" class="md-nav__link">
<span class="md-ellipsis">
save
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#mail_intake.credentials.PickleCredentialStore" class="md-nav__link">
<span class="md-ellipsis">
PickleCredentialStore
</span>
</a>
<nav class="md-nav" aria-label="PickleCredentialStore">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#mail_intake.credentials.PickleCredentialStore-functions" class="md-nav__link">
<span class="md-ellipsis">
Functions
</span>
</a>
<nav class="md-nav" aria-label="Functions">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#mail_intake.credentials.PickleCredentialStore.clear" class="md-nav__link">
<span class="md-ellipsis">
clear
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#mail_intake.credentials.PickleCredentialStore.load" class="md-nav__link">
<span class="md-ellipsis">
load
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#mail_intake.credentials.PickleCredentialStore.save" class="md-nav__link">
<span class="md-ellipsis">
save
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#mail_intake.credentials.RedisCredentialStore" class="md-nav__link">
<span class="md-ellipsis">
RedisCredentialStore
</span>
</a>
<nav class="md-nav" aria-label="RedisCredentialStore">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#mail_intake.credentials.RedisCredentialStore-functions" class="md-nav__link">
<span class="md-ellipsis">
Functions
</span>
</a>
<nav class="md-nav" aria-label="Functions">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#mail_intake.credentials.RedisCredentialStore.clear" class="md-nav__link">
<span class="md-ellipsis">
clear
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#mail_intake.credentials.RedisCredentialStore.load" class="md-nav__link">
<span class="md-ellipsis">
load
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#mail_intake.credentials.RedisCredentialStore.save" class="md-nav__link">
<span class="md-ellipsis">
save
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</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="credentials">Credentials</h1>
<div class="doc doc-object doc-module">
<h2 id="mail_intake.credentials" class="doc doc-heading">
<code class="doc-symbol doc-symbol-heading doc-symbol-module"></code> <span class="doc doc-object-name doc-module-name">mail_intake.credentials</span>
</h2>
<div class="doc doc-contents first">
<p>Credential persistence interfaces and implementations for Mail Intake.</p>
<hr />
<h4 id="mail_intake.credentials--summary">Summary</h4>
<p>This package defines the abstractions and concrete implementations used
to persist authentication credentials across Mail Intake components.</p>
<p>The credential persistence layer is intentionally decoupled from
authentication logic. Authentication providers are responsible for
credential acquisition, validation, and refresh, while implementations
within this package are responsible solely for storage and retrieval.</p>
<p>The package provides:
- A generic <code>CredentialStore</code> abstraction defining the persistence contract
- Local filesystembased storage for development and single-node use
- Distributed, Redis-backed storage for production and scaled deployments</p>
<p>Credential lifecycle management, interpretation, and security policy
decisions remain the responsibility of authentication providers.</p>
<hr />
<h4 id="mail_intake.credentials--public-api">Public API</h4>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span></pre></div></td><td class="code"><div><pre><span></span><code>CredentialStore
PickleCredentialStore
RedisCredentialStore
</code></pre></div></td></tr></table></div>
<hr />
<div class="doc doc-children">
<h3 id="mail_intake.credentials-classes">Classes</h3>
<div class="doc doc-object doc-class">
<h4 id="mail_intake.credentials.CredentialStore" class="doc doc-heading">
<code class="doc-symbol doc-symbol-heading doc-symbol-class"></code> <span class="doc doc-object-name doc-class-name">CredentialStore</span>
</h4>
<div class="doc doc-contents ">
<p class="doc doc-class-bases">
Bases: <code><span title="abc.ABC">ABC</span></code>, <code><span title="typing.Generic">Generic</span>[<span title="mail_intake.credentials.store.T">T</span>]</code></p>
<p>Abstract base class defining a generic persistence interface for
authentication credentials.</p>
<details class="notes" open>
<summary>Notes</summary>
<p><strong>Responsibilities:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>- Provide persistent storage separating life-cycle management from storage mechanics
- Keep implementation focused only on persistence
</code></pre></div></td></tr></table></div>
<p><strong>Constraints:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span>
<span class="normal">4</span></pre></div></td><td class="code"><div><pre><span></span><code>- The store is intentionally agnostic to:
- The concrete credential type being stored
- The serialization format used to persist credentials
- The underlying storage backend or durability guarantees
</code></pre></div></td></tr></table></div>
</details>
<div class="doc doc-children">
<h5 id="mail_intake.credentials.CredentialStore-functions">Functions</h5>
<div class="doc doc-object doc-function">
<h6 id="mail_intake.credentials.CredentialStore.clear" class="doc doc-heading">
<code class="doc-symbol doc-symbol-heading doc-symbol-method"></code> <span class="doc doc-object-name doc-function-name">clear</span>
<span class="doc doc-labels">
<small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small>
</span>
</h6>
<div class="language-python doc-signature highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1">1</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">clear</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kc">None</span>
</span></code></pre></div></td></tr></table></div>
<div class="doc doc-contents ">
<p>Remove any persisted credentials from the store.</p>
<details class="notes" open>
<summary>Notes</summary>
<p><strong>Lifecycle:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>- This method is called when credentials are known to be invalid, revoked, corrupted, or otherwise unusable
- Must ensure that no stale authentication material remains accessible
</code></pre></div></td></tr></table></div>
<p><strong>Guarantees:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>- Implementations should treat this operation as idempotent
</code></pre></div></td></tr></table></div>
</details>
</div>
</div>
<div class="doc doc-object doc-function">
<h6 id="mail_intake.credentials.CredentialStore.load" class="doc doc-heading">
<code class="doc-symbol doc-symbol-heading doc-symbol-method"></code> <span class="doc doc-object-name doc-function-name">load</span>
<span class="doc doc-labels">
<small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small>
</span>
</h6>
<div class="language-python doc-signature highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1">1</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">load</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">Optional</span><span class="p">[</span><span class="n">T</span><span class="p">]</span>
</span></code></pre></div></td></tr></table></div>
<div class="doc doc-contents ">
<p>Load previously persisted credentials.</p>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><span title="typing.Optional">Optional</span>[<span title="mail_intake.credentials.store.T">T</span>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Optional[T]:
An instance of type <code>T</code> if credentials are available and
loadable; otherwise <code>None</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
<details class="notes" open>
<summary>Notes</summary>
<p><strong>Guarantees:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>- Implementations should return ``None`` when no credentials are present or when stored credentials cannot be successfully decoded or deserialized
- The store must not attempt to validate, refresh, or otherwise interpret the returned credentials
</code></pre></div></td></tr></table></div>
</details>
</div>
</div>
<div class="doc doc-object doc-function">
<h6 id="mail_intake.credentials.CredentialStore.save" class="doc doc-heading">
<code class="doc-symbol doc-symbol-heading doc-symbol-method"></code> <span class="doc doc-object-name doc-function-name">save</span>
<span class="doc doc-labels">
<small class="doc doc-label doc-label-abstractmethod"><code>abstractmethod</code></small>
</span>
</h6>
<div class="language-python doc-signature highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1">1</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">save</span><span class="p">(</span><span class="n">credentials</span><span class="p">:</span> <span class="n">T</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span>
</span></code></pre></div></td></tr></table></div>
<div class="doc doc-contents ">
<p>Persist credentials to the underlying storage backend.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td><code>credentials</code></td>
<td>
<code><span title="mail_intake.credentials.store.T">T</span></code>
</td>
<td>
<div class="doc-md-description">
<p>The credential object to persist.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<details class="notes" open>
<summary>Notes</summary>
<p><strong>Lifecycle:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>- This method is invoked when credentials are newly obtained or have been refreshed and are known to be valid at the time of persistence
</code></pre></div></td></tr></table></div>
<p><strong>Responsibilities:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span></pre></div></td><td class="code"><div><pre><span></span><code>- Ensuring durability appropriate to the deployment context
- Applying encryption or access controls where required
- Overwriting any previously stored credentials
</code></pre></div></td></tr></table></div>
</details>
</div>
</div>
</div>
</div>
</div>
<div class="doc doc-object doc-class">
<h4 id="mail_intake.credentials.PickleCredentialStore" class="doc doc-heading">
<code class="doc-symbol doc-symbol-heading doc-symbol-class"></code> <span class="doc doc-object-name doc-class-name">PickleCredentialStore</span>
</h4>
<div class="language-python doc-signature highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1">1</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">PickleCredentialStore</span><span class="p">(</span><span class="n">path</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span>
</span></code></pre></div></td></tr></table></div>
<div class="doc doc-contents ">
<p class="doc doc-class-bases">
Bases: <code><a class="autorefs autorefs-internal" title="mail_intake.credentials.store.CredentialStore" href="store/#mail_intake.credentials.store.CredentialStore">CredentialStore</a>[<span title="mail_intake.credentials.pickle.T">T</span>]</code></p>
<p>Filesystem-backed credential store using pickle serialization.</p>
<p>This store persists credentials as a pickled object on the local
filesystem. It is a simple implementation intended primarily for
development, testing, and single-process execution contexts.</p>
<details class="notes" open>
<summary>Notes</summary>
<p><strong>Guarantees:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span></pre></div></td><td class="code"><div><pre><span></span><code>- Stores credentials on the local filesystem
- Uses pickle for serialization and deserialization
- Does not provide encryption, locking, or concurrency guarantees
</code></pre></div></td></tr></table></div>
<p><strong>Constraints:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>- Credential lifecycle management, validation, and refresh logic are explicitly out of scope for this class
</code></pre></div></td></tr></table></div>
</details>
<p>Initialize a pickle-backed credential store.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td><code>path</code></td>
<td>
<code>str</code>
</td>
<td>
<div class="doc-md-description">
<p>Filesystem path where credentials will be stored.
The file will be created or overwritten as needed.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<div class="doc doc-children">
<h5 id="mail_intake.credentials.PickleCredentialStore-functions">Functions</h5>
<div class="doc doc-object doc-function">
<h6 id="mail_intake.credentials.PickleCredentialStore.clear" class="doc doc-heading">
<code class="doc-symbol doc-symbol-heading doc-symbol-method"></code> <span class="doc doc-object-name doc-function-name">clear</span>
</h6>
<div class="language-python doc-signature highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1">1</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">clear</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kc">None</span>
</span></code></pre></div></td></tr></table></div>
<div class="doc doc-contents ">
<p>Remove persisted credentials from the local filesystem.</p>
<details class="notes" open>
<summary>Notes</summary>
<p><strong>Lifecycle:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>- This method deletes the credential file if it exists and should be treated as an idempotent operation
</code></pre></div></td></tr></table></div>
</details>
</div>
</div>
<div class="doc doc-object doc-function">
<h6 id="mail_intake.credentials.PickleCredentialStore.load" class="doc doc-heading">
<code class="doc-symbol doc-symbol-heading doc-symbol-method"></code> <span class="doc doc-object-name doc-function-name">load</span>
</h6>
<div class="language-python doc-signature highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1">1</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">load</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">Optional</span><span class="p">[</span><span class="n">T</span><span class="p">]</span>
</span></code></pre></div></td></tr></table></div>
<div class="doc doc-contents ">
<p>Load credentials from the local filesystem.</p>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><span title="typing.Optional">Optional</span>[<span title="mail_intake.credentials.pickle.T">T</span>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Optional[T]:
An instance of type <code>T</code> if credentials are present and
successfully deserialized; otherwise <code>None</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
<details class="notes" open>
<summary>Notes</summary>
<p><strong>Guarantees:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>- If the credential file does not exist or cannot be successfully deserialized, this method returns ``None``
- The store does not attempt to validate or interpret the returned credentials
</code></pre></div></td></tr></table></div>
</details>
</div>
</div>
<div class="doc doc-object doc-function">
<h6 id="mail_intake.credentials.PickleCredentialStore.save" class="doc doc-heading">
<code class="doc-symbol doc-symbol-heading doc-symbol-method"></code> <span class="doc doc-object-name doc-function-name">save</span>
</h6>
<div class="language-python doc-signature highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1">1</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">save</span><span class="p">(</span><span class="n">credentials</span><span class="p">:</span> <span class="n">T</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span>
</span></code></pre></div></td></tr></table></div>
<div class="doc doc-contents ">
<p>Persist credentials to the local filesystem.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td><code>credentials</code></td>
<td>
<code><span title="mail_intake.credentials.pickle.T">T</span></code>
</td>
<td>
<div class="doc-md-description">
<p>The credential object to persist.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<details class="notes" open>
<summary>Notes</summary>
<p><strong>Responsibilities:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span></pre></div></td><td class="code"><div><pre><span></span><code>- Any previously stored credentials at the configured path are overwritten
</code></pre></div></td></tr></table></div>
</details>
</div>
</div>
</div>
</div>
</div>
<div class="doc doc-object doc-class">
<h4 id="mail_intake.credentials.RedisCredentialStore" class="doc doc-heading">
<code class="doc-symbol doc-symbol-heading doc-symbol-class"></code> <span class="doc doc-object-name doc-class-name">RedisCredentialStore</span>
</h4>
<div class="language-python doc-signature highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1">1</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">RedisCredentialStore</span><span class="p">(</span><span class="n">redis_client</span><span class="p">:</span> <span class="n">Any</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">serialize</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[[</span><span class="n">T</span><span class="p">],</span> <span class="nb">bytes</span><span class="p">],</span> <span class="n">deserialize</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[[</span><span class="nb">bytes</span><span class="p">],</span> <span class="n">T</span><span class="p">],</span> <span class="n">ttl_seconds</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span>
</span></code></pre></div></td></tr></table></div>
<div class="doc doc-contents ">
<p class="doc doc-class-bases">
Bases: <code><a class="autorefs autorefs-internal" title="mail_intake.credentials.store.CredentialStore" href="store/#mail_intake.credentials.store.CredentialStore">CredentialStore</a>[<span title="mail_intake.credentials.redis.T">T</span>]</code></p>
<p>Redis-backed implementation of <code>CredentialStore</code>.</p>
<p>This store persists credentials in Redis and is suitable for
distributed and horizontally scaled deployments where credentials
must be shared across multiple processes or nodes.</p>
<details class="notes" open>
<summary>Notes</summary>
<p><strong>Responsibilities:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>- This class is responsible only for persistence and retrieval
- It does not interpret, validate, refresh, or otherwise manage the lifecycle of the credentials being stored
</code></pre></div></td></tr></table></div>
<p><strong>Guarantees:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>- The store is intentionally generic and delegates all serialization concerns to caller-provided functions
- This avoids unsafe mechanisms such as pickle and allows credential formats to be explicitly controlled and audited
</code></pre></div></td></tr></table></div>
</details>
<p>Initialize a Redis-backed credential store.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td><code>redis_client</code></td>
<td>
<code><span title="typing.Any">Any</span></code>
</td>
<td>
<div class="doc-md-description">
<p>An initialized Redis client instance (for example, <code>redis.Redis</code> or a compatible interface) used to communicate with the Redis server.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td><code>key</code></td>
<td>
<code>str</code>
</td>
<td>
<div class="doc-md-description">
<p>The Redis key under which credentials are stored. Callers are responsible for applying appropriate namespacing to avoid collisions.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td><code>serialize</code></td>
<td>
<code><span title="typing.Callable">Callable</span>[[<span title="mail_intake.credentials.redis.T">T</span>], bytes]</code>
</td>
<td>
<div class="doc-md-description">
<p>A callable that converts a credential object of type <code>T</code> into a <code>bytes</code> representation suitable for storage in Redis.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td><code>deserialize</code></td>
<td>
<code><span title="typing.Callable">Callable</span>[[bytes], <span title="mail_intake.credentials.redis.T">T</span>]</code>
</td>
<td>
<div class="doc-md-description">
<p>A callable that converts a <code>bytes</code> payload retrieved from Redis back into a credential object of type <code>T</code>.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
<tr class="doc-section-item">
<td><code>ttl_seconds</code></td>
<td>
<code><span title="typing.Optional">Optional</span>[int]</code>
</td>
<td>
<div class="doc-md-description">
<p>Optional time-to-live (TTL) for the stored credentials, expressed in seconds. When provided, Redis will automatically expire the stored credentials after the specified duration. If <code>None</code>, credentials are stored without an expiration.</p>
</div>
</td>
<td>
<code>None</code>
</td>
</tr>
</tbody>
</table>
<div class="doc doc-children">
<h5 id="mail_intake.credentials.RedisCredentialStore-functions">Functions</h5>
<div class="doc doc-object doc-function">
<h6 id="mail_intake.credentials.RedisCredentialStore.clear" class="doc doc-heading">
<code class="doc-symbol doc-symbol-heading doc-symbol-method"></code> <span class="doc doc-object-name doc-function-name">clear</span>
</h6>
<div class="language-python doc-signature highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1">1</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">clear</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="kc">None</span>
</span></code></pre></div></td></tr></table></div>
<div class="doc doc-contents ">
<p>Remove stored credentials from Redis.</p>
<details class="notes" open>
<summary>Notes</summary>
<p><strong>Lifecycle:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>- This operation deletes the configured Redis key if it exists
- Implementations should treat this method as idempotent
</code></pre></div></td></tr></table></div>
</details>
</div>
</div>
<div class="doc doc-object doc-function">
<h6 id="mail_intake.credentials.RedisCredentialStore.load" class="doc doc-heading">
<code class="doc-symbol doc-symbol-heading doc-symbol-method"></code> <span class="doc doc-object-name doc-function-name">load</span>
</h6>
<div class="language-python doc-signature highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1">1</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">load</span><span class="p">()</span> <span class="o">-&gt;</span> <span class="n">Optional</span><span class="p">[</span><span class="n">T</span><span class="p">]</span>
</span></code></pre></div></td></tr></table></div>
<div class="doc doc-contents ">
<p>Load credentials from Redis.</p>
<p><span class="doc-section-title">Returns:</span></p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td>
<code><span title="typing.Optional">Optional</span>[<span title="mail_intake.credentials.redis.T">T</span>]</code>
</td>
<td>
<div class="doc-md-description">
<p>Optional[T]:
An instance of type <code>T</code> if credentials are present and
successfully deserialized; otherwise <code>None</code>.</p>
</div>
</td>
</tr>
</tbody>
</table>
<details class="notes" open>
<summary>Notes</summary>
<p><strong>Guarantees:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>- If no value exists for the configured key, or if the stored payload cannot be successfully deserialized, this method returns ``None``
- The store does not attempt to validate the returned credentials or determine whether they are expired or otherwise usable
</code></pre></div></td></tr></table></div>
</details>
</div>
</div>
<div class="doc doc-object doc-function">
<h6 id="mail_intake.credentials.RedisCredentialStore.save" class="doc doc-heading">
<code class="doc-symbol doc-symbol-heading doc-symbol-method"></code> <span class="doc doc-object-name doc-function-name">save</span>
</h6>
<div class="language-python doc-signature highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1">1</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="nf">save</span><span class="p">(</span><span class="n">credentials</span><span class="p">:</span> <span class="n">T</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span>
</span></code></pre></div></td></tr></table></div>
<div class="doc doc-contents ">
<p>Persist credentials to Redis.</p>
<p><span class="doc-section-title">Parameters:</span></p>
<table>
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Description</th>
<th>Default</th>
</tr>
</thead>
<tbody>
<tr class="doc-section-item">
<td><code>credentials</code></td>
<td>
<code><span title="mail_intake.credentials.redis.T">T</span></code>
</td>
<td>
<div class="doc-md-description">
<p>The credential object to persist.</p>
</div>
</td>
<td>
<em>required</em>
</td>
</tr>
</tbody>
</table>
<details class="notes" open>
<summary>Notes</summary>
<p><strong>Responsibilities:</strong></p>
<div class="language-text highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal">1</span>
<span class="normal">2</span></pre></div></td><td class="code"><div><pre><span></span><code>- Any previously stored credentials under the same key are overwritten
- If a TTL is configured, the credentials will expire automatically after the specified duration
</code></pre></div></td></tr></table></div>
</details>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div><ul>
<li><a href="pickle/">Pickle</a></li>
<li><a href="redis/">Redis</a></li>
<li><a href="store/">Store</a></li>
</ul>
</article>
</div>
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</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": ["navigation.sections", "navigation.expand", "navigation.top", "navigation.instant", "navigation.tracking", "navigation.indexes", "content.code.copy", "content.code.annotate", "content.tabs.link", "content.action.edit", "search.highlight", "search.share", "search.suggest"], "search": "../../assets/javascripts/workers/search.973d3a69.min.js", "tags": null, "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"}, "version": null}</script>
<script src="../../assets/javascripts/bundle.f55a23d4.min.js"></script>
</body>
</html>