flowmesh-sdk-stack 0.1.1__tar.gz → 0.1.2__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.
Files changed (19) hide show
  1. {flowmesh_sdk_stack-0.1.1/src/flowmesh_sdk_stack.egg-info → flowmesh_sdk_stack-0.1.2}/PKG-INFO +2 -2
  2. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/pyproject.toml +2 -2
  3. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2/src/flowmesh_sdk_stack.egg-info}/PKG-INFO +2 -2
  4. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/src/flowmesh_sdk_stack.egg-info/requires.txt +1 -1
  5. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/src/flowmesh_stack/env_schema.py +35 -8
  6. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/LICENSE +0 -0
  7. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/README.md +0 -0
  8. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/setup.cfg +0 -0
  9. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/src/flowmesh_sdk_stack.egg-info/SOURCES.txt +0 -0
  10. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/src/flowmesh_sdk_stack.egg-info/dependency_links.txt +0 -0
  11. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/src/flowmesh_sdk_stack.egg-info/top_level.txt +0 -0
  12. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/src/flowmesh_stack/__init__.py +0 -0
  13. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/src/flowmesh_stack/docker.py +0 -0
  14. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/src/flowmesh_stack/doctor.py +0 -0
  15. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/src/flowmesh_stack/env.py +0 -0
  16. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/src/flowmesh_stack/images.py +0 -0
  17. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/src/flowmesh_stack/node_client.py +0 -0
  18. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/src/flowmesh_stack/paths.py +0 -0
  19. {flowmesh_sdk_stack-0.1.1 → flowmesh_sdk_stack-0.1.2}/src/flowmesh_stack/workers.py +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flowmesh-sdk-stack
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: FlowMesh SDK stack client
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: >=3.12
7
7
  Description-Content-Type: text/markdown
8
8
  License-File: LICENSE
9
- Requires-Dist: flowmesh-sdk==0.1.1
9
+ Requires-Dist: flowmesh-sdk==0.1.2
10
10
  Requires-Dist: httpx>=0.27.0
11
11
  Requires-Dist: pyyaml>=6.0.0
12
12
  Requires-Dist: docker>=7.1.0
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "flowmesh-sdk-stack"
7
- version = "0.1.1"
7
+ version = "0.1.2"
8
8
  description = "FlowMesh SDK stack client"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
11
11
  license = "Apache-2.0"
12
12
  license-files = ["LICENSE"]
13
13
  dependencies = [
14
- "flowmesh-sdk==0.1.1",
14
+ "flowmesh-sdk==0.1.2",
15
15
  "httpx>=0.27.0",
16
16
  "pyyaml>=6.0.0",
17
17
  "docker>=7.1.0",
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flowmesh-sdk-stack
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: FlowMesh SDK stack client
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: >=3.12
7
7
  Description-Content-Type: text/markdown
8
8
  License-File: LICENSE
9
- Requires-Dist: flowmesh-sdk==0.1.1
9
+ Requires-Dist: flowmesh-sdk==0.1.2
10
10
  Requires-Dist: httpx>=0.27.0
11
11
  Requires-Dist: pyyaml>=6.0.0
12
12
  Requires-Dist: docker>=7.1.0
@@ -1,4 +1,4 @@
1
- flowmesh-sdk==0.1.1
1
+ flowmesh-sdk==0.1.2
2
2
  httpx>=0.27.0
3
3
  pyyaml>=6.0.0
4
4
  docker>=7.1.0
@@ -1,6 +1,7 @@
1
1
  """Environment schema definitions and pure validation helpers."""
2
2
 
3
3
  import enum
4
+ import operator
4
5
  from collections.abc import Callable, Iterable, Mapping
5
6
  from dataclasses import dataclass, field
6
7
  from logging import _nameToLevel as LOG_LEVELS
@@ -34,7 +35,9 @@ class EnvVar:
34
35
  use_default: bool = False
35
36
  choices: Iterable[str] | None = None
36
37
  min_value: float | None = None
38
+ min_inclusive: bool = True
37
39
  max_value: float | None = None
40
+ max_inclusive: bool = True
38
41
  min_length: int | None = None
39
42
  ensure_path: Literal["error", "warn", "create"] | None = None
40
43
  url_schemes: set[str] | None = None
@@ -133,19 +136,13 @@ def validate_env_values(
133
136
  if int_value is None:
134
137
  errors.append(f"{var.key} must be an integer")
135
138
  continue
136
- if var.min_value is not None and int_value < var.min_value:
137
- errors.append(f"{var.key} must be >= {int(var.min_value)}")
138
- if var.max_value is not None and int_value > var.max_value:
139
- errors.append(f"{var.key} must be <= {int(var.max_value)}")
139
+ _check_value_range(var, int_value, errors)
140
140
  case EnvVarType.FLOAT:
141
141
  float_value = parse_float(raw)
142
142
  if float_value is None:
143
143
  errors.append(f"{var.key} must be a number")
144
144
  continue
145
- if var.min_value is not None and float_value < var.min_value:
146
- errors.append(f"{var.key} must be >= {var.min_value}")
147
- if var.max_value is not None and float_value > var.max_value:
148
- errors.append(f"{var.key} must be <= {var.max_value}")
145
+ _check_value_range(var, float_value, errors)
149
146
  case EnvVarType.BOOL:
150
147
  if parse_bool(raw) is None:
151
148
  errors.append(
@@ -213,6 +210,36 @@ def require_all_or_none(
213
210
  errors.append(f"Either all or none of {', '.join(keys)} must be set")
214
211
 
215
212
 
213
+ _COMPARE_OPS = {
214
+ "<": operator.lt,
215
+ "<=": operator.le,
216
+ ">": operator.gt,
217
+ ">=": operator.ge,
218
+ }
219
+
220
+
221
+ def _check_value_range(var: EnvVar, value: float, errors: list[str]) -> None:
222
+ comp: Literal["<", "<=", ">", ">="]
223
+ if var.min_value is not None:
224
+ comp = ">=" if var.min_inclusive else ">"
225
+ _check_bound(var, value, var.min_value, comp, errors)
226
+ if var.max_value is not None:
227
+ comp = "<=" if var.max_inclusive else "<"
228
+ _check_bound(var, value, var.max_value, comp, errors)
229
+
230
+
231
+ def _check_bound(
232
+ var: EnvVar,
233
+ value: float,
234
+ bound: float,
235
+ comparison: Literal["<", "<=", ">", ">="],
236
+ errors: list[str],
237
+ ) -> None:
238
+ op = _COMPARE_OPS[comparison]
239
+ if not op(value, bound):
240
+ errors.append(f"{var.key} must be {comparison} {bound}")
241
+
242
+
216
243
  def _ensure_path(raw: str, var: EnvVar, errors: list[str], warnings: list[str]) -> None:
217
244
  if not raw:
218
245
  errors.append(f"{var.key} must be a non-empty path")