Merge pull request #4237 from pipecat-ai/mb/docstring-fixes-2026-04-03

Docstring fixes for docs auto-generation
This commit is contained in:
Mark Backman
2026-04-03 11:50:20 -04:00
committed by GitHub
22 changed files with 81 additions and 117 deletions

View File

@@ -1,108 +1,60 @@
# Pipecat Documentation # Pipecat API Documentation
This directory contains the source files for auto-generating Pipecat's server API reference documentation. This directory contains the source files for auto-generating Pipecat's API reference documentation.
## Setup
1. Install documentation dependencies:
```bash
pip install -r requirements.txt
```
2. Make the build scripts executable:
```bash
chmod +x build-docs.sh rtd-test.py
```
## Building Documentation ## Building Documentation
From this directory, you can build the documentation in several ways: From this directory:
### Local Build
```bash ```bash
# Using the build script (automatically opens docs when done) # Build docs (warnings shown but don't fail the build)
./build-docs.sh cd docs/api && uv run ./build-docs.sh
# Or directly with sphinx-build # Build with strict mode (warnings treated as errors)
sphinx-build -b html . _build/html -W --keep-going cd docs/api && uv run ./build-docs.sh --strict
``` ```
### ReadTheDocs Test Build The build script will:
To test the documentation build process exactly as it would run on ReadTheDocs: 1. Install documentation dependencies via `uv sync --group docs`
2. Clean previous build output
```bash 3. Run `sphinx-build` to generate HTML documentation
./rtd-test.py 4. Open the result in your browser (macOS)
```
This script:
- Creates a fresh virtual environment
- Installs all dependencies as specified in requirements files
- Handles conflicting dependencies (like grpcio versions for Riva)
- Builds the documentation in an isolated environment
- Provides detailed logging of the build process
Use this script to verify your documentation will build correctly on ReadTheDocs before pushing changes.
## Viewing Documentation
The built documentation will be available at `_build/html/index.html`. To open:
```bash
# On MacOS
open _build/html/index.html
# On Linux
xdg-open _build/html/index.html
# On Windows
start _build/html/index.html
```
## Directory Structure ## Directory Structure
``` ```
. .
├── api/ # Auto-generated API documentation ├── api/ # Auto-generated API documentation (created during build)
├── _build/ # Built documentation ├── _build/ # Built documentation output
├── _static/ # Static files (images, css, etc.) ├── conf.py # Sphinx configuration (mock imports, extensions, etc.)
├── conf.py # Sphinx configuration
├── index.rst # Main documentation entry point ├── index.rst # Main documentation entry point
├── requirements-base.txt # Base documentation dependencies
├── requirements-riva.txt # Riva-specific dependencies
├── build-docs.sh # Local build script ├── build-docs.sh # Local build script
└── rtd-test.py # ReadTheDocs test build script └── rtd-test.sh # ReadTheDocs test build script (uses pip, not uv)
``` ```
## Notes ## How It Works
- Documentation is auto-generated from Python docstrings - `conf.py` runs `sphinx-apidoc` during Sphinx's `setup()` phase to generate `.rst` files from Python source
- Service modules are automatically detected and included - Sphinx autodoc imports each module to extract docstrings
- The build process matches our ReadTheDocs configuration - Modules with unavailable dependencies are listed in `autodoc_mock_imports` in `conf.py`
- Warnings are treated as errors (-W flag) to maintain consistency - Napoleon extension converts Google-style docstrings to reStructuredText
- The --keep-going flag ensures all errors are reported
- Dependencies are split into multiple requirements files to handle version conflicts
## Troubleshooting ## Troubleshooting
If you encounter missing service modules: **Module not appearing in docs:**
1. Verify the service is installed with its extras: `pip install pipecat-ai[service-name]` 1. Check the build output for `autodoc: failed to import` warnings
2. Check the build logs for import errors 2. If the module has an unresolvable import dependency, add it to `autodoc_mock_imports` in `conf.py`
3. Ensure the service module is properly initialized in the package 3. Verify the module is importable: `uv run python -c "import pipecat.module.name"`
4. Run `./rtd-test.py` to test in an isolated environment matching ReadTheDocs
For dependency conflicts: **Duplicate object warnings:**
1. Check the requirements files for version specifications These come from re-export modules or Sphinx discovering the same class through multiple import paths. Usually cosmetic.
2. Use `rtd-test.py` to verify dependency resolution
3. Consider adding service-specific requirements files if needed
For more information: **Docstring formatting warnings:**
- [ReadTheDocs Configuration](.readthedocs.yaml) Docstrings use reStructuredText, not Markdown. Common issues:
- [Sphinx Documentation](https://www.sphinx-doc.org/) - Use `Example::` with indented code blocks, not `` ```python ``
- Ensure blank lines between directive content and subsequent sections
- Use `Parameters:` (not `Attributes:`) for dataclass field documentation to avoid duplicate entries

View File

@@ -1,5 +1,13 @@
#!/bin/bash #!/bin/bash
# Usage: ./build-docs.sh [--strict]
# --strict: Treat warnings as errors (default: warnings only)
SPHINX_OPTS=""
if [ "$1" = "--strict" ]; then
SPHINX_OPTS="-W --keep-going"
fi
# Build docs using uv # Build docs using uv
echo "Installing dependencies with uv..." echo "Installing dependencies with uv..."
uv sync --group docs --all-extras --no-extra gstreamer --no-extra local_smart_turn --no-extra moondream --no-extra mlx-whisper uv sync --group docs --all-extras --no-extra gstreamer --no-extra local_smart_turn --no-extra moondream --no-extra mlx-whisper
@@ -14,8 +22,7 @@ fi
rm -rf _build rm -rf _build
echo "Building documentation..." echo "Building documentation..."
# Build docs matching ReadTheDocs configuration uv run sphinx-build -b html -d _build/doctrees . _build/html $SPHINX_OPTS
uv run sphinx-build -b html -d _build/doctrees . _build/html -W --keep-going
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
echo "Documentation built successfully!" echo "Documentation built successfully!"

View File

@@ -97,6 +97,8 @@ autodoc_mock_imports = [
"fastapi.middleware", "fastapi.middleware",
"fastapi.responses", "fastapi.responses",
"uvicorn", "uvicorn",
# Deepgram dependencies
"deepgram",
] ]
# HTML output settings # HTML output settings

