Skip to content
Open
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
22 changes: 8 additions & 14 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@ on:
paths:
- ".github/workflows/docs.yml"
- ".github/docs-versions.yml"
- "build_scripts/inject_version_picker.py"
- "build_scripts/version_picker_assets/**"
- "build_scripts/**"
- "doc/**"
- "build_scripts/pydoc2json.py"
- "build_scripts/gen_api_md.py"
- "pyrit/**"
workflow_dispatch:

Expand Down Expand Up @@ -62,7 +59,7 @@ jobs:
with:
sparse-checkout: |
.github/docs-versions.yml
build_scripts/resolve_docs_matrix.py
/build_scripts/
sparse-checkout-cone-mode: false

- name: Set up Python 3.13
Expand All @@ -76,7 +73,7 @@ jobs:
- name: Compute matrix
id: matrix
run: |
python build_scripts/resolve_docs_matrix.py \
python -m build_scripts.resolve_docs_matrix \
--config .github/docs-versions.yml \
--github-output "$GITHUB_OUTPUT"

Expand Down Expand Up @@ -164,8 +161,8 @@ jobs:
if: steps.cache.outputs.cache-hit != 'true'
run: |
source .venv/bin/activate
python build_scripts/pydoc2json.py pyrit --submodules -o doc/_api/pyrit_all.json
python build_scripts/gen_api_md.py
python -m build_scripts.pydoc2json pyrit --submodules -o doc/_api/pyrit_all.json
python -m build_scripts.gen_api_md

- name: Build the static HTML site
if: steps.cache.outputs.cache-hit != 'true'
Expand Down Expand Up @@ -208,10 +205,7 @@ jobs:
with:
sparse-checkout: |
.github/docs-versions.yml
build_scripts/inject_version_picker.py
build_scripts/version_picker_assets
build_scripts/generate_pages_manifest.py
build_scripts/compose_docs_dist.py
/build_scripts/
sparse-checkout-cone-mode: false

- name: Set up Python 3.13
Expand All @@ -235,15 +229,15 @@ jobs:
# auto-redirect script that uses the manifest to find the closest
# sibling page in the same version).
run: |
python build_scripts/compose_docs_dist.py \
python -m build_scripts.compose_docs_dist \
--artifacts-dir artifacts \
--dist-dir dist \
--config .github/docs-versions.yml \
--base "${DOCS_BASE}"

- name: Inject version picker
run: |
python build_scripts/inject_version_picker.py \
python -m build_scripts.inject_version_picker \
--site-dir dist \
--base "${DOCS_BASE}"

Expand Down
16 changes: 8 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,46 @@ repos:
hooks:
- id: sanitize-notebook-paths
name: Sanitize Notebook Paths
entry: python ./build_scripts/sanitize_notebook_paths.py
entry: python -m build_scripts.sanitize_notebook_paths
language: python
files: ^doc.*\.(ipynb)$
- id: strip-notebook-progress-bars
name: Strip Notebook Progress Bars
entry: python ./build_scripts/strip_notebook_progress_bars.py
entry: python -m build_scripts.strip_notebook_progress_bars
language: python
files: ^doc.*\.(ipynb)$
- id: strip-py-kernelspec
name: Strip kernelspec from jupytext .py files
entry: python ./build_scripts/strip_py_kernelspec.py
entry: python -m build_scripts.strip_py_kernelspec
language: python
files: ^doc/.*\.py$
- id: validate-docs
name: Validate Documentation Structure
entry: python ./build_scripts/validate_docs.py
entry: python -m build_scripts.validate_docs
language: python
files: ^(doc/.*\.(py|ipynb|md)|doc/myst\.yml)$
pass_filenames: false
additional_dependencies: ['pyyaml']
- id: check-no-rest-roles
name: Reject Sphinx reST cross-reference roles
entry: python ./build_scripts/check_no_rest_roles.py
entry: python -m build_scripts.check_no_rest_roles
language: python
files: ^pyrit/.*\.py$
- id: enforce_alembic_revision_immutability
name: Enforce Alembic Revision Immutability
entry: python ./build_scripts/enforce_alembic_revision_immutability.py
entry: python -m build_scripts.enforce_alembic_revision_immutability
language: python
files: ^pyrit/memory/alembic/versions/.*\.py$
pass_filenames: false
- id: check-async-suffix
name: Enforce _async Suffix on async def
entry: python ./build_scripts/check_async_suffix.py
entry: python -m build_scripts.check_async_suffix
language: python
files: ^pyrit/.*\.py$
pass_filenames: false
- id: memory-migrations-check
name: Check Memory Migrations
entry: python ./build_scripts/memory_migrations.py check
entry: python -m build_scripts.memory_migrations check
language: system
pass_filenames: false
files: ^pyrit/memory/(memory_models\.py|alembic/.*|migration\.py)$
Expand Down
16 changes: 8 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,28 @@ ty:
# 3. Build the Jupyter Book site (HTML only — fast, no LaTeX needed)
# 4. Generate RSS feed
docs-build:
uv run python build_scripts/pydoc2json.py pyrit --submodules -o doc/_api/pyrit_all.json
uv run python build_scripts/gen_api_md.py
uv run python -m build_scripts.pydoc2json pyrit --submodules -o doc/_api/pyrit_all.json
uv run python -m build_scripts.gen_api_md
# --strict validates URLs and cross-refs; skips are configured in doc/myst.yml under error_rules
cd doc && uv run jupyter-book build --all --html --strict
uv run ./build_scripts/generate_rss.py
uv run python -m build_scripts.generate_rss

