pyoncat 2.8__tar.gz → 2.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyoncat-2.8 → pyoncat-2.9}/PKG-INFO +2 -2
- {pyoncat-2.8 → pyoncat-2.9}/pyoncat/README.md +1 -1
- {pyoncat-2.8 → pyoncat-2.9}/pyoncat/__init__.py +61 -22
- {pyoncat-2.8 → pyoncat-2.9}/pyproject.toml +3 -3
- {pyoncat-2.8 → pyoncat-2.9}/pyoncat/LICENSE +0 -0
- {pyoncat-2.8 → pyoncat-2.9}/pyoncat/reduction.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyoncat
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.9
|
|
4
4
|
Summary: A Python Client for ONCat (the ORNL Neutron Catalog).
|
|
5
5
|
Keywords: ornl,neutron,metadata,catalog
|
|
6
6
|
Author: ONCat Support
|
|
@@ -30,7 +30,7 @@ The `pyoncat` package serves as a Python client to more easily interact with the
|
|
|
30
30
|
|
|
31
31
|
### Requirements
|
|
32
32
|
|
|
33
|
-
- Python version: `>=3.
|
|
33
|
+
- Python version: `>=3.9, <4`
|
|
34
34
|
- Python packages: `requests`
|
|
35
35
|
- Optional packages for authenticated API access: `oauthlib`, `requests-oauthlib`
|
|
36
36
|
|
|
@@ -10,7 +10,7 @@ The `pyoncat` package serves as a Python client to more easily interact with the
|
|
|
10
10
|
|
|
11
11
|
### Requirements
|
|
12
12
|
|
|
13
|
-
- Python version: `>=3.
|
|
13
|
+
- Python version: `>=3.9, <4`
|
|
14
14
|
- Python packages: `requests`
|
|
15
15
|
- Optional packages for authenticated API access: `oauthlib`, `requests-oauthlib`
|
|
16
16
|
|
|
@@ -34,7 +34,7 @@ from pyoncat.reduction import ReductionFileBuilder
|
|
|
34
34
|
if TYPE_CHECKING:
|
|
35
35
|
import threading
|
|
36
36
|
|
|
37
|
-
__version__ = "2.
|
|
37
|
+
__version__ = "2.9"
|
|
38
38
|
|
|
39
39
|
# Sent on every request PyONCat makes, API calls and token requests alike,
|
|
40
40
|
# so server logs can tell PyONCat traffic from other clients.
|
|
@@ -937,12 +937,13 @@ class ONCat:
|
|
|
937
937
|
device_authorization_timeout: float | None
|
|
938
938
|
Device Authorization Grant only. An overall caller
|
|
939
939
|
deadline in seconds for the sign-in, distinct from the
|
|
940
|
-
RFC 8628 server-side `expires_in`.
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
the
|
|
945
|
-
|
|
940
|
+
RFC 8628 server-side `expires_in`. Polling stops at the
|
|
941
|
+
earlier of the two. When the caller deadline is reached
|
|
942
|
+
first, the sign-in raises `DeviceAuthorizationTimeout`;
|
|
943
|
+
when the server's `expires_in` is reached first (or at
|
|
944
|
+
the same moment, or no caller deadline is set), it raises
|
|
945
|
+
`DeviceAuthorizationExpired`. `None` (the default) means
|
|
946
|
+
no overall caller deadline.
|
|
946
947
|
|
|
947
948
|
http_timeout: float | None
|
|
948
949
|
Device Authorization Grant only. The connect/read HTTP
|
|
@@ -1212,14 +1213,22 @@ class ONCat:
|
|
|
1212
1213
|
# The effective deadline is the earlier of the caller's overall
|
|
1213
1214
|
# `device_authorization_timeout` (clocked from before the
|
|
1214
1215
|
# initial POST) and the server's own `expires_in` (clocked from
|
|
1215
|
-
# now, once known).
|
|
1216
|
+
# now, once known). Which one it is decides the outcome raised
|
|
1217
|
+
# when it passes: the server expiry means the device code is dead
|
|
1218
|
+
# (`DeviceAuthorizationExpired`, the same outcome as a server
|
|
1219
|
+
# `expired_token`), the caller deadline means the caller gave up
|
|
1220
|
+
# (`DeviceAuthorizationTimeout`). On a tie the device code is dead
|
|
1221
|
+
# either way, so the server expiry wins.
|
|
1216
1222
|
server_expiry = (
|
|
1217
1223
|
monotonic() + expires_in if expires_in is not None else None
|
|
1218
1224
|
)
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1225
|
+
deadline = caller_deadline
|
|
1226
|
+
deadline_is_server_expiry = False
|
|
1227
|
+
if server_expiry is not None and (
|
|
1228
|
+
caller_deadline is None or server_expiry <= caller_deadline
|
|
1229
|
+
):
|
|
1230
|
+
deadline = server_expiry
|
|
1231
|
+
deadline_is_server_expiry = True
|
|
1223
1232
|
|
|
1224
1233
|
self._dispatch_device_authorization_challenge(
|
|
1225
1234
|
prompt,
|
|
@@ -1241,10 +1250,18 @@ class ONCat:
|
|
|
1241
1250
|
|
|
1242
1251
|
while True:
|
|
1243
1252
|
self._raise_if_cancelled(cancel_event)
|
|
1244
|
-
self._raise_if_past_deadline(
|
|
1253
|
+
self._raise_if_past_deadline(
|
|
1254
|
+
deadline,
|
|
1255
|
+
monotonic,
|
|
1256
|
+
server_expiry=deadline_is_server_expiry,
|
|
1257
|
+
)
|
|
1245
1258
|
sleep(self._poll_wait_seconds(interval, deadline, monotonic))
|
|
1246
1259
|
self._raise_if_cancelled(cancel_event)
|
|
1247
|
-
self._raise_if_past_deadline(
|
|
1260
|
+
self._raise_if_past_deadline(
|
|
1261
|
+
deadline,
|
|
1262
|
+
monotonic,
|
|
1263
|
+
server_expiry=deadline_is_server_expiry,
|
|
1264
|
+
)
|
|
1248
1265
|
|
|
1249
1266
|
try:
|
|
1250
1267
|
token_response = requests.post(
|
|
@@ -1377,14 +1394,32 @@ class ONCat:
|
|
|
1377
1394
|
|
|
1378
1395
|
@staticmethod
|
|
1379
1396
|
def _raise_if_past_deadline(
|
|
1380
|
-
deadline: float | None,
|
|
1397
|
+
deadline: float | None,
|
|
1398
|
+
monotonic: Callable[[], float],
|
|
1399
|
+
*,
|
|
1400
|
+
server_expiry: bool = False,
|
|
1381
1401
|
) -> None:
|
|
1382
|
-
|
|
1402
|
+
"""Raise once `deadline` has passed.
|
|
1403
|
+
|
|
1404
|
+
`server_expiry` says the deadline is the device code's own
|
|
1405
|
+
`expires_in`, so passing it raises `DeviceAuthorizationExpired`;
|
|
1406
|
+
otherwise it is the caller's `device_authorization_timeout` and
|
|
1407
|
+
passing it raises `DeviceAuthorizationTimeout`.
|
|
1408
|
+
"""
|
|
1409
|
+
if deadline is None or monotonic() < deadline:
|
|
1410
|
+
return
|
|
1411
|
+
if server_expiry:
|
|
1383
1412
|
msg = (
|
|
1384
|
-
"Device authorization
|
|
1385
|
-
"the sign-in."
|
|
1413
|
+
"Device authorization expired: the device code's "
|
|
1414
|
+
"expires_in lapsed before the user completed the sign-in."
|
|
1386
1415
|
)
|
|
1387
|
-
raise
|
|
1416
|
+
raise DeviceAuthorizationExpired(msg)
|
|
1417
|
+
msg = (
|
|
1418
|
+
"Device authorization timed out: the caller's "
|
|
1419
|
+
"device_authorization_timeout lapsed before the user completed "
|
|
1420
|
+
"the sign-in."
|
|
1421
|
+
)
|
|
1422
|
+
raise DeviceAuthorizationTimeout(msg)
|
|
1388
1423
|
|
|
1389
1424
|
def _dispatch_device_authorization_challenge(
|
|
1390
1425
|
self,
|
|
@@ -2160,7 +2195,10 @@ class DeviceAuthorizationDenied(DeviceAuthorizationError): # ruff: ignore[error
|
|
|
2160
2195
|
|
|
2161
2196
|
class DeviceAuthorizationExpired(DeviceAuthorizationError): # ruff: ignore[error-suffix-on-exception-name] - public API name (ADR-000097)
|
|
2162
2197
|
"""Raised when the device code expired before the user approved the
|
|
2163
|
-
sign-in
|
|
2198
|
+
sign-in: the IdP returned `expired_token` (RFC 8628 §3.5), or the
|
|
2199
|
+
server's `expires_in` lapsed no later than the caller's
|
|
2200
|
+
`device_authorization_timeout`. The code is dead, so a new sign-in
|
|
2201
|
+
must start from a fresh device code."""
|
|
2164
2202
|
|
|
2165
2203
|
|
|
2166
2204
|
class DeviceAuthorizationCancelled(DeviceAuthorizationError): # ruff: ignore[error-suffix-on-exception-name] - public API name (ADR-000097)
|
|
@@ -2170,8 +2208,9 @@ class DeviceAuthorizationCancelled(DeviceAuthorizationError): # ruff: ignore[er
|
|
|
2170
2208
|
|
|
2171
2209
|
class DeviceAuthorizationTimeout(DeviceAuthorizationError): # ruff: ignore[error-suffix-on-exception-name] - public API name (ADR-000097)
|
|
2172
2210
|
"""Raised when the sign-in did not complete before the overall
|
|
2173
|
-
caller deadline (`device_authorization_timeout`)
|
|
2174
|
-
`expires_in
|
|
2211
|
+
caller deadline (`device_authorization_timeout`) and that deadline
|
|
2212
|
+
came strictly before the server's own `expires_in`. A server expiry
|
|
2213
|
+
reached first raises `DeviceAuthorizationExpired` instead."""
|
|
2175
2214
|
|
|
2176
2215
|
|
|
2177
2216
|
class DeviceAuthorizationNetworkError(DeviceAuthorizationError):
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["poetry"]
|
|
3
|
-
build-backend = "poetry.masonry.api"
|
|
2
|
+
requires = ["poetry-core"]
|
|
3
|
+
build-backend = "poetry.core.masonry.api"
|
|
4
4
|
|
|
5
5
|
# Poetry requires it's own condfiguration because it predates the
|
|
6
6
|
# "[project]" standard. See:
|
|
7
7
|
# https://github.com/python-poetry/roadmap/issues/3
|
|
8
8
|
[tool.poetry]
|
|
9
9
|
name = "pyoncat"
|
|
10
|
-
version = "2.
|
|
10
|
+
version = "2.9"
|
|
11
11
|
description = "A Python Client for ONCat (the ORNL Neutron Catalog)."
|
|
12
12
|
authors = ["ONCat Support <oncat-support@ornl.gov>"]
|
|
13
13
|
readme = ["pyoncat/README.md", "pyoncat/LICENSE"]
|
|
File without changes
|
|
File without changes
|