Metadata-Version: 2.4
Name: pearatings
Version: 0.2.0
Summary: Python client for the PEARatings college baseball and softball data API
Author-email: PEARatings <pearatings@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://pearatings.com
Project-URL: Pricing, https://api.pearatings.com/billing
Project-URL: Documentation, https://api.pearatings.com/docs
Project-URL: Source, https://github.com/pearatings/pear-api
Keywords: college baseball,college softball,ratings,sports analytics,api,ncaa,naia
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.25
Requires-Dist: pandas>=1.3
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Dynamic: license-file

# pearatings

Python client for the [PEARatings](https://pearatings.com) data API: college baseball (D1, D2, D3, NAIA)
and softball (D1, D2, D3) ratings, projections, player stats, history, Lookup and tournament simulations.
Tables come back as pandas DataFrames.

## Install

```bash
pip install pearatings
```

## Get a key

Pick a tier at **https://api.pearatings.com/billing**. Your key is shown once: copy it.

| Tier | Price | API calls per month | Per minute |
|---|---|---|---|
| Free | $0 | 500 | 10 |
| Starter | $1.99/month | 1,000 | 30 |
| Plus | $4.99/month | 5,000 | 60 |
| Pro | $9.99/month | 20,000 | 120 |
| Max | $19.99/month | 50,000 | 120 |

Every request is one call; `players()` fetches a full leaderboard 200 rows per call. Calls reset on the 1st
(UTC). `pear.account()` shows your tier and calls used this month; `pear.billing_portal()` changes tier or cancels.

## Set your key

```bash
export PEAR_API_KEY='your-key'        # single quotes if the key has a ! in it
```
or pass it: `Pear(api_key="your-key")`.

## Quick start

```python
from pearatings import Pear

pear = Pear()

ratings = pear.ratings()                               # D1 baseball, current
ratings.attrs["date"]                                  # when the ratings were updated
pear.ratings(sport="softball", division="d2")

pear.preseason(2027)                                   # preseason ratings
pear.stats(2025)                                       # team stats + end-of-season ratings for 2025

pear.games("2026-04-18")                               # that day's games with PEAR's line and win probability
pear.matchup("LSU", "Florida", neutral=True)           # any two teams
pear.team_schedule("LSU", 2026)["schedule"]            # every game of a team's season

pear.players(2026)                                     # full hitting leaderboard (every page)
pear.players(2026, side="pitching", conferences=["SEC"], limit=50)
roster = pear.roster("LSU", 2026)
pear.player(roster["player_id"].iloc[0])["games"]      # one player's game-by-game lines

pear.history("LSU")                                    # end-of-season numbers, every season
pear.tournament_outlook()                              # projected NCAA field
pear.simulate_bracket(seed=7)                          # one simulated tournament

open("lsu.png", "wb").write(pear.logo("LSU"))
```

Every method takes keyword-only `sport` (`"baseball"` default, or `"softball"`) and `division` (`"d1"`
default, `"d2"`, `"d3"`, `"naia"`) unless it exists for one division only. Use `help(pear.games)` for any
method's details.

## What comes back

- **One table** → a `DataFrame`; the rest of the response (data date, season, totals) is in `df.attrs`.
- **Anything else** → a `dict`, where every list of records is a `DataFrame`.
- Nested fields are flattened to dotted columns: `record.wins`, `stats.PA`.
- `pear.get("baseball/d1/ratings")` / `pear.post(path, body)` return the raw JSON of any endpoint.

## Methods

| Area | Methods |
|---|---|
| Your account | `account`, `billing_portal` |
| Teams and ratings | `ratings`, `preseason`, `stats`, `teams`, `team`, `team_conferences`, `conferences`, `conference_standings`, `records`, `pcr_ranks`, `combined_ratings`, `logo`, `conference_logo` |
| Projections | `games`, `matchup`, `team_schedule`, `simulate_wins`, `season_projection`, `conference_projections` |
| Players | `players`, `roster`, `player` |
| History | `history`, `tournament_history`, `historical_table` |
| Lookup | `lookup_fields`, `lookup_options`, `lookup` |
| Tournaments | `tournament_outlook`, `tournament_regionals`, `tournament_team`, `simulate_bracket`, `conference_tournament_probs`, `d2_simulate_cary`, `naia_simulate_regional`, `naia_simulate_ws`, `naia_ws_odds` |

## Lookup

Find games or player games that meet conditions. Field keys come from `pear.lookup_fields()`.

```python
pear.lookup_fields()                                   # kind, key, label, group, unit

# games where a team scored 25+ in 2026
pear.lookup(2026, conditions=[{"kind": "team", "field": "R", "op": ">=", "value": 25, "scope": "either"}])

# 3-homer games, 2021-2026
pear.lookup(2021, 2026, mode="players", role="bat",
            conditions=[{"kind": "player", "field": "HR", "op": ">=", "value": 3}], limit=200)
```
Up to 200 rows per call; `df.attrs["total"]` is the full count, page with `offset=`.

## Errors

All errors subclass `pearatings.PearError` and carry `.status_code`:
`AuthenticationError` (bad or missing key, or a lapsed subscription), `NotFoundError` (unknown team / season),
`InvalidRequestError` (bad parameters), `RateLimitError` (over your tier's limit; `.retry_after` says how many
seconds to wait), `APIError` (anything else, e.g. data not available out of season).

## Development

```bash
pip install -e '.[test]'
pytest                                                    # offline tests
PEAR_API_KEY='...' PEAR_API_URL=http://127.0.0.1:8001 pytest -m live   # every method against a running API
```
`PEAR_API_URL` (or `Pear(base_url=...)`) points the client at another server; the default is
`https://api.pearatings.com`.