# Build the full documentation site including the PDF export.
# Mirrors the ReadTheDocs build (.readthedocs.yaml) so CI catches PDF-only issues
# such as missing images that the HTML-only build silently ignores.
# Requires xelatex / latexmk on PATH (texlive-xetex + texlive-fonts-recommended +
# texlive-plain-generic + latexmk on Ubuntu).
docs-build-all:
uv run python build_scripts/pydoc2json.py pyrit --submodules -o doc/_api/pyrit_all.json
uv run python build_scripts/gen_api_md.py
uv run python -m build_scripts.pydoc2json pyrit --submodules -o doc/_api/pyrit_all.json
uv run python -m build_scripts.gen_api_md
# --strict validates URLs and cross-refs; skips are configured in doc/myst.yml under error_rules
cd doc && uv run jupyter-book build --all --html --pdf --strict
uv run ./build_scripts/generate_rss.py
uv run python -m build_scripts.generate_rss

# Regenerate only the API reference pages (without building the full site)
docs-api:
uv run python build_scripts/pydoc2json.py pyrit --submodules -o doc/_api/pyrit_all.json
uv run python build_scripts/gen_api_md.py
uv run python -m build_scripts.pydoc2json pyrit --submodules -o doc/_api/pyrit_all.json
uv run python -m build_scripts.gen_api_md

# Because of import time, "auto" seemed to actually go slower than just using 4 processes
unit-test:
Expand Down
9 changes: 9 additions & 0 deletions build_scripts/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.

"""Repository build and maintenance scripts.

Modules here are executed as ``python -m build_scripts.<name>`` from the
repository root so sibling imports resolve through the package rather than
through ``sys.path`` mutation.
"""
2 changes: 1 addition & 1 deletion build_scripts/check_no_rest_roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
This hook flags any newly introduced reST role inside ``pyrit/`` so it can
be replaced before landing. Run it manually with::

uv run python build_scripts/check_no_rest_roles.py
uv run python -m build_scripts.check_no_rest_roles

or rely on the ``check-no-rest-roles`` pre-commit hook in
``.pre-commit-config.yaml``.
Expand Down
5 changes: 3 additions & 2 deletions build_scripts/compose_docs_dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
tweaking the 404 markup is a code change, not a shell-quoting puzzle.

Usage:
python build_scripts/compose_docs_dist.py \\
python -m build_scripts.compose_docs_dist \\
--artifacts-dir artifacts \\
--dist-dir dist \\
--config .github/docs-versions.yml \\
Expand All @@ -39,7 +39,8 @@
from typing import Any

import yaml
from generate_pages_manifest import collect_pages

from build_scripts.generate_pages_manifest import collect_pages

# Single source of truth for the closest-page algorithm. Both the version
# picker (inject_version_picker.py) and the 404 page below concat the
Expand Down
8 changes: 4 additions & 4 deletions build_scripts/evaluate_scorers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
scorer performance. Results are saved to the scorer_evals directory and checked in.

Usage:
python build_scripts/evaluate_scorers.py
python build_scripts/evaluate_scorers.py --tags refusal
python build_scripts/evaluate_scorers.py --tags refusal,default
python build_scripts/evaluate_scorers.py --max-concurrency 3
python -m build_scripts.evaluate_scorers
python -m build_scripts.evaluate_scorers --tags refusal
python -m build_scripts.evaluate_scorers --tags refusal,default
python -m build_scripts.evaluate_scorers --max-concurrency 3
"""

import argparse
Expand Down
4 changes: 1 addition & 3 deletions build_scripts/example_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@
import ast
import json
import re
import sys
import textwrap
from dataclasses import dataclass
from pathlib import Path

import yaml

sys.path.insert(0, str(Path(__file__).parent))
import validate_docs
from build_scripts import validate_docs


@dataclass(frozen=True)
Expand Down
7 changes: 3 additions & 4 deletions build_scripts/gen_api_md.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
MyST markdown pages suitable for Jupyter Book 2.

Usage:
python build_scripts/gen_api_md.py
python -m build_scripts.gen_api_md
"""

import json
Expand All @@ -22,9 +22,8 @@
from pathlib import Path

# Import sibling script for post-generation TOC validation.
sys.path.insert(0, str(Path(__file__).parent))
import validate_docs
from example_index import ExampleReference, SymbolEntry, _build_example_index
from build_scripts import validate_docs
from build_scripts.example_index import ExampleReference, SymbolEntry, _build_example_index

