baseballcommand 0.1.0__tar.gz

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 baseballcommand might be problematic. Click here for more details.

Files changed (42) hide show
  1. baseballcommand-0.1.0/.github/workflows/python-publish.yml +70 -0
  2. baseballcommand-0.1.0/.gitignore +12 -0
  3. baseballcommand-0.1.0/CHANGELOG.md +52 -0
  4. baseballcommand-0.1.0/CONTRIBUTING.md +160 -0
  5. baseballcommand-0.1.0/LICENSE +21 -0
  6. baseballcommand-0.1.0/PKG-INFO +359 -0
  7. baseballcommand-0.1.0/README.md +310 -0
  8. baseballcommand-0.1.0/docs/commands.md +450 -0
  9. baseballcommand-0.1.0/docs/data-source.md +132 -0
  10. baseballcommand-0.1.0/docs/stats-glossary.md +108 -0
  11. baseballcommand-0.1.0/pyproject.toml +55 -0
  12. baseballcommand-0.1.0/src/baseballcommand/__init__.py +8 -0
  13. baseballcommand-0.1.0/src/baseballcommand/__main__.py +8 -0
  14. baseballcommand-0.1.0/src/baseballcommand/api.py +395 -0
  15. baseballcommand-0.1.0/src/baseballcommand/cache.py +115 -0
  16. baseballcommand-0.1.0/src/baseballcommand/cli.py +121 -0
  17. baseballcommand-0.1.0/src/baseballcommand/commands/__init__.py +38 -0
  18. baseballcommand-0.1.0/src/baseballcommand/commands/cache.py +65 -0
  19. baseballcommand-0.1.0/src/baseballcommand/commands/compare.py +149 -0
  20. baseballcommand-0.1.0/src/baseballcommand/commands/glossary.py +48 -0
  21. baseballcommand-0.1.0/src/baseballcommand/commands/leaders.py +222 -0
  22. baseballcommand-0.1.0/src/baseballcommand/commands/player.py +209 -0
  23. baseballcommand-0.1.0/src/baseballcommand/commands/roster.py +225 -0
  24. baseballcommand-0.1.0/src/baseballcommand/commands/scores.py +214 -0
  25. baseballcommand-0.1.0/src/baseballcommand/commands/standings.py +193 -0
  26. baseballcommand-0.1.0/src/baseballcommand/commands/team.py +165 -0
  27. baseballcommand-0.1.0/src/baseballcommand/commands/teams.py +83 -0
  28. baseballcommand-0.1.0/src/baseballcommand/dates.py +96 -0
  29. baseballcommand-0.1.0/src/baseballcommand/errors.py +39 -0
  30. baseballcommand-0.1.0/src/baseballcommand/lookup.py +207 -0
  31. baseballcommand-0.1.0/src/baseballcommand/output.py +193 -0
  32. baseballcommand-0.1.0/src/baseballcommand/stats.py +171 -0
  33. baseballcommand-0.1.0/tests/__init__.py +0 -0
  34. baseballcommand-0.1.0/tests/conftest.py +201 -0
  35. baseballcommand-0.1.0/tests/test_api.py +152 -0
  36. baseballcommand-0.1.0/tests/test_cache.py +61 -0
  37. baseballcommand-0.1.0/tests/test_cli.py +368 -0
  38. baseballcommand-0.1.0/tests/test_dates.py +58 -0
  39. baseballcommand-0.1.0/tests/test_lookup.py +97 -0
  40. baseballcommand-0.1.0/tests/test_output.py +66 -0
  41. baseballcommand-0.1.0/tests/test_roster.py +204 -0
  42. baseballcommand-0.1.0/tests/test_stats.py +49 -0
