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
110 changes: 110 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,113 @@ jobs:

- name: Type-level tests (tsd)
run: npm run test:types --workspace=modelparams

modelparams-python:
name: modelparams Python package
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"

- name: Install Node dependencies
run: npm ci

- name: Generate Python catalog and types
run: npm run codegen:python

- name: Verify Python generated files are in sync
run: |
if [[ -n "$(git status --porcelain -- packages/modelparams-python/src/modelparams/_generated packages/modelparams-python/src/modelparams/types)" ]]; then
echo "::error::Generated Python package files are out of date."
echo "Run \`npm run codegen:python\` locally and commit the result."
git status --short -- packages/modelparams-python/src/modelparams/_generated packages/modelparams-python/src/modelparams/types
exit 1
fi

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Set up uv
uses: astral-sh/setup-uv@v6
with:
enable-cache: true

- name: Install Python dependencies
run: uv sync --project packages/modelparams-python --extra dev --locked

- name: Lint and format check
run: |
uv run --project packages/modelparams-python ruff check packages/modelparams-python
uv run --project packages/modelparams-python ruff format --check packages/modelparams-python/src packages/modelparams-python/tests

- name: Typecheck
run: uv run --project packages/modelparams-python mypy --config-file packages/modelparams-python/pyproject.toml packages/modelparams-python/src/modelparams packages/modelparams-python/tests/typecheck

- name: Test
run: uv run --project packages/modelparams-python pytest packages/modelparams-python/tests

