mirror of
https://github.com/larksuite/cli.git
synced 2026-07-04 06:29:52 +08:00
99 lines
3.3 KiB
Python
99 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
# Copyright (c) 2026 Lark Technologies Pte. Ltd.
|
|
# SPDX-License-Identifier: MIT
|
|
"""Fetch meta_data.json from remote API for build-time embedding.
|
|
|
|
Usage:
|
|
python3 scripts/fetch_meta.py # fetch from feishu (default)
|
|
python3 scripts/fetch_meta.py --brand lark # fetch from larksuite
|
|
"""
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import urllib.request
|
|
import urllib.error
|
|
|
|
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
ROOT = os.path.join(SCRIPT_DIR, "..")
|
|
OUT_PATH = os.path.join(ROOT, "internal", "registry", "meta_data.json")
|
|
|
|
API_HOSTS = {
|
|
"feishu": "https://open.feishu.cn/api/tools/open/api_definition",
|
|
"lark": "https://open.larksuite.com/api/tools/open/api_definition",
|
|
}
|
|
|
|
TIMEOUT = 10 # seconds
|
|
|
|
|
|
def get_version():
|
|
"""Get version from git tags, matching Makefile logic."""
|
|
try:
|
|
return subprocess.check_output(
|
|
["git", "describe", "--tags", "--always", "--dirty"],
|
|
stderr=subprocess.DEVNULL,
|
|
text=True,
|
|
cwd=ROOT,
|
|
).strip()
|
|
except Exception:
|
|
return "dev"
|
|
|
|
|
|
def fetch_remote(brand):
|
|
"""Fetch MergedRegistry from remote API."""
|
|
base = API_HOSTS.get(brand, API_HOSTS["feishu"])
|
|
version = get_version()
|
|
url = f"{base}?protocol=meta&client_version={urllib.request.quote(version)}"
|
|
|
|
print(f"fetch-meta: GET {url}", file=sys.stderr)
|
|
req = urllib.request.Request(url)
|
|
resp = urllib.request.urlopen(req, timeout=TIMEOUT)
|
|
body = resp.read()
|
|
|
|
envelope = json.loads(body)
|
|
if envelope.get("msg") != "succeeded":
|
|
raise RuntimeError(f"unexpected response msg: {envelope.get('msg')!r}")
|
|
|
|
data = envelope.get("data", {})
|
|
if not data.get("services"):
|
|
raise RuntimeError("remote returned empty services")
|
|
|
|
return data
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Fetch meta_data.json for build-time embedding")
|
|
parser.add_argument("--brand", default="feishu", choices=["feishu", "lark"],
|
|
help="API brand (default: feishu)")
|
|
parser.add_argument("--force", action="store_true",
|
|
help="force refresh from remote even if local file exists")
|
|
args = parser.parse_args()
|
|
|
|
if os.path.exists(OUT_PATH) and not args.force:
|
|
if os.path.isfile(OUT_PATH):
|
|
try:
|
|
with open(OUT_PATH, "r", encoding="utf-8") as fp:
|
|
local = json.load(fp)
|
|
if local.get("services"):
|
|
print(f"fetch-meta: {OUT_PATH} already exists, skipping (use --force to re-fetch)", file=sys.stderr)
|
|
return
|
|
print(f"fetch-meta: {OUT_PATH} has no services, re-fetching", file=sys.stderr)
|
|
except (OSError, json.JSONDecodeError):
|
|
print(f"fetch-meta: {OUT_PATH} is invalid JSON, re-fetching", file=sys.stderr)
|
|
else:
|
|
print(f"fetch-meta: {OUT_PATH} is not a file, re-fetching", file=sys.stderr)
|
|
|
|
data = fetch_remote(args.brand)
|
|
count = len(data.get("services", []))
|
|
print(f"fetch-meta: OK, {count} services from remote API", file=sys.stderr)
|
|
|
|
with open(OUT_PATH, "w", encoding="utf-8", newline="\n") as fp:
|
|
json.dump(data, fp, ensure_ascii=False, indent=2)
|
|
fp.write("\n")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|