docs for pattern_lens v0.3.0
View Source on GitHub

pattern_lens.indexes

writes indexes to the model directory for the frontend to use or for record keeping


  1"""writes indexes to the model directory for the frontend to use or for record keeping"""
  2
  3import importlib.metadata
  4import importlib.resources
  5import inspect
  6import itertools
  7import json
  8from collections.abc import Callable
  9from pathlib import Path
 10
 11import pattern_lens
 12from pattern_lens.attn_figure_funcs import (
 13	_FIGURE_NAMES_KEY,
 14	ATTENTION_MATRIX_FIGURE_FUNCS,
 15)
 16
 17
 18def generate_prompts_jsonl(model_dir: Path) -> None:
 19	"""creates a `prompts.jsonl` file with all the prompts in the model directory
 20
 21	looks in all directories in `{model_dir}/prompts` for a `prompt.json` file
 22	"""
 23	prompts: list[dict] = list()
 24	for prompt_dir in (model_dir / "prompts").iterdir():
 25		prompt_file: Path = prompt_dir / "prompt.json"
 26		if prompt_file.exists():
 27			with open(prompt_file, "r") as f:
 28				prompt_data: dict = json.load(f)
 29				prompts.append(prompt_data)
 30
 31	with open(model_dir / "prompts.jsonl", "w") as f:
 32		for prompt in prompts:
 33			f.write(json.dumps(prompt))
 34			f.write("\n")
 35
 36
 37def generate_models_jsonl(path: Path) -> None:
 38	"""creates a `models.jsonl` file with all the models"""
 39	models: list[dict] = list()
 40	for model_dir in (path).iterdir():
 41		model_cfg_path: Path = model_dir / "model_cfg.json"
 42		if model_cfg_path.exists():
 43			with open(model_cfg_path, "r") as f:
 44				model_cfg: dict = json.load(f)
 45				models.append(model_cfg)
 46
 47	with open(path / "models.jsonl", "w") as f:
 48		for model in models:
 49			f.write(json.dumps(model))
 50			f.write("\n")
 51
 52
 53def get_func_metadata(func: Callable) -> list[dict[str, str | None]]:
 54	"""get metadata for a function
 55
 56	# Parameters:
 57	- `func : Callable` which has a `_FIGURE_NAMES_KEY` (by default `_figure_names`) attribute
 58
 59	# Returns:
 60
 61	`list[dict[str, str | None]]`
 62	each dictionary is for a function, containing:
 63
 64	- `name : str` : the name of the figure
 65	- `func_name : str`
 66		the name of the function. if not a multi-figure function, this is identical to `name`
 67		if it is a multi-figure function, then `name` is `{func_name}.{figure_name}`
 68	- `doc : str` : the docstring of the function
 69	- `figure_save_fmt : str | None` : the format of the figure that the function saves, using the `figure_save_fmt` attribute of the function. `None` if the attribute does not exist
 70	- `source : str | None` : the source file of the function
 71	- `code : str | None` : the source code of the function, split by line. `None` if the source file cannot be read
 72
 73	"""
 74	source_file: str | None = inspect.getsourcefile(func)
 75	output: dict[str, str | None] = dict(
 76		func_name=func.__name__,
 77		doc=func.__doc__,
 78		figure_save_fmt=getattr(func, "figure_save_fmt", None),
 79		source=Path(source_file).as_posix() if source_file else None,
 80	)
 81
 82	try:
 83		output["code"] = inspect.getsource(func)
 84	except OSError:
 85		output["code"] = None
 86
 87	fig_names: list[str] | None = getattr(func, _FIGURE_NAMES_KEY, None)
 88	if fig_names:
 89		return [
 90			{
 91				"name": func_name,
 92				**output,
 93			}
 94			for func_name in fig_names
 95		]
 96	else:
 97		return [
 98			{
 99				"name": func.__name__,
100				**output,
101			},
102		]
103
104
105def generate_functions_jsonl(path: Path) -> None:
106	"unions all functions from `figures.jsonl` and `ATTENTION_MATRIX_FIGURE_FUNCS` into the file"
107	figures_file: Path = path / "figures.jsonl"
108	existing_figures: dict[str, dict] = dict()
109
110	if figures_file.exists():
111		with open(figures_file, "r") as f:
112			for line in f:
113				func_data: dict = json.loads(line)
114				existing_figures[func_data["name"]] = func_data
115
116	# Add any new functions from ALL_FUNCTIONS
117	new_functions_lst: list[dict] = list(
118		itertools.chain.from_iterable(
119			get_func_metadata(func) for func in ATTENTION_MATRIX_FIGURE_FUNCS
120		),
121	)
122	new_functions: dict[str, dict] = {func["name"]: func for func in new_functions_lst}
123
124	all_functions: list[dict] = list(
125		{
126			**existing_figures,
127			**new_functions,
128		}.values(),
129	)
130
131	with open(figures_file, "w") as f:
132		for func_meta in sorted(all_functions, key=lambda x: x["name"]):
133			json.dump(func_meta, f)
134			f.write("\n")
135
136
137def write_html_index(path: Path) -> None:
138	"""writes an index.html file to the path"""
139	html_index: str = (
140		importlib.resources.files(pattern_lens)
141		.joinpath("frontend/index.html")
142		.read_text(encoding="utf-8")
143	)
144	pattern_lens_version: str = importlib.metadata.version("pattern-lens")
145	html_index = html_index.replace("$$PATTERN_LENS_VERSION$$", pattern_lens_version)
146	with open(path / "index.html", "w", encoding="utf-8") as f:
147		f.write(html_index)

