Skip to content

Commit

Permalink
docs: Update docs
Browse files Browse the repository at this point in the history
  • Loading branch information
ecederstrand committed May 14, 2024
1 parent 39df56a commit 73d3167
Show file tree
Hide file tree
Showing 13 changed files with 1,368 additions and 655 deletions.
4 changes: 2 additions & 2 deletions docs/exchangelib/autodiscover/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ <h1 class="title">Module <code>exchangelib.autodiscover</code></h1>
&#34;AutodiscoverCache&#34;,
&#34;AutodiscoverProtocol&#34;,
&#34;Autodiscovery&#34;,
&#34;discover&#34;,
&#34;autodiscover_cache&#34;,
&#34;close_connections&#34;,
&#34;clear_cache&#34;,
&#34;close_connections&#34;,
&#34;discover&#34;,
]</code></pre>
</details>
</section>
Expand Down
69 changes: 67 additions & 2 deletions docs/exchangelib/configuration.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ <h1 class="title">Module <code>exchangelib.configuration</code></h1>

from cached_property import threaded_cached_property

from .credentials import BaseCredentials, BaseOAuth2Credentials
from .credentials import BaseCredentials, BaseOAuth2Credentials, O365InteractiveCredentials
from .errors import InvalidEnumValue, InvalidTypeError
from .protocol import FailFast, RetryPolicy
from .transport import AUTH_TYPE_MAP, CREDENTIALS_REQUIRED, OAUTH2
Expand Down Expand Up @@ -123,7 +123,15 @@ <h1 class="title">Module <code>exchangelib.configuration</code></h1>
f&#34;{k}={getattr(self, k)!r}&#34;
for k in (&#34;credentials&#34;, &#34;service_endpoint&#34;, &#34;auth_type&#34;, &#34;version&#34;, &#34;retry_policy&#34;)
)
return f&#34;{self.__class__.__name__}({args_str})&#34;</code></pre>
return f&#34;{self.__class__.__name__}({args_str})&#34;


class O365InteractiveConfiguration(Configuration):
SERVER = &#34;outlook.office365.com&#34;

def __init__(self, client_id, username):
credentials = O365InteractiveCredentials(client_id=client_id, username=username)
super().__init__(server=self.SERVER, auth_type=OAUTH2, credentials=credentials)</code></pre>
</details>
</section>
<section>
Expand Down Expand Up @@ -248,6 +256,10 @@ <h2 class="section-title" id="header-classes">Classes</h2>
)
return f&#34;{self.__class__.__name__}({args_str})&#34;</code></pre>
</details>
<h3>Subclasses</h3>
<ul class="hlist">
<li><a title="exchangelib.configuration.O365InteractiveConfiguration" href="#exchangelib.configuration.O365InteractiveConfiguration">O365InteractiveConfiguration</a></li>
</ul>
<h3>Instance variables</h3>
<dl>
<dt id="exchangelib.configuration.Configuration.credentials"><code class="name">var <span class="ident">credentials</span></code></dt>
Expand Down Expand Up @@ -288,6 +300,53 @@ <h3>Instance variables</h3>
</dd>
</dl>
</dd>
<dt id="exchangelib.configuration.O365InteractiveConfiguration"><code class="flex name class">
<span>class <span class="ident">O365InteractiveConfiguration</span></span>
<span>(</span><span>client_id, username)</span>
</code></dt>
<dd>
<div class="desc"><p>Contains information needed to create an authenticated connection to an EWS endpoint.</p>
<p>The 'credentials' argument contains the credentials needed to authenticate with the server. Multiple credentials
implementations are available in 'exchangelib.credentials'.</p>
<p>config = Configuration(credentials=Credentials('[email protected]', 'MY_SECRET'), &hellip;)</p>
<p>The 'server' and 'service_endpoint' arguments are mutually exclusive. The former must contain only a domain name,
the latter a full URL:</p>
<pre><code>config = Configuration(server='example.com', ...)
config = Configuration(service_endpoint='https://mail.example.com/EWS/Exchange.asmx', ...)
</code></pre>
<p>If you know which authentication type the server uses, you add that as a hint in 'auth_type'. Likewise, you can
add the server version as a hint. This allows to skip the auth type and version guessing routines:</p>
<pre><code>config = Configuration(auth_type=NTLM, ...)
config = Configuration(version=Version(build=Build(15, 1, 2, 3)), ...)
</code></pre>
<p>You can use 'retry_policy' to define a custom retry policy for handling server connection failures:</p>
<pre><code>config = Configuration(retry_policy=FaultTolerance(max_wait=3600), ...)
</code></pre>
<p>'max_connections' defines the max number of connections allowed for this server. This may be restricted by
policies on the Exchange server.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class O365InteractiveConfiguration(Configuration):
SERVER = &#34;outlook.office365.com&#34;

