HTML 77.2%
TypeScript 10.5%
Python 9.6%
JavaScript 2.5%
1"""Licence ontology.23A licence is identified by its SPDX id when one exists (`Apache-2.0`, `MIT`, `CC-BY-NC-4.0`) and by a stable AI Atlas key otherwise4(`llama-3.1-community`, `gemma-terms`, `openrail-m`). Every entry states, as booleans (or `None` when the text is ambiguous), what the5licence permits — so the UI can say "commercial use allowed / derivatives allowed / redistribution allowed / acceptable-use restrictions"6instead of the meaningless "open source" for a model whose weights merely download.78`normalize_license(raw)` maps the strings observed in the wild (Hugging Face `license:` tags, docs pages, GitHub) to a canonical key.9Unknown strings return `None` — the raw label is kept separately by the writer (`license_raw`); nothing is guessed.10"""11from __future__ import annotations1213import re14from dataclasses import dataclass, field1516# Categories are about *what the text allows*, not about ideology.17CATEGORIES = ("permissive", "copyleft", "creative-commons", "responsible-ai", "community", "research-only", "proprietary", "unknown")181920@dataclass(frozen=True)21class LicenseInfo:22 key: str # canonical key (SPDX id when applicable)23 label: str # display name24 category: str # one of CATEGORIES25 spdx: str | None = None # SPDX identifier when the licence is in the SPDX list26 url: str | None = None # canonical text27 commercial_use: bool | None = None # may be used commercially28 redistribution: bool | None = None # weights/code may be redistributed29 derivatives: bool | None = None # fine-tunes / modifications allowed30 hosting_restrictions: bool | None = None # restrictions on hosting the model as a service for third parties (incl. MAU caps)31 attribution: bool | None = None # attribution / notice required32 acceptable_use: bool | None = None # an acceptable-use policy restricts what the model may do33 osi_approved: bool = False # OSI-approved open-source licence (code) — never true for custom model licences34 weights_downloadable: bool = True # False for proprietary API-only terms35 aliases: tuple[str, ...] = field(default_factory=tuple)3637 def as_dict(self) -> dict[str, object]:38 return {39 "key": self.key, "label": self.label, "category": self.category, "spdx": self.spdx, "url": self.url,40 "commercial_use": self.commercial_use, "redistribution": self.redistribution, "derivatives": self.derivatives,41 "hosting_restrictions": self.hosting_restrictions, "attribution": self.attribution, "acceptable_use": self.acceptable_use,42 "osi_approved": self.osi_approved, "weights_downloadable": self.weights_downloadable,43 }444546def _permissive(key: str, label: str, spdx: str, url: str, **kw: object) -> LicenseInfo:47 base: dict[str, object] = dict(key=key, label=label, category="permissive", spdx=spdx, url=url, commercial_use=True, redistribution=True,48 derivatives=True, hosting_restrictions=False, attribution=True, acceptable_use=False, osi_approved=True)49 base.update(kw)50 return LicenseInfo(**base) # type: ignore[arg-type]515253LICENSES: dict[str, LicenseInfo] = {}545556def _add(info: LicenseInfo) -> None:57 LICENSES[info.key] = info585960# ---------------------------------------------------------------------------------------------- permissive / copyleft (OSI)61_add(_permissive("Apache-2.0", "Apache License 2.0", "Apache-2.0", "https://www.apache.org/licenses/LICENSE-2.0",62 aliases=("apache 2.0", "apache-2", "apache2", "apache license 2.0", "apache license, version 2.0", "apache", "apache license",63 "apache software license", "apache software license 2.0", "asl 2.0", "asl-2.0")))64_add(_permissive("MIT", "MIT License", "MIT", "https://opensource.org/license/mit", aliases=("mit license", "the mit license")))65_add(LicenseInfo(key="MIT-Modified", label="Modified MIT License", category="permissive", spdx=None, commercial_use=True, redistribution=True,66 derivatives=True, hosting_restrictions=None, attribution=True, acceptable_use=None, aliases=("modified mit", "mit-modified")))67_add(_permissive("BSD-3-Clause", "BSD 3-Clause License", "BSD-3-Clause", "https://opensource.org/license/bsd-3-clause",68 aliases=("bsd-3", "bsd 3-clause", "bsd3", "new bsd", "modified bsd", "bsd", "bsd license", "bsd-3-clause license")))69_add(_permissive("BSD-2-Clause", "BSD 2-Clause License", "BSD-2-Clause", "https://opensource.org/license/bsd-2-clause", aliases=("bsd-2", "simplified bsd")))70_add(_permissive("ISC", "ISC License", "ISC", "https://opensource.org/license/isc-license-txt"))71_add(_permissive("Unlicense", "The Unlicense", "Unlicense", "https://unlicense.org", attribution=False, aliases=("unlicense",)))72_add(_permissive("0BSD", "Zero-Clause BSD", "0BSD", "https://opensource.org/license/0bsd", attribution=False))73_add(LicenseInfo(key="GPL-3.0", label="GNU GPL v3", category="copyleft", spdx="GPL-3.0-only", url="https://www.gnu.org/licenses/gpl-3.0.html",74 commercial_use=True, redistribution=True, derivatives=True, hosting_restrictions=False, attribution=True, acceptable_use=False,75 osi_approved=True, aliases=("gpl-3.0-only", "gpl-3.0-or-later", "gplv3", "gpl3", "gpl-3")))76_add(LicenseInfo(key="GPL-2.0", label="GNU GPL v2", category="copyleft", spdx="GPL-2.0-only", url="https://www.gnu.org/licenses/old-licenses/gpl-2.0.html",77 commercial_use=True, redistribution=True, derivatives=True, hosting_restrictions=False, attribution=True, acceptable_use=False,78 osi_approved=True, aliases=("gpl-2.0-only", "gpl-2.0-or-later", "gplv2", "gpl2", "gpl-2")))79_add(LicenseInfo(key="LGPL-3.0", label="GNU LGPL v3", category="copyleft", spdx="LGPL-3.0-only", url="https://www.gnu.org/licenses/lgpl-3.0.html",80 commercial_use=True, redistribution=True, derivatives=True, hosting_restrictions=False, attribution=True, acceptable_use=False,81 osi_approved=True, aliases=("lgpl-3.0-only", "lgpl-3.0-or-later", "lgplv3", "lgpl")))82_add(LicenseInfo(key="AGPL-3.0", label="GNU AGPL v3", category="copyleft", spdx="AGPL-3.0-only", url="https://www.gnu.org/licenses/agpl-3.0.html",83 commercial_use=True, redistribution=True, derivatives=True, hosting_restrictions=True, attribution=True, acceptable_use=False,84 osi_approved=True, aliases=("agpl-3.0-only", "agpl-3.0-or-later", "agplv3", "agpl")))85_add(LicenseInfo(key="MPL-2.0", label="Mozilla Public License 2.0", category="copyleft", spdx="MPL-2.0", url="https://www.mozilla.org/MPL/2.0/",86 commercial_use=True, redistribution=True, derivatives=True, hosting_restrictions=False, attribution=True, acceptable_use=False,87 osi_approved=True, aliases=("mpl", "mozilla public license 2.0")))88_add(LicenseInfo(key="EPL-2.0", label="Eclipse Public License 2.0", category="copyleft", spdx="EPL-2.0", url="https://www.eclipse.org/legal/epl-2.0/",89 commercial_use=True, redistribution=True, derivatives=True, hosting_restrictions=False, attribution=True, acceptable_use=False, osi_approved=True))9091# ---------------------------------------------------------------------------------------------- Creative Commons92def _cc(key: str, label: str, url: str, *, nc: bool, nd: bool, sa: bool, aliases: tuple[str, ...]) -> LicenseInfo:93 return LicenseInfo(key=key, label=label, category="creative-commons", spdx=key, url=url, commercial_use=not nc, redistribution=True,94 derivatives=not nd, hosting_restrictions=nc or None, attribution=True, acceptable_use=False, osi_approved=False, aliases=aliases)959697_add(_cc("CC-BY-4.0", "Creative Commons Attribution 4.0", "https://creativecommons.org/licenses/by/4.0/", nc=False, nd=False, sa=False,98 aliases=("cc by 4.0", "cc-by", "cc by", "cc-by-4", "creative commons attribution 4.0")))99_add(_cc("CC-BY-SA-4.0", "Creative Commons Attribution-ShareAlike 4.0", "https://creativecommons.org/licenses/by-sa/4.0/", nc=False, nd=False, sa=True,100 aliases=("cc by-sa 4.0", "cc-by-sa", "cc by-sa")))101_add(_cc("CC-BY-NC-4.0", "Creative Commons Attribution-NonCommercial 4.0", "https://creativecommons.org/licenses/by-nc/4.0/", nc=True, nd=False, sa=False,102 aliases=("cc by-nc 4.0", "cc-by-nc", "cc by-nc", "cc-by-nc-4", "creative commons attribution non commercial 4.0")))103_add(_cc("CC-BY-NC-SA-4.0", "Creative Commons Attribution-NonCommercial-ShareAlike 4.0", "https://creativecommons.org/licenses/by-nc-sa/4.0/", nc=True, nd=False, sa=True,104 aliases=("cc by-nc-sa 4.0", "cc-by-nc-sa", "cc by-nc-sa")))105_add(_cc("CC-BY-NC-ND-4.0", "Creative Commons Attribution-NonCommercial-NoDerivatives 4.0", "https://creativecommons.org/licenses/by-nc-nd/4.0/", nc=True, nd=True, sa=False,106 aliases=("cc by-nc-nd 4.0", "cc-by-nc-nd")))107_add(_cc("CC-BY-ND-4.0", "Creative Commons Attribution-NoDerivatives 4.0", "https://creativecommons.org/licenses/by-nd/4.0/", nc=False, nd=True, sa=False,108 aliases=("cc by-nd 4.0", "cc-by-nd")))109_add(LicenseInfo(key="CC0-1.0", label="Creative Commons Zero 1.0 (public domain dedication)", category="creative-commons", spdx="CC0-1.0",110 url="https://creativecommons.org/publicdomain/zero/1.0/", commercial_use=True, redistribution=True, derivatives=True,111 hosting_restrictions=False, attribution=False, acceptable_use=False, aliases=("cc0", "cc0 1.0", "public domain")))112_add(LicenseInfo(key="ODC-By-1.0", label="Open Data Commons Attribution", category="creative-commons", spdx="ODC-By-1.0", url="https://opendatacommons.org/licenses/by/1-0/",113 commercial_use=True, redistribution=True, derivatives=True, hosting_restrictions=False, attribution=True, acceptable_use=False, aliases=("odc-by",)))114_add(LicenseInfo(key="PDDL-1.0", label="Open Data Commons Public Domain Dedication", category="creative-commons", spdx="PDDL-1.0", url="https://opendatacommons.org/licenses/pddl/",115 commercial_use=True, redistribution=True, derivatives=True, hosting_restrictions=False, attribution=False, acceptable_use=False, aliases=("pddl",)))116117# ---------------------------------------------------------------------------------------------- responsible-AI (RAIL) family118def _rail(key: str, label: str, url: str, aliases: tuple[str, ...]) -> LicenseInfo:119 return LicenseInfo(key=key, label=label, category="responsible-ai", spdx=None, url=url, commercial_use=True, redistribution=True, derivatives=True,120 hosting_restrictions=False, attribution=True, acceptable_use=True, osi_approved=False, aliases=aliases)121122123_add(_rail("OpenRAIL-M", "Open RAIL-M", "https://www.licenses.ai/ai-licenses", ("openrail", "openrail-m", "open rail-m", "creativeml-openrail-m", "creativeml openrail-m")))124_add(_rail("OpenRAIL++-M", "Open RAIL++-M (Stable Diffusion XL)", "https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/LICENSE.md", ("openrail++", "openrail++-m")))125_add(_rail("BigScience-BLOOM-RAIL-1.0", "BigScience BLOOM RAIL 1.0", "https://huggingface.co/spaces/bigscience/license", ("bigscience-bloom-rail-1.0", "bloom-rail", "bigscience-openrail-m")))126_add(_rail("BigCode-OpenRAIL-M", "BigCode Open RAIL-M", "https://www.bigcode-project.org/docs/pages/bigcode-openrail/", ("bigcode-openrail-m",)))127128# ---------------------------------------------------------------------------------------------- community / custom model licences (weights download, restrictions apply)129def _community(key: str, label: str, url: str, aliases: tuple[str, ...], *, commercial: bool | None = True, hosting: bool | None = True,130 derivatives: bool | None = True, aup: bool | None = True) -> LicenseInfo:131 return LicenseInfo(key=key, label=label, category="community", spdx=None, url=url, commercial_use=commercial, redistribution=True, derivatives=derivatives,132 hosting_restrictions=hosting, attribution=True, acceptable_use=aup, osi_approved=False, aliases=aliases)133134135_add(_community("Llama-2-Community", "Llama 2 Community License", "https://ai.meta.com/llama/license/", ("llama2", "llama-2", "llama 2 community license", "llama2 community license")))136_add(_community("Llama-3-Community", "Llama 3 Community License", "https://llama.meta.com/llama3/license/", ("llama3", "llama-3", "llama 3 community license", "meta llama 3 community license")))137_add(_community("Llama-3.1-Community", "Llama 3.1 Community License", "https://llama.meta.com/llama3_1/license/", ("llama3.1", "llama-3.1", "llama 3.1 community license")))138_add(_community("Llama-3.2-Community", "Llama 3.2 Community License", "https://www.llama.com/llama3_2/license/", ("llama3.2", "llama-3.2", "llama 3.2 community license")))139_add(_community("Llama-3.3-Community", "Llama 3.3 Community License", "https://www.llama.com/llama3_3/license/", ("llama3.3", "llama-3.3", "llama 3.3 community license")))140_add(_community("Llama-4-Community", "Llama 4 Community License", "https://www.llama.com/llama4/license/", ("llama4", "llama-4", "llama 4 community license")))141_add(_community("Gemma-Terms", "Gemma Terms of Use", "https://ai.google.dev/gemma/terms", ("gemma", "gemma terms of use", "gemma license", "gemma-terms")))142_add(_community("Mistral-Research", "Mistral AI Research License", "https://mistral.ai/licenses/MRL-0.1.md", ("mrl", "mistral research license", "mistral ai research license", "mrl-0.1"),143 commercial=False, hosting=True, aup=True))144_add(_community("Mistral-Non-Production", "Mistral AI Non-Production License", "https://mistral.ai/licenses/MNPL-0.1.md", ("mnpl", "mnpl-0.1", "mistral ai non-production license"),145 commercial=False, hosting=True, aup=True))146_add(_community("Qwen-Research", "Qwen Research License", "https://huggingface.co/Qwen/Qwen2.5-3B/blob/main/LICENSE", ("qwen research license", "qwen-research"), commercial=False))147_add(_community("Tongyi-Qianwen", "Tongyi Qianwen License", "https://github.com/QwenLM/Qwen/blob/main/Tongyi%20Qianwen%20LICENSE%20AGREEMENT", ("tongyi-qianwen", "tongyi qianwen license", "qianwen"),148 commercial=True, hosting=True))149_add(_community("DeepSeek-Model", "DeepSeek Model License", "https://github.com/deepseek-ai/DeepSeek-LLM/blob/main/LICENSE-MODEL", ("deepseek", "deepseek license", "deepseek model license"), hosting=False))150_add(_community("NVIDIA-Open-Model", "NVIDIA Open Model License", "https://www.nvidia.com/en-us/agreements/enterprise-software/nvidia-open-model-license/",151 ("nvidia open model license", "nvidia-open-model-license", "nvidia open model"), hosting=False))152_add(_community("NVIDIA-Community-Model", "NVIDIA Community Model License", "https://www.nvidia.com/en-us/agreements/enterprise-software/nvidia-community-models-license/",153 ("nvidia community model license", "nvidia-community-model-license"), hosting=None))154_add(_community("Apple-AMLR", "Apple Sample Code / ML Research License", "https://github.com/apple/ml-fastvlm/blob/main/LICENSE_MODEL", ("apple-amlr", "apple-ascl", "apple ml research license"),155 commercial=False, hosting=True, derivatives=True))156_add(_community("Cohere-CC-BY-NC", "Cohere Labs Acceptable Use (CC-BY-NC)", "https://cohere.com/c4ai-cc-by-nc-license", ("cohere", "c4ai", "cc-by-nc-4.0 + acceptable use"), commercial=False))157_add(_community("Stability-Community", "Stability AI Community License", "https://stability.ai/community-license-agreement", ("stabilityai-ai-community", "stability ai community license", "stabilityai-community"),158 commercial=True, hosting=True))159_add(_community("Stability-Non-Commercial-Research", "Stability AI Non-Commercial Research Community License", "https://stability.ai/license",160 ("stabilityai-nc-research-community", "stability ai non-commercial research community"), commercial=False))161_add(_community("Falcon-LLM", "Falcon LLM License (TII)", "https://falconllm.tii.ae/falcon-terms-and-conditions.html", ("falcon-llm-license", "tii falcon license", "falcon"), hosting=None))162_add(_community("Yi", "Yi Series Models Community License", "https://github.com/01-ai/Yi/blob/main/MODEL_LICENSE_AGREEMENT.txt", ("yi-license", "yi license", "yi"), commercial=True))163_add(_community("ChatGLM", "ChatGLM / GLM Model License", "https://github.com/THUDM/ChatGLM3/blob/main/MODEL_LICENSE", ("glm-4", "chatglm", "glm license", "zhipu"), commercial=True))164_add(_community("Phi", "Microsoft Phi (MIT with terms)", "https://huggingface.co/microsoft/phi-4/blob/main/LICENSE", ("phi",), commercial=True, hosting=False))165_add(_community("LFM-Open-1.0", "LFM Open License v1.0 (Liquid AI)", "https://www.liquid.ai/lfm-license", ("lfm1.0", "lfm-1.0", "lfm open license"), commercial=True, hosting=True))166_add(_community("Jamba-Open-Model", "Jamba Open Model License (AI21)", "https://www.ai21.com/jamba-open-model-license/", ("jamba open model license", "jamba"), commercial=True))167_add(_community("Kimi-Modified-MIT", "Kimi Modified MIT License (Moonshot)", "https://huggingface.co/moonshotai/Kimi-K2-Instruct/blob/main/LICENSE", ("kimi modified mit", "moonshot modified mit"),168 commercial=True, hosting=True, aup=False))169_add(_community("SEED-Model", "ByteDance Seed Model License", "https://github.com/ByteDance-Seed", ("seed license", "bytedance seed"), commercial=None))170_add(_community("Hunyuan-Community", "Tencent Hunyuan Community License", "https://github.com/Tencent/Tencent-Hunyuan-Large/blob/main/License.docx", ("tencent-hunyuan-community", "hunyuan", "tencent hunyuan community license"),171 commercial=True, hosting=True))172_add(_community("IBM-Granite", "IBM Granite (Apache-2.0 with usage terms)", "https://www.ibm.com/granite", ("granite",), commercial=True, hosting=False, aup=True))173_add(_community("Custom-Community", "Custom community licence (see source)", "", ("custom community", "community license", "other-community"), commercial=None, hosting=None, derivatives=None, aup=None))174175# ---------------------------------------------------------------------------------------------- research-only / non-commercial custom176_add(LicenseInfo(key="Research-Only", label="Research / non-commercial licence (custom)", category="research-only", spdx=None, commercial_use=False, redistribution=None,177 derivatives=None, hosting_restrictions=True, attribution=True, acceptable_use=True, aliases=("research", "research only", "research-only", "non-commercial", "noncommercial",178 "academic", "academic use only", "non commercial")))179_add(LicenseInfo(key="Meta-Research", label="Meta Research License", category="research-only", spdx=None, url="https://ai.meta.com/resources/models-and-libraries/",180 commercial_use=False, redistribution=False, derivatives=True, hosting_restrictions=True, attribution=True, acceptable_use=True,181 aliases=("meta research license", "fair noncommercial research license", "fair-noncommercial")))182183# ---------------------------------------------------------------------------------------------- proprietary184_add(LicenseInfo(key="Proprietary", label="Proprietary (API / terms of service)", category="proprietary", spdx=None, commercial_use=None, redistribution=False,185 derivatives=False, hosting_restrictions=True, attribution=None, acceptable_use=True, weights_downloadable=False,186 aliases=("proprietary", "closed", "closed source", "commercial", "terms of service", "tos", "api terms", "license: proprietary")))187_add(LicenseInfo(key="Other", label="Other (unclassified licence)", category="unknown", spdx=None, aliases=("other", "unknown", "custom", "see model card", "license: other")))188189190# ---------------------------------------------------------------------------------------------- normalisation191_ALIAS_INDEX: dict[str, str] = {}192for _info in LICENSES.values():193 _ALIAS_INDEX[_info.key.lower()] = _info.key194 if _info.spdx:195 _ALIAS_INDEX[_info.spdx.lower()] = _info.key196 for _a in _info.aliases:197 _ALIAS_INDEX[_a.lower()] = _info.key198199_STRIP = re.compile(r"\s+|[_]")200_PATTERNS: list[tuple[re.Pattern[str], str]] = [201 (re.compile(r"^apache[\s\-]*(license)?[\s\-,]*(version)?[\s\-]*2(\.0)?$", re.I), "Apache-2.0"),202 (re.compile(r"^llama[\s\-]*4", re.I), "Llama-4-Community"),203 (re.compile(r"^llama[\s\-]*3[.\-]3", re.I), "Llama-3.3-Community"),204 (re.compile(r"^llama[\s\-]*3[.\-]2", re.I), "Llama-3.2-Community"),205 (re.compile(r"^llama[\s\-]*3[.\-]1", re.I), "Llama-3.1-Community"),206 (re.compile(r"^(meta[\s\-]*)?llama[\s\-]*3", re.I), "Llama-3-Community"),207 (re.compile(r"^(meta[\s\-]*)?llama[\s\-]*2", re.I), "Llama-2-Community"),208 (re.compile(r"^gemma", re.I), "Gemma-Terms"),209 (re.compile(r"^cc[\s\-]*by[\s\-]*nc[\s\-]*sa", re.I), "CC-BY-NC-SA-4.0"),210 (re.compile(r"^cc[\s\-]*by[\s\-]*nc[\s\-]*nd", re.I), "CC-BY-NC-ND-4.0"),211 (re.compile(r"^cc[\s\-]*by[\s\-]*nc", re.I), "CC-BY-NC-4.0"),212 (re.compile(r"^cc[\s\-]*by[\s\-]*sa", re.I), "CC-BY-SA-4.0"),213 (re.compile(r"^cc[\s\-]*by[\s\-]*nd", re.I), "CC-BY-ND-4.0"),214 (re.compile(r"^cc[\s\-]*by", re.I), "CC-BY-4.0"),215 (re.compile(r"^cc0", re.I), "CC0-1.0"),216 (re.compile(r"^(creativeml[\s\-]*)?openrail\+\+", re.I), "OpenRAIL++-M"),217 (re.compile(r"^(creativeml[\s\-]*)?openrail", re.I), "OpenRAIL-M"),218 (re.compile(r"^bigscience", re.I), "BigScience-BLOOM-RAIL-1.0"),219 (re.compile(r"^bigcode", re.I), "BigCode-OpenRAIL-M"),220 (re.compile(r"^(gpl|gnu general public license)[\s\-]*v?3", re.I), "GPL-3.0"),221 (re.compile(r"^(gpl|gnu general public license)[\s\-]*v?2", re.I), "GPL-2.0"),222 (re.compile(r"^agpl", re.I), "AGPL-3.0"),223 (re.compile(r"^lgpl", re.I), "LGPL-3.0"),224 (re.compile(r"^bsd[\s\-]*3", re.I), "BSD-3-Clause"),225 (re.compile(r"^bsd[\s\-]*2", re.I), "BSD-2-Clause"),226 (re.compile(r"^mit\b", re.I), "MIT"),227 (re.compile(r"^mistral.*research", re.I), "Mistral-Research"),228 (re.compile(r"^mistral.*non[\s\-]*production", re.I), "Mistral-Non-Production"),229 (re.compile(r"^nvidia.*open.*model", re.I), "NVIDIA-Open-Model"),230 (re.compile(r"^nvidia.*community", re.I), "NVIDIA-Community-Model"),231 (re.compile(r"^deepseek", re.I), "DeepSeek-Model"),232 (re.compile(r"^qwen.*research", re.I), "Qwen-Research"),233 (re.compile(r"^tongyi", re.I), "Tongyi-Qianwen"),234 (re.compile(r"^stability.*(nc|non[\s\-]*commercial)", re.I), "Stability-Non-Commercial-Research"),235 (re.compile(r"^stability", re.I), "Stability-Community"),236 (re.compile(r"^apple", re.I), "Apple-AMLR"),237 (re.compile(r"^(tencent[\s\-]*)?hunyuan", re.I), "Hunyuan-Community"),238 (re.compile(r"^lfm", re.I), "LFM-Open-1.0"),239 (re.compile(r"^jamba", re.I), "Jamba-Open-Model"),240 (re.compile(r"^falcon", re.I), "Falcon-LLM"),241 (re.compile(r"^yi\b", re.I), "Yi"),242 (re.compile(r"(research|academic|non[\s\-]*commercial|noncommercial)", re.I), "Research-Only"),243 (re.compile(r"(proprietary|closed|terms of service)", re.I), "Proprietary"),244]245246247def normalize_license(raw: str | None) -> str | None:248 """Map an observed licence label to a canonical key, or `None` when it cannot be classified (keep the raw string separately)."""249 if raw is None:250 return None251 s = str(raw).strip()252 if not s:253 return None254 low = s.lower().strip().strip(".")255 low = re.sub(r"^license:\s*", "", low)256 if low in _ALIAS_INDEX:257 return _ALIAS_INDEX[low]258 compact = _STRIP.sub("-", low).replace("--", "-")259 if compact in _ALIAS_INDEX:260 return _ALIAS_INDEX[compact]261 for pattern, key in _PATTERNS:262 if pattern.search(low):263 return key264 return None265266267def license_info(key_or_raw: str | None) -> LicenseInfo | None:268 key = key_or_raw if key_or_raw in LICENSES else normalize_license(key_or_raw)269 return LICENSES.get(key) if key else None270271272def license_label(key_or_raw: str | None) -> str | None:273 info = license_info(key_or_raw)274 return info.label if info else (str(key_or_raw) if key_or_raw else None)275276277__all__ = ["CATEGORIES", "LICENSES", "LicenseInfo", "license_info", "license_label", "normalize_license"]278