def generate_prompts_jsonl(model_dir: pathlib.Path) -> None:
19def generate_prompts_jsonl(model_dir: Path) -> None:
20	"""creates a `prompts.jsonl` file with all the prompts in the model directory
21
22	looks in all directories in `{model_dir}/prompts` for a `prompt.json` file
23	"""
24	prompts: list[dict] = list()
25	for prompt_dir in (model_dir / "prompts").iterdir():
26		prompt_file: Path = prompt_dir / "prompt.json"
27		if prompt_file.exists():
28			with open(prompt_file, "r") as f:
29				prompt_data: dict = json.load(f)
30				prompts.append(prompt_data)
31
32	with open(model_dir / "prompts.jsonl", "w") as f:
33		for prompt in prompts:
34			f.write(json.dumps(prompt))
35			f.write("\n")

creates a prompts.jsonl file with all the prompts in the model directory

looks in all directories in {model_dir}/prompts for a prompt.json file

def generate_models_jsonl(path: pathlib.Path) -> None:
38def generate_models_jsonl(path: Path) -> None:
39	"""creates a `models.jsonl` file with all the models"""
40	models: list[dict] = list()
41	for model_dir in (path).iterdir():
42		model_cfg_path: Path = model_dir / "model_cfg.json"
43		if model_cfg_path.exists():
44			with open(model_cfg_path, "r") as f:
45				model_cfg: dict = json.load(f)
46				models.append(model_cfg)
47
48	with open(path / "models.jsonl", "w") as f:
49		for model in models:
50			f.write(json.dumps(model))
51			f.write("\n")

creates a models.jsonl file with all the models

def get_func_metadata(func: Callable) -> list[dict[str, str | None]]:
 54def get_func_metadata(func: Callable) -> list[dict[str, str | None]]:
 55	"""get metadata for a function
 56
 57	# Parameters:
 58	- `func : Callable` which has a `_FIGURE_NAMES_KEY` (by default `_figure_names`) attribute
 59
 60	# Returns:
 61
 62	`list[dict[str, str | None]]`
 63	each dictionary is for a function, containing:
 64
 65	- `name : str` : the name of the figure
 66	- `func_name : str`
 67		the name of the function. if not a multi-figure function, this is identical to `name`
 68		if it is a multi-figure function, then `name` is `{func_name}.{figure_name}`
 69	- `doc : str` : the docstring of the function
 70	- `figure_save_fmt : str | None` : the format of the figure that the function saves, using the `figure_save_fmt` attribute of the function. `None` if the attribute does not exist
 71	- `source : str | None` : the source file of the function
 72	- `code : str | None` : the source code of the function, split by line. `None` if the source file cannot be read
 73
 74	"""
 75	source_file: str | None = inspect.getsourcefile(func)
 76	output: dict[str, str | None] = dict(
 77		func_name=func.__name__,
 78		doc=func.__doc__,
 79		figure_save_fmt=getattr(func, "figure_save_fmt", None),
 80		source=Path(source_file).as_posix() if source_file else None,
 81	)
 82
 83	try:
 84		output["code"] = inspect.getsource(func)
 85	except OSError:
 86		output["code"] = None
 87
 88	fig_names: list[str] | None = getattr(func, _FIGURE_NAMES_KEY, None)
 89	if fig_names:
 90		return [
 91			{
 92				"name": func_name,
 93				**output,
 94			}
 95			for func_name in fig_names
 96		]
 97	else:
 98		return [
 99			{
100				"name": func.__name__,
101				**output,
102			},
103		]

get metadata for a function

Parameters:

  • func : Callable which has a _FIGURE_NAMES_KEY (by default _figure_names) attribute

Returns:

list[dict[str, str | None]] each dictionary is for a function, containing:

  • name : str : the name of the figure
  • func_name : str the name of the function. if not a multi-figure function, this is identical to name if it is a multi-figure function, then name is {func_name}.{figure_name}
  • doc : str : the docstring of the function
  • figure_save_fmt : str | None : the format of the figure that the function saves, using the figure_save_fmt attribute of the function. None if the attribute does not exist
  • source : str | None : the source file of the function
  • code : str | None : the source code of the function, split by line. None if the source file cannot be read
def generate_functions_jsonl(path: pathlib.Path) -> None:
106def generate_functions_jsonl(path: Path) -> None:
107	"unions all functions from `figures.jsonl` and `ATTENTION_MATRIX_FIGURE_FUNCS` into the file"
108	figures_file: Path = path / "figures.jsonl"
109	existing_figures: dict[str, dict] = dict()
110
111	if figures_file.exists():
112		with open(figures_file, "r") as f:
113			for line in f:
114				func_data: dict = json.loads(line)
115				existing_figures[func_data["name"]] = func_data
116
117	# Add any new functions from ALL_FUNCTIONS
118	new_functions_lst: list[dict] = list(
119		itertools.chain.from_iterable(
120			get_func_metadata(func) for func in ATTENTION_MATRIX_FIGURE_FUNCS
121		),
122	)
123	new_functions: dict[str, dict] = {func["name"]: func for func in new_functions_lst}
124
125	all_functions: list[dict] = list(
126		{
127			**existing_figures,
128			**new_functions,
129		}.values(),
130	)
131
132	with open(figures_file, "w") as f:
133		for func_meta in sorted(all_functions, key=lambda x: x["name"]):
134			json.dump(func_meta, f)
135			f.write("\n")

unions all functions from figures.jsonl and ATTENTION_MATRIX_FIGURE_FUNCS into the file

def write_html_index(path: pathlib.Path) -> None:
138def write_html_index(path: Path) -> None:
139	"""writes an index.html file to the path"""
140	html_index: str = (
141		importlib.resources.files(pattern_lens)
142		.joinpath("frontend/index.html")
143		.read_text(encoding="utf-8")
144	)
145	pattern_lens_version: str = importlib.metadata.version("pattern-lens")
146	html_index = html_index.replace("$$PATTERN_LENS_VERSION$$", pattern_lens_version)
147	with open(path / "index.html", "w", encoding="utf-8") as f:
148		f.write(html_index)

writes an index.html file to the path