- name: Build and verify distributions
run: |
uv build --project packages/modelparams-python
uv run --project packages/modelparams-python twine check packages/modelparams-python/dist/*

- name: Smoke-test installed wheel
run: |
smoke_dir="$(mktemp -d)"
python -m venv "$smoke_dir/venv"
"$smoke_dir/venv/bin/pip" install packages/modelparams-python/dist/*.whl
cd "$smoke_dir"
"$smoke_dir/venv/bin/python" -c 'import modelparams; assert len(modelparams.MODEL_IDS) > 0; assert modelparams.validate_params("openai/gpt-4.1", {"temperature": 0.5}) == {"temperature": 0.5}'

modelparams-python-compat:
name: Python ${{ matrix.python-version }} compatibility
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- uses: astral-sh/setup-uv@v6
with:
enable-cache: true

- name: Install
run: uv sync --project packages/modelparams-python --extra dev --locked --python "${{ matrix.python-version }}"

- name: Test
run: uv run --project packages/modelparams-python --python "${{ matrix.python-version }}" pytest packages/modelparams-python/tests

modelparams-python-min-pydantic:
name: Python 3.10 + Pydantic 2.10
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.10"

- uses: astral-sh/setup-uv@v6

- name: Install minimum Pydantic
run: |
uv sync --project packages/modelparams-python --extra dev --locked --python "3.10"
uv pip install --python packages/modelparams-python/.venv/bin/python "pydantic==2.10.*"

- name: Test
run: |
packages/modelparams-python/.venv/bin/python -c 'import pydantic; assert pydantic.__version__.startswith("2.10.")'
packages/modelparams-python/.venv/bin/pytest packages/modelparams-python/tests
140 changes: 140 additions & 0 deletions .github/workflows/release-modelparams-python.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
name: Release modelparams Python

on:
push:
branches: [main]
paths:
- "models/**"
- "packages/modelparams-python/**"
- "src/schema/model.ts"
- "src/data/load.ts"
- ".github/workflows/release-modelparams-python.yml"
workflow_dispatch:
inputs:
force_level:
description: "Force bump level (overrides auto-detect)"
required: false
type: choice
options: ["auto", "patch", "major"]
default: "auto"

concurrency:
group: release-modelparams-python
cancel-in-progress: false

jobs:
build:
name: Build distributions
runs-on: ubuntu-latest
outputs:
next: ${{ steps.bump.outputs.next }}
steps:
- name: Check out repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"

- name: Install Node dependencies
run: npm ci

- name: Validate catalog
run: npm run validate

- name: Generate Python catalog and types
run: npm run codegen:python

- name: Verify generated files are in sync
run: |
if [[ -n "$(git status --porcelain -- packages/modelparams-python/src/modelparams/_generated packages/modelparams-python/src/modelparams/types)" ]]; then
echo "::error::Generated Python package files are out of date."
git status --short -- packages/modelparams-python/src/modelparams/_generated packages/modelparams-python/src/modelparams/types
exit 1
fi

- name: Compute next version
id: bump
run: npx tsx packages/modelparams-python/scripts/compute-version.ts
env:
FORCE_LEVEL: ${{ inputs.force_level }}

- name: Set up Python
if: steps.bump.outputs.next != ''
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Set up uv
if: steps.bump.outputs.next != ''
uses: astral-sh/setup-uv@v6

- name: Install, test, and build
if: steps.bump.outputs.next != ''
env:
NEXT: ${{ steps.bump.outputs.next }}
run: |
uv sync --project packages/modelparams-python --extra dev --locked
uv version --project packages/modelparams-python "$NEXT"
uv run --project packages/modelparams-python ruff check packages/modelparams-python
uv run --project packages/modelparams-python ruff format --check packages/modelparams-python/src packages/modelparams-python/tests
uv run --project packages/modelparams-python pytest packages/modelparams-python/tests
uv run --project packages/modelparams-python mypy --config-file packages/modelparams-python/pyproject.toml packages/modelparams-python/src/modelparams packages/modelparams-python/tests/typecheck
uv build --project packages/modelparams-python
uv run --project packages/modelparams-python twine check packages/modelparams-python/dist/*

- name: Smoke-test installed wheel
if: steps.bump.outputs.next != ''
run: |
smoke_dir="$(mktemp -d)"
python -m venv "$smoke_dir/venv"
"$smoke_dir/venv/bin/pip" install packages/modelparams-python/dist/*.whl
cd "$smoke_dir"
"$smoke_dir/venv/bin/python" -c 'import modelparams; assert len(modelparams.MODEL_IDS) > 0; assert modelparams.validate_params("openai/gpt-4.1", {"temperature": 0.5}) == {"temperature": 0.5}'

- name: Upload distributions
if: steps.bump.outputs.next != ''
uses: actions/upload-artifact@v4
with:
name: modelparams-python-distributions
path: packages/modelparams-python/dist/
if-no-files-found: error

- name: Skip publish
if: steps.bump.outputs.next == ''
run: echo "::notice::No Python package or catalog change since the latest release."

publish:
name: Publish to PyPI
needs: build
if: needs.build.outputs.next != ''
runs-on: ubuntu-latest
environment: pypi
permissions:
actions: read
contents: write
id-token: write
steps:
- name: Download distributions
uses: actions/download-artifact@v4
with:
name: modelparams-python-distributions
path: dist/

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
skip-existing: true

- name: Create GitHub release and tag
uses: softprops/action-gh-release@v2
with:
tag_name: "modelparams-py@${{ needs.build.outputs.next }}"
name: "modelparams-py@${{ needs.build.outputs.next }}"
target_commitish: ${{ github.sha }}
generate_release_notes: true
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ node_modules/
packages/*/dist/
packages/*/*.tsbuildinfo
.cache/
.venv/
.mypy_cache/
.pytest_cache/
.ruff_cache/
__pycache__/
*.py[cod]
*.log
.DS_Store
.env
Expand Down
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ coverage/
*.min.js
*.min.css
packages/modelparams/src/generated/
packages/modelparams-python/src/modelparams/_generated/
packages/modelparams-python/src/modelparams/types/
packages/*/dist/
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,26 @@ await new OpenAI().chat.completions.create({ model: "gpt-4.1", messages, ...para

Defaults, runtime validation, and the helper APIs are in the [package README](packages/modelparams/README.md).

## Python

```bash
pip install modelparams
```

Generated `TypedDict` definitions provide model-specific autocomplete and static checking, while
Pydantic validates untrusted values at runtime:

```python
from modelparams import validate_params
from modelparams.types.openai import Gpt_4_1Params

params: Gpt_4_1Params = {"max_tokens": 1024, "temperature": 0.7}
validated = validate_params("openai/gpt-4.1", params)
```

Defaults, catalog helpers, and validation details are in the
[Python package README](packages/modelparams-python/README.md).

## API

Prefer raw JSON?
Expand All @@ -58,6 +78,7 @@ npm install
npm run dev # http://localhost:3000
npm run build # → dist/
npm run validate # check every YAML
npm run codegen:python # regenerate the Python package catalog and types
npm test
```

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"scripts": {
"build": "tsx src/build/build.ts",
"codegen:python": "tsx packages/modelparams-python/scripts/codegen.ts",
"dev": "tsx watch src/server/dev.ts",
"validate": "tsx src/data/validate.ts",
"guard:params": "tsx src/data/check-removals.ts",
Expand Down
21 changes: 21 additions & 0 deletions packages/modelparams-python/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 modelparams.dev contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Loading
Loading