lockss-pybasic 0.3.0.dev6__tar.gz → 0.3.0.dev7__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.
- {lockss_pybasic-0.3.0.dev6 → lockss_pybasic-0.3.0.dev7}/PKG-INFO +2 -2
- {lockss_pybasic-0.3.0.dev6 → lockss_pybasic-0.3.0.dev7}/README.rst +1 -1
- {lockss_pybasic-0.3.0.dev6 → lockss_pybasic-0.3.0.dev7}/pyproject.toml +1 -1
- {lockss_pybasic-0.3.0.dev6 → lockss_pybasic-0.3.0.dev7}/src/lockss/pybasic/__init__.py +1 -1
- {lockss_pybasic-0.3.0.dev6 → lockss_pybasic-0.3.0.dev7}/src/lockss/pybasic/nodeutil.py +31 -15
- {lockss_pybasic-0.3.0.dev6 → lockss_pybasic-0.3.0.dev7}/CHANGELOG.rst +0 -0
- {lockss_pybasic-0.3.0.dev6 → lockss_pybasic-0.3.0.dev7}/LICENSE +0 -0
- {lockss_pybasic-0.3.0.dev6 → lockss_pybasic-0.3.0.dev7}/src/lockss/pybasic/auidutil.py +0 -0
- {lockss_pybasic-0.3.0.dev6 → lockss_pybasic-0.3.0.dev7}/src/lockss/pybasic/cliutil.py +0 -0
- {lockss_pybasic-0.3.0.dev6 → lockss_pybasic-0.3.0.dev7}/src/lockss/pybasic/errorutil.py +0 -0
- {lockss_pybasic-0.3.0.dev6 → lockss_pybasic-0.3.0.dev7}/src/lockss/pybasic/fileutil.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lockss-pybasic
|
|
3
|
-
Version: 0.3.0.
|
|
3
|
+
Version: 0.3.0.dev7
|
|
4
4
|
Summary: Basic Python utilities
|
|
5
5
|
License: BSD-3-Clause
|
|
6
6
|
License-File: LICENSE
|
|
@@ -26,7 +26,7 @@ Description-Content-Type: text/x-rst
|
|
|
26
26
|
lockss-pybasic
|
|
27
27
|
==============
|
|
28
28
|
|
|
29
|
-
.. |RELEASE| replace:: 0.3.0-
|
|
29
|
+
.. |RELEASE| replace:: 0.3.0-dev7
|
|
30
30
|
.. |RELEASE_DATE| replace:: NOT YET RELEASED
|
|
31
31
|
|
|
32
32
|
**Latest release:** |RELEASE| (|RELEASE_DATE|)
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
[project]
|
|
30
30
|
name = "lockss-pybasic"
|
|
31
|
-
version = "0.3.0-
|
|
31
|
+
version = "0.3.0-dev7" # Always change in __init__.py, and at release time in README.rst and CHANGELOG.rst
|
|
32
32
|
description = "Basic Python utilities"
|
|
33
33
|
license = { text = "BSD-3-Clause" }
|
|
34
34
|
readme = "README.rst"
|
|
@@ -35,14 +35,14 @@ LOCKSS node utilities.
|
|
|
35
35
|
from enum import Enum
|
|
36
36
|
from re import Match, Pattern
|
|
37
37
|
import re
|
|
38
|
-
from typing import Annotated, Any, ClassVar, Literal, Optional, Union
|
|
38
|
+
from typing import Annotated, Any, ClassVar, Literal, Optional, TypeAlias, Union
|
|
39
39
|
|
|
40
40
|
from annotated_types import Ge, Le
|
|
41
41
|
from pydantic import BaseModel, BeforeValidator, Field, TypeAdapter
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
#: An annotated type for port numbers (0-65535)
|
|
45
|
-
PortNumber = Annotated[int, Ge(0), Le(65535)]
|
|
45
|
+
PortNumber: TypeAlias = Annotated[int, Ge(0), Le(65535)]
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
class NodeTypeEnum(Enum):
|
|
@@ -61,6 +61,12 @@ class NodeProtocolEnum(Enum):
|
|
|
61
61
|
HTTPS = 'https'
|
|
62
62
|
|
|
63
63
|
|
|
64
|
+
NodeSpecKind: TypeAlias = Literal['NodeSpec']
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
NodeIdentifier: TypeAlias = str
|
|
68
|
+
|
|
69
|
+
|
|
64
70
|
class BaseNodeSpec(BaseModel):
|
|
65
71
|
|
|
66
72
|
DEFAULT_PROTOCOL: ClassVar[NodeProtocolEnum] = NodeProtocolEnum.HTTP
|
|
@@ -68,6 +74,13 @@ class BaseNodeSpec(BaseModel):
|
|
|
68
74
|
TYPE_FIELD: ClassVar[dict[str, str]] = dict(title='Type',
|
|
69
75
|
description="The node's type")
|
|
70
76
|
|
|
77
|
+
kind: NodeSpecKind = Field(title='Kind',
|
|
78
|
+
description="This object's kind")
|
|
79
|
+
|
|
80
|
+
id: NodeIdentifier = Field(default='',
|
|
81
|
+
title='Node Identifier',
|
|
82
|
+
description='An identifier for the node')
|
|
83
|
+
|
|
71
84
|
protocol: NodeProtocolEnum = Field(default=DEFAULT_PROTOCOL,
|
|
72
85
|
title='Protocol',
|
|
73
86
|
description="The protocol for reaching the node")
|
|
@@ -86,6 +99,9 @@ class NodeSpec1(BaseNodeSpec):
|
|
|
86
99
|
title='UI Port',
|
|
87
100
|
description="The LOCKSS 1.x node's Web user interface port")
|
|
88
101
|
|
|
102
|
+
def __str__(self) -> str:
|
|
103
|
+
return f'{self.protocol.value}://{self.host}:{self.ui}'
|
|
104
|
+
|
|
89
105
|
|
|
90
106
|
class NodeSpec2(BaseNodeSpec):
|
|
91
107
|
|
|
@@ -127,19 +143,22 @@ class NodeSpec2(BaseNodeSpec):
|
|
|
127
143
|
title='SOAP Port',
|
|
128
144
|
description="The node's SOAP Compatibility Service REST API Port")
|
|
129
145
|
|
|
146
|
+
def __str__(self) -> str:
|
|
147
|
+
return f'{self.protocol.value}://{self.host}:{self.repository}:{self.configuration}:{self.poller}:{self.crawler}:{self.metadata}:{self.soap}'
|
|
148
|
+
|
|
130
149
|
|
|
131
150
|
_RE_COMPACT_NODE_SPEC: Pattern[str] = re.compile(r'((?P<protocol>https?)://)?(?P<host>[^:]+)(:(?P<repository>\d+|(?=:))(:(?P<configuration>\d+|(?=:))(:(?P<poller>\d+|(?=:))(:(?P<crawler>\d+|(?=:))(:(?P<metadata>\d+|(?=:))(:(?P<soap>\d+))?)?)?)?)?)?')
|
|
132
151
|
|
|
133
152
|
|
|
134
153
|
#: A type for LOCKSS node specification strings.
|
|
135
|
-
CompactNodeSpec = str
|
|
154
|
+
CompactNodeSpec: TypeAlias = str
|
|
136
155
|
|
|
137
156
|
|
|
138
157
|
def _parse_compact_node_spec(compact_node_spec: CompactNodeSpec) -> dict[str, str]:
|
|
139
158
|
mat: Optional[Match[str]] = _RE_COMPACT_NODE_SPEC.fullmatch(compact_node_spec)
|
|
140
159
|
if mat is None:
|
|
141
160
|
raise ValueError(f'Invalid compact node specification: {compact_node_spec}')
|
|
142
|
-
d = dict(host=mat.group('host'))
|
|
161
|
+
d = dict(kind='NodeSpec', host=mat.group('host'))
|
|
143
162
|
if prot := mat.group('protocol'):
|
|
144
163
|
d['protocol'] = prot
|
|
145
164
|
five = ('configuration', 'poller', 'crawler', 'metadata', 'soap')
|
|
@@ -147,7 +166,7 @@ def _parse_compact_node_spec(compact_node_spec: CompactNodeSpec) -> dict[str, st
|
|
|
147
166
|
if any(mat.group(x) for x in five) or len(repo_or_ui) >= 5:
|
|
148
167
|
# 10000 or larger: assume V2
|
|
149
168
|
d['type'] = NodeTypeEnum.V2.value
|
|
150
|
-
d['repository'] = repo_or_ui
|
|
169
|
+
d['repository'] = repo_or_ui # all these strings will be coerced to int
|
|
151
170
|
elif len(repo_or_ui) == 4:
|
|
152
171
|
# 1000 through 9999: assume V1
|
|
153
172
|
d['type'] = NodeTypeEnum.V1.value
|
|
@@ -159,7 +178,7 @@ def _parse_compact_node_spec(compact_node_spec: CompactNodeSpec) -> dict[str, st
|
|
|
159
178
|
d['type'] = NodeTypeEnum.V2.value
|
|
160
179
|
for k in five:
|
|
161
180
|
if p := mat.group(k):
|
|
162
|
-
d[k] = p
|
|
181
|
+
d[k] = p
|
|
163
182
|
return d
|
|
164
183
|
|
|
165
184
|
|
|
@@ -171,7 +190,7 @@ def _maybe_deserialize_compact_node_spec(value: Any) -> Any:
|
|
|
171
190
|
|
|
172
191
|
#: A type for LOCKSS node specifications, that also accepts a compact LOCKSS
|
|
173
192
|
#: node specification.
|
|
174
|
-
NodeSpec = Annotated[
|
|
193
|
+
NodeSpec: TypeAlias = Annotated[
|
|
175
194
|
Annotated[Union[NodeSpec1, NodeSpec2], Field(discriminator='type')],
|
|
176
195
|
BeforeValidator(_maybe_deserialize_compact_node_spec)
|
|
177
196
|
]
|
|
@@ -191,13 +210,10 @@ def get_node_spec_adapter() -> TypeAdapter[NodeSpec]:
|
|
|
191
210
|
return _node_spec_adapter
|
|
192
211
|
|
|
193
212
|
|
|
194
|
-
NodeSetKind = Literal['NodeSet']
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
NodeSetIdentifier = str
|
|
213
|
+
NodeSetKind: TypeAlias = Literal['NodeSet']
|
|
198
214
|
|
|
199
215
|
|
|
200
|
-
|
|
216
|
+
NodeSetIdentifier: TypeAlias = str
|
|
201
217
|
|
|
202
218
|
|
|
203
219
|
class NodeSet(BaseModel):
|
|
@@ -211,6 +227,6 @@ class NodeSet(BaseModel):
|
|
|
211
227
|
name: str = Field(title='Node Set Name',
|
|
212
228
|
description='A name for the node set')
|
|
213
229
|
|
|
214
|
-
nodes:
|
|
215
|
-
|
|
216
|
-
|
|
230
|
+
nodes: list[NodeSpec] = Field(min_length=1,
|
|
231
|
+
title='Nodes',
|
|
232
|
+
description='A non-empty list of nodes')
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|