← Files JinkōARCHIVED FILE
skills/jinko-solution-and-product-guide/scripts/search_model_library.py
4.71 KB · Oct 5, 2026 · 18:30 UTC
#!/usr/bin/env python3
"""Fetch, validate, and deterministically filter the public Jinkō model library."""
from __future__ import annotations
import argparse
import json
from typing import Any
from urllib.parse import urlsplit
from urllib.request import HTTPRedirectHandler, Request, build_opener
LIBRARY_URL = "https://doc.jinko.ai/model-library.json"
TRUSTED_HOST = "doc.jinko.ai"
MAX_RESPONSE_BYTES = 5 * 1024 * 1024
REQUIRED_FIELDS = (
"projectName",
"type",
"groupName",
"description",
"contextOfUse",
"inputs",
"outputs",
"Access",
)
class NoRedirectHandler(HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl): # noqa: ANN001
return None
def fetch_library() -> bytes:
request = Request(
LIBRARY_URL,
headers={
"Accept": "application/json",
"User-Agent": "jinko-skills-model-library/1",
},
)
opener = build_opener(NoRedirectHandler())
with opener.open(request, timeout=20) as response: # noqa: S310 - fixed URL
final_url = urlsplit(response.geturl())
if final_url.scheme != "https" or final_url.hostname != TRUSTED_HOST:
raise ValueError(
f"Refusing model-library redirect to {response.geturl()!r}"
)
declared_size = response.headers.get("Content-Length")
if declared_size and int(declared_size) > MAX_RESPONSE_BYTES:
raise ValueError("Model-library response exceeds the 5 MiB limit")
payload = response.read(MAX_RESPONSE_BYTES + 1)
if len(payload) > MAX_RESPONSE_BYTES:
raise ValueError("Model-library response exceeds the 5 MiB limit")
return payload
def validate_library(payload: bytes) -> list[dict[str, str]]:
parsed = json.loads(payload)
if not isinstance(parsed, list):
raise ValueError("Model library must be a JSON array")
records: list[dict[str, str]] = []
for index, item in enumerate(parsed):
if not isinstance(item, dict):
raise ValueError(f"Model record {index} is not an object")
missing = [field for field in REQUIRED_FIELDS if field not in item]
if missing:
raise ValueError(f"Model record {index} is missing: {', '.join(missing)}")
invalid = [
field for field in REQUIRED_FIELDS if not isinstance(item[field], str)
]
if invalid:
raise ValueError(
f"Model record {index} has non-string fields: {', '.join(invalid)}"
)
records.append({field: item[field] for field in REQUIRED_FIELDS})
return records
def filter_library(
records: list[dict[str, str]],
*,
query: str | None,
model_type: str | None,
group: str | None,
access: str | None,
) -> list[dict[str, str]]:
query_value = query.casefold() if query else None
def matches(record: dict[str, str]) -> bool:
if model_type and record["type"].casefold() != model_type.casefold():
return False
if group and record["groupName"].casefold() != group.casefold():
return False
if access and record["Access"].casefold() != access.casefold():
return False
if query_value and not any(
query_value in record[field].casefold() for field in REQUIRED_FIELDS
):
return False
return True
return sorted(
(record for record in records if matches(record)),
key=lambda record: (
record["projectName"].casefold(),
record["type"].casefold(),
record["groupName"].casefold(),
),
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument(
"--query", help="Case-insensitive text contained in any required field"
)
parser.add_argument("--type", dest="model_type", help="Exact model type")
parser.add_argument("--group", help="Exact group name")
parser.add_argument("--access", help="Exact Access value")
parser.add_argument("--limit", type=int, default=20, choices=range(1, 101))
return parser.parse_args()
def main() -> int:
args = parse_args()
records = validate_library(fetch_library())
matches = filter_library(
records,
query=args.query,
model_type=args.model_type,
group=args.group,
access=args.access,
)
output: dict[str, Any] = {
"source": LIBRARY_URL,
"total_records": len(records),
"matching_records": len(matches),
"returned_records": min(len(matches), args.limit),
"models": matches[: args.limit],
}
print(json.dumps(output, ensure_ascii=True, indent=2, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())
SHA-256: ea24dab60f856e89faada90ec7298f0efbf6e96a7749ebbdcdab864a7b3eaffa