DOC_ROOT = Path("doc")
API_JSON_DIR = DOC_ROOT / "_api"
Expand Down
2 changes: 1 addition & 1 deletion build_scripts/generate_pages_manifest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""Generate a pages.json manifest listing every rendered HTML page in a built site.

Usage:
python build_scripts/generate_pages_manifest.py \\
python -m build_scripts.generate_pages_manifest \\
--site-dir dist/0.13.0 \\
--output dist/0.13.0/pages.json

Expand Down
2 changes: 1 addition & 1 deletion build_scripts/inject_version_picker.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""Inject the PyRIT version picker into a built doc site.

Usage:
python build_scripts/inject_version_picker.py \\
python -m build_scripts.inject_version_picker \\
--site-dir dist \\
--base /PyRIT

Expand Down
2 changes: 1 addition & 1 deletion build_scripts/migrate_prod_memory_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
- Exits non-zero on any failure.

Usage:
python build_scripts/migrate_prod_memory_schema.py
python -m build_scripts.migrate_prod_memory_schema

The script reads the production connection string from
AZURE_SQL_DB_CONNECTION_STRING_PROD (loaded from ~/.pyrit/.env).
Expand Down
2 changes: 1 addition & 1 deletion build_scripts/preview_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

Run from the directory you want to serve:

python build_scripts/preview_server.py [--port 8000] [--directory dist]
python -m build_scripts.preview_server [--port 8000] [--directory dist]

Resolution rules, in order:
1. If the requested path is a file, serve it.
Expand Down
2 changes: 1 addition & 1 deletion build_scripts/resolve_docs_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
or to stdout when ``--github-output`` is not provided (for local testing).

Usage:
python build_scripts/resolve_docs_matrix.py \\
python -m build_scripts.resolve_docs_matrix \\
--config .github/docs-versions.yml \\
--github-output "$GITHUB_OUTPUT"

Expand Down
12 changes: 6 additions & 6 deletions doc/code/scoring/4_scorer_metrics.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -688,14 +688,14 @@
"\n",
"```bash\n",
"# Evaluate all registered scorers (long-running — can take hours)\n",
"python build_scripts/evaluate_scorers.py\n",
"python -m build_scripts.evaluate_scorers\n",
"\n",
"# Evaluate only scorers with specific tags\n",
"python build_scripts/evaluate_scorers.py --tags refusal\n",
"python build_scripts/evaluate_scorers.py --tags refusal,default\n",
"python -m build_scripts.evaluate_scorers --tags refusal\n",
"python -m build_scripts.evaluate_scorers --tags refusal,default\n",
"\n",
"# Control parallelism (default: 5, lower if hitting rate limits)\n",
"python build_scripts/evaluate_scorers.py --max-concurrency 3\n",
"python -m build_scripts.evaluate_scorers --max-concurrency 3\n",
"```\n",
"\n",
"### Tags\n",
Expand All @@ -715,7 +715,7 @@
"**Step 1: Evaluate refusal scorers first**\n",
"\n",
"```bash\n",
"python build_scripts/evaluate_scorers.py --tags refusal\n",
"python -m build_scripts.evaluate_scorers --tags refusal\n",
"```\n",
"\n",
"This evaluates only the 4 refusal variants and writes results to\n",
Expand All @@ -725,7 +725,7 @@
"**Step 2: Re-evaluate all scorers**\n",
"\n",
"```bash\n",
"python build_scripts/evaluate_scorers.py\n",
"python -m build_scripts.evaluate_scorers\n",
"```\n",
"\n",
"On the next full run, `ScorerInitializer` reads the refusal metrics from Step 1, picks the best\n",
Expand Down
12 changes: 6 additions & 6 deletions doc/code/scoring/4_scorer_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,14 +368,14 @@
#
# ```bash
# # Evaluate all registered scorers (long-running — can take hours)
# python build_scripts/evaluate_scorers.py
# python -m build_scripts.evaluate_scorers
#
# # Evaluate only scorers with specific tags
# python build_scripts/evaluate_scorers.py --tags refusal
# python build_scripts/evaluate_scorers.py --tags refusal,default
# python -m build_scripts.evaluate_scorers --tags refusal
# python -m build_scripts.evaluate_scorers --tags refusal,default
#
# # Control parallelism (default: 5, lower if hitting rate limits)
# python build_scripts/evaluate_scorers.py --max-concurrency 3
# python -m build_scripts.evaluate_scorers --max-concurrency 3
# ```
#
# ### Tags
Expand All @@ -395,7 +395,7 @@
# **Step 1: Evaluate refusal scorers first**
#
# ```bash
# python build_scripts/evaluate_scorers.py --tags refusal
# python -m build_scripts.evaluate_scorers --tags refusal
# ```
#
# This evaluates only the 4 refusal variants and writes results to
Expand All @@ -405,7 +405,7 @@
# **Step 2: Re-evaluate all scorers**
#
# ```bash
# python build_scripts/evaluate_scorers.py
# python -m build_scripts.evaluate_scorers
# ```
#
# On the next full run, `ScorerInitializer` reads the refusal metrics from Step 1, picks the best
Expand Down
Loading