View File

@@ -40,7 +40,7 @@ class TranscriptHandler:
Maintains a list of conversation messages and outputs them either to a log Maintains a list of conversation messages and outputs them either to a log
or to a file as they are received. Each message includes its timestamp and role. or to a file as they are received. Each message includes its timestamp and role.
Attributes: Parameters:
messages: List of all processed transcript messages messages: List of all processed transcript messages
output_file: Optional path to file where transcript is saved. If None, outputs to log only. output_file: Optional path to file where transcript is saved. If None, outputs to log only.
""" """

View File

@@ -27,7 +27,7 @@ from pipecat.services.xai.realtime import events
class GrokRealtimeLLMInvocationParams(TypedDict): class GrokRealtimeLLMInvocationParams(TypedDict):
"""Context-based parameters for invoking Grok Realtime API. """Context-based parameters for invoking Grok Realtime API.
Attributes: Parameters:
system_instruction: System prompt/instructions for the session. system_instruction: System prompt/instructions for the session.
messages: List of conversation items formatted for Grok Realtime. messages: List of conversation items formatted for Grok Realtime.
tools: List of tool definitions (function, web_search, x_search, file_search). tools: List of tool definitions (function, web_search, x_search, file_search).

View File

@@ -36,7 +36,7 @@ class FrameOrder(Enum):
When multiple parallel pipelines produce output for the same input frame, When multiple parallel pipelines produce output for the same input frame,
this setting determines the order in which those output frames are pushed. this setting determines the order in which those output frames are pushed.
Attributes: Parameters:
ARRIVAL: Frames are pushed in the order they arrive from any pipeline. ARRIVAL: Frames are pushed in the order they arrive from any pipeline.
This is the default and matches the behavior of prior versions. This is the default and matches the behavior of prior versions.
PIPELINE: Frames are pushed in pipeline definition order — all frames PIPELINE: Frames are pushed in pipeline definition order — all frames

View File

