odatadol.transport#
The one request odatadol makes: an authenticated GET, through a swappable fetch.
Everything that touches the network goes through odata_get(), and
odata_get() has no verb argument: odatadol cannot write, by construction.
The transport seam is fetch=(url, headers) -> (status, body bytes). The default,
urllib_fetch(), is the standard library; a test scripts a fake server instead,
and a host behind a proxy or with its own session pool passes its own.
>>> calls = []
>>> def fake(url, headers):
... calls.append((url, dict(headers)))
... return 200, b'{"value": []}'
>>> odata_get('https://example.com/odata/Products', fetch=fake)
b'{"value": []}'
>>> calls[0][1]
{'Accept': 'application/json'}
Credentials are anything with a header() -> str method (BasicAuth,
BearerToken), or a zero-argument callable returning one, so a host can defer a
keychain or file lookup until a read starts (it runs once per read). Neither the password nor the
Authorization header ever appears in an error message, and the header never
follows a redirect or a nextLink to another origin.
Module Attributes
Seconds before the default transport gives up on one request. |
|
the transport seam. |
|
|
Functions
|
The default transport: one |
|
|
|
|
|
|
|
Whether two URLs share scheme, host and port: where credentials may follow. |
Classes
|
An account and its password, for HTTP Basic. |
|
An OAuth2 or similar bearer token. |
Exceptions
|
The service answered with an error. |
- class odatadol.transport.BasicAuth(account, password)[source]#
Bases:
objectAn account and its password, for HTTP Basic. The password is never shown.
>>> BasicAuth('reader', 'secret') BasicAuth(account='reader') >>> BasicAuth('reader', 'secret').header() 'Basic cmVhZGVyOnNlY3JldA=='
- class odatadol.transport.BearerToken(token)[source]#
Bases:
objectAn OAuth2 or similar bearer token. Never shown.
- odatadol.transport.Credentials#
None(anonymous), an object withheader(), or a zero-argument callable returning either.- Type:
What
credentials=accepts
- odatadol.transport.DEFAULT_TIMEOUT = 120.0#
Seconds before the default transport gives up on one request.
- odatadol.transport.Fetch#
the transport seam. Only
GETis ever issued through it.- Type:
(url, headers) -> (status, body bytes)
alias of
Callable[[str,Mapping[str,str]], tuple[int, bytes]]
- exception odatadol.transport.ODataError(message, *, status=None, code='')[source]#
Bases:
RuntimeErrorThe service answered with an error. Carries the HTTP status and the OData code.
- odatadol.transport.odata_get(url, *, credentials=None, accept='application/json', fetch=None)[source]#
GETone OData URL and return the body. The only request odatadol makes.- Raises:
ODataError – On any non-2xx status, with the service’s error code and message. The message names the URL (without userinfo) and never the
Authorizationheader.- Return type:
- odatadol.transport.redact(url)[source]#
urlwithout anyuser:password@it carries.>>> redact('https://user:pw@example.com:8443/odata/Products?$top=1') 'https://example.com:8443/odata/Products?$top=1' >>> redact('https://u:p@[::1]:8443/x') 'https://[::1]:8443/x'
- Return type:
- odatadol.transport.resolve_credentials(credentials)[source]#
credentialsas an object withheader()(orNone), calling a factory.Functions that make several requests resolve once, so a factory (a keychain lookup) runs once per read, not once per page.
- Return type:
_HasHeader|None
- odatadol.transport.same_origin(a, b)[source]#
Whether two URLs share scheme, host and port: where credentials may follow.
>>> same_origin('https://example.com/odata/A', 'https://example.com/odata/B?x=1') True >>> same_origin('https://example.com/odata', 'https://elsewhere.example/odata') False
- Return type:
- odatadol.transport.urllib_fetch(url, headers, *, timeout=120.0)[source]#
The default transport: one
GETwithurllib. An HTTP error is returned, not raised, soodata_get()reads every status the same way.A redirect to another origin is followed without the
Authorizationheader. Usefunctools.partial()to changetimeout.- Raises:
ODataError – If no HTTP answer came back (DNS, refused connection, timeout, a malformed URL), naming the URL without any userinfo it carries.
- Return type: