bioguider 0.2.19__py3-none-any.whl → 0.2.20__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of bioguider might be problematic. Click here for more details.

Files changed (35) hide show
  1. bioguider/agents/agent_utils.py +5 -3
  2. bioguider/agents/collection_execute_step.py +1 -1
  3. bioguider/agents/common_conversation.py +20 -2
  4. bioguider/agents/consistency_collection_execute_step.py +152 -0
  5. bioguider/agents/consistency_collection_observe_step.py +128 -0
  6. bioguider/agents/consistency_collection_plan_step.py +128 -0
  7. bioguider/agents/consistency_collection_task.py +109 -0
  8. bioguider/agents/consistency_collection_task_utils.py +137 -0
  9. bioguider/agents/evaluation_task.py +2 -2
  10. bioguider/agents/evaluation_userguide_prompts.py +162 -0
  11. bioguider/agents/evaluation_userguide_task.py +164 -0
  12. bioguider/agents/prompt_utils.py +11 -8
  13. bioguider/database/code_structure_db.py +489 -0
  14. bioguider/generation/__init__.py +39 -0
  15. bioguider/generation/change_planner.py +140 -0
  16. bioguider/generation/document_renderer.py +47 -0
  17. bioguider/generation/llm_cleaner.py +43 -0
  18. bioguider/generation/llm_content_generator.py +69 -0
  19. bioguider/generation/llm_injector.py +270 -0
  20. bioguider/generation/models.py +77 -0
  21. bioguider/generation/output_manager.py +54 -0
  22. bioguider/generation/repo_reader.py +37 -0
  23. bioguider/generation/report_loader.py +151 -0
  24. bioguider/generation/style_analyzer.py +36 -0
  25. bioguider/generation/suggestion_extractor.py +136 -0
  26. bioguider/generation/test_metrics.py +104 -0
  27. bioguider/managers/evaluation_manager.py +24 -0
  28. bioguider/managers/generation_manager.py +160 -0
  29. bioguider/managers/generation_test_manager.py +74 -0
  30. bioguider/utils/code_structure_builder.py +42 -0
  31. bioguider/utils/file_handler.py +65 -0
  32. {bioguider-0.2.19.dist-info → bioguider-0.2.20.dist-info}/METADATA +1 -1
  33. {bioguider-0.2.19.dist-info → bioguider-0.2.20.dist-info}/RECORD +35 -10
  34. {bioguider-0.2.19.dist-info → bioguider-0.2.20.dist-info}/LICENSE +0 -0
  35. {bioguider-0.2.19.dist-info → bioguider-0.2.20.dist-info}/WHEEL +0 -0
