diff --git a/.github/workflows/python-api-docs.yaml b/.github/workflows/python-api-docs.yaml new file mode 100644 index 0000000..560cffe --- /dev/null +++ b/.github/workflows/python-api-docs.yaml @@ -0,0 +1,51 @@ +name: Build Python API Docs + +on: + workflow_dispatch: + +permissions: {} + +jobs: + build-api-docs: + name: "Build bdkpython API docs" + runs-on: ubuntu-24.04 + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + submodules: recursive + persist-credentials: false + fetch-depth: 0 + + - name: "Configure Git safe directory" + run: git config --global --add safe.directory /__w/bdk-python/bdk-python + + - name: "Install Rust 1.84.1" + uses: actions-rs/toolchain@v1 + with: + toolchain: 1.84.1 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: "Generate bdk.py" + env: + PYBIN: ${{ env.pythonLocation }}/bin + run: bash ./scripts/generate-linux.sh + + - name: "Install Sphinx and Theme" + run: pip install sphinx sphinx_rtd_theme + + - name: "Generate python API Documentation" + run: python ./docs/generate_docs.py + + - name: "Build HTML Documentation" + run: python -m sphinx -b html -W --keep-going docs/source docs/_build/html + + - name: "Upload API Docs" + uses: actions/upload-artifact@v4 + with: + name: artifact-bdkpython-api-docs + path: /home/runner/work/bdk-python/bdk-python/docs/_build/html \ No newline at end of file diff --git a/.gitignore b/.gitignore index 41a211e..e31650e 100644 --- a/.gitignore +++ b/.gitignore @@ -63,3 +63,7 @@ build/ testing-setup-py-simple-example.py .localpythonenv/ + +# API docs +api.rst +_build/ diff --git a/README.md b/README.md index 5ffdc79..e57499f 100644 --- a/README.md +++ b/README.md @@ -30,3 +30,14 @@ pip3 install ./dist/bdkpython-.whl --force-reinstall python3 -m unittest --verbose ``` + +## Build HTML API Documentation (Optional) + +6. Generate docs +7. Build HTML Documentation + +```sh +python3 ./docs/generate_docs.py + +python3 -m sphinx -b html -W --keep-going -v docs/source docs/_build/html +``` \ No newline at end of file diff --git a/docs/generate_docs.py b/docs/generate_docs.py new file mode 100644 index 0000000..586d0cb --- /dev/null +++ b/docs/generate_docs.py @@ -0,0 +1,51 @@ +import os +import re +import subprocess +import shutil + +# ---------------- +# Generate API RST +# ---------------- + +# Define the directory where the Python source files are located +src_dir = 'src/bdkpython' +package_root = 'bdkpython' + +# Define the output file for the API documentation +output_file = 'docs/source/api.rst' + +# Regex pattern to match class definitions +class_pattern = re.compile(r'^class ([A-Za-z][A-Za-z0-9_]*)') + +# Store classes with their full module path +public_classes = {} + +for root, _, files in os.walk(src_dir): + for file in files: + if file.endswith('.py'): + module_path = os.path.relpath(os.path.join(root, file), src_dir) + module_path = module_path.replace(os.sep, '.').removesuffix('.py') + full_module = f'{package_root}.{module_path}' + with open(os.path.join(root, file), 'r', encoding='utf-8') as f: + for line in f: + match = class_pattern.match(line) + if match: + class_name = match.group(1) + if not class_name.startswith('_'): + fqcn = f'{full_module}.{class_name}' + public_classes[fqcn] = True + +# Generate the RST content +rst_content = "API Reference\n============\n\n" + +for fqcn in sorted(public_classes.keys()): + rst_content += f".. autoclass:: {fqcn}\n" + rst_content += " :members:\n" + rst_content += " :undoc-members:\n" + rst_content += " :show-inheritance:\n\n" + +# Write the RST content to the output file +with open(output_file, 'w') as f: + f.write(rst_content) + +print(f"API documentation has been generated in {output_file}") \ No newline at end of file diff --git a/docs/source/_static/css/custom.css b/docs/source/_static/css/custom.css new file mode 100644 index 0000000..60a3c7f --- /dev/null +++ b/docs/source/_static/css/custom.css @@ -0,0 +1,8 @@ +/* Remove max-width restriction */ +.wy-nav-content { + max-width: none !important; +} + +.wy-menu-vertical a { + font-size: 1.1em !important; +} diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..58da6d3 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,50 @@ +# 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 + +import os +import sys +sys.path.insert(0, os.path.abspath('../../src')) + + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'bdkpython' +copyright = '2025, Bitcoin Dev Kit Developers' +author = 'Bitcoin Dev Kit Developers' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.viewcode', + 'sphinx_rtd_theme', +] + +templates_path = ['_templates'] +exclude_patterns = [] + +# Suppress docstring formatting warnings due to uniffi bindings +suppress_warnings = [ + 'docutils' +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'sphinx_rtd_theme' +html_static_path = ['_static'] + +# Register custom CSS +html_css_files = [ + 'css/custom.css', +] + +def setup(app): + app.add_css_file('css/custom.css') \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..9f2c512 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,15 @@ +Welcome to bdkpython's documentation! +===================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + api + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/justfile b/justfile index b13817f..f03627b 100644 --- a/justfile +++ b/justfile @@ -26,6 +26,11 @@ build: install: pip3 install dist/bdkpython-*.whl --force-reinstall +[group("Build")] +[doc("Build Sphinx api documentation.")] +api-docs: + python3 -m sphinx -b html -W --keep-going -v docs/source docs/_build/html + [group("Submodule")] [doc("Initialize bdk-ffi submodule to committed hash.")] submodule-init: diff --git a/requirements-dev.txt b/requirements-dev.txt index b95a8a8..0714a87 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,2 +1,4 @@ pytest==7.1.2 tox==3.25.1 +sphinx +sphinx_rtd_theme