diff --git a/.github/workflows/photon-api-docs.yml b/.github/workflows/photon-api-docs.yml
index f93d5b6e5..e61608f60 100644
--- a/.github/workflows/photon-api-docs.yml
+++ b/.github/workflows/photon-api-docs.yml
@@ -84,15 +84,17 @@ jobs:
python -m pip install --upgrade pip
pip install -r photon-lib/py/docs/requirements.txt
- - name: Build MkDocs site
- run: mkdocs build
+ - name: Build Sphinx site
+ run: |
+ sphinx-apidocs -o docs/source photonlibpy
+ make -C docs html
working-directory: photon-lib/py
- name: Upload built site as artifact
uses: actions/upload-artifact@v4
with:
name: docs-python
- path: photon-lib/py/site/
+ path: photon-lib/py/docs/build/html
publish_api_docs:
name: Publish API Docs
@@ -105,7 +107,7 @@ jobs:
pattern: docs-*
- run: find .
- name: Publish Docs To Development
- if: github.ref == 'refs/heads/main'
+ # if: github.ref == 'refs/heads/main'
uses: up9cloud/action-rsync@v1.4
env:
HOST: ${{ secrets.WEBMASTER_SSH_HOST }}
diff --git a/.gitignore b/.gitignore
index 78aa69b11..920c55008 100644
--- a/.gitignore
+++ b/.gitignore
@@ -149,5 +149,4 @@ dist
components.d.ts
# Py docs stuff
-photon-lib/py/site
-photon-lib/py/docs/reference
+photon-lib/py/docs/build
diff --git a/photon-lib/py/docs/Makefile b/photon-lib/py/docs/Makefile
new file mode 100644
index 000000000..d0c3cbf10
--- /dev/null
+++ b/photon-lib/py/docs/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build
+SOURCEDIR = source
+BUILDDIR = build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/photon-lib/py/docs/SUMMARY.md b/photon-lib/py/docs/SUMMARY.md
deleted file mode 100644
index cd684b058..000000000
--- a/photon-lib/py/docs/SUMMARY.md
+++ /dev/null
@@ -1,24 +0,0 @@
-* [estimatedRobotPose](reference/estimatedRobotPose.md)
-* estimation
- * [cameraTargetRelation](reference/estimation/cameraTargetRelation.md)
- * [openCVHelp](reference/estimation/openCVHelp.md)
- * [rotTrlTransform3d](reference/estimation/rotTrlTransform3d.md)
- * [targetModel](reference/estimation/targetModel.md)
- * [visionEstimation](reference/estimation/visionEstimation.md)
-* networktables
- * [NTTopicSet](reference/networktables/NTTopicSet.md)
-* [photonCamera](reference/photonCamera.md)
-* [photonPoseEstimator](reference/photonPoseEstimator.md)
-* simulation
- * [photonCameraSim](reference/simulation/photonCameraSim.md)
- * [simCameraProperties](reference/simulation/simCameraProperties.md)
- * [videoSimUtil](reference/simulation/videoSimUtil.md)
- * [visionSystemSim](reference/simulation/visionSystemSim.md)
- * [visionTargetSim](reference/simulation/visionTargetSim.md)
-* targeting
- * [TargetCorner](reference/targeting/TargetCorner.md)
- * [multiTargetPNPResult](reference/targeting/multiTargetPNPResult.md)
- * [photonPipelineResult](reference/targeting/photonPipelineResult.md)
- * [photonTrackedTarget](reference/targeting/photonTrackedTarget.md)
-* timesync
- * [timeSyncServer](reference/timesync/timeSyncServer.md)
diff --git a/photon-lib/py/docs/index.md b/photon-lib/py/docs/index.md
deleted file mode 100644
index 06545b8e2..000000000
--- a/photon-lib/py/docs/index.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# PhotonLib Python Docs
-
-For the full PhotonVision documentation visit [docs.photonvision.org](https://docs.photonvision.org).
diff --git a/photon-lib/py/docs/logo.svg b/photon-lib/py/docs/logo.svg
deleted file mode 100644
index 88643de26..000000000
--- a/photon-lib/py/docs/logo.svg
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
diff --git a/photon-lib/py/docs/make.bat b/photon-lib/py/docs/make.bat
new file mode 100644
index 000000000..dc1312ab0
--- /dev/null
+++ b/photon-lib/py/docs/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=source
+set BUILDDIR=build
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.https://www.sphinx-doc.org/
+ exit /b 1
+)
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+
+:end
+popd
diff --git a/photon-lib/py/docs/requirements.txt b/photon-lib/py/docs/requirements.txt
index 6280a794a..0a149a303 100644
--- a/photon-lib/py/docs/requirements.txt
+++ b/photon-lib/py/docs/requirements.txt
@@ -1,7 +1,4 @@
-mkdocs==1.6.1
-mkdocs-material==9.6.12
-mkdocstrings[python]==0.29.1
-mkdocs-gen-files==0.5.0
-mkdocs-literate-nav==0.6.2
-mkdocs-section-index==0.3.10
-mkdocs-exclude==1.0.2
+sphinx==7.2.6
+sphinx-autodoc-typehints==1.25.2
+sphinx-rtd-theme==1.3.0
+sphinx-apidoc==1.0.0
diff --git a/photon-lib/py/docs/source/conf.py b/photon-lib/py/docs/source/conf.py
new file mode 100644
index 000000000..078ed31d0
--- /dev/null
+++ b/photon-lib/py/docs/source/conf.py
@@ -0,0 +1,35 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# For the full list of built-in configuration values, see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Project information -----------------------------------------------------
+# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
+
+project = "PhotonVision"
+copyright = "2025, Matt Morley, Banks Troutman"
+author = "Matt Morley, Banks Troutman"
+
+# -- General configuration ---------------------------------------------------
+# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
+
+extensions = [
+ "sphinx.ext.autodoc",
+ "sphinx.ext.napoleon", # for Google/NumPy docstrings
+ "sphinx_autodoc_typehints", # for type hints in docs
+]
+
+import os
+import sys
+
+sys.path.insert(0, os.path.abspath("../..")) # adjust based on your project layout
+
+templates_path = ["_templates"]
+exclude_patterns = []
+
+
+# -- Options for HTML output -------------------------------------------------
+# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
+
+html_theme = "alabaster"
+html_static_path = ["_static"]
diff --git a/photon-lib/py/docs/source/index.rst b/photon-lib/py/docs/source/index.rst
new file mode 100644
index 000000000..78b78862c
--- /dev/null
+++ b/photon-lib/py/docs/source/index.rst
@@ -0,0 +1,16 @@
+.. PhotonVision documentation master file, created by
+ sphinx-quickstart on Fri May 9 12:16:37 2025.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+PhotonVision documentation
+==========================
+
+Add your content using ``reStructuredText`` syntax. See the
+`reStructuredText `_
+documentation for details.
+
+
+.. toctree::
+ :maxdepth: 2
+ :caption: Contents:
diff --git a/photon-lib/py/docs/source/modules.rst b/photon-lib/py/docs/source/modules.rst
new file mode 100644
index 000000000..486e41787
--- /dev/null
+++ b/photon-lib/py/docs/source/modules.rst
@@ -0,0 +1,7 @@
+photonlibpy
+===========
+
+.. toctree::
+ :maxdepth: 4
+
+ photonlibpy
diff --git a/photon-lib/py/docs/source/photonlibpy.estimation.rst b/photon-lib/py/docs/source/photonlibpy.estimation.rst
new file mode 100644
index 000000000..05004e2f4
--- /dev/null
+++ b/photon-lib/py/docs/source/photonlibpy.estimation.rst
@@ -0,0 +1,53 @@
+photonlibpy.estimation package
+==============================
+
+Submodules
+----------
+
+photonlibpy.estimation.cameraTargetRelation module
+--------------------------------------------------
+
+.. automodule:: photonlibpy.estimation.cameraTargetRelation
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.estimation.openCVHelp module
+----------------------------------------
+
+.. automodule:: photonlibpy.estimation.openCVHelp
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.estimation.rotTrlTransform3d module
+-----------------------------------------------
+
+.. automodule:: photonlibpy.estimation.rotTrlTransform3d
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.estimation.targetModel module
+-----------------------------------------
+
+.. automodule:: photonlibpy.estimation.targetModel
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.estimation.visionEstimation module
+----------------------------------------------
+
+.. automodule:: photonlibpy.estimation.visionEstimation
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+Module contents
+---------------
+
+.. automodule:: photonlibpy.estimation
+ :members:
+ :undoc-members:
+ :show-inheritance:
diff --git a/photon-lib/py/docs/source/photonlibpy.generated.rst b/photon-lib/py/docs/source/photonlibpy.generated.rst
new file mode 100644
index 000000000..bc21eb9fa
--- /dev/null
+++ b/photon-lib/py/docs/source/photonlibpy.generated.rst
@@ -0,0 +1,61 @@
+photonlibpy.generated package
+=============================
+
+Submodules
+----------
+
+photonlibpy.generated.MultiTargetPNPResultSerde module
+------------------------------------------------------
+
+.. automodule:: photonlibpy.generated.MultiTargetPNPResultSerde
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.generated.PhotonPipelineMetadataSerde module
+--------------------------------------------------------
+
+.. automodule:: photonlibpy.generated.PhotonPipelineMetadataSerde
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.generated.PhotonPipelineResultSerde module
+------------------------------------------------------
+
+.. automodule:: photonlibpy.generated.PhotonPipelineResultSerde
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.generated.PhotonTrackedTargetSerde module
+-----------------------------------------------------
+
+.. automodule:: photonlibpy.generated.PhotonTrackedTargetSerde
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.generated.PnpResultSerde module
+-------------------------------------------
+
+.. automodule:: photonlibpy.generated.PnpResultSerde
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.generated.TargetCornerSerde module
+----------------------------------------------
+
+.. automodule:: photonlibpy.generated.TargetCornerSerde
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+Module contents
+---------------
+
+.. automodule:: photonlibpy.generated
+ :members:
+ :undoc-members:
+ :show-inheritance:
diff --git a/photon-lib/py/docs/source/photonlibpy.networktables.rst b/photon-lib/py/docs/source/photonlibpy.networktables.rst
new file mode 100644
index 000000000..88327af97
--- /dev/null
+++ b/photon-lib/py/docs/source/photonlibpy.networktables.rst
@@ -0,0 +1,21 @@
+photonlibpy.networktables package
+=================================
+
+Submodules
+----------
+
+photonlibpy.networktables.NTTopicSet module
+-------------------------------------------
+
+.. automodule:: photonlibpy.networktables.NTTopicSet
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+Module contents
+---------------
+
+.. automodule:: photonlibpy.networktables
+ :members:
+ :undoc-members:
+ :show-inheritance:
diff --git a/photon-lib/py/docs/source/photonlibpy.rst b/photon-lib/py/docs/source/photonlibpy.rst
new file mode 100644
index 000000000..8d14d1983
--- /dev/null
+++ b/photon-lib/py/docs/source/photonlibpy.rst
@@ -0,0 +1,58 @@
+photonlibpy package
+===================
+
+Subpackages
+-----------
+
+.. toctree::
+ :maxdepth: 4
+
+ photonlibpy.estimation
+ photonlibpy.generated
+ photonlibpy.networktables
+ photonlibpy.simulation
+ photonlibpy.targeting
+ photonlibpy.timesync
+
+Submodules
+----------
+
+photonlibpy.estimatedRobotPose module
+-------------------------------------
+
+.. automodule:: photonlibpy.estimatedRobotPose
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.packet module
+-------------------------
+
+.. automodule:: photonlibpy.packet
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.photonCamera module
+-------------------------------
+
+.. automodule:: photonlibpy.photonCamera
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.photonPoseEstimator module
+--------------------------------------
+
+.. automodule:: photonlibpy.photonPoseEstimator
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+Module contents
+---------------
+
+.. automodule:: photonlibpy
+ :members:
+ :undoc-members:
+ :show-inheritance:
diff --git a/photon-lib/py/docs/source/photonlibpy.simulation.rst b/photon-lib/py/docs/source/photonlibpy.simulation.rst
new file mode 100644
index 000000000..4d691df70
--- /dev/null
+++ b/photon-lib/py/docs/source/photonlibpy.simulation.rst
@@ -0,0 +1,53 @@
+photonlibpy.simulation package
+==============================
+
+Submodules
+----------
+
+photonlibpy.simulation.photonCameraSim module
+---------------------------------------------
+
+.. automodule:: photonlibpy.simulation.photonCameraSim
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.simulation.simCameraProperties module
+-------------------------------------------------
+
+.. automodule:: photonlibpy.simulation.simCameraProperties
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.simulation.videoSimUtil module
+------------------------------------------
+
+.. automodule:: photonlibpy.simulation.videoSimUtil
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.simulation.visionSystemSim module
+---------------------------------------------
+
+.. automodule:: photonlibpy.simulation.visionSystemSim
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.simulation.visionTargetSim module
+---------------------------------------------
+
+.. automodule:: photonlibpy.simulation.visionTargetSim
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+Module contents
+---------------
+
+.. automodule:: photonlibpy.simulation
+ :members:
+ :undoc-members:
+ :show-inheritance:
diff --git a/photon-lib/py/docs/source/photonlibpy.targeting.rst b/photon-lib/py/docs/source/photonlibpy.targeting.rst
new file mode 100644
index 000000000..2619708e1
--- /dev/null
+++ b/photon-lib/py/docs/source/photonlibpy.targeting.rst
@@ -0,0 +1,45 @@
+photonlibpy.targeting package
+=============================
+
+Submodules
+----------
+
+photonlibpy.targeting.TargetCorner module
+-----------------------------------------
+
+.. automodule:: photonlibpy.targeting.TargetCorner
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.targeting.multiTargetPNPResult module
+-------------------------------------------------
+
+.. automodule:: photonlibpy.targeting.multiTargetPNPResult
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.targeting.photonPipelineResult module
+-------------------------------------------------
+
+.. automodule:: photonlibpy.targeting.photonPipelineResult
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+photonlibpy.targeting.photonTrackedTarget module
+------------------------------------------------
+
+.. automodule:: photonlibpy.targeting.photonTrackedTarget
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+Module contents
+---------------
+
+.. automodule:: photonlibpy.targeting
+ :members:
+ :undoc-members:
+ :show-inheritance:
diff --git a/photon-lib/py/docs/source/photonlibpy.timesync.rst b/photon-lib/py/docs/source/photonlibpy.timesync.rst
new file mode 100644
index 000000000..5c111332f
--- /dev/null
+++ b/photon-lib/py/docs/source/photonlibpy.timesync.rst
@@ -0,0 +1,21 @@
+photonlibpy.timesync package
+============================
+
+Submodules
+----------
+
+photonlibpy.timesync.timeSyncServer module
+------------------------------------------
+
+.. automodule:: photonlibpy.timesync.timeSyncServer
+ :members:
+ :undoc-members:
+ :show-inheritance:
+
+Module contents
+---------------
+
+.. automodule:: photonlibpy.timesync
+ :members:
+ :undoc-members:
+ :show-inheritance:
diff --git a/photon-lib/py/docs/stylesheets/extra.css b/photon-lib/py/docs/stylesheets/extra.css
deleted file mode 100644
index 30bbccf68..000000000
--- a/photon-lib/py/docs/stylesheets/extra.css
+++ /dev/null
@@ -1,3 +0,0 @@
-:root > * {
- --md-primary-fg-color: #3498DB;
-}
diff --git a/photon-lib/py/gen_api_docs.py b/photon-lib/py/gen_api_docs.py
deleted file mode 100644
index 4bba82f00..000000000
--- a/photon-lib/py/gen_api_docs.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# gen_api_docs.py
-
-from pathlib import Path
-
-import mkdocs_gen_files
-
-nav = mkdocs_gen_files.Nav()
-
-for path in sorted(Path("photonlibpy").rglob("*.py")):
- if path.name == "py.typed":
- continue
-
- module_path = path.with_suffix("").as_posix().replace("/", ".")
- parts = tuple(path.relative_to("photonlibpy").with_suffix("").parts)
-
- if path.name == "__init__.py":
- continue
- else:
- doc_path = Path("reference", *parts).with_suffix(".md")
-
- nav[parts] = doc_path.as_posix()
-
- with mkdocs_gen_files.open(doc_path, "w") as f:
- f.write(f"# `{module_path}`\n\n::: {module_path}")
-
- mkdocs_gen_files.set_edit_path(doc_path, path)
-
-with mkdocs_gen_files.open("reference/SUMMARY.md", "w") as nav_file:
- nav_file.writelines(nav.build_literate_nav())
diff --git a/photon-lib/py/mkdocs.yml b/photon-lib/py/mkdocs.yml
deleted file mode 100644
index 7e57fa0d3..000000000
--- a/photon-lib/py/mkdocs.yml
+++ /dev/null
@@ -1,40 +0,0 @@
-site_name: PhotonLibPy Docs
-theme:
- name: material
- favicon: docs/favicon.ico # If you want a favicon
- logo: logo.svg # Optional logo
- palette:
- primary: custom
-
-plugins:
- - search:
- - mkdocstrings:
- handlers:
- python:
- options:
- show_source: false
- docstring_style: sphinx
- paths:
- - "."
- - gen-files:
- scripts:
- - gen_api_docs.py
- - literate-nav
- - section-index
- # To exclude files, add them under glob using their
- # path from photonlibpy prepended by reference/
- # Additionally, change the extension from .py to .md
- - exclude:
- glob:
- - "reference/packet.md"
- - "reference/generated/*"
-
-nav:
- - Home: index.md
- - Reference: reference/SUMMARY.md
-
-extra_css:
- - stylesheets/extra.css
-
-extra_javascript:
- - js/exclude-details.js