@@ -0,0 +1,74 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import json
5
+ from typing import Tuple
6
+
7
+ from bioguider.generation.llm_injector import LLMErrorInjector
8
+ from bioguider.generation.test_metrics import evaluate_fixes
9
+ from bioguider.managers.generation_manager import DocumentationGenerationManager
10
+ from bioguider.agents.agent_utils import read_file, write_file
11
+
12
+
13
+ class GenerationTestManager:
14
+ def __init__(self, llm, step_callback):
15
+ self.llm = llm
16
+ self.step_output = step_callback
17
+
18
+ def print_step(self, name: str, out: str | None = None):
19
+ if self.step_output:
20
+ self.step_output(step_name=name, step_output=out)
21
+
22
+ def run_quant_test(self, report_path: str, baseline_repo_path: str, tmp_repo_path: str) -> str:
23
+ self.print_step("QuantTest:LoadBaseline", baseline_repo_path)
24
+ baseline_readme_path = os.path.join(baseline_repo_path, "README.md")
25
+ baseline = read_file(baseline_readme_path) or ""
26
+
27
+ self.print_step("QuantTest:Inject")
28
+ injector = LLMErrorInjector(self.llm)
29
+ corrupted, inj_manifest = injector.inject(baseline, min_per_category=3)
30
+
31
+ # write corrupted into tmp repo path
32
+ os.makedirs(tmp_repo_path, exist_ok=True)
33
+ corrupted_readme_path = os.path.join(tmp_repo_path, "README.md")
34
+ write_file(corrupted_readme_path, corrupted)
35
+ inj_path = os.path.join(tmp_repo_path, "INJECTION_MANIFEST.json")
36
+ with open(inj_path, "w", encoding="utf-8") as fobj:
37
+ json.dump(inj_manifest, fobj, indent=2)
38
+
39
+ self.print_step("QuantTest:Generate")
40
+ gen = DocumentationGenerationManager(self.llm, self.step_output)
41
+ out_dir = gen.run(report_path=report_path, repo_path=tmp_repo_path)
42
+
43
+ # read revised
44
+ revised_readme_path = os.path.join(out_dir, "README.md")
45
+ revised = read_file(revised_readme_path) or ""
46
+
47
+ self.print_step("QuantTest:Evaluate")
48
+ results = evaluate_fixes(baseline, corrupted, revised, inj_manifest)
49
+ # write results
50
+ with open(os.path.join(out_dir, "GEN_TEST_RESULTS.json"), "w", encoding="utf-8") as fobj:
51
+ json.dump(results, fobj, indent=2)
52
+ # simple md report
53
+ lines = ["# Quantifiable Generation Test Report\n"]
54
+ lines.append("## Metrics by Category\n")
55
+ for cat, m in results["per_category"].items():
56
+ lines.append(f"- {cat}: {m}")
57
+ lines.append("\n## Notes\n")
58
+ lines.append("- Three versions saved in this directory: README.original.md, README.corrupted.md, README.md (fixed).")
59
+ with open(os.path.join(out_dir, "GEN_TEST_REPORT.md"), "w", encoding="utf-8") as fobj:
60
+ fobj.write("\n".join(lines))
61
+ # Save versioned files into output dir
62
+ write_file(os.path.join(out_dir, "README.original.md"), baseline)
63
+ write_file(os.path.join(out_dir, "README.corrupted.md"), corrupted)
64
+ # Copy injection manifest
65
+ try:
66
+ with open(inj_path, "r", encoding="utf-8") as fin:
67
+ with open(os.path.join(out_dir, "INJECTION_MANIFEST.json"), "w", encoding="utf-8") as fout:
68
+ fout.write(fin.read())
69
+ except Exception:
70
+ pass
71
+ self.print_step("QuantTest:Done", out_dir)
72
+ return out_dir
73
+
74
+
@@ -0,0 +1,42 @@
1
+ from pathlib import Path
2
+ import logging
3
+
4
+ from .gitignore_checker import GitignoreChecker
5
+ from .file_handler import FileHandler
6
+ from ..database.code_structure_db import CodeStructureDb
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+ class CodeStructureBuilder:
11
+ def __init__(
12
+ self,
13
+ repo_path: str,
14
+ gitignore_path: str,
15
+ code_structure_db: CodeStructureDb,
16
+ ):
17
+ self.repo_path = repo_path
18
+ self.gitignore_checker = GitignoreChecker(repo_path, gitignore_path)
19
+ self.file_handler = FileHandler(repo_path)
20
+ self.code_structure_db = code_structure_db
21
+
22
+ def build_code_structure(self):
23
+ files = self.gitignore_checker.check_files_and_folders()
24
+ for file in files:
25
+ if not file.endswith(".py"):
26
+ continue
27
+ logger.info(f"Building code structure for {file}")
28
+ file_handler = FileHandler(Path(self.repo_path) / file)
29
+ functions_and_classes = file_handler.get_functions_and_classes()
30
+ # fixme: currently, we don't extract reference graph for each function or class
31
+ for function_or_class in functions_and_classes:
32
+ self.code_structure_db.insert_code_structure(
33
+ function_or_class[0], # name
34
+ file,
35
+ function_or_class[2], # start line number
36
+ function_or_class[3], # end line number
37
+ function_or_class[1], # parent name
38
+ function_or_class[4], # doc string
39
+ function_or_class[5], # params
40
+ )
41
+
42
+
@@ -0,0 +1,65 @@
1
+ import ast
2
+ import os
3
+
4
+ class FileHandler:
5
+ def __init__(self, file_path: str):
6
+ self.file_path = file_path
7
+
8
+ def get_functions_and_classes(self) -> list[str]:
9
+ """
10
+ Get the functions and classes in a given file.
11
+ Returns a list of tuples, each containing:
12
+ 1. the function or class name,
13
+ 2. parent name,
14
+ 3. start line number,
15
+ 4. end line number,
16
+ 5. doc string,
17
+ 6. params.
18
+ """
19
+ with open(self.file_path, 'r') as f:
20
+ tree = ast.parse(f.read())
21
+ functions_and_classes = []
22
+ for node in tree.body:
23
+ if isinstance(node, ast.FunctionDef) or isinstance(node, ast.ClassDef):
24
+ start_lineno = node.lineno
25
+ end_lineno = self.get_end_lineno(node)
26
+ doc_string = ast.get_docstring(node)
27
+ params = (
28
+ [arg.arg for arg in node.args.args] if "args" in dir(node) else []
29
+ )
30
+ parent = None
31
+ functions_and_classes.append((node.name, parent, start_lineno, end_lineno, doc_string, params))
32
+ for child in node.body:
33
+ if isinstance(child, ast.FunctionDef):
34
+ start_lineno = child.lineno
35
+ end_lineno = self.get_end_lineno(child)
36
+ doc_string = ast.get_docstring(child)
37
+ params = (
38
+ [arg.arg for arg in child.args.args] if "args" in dir(child) else []
39
+ )
40
+ parent = node.name
41
+ functions_and_classes.append((child.name, parent, start_lineno, end_lineno, doc_string, params))
42
+ return functions_and_classes
43
+
44
+ def get_imports(self) -> list[str]:
45
+ pass
46
+
47
+ def get_end_lineno(self, node):
48
+ """
49
+ Get the end line number of a given node.
50
+
51
+ Args:
52
+ node: The node for which to find the end line number.
53
+
54
+ Returns:
55
+ int: The end line number of the node. Returns -1 if the node does not have a line number.
56
+ """
57
+ if not hasattr(node, "lineno"):
58
+ return -1 # 返回-1表示此节点没有行号
59
+
60
+ end_lineno = node.lineno
61
+ for child in ast.iter_child_nodes(node):
62
+ child_end = getattr(child, "end_lineno", None) or self.get_end_lineno(child)
63
+ if child_end > -1: # 只更新当子节点有有效行号时
64
+ end_lineno = max(end_lineno, child_end)
65
+ return end_lineno
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: bioguider
3
- Version: 0.2.19
3
+ Version: 0.2.20
4
4
  Summary: An AI-Powered package to help biomedical developers to generate clear documentation
