Skip to content

Commit 5ea4ee5

Browse files
committed
docs: update documentation generation scripts and dependencies
1 parent cc8416b commit 5ea4ee5

File tree

5 files changed

+259
-802
lines changed

5 files changed

+259
-802
lines changed

.github/workflows/docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525

2626
- name: Generate API documentation
2727
working-directory: sdk
28-
run: uv run pydoc-markdown
28+
run: uv run python scripts/generate_docs.py
2929

3030
- name: Checkout docs
3131
uses: actions/checkout@v4

pyproject.toml

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -55,27 +55,11 @@ asyncio_mode = "auto"
5555

5656
[dependency-groups]
5757
dev = [
58+
"griffe2md>=1.2.5",
5859
"mypy>=1.14.1",
59-
"pydoc-markdown>=4.8.2",
6060
"pytest>=8.3.5",
6161
"pytest-asyncio>=0.24.0",
6262
"pytest-cov>=5.0.0",
6363
"python-dotenv>=1.0.1",
6464
"ruff>=0.14.3",
6565
]
66-
67-
[[tool.pydoc-markdown.loaders]]
68-
type = "python"
69-
packages = ["fishaudio", "fish_audio_sdk"]
70-
71-
[tool.pydoc-markdown.renderer]
72-
type = "mkdocs"
73-
pages = [
74-
{title = "Fish Audio SDK", name="index", source = "README.md"},
75-
{title = "Client", name="fishaudio/client", contents = ["fishaudio.client.*"] },
76-
{title = "Resources", name="fishaudio/resources", contents = ["fishaudio.resources.*"] },
77-
{title = "Types", name="fishaudio/types", contents = ["fishaudio.types.*"] },
78-
{title = "Core", name="fishaudio/core", contents = ["fishaudio.core.*"] },
79-
{title = "Utils", name="fishaudio/utils", contents = ["fishaudio.utils.*"] },
80-
{title = "Exceptions", name="fishaudio/exceptions", contents = ["fishaudio.exceptions.*"] },
81-
]

scripts/copy_docs.py

Lines changed: 31 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -1,182 +1,50 @@
11
#!/usr/bin/env python3
2-
"""
3-
Script to copy generated documentation files to the docs repository.
2+
"""Copy generated docs to Mintlify repo with frontmatter."""
43

5-
Usage:
6-
python scripts/copy_docs.py <sdk_root> <docs_root>
7-
8-
Example:
9-
python scripts/copy_docs.py . ../docs
10-
python scripts/copy_docs.py sdk docs # In CI context
11-
"""
12-
13-
import argparse
14-
import shutil
4+
import sys
155
from pathlib import Path
16-
from typing import Callable
176

187

198
def add_frontmatter(content: str, title: str, description: str, icon: str) -> str:
20-
"""
21-
Add Mintlify frontmatter to markdown content.
22-
23-
Args:
24-
content: Original markdown content
25-
title: Page title
26-
description: Page description
27-
icon: Icon name
28-
29-
Returns:
30-
Content with frontmatter prepended
31-
"""
32-
frontmatter = f"""---
9+
"""Add Mintlify frontmatter to markdown content."""
10+
return f"""---
3311
title: "{title}"
3412
description: "{description}"
3513
icon: "{icon}"
3614
---
3715
38-
"""
39-
return frontmatter + content
40-
41-
42-
def copy_file_with_extension_change(
43-
source: Path, dest_dir: Path, new_extension: str = ".mdx"
44-
) -> None:
45-
"""
46-
Copy a single file to destination directory with extension change.
47-
48-
Args:
49-
source: Source file path
50-
dest_dir: Destination directory
51-
new_extension: New file extension (default: .mdx)
52-
"""
53-
if not source.exists():
54-
print(f"Warning: {source} does not exist")
55-
return
56-
57-
dest = dest_dir / source.with_suffix(new_extension).name
58-
shutil.copy2(source, dest)
59-
print(f" ✓ {source.name} -> {dest.name}")
60-
61-
62-
def copy_files_from_directory(
63-
source_dir: Path, dest_dir: Path, pattern: str = "*.md", new_extension: str = ".mdx"
64-
) -> None:
65-
"""
66-
Copy all files matching pattern from source directory to destination with extension change.
67-
68-
Args:
69-
source_dir: Source directory
70-
dest_dir: Destination directory
71-
pattern: File pattern to match (default: *.md)
72-
new_extension: New file extension (default: .mdx)
73-
"""
74-
if not source_dir.exists():
75-
print(f"Warning: {source_dir} does not exist")
76-
return
77-
78-
print(f"Copying files from {source_dir} to {dest_dir}")
79-
for file in source_dir.glob(pattern):
80-
dest = dest_dir / file.with_suffix(new_extension).name
81-
shutil.copy2(file, dest)
82-
print(f" ✓ {file.name} -> {dest.name}")
83-
84-
85-
def copy_file_with_transformation(
86-
source: Path,
87-
dest_dir: Path,
88-
transform_fn: Callable[[str], str],
89-
new_extension: str = ".mdx",
90-
dest_filename: str | None = None,
91-
) -> None:
92-
"""
93-
Copy a file with content transformation.
94-
95-
Args:
96-
source: Source file path
97-
dest_dir: Destination directory
98-
transform_fn: Function to transform file content
99-
new_extension: New file extension (default: .mdx)
100-
dest_filename: Optional custom destination filename (without extension)
101-
"""
102-
if not source.exists():
103-
print(f"Warning: {source} does not exist")
104-
return
105-
106-
if dest_filename:
107-
dest = dest_dir / f"{dest_filename}{new_extension}"
108-
else:
109-
dest = dest_dir / source.with_suffix(new_extension).name
16+
{content}"""
11017

