Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,29 @@ on:

jobs:
deploy:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
- uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
python-version: '3.x'
# Install a specific version of uv.
version: "0.9.26"
enable-cache: true
- name: Set up Python
run: uv python install
- name: Install dependencies
run: uv sync --locked --all-extras --dev
- name: Build package
run: uv build
- name: Smoke test (wheel)
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
uv run --isolated --no-project --with dist/*.whl tests/smoke_test.py
- name: Smoke test (source distribution)
run: |
python setup.py sdist bdist_wheel
twine upload dist/*
uv run --isolated --no-project --with dist/*.tar.gz tests/smoke_test.py
- name: Publish to PyPI
env:
UV_PUBLISH_USERNAME: ${{ secrets.PYPI_USERNAME }}
UV_PUBLISH_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: uv publish --repository pypi
30 changes: 20 additions & 10 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,28 @@ on: [pull_request, workflow_dispatch]
jobs:
deploy:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13', '3.14']
name: Python ${{ matrix.python-version }} tests
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
- uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
python-version: '3.9'
# Install a specific version of uv.
version: "0.9.26"
enable-cache: true
python-version: ${{ matrix.python-version }}
- name: Set up Python
run: uv python install
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools pytest wheel
run: uv sync --locked --all-extras --dev
- name: Run basic tests
env:
CI: "true"
run: |
pip install .[all]
pytest ./tests/cfb
pytest ./tests/mbb
uv run pytest ./tests/cfb
uv run pytest ./tests/mbb
- name: Build distributions
run: uv build
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ dist
*_box_score_*.csv
.venv
sportsdataverse.egg-info/PKG-INFO
.coverage
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13
88 changes: 88 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,94 @@ cd sportsdataverse-py
pip install -e .[all]
```

## Development

This project uses [uv](https://docs.astral.sh/uv/) for fast, reliable Python package management. The minimum supported Python version is 3.9.

### Prerequisites

Install uv if you haven't already:

```bash
pip install uv
```

Or follow the [official installation guide](https://docs.astral.sh/uv/getting-started/installation/).

### Setting Up the Development Environment

Clone the repository and install all dependencies including development tools:

```bash
git clone https://github.com/sportsdataverse/sportsdataverse-py
cd sportsdataverse-py

# Install all dependencies (including test and doc dependencies)
uv sync --locked --all-extras --dev

# Install the package in editable mode
pip install -e .[all]
Copy link
Copy Markdown
Collaborator

@akeaswaran akeaswaran Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this step fails for me? I can get the package installed in editable mode with pip install -e . but pip tells me there is no dependency group marked all to install (even though I see it in pyproject.toml).

Copy link
Copy Markdown
Collaborator

@akeaswaran akeaswaran Jan 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: was a zsh error. Just needed quotes around .[all] and worked just fine. We may want to document that here just in case

```

### Running Tests

```bash
# Run all tests
uv run pytest ./tests

# Run tests for a specific sport module
uv run pytest ./tests/cfb
uv run pytest ./tests/mbb
uv run pytest ./tests/nfl

# Run tests with coverage
uv run pytest --cov=sportsdataverse

# Run tests in parallel (much faster)
uv run pytest -n auto
```

### Code Quality

The project uses [ruff](https://docs.astral.sh/ruff/) for linting and formatting:

```bash
# Format all Python code
uv run ruff format .

# Check for linting issues
uv run ruff check .

# Type checking (requires mypy)
uv run mypy sportsdataverse
```

### Building the Package

```bash
# Build distribution packages (wheel and source)
uv build

# Run smoke tests on built distributions
uv run --isolated --no-project --with dist/*.whl tests/smoke_test.py
uv run --isolated --no-project --with dist/*.tar.gz tests/smoke_test.py
```

### Project Structure

The package is organized by sport, with each module providing data loading and processing functions:

- `sportsdataverse/cfb/` - College Football
- `sportsdataverse/nfl/` - NFL
- `sportsdataverse/mbb/` - Men's College Basketball
- `sportsdataverse/nba/` - NBA
- `sportsdataverse/wbb/` - Women's College Basketball
- `sportsdataverse/wnba/` - WNBA
- `sportsdataverse/nhl/` - NHL
- `sportsdataverse/mlb/` - MLB

Football modules include pre-trained XGBoost models for expected points (EP) and win probability (WP) calculations.

# **Our Authors**

- [Saiem Gilani](https://twitter.com/saiemgilani)
Expand Down
38 changes: 21 additions & 17 deletions Sphinx-docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@

# -- Project information -----------------------------------------------------

project = 'sdv-py'
copyright = '2022, Saiem Gilani'
author = 'Saiem Gilani'
project = "sdv-py"
copyright = "2022, Saiem Gilani"
author = "Saiem Gilani"


# -- General configuration ---------------------------------------------------
Expand All @@ -28,39 +28,39 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.viewcode',
'sphinx.ext.todo',
"sphinx.ext.autodoc",
"sphinx.ext.doctest",
"sphinx.ext.viewcode",
"sphinx.ext.todo",
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
templates_path = ["_templates"]

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'en'
language = "en"

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'setup.py']
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "setup.py"]


# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx-material'
html_theme = "sphinx-material"

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_static_path = ["_static"]


# -- Extension configuration -------------------------------------------------
Expand All @@ -71,11 +71,15 @@
todo_include_todos = True
import os
import sys
sys.path.insert(0,os.path.abspath('../'))
def skip(app, what, name, obj,would_skip, options):
if name in ( '__init__',):

sys.path.insert(0, os.path.abspath("../"))


def skip(app, what, name, obj, would_skip, options):
if name in ("__init__",):
return False
return would_skip
def setup(app):
app.connect('autodoc-skip-member', skip)


def setup(app):
app.connect("autodoc-skip-member", skip)
Loading