5
5
  License: MIT
6
6
  Author: Cankun Wang
@@ -2,16 +2,21 @@ bioguider/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  bioguider/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  bioguider/agents/agent_task.py,sha256=TL0Zx8zOmiAVslmNbfMPQ38qTQ73QospY6Dwrwf8POg,2890
4
4
  bioguider/agents/agent_tools.py,sha256=r21wHV6a-Ic2T0dk4YzA-_d7PodHPM3GzRxJqv-llSw,7286
5
- bioguider/agents/agent_utils.py,sha256=Om1xwAmRdHFC4jkbtaBM3p309z5KFjMX1a6BFVPXX68,14449
6
- bioguider/agents/collection_execute_step.py,sha256=Ev4BLjjmBdsc52M1zrq7QK8g7fsffDkSxu-jN2rvedw,5614
5
+ bioguider/agents/agent_utils.py,sha256=SoYFc5oZGY2QqTDHR1DCgBPiwQpigUOANHmlUCUPzu4,14683
6
+ bioguider/agents/collection_execute_step.py,sha256=jE_oSQZI5WDaz0bJjUWoAfqWfVbGUqN--cvITSWCGiI,5614
7
7
  bioguider/agents/collection_observe_step.py,sha256=n863HrbVANQVeltffjS2zXv-AfVErC8ZEMfb_78hafk,5140
8
8
  bioguider/agents/collection_plan_step.py,sha256=Nn0f8AOkEDCDtnhaqE7yCQoi7PVpsHmiUcsIqC0T0dQ,5956
9
9
  bioguider/agents/collection_task.py,sha256=MjpTYiQQYUpmQf2UOn-dOCZU3kxypc4uOnzd15wb1Ow,7882