def __init__(self, client_id, username):
credentials = O365InteractiveCredentials(client_id=client_id, username=username)
super().__init__(server=self.SERVER, auth_type=OAUTH2, credentials=credentials)</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li><a title="exchangelib.configuration.Configuration" href="#exchangelib.configuration.Configuration">Configuration</a></li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="exchangelib.configuration.O365InteractiveConfiguration.SERVER"><code class="name">var <span class="ident">SERVER</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
</dd>
</dl>
</section>
</article>
Expand All @@ -311,6 +370,12 @@ <h4><code><a title="exchangelib.configuration.Configuration" href="#exchangelib.
<li><code><a title="exchangelib.configuration.Configuration.server" href="#exchangelib.configuration.Configuration.server">server</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="exchangelib.configuration.O365InteractiveConfiguration" href="#exchangelib.configuration.O365InteractiveConfiguration">O365InteractiveConfiguration</a></code></h4>
<ul class="">
<li><code><a title="exchangelib.configuration.O365InteractiveConfiguration.SERVER" href="#exchangelib.configuration.O365InteractiveConfiguration.SERVER">SERVER</a></code></li>
</ul>
</li>
</ul>
</li>
</ul>
Expand Down
96 changes: 95 additions & 1 deletion docs/exchangelib/credentials.html
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,20 @@ <h1 class="title">Module <code>exchangelib.credentials</code></h1>
else (&#34;[authorization_code]&#34; if self.authorization_code is not None else None)
)
description = &#34; &#34;.join(filter(None, [client_id, credential]))
return description or &#34;[underspecified credentials]&#34;</code></pre>
return description or &#34;[underspecified credentials]&#34;