@@ -0,0 +1,70 @@
1
+ # This workflow will upload a Python Package to PyPI when a release is created
2
+ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
3
+
4
+ # This workflow uses actions that are not certified by GitHub.
5
+ # They are provided by a third-party and are governed by
6
+ # separate terms of service, privacy policy, and support
7
+ # documentation.
8
+
9
+ name: Upload Python Package
10
+
11
+ on:
12
+ release:
13
+ types: [published]
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ release-build:
20
+ runs-on: ubuntu-latest
21
+
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+
25
+ - uses: actions/setup-python@v5
26
+ with:
27
+ python-version: "3.x"
28
+
29
+ - name: Build release distributions
30
+ run: |
31
+ # NOTE: put your own distribution build steps here.
32
+ python -m pip install build
33
+ python -m build
34
+
35
+ - name: Upload distributions
36
+ uses: actions/upload-artifact@v4
37
+ with:
38
+ name: release-dists
39
+ path: dist/
40
+
41
+ pypi-publish:
42
+ runs-on: ubuntu-latest
43
+ needs:
44
+ - release-build
45
+ permissions:
46
+ # IMPORTANT: this permission is mandatory for trusted publishing
47
+ id-token: write
48
+
49
+ # Dedicated environments with protections for publishing are strongly recommended.
50
+ # For more information, see: https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#deployment-protection-rules
51
+ environment:
52
+ name: pypi
53
+ # OPTIONAL: uncomment and update to include your PyPI project URL in the deployment status:
54
+ # url: https://pypi.org/p/YOURPROJECT
55
+ #
56
+ # ALTERNATIVE: if your GitHub Release name is the PyPI project version string
57
+ # ALTERNATIVE: exactly, uncomment the following line instead:
58
+ # url: https://pypi.org/project/YOURPROJECT/${{ github.event.release.name }}
59
+
60
+ steps:
61
+ - name: Retrieve release distributions
62
+ uses: actions/download-artifact@v4
63
+ with:
64
+ name: release-dists
65
+ path: dist/
66
+
67
+ - name: Publish release distributions to PyPI
68
+ uses: pypa/gh-action-pypi-publish@release/v1
69
+ with:
70
+ packages-dir: dist/
@@ -0,0 +1,12 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ build/
5
+ dist/
6
+ .venv/
7
+ venv/
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .coverage
11
+ htmlcov/
12
+ .DS_Store
@@ -0,0 +1,52 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
5
+ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.0] — 2026-08-14
10
+
11
+ First release.
12
+
13
+ ### Added
14
+
15
+ - `base scores` — scores and status for a day's games, with `--linescore` for
16
+ inning-by-inning detail, `--team` to filter, and flexible date input
17
+ (`yesterday`, `8/14`, `-3`).
18
+ - `base player` — biographical record plus season, career, or year-by-year stat
19
+ lines. The stat group follows the player's position; two-way players get both
20
+ hitting and pitching. Supports `--postseason` and `--full`.
21
+ - `base team` — a club's record, division standing, and season stat totals.
22
+ - `base standings` — division and wild card standings with L10, streak, and run
23
+ differential.
24
+ - `base leaders` — league leaderboards for any category, with shorthand (`hr`,
25
+ `era`, `whip`) and `--list` to enumerate all categories.
26
+ - `base roster` — a club's roster, with `--stats` to include every player's
27
+ season line in a single request, and `--sort` by any column.
28
+ - `base compare` — two or more players side by side, with the better figure in
29
+ each row highlighted.
30
+ - `base teams` — every club with its abbreviation and id.
31
+ - `base glossary` — what the column headings mean.
32
+ - `base cache` — inspect or clear the on-disk response cache.
33
+ - `--json` on every command, emitting a flat, stable shape rather than the raw
34
+ API envelope.
35
+ - Forgiving lookups: teams by abbreviation, city, nickname, or id; players by
36
+ any part of a name or MLBAM id, including retired players. Genuine ambiguity
37
+ is reported with candidates instead of guessed at.
38
+ - On-disk response cache with lifetimes matched to how fast each kind of data
39
+ changes.
40
+ - Actionable guidance when TLS verification fails, which is the common failure
41
+ on macOS python.org installs. `certifi` is used automatically when present but
42
+ is never required.
43
+
44
+ ### Notes
45
+
46
+ - Zero runtime dependencies; standard library only.
47
+ - Requires Python 3.9 or newer.
48
+ - Data comes from the free public MLB Stats API. See
49
+ [docs/data-source.md](docs/data-source.md) for terms of use.
50
+
51
+ [Unreleased]: https://github.com/opowell28/BaseballCommand/compare/v0.1.0...HEAD
52
+ [0.1.0]: https://github.com/opowell28/BaseballCommand/releases/tag/v0.1.0
@@ -0,0 +1,160 @@
1
+ # Contributing
2
+
3
+ Thanks for taking a look. Bug reports, ideas, and pull requests are all welcome.
4
+
5
+ ## Getting set up
6
+
7
+ ```bash
8
+ git clone https://github.com/opowell28/BaseballCommand.git
9
+ cd BaseballCommand
10
+ python -m venv .venv && source .venv/bin/activate
11
+ pip install -e ".[dev]"
12
+ ```
13
+
14
+ Then:
15
+
16
+ ```bash
17
+ pytest # the full suite — offline, under a second
18
+ ruff check . # lint
19
+ ruff check . --fix
20
+ ```
21
+
22
+ ## How the code is laid out
23
+
24
+ ```
25
+ src/baseballcommand/
26
+ ├── cli.py argparse setup, global flags, dispatch, error handling
27
+ ├── api.py the only module that touches the network
28
+ ├── cache.py on-disk TTL cache for API responses
29
+ ├── lookup.py "nyy" -> team 147, "judge" -> player 592450
30
+ ├── stats.py which stats to show, in what order, under what heading
31
+ ├── dates.py date parsing and local-time formatting
32
+ ├── output.py tables, color, layout
33
+ ├── errors.py the exception types the CLI catches
34
+ └── commands/ one module per subcommand
35
+ ```
36
+
37
+ Two rules keep this from tangling:
38
+
39
+ 1. **Only `api.py` makes requests.** Commands receive a client and call its
40
+ methods. Caching, retries, and error translation live in one place.
41
+ 2. **Only `output.py` formats.** Commands assemble rows and hand them over.
42
+ That is what makes `--no-color` and column alignment work everywhere at once.
43
+
44
+ ## Adding a command
45
+
46
+ Write a module in `commands/` with two functions:
47
+
48
+ ```python
49
+ """``base thing`` — one line on what it does."""
50
+
51
+ from __future__ import annotations
52
+
53
+ from .. import output
54
+
55
+
56
+ def register(subparsers) -> None:
57
+ parser = subparsers.add_parser(
58
+ "thing",
59
+ help="short text for `base --help`",
60
+ description="longer text for `base thing -h`",
61
+ )
62
+ parser.add_argument("name", help="what this is")
63
+ parser.set_defaults(func=run)
64
+
65
+
66
+ def run(args, ctx) -> int:
67
+ data = ctx.client.get("some/endpoint", {"param": args.name})
68
+
69
+ if ctx.json:
70
+ output.emit_json({"thing": data})
71
+ return 0
72
+
73
+ print(output.heading("Thing"))
74
+ output.blank()
75
+ print(output.table(["A", "B"], [[1, 2]]))
76
+ return 0
77
+ ```
78
+
79
+ Then add it to `MODULES` in `commands/__init__.py`. The tuple order is the order
80
+ subcommands appear in `base --help`.
81
+
82
+ `ctx` is a `cli.Context`: `ctx.client` is the API client, `ctx.json` is the
83
+ global `--json` flag.
84
+
85
+ Checklist for a new command:
86
+
87
+ - [ ] Supports `--json` with a flat, stable shape — not the raw API envelope.
88
+ - [ ] Raises `NotFoundError`, `AmbiguousError`, or `UsageError` for expected
89
+ failures, so the user gets a message instead of a traceback.
90
+ - [ ] Fails before printing anything, rather than half-way through a table.
91
+ - [ ] Documented in `docs/commands.md` and listed in the README table.
92
+ - [ ] Covered by a test in `tests/`.
93
+
94
+ ## Conventions
95
+
96
+ - **Standard library only** for runtime code. This is deliberate: it keeps
97
+ installation trivial and the tool immune to dependency churn. `certifi` is
98
+ used if it happens to be installed, but is never required. Dev dependencies
99
+ (pytest, ruff) are unconstrained.
100
+ - **Python 3.9+.** Every module starts with `from __future__ import annotations`,
101
+ which is what lets `list[str]` and `str | None` appear in annotations on 3.9.
102
+ - **Line length 100**, enforced by ruff.
103
+ - **Comments explain why, not what.** If a line needs a comment to say what it
104
+ does, rewrite the line.
105
+ - **Missing data renders as `-`.** The API omits stats rather than nulling them;
106
+ never let that raise.
107
+
108
+ ## Testing
109
+
110
+ The suite runs entirely offline. `tests/conftest.py` provides `FakeAPI`, a
111
+ stand-in for the real client that serves canned payloads:
112
+
113
+ ```python
114
+ def test_something(monkeypatch, capsys):
115
+ from .test_cli import run
116
+
117
+ code, out, err = run(monkeypatch, capsys, ["scores"], schedule=SCHEDULE)
118
+ assert code == 0
119
+ assert "Final" in out
120
+ ```
121
+
122
+ `run()` drives `cli.main` exactly as the shell does, so one test covers argument
123
+ parsing, command logic, and rendering together.
124
+
125
+ `FakeAPI` raises on any method a test did not set up. That is intentional — it
126
+ stops a test from silently passing on data it never provided.
127
+
128
+ If you are fixing a bug in how a response is parsed, add the real shape that
129
+ broke it to the fixtures. That is the most useful kind of test in this codebase,
130
+ because the upstream API is undocumented and its shapes are discovered rather
131
+ than specified.
132
+
133
+ ## Reporting bugs
134
+
135
+ Please include:
136
+
137
+ - The exact command you ran.
138
+ - What you expected and what happened.
139
+ - `base --version` and your Python version.
140
+ - For a rendering or parsing bug, the output of the same command with `--json`.
141
+ That distinguishes "the API gave us something unexpected" from "we formatted
142
+ it wrong".
143
+
144
+ ## Before opening a pull request
145
+
146
+ ```bash
147
+ ruff check . && pytest
148
+ ```
149
+
150
+ Keep changes focused, and update `docs/commands.md` and `CHANGELOG.md` when
151
+ behavior changes.
152
+
153
+ ## Scope
154
+
155
+ BaseballCommand is a lookup tool: you ask a question, it prints an answer. Things
156
+ that fit well are more stat groups, better splits, more useful output shapes.
157
+
158
+ Things that don't fit: bulk export, a persistent database, or anything that
159
+ implies scraping the API in volume — see
160
+ [docs/data-source.md](docs/data-source.md) for why.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Owen Powell
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,359 @@
1
+ Metadata-Version: 2.5
2
+ Name: baseballcommand
3
+ Version: 0.1.0
4
+ Summary: Baseball scores and statistics in your terminal, from the free MLB Stats API.
5
+ Project-URL: Homepage, https://github.com/opowell28/BaseballCommand
6
+ Project-URL: Repository, https://github.com/opowell28/BaseballCommand
7
+ Project-URL: Issues, https://github.com/opowell28/BaseballCommand/issues
8
+ Author: Owen Powell
9
+ License: MIT License
10
+
11
+ Copyright (c) 2026 Owen Powell
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
30
+ License-File: LICENSE
31
+ Keywords: baseball,cli,mlb,scores,sports,statistics
32
+ Classifier: Development Status :: 4 - Beta
33
+ Classifier: Environment :: Console
34
+ Classifier: Intended Audience :: End Users/Desktop
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Operating System :: OS Independent
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3.9
39
+ Classifier: Programming Language :: Python :: 3.10
40
+ Classifier: Programming Language :: Python :: 3.11
41
+ Classifier: Programming Language :: Python :: 3.12
42
+ Classifier: Programming Language :: Python :: 3.13
43
+ Classifier: Topic :: Utilities
44
+ Requires-Python: >=3.9
45
+ Provides-Extra: dev
46
+ Requires-Dist: pytest>=7.0; extra == 'dev'
47
+ Requires-Dist: ruff>=0.4; extra == 'dev'
48
+ Description-Content-Type: text/markdown
49
+
50
+ # BaseballCommand
51
+
52
+ Baseball scores and statistics in your terminal.
53
+
54
+ BaseballCommand (`base`) is a command-line tool for looking up player stats, team
55
+ stats, standings, league leaders, and the day's scores. It reads from the public
56
+ MLB Stats API, so there is **no API key, no account, and no signup** — install it
57
+ and run it.
58
+
59
+ ```
60
+ $ base scores yesterday
61
+
62
+ Scores — Thursday, August 13, 2026
63
+ 9 games
64
+
65
+ Status Away R Home R
66
+ ------ --------------------- -- -------------------- -
67
+ Final Cleveland Guardians 0 Detroit Tigers 3
68
+ Final Cincinnati Reds 9 Chicago White Sox 8
69
+ Final Pittsburgh Pirates 13 Miami Marlins 1
70
+ Final Seattle Mariners 1 New York Yankees 0
71
+ Final Boston Red Sox 7 Toronto Blue Jays 0
72
+ ```
73
+
74
+ ```
75
+ $ base player "Aaron Judge"
76
+
77
+ Aaron Judge
78
+ #99 · Outfielder · New York Yankees
79
+
80
+ Bats/Throws Right/Right
81
+ Height/Weight 6' 7", 282 lb
82
+ Age 34
83
+ Born 1992-04-26 (Linden, CA, USA)
84
+ MLB debut 2016-08-13
85
+ Status Active
86
+ MLBAM id 592450
87
+
88
+ Hitting — 2026
89
+ G PA AB R H 2B 3B HR RBI BB SO SB CS AVG OBP SLG OPS
90
+ -- --- --- -- -- -- -- -- --- -- -- -- -- ---- ---- ---- ----
91
+ 59 261 214 43 53 10 0 17 38 42 72 5 3 .248 .375 .533 .908
92
+ ```
93
+
94
+ ---
95
+
96
+ ## Contents
97
+
98
+ - [Data Sources and Dependencies](#data-sources-and-dependencies)
99
+ - [Install](#install)
100
+ - [Quick start](#quick-start)
101
+ - [Commands](#commands)
102
+ - [Global options](#global-options)
103
+ - [Naming players and teams](#naming-players-and-teams)
104
+ - [JSON output and scripting](#json-output-and-scripting)
105
+ - [Caching](#caching)
106
+ - [Troubleshooting](#troubleshooting)
107
+ - [Data source and terms of use](#data-source-and-terms-of-use)
108
+ - [Development](#development)
109
+ - [License](#license)
110
+
111
+ ---
112
+
113
+ ## Data Sources and Dependencies
114
+
115
+ Everything comes from `statsapi.mlb.com`, the same public API that powers
116
+ MLB.com's own scoreboards. It is unauthenticated and free to query. There is no
117
+ paid tier, no rate-limit key, and nothing to configure.
118
+
119
+ BaseballCommand also has **zero runtime dependencies**. It runs on the Python
120
+ standard library alone, so `pip install` pulls in nothing else and the tool keeps
121
+ working regardless of what happens to any third-party package.
122
+
123
+ Please read [Data source and terms of use](#data-source-and-terms-of-use) before
124
+ building anything on top of it — MLBAM permits individual, non-commercial,
125
+ non-bulk use of this data.
126
+
127
+ ## Install
128
+
129
+ Requires Python 3.9 or newer.
130
+
131
+ The recommended way is [pipx](https://pipx.pypa.io/), which installs the CLI into
132
+ its own environment and puts `base` on your PATH:
133
+
134
+ ```bash
135
+ pipx install https://github.com/opowell28/BaseballCommand.git
136
+ ```
137
+
138
+ Or with pip:
139
+
140
+ ```bash
141
+ pip install https://github.com/opowell28/BaseballCommand.git
142
+ ```
143
+
144
+ From a local clone:
145
+
146
+ ```bash
147
+ git clone https://github.com/opowell28/BaseballCommand.git && cd BaseballCommand && pip install -e .
148
+ ```
149
+
150
+ Check that it worked:
151
+
152
+ ```bash
153
+ base --version
154
+ ```
155
+
156
+ The package installs two identical entry points, `base` and `baseballcommand`, and
157
+ also runs as a module with `python -m baseballcommand`.
158
+
159
+ ## Quick start
160
+
161
+ ```bash
162
+ base scores # today's games
163
+ base scores yesterday --linescore # yesterday's games, inning by inning
164
+ base player "Aaron Judge" # a player's current season
165
+ base player Ohtani --years # every season a player has played
166
+ base team NYY # a club's record and season totals
167
+ base standings --league al # American League standings
168
+ base leaders hr -n 5 # this season's top five home run hitters
169
+ base roster LAD --stats --sort HR # a full roster, sorted by home runs
170
+ base compare Judge Ohtani # two players side by side
171
+ ```
172
+
173
+ ## Commands
174
+
175
+ | Command | What it does |
176
+ | --- | --- |
177
+ | [`base scores [DATE]`](docs/commands.md#base-scores) | Scores and status for a day's games |
178
+ | [`base player NAME`](docs/commands.md#base-player) | One player's bio and stat lines |
179
+ | [`base team NAME`](docs/commands.md#base-team) | A club's record and season totals |
180
+ | [`base standings`](docs/commands.md#base-standings) | Division or wild card standings |
181
+ | [`base leaders CATEGORY`](docs/commands.md#base-leaders) | League leaderboards |
182
+ | [`base roster NAME`](docs/commands.md#base-roster) | A club's roster, optionally with everyone's stats |
183
+ | [`base compare A B`](docs/commands.md#base-compare) | Players side by side |
184
+ | [`base teams`](docs/commands.md#base-teams) | Every club and its abbreviation |
185
+ | [`base glossary`](docs/commands.md#base-glossary) | What the column headings mean |
186
+ | [`base cache`](docs/commands.md#base-cache) | Inspect or clear the response cache |
187
+
188
+ Every command takes `-h` for its own options. The full reference, with examples
189
+ and output for each, is in **[docs/commands.md](docs/commands.md)**.
190
+
191
+ ## Global options
192
+
193
+ These go before the subcommand — `base --json scores`, not `base scores --json`.
194
+
195
+ | Option | Effect |
196
+ | --- | --- |
197
+ | `--json` | Print raw JSON instead of tables. Implies `--no-color`. |
198
+ | `--no-color` | Disable ANSI color. |
199
+ | `--no-cache` | Bypass the cache; always fetch fresh. |
200
+ | `--timeout SECONDS` | Network timeout per request (default 15). |
201
+ | `-V`, `--version` | Print the version. |
202
+
203
+ Color is enabled only when stdout is a terminal, and is disabled automatically
204
+ when you pipe or redirect output, or when [`NO_COLOR`](https://no-color.org/) is
205
+ set.
206
+
207
+ ## Naming players and teams
208
+
209
+ You do not have to be precise. Teams accept an abbreviation, a city, a nickname,
210
+ a club name, a full name, or a numeric id:
211
+
212
+ ```bash
213
+ base team NYY
214
+ base team "New York Yankees"
215
+ base team yanks
216
+ base team 147
217
+ ```
218
+
219
+ Players accept any part of a name, or an MLBAM id. Retired players work too:
220
+
221
+ ```bash
222
+ base player judge
223
+ base player "Ken Griffey Jr."
224
+ base player 592450
225
+ ```
226
+
227
+ When a query genuinely matches more than one, BaseballCommand says so and lists
228
+ the candidates rather than guessing:
229
+
230
+ ```
231
+ $ base team sox
232
+ base: 'sox' matches more than one team:
233
+ CWS Chicago White Sox
234
+ BOS Boston Red Sox
235
+ ```
236
+
237
+ ```
238
+ $ base player "ken griffey"
239
+ base: 'ken griffey' matches 2 players — rerun with a fuller name or an id:
240
+ 115135 Ken Griffey Jr. (retired) [CF — Seattle Mariners]
241
+ 115136 Ken Griffey Sr. (retired) [RF — Seattle Mariners]
242
+ ```
243
+
244
+ Run `base teams` for the full list of clubs and abbreviations.
245
+
246
+ ## JSON output and scripting
247
+
248
+ Every command supports `--json`, which prints a stable, flattened structure
249
+ rather than the API's raw envelope. This makes `base` usable as a data source in
250
+ scripts:
251
+
252
+ ```bash
253
+ # Tonight's matchups
254
+ base --json scores | jq -r '.games[] | "\(.away.name) @ \(.home.name)"'
255
+
256
+ # Every team over .500
257
+ base --json standings | jq -r '.groups[].teams[] | select((.pct|tonumber) > 0.5) | .name'
258
+
259
+ # A player's home run total
260
+ base --json player "Aaron Judge" | jq '.stats.hitting[0].stat.homeRuns'
261
+ ```
262
+
263
+ Exit codes are script-friendly:
264
+
265
+ | Code | Meaning |
266
+ | --- | --- |
267
+ | `0` | Success |
268
+ | `1` | Lookup or network failure (unknown player, API unreachable) |
269
+ | `2` | Bad usage (unparseable date, unknown category, ambiguous input) |
270
+ | `130` | Interrupted with Ctrl-C |
271
+
272
+ ## Caching
273
+
274
+ Responses are cached on disk so repeated commands are fast and the free public
275
+ API is not hammered. Live scores get a 30-second lifetime; season stats get an
276
+ hour; team lists and biographical data get a day.
277
+
278
+ ```bash
279
+ base cache # location, entry count, size on disk
280
+ base cache clear # throw it all away
281
+ base --no-cache … # bypass for one command
282
+ ```
283
+
284
+ The cache lives in `~/.cache/baseballcommand` by default, honoring
285
+ `XDG_CACHE_HOME`. Set `BASEBALLCOMMAND_CACHE_DIR` to put it somewhere else. It is
286
+ safe to delete at any time.
287
+
288
+ ## Troubleshooting
289
+
290
+ **`TLS certificate verification failed`**
291
+
292
+ Your Python installation has no usable root certificates. This is common with
293
+ the python.org macOS installer, which ships certificates but does not install
294
+ them.
295
+
296
+ - macOS, python.org build: run `/Applications/Python 3.x/Install Certificates.command`
297
+ - Any platform: `pip install certifi` — BaseballCommand uses it automatically
298
+ when it is present.
299
+
300
+ BaseballCommand never disables certificate verification.
301
+
302
+ **Stats are empty for the current season**
303
+
304
+ In January and February the current season has not started, so `base` defaults to
305
+ the season that just finished. During spring training the regular-season stats
306
+ are genuinely empty; pass `--season` for a specific year.
307
+
308
+ **`Could not reach the MLB Stats API`**
309
+
310
+ Check your network. If you are behind a proxy, `urllib` honors the standard
311
+ `HTTP_PROXY` and `HTTPS_PROXY` environment variables.
312
+
313
+ ## Data source and terms of use
314
+
315
+ All data comes from the MLB Stats API at `https://statsapi.mlb.com`. That API is
316
+ publicly reachable but **not officially documented or supported for third-party
317
+ use**, and its responses carry this notice from MLB Advanced Media:
318
+
319
+ > Only individual, non-commercial, non-bulk use of the Materials is permitted and
320
+ > any other use of the Materials is prohibited without prior written
321
+ > authorization from MLBAM.
322
+ > — [gdx.mlb.com/components/copyright.txt](http://gdx.mlb.com/components/copyright.txt)
323
+
324
+ BaseballCommand is a personal-use tool and is built to stay inside that: it
325
+ queries only what you ask for, and it caches responses to avoid redundant
326
+ requests. If you intend to use this data commercially or to bulk-download it,
327
+ contact MLBAM for authorization first.
328
+
329
+ BaseballCommand is an independent project. It is **not affiliated with,
330
+ endorsed by, or sponsored by** Major League Baseball, MLB Advanced Media, or any
331
+ club. All trademarks belong to their respective owners.
332
+
333
+ More detail on which endpoints are used and how, in
334
+ **[docs/data-source.md](docs/data-source.md)**.
335
+
336
+ ## Development
337
+
338
+ ```bash
339
+ git clone https://github.com/opowell28/BaseballCommand.git
340
+ cd BaseballCommand
341
+ python -m venv .venv && source .venv/bin/activate
342
+ pip install -e ".[dev]"
343
+
344
+ pytest # the full suite, entirely offline
345
+ ruff check . # lint
346
+ ```
347
+
348
+ The test suite makes no network calls — the API client is replaced with a fake
349
+ serving canned payloads — so it is fast and works offline.
350
+
351
+ See **[CONTRIBUTING.md](CONTRIBUTING.md)** for the layout of the codebase and how
352
+ to add a command.
353
+
354
+ ## License
355
+
356
+ [MIT](LICENSE) © Owen Powell.
357
+
358
+ The license covers this software. It does not cover the data, which remains the
359
+ property of MLB Advanced Media under the terms linked above.