10
10
  bioguider/agents/collection_task_utils.py,sha256=_e2EebYhl-UYjZ0rHNf2-p32YlstBSffv32suiuT9LI,5386
11
11
  bioguider/agents/common_agent.py,sha256=TpfxbYskwuwWrjs1g9RaG7sdA5rOLdiVac7If7uK2sg,4558
12
12
  bioguider/agents/common_agent_2step.py,sha256=rGiDzUkmmUIFnmJJxzXK5M5BfIyINHXLZ0pmPRUVqQg,7911
13
- bioguider/agents/common_conversation.py,sha256=VrnQoPXXK3xeFjeP4-HH-yD9qmw-o9v93LFtNbYey6E,1655
13
+ bioguider/agents/common_conversation.py,sha256=_9l6SunRmOZ_3R4Q8CTO9oE_qmP7aYYKFX1EiFBIrm8,2589
14
14
  bioguider/agents/common_step.py,sha256=GdOCbmj1pwh4etg-futVFYVDQuoUG89DnIrw-B6QbzM,2594
15
+ bioguider/agents/consistency_collection_execute_step.py,sha256=SBZjdaIc4AX6ljedd8TsJC-1GoYeI16jaqIcfDnTezs,4938
16
+ bioguider/agents/consistency_collection_observe_step.py,sha256=XghjlSMBpq1Va68jRP8_-ZG0O7UlZy1Qhwai9c0LNoo,5029
17
+ bioguider/agents/consistency_collection_plan_step.py,sha256=NUl0Nl39O5EFibJQQB1oMIVY_Tikh75YNVbyt7ryw6s,5389
18
+ bioguider/agents/consistency_collection_task.py,sha256=WP3GL4iPJ38b5F1zZMHmJALx0pRDcF-9JAmz3OHqi6o,5261
19
+ bioguider/agents/consistency_collection_task_utils.py,sha256=BnpBXmpxmmr8NRaBw5sACipP0mMtj1Qpe2AvcMlX_cg,6143
15
20
  bioguider/agents/dockergeneration_execute_step.py,sha256=F92jDlkc6KjAvTkX7q1FsCYP8J15SCaNgmwh3YPqfDo,6500
16
21
  bioguider/agents/dockergeneration_observe_step.py,sha256=Bo5Td0fzMYLbLki0FvwamzqRFOy4eu3AvIUa8oFApE4,6131
17
22
  bioguider/agents/dockergeneration_plan_step.py,sha256=SB8tQM9PkIKsD2o1DFD7bedcxz6r6hSy8n_EVK60Fz0,7235
@@ -20,32 +25,52 @@ bioguider/agents/dockergeneration_task_utils.py,sha256=v7emqrJlVW-A5ZdLmPSdiaMSK
20
25
  bioguider/agents/evaluation_installation_task.py,sha256=0RNH5NV7YKwn_we_d3IjnFf_ee9IPCEQ_olebq2y8Ng,12130
21
26
  bioguider/agents/evaluation_readme_task.py,sha256=pi3oAGJgZhJgJG1xLgiobrk3Uy2a_JIarD5QSPBkmHA,30647
22
27
  bioguider/agents/evaluation_submission_requirements_task.py,sha256=J_6C-M2AfYue2C-gWBHl7KqGrTBuFBn9zmMV5vSRk-U,7834
23
- bioguider/agents/evaluation_task.py,sha256=4UrcUCy8UIVLd1NpBpqGgmudqeSK3wWI3Jm8LEYySbY,12661
28
+ bioguider/agents/evaluation_task.py,sha256=c3kvc3xgzGbT0C2KpkE-zHBvaxx9zKdmpLzeKHddrds,12690
29
+ bioguider/agents/evaluation_userguide_prompts.py,sha256=eyJUx5nUr8v9k0B5GpKDaX2dBxSLVZGA0fwOWS4Uiow,7154
30
+ bioguider/agents/evaluation_userguide_task.py,sha256=AJ7y5WSMs4EqXpQzyAu_5NPmWK0jl3AeHhRXxdZgpz0,8266
24
31
  bioguider/agents/identification_execute_step.py,sha256=w3IjL8f2WiHCyiLjVSoySnIAXpi1-hK1DLKCnXbAN2Y,5587