@@ -95,8 +95,8 @@ class GenesysAudioHookSerializer(FrameSerializer):
- Text WebSocket frames for JSON control messages - Text WebSocket frames for JSON control messages
- Binary WebSocket frames for audio data - Binary WebSocket frames for audio data
Example usage: Example usage::
```python
serializer = GenesysAudioHookSerializer( serializer = GenesysAudioHookSerializer(
params=GenesysAudioHookSerializer.InputParams( params=GenesysAudioHookSerializer.InputParams(
channel=AudioHookChannel.EXTERNAL, channel=AudioHookChannel.EXTERNAL,
@@ -122,9 +122,8 @@ class GenesysAudioHookSerializer(FrameSerializer):
# Set output variables to return to Architect # Set output variables to return to Architect
serializer.set_output_variables({"intent": "billing", "resolved": True}) serializer.set_output_variables({"intent": "billing", "resolved": True})
```
Attributes: Parameters:
PROTOCOL_VERSION: The AudioHook protocol version (currently "2"). PROTOCOL_VERSION: The AudioHook protocol version (currently "2").
""" """
@@ -133,7 +132,7 @@ class GenesysAudioHookSerializer(FrameSerializer):
class InputParams(FrameSerializer.InputParams): class InputParams(FrameSerializer.InputParams):
"""Configuration parameters for GenesysAudioHookSerializer. """Configuration parameters for GenesysAudioHookSerializer.
Attributes: Parameters:
genesys_sample_rate: Sample rate used by Genesys (default: 8000 Hz). genesys_sample_rate: Sample rate used by Genesys (default: 8000 Hz).
sample_rate: Optional override for pipeline input sample rate. sample_rate: Optional override for pipeline input sample rate.
channel: Which audio channels to process (external, internal, both). channel: Which audio channels to process (external, internal, both).
@@ -246,8 +245,8 @@ class GenesysAudioHookSerializer(FrameSerializer):
Args: Args:
variables: Dictionary of custom variables to send to Genesys. variables: Dictionary of custom variables to send to Genesys.
Example: Example::
```python
# During the conversation, collect data and set it # During the conversation, collect data and set it
serializer.set_output_variables({ serializer.set_output_variables({
"intent": "billing_inquiry", "intent": "billing_inquiry",
@@ -255,7 +254,6 @@ class GenesysAudioHookSerializer(FrameSerializer):
"summary": "Customer asked about their bill", "summary": "Customer asked about their bill",
"transfer_to": "billing_queue" "transfer_to": "billing_queue"
}) })
```
""" """
self._output_variables = variables self._output_variables = variables
logger.debug(f"Output variables set: {variables}") logger.debug(f"Output variables set: {variables}")
@@ -413,8 +411,8 @@ class GenesysAudioHookSerializer(FrameSerializer):
Returns: Returns:
Dictionary of the closed response message. Dictionary of the closed response message.
Example: Example::
```python
# Pass custom data back to Genesys # Pass custom data back to Genesys
serializer.create_closed_response( serializer.create_closed_response(
output_variables={ output_variables={
@@ -423,7 +421,6 @@ class GenesysAudioHookSerializer(FrameSerializer):
"summary": "Customer asked about their bill" "summary": "Customer asked about their bill"
} }
) )
```
""" """
parameters: Optional[Dict[str, Any]] = None parameters: Optional[Dict[str, Any]] = None

View File

@@ -520,8 +520,7 @@ class GoogleTTSSettings(TTSSettings):
speaking_rate: float | None | _NotGiven = field(default_factory=lambda: NOT_GIVEN) speaking_rate: float | None | _NotGiven = field(default_factory=lambda: NOT_GIVEN)
#: .. deprecated:: 0.0.105 #: *Deprecated since 0.0.105:* Use ``GoogleTTSService.Settings`` instead.
#: Use ``GoogleTTSService.Settings`` instead.
GoogleStreamTTSSettings = GoogleTTSSettings GoogleStreamTTSSettings = GoogleTTSSettings

View File

@@ -83,7 +83,7 @@ class HeyGenClient:
1. WebSocket connection for avatar control and audio streaming 1. WebSocket connection for avatar control and audio streaming
2. LiveKit connection for receiving avatar video and audio 2. LiveKit connection for receiving avatar video and audio
Attributes: Parameters:
HEY_GEN_SAMPLE_RATE (int): The required sample rate for HeyGen's audio processing (24000 Hz) HEY_GEN_SAMPLE_RATE (int): The required sample rate for HeyGen's audio processing (24000 Hz)
""" """

View File

