Coverage for src/fjc_biographies/__main__.py: 100%
28 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-22 22:47 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-22 22:47 +0000
1"""Command line interface for downloading and exporting the FJC's biographies.
3Examples:
4 python -m fjc_biographies
5 fjc-biographies --update
6 fjc-biographies --rulebook my_careers.csv
7 fjc-biographies --jcs --martin-quinn
8 fjc-biographies --martin-quinn ~/Downloads/justices.csv
9 fjc-biographies --download-only --data-folder ~/data/fjc
11"""
13from __future__ import annotations
15import argparse
16import logging
17import time
18from collections.abc import Sequence
20from . import downloader
21from . import main as biographies
23logger = logging.getLogger(__name__)
26def main(arguments: Sequence[str] | None = None) -> None:
27 """Downloads and exports the FJC's files as the command line arguments say.
29 Args:
30 arguments: the command line arguments. Defaults to None, in which case
31 the arguments passed to the program are used.
33 """
34 parsed = _get_parser().parse_args(arguments)
35 logging.basicConfig(level = logging.INFO, format = '%(message)s')
36 started = time.time()
37 if parsed.download_only:
38 files = downloader.download(
39 folder = parsed.data_folder, overwrite = parsed.update)
40 logger.info(
41 'Downloaded %s files in %.0fs.', len(files), time.time() - started)
42 return
43 files = biographies.run(
44 parsed.data_folder, update = parsed.update, rulebook = parsed.rulebook,
45 jcs = parsed.jcs, martin_quinn = parsed.martin_quinn,
46 scores_folder = parsed.scores_folder)
47 logger.info(
48 'Exported %s tables to %s in %.0fs.',
49 len(files), next(iter(files.values())).parent, time.time() - started)
52def _get_parser() -> argparse.ArgumentParser:
53 """Returns the parser for the command line arguments.
55 Returns:
56 The command line parser.
58 """
59 parser = argparse.ArgumentParser(
60 prog = 'fjc-biographies',
61 description = (
62 "Download the FJC's Biographical Directory of Article III Federal "
63 'Judges and export tidy CSV files and a roster of judges, by '
64 'appointment and by judge.'))
65 parser.add_argument(
66 '--data-folder',
67 default = None,
68 help = (
69 'the folder for the downloaded and exported files (default: '
70 f'{downloader.data_folder()})'))
71 parser.add_argument(
72 '--update',
73 action = 'store_true',
74 help = (
75 'download the files again even if they were downloaded before, '
76 'to get the judges and corrections the FJC has added since'))
77 parser.add_argument(
78 '--rulebook',
79 default = 'judges',
80 help = (
81 "a CSV file of rules that make the roster's fields from judges' "
82 'careers, or the name of a built-in rulebook (default: '
83 '%(default)s)'))
84 parser.add_argument(
85 '--jcs',
86 action = 'store_true',
87 help = (
88 "add each appointment's Judicial Common Space score, computed by "
89 'the judicial-common-space package'))
90 parser.add_argument(
91 '--martin-quinn',
92 nargs = '?',
93 const = True,
94 default = False,
95 metavar = 'PATH',
96 help = (
97 "add the justices' Martin-Quinn scores and export their scores in "
98 'each term, downloading them, or from PATH (a "justices.csv" saved '
99 'from https://mqscores.wustl.edu/measures.php)'))
100 parser.add_argument(
101 '--scores-folder',
102 default = None,
103 help = (
104 'the folder for the files that the scores come from (default: '
105 "the judicial-common-space package's data folder)"))
106 parser.add_argument(
107 '--download-only',
108 action = 'store_true',
109 help = 'download the files without exporting them')
110 return parser
113if __name__ == '__main__':
114 main()