25
32
  bioguider/agents/identification_observe_step.py,sha256=Me5mhEM4e7FGnVFcluNtqfhIxzng6guGIu39xi1TrS8,4341
26
33
  bioguider/agents/identification_plan_step.py,sha256=owsTK1NZIuiZL7QPVknJyp9TBRK-mhnuf2RwK4YzaxU,5442
27
34
  bioguider/agents/identification_task.py,sha256=bTbovxxQVpO1TcdcQAxDxwPISuAcXndO7zsvHpJSb64,10147
28
35
  bioguider/agents/identification_task_utils.py,sha256=Lf0Rj0L0KSiyJmPAgeSz0vLUFQr6TSFuzgufimEN4H0,630
29
36
  bioguider/agents/peo_common_step.py,sha256=iw2c1h7X11WJzSE2tSRg0UAoXH0QOlQDxW9CCzSVMOY,2677
30
- bioguider/agents/prompt_utils.py,sha256=EuR7NkB7PcCgNroeX91fHUSK2X6mLS6vK7RnzyQHAHI,17593
37
+ bioguider/agents/prompt_utils.py,sha256=kTeK0LOsxpEIpQ5PMXY0DOHXJ5Z6ryu0UuJIO4ga9Rg,17743
31
38
  bioguider/agents/python_ast_repl_tool.py,sha256=o7-4P1h8jS8ikhGSA4CI_OWQ2a0Eg5tEdmuAp_qrO-0,2519
32
39
  bioguider/agents/rag_collection_task.py,sha256=r_jPAMjQcC7dIydKxX77UuMqjJ3MiVKswNZ-yNw7yx8,5199
33
40
  bioguider/conversation.py,sha256=DIvk_d7pz_guuORByK1eaaF09FAK-8shcNTrbSUHz9Y,1779
41
+ bioguider/database/code_structure_db.py,sha256=drYkoQa7mDexCpulG3885Gwcnu92lnHNRlWT8byjF-A,16630
34
42
  bioguider/database/summarized_file_db.py,sha256=gGubM5vH3SN_1vouKO0LemvE_EfyjinAScRhlvxJsi0,4654
35
- bioguider/managers/evaluation_manager.py,sha256=O8mxrAGllDIkcQVsrRrqxH0eyJHwtoSauWrPe_F7qqU,4778
43
+ bioguider/generation/__init__.py,sha256=esV02QgCsY67-HBwSHDbA5AcbKzNRIT3wDwwh6N4OFM,945
44
+ bioguider/generation/change_planner.py,sha256=1u_1tcVwggVw6QebXvPJVULYnRAIkKMteFxbnf42aAw,6964
45
+ bioguider/generation/document_renderer.py,sha256=67-XGFGNe8WgHJpqkHLMecgk2OeV8a5cJRAeDTLsXG4,1806
46
+ bioguider/generation/llm_cleaner.py,sha256=aMxc3j6IH_9mCfBjxY1bn0bAUtUkUoHjumobzGkN0h8,1422
47
+ bioguider/generation/llm_content_generator.py,sha256=45z_SWaoL0Z4hBFhYJHT-_L7mFwaLgvGocQiXIBmCpw,3332
48
+ bioguider/generation/llm_injector.py,sha256=Q6F9IshTlZ7KUiRvOl1gT4RKQn-AtD1QiN7aK0gba4A,13083
49
+ bioguider/generation/models.py,sha256=FEfXvszF2sGOYa98Jn4VDp6TyktJL4cD6LQFhx9rmsk,2328
50
+ bioguider/generation/output_manager.py,sha256=V0eXYG9iaWxUjU44eLLX5mQcfjOz5tAKa_X0rkTc5Aw,1935
51
+ bioguider/generation/repo_reader.py,sha256=ivTURU61fR8er4ev7gSpOxER3FJv2d9GAx_X5JoVTvQ,1177
52
+ bioguider/generation/report_loader.py,sha256=KtJ6JHGPDL-PQoucU8hkVzMSz-B0bHbF2WShjuz2fY8,5102
53
+ bioguider/generation/style_analyzer.py,sha256=Vn9FAK1qJBNLolLC1tz362k4UBaPl107BlvkQc8pV2I,983
54
+ bioguider/generation/suggestion_extractor.py,sha256=tfkyWtdbAo-maLCF_wqwBXyh93yjulvDY17FuvTnTjk,7611
55
+ bioguider/generation/test_metrics.py,sha256=fG6H1jVikHEx1YvN5Ds4QbVinudJ5OEYkzrV760oLLQ,3766
56
+ bioguider/managers/evaluation_manager.py,sha256=obsesQdEgxBzTd1Re00kanH1d5_4_vxzXI_ndICgedg,5834
57
+ bioguider/managers/generation_manager.py,sha256=EbAJSvUz-SIriVlozuJ6wa5_1aIbbFfpgg3c9Vcz34g,7615
58
+ bioguider/managers/generation_test_manager.py,sha256=0ty8IibdfN90Oj6M6lkYbxASnQxHYb9I3w9eG7hvEsQ,3270
36
59
  bioguider/rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
