[Django + GitHub Actions] 使用pdoc将文档上传到GitHub Pages!

总结

使用pdoc可以将用Python编写的源代码进行文档化。
此外,还可以使用GitHub Actions和GitHub Pages将文档作为网站发布到存储库中。
这次将从使用pdoc将Django项目内的测试代码输出为单元测试规范书,到使用GitHub Actions发布规范书的方法进行解释。
虽然量比较大且内容稍微有难度,但让我们一起努力吧。

首先

    • 今回のプロジェクトではPoetryとPostgresを使用

 

    • Pythonのバージョンは3.11を使用

 

    • テストフレームワークはPytestを使用

 

    • テストコードを作成済みおよびdocstringを記載済み

 

    Djangoのプロジェクトを作成済み

文件架构

文件结构如下所示:
本次将在application文件夹中存储Django项目。
Django项目的名称为project,应用程序名称为application。

tree
・
├── .github
│   └── workflows
│       └── docs.yml
├── .gitignore
└── application
    ├── application
    │   ├── __init__.py
    │   ├── admin.py
    │   ├── apps.py
    │   ├── migrations
    │   ├── models.py
    │   ├── tests
    │   ├── urls.py
    │   └── views.py
    ├── manage.py
    ├── poetry.lock
    ├── project
    │   ├── __init__.py
    │   ├── asgi.py
    │   ├── settings.py
    │   ├── urls
    │   └── wsgi.py
    └── pyproject.toml

这个文件我们将制作

本次要制作的文件如下所示。

    • application/pyproject.toml

 

    • application/application/__init__.py

 

    • .gitignore

 

    .github/workflow/docs.yml

应用程序/ pyproject.toml

创建 pyproject.toml 文件
这次

    • Python

 

    • Django

 

    • Postgres

 

    • Pytest

 

    Pdoc

安装包。