class O365InteractiveCredentials(OAuth2AuthorizationCodeCredentials):
AUTHORITY = &#34;https://login.microsoftonline.com/organizations&#34;
SCOPE = [&#34;EWS.AccessAsUser.All&#34;]

def __init__(self, client_id, username):
import msal

app = msal.PublicClientApplication(client_id=client_id, authority=self.AUTHORITY)
print(&#34;A local browser window will be open for you to sign in. CTRL+C to cancel.&#34;)
access_token = app.acquire_token_interactive(self.SCOPE, login_hint=username)
super().__init__(access_token=access_token)</code></pre>
</details>
</section>
<section>
Expand Down Expand Up @@ -802,6 +815,76 @@ <h3>Class variables</h3>
</dd>
</dl>
</dd>
<dt id="exchangelib.credentials.O365InteractiveCredentials"><code class="flex name class">
<span>class <span class="ident">O365InteractiveCredentials</span></span>
<span>(</span><span>client_id, username)</span>
</code></dt>
<dd>
<div class="desc"><p>Login info for OAuth 2.0 authentication using the authorization code grant type. This can be used in one of
several ways:
* Given an authorization code, client ID, and client secret, fetch a token ourselves and refresh it as needed if
supplied with a refresh token.
* Given an existing access token, client ID, and client secret, use the access token until it expires and then
refresh it as needed.
* Given only an existing access token, use it until it expires. This can be used to let the calling application
refresh tokens itself by subclassing and implementing refresh().</p>
<p>Unlike the base (client credentials) grant, authorization code credentials don't require a Microsoft tenant ID
because each access token (and the authorization code used to get the access token) is restricted to a single
tenant.</p>
<p>:param authorization_code: Code obtained when authorizing the application to access an account. In combination
with client_id and client_secret, will be used to obtain an access token.</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">class O365InteractiveCredentials(OAuth2AuthorizationCodeCredentials):
AUTHORITY = &#34;https://login.microsoftonline.com/organizations&#34;
SCOPE = [&#34;EWS.AccessAsUser.All&#34;]

def __init__(self, client_id, username):
import msal

app = msal.PublicClientApplication(client_id=client_id, authority=self.AUTHORITY)
print(&#34;A local browser window will be open for you to sign in. CTRL+C to cancel.&#34;)
access_token = app.acquire_token_interactive(self.SCOPE, login_hint=username)
super().__init__(access_token=access_token)</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li><a title="exchangelib.credentials.OAuth2AuthorizationCodeCredentials" href="#exchangelib.credentials.OAuth2AuthorizationCodeCredentials">OAuth2AuthorizationCodeCredentials</a></li>
<li><a title="exchangelib.credentials.BaseOAuth2Credentials" href="#exchangelib.credentials.BaseOAuth2Credentials">BaseOAuth2Credentials</a></li>
<li><a title="exchangelib.credentials.BaseCredentials" href="#exchangelib.credentials.BaseCredentials">BaseCredentials</a></li>
</ul>
<h3>Class variables</h3>
<dl>
<dt id="exchangelib.credentials.O365InteractiveCredentials.AUTHORITY"><code class="name">var <span class="ident">AUTHORITY</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
<dt id="exchangelib.credentials.O365InteractiveCredentials.SCOPE"><code class="name">var <span class="ident">SCOPE</span></code></dt>
<dd>
<div class="desc"></div>
</dd>
</dl>
<h3>Inherited members</h3>
<ul class="hlist">
<li><code><b><a title="exchangelib.credentials.OAuth2AuthorizationCodeCredentials" href="#exchangelib.credentials.OAuth2AuthorizationCodeCredentials">OAuth2AuthorizationCodeCredentials</a></b></code>:
<ul class="hlist">
<li><code><a title="exchangelib.credentials.OAuth2AuthorizationCodeCredentials.on_token_auto_refreshed" href="#exchangelib.credentials.BaseOAuth2Credentials.on_token_auto_refreshed">on_token_auto_refreshed</a></code></li>
<li><code><a title="exchangelib.credentials.OAuth2AuthorizationCodeCredentials.refresh" href="#exchangelib.credentials.BaseOAuth2Credentials.refresh">refresh</a></code></li>
<li><code><a title="exchangelib.credentials.OAuth2AuthorizationCodeCredentials.scope" href="#exchangelib.credentials.BaseOAuth2Credentials.scope">scope</a></code></li>
<li><code><a title="exchangelib.credentials.OAuth2AuthorizationCodeCredentials.session_params" href="#exchangelib.credentials.BaseOAuth2Credentials.session_params">session_params</a></code></li>
<li><code><a title="exchangelib.credentials.OAuth2AuthorizationCodeCredentials.token_params" href="#exchangelib.credentials.BaseOAuth2Credentials.token_params">token_params</a></code></li>
<li><code><a title="exchangelib.credentials.OAuth2AuthorizationCodeCredentials.token_url" href="#exchangelib.credentials.BaseOAuth2Credentials.token_url">token_url</a></code></li>
</ul>
</li>
<li><code><b><a title="exchangelib.credentials.BaseOAuth2Credentials" href="#exchangelib.credentials.BaseOAuth2Credentials">BaseOAuth2Credentials</a></b></code>:
<ul class="hlist">
<li><code><a title="exchangelib.credentials.BaseOAuth2Credentials.client" href="#exchangelib.credentials.BaseOAuth2Credentials.client">client</a></code></li>
</ul>
</li>
</ul>
</dd>
<dt id="exchangelib.credentials.OAuth2AuthorizationCodeCredentials"><code class="flex name class">
<span>class <span class="ident">OAuth2AuthorizationCodeCredentials</span></span>
<span>(</span><span>authorization_code=None, **kwargs)</span>
Expand Down Expand Up @@ -887,6 +970,10 @@ <h3>Ancestors</h3>
<li><a title="exchangelib.credentials.BaseOAuth2Credentials" href="#exchangelib.credentials.BaseOAuth2Credentials">BaseOAuth2Credentials</a></li>
<li><a title="exchangelib.credentials.BaseCredentials" href="#exchangelib.credentials.BaseCredentials">BaseCredentials</a></li>
</ul>
<h3>Subclasses</h3>
<ul class="hlist">
<li><a title="exchangelib.credentials.O365InteractiveCredentials" href="#exchangelib.credentials.O365InteractiveCredentials">O365InteractiveCredentials</a></li>
</ul>
<h3>Inherited members</h3>
<ul class="hlist">
<li><code><b><a title="exchangelib.credentials.BaseOAuth2Credentials" href="#exchangelib.credentials.BaseOAuth2Credentials">BaseOAuth2Credentials</a></b></code>:
Expand Down Expand Up @@ -1078,6 +1165,13 @@ <h4><code><a title="exchangelib.credentials.Credentials" href="#exchangelib.cred
</ul>
</li>
<li>
<h4><code><a title="exchangelib.credentials.O365InteractiveCredentials" href="#exchangelib.credentials.O365InteractiveCredentials">O365InteractiveCredentials</a></code></h4>
<ul class="">
<li><code><a title="exchangelib.credentials.O365InteractiveCredentials.AUTHORITY" href="#exchangelib.credentials.O365InteractiveCredentials.AUTHORITY">AUTHORITY</a></code></li>
<li><code><a title="exchangelib.credentials.O365InteractiveCredentials.SCOPE" href="#exchangelib.credentials.O365InteractiveCredentials.SCOPE">SCOPE</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="exchangelib.credentials.OAuth2AuthorizationCodeCredentials" href="#exchangelib.credentials.OAuth2AuthorizationCodeCredentials">OAuth2AuthorizationCodeCredentials</a></code></h4>
</li>
<li>
Expand Down
2 changes: 1 addition & 1 deletion docs/exchangelib/ewsdatetime.html
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ <h3>Static methods</h3>
<span>def <span class="ident">fromisoformat</span></span>(<span>date_string)</span>
</code></dt>
<dd>
<div class="desc"><p>string -&gt; datetime from datetime.isoformat() output</p></div>
<div class="desc"><p>string -&gt; datetime from a string in most ISO 8601 formats</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
Expand Down
22 changes: 19 additions & 3 deletions docs/exchangelib/folders/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ <h1 class="title">Module <code>exchangelib.folders.base</code></h1>
)
from ..queryset import DoesNotExist, SearchableMixIn
from ..util import TNS, is_iterable, require_id
from ..version import EXCHANGE_2007_SP1, EXCHANGE_2010, SupportedVersionClassMixIn
from ..version import EXCHANGE_2007_SP1, EXCHANGE_2010, EXCHANGE_2016, SupportedVersionClassMixIn
from .collections import FolderCollection, PullSubscription, PushSubscription, StreamingSubscription, SyncCompleted
from .queryset import DEEP as DEEP_FOLDERS
from .queryset import MISSING_FOLDER_ERRORS
Expand Down Expand Up @@ -105,7 +105,9 @@ <h1 class="title">Module <code>exchangelib.folders.base</code></h1>
ID_ELEMENT_CLS = FolderId

_id = IdElementField(field_uri=&#34;folder:FolderId&#34;, value_cls=ID_ELEMENT_CLS)
_distinguished_id = IdElementField(field_uri=&#34;folder:DistinguishedFolderId&#34;, value_cls=DistinguishedFolderId)
_distinguished_id = IdElementField(
field_uri=&#34;folder:DistinguishedFolderId&#34;, value_cls=DistinguishedFolderId, supported_from=EXCHANGE_2016
)
parent_folder_id = EWSElementField(field_uri=&#34;folder:ParentFolderId&#34;, value_cls=ParentFolderId, is_read_only=True)
folder_class = CharField(field_uri=&#34;folder:FolderClass&#34;, is_required_after_save=True)
name = CharField(field_uri=&#34;folder:DisplayName&#34;)
Expand Down Expand Up @@ -972,6 +974,10 @@ <h1 class="title">Module <code>exchangelib.folders.base</code></h1>
)
if folder_cls == Folder:
log.debug(&#34;Fallback to class Folder (folder_class %s, name %s)&#34;, folder.folder_class, folder.name)
# Some servers return folders in a FindFolder result that have a DistinguishedFolderId element that the same
# server cannot handle in a GetFolder request. Only set the DistinguishedFolderId field if we recognize the ID.
if folder._distinguished_id and not folder_cls.DISTINGUISHED_FOLDER_ID:
folder._distinguished_id = None
return folder_cls(root=root, **{f.name: getattr(folder, f.name) for f in folder.FIELDS})</code></pre>
</details>
</section>
Expand Down Expand Up @@ -1014,7 +1020,9 @@ <h2 class="section-title" id="header-classes">Classes</h2>
ID_ELEMENT_CLS = FolderId

_id = IdElementField(field_uri=&#34;folder:FolderId&#34;, value_cls=ID_ELEMENT_CLS)
_distinguished_id = IdElementField(field_uri=&#34;folder:DistinguishedFolderId&#34;, value_cls=DistinguishedFolderId)
_distinguished_id = IdElementField(
field_uri=&#34;folder:DistinguishedFolderId&#34;, value_cls=DistinguishedFolderId, supported_from=EXCHANGE_2016
)
parent_folder_id = EWSElementField(field_uri=&#34;folder:ParentFolderId&#34;, value_cls=ParentFolderId, is_read_only=True)
folder_class = CharField(field_uri=&#34;folder:FolderClass&#34;, is_required_after_save=True)
name = CharField(field_uri=&#34;folder:DisplayName&#34;)
Expand Down Expand Up @@ -3101,6 +3109,10 @@ <h3>Inherited members</h3>
)
if folder_cls == Folder:
log.debug(&#34;Fallback to class Folder (folder_class %s, name %s)&#34;, folder.folder_class, folder.name)
# Some servers return folders in a FindFolder result that have a DistinguishedFolderId element that the same
# server cannot handle in a GetFolder request. Only set the DistinguishedFolderId field if we recognize the ID.
if folder._distinguished_id and not folder_cls.DISTINGUISHED_FOLDER_ID:
folder._distinguished_id = None
return folder_cls(root=root, **{f.name: getattr(folder, f.name) for f in folder.FIELDS})</code></pre>
</details>
<h3>Ancestors</h3>
Expand Down Expand Up @@ -3181,6 +3193,10 @@ <h3>Static methods</h3>
)
if folder_cls == Folder:
log.debug(&#34;Fallback to class Folder (folder_class %s, name %s)&#34;, folder.folder_class, folder.name)
# Some servers return folders in a FindFolder result that have a DistinguishedFolderId element that the same
# server cannot handle in a GetFolder request. Only set the DistinguishedFolderId field if we recognize the ID.
if folder._distinguished_id and not folder_cls.DISTINGUISHED_FOLDER_ID:
folder._distinguished_id = None
return folder_cls(root=root, **{f.name: getattr(folder, f.name) for f in folder.FIELDS})</code></pre>
</details>
</dd>
Expand Down
Loading

0 comments on commit 73d3167

Please sign in to comment.