111-
content = source.read_text(encoding="utf-8")
112-
transformed_content = transform_fn(content)
113-
dest.write_text(transformed_content, encoding="utf-8")
114-
print(f" ✓ {source.name} -> {dest.name} (transformed)")
11518

116-
117-
def copy_docs(sdk_root: Path, docs_root: Path) -> None:
118-
"""
119-
Copy generated documentation files to the docs repository.
120-
121-
Args:
122-
sdk_root: Root directory of the fish-audio-python SDK
123-
docs_root: Root directory of the docs repository
124-
"""
125-
# Source paths
19+
def main():
20+
sdk_root, docs_root = Path(sys.argv[1]), Path(sys.argv[2])
12621
build_dir = sdk_root / "build" / "docs" / "content"
127-
fishaudio_dir = build_dir / "fishaudio"
128-
index_file = build_dir / "index.md"
129-
130-
# Destination path (flat structure - all files go to the same directory)
131-
python_sdk_dir = docs_root / "api-reference" / "sdk" / "python"
132-
133-
# Create destination directory
134-
python_sdk_dir.mkdir(parents=True, exist_ok=True)
135-
136-
# Copy fishaudio module reference files
137-
copy_files_from_directory(fishaudio_dir, python_sdk_dir)
138-
139-
# Copy index.md to python directory as overview.mdx with frontmatter
140-
copy_file_with_transformation(
141-
index_file,
142-
python_sdk_dir,
143-
lambda content: add_frontmatter(
144-
content,
145-
title="Python SDK",
146-
description="Fish Audio Python SDK for text-to-speech and voice cloning",
147-
icon="python",
148-
),
149-
dest_filename="overview",
22+
dest_dir = docs_root / "api-reference" / "sdk" / "python"
23+
dest_dir.mkdir(parents=True, exist_ok=True)
24+
25+
# Copy API reference with frontmatter
26+
api_ref = build_dir / "api-reference.md"
27+
(dest_dir / "api-reference.mdx").write_text(
28+
add_frontmatter(
29+
api_ref.read_text(),
30+
"API Reference",
31+
"Complete API reference for Fish Audio Python SDK",
32+
"code",
33+
)
15034
)
151-
152-
print("\nDocumentation copy completed successfully!")
153-
154-
155-
def main() -> None:
156-
parser = argparse.ArgumentParser(
157-
description="Copy generated documentation files to the docs repository"
158-
)
159-
parser.add_argument(
160-
"sdk_root",
161-
type=Path,
162-
help="Root directory of the fish-audio-python SDK",
35+
print("Copied api-reference.md -> api-reference.mdx")
36+
37+
# Copy overview with frontmatter
38+
index = build_dir / "index.md"
39+
(dest_dir / "overview.mdx").write_text(
40+
add_frontmatter(
41+
index.read_text(),
42+
"Python SDK",
43+
"Fish Audio Python SDK for text-to-speech and voice cloning",
44+
"python",
45+
)
16346
)
164-
parser.add_argument(
165-
"docs_root",
166-
type=Path,
167-
help="Root directory of the docs repository",
168-
)
169-
170-
args = parser.parse_args()
171-
172-
# Validate paths
173-
if not args.sdk_root.exists():
174-
parser.error(f"SDK root directory does not exist: {args.sdk_root}")
175-
176-
if not args.docs_root.exists():
177-
parser.error(f"Docs root directory does not exist: {args.docs_root}")
178-
179-
copy_docs(args.sdk_root, args.docs_root)
47+
print("Copied index.md -> overview.mdx")
18048

18149

18250
if __name__ == "__main__":

scripts/generate_docs.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Generate API documentation using griffe2md.
4+
5+
This script generates markdown documentation for the Fish Audio Python SDK
6+
and outputs it to build/docs/content/ for copying to the docs repository.
7+
"""
8+
9+
import shutil
10+
import subprocess
11+
from pathlib import Path
12+
13+
14+
def main():
15+
# Paths
16+
project_root = Path(__file__).parent.parent
17+
build_dir = project_root / "build" / "docs" / "content"
18+
19+
# Clean and create build directory
20+
if build_dir.exists():
21+
shutil.rmtree(build_dir)
22+
build_dir.mkdir(parents=True, exist_ok=True)
23+
24+
print("Generating API documentation with griffe2md...")
25+
26+
# Generate single API reference file for entire fishaudio package
27+
output_path = build_dir / "api-reference.md"
28+
print(" Generating fishaudio package -> api-reference.md")
29+
30+
try:
31+
result = subprocess.run(
32+
[
33+
"uv",
34+
"run",
35+
"griffe2md",
36+
"fishaudio",
37+
"-o",
38+
str(output_path),
39+
],
40+
check=True,
41+
cwd=project_root,
42+
capture_output=True,
43+
text=True,
44+
)
45+
print(f"Generated api-reference.md ({output_path.stat().st_size} bytes)")
46+
if result.stderr:
47+
print(f"Warnings:\n{result.stderr}")
48+
except subprocess.CalledProcessError as e:
49+
print("Failed to generate api-reference.md")
50+
print(f"Error: {e.stderr}")
51+
raise
52+
53+
# Copy README as index.md
54+
readme_path = project_root / "README.md"
55+
index_path = build_dir / "index.md"
56+
if readme_path.exists():
57+
shutil.copy2(readme_path, index_path)
58+
print("Copied README.md -> index.md")
59+
60+
print("\nDocumentation generation completed!")
61+
print(f"Output directory: {build_dir}")
62+
63+
64+
if __name__ == "__main__":
65+
main()

0 commit comments

Comments
 (0)