Metadata-Version: 2.4
Name: pssbl-api
Version: 0.1.0
Summary: Python API wrapper for the Puget Sound Senior Baseball League (PSSBL)
Author: Nick Snyder
License-Expression: MIT
License-File: LICENSE
Keywords: api,baseball,pssbl,wrapper
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Requires-Dist: hishel[async]>=1.0.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic>=2.0.0
Provides-Extra: dev
Requires-Dist: black>=24.0.0; extra == 'dev'
Requires-Dist: mypy>=1.8.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: respx>=0.21.0; extra == 'dev'
Description-Content-Type: text/markdown

# pssbl-api

[![PyPI version](https://img.shields.io/pypi/v/pssbl-api.svg)](https://pypi.org/project/pssbl-api/)
[![Python versions](https://img.shields.io/pypi/pyversions/pssbl-api.svg)](https://pypi.org/project/pssbl-api/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

A Python API wrapper for the **Puget Sound Senior Baseball League (PSSBL)**. Provides both async and sync clients for fetching team, player, and statistics data.

## Table of Contents

- [Installation](#installation)
- [Quick Start](#quick-start)
- [Configuration](#configuration)
- [API Reference](#api-reference)
  - [Team & Division Endpoints](#team--division-endpoints)
  - [Player Endpoints](#player-endpoints)
  - [Stats Endpoints](#stats-endpoints)
- [Caching](#caching)
- [Error Handling](#error-handling)
- [Project Structure](#project-structure)
- [Development](#development)
- [Contributing](#contributing)
- [License](#license)
- [Credits and Acknowledgements](#credits-and-acknowledgements)

## Installation

```bash
pip install pssbl-api
```

## Quick Start

### Async Client (recommended for applications)

```python
from pssbl_api import PSSBLClientAsync

async with PSSBLClientAsync() as client:
    teams = await client.get_team_names(year=2025)
    for team in teams:
        print(f"{team.team_name} ({team.division_name})")
```

### Sync Client (for simple scripts)

```python
from pssbl_api import PSSBLClient

client = PSSBLClient()
teams = client.get_team_names(year=2025)
for team in teams:
    print(f"{team.team_name} ({team.division_name})")
```

## Configuration

Set defaults via environment variables:

```bash
export SEASON_YEAR=2025
export DEFAULT_TEAM_ID=1404
export DEFAULT_DIVISION_NAME=Denali
```

Or pass a `Config` object:

```python
from pssbl_api import PSSBLClientAsync, Config

config = Config(
    season_year=2025,
    default_team_id=1404,
    default_division_name="Denali",
)

async with PSSBLClientAsync(config=config) as client:
    roster = await client.get_roster()  # Uses default team_id
```

## API Reference

### Team & Division Endpoints

| Method | Description |
| ------ | ----------- |
| `get_team_names(year)` | All teams in the league |
| `get_divisions(year)` | All divisions in the league |
| `get_division(division, year)` | Teams in a specific division |
| `get_games(division, year)` | All games for a division |

### Player Endpoints

| Method | Description |
| ------ | ----------- |
| `get_all_players(year)` | All registered players |
| `get_roster(team_id, year)` | Players on a specific team |

### Stats Endpoints

All stats methods use a `StatType` enum: `BATTING`, `PITCHING`, or `BOTH`.

| Method | Description |
| ------ | ----------- |
| `get_player_stats(player_id, stat_type, year, show_career)` | Stats for a single player |
| `get_team_stats(team_id, stat_type, year)` | Stats for all players on a team |
| `get_division_player_stats(division, stat_type, year)` | Stats for all players in a division |
| `get_division_team_stats(division, stat_type, year)` | Aggregated team stats in a division |

#### Stats Examples

```python
from pssbl_api import PSSBLClient, StatType

client = PSSBLClient()

# Get 2024 batting stats for a player
result = client.get_player_stats(player_id=1404, stat_type=StatType.BATTING, year=2024)
print(result["batting"])

# Get career pitching stats for a player
result = client.get_player_stats(player_id=1404, stat_type=StatType.PITCHING, show_career=True)
print(result["pitching"])

# Get both batting and pitching stats for current year
result = client.get_player_stats(player_id=1404, stat_type=StatType.BOTH)
print(result["batting"], result["pitching"])

# Get team batting stats
result = client.get_team_stats(team_id=1500, stat_type=StatType.BATTING, year=2024)
print(result["batting"])

# Get division-wide player stats
result = client.get_division_player_stats(division="Denali", stat_type=StatType.BOTH)
print(result["batting"], result["pitching"])

# Get aggregated team stats for a division
result = client.get_division_team_stats(division="Denali", stat_type=StatType.BATTING)
print(result["batting"])  # Team averages and totals
```

## Caching

Responses are cached for 24 hours by default. To clear the cache:

```python
from pssbl_api import clear_cache

clear_cache()
```

To disable caching:

```python
client = PSSBLClient(use_cache=False)
```

## Error Handling

All methods return `None` on error and log exceptions. This design prevents exceptions from bubbling up in async contexts like Slack bots.

```python
teams = client.get_team_names()
if teams is None:
    print("Failed to fetch teams")
```

## Project Structure

```text
pssbl-api/
├── src/
│   └── pssbl_api/
│       ├── __init__.py      # Public API exports
│       ├── cache.py         # Caching layer (24h TTL with hishel)
│       ├── client.py        # Async and sync API clients
│       ├── config.py        # Configuration and environment variables
│       └── models/
│           ├── __init__.py  # Model exports
│           ├── enums.py     # StatType enum
│           ├── games.py     # Game model
│           ├── players.py   # Player and roster models
│           ├── stats.py     # Batting and pitching stats models
│           └── teams.py     # Team and division models
├── tests/
│   ├── test_client.py       # Async client tests
│   ├── test_config.py       # Configuration tests
│   ├── test_models.py       # Model parsing tests
│   └── test_sync_client.py  # Sync client tests
├── pyproject.toml           # Package configuration
├── LICENSE                  # MIT License
├── CONTRIBUTING.md          # Contribution guidelines
└── README.md                # This file
```

## Development

```bash
# Clone the repository
git clone https://github.com/YOUR_USERNAME/pssbl-api.git
cd pssbl-api

# Create virtual environment
python -m venv .venv
source .venv/bin/activate

# Install in development mode
pip install -e ".[dev]"

# Run tests
pytest

# Format code
black .
```

## Contributing

Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on:

- Setting up a development environment
- Code style and testing requirements
- Submitting pull requests
- Reporting issues

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Credits and Acknowledgements

### Data Source

All baseball data is provided by [PSSBL.com](https://pssbl.com), the official website of the Puget Sound Senior Baseball League.

### Disclaimer

This project is **not affiliated with, endorsed by, or officially connected to the Puget Sound Senior Baseball League (PSSBL)** in any way. It is an independent, community-driven project that provides a convenient Python interface to publicly available league data.

### Tech Stack

- [httpx](https://www.python-httpx.org/) - HTTP client with async support
- [Pydantic](https://docs.pydantic.dev/) - Data validation and parsing
- [hishel](https://hishel.com/) - HTTP caching layer
