Setting the file. One moment.
Hf Model Card Frontmatter · Huggingface Tool Builder · huggingface/skills · Skills Docs
ContentsBack to the top of the page references/ hf_model_card_frontmatter.sh
Shell · 188 lines · 4 KB
16 Uses HF_TOKEN if set (passed to the hf CLI).
17
18 Output fields:
19 id, license, pipeline_tag, library_name, tags, language,
20 new_version, has_extra_gated_prompt
21
22 Examples:
23 hf_model_card_frontmatter.sh openai/gpt-oss-120b
24 cat ids.txt | hf_model_card_frontmatter.sh | jq -s '.'
25 hf_model_card_frontmatter.sh meta-llama/Meta-Llama-3-8B \
26 | jq -s 'map({id, license, has_extra_gated_prompt})'
27 USAGE
28 }
29
30 if [[ " ${1 :- } " == "--help" ]]; then
31 show_help
32 exit 0
33 fi
34
35 if ! command -v hf > /dev/null 2>&1 ; then
36 echo "Error: hf CLI is required but not installed" >&2
37 exit 1
38 fi
39
40 if ! command -v python3 > /dev/null 2>&1 ; then
41 echo "Error: python3 is required but not installed" >&2
42 exit 1
43 fi
44
45 token_args = ()
46 if [[ -n "${ HF_TOKEN :- }" ]]; then
47 token_args = ( --token " $HF_TOKEN " )
48 fi
49
50 tmp_dir = $( mktemp -d )
51 cleanup () {
52 rm -rf " $tmp_dir "
53 }
54 trap cleanup EXIT
55
56 emit_error () {
57 local model_id = " $1 "
58 local message = " $2 "
59 python3 - << 'PY' " $model_id " " $message "
60 import json
61 import sys
62
63 model_id = sys.argv[1]
64 message = sys.argv[2]
65 print(json.dumps({"id": model_id, "error": message}))
66 PY
67 }
68
69 parse_readme () {
70 local model_id = " $1 "
71 local readme_path = " $2 "
72
73 MODEL_ID = " $model_id " README_PATH = " $readme_path " python3 - << 'PY'
74 import json
75 import os
76 import sys
77
78 model_id = os.environ.get("MODEL_ID", "")
79 readme_path = os.environ.get("README_PATH", "")
80
81 try:
82 with open(readme_path, "r", encoding="utf-8") as f:
83 lines = f.read().splitlines()
84 except OSError:
85 print(json.dumps({"id": model_id, "error": "readme_missing"}))
86 sys.exit(0)
87
88 frontmatter = []
89 in_block = False
90 for line in lines:
91 if line.strip() == "---":
92 if in_block:
93 break
94 in_block = True
95 continue
96 if in_block:
97 frontmatter.append(line)
98
99 if not frontmatter:
100 print(json.dumps({"id": model_id, "error": "frontmatter_missing"}))
101 sys.exit(0)
102
103 key = None
104 out = {}
105
106 for line in frontmatter:
107 stripped = line.strip()
108 if not stripped or line.lstrip().startswith("#"):
109 continue
110
111 if ":" in line and not line.lstrip().startswith("- "):
112 key_candidate, value = line.split(":", 1)
113 key_candidate = key_candidate.strip()
114 value = value.strip()
115 if key_candidate and all(c.isalnum() or c in "_-" for c in key_candidate):
116 key = key_candidate
117 if value in ("|", "|-", ">", ">-") or value == "":
118 out[key] = None
119 continue
120 if value.startswith("[") and value.endswith("]"):
121 items = [v.strip() for v in value.strip("[]").split(",") if v.strip()]
122 out[key] = items
123 else:
124 out[key] = value
125 continue
126
127 if line.lstrip().startswith("- ") and key:
128 item = line.strip()[2:]
129 if key not in out or out[key] is None:
130 out[key] = []
131 if isinstance(out[key], list):
132 out[key].append(item)
133
134 result = {
135 "id": model_id,
136 "license": out.get("license"),
137 "pipeline_tag": out.get("pipeline_tag"),
138 "library_name": out.get("library_name"),
139 "tags": out.get("tags", []),
140 "language": out.get("language", []),
141 "new_version": out.get("new_version"),
142 "has_extra_gated_prompt": "extra_gated_prompt" in out,
143 }
144
145 print(json.dumps(result))
146 PY
147 }
148
149 process_id () {
150 local model_id = " $1 "
151
152 if [[ -z " $model_id " ]]; then
153 return 0
154 fi
155
156 local safe_id
157 safe_id = $( printf '%s' " $model_id " | tr '/' '_' )
158 local local_dir = " $tmp_dir / $safe_id "
159
160 if ! hf download " $model_id " README.md --repo-type model --local-dir " $local_dir " "${ token_args [ @ ]}" > /dev/null 2>&1 ; then
161 emit_error " $model_id " "download_failed"
162 return 0
163 fi
164
165 local readme_path = " $local_dir /README.md"
166 if [[ ! -f " $readme_path " ]]; then
167 emit_error " $model_id " "readme_missing"
168 return 0
169 fi
170
171 parse_readme " $model_id " " $readme_path "
172 }
173
174 if [[ $# -gt 0 ]]; then
175 for model_id in " $@ " ; do
176 process_id " $model_id "
177 done
178 exit 0
179 fi
180
181 if [[ -t 0 ]]; then
182 show_help
183 exit 1
184 fi
185
186 while IFS = read -r model_id ; do
187 process_id " $model_id "
188 done