mirror of
https://github.com/zap-proto/spec.git
synced 2026-10-30 15:04:03 +00:00
config.py imported the stdlib 'tomllib' unconditionally, but that module only exists in 3.11+. On 3.10 the import crashed at package-import time, breaking ALL test collection (pytest exit 2) despite requires-python>=3.10. Use tomli as 'tomllib' on <3.11 (identical API; tomllib is tomli upstream) and declare 'tomli>=2.0; python_version < 3.11' as a runtime dependency. Green now on 3.10 / 3.11 / 3.12: ruff + mypy clean, 129 passed, ~91% cov.
94 lines
2.2 KiB
Python
94 lines
2.2 KiB
Python
"""ZAP configuration."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from dataclasses import dataclass, field
|
|
from enum import Enum
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
if sys.version_info >= (3, 11):
|
|
import tomllib
|
|
else: # Python 3.10: tomllib was added to the stdlib in 3.11
|
|
import tomli as tomllib
|
|
|
|
|
|
class Transport(Enum):
|
|
"""Transport type."""
|
|
|
|
STDIO = "stdio"
|
|
HTTP = "http"
|
|
WEBSOCKET = "websocket"
|
|
ZAP = "zap"
|
|
UNIX = "unix"
|
|
|
|
|
|
@dataclass
|
|
class Auth:
|
|
"""Authentication config."""
|
|
|
|
type: str = "none"
|
|
token: str | None = None
|
|
username: str | None = None
|
|
password: str | None = None
|
|
|
|
|
|
@dataclass
|
|
class ServerConfig:
|
|
"""Server configuration."""
|
|
|
|
name: str
|
|
url: str
|
|
transport: Transport = Transport.STDIO
|
|
timeout: int = 30000
|
|
auth: Auth | None = None
|
|
|
|
|
|
@dataclass
|
|
class Config:
|
|
"""ZAP configuration."""
|
|
|
|
listen: str = "0.0.0.0"
|
|
port: int = 9999
|
|
servers: list[ServerConfig] = field(default_factory=list)
|
|
log_level: str = "info"
|
|
|
|
@classmethod
|
|
def load(cls, path: Path) -> Config:
|
|
"""Load config from file."""
|
|
with open(path, "rb") as f:
|
|
data = tomllib.load(f)
|
|
return cls.from_dict(data)
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: dict[str, Any]) -> Config:
|
|
"""Create config from dict."""
|
|
servers = [
|
|
ServerConfig(
|
|
name=s["name"],
|
|
url=s["url"],
|
|
transport=Transport(s.get("transport", "stdio")),
|
|
timeout=s.get("timeout", 30000),
|
|
)
|
|
for s in data.get("servers", [])
|
|
]
|
|
return cls(
|
|
listen=data.get("listen", "0.0.0.0"),
|
|
port=data.get("port", 9999),
|
|
servers=servers,
|
|
log_level=data.get("log_level", "info"),
|
|
)
|
|
|
|
@staticmethod
|
|
def default_path() -> Path:
|
|
"""Get default config path."""
|
|
import platform
|
|
|
|
if platform.system() == "Darwin":
|
|
return Path.home() / "Library" / "Application Support" / "zap" / "config.toml"
|
|
elif platform.system() == "Windows":
|
|
return Path.home() / "AppData" / "Roaming" / "zap" / "config.toml"
|
|
else:
|
|
return Path.home() / ".config" / "zap" / "config.toml"
|