_common.py
"""给所有 Python 示例共用的最小启动代码。
目标:
1. 让示例不依赖 pytest,直接 ``python xx.py`` 就能跑;
2. 从下列位置之一加载环境变量(排序即优先级):
- 进程环境变量 VJMAP_API / VJMAP_TOKEN / ...
- ``vjmap-service/tests/.env``(可选)
- 上级目录 ``test/.env``(可选;使用 ``k:v`` 或 ``k=v`` 均可)
3. 导出 :func:`make_client` 一键拿 :class:`vjmap.Vjmap` 实例。
"""
from __future__ import annotations
import os
import sys
from pathlib import Path
from typing import Dict
HERE = Path(__file__).resolve().parent
NB_ROOT = HERE.parent.parent
SDK_DIR = NB_ROOT / "sdk" / "python"
if str(SDK_DIR) not in sys.path:
sys.path.insert(0, str(SDK_DIR))
import vjmap
def _parse_env_file(path: Path) -> Dict[str, str]:
out: Dict[str, str] = {}
if not path.is_file():
return out
for line in path.read_text("utf-8").splitlines():
line = line.strip()
if not line or line.startswith("#"):
continue
sep_eq = line.find("=")
sep_co = line.find(":")
if sep_eq != -1 and (sep_co == -1 or sep_eq < sep_co):
k, v = line[:sep_eq], line[sep_eq + 1:]
elif sep_co != -1:
k, v = line[:sep_co], line[sep_co + 1:]
else:
continue
out[k.strip()] = v.strip().strip('"').strip("'")
return out
def _merge_env() -> Dict[str, str]:
merged: Dict[str, str] = dict(os.environ)
nb_env = NB_ROOT / "tests" / ".env"
for k, v in _parse_env_file(nb_env).items():
merged.setdefault(k, v)
root_env = NB_ROOT.parent / "test" / ".env"
alias = {"api": "VJMAP_API", "token": "VJMAP_TOKEN", "map_super_key": "VJMAP_MAP_SUPER_KEY"}
for k, v in _parse_env_file(root_env).items():
key = alias.get(k, k)
merged.setdefault(key, v)
return merged
_ENV = _merge_env()
def env(key: str, default: str = "") -> str:
return _ENV.get(key, default)
def make_client() -> vjmap.Vjmap:
base = env("VJMAP_API", "http://127.0.0.1:27660/api/v1").rstrip("/")
token = env("VJMAP_TOKEN", "")
if not token:
raise SystemExit("VJMAP_TOKEN 未配置:请设置环境变量(或写入 vjmap-service/tests/.env)")
return vjmap.Vjmap(base, token)
def sample_mapid() -> str:
return env("VJMAP_SAMPLE_MAPID", "sys_zp")
def sample_version() -> str:
return env("VJMAP_SAMPLE_VERSION", "v1")
def sample_dwg() -> Path:
d = env("VJMAP_TEST_DWG_DIR") or "test"
n = env("VJMAP_TEST_DWG_NAME") or "caf27de8a225.dwg"
repo_root = NB_ROOT.parent
candidates = [
(repo_root / d / n),
(NB_ROOT / d / n),
(Path(d) / n) if Path(d).is_absolute() else None,
]
for c in candidates:
if c is not None and c.is_file():
return c
raise SystemExit(
f"示例 DWG 不存在,已尝试:{[str(c) for c in candidates if c]}\n"
f"请用环境变量(或 vjmap-service/tests/.env)设置 VJMAP_TEST_DWG_DIR / VJMAP_TEST_DWG_NAME"
)