[tool.poetry]
name = "api"
version = "0.1.0"
description = "api"
authors = ["shun198"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.11"
Django = "^4.1.2"
psycopg2 = "^2.9.6"

[tool.poetry.group.dev.dependencies]
pytest = "^7.1.3"
pytest-django = "^4.5.2"
pdoc = "^13.0.0"

如果您想详细了解Poetry的使用方法,请参考以下文章。

 

为什么无法在Django上运行pdoc?

当您需要生成Pdoc文档时,请执行以下命令。

poetry run pdoc -o docs application/tests

我认为,当你运行此命令时,原本应该将位于application/tests文件夹内的所有源代码以HTML格式输出到docs文件夹,但是估计会遇到以下错误输出。

  File "/root/.cache/pypoetry/virtualenvs/api-MATOk_fk-py3.11/lib/python3.11/site-packages/django/apps/registry.py", line 260, in get_containing_app_config
    self.check_apps_ready()
  File "/root/.cache/pypoetry/virtualenvs/api-MATOk_fk-py3.11/lib/python3.11/site-packages/django/apps/registry.py", line 138, in check_apps_ready
    raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

只需一个方式,原文是這樣的:当执行pdoc时,在内部启动Django并输出结果。但是,这次在输出tests文件夹内的源代码时并没有启动Django。

Apps aren't loaded yet

可能是表示在屏幕上

对于想更了解尚未加载的应用的人士

运行Django时,会执行asgi.py(或wsgi.py)中的内容。

"""
ASGI config for project project.

It exposes the ASGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/
"""

import os

from django.core.asgi import get_asgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")

application = get_asgi_application()

之后将调用get_asgi_application()

import django
from django.core.handlers.asgi import ASGIHandler


def get_asgi_application():
    """
    The public interface to Django's ASGI support. Return an ASGI 3 callable.

    Avoids making django.core.handlers.ASGIHandler a public API, in case the
    internal implementation changes or moves in the future.
    """
    django.setup(set_prefix=False)
    return ASGIHandler()

setup() function is called in Django.

    • apps

 

    settings

只有当导入了Django所需的包时,才会导入setup()方法。如果没有setup()方法,将无法导入apps或settings。

Apps aren't loaded yet

出现这个错误是因为这个原因。

from django.utils.version import get_version

VERSION = (4, 0, 6, "final", 0)

__version__ = get_version(VERSION)


def setup(set_prefix=True):
    """
    Configure the settings (this happens as a side effect of accessing the
    first setting), configure logging and populate the app registry.
    Set the thread-local urlresolvers script prefix if `set_prefix` is True.
    """
    from django.apps import apps
    from django.conf import settings
    from django.urls import set_script_prefix
    from django.utils.log import configure_logging

    configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
    if set_prefix:
        set_script_prefix(
            "/" if settings.FORCE_SCRIPT_NAME is None else settings.FORCE_SCRIPT_NAME
        )
    apps.populate(settings.INSTALLED_APPS)

换句话说,当执行pdoc时,必须先执行setup方法。

处理方法

在执行django.setup()之前,可以在想要输出的文件夹(例如application/tests)的__init__.py文件中添加django.setup()。由于django.setup()也会在项目内执行,因此如果尝试启动Django,可能会发生与django.setup()冲突无法启动的情况。因此,我们可以通过判断是否存在名为CI_MAKING_DOCS的环境变量来避免冲突。

import os

if os.environ.get("CI_MAKING_DOCS") is not None:
    """テスト仕様書をpdocで出力するためにdjango.setupを実施する"""
    import django

    django.setup()

执行pdoc的命令

通过将值传递给名为CI_MAKING_DOCS的环境变量,在Poetry运行时,将执行django.setup()。

CI_MAKING_DOCS=1 poetry run pdoc -o docs application/tests/

如果您使用docker-compose,请执行以下命令。

docker-compose exec app env CI_MAKING_DOCS=1 poetry run pdoc -o docs application/tests/

如果创建了一个名为“docs”的文件夹,那就是成功了。

スクリーンショット 2023-06-10 11.49.13.png

.gitignore 文件

将docs文件夹添加到.gitignore中,因为不需要对其进行版本控制。

docs/

GitHub Pages的设置

在创建工作流之前,我们需要进行GitHub Pages的设置。在打开”设置”页面后,将”源”设为”GitHub Actions”。

スクリーンショット 2023-06-10 14.42.18.png

创建工作流程 (Create a workflow)

接下来,我将解释如何创建一个工作流,将通过pdoc导出的文档上传到GitHub Pages。这里的工作流是根据pdoc官方提供的工作流进行创建的,但由于使用了Poetry等稍有不同之处,我将进行解释说明。

 

name: GitHub Pages
on:
  push:
    branches:
      - develop

# security: restrict permissions for CI jobs.
permissions:
  contents: read

env:
  SECRET_KEY: test
  DJANGO_SETTINGS_MODULE: project.settings
  ALLOWED_HOSTS: 127.0.0.1
  POSTGRES_NAME: test
  POSTGRES_USER: test
  POSTGRES_PASSWORD: test
  POSTGRES_HOST: 127.0.0.1
  POSTGRES_PORT: 5432
  CI_MAKING_DOCS: 1

jobs:
  # Build the documentation and upload the static HTML files as an artifact.
  build:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: application
    steps:
      - name: Chekcout code
        uses: actions/checkout@v3
      - name: Install poetry
        run: pipx install poetry
      - name: Use cache dependencies
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'
          cache: 'poetry'
      - name: Install Packages
        run: poetry install
      - name: Create documentation
        run: poetry run pdoc -o docs application/tests/
      - name: Upload Documents
        uses: actions/upload-pages-artifact@v1
        with:
          # 絶対パスを指定
          path: application/docs/

  # Deploy the artifact to GitHub pages.
  # This is a separate job so that only actions/deploy-pages has the necessary permissions.
  deploy:
    needs: build
    runs-on: ubuntu-latest
    permissions:
      pages: write
      id-token: write
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - id: deployment
        uses: actions/deploy-pages@v2

在执行时指定分支

我們將確保在本次開發分支和功能分支合併或推送到develop分支時,工作流程將被執行。

name: GitHub Pages
on:
  push:
    branches:
      - develop

环境变量

由于这次我正在使用Postgres,所以在使用数据库时,请指定数据库的环境变量。
还请指定启动Django所需的环境变量,包括SECRET_KEY。
在使用pdoc时,也需要提供CI_MAKING_DOCS环境变量。

env:
  SECRET_KEY: test
  DJANGO_SETTINGS_MODULE: project.settings
  ALLOWED_HOSTS: 127.0.0.1
  POSTGRES_NAME: test
  POSTGRES_USER: test
  POSTGRES_PASSWORD: test
  POSTGRES_HOST: 127.0.0.1
  POSTGRES_PORT: 5432
  CI_MAKING_DOCS: 1

使用诗歌实施的PDOC执行

如果你想要了解有关Poetry缓存的使用方法以及其他详细信息,请参考以下文章,因为这次我们使用了Poetry来实现安装的加速,并利用Poetry的设置和缓存来加快第二次及以后的安装速度。

 

此外,在使用actions/upload-pages-artifact@v1时,请将docs文件夹的路径设置为绝对路径。通过使用官方提供的这个action,docs文件夹中的文件将被保存为artifact在GitHub Actions内,并且可以上传到GitHub Pages。

jobs:
  # Build the documentation and upload the static HTML files as an artifact.
  build:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: application
    steps:
      - name: Chekcout code
        uses: actions/checkout@v3
      - name: Install poetry
        run: pipx install poetry
      - name: Use cache dependencies
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'
          cache: 'poetry'
      - name: Install Packages
        run: poetry install
      - name: Create documentation
        run: poetry run pdoc -o docs application/tests/
      - name: Upload Documents
        uses: actions/upload-pages-artifact@v1
        with:
          # 絶対パスを指定
          path: application/docs/

让我们来执行工作流程吧!

如果直接将更改提交到develop分支,或者将PR合并到develop分支,工作流程将被执行。

如果能够创建名为GitHub Pages的构件并成功地在链接上进行转移并查看,则表示成功。

スクリーンショット 2023-06-10 12.13.06.png
スクリーンショット 2023-06-10 12.14.52.png

总结

由于找不到使用Django和pdoc将文档上传到GitHub Pages的文章,而且还遇到了从未见过的错误消息,起初不知道该怎么办,所以我写了这篇文章。如果你理解了原理,就能轻松地创建,希望你能尝试一下。

请提供更多上下文。

 

bannerAds