Added docs generation

This commit is contained in:
Donkie
2023-04-03 19:25:27 +02:00
parent 6b17a43e17
commit a6f872bf69
5 changed files with 120 additions and 1 deletions

41
.github/workflows/apidocs.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Generate and deploy API documentation
on:
push:
branches: ["master"]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
# Single deploy job since we're just deploying
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.9'
- run: pip install -e .
- run: spoolman_docs
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
path: 'docs/'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2

1
.gitignore vendored
View File

@@ -71,6 +71,7 @@ instance/
# Sphinx documentation # Sphinx documentation
docs/_build/ docs/_build/
docs/
# PyBuilder # PyBuilder
.pybuilder/ .pybuilder/

View File

@@ -5,6 +5,10 @@ version = "0.1.0"
requires-python = ">=3.9" requires-python = ">=3.9"
readme = "README.md" readme = "README.md"
license = {text = "AGPL-3.0-only"} license = {text = "AGPL-3.0-only"}
dynamic = ["dependencies"]
[tool.setuptools.dynamic]
dependencies = {file = ["requirements.txt"]}
[tool.ruff] [tool.ruff]
select = ["ALL"] select = ["ALL"]
@@ -16,3 +20,9 @@ target-version = "py39"
line-length = 120 line-length = 120
target-version = ['py39'] target-version = ['py39']
[build-system]
requires = ["setuptools>=67.0"]
build-backend = "setuptools.build_meta"
[project.scripts]
spoolman_docs = "spoolman.docs:generate_docs"

View File

@@ -12,7 +12,7 @@ from . import filament, models, spool, vendor
# ruff: noqa: D103 # ruff: noqa: D103
app = FastAPI( app = FastAPI(
title="Spoolson REST API v1", title="Spoolman REST API v1",
version="1.0.0", version="1.0.0",
root_path_in_servers=False, root_path_in_servers=False,
responses={404: {"model": models.Message}}, responses={404: {"model": models.Message}},

67
spoolman/docs.py Normal file
View File

@@ -0,0 +1,67 @@
"""Functions for generating documentation."""
from contextlib import suppress
import json
from pathlib import Path
from typing import Any
from fastapi import FastAPI
from fastapi.openapi.utils import get_openapi
from spoolman.api.v1.router import app as v1_app
def generate_openapi(app: FastAPI) -> dict[str, Any]:
"""Generate the OpenAPI document for a specific FastAPI app.
Args:
app (FastAPI): The FastAPI app.
Returns:
dict[str, Any]: The OpenAPI document.
"""
return get_openapi(
title=app.title,
version=app.version,
openapi_version=app.openapi_version,
description=app.description,
routes=app.routes,
contact=app.contact,
license_info=app.license_info,
servers=app.servers,
tags=app.openapi_tags,
terms_of_service=app.terms_of_service,
)
def generate_docs() -> None:
"""Generate documentation for this service in the docs/ directory."""
with suppress(FileExistsError):
Path("docs").mkdir()
spec = json.dumps(generate_openapi(v1_app))
with Path("docs", "index.html").open("w") as f:
f.write(
f"""
<!DOCTYPE html>
<html>
<head>
<title>Spoolson REST API v1 - ReDoc</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
<link rel="shortcut icon" href="https://fastapi.tiangolo.com/img/favicon.png">
<style> body {{margin: 0; padding: 0; }} </style>
</head>
<body>
<div id="redoc-container"></div>
<script src="https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js"> </script>
<script>
var spec = {spec};
Redoc.init(spec, {{}}, document.getElementById("redoc-container"));
</script>
</body>
</html>""",
)