@@ -269,7 +269,9 @@ class NvidiaSTTService(STTService):
.. deprecated:: 0.0.104 .. deprecated:: 0.0.104
Model cannot be changed after initialization for NVIDIA Riva streaming STT. Model cannot be changed after initialization for NVIDIA Riva streaming STT.
Set model and function id in the constructor instead, e.g.:: Set model and function id in the constructor instead.
Example::
NvidiaSTTService( NvidiaSTTService(
api_key=..., api_key=...,

View File

@@ -163,7 +163,9 @@ class NvidiaTTSService(TTSService):
.. deprecated:: 0.0.104 .. deprecated:: 0.0.104
Model cannot be changed after initialization for NVIDIA Riva TTS. Model cannot be changed after initialization for NVIDIA Riva TTS.
Set model and function id in the constructor instead, e.g.:: Set model and function id in the constructor instead.
Example::
NvidiaTTSService( NvidiaTTSService(
api_key=..., api_key=...,

View File

@@ -86,7 +86,7 @@ def language_to_sarvam_language(language: Language) -> str:
class ModelConfig: class ModelConfig:
"""Immutable configuration for a Sarvam STT model. """Immutable configuration for a Sarvam STT model.
Attributes: Parameters:
supports_prompt: Whether the model accepts prompt parameter. supports_prompt: Whether the model accepts prompt parameter.
supports_mode: Whether the model accepts mode parameter. supports_mode: Whether the model accepts mode parameter.
supports_language: Whether the model accepts language parameter. supports_language: Whether the model accepts language parameter.

View File

@@ -75,7 +75,7 @@ except ModuleNotFoundError as e:
class SarvamTTSModel(str, Enum): class SarvamTTSModel(str, Enum):
"""Available Sarvam TTS models. """Available Sarvam TTS models.
Attributes: Parameters:
BULBUL_V2: Standard TTS model with pitch/loudness control. BULBUL_V2: Standard TTS model with pitch/loudness control.
- Supports pitch, loudness, pace (0.3-3.0) - Supports pitch, loudness, pace (0.3-3.0)
- Default sample rate: 22050 Hz - Default sample rate: 22050 Hz
@@ -145,7 +145,7 @@ class SarvamTTSSpeakerV3(str, Enum):
class TTSModelConfig: class TTSModelConfig:
"""Immutable configuration for a Sarvam TTS model. """Immutable configuration for a Sarvam TTS model.
Attributes: Parameters:
supports_pitch: Whether the model accepts pitch parameter. supports_pitch: Whether the model accepts pitch parameter.
supports_loudness: Whether the model accepts loudness parameter. supports_loudness: Whether the model accepts loudness parameter.
supports_temperature: Whether the model accepts temperature parameter. supports_temperature: Whether the model accepts temperature parameter.

View File

@@ -67,7 +67,7 @@ from pipecat.utils.time import seconds_to_nanoseconds
class TTSContext: class TTSContext:
"""Context information for a TTS request. """Context information for a TTS request.
Attributes: Parameters:
append_to_context: Whether this TTS output should be appended to the append_to_context: Whether this TTS output should be appended to the
conversation context after it is spoken. conversation context after it is spoken.
push_assistant_aggregation: Whether to push an push_assistant_aggregation: Whether to push an

View File

@@ -168,7 +168,7 @@ class BaseWhisperSTTService(SegmentedSTTService):
include_prob_metrics: If True, enables probability metrics in API response. include_prob_metrics: If True, enables probability metrics in API response.
Each service implements this differently (see child classes). Each service implements this differently (see child classes).
Defaults to False. Defaults to False.
push_empty_transcripts: - If true, allow empty `TranscriptionFrame` frames to be push_empty_transcripts: If true, allow empty `TranscriptionFrame` frames to be
pushed downstream instead of discarding them. This is intended for situations pushed downstream instead of discarding them. This is intended for situations
where VAD fires even though the user did not speak. In these cases, it is where VAD fires even though the user did not speak. In these cases, it is
useful to know that nothing was transcribed so that the agent can resume useful to know that nothing was transcribed so that the agent can resume

View File

@@ -37,7 +37,7 @@ class WhatsAppClient:
events from WhatsApp, and maintains ongoing call state. It supports both events from WhatsApp, and maintains ongoing call state. It supports both
incoming call handling and call termination through the WhatsApp Cloud API. incoming call handling and call termination through the WhatsApp Cloud API.
Attributes: Parameters:
_whatsapp_api: WhatsApp API instance for making API calls _whatsapp_api: WhatsApp API instance for making API calls
_ongoing_calls_map: Dictionary mapping call IDs to WebRTC connections _ongoing_calls_map: Dictionary mapping call IDs to WebRTC connections
_ice_servers: List of ICE servers for WebRTC connections _ice_servers: List of ICE servers for WebRTC connections

View File

@@ -15,7 +15,7 @@ class ProcessFrameResult(Enum):
Controls whether the strategy loop in the controller continues to the Controls whether the strategy loop in the controller continues to the
next strategy or stops early. next strategy or stops early.
Attributes: Parameters:
CONTINUE: Continue to the next strategy in the loop. CONTINUE: Continue to the next strategy in the loop.
STOP: Stop evaluating further strategies for this frame. STOP: Stop evaluating further strategies for this frame.
""" """

View File

@@ -24,7 +24,7 @@ class UserTurnStartedParams:
contextual information about how the user turn should be handled by the user contextual information about how the user turn should be handled by the user
aggregator. aggregator.
Attributes: Parameters:
enable_user_speaking_frames: Whether the user aggregator should emit enable_user_speaking_frames: Whether the user aggregator should emit
frames indicating user speaking state (e.g., user started speaking) frames indicating user speaking state (e.g., user started speaking)
during the bot's turn. This is typically enabled by default, but may during the bot's turn. This is typically enabled by default, but may

View File

@@ -24,7 +24,7 @@ class UserTurnStoppedParams:
contextual information about how the end of user turn should be handled by contextual information about how the end of user turn should be handled by
the user aggregator. the user aggregator.
Attributes: Parameters:
enable_user_speaking_frames: Whether the user aggregator should emit enable_user_speaking_frames: Whether the user aggregator should emit
frames indicating user speaking state (e.g., user stopped speaking). frames indicating user speaking state (e.g., user stopped speaking).
This is typically enabled by default, but may be disabled when another This is typically enabled by default, but may be disabled when another

View File

@@ -147,7 +147,7 @@ Remember: Focus on conversational completeness and how long the user might need.
class UserTurnCompletionConfig: class UserTurnCompletionConfig:
"""Configuration for turn completion behavior. """Configuration for turn completion behavior.
Attributes: Parameters:
instructions: Custom instructions for turn completion. If not provided, instructions: Custom instructions for turn completion. If not provided,
uses default USER_TURN_COMPLETION_INSTRUCTIONS. uses default USER_TURN_COMPLETION_INSTRUCTIONS.
incomplete_short_timeout: Seconds to wait after short incomplete (○) before prompting. incomplete_short_timeout: Seconds to wait after short incomplete (○) before prompting.
@@ -191,9 +191,7 @@ class UserTurnCompletionLLMServiceMixin:
When incomplete timeouts expire, the mixin automatically prompts the LLM When incomplete timeouts expire, the mixin automatically prompts the LLM
with a contextual follow-up message to re-engage the user. with a contextual follow-up message to re-engage the user.
Usage: Usage example::
The LLM service controls when to use turn completion by calling
_push_turn_text instead of push_frame:
# With turn completion: # With turn completion:
if self._filter_incomplete_user_turns: if self._filter_incomplete_user_turns:
@@ -201,7 +199,10 @@ class UserTurnCompletionLLMServiceMixin:
else: else:
await self.push_frame(LLMTextFrame(chunk.text)) await self.push_frame(LLMTextFrame(chunk.text))
The mixin requires that the base class has a `push_frame` method compatible The LLM service controls when to use turn completion by calling
``_push_turn_text`` instead of ``push_frame``.
The mixin requires that the base class has a ``push_frame`` method compatible
with FrameProcessor's signature. with FrameProcessor's signature.
""" """

View File

@@ -57,7 +57,7 @@ class UserTurnStrategies:
start: [VADUserTurnStartStrategy, TranscriptionUserTurnStartStrategy] start: [VADUserTurnStartStrategy, TranscriptionUserTurnStartStrategy]
stop: [TurnAnalyzerUserTurnStopStrategy(LocalSmartTurnAnalyzerV3)] stop: [TurnAnalyzerUserTurnStopStrategy(LocalSmartTurnAnalyzerV3)]
Attributes: Parameters:
start: A list of user turn start strategies used to detect when start: A list of user turn start strategies used to detect when
the user starts speaking. the user starts speaking.
stop: A list of user turn stop strategies used to decide when stop: A list of user turn stop strategies used to decide when

View File

@@ -168,7 +168,9 @@ class LLMContextSummarizationConfig:
.. deprecated:: 0.0.104 .. deprecated:: 0.0.104
Use :class:`LLMAutoContextSummarizationConfig` with a nested Use :class:`LLMAutoContextSummarizationConfig` with a nested
:class:`LLMContextSummaryConfig` instead:: :class:`LLMContextSummaryConfig` instead.
Example::
LLMAutoContextSummarizationConfig( LLMAutoContextSummarizationConfig(
max_context_tokens=8000, max_context_tokens=8000,