60
  bioguider/rag/config.py,sha256=5g4IqTzgyfZfax9Af9CTkXShgItPOt4_9TEMSekCPik,4602
38
61
  bioguider/rag/data_pipeline.py,sha256=bkJ2IUCgPx_OL2uZtPd6cIBor2VFZEIfGd5kVlmiPjw,27292
39
62
  bioguider/rag/embedder.py,sha256=jofR8hOj3Aj2IyBQ9y6FeAc84tgq5agbIfCGyFxYpJ8,650
40
63
  bioguider/rag/rag.py,sha256=JFPwrJlKDSyd3U3Gce_NSxI5343eNUbqPG9Fs5Pfoq0,4696
41
64
  bioguider/settings.py,sha256=BD_iz9aYarxmWUl0XaKl4-D4oTXMhFzljsXLNn2phis,3143
65
+ bioguider/utils/code_structure_builder.py,sha256=TBrsmlUPEwqpi5bSVLrOEwFK1dQ49goYJ1EGYmRrtZ8,1607
42
66
  bioguider/utils/constants.py,sha256=Yzo9oFG4P4C83vKl22RsWkIDa4dcitvcCIceusNPIRQ,8928
43
67
  bioguider/utils/default.gitignore,sha256=XjPdyO2KV8z8iyuqluaNR_70tBQftMpyKL8HboVNyeI,1605
68
+ bioguider/utils/file_handler.py,sha256=xTrJBQ7VY5baIJPpX7YJP0oniPO3y9ltzayqUOQXJ5g,2644
44
69
  bioguider/utils/file_utils.py,sha256=9VfAHsz1UkFPtzAmvWZvPl1TMaKIYNjNlLgsfB8tNjg,3683
45
70
  bioguider/utils/gitignore_checker.py,sha256=pOYUwsS9D5014LxcZb0cj3s2CAYaD2uF_pYJpaNKcho,6532
46
71
  bioguider/utils/pyphen_utils.py,sha256=cdZc3qphkvMDeL5NiZ8Xou13M_uVNP7ifJ-FwxO-0BE,2680
47
72
  bioguider/utils/utils.py,sha256=aWtgdvB04gEiJTfQNK4aQPO1mxv2zRZTbDaGUBy9DFc,2275
48
- bioguider-0.2.19.dist-info/LICENSE,sha256=qzkvZcKwwA5DuSuhXMOm2LcO6BdEr4V7jwFZVL2-jL4,1065
49
- bioguider-0.2.19.dist-info/METADATA,sha256=YvAwNzOyncowyrbKcoKBSEeIVLPk8UiRK-Y4vihrUUY,1868
50
- bioguider-0.2.19.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
51
- bioguider-0.2.19.dist-info/RECORD,,
73
+ bioguider-0.2.20.dist-info/LICENSE,sha256=qzkvZcKwwA5DuSuhXMOm2LcO6BdEr4V7jwFZVL2-jL4,1065
74
+ bioguider-0.2.20.dist-info/METADATA,sha256=jAGUMMHuLYW5_lyvc0tYcvKGYlB9YUG1hqT3Kjaqii0,1868
75
+ bioguider-0.2.20.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
76
+ bioguider-0.2.20.dist-info/RECORD,,