FastHTML Reader View component for verifying transcript segmentation with audio playback and context graph commit.
Project description
cjm-transcript-review
Install
pip install cjm_transcript_review
Project Structure
nbs/
├── components/ (7)
│ ├── audio_controls.ipynb # Audio playback controls: speed selector and auto-navigate toggle
│ ├── callbacks.ipynb # Focus change callback and audio playback JavaScript for the review card stack
│ ├── card_stack_config.ipynb # Card stack configuration, HTML IDs, and button IDs for the review card stack
│ ├── helpers.ipynb # State getters for the review step from InteractionContext
│ ├── keyboard_config.ipynb # Review-specific keyboard building blocks for assembly into a KeyboardManager
│ ├── review_card.ipynb # Review card component showing assembled segment with timing and source info
│ └── step_renderer.ipynb # Composable render functions for the review card stack step
├── routes/ (5)
│ ├── audio.ipynb # Route handlers for audio playback controls
│ ├── card_stack.ipynb # Card stack UI operations — navigation, viewport, and response builders
│ ├── commit.ipynb # Route handler for committing the document to the context graph
│ ├── core.ipynb # Review step state management helpers
│ └── init.ipynb # Router assembly for Phase 3 review routes
├── services/ (1)
│ └── graph.ipynb # Graph service for committing documents and segments to the context graph
├── html_ids.ipynb # HTML ID constants for Phase 3: Review & Commit
├── models.ipynb # Review step state and working document model for Phase 3: Review & Commit
└── utils.ipynb # Time formatting and source info display utilities for review cards
Total: 16 notebooks across 3 directories
Module Dependencies
graph LR
components_audio_controls[components.audio_controls<br/>audio_controls]
components_callbacks[components.callbacks<br/>callbacks]
components_card_stack_config[components.card_stack_config<br/>card_stack_config]
components_helpers[components.helpers<br/>helpers]
components_keyboard_config[components.keyboard_config<br/>keyboard_config]
components_review_card[components.review_card<br/>review_card]
components_step_renderer[components.step_renderer<br/>step_renderer]
html_ids[html_ids<br/>html_ids]
models[models<br/>models]
routes_audio[routes.audio<br/>audio]
routes_card_stack[routes.card_stack<br/>card_stack]
routes_commit[routes.commit<br/>commit]
routes_core[routes.core<br/>core]
routes_init[routes.init<br/>init]
services_graph[services.graph<br/>graph]
utils[utils<br/>utils]
components_callbacks --> components_audio_controls
components_helpers --> models
components_review_card --> utils
components_review_card --> html_ids
components_step_renderer --> components_card_stack_config
components_step_renderer --> models
components_step_renderer --> components_callbacks
components_step_renderer --> components_keyboard_config
components_step_renderer --> components_review_card
components_step_renderer --> components_audio_controls
components_step_renderer --> html_ids
routes_audio --> routes_core
routes_audio --> models
routes_card_stack --> components_card_stack_config
routes_card_stack --> models
routes_card_stack --> routes_core
routes_card_stack --> components_step_renderer
routes_card_stack --> components_review_card
routes_commit --> models
routes_commit --> utils
routes_commit --> routes_core
routes_commit --> services_graph
routes_core --> models
routes_core --> components_review_card
routes_init --> services_graph
routes_init --> routes_audio
routes_init --> routes_core
routes_init --> routes_card_stack
routes_init --> models
routes_init --> routes_commit
30 cross-module dependencies detected
CLI Reference
No CLI commands found in this project.
Module Overview
Detailed documentation for each module in the project:
audio (audio.ipynb)
Route handlers for audio playback controls
Import
from cjm_transcript_review.routes.audio import (
DEBUG_AUDIO_ROUTES,
init_audio_router
)
Functions
def _generate_speed_change_js(
speed:float # New playback speed
) -> str: # JavaScript to update playback rate
"Generate JS to update Web Audio API playback rate via shared library."
def _generate_auto_nav_js(
enabled:bool # Whether auto-navigate is enabled
) -> str: # JavaScript to update auto-navigate flag
"Generate JS to update auto-navigate flag via shared library."
def _generate_replay_js() -> str: # JavaScript to replay current segment
"Generate JS to replay the current segment's audio."
def init_audio_router(
state_store:WorkflowStateStore, # The workflow state store
workflow_id:str, # The workflow identifier
prefix:str, # Base prefix for audio routes
urls:ReviewUrls, # URL bundle to populate
) -> Tuple[APIRouter, Dict[str, Callable]]: # (router, routes dict)
"Initialize audio control routes."
Variables
DEBUG_AUDIO_ROUTES = False
audio_controls (audio_controls.ipynb)
Audio playback controls: speed selector and auto-navigate toggle
Import
from cjm_transcript_review.components.audio_controls import (
PLAYBACK_SPEEDS,
AudioControlIds,
render_speed_selector,
render_auto_navigate_toggle,
render_audio_controls
)
Functions
def render_speed_selector(
current_speed:float=1.0, # Current playback speed
change_url:str="", # URL to POST speed changes to
) -> Any: # Speed selector component
"Render playback speed selector dropdown."
def _toggle_color_js(toggle_id:str) -> str: # JS snippet to sync toggle color classes
"""Generate JS to swap bg-error/bg-success on the toggle based on checked state."""
return (
f"var _t=document.getElementById('{toggle_id}');"
f"if(_t){{_t.classList.remove('{_TOGGLE_BG_OFF}','{_TOGGLE_BG_ON}');"
f"_t.classList.add(_t.checked?'{_TOGGLE_BG_ON}':'{_TOGGLE_BG_OFF}');}}"
)
def render_auto_navigate_toggle(
enabled:bool=False, # Whether auto-navigate is enabled
) -> Any: # Auto-navigate toggle component
"Generate JS to swap bg-error/bg-success on the toggle based on checked state."
def render_auto_navigate_toggle(
enabled:bool=False, # Whether auto-navigate is enabled
) -> Any: # Auto-navigate toggle component
"Render auto-navigate toggle switch (client-side only, no server persistence)."
def render_audio_controls(
current_speed:float=1.0, # Current playback speed
auto_navigate:bool=False, # Whether auto-navigate is enabled
speed_url:str="", # URL for speed changes
oob:bool=False, # Whether to render as OOB swap
) -> Any: # Combined audio controls component
"Render combined audio controls (speed selector + auto-navigate toggle)."
Classes
class AudioControlIds:
"HTML ID constants for audio control elements."
Variables
PLAYBACK_SPEEDS: List[tuple]
_TOGGLE_BG_OFF # Red when auto-play disabled
_TOGGLE_BG_ON # Green when auto-play enabled
callbacks (callbacks.ipynb)
Focus change callback and audio playback JavaScript for the review card stack
Import
from cjm_transcript_review.components.callbacks import (
REVIEW_AUDIO_CONFIG,
generate_review_callbacks_script
)
Functions
def _generate_toggle_auto_play_js() -> str: # JS defining window.toggleReviewAutoPlay
"Generate JS for the A key auto-play toggle function."
def generate_review_callbacks_script(
ids:CardStackHtmlIds, # Card stack HTML IDs
button_ids:CardStackButtonIds, # Card stack button IDs
config:CardStackConfig, # Card stack configuration
urls:CardStackUrls, # Card stack URL bundle
container_id:str, # ID of the review container (parent of card stack)
focus_input_id:str, # ID of hidden input for focused segment index
) -> any: # Script element with all JavaScript callbacks
"Generate JavaScript for review card stack with Web Audio API audition."
Variables
REVIEW_AUDIO_CONFIG
card_stack (card_stack.ipynb)
Card stack UI operations — navigation, viewport, and response builders
Import
from cjm_transcript_review.routes.card_stack import (
init_card_stack_router
)
Functions
def _build_slots_oob(
assembled:List[AssembledSegment], # Assembled segments with VAD chunks
state:CardStackState, # Card stack viewport state
urls:ReviewUrls, # URL bundle
) -> List[Any]: # OOB slot elements
"Build OOB slot updates for the viewport sections."
def _build_nav_response(
assembled:List[AssembledSegment], # Assembled segments with VAD chunks
state:CardStackState, # Card stack viewport state
urls:ReviewUrls, # URL bundle
) -> Tuple: # OOB elements (slots + progress + focus)
"Build OOB response for navigation."
def _handle_review_navigate(
state_store:WorkflowStateStore, # The workflow state store
workflow_id:str, # The workflow identifier
sess, # FastHTML session object
direction:str, # Navigation direction: "up", "down", "first", "last", "page_up", "page_down"
urls:ReviewUrls, # URL bundle for review routes
): # OOB slot updates with progress, focus, and source position
"Navigate to a different segment in the viewport using OOB slot swaps."
def _handle_review_navigate_to_index(
state_store:WorkflowStateStore, # The workflow state store
workflow_id:str, # The workflow identifier
sess, # FastHTML session object
target_index:int, # Target item index to navigate to
urls:ReviewUrls, # URL bundle for review routes
): # OOB slot updates with progress, focus, and source position
"Navigate to a specific segment index using OOB slot swaps."
async def _handle_review_update_viewport(
state_store:WorkflowStateStore, # The workflow state store
workflow_id:str, # The workflow identifier
request, # FastHTML request object
sess, # FastHTML session object
visible_count:int, # New number of visible cards
urls:ReviewUrls, # URL bundle for review routes
): # Full viewport component (outerHTML swap)
"Update the viewport with a new card count."
def _handle_review_save_width(
state_store:WorkflowStateStore, # The workflow state store
workflow_id:str, # The workflow identifier
sess, # FastHTML session object
card_width:int, # Card stack width in rem
) -> None: # No response body (swap=none on client)
"Save the card stack width to server state."
def init_card_stack_router(
state_store:WorkflowStateStore, # The workflow state store
workflow_id:str, # The workflow identifier
prefix:str, # Route prefix (e.g., "/workflow/review/card_stack")
urls:ReviewUrls, # URL bundle (populated after routes defined)
) -> Tuple[APIRouter, Dict[str, Callable]]: # (router, route_dict)
"Initialize card stack routes for review."
card_stack_config (card_stack_config.ipynb)
Card stack configuration, HTML IDs, and button IDs for the review card stack
Import
from cjm_transcript_review.components.card_stack_config import (
REVIEW_CS_CONFIG,
REVIEW_CS_IDS,
REVIEW_CS_BTN_IDS
)
Variables
REVIEW_CS_CONFIG
REVIEW_CS_IDS
REVIEW_CS_BTN_IDS
commit (commit.ipynb)
Route handler for committing the document to the context graph
Import
from cjm_transcript_review.routes.commit import (
DEBUG_COMMIT_ROUTES,
COMMIT_ALERT_ID,
CommitResult,
init_commit_router
)
Functions
def _render_commit_alert(
result:CommitResult, # Commit operation result
auto_dismiss_ms:int=5000, # Auto-dismiss after milliseconds (0 = no auto-dismiss)
) -> Div: # Alert element with optional auto-dismiss script
"Render a success or error alert for commit result."
async def _handle_commit(
state_store:WorkflowStateStore, # The workflow state store
workflow_id:str, # The workflow identifier
session_id:str, # Session identifier string
graph_service:GraphService, # Graph service for committing
document_title:Optional[str]=None, # Override document title (None = auto-generate)
) -> CommitResult: # Result of the commit operation
"Handle committing the document to the context graph."
def init_commit_router(
state_store:WorkflowStateStore, # The workflow state store
workflow_id:str, # The workflow identifier
prefix:str, # Base prefix for commit route
graph_service:GraphService, # Graph service for committing
urls:ReviewUrls, # URL bundle to populate
alert_container_id:str="commit-alert-container", # ID of container for alert OOB swap
) -> Tuple[APIRouter, Dict[str, Callable]]: # (router, routes dict)
"Initialize commit route."
Classes
@dataclass
class CommitResult:
"Result of a commit operation."
success: bool # Whether the commit succeeded
document_id: Optional[str] # Created document node ID
segment_count: int = 0 # Number of segments committed
edge_count: int = 0 # Number of edges created
error: Optional[str] # Error message if failed
Variables
DEBUG_COMMIT_ROUTES = False
COMMIT_ALERT_ID = 'commit-alert'
core (core.ipynb)
Review step state management helpers
Import
from cjm_transcript_review.routes.core import (
WorkflowStateStore,
DEBUG_REVIEW_STATE,
ReviewContext
)
Functions
def _get_review_state(
state_store:WorkflowStateStore, # The workflow state store
workflow_id:str, # The workflow identifier
session_id:str # Session identifier string
) -> ReviewStepState: # Review step state dictionary
"Get the review step state from the workflow state store."
def _get_segmentation_state(
state_store:WorkflowStateStore, # The workflow state store
workflow_id:str, # The workflow identifier
session_id:str # Session identifier string
) -> Dict[str, Any]: # Segmentation step state dictionary
"Get the segmentation step state from the workflow state store."
def _get_alignment_state(
state_store:WorkflowStateStore, # The workflow state store
workflow_id:str, # The workflow identifier
session_id:str # Session identifier string
) -> Dict[str, Any]: # Alignment step state dictionary
"Get the alignment step state from the workflow state store."
def _load_review_context(
state_store:WorkflowStateStore, # The workflow state store
workflow_id:str, # The workflow identifier
session_id:str # Session identifier string
) -> ReviewContext: # Common review state values
"Load commonly-needed review state values including cross-step data."
def _get_assembled_segments(
ctx:ReviewContext # Loaded review context
) -> List[AssembledSegment]: # Paired segments with VAD chunks
"Pair segments with VAD chunks for review display."
def _update_review_state(
state_store:WorkflowStateStore, # The workflow state store
workflow_id:str, # The workflow identifier
session_id:str, # Session identifier string
focused_index:int=None, # Updated focused index (None = don't change)
visible_count:int=None, # Visible card count (None = don't change)
is_auto_mode:bool=None, # Auto-adjust mode flag (None = don't change)
card_width:int=None, # Card stack width in rem (None = don't change)
document_title:str=None, # Document title (None = don't change)
is_validated:bool=None, # Validation flag (None = don't change)
playback_speed:float=None, # Playback speed (None = don't change)
auto_navigate:bool=None, # Auto-navigate flag (None = don't change)
) -> None
"Update the review step state in the workflow state store."
def _handle_update_title(
state_store:WorkflowStateStore, # The workflow state store
workflow_id:str, # The workflow identifier
session_id:str, # Session identifier string
document_title:str, # New document title from form input
) -> None
"Update the document title in review state."
def _build_card_stack_state(
ctx:ReviewContext, # Loaded review context
) -> CardStackState: # Card stack state for library functions
"Build a CardStackState from review context for library calls."
Classes
class ReviewContext(NamedTuple):
"Common review state values loaded by handlers."
Variables
DEBUG_REVIEW_STATE = False
graph (graph.ipynb)
Graph service for committing documents and segments to the context graph
Import
from cjm_transcript_review.services.graph import (
GraphService
)
Classes
class GraphService:
def __init__(
self,
plugin_manager:PluginManager, # Plugin manager for accessing graph plugin
plugin_name:str="cjm-graph-plugin-sqlite", # Name of the graph plugin
)
"Service for committing structure to context graph."
def __init__(
self,
plugin_manager:PluginManager, # Plugin manager for accessing graph plugin
plugin_name:str="cjm-graph-plugin-sqlite", # Name of the graph plugin
)
"Initialize the graph service."
def is_available(self) -> bool: # True if plugin is loaded and ready
"""Check if the graph plugin is available."""
return self._manager.get_plugin(self._plugin_name) is not None
def ensure_loaded(
self,
config:Optional[Dict[str, Any]]=None, # Optional plugin configuration
) -> bool: # True if successfully loaded
"Check if the graph plugin is available."
def ensure_loaded(
self,
config:Optional[Dict[str, Any]]=None, # Optional plugin configuration
) -> bool: # True if successfully loaded
"Ensure the graph plugin is loaded."
async def commit_document_async(
self,
title:str, # Document title
text_segments:List[TextSegment], # Text segments from decomposition
vad_chunks:List[VADChunk], # VAD chunks for timing (1:1 with segments)
media_type:str="audio", # Source media type
) -> Dict[str, Any]: # Result with document_id and segment_ids
"Commit a document to the context graph.
Assembles text segments with VAD timing at commit time.
Requires 1:1 alignment: len(text_segments) == len(vad_chunks)."
def commit_document(
self,
title:str, # Document title
text_segments:List[TextSegment], # Text segments from decomposition
vad_chunks:List[VADChunk], # VAD chunks for timing
media_type:str="audio", # Source media type
) -> Dict[str, Any]: # Result with document_id and segment_ids
"Commit a document to the context graph synchronously."
helpers (helpers.ipynb)
State getters for the review step from InteractionContext
Import
from cjm_transcript_review.components.helpers import *
Functions
def _get_review_state(
ctx:InteractionContext # Interaction context with state
) -> ReviewStepState: # Typed review step state
"Get the full review step state from context."
def _get_focused_index(
ctx:InteractionContext, # Interaction context with state
default:int=0, # Default focused index
) -> int: # Currently focused segment index
"Get the currently focused segment index."
def _get_visible_count(
ctx:InteractionContext, # Interaction context with state
default:int=5, # Default visible card count
) -> int: # Number of visible cards in viewport
"Get the stored visible card count."
def _get_is_auto_mode(
ctx:InteractionContext, # Interaction context with state
) -> bool: # Whether card count is in auto-adjust mode
"Get whether the card count is in auto-adjust mode."
def _get_card_width(
ctx:InteractionContext, # Interaction context with state
default:int=50, # Default card width in rem
) -> int: # Card stack width in rem
"Get the stored card stack width."
def _get_segments(
ctx:InteractionContext # Interaction context with state
) -> List[TextSegment]: # List of TextSegment objects from segmentation step
"Get text segments from segmentation step state."
def _get_vad_chunks(
ctx:InteractionContext # Interaction context with state
) -> List[VADChunk]: # List of VADChunk objects from alignment step
"Get VAD chunks from alignment step state."
def _get_media_path(
ctx:InteractionContext # Interaction context with state
) -> Optional[str]: # Path to original audio file or None
"Get the original audio file path from alignment step."
def _is_aligned(
ctx:InteractionContext # Interaction context with state
) -> bool: # True if segment count matches VAD chunk count
"Check if segments are aligned with VAD chunks (1:1 match)."
html_ids (html_ids.ipynb)
HTML ID constants for Phase 3: Review & Commit
Import
from cjm_transcript_review.html_ids import (
ReviewHtmlIds
)
Classes
class ReviewHtmlIds:
"HTML ID constants for Phase 3: Review & Commit."
def as_selector(
id_str:str # The HTML ID to convert
) -> str: # CSS selector with # prefix
"Convert an ID to a CSS selector format."
def review_card(
index:int # Segment index
) -> str: # HTML ID for review card
"Generate HTML ID for a review card."
init (init.ipynb)
Router assembly for Phase 3 review routes
Import
from cjm_transcript_review.routes.init import (
init_review_routers
)
Functions
def init_review_routers(
state_store:WorkflowStateStore, # The workflow state store
workflow_id:str, # The workflow identifier
prefix:str, # Base prefix for review routes (e.g., "/workflow/review")
audio_src_url:str="", # Audio source route (from core routes)
graph_service:Optional[GraphService]=None, # Graph service for commit (None = no commit route)
alert_container_id:str="commit-alert-container", # ID of container for commit alerts
) -> Tuple[List[APIRouter], ReviewUrls, Dict[str, Callable]]: # (routers, urls, routes)
"Initialize and return all review routers with URL bundle."
keyboard_config (keyboard_config.ipynb)
Review-specific keyboard building blocks for assembly into a KeyboardManager
Import
from cjm_transcript_review.components.keyboard_config import (
create_review_kb_parts,
create_review_keyboard_manager
)
Functions
def create_review_kb_parts(
ids:CardStackHtmlIds, # Card stack HTML IDs
button_ids:CardStackButtonIds, # Card stack button IDs for navigation
config:CardStackConfig, # Card stack configuration
) -> Tuple[FocusZone, tuple, tuple]: # (zone, actions, modes)
"Create review-specific keyboard building blocks."
def create_review_keyboard_manager(
ids:CardStackHtmlIds, # Card stack HTML IDs
button_ids:CardStackButtonIds, # Card stack button IDs for navigation
config:CardStackConfig, # Card stack configuration
) -> ZoneManager: # Configured keyboard zone manager
"Create the keyboard zone manager for the review step."
models (models.ipynb)
Review step state and working document model for Phase 3: Review & Commit
Import
from cjm_transcript_review.models import (
ReviewStepState,
ReviewUrls,
WorkingDocument
)
Classes
class ReviewStepState(TypedDict):
"State for Phase 3: Review & Commit."
@dataclass
class ReviewUrls:
"URL bundle for Phase 3 review route handlers and renderers."
card_stack: CardStackUrls = field(...)
audio_src: str = '' # Audio source route
speed_change: str = '' # Playback speed change handler
toggle_auto_nav: str = '' # Auto-navigate toggle handler
replay_current: str = '' # Replay current segment handler
update_title: str = '' # Document title update handler
commit: str = '' # Commit handler route
@dataclass
class WorkingDocument:
"Container for workflow state during structure decomposition."
title: str = '' # Document title
media_type: str = 'audio' # Source media type ('audio', 'video', 'text')
media_path: Optional[str] # Path to primary source media
source_blocks: List[SourceBlock] = field(...) # Ordered source blocks
combined_text: str = '' # Concatenated text from all sources
segments: List[TextSegment] = field(...) # Decomposed segments
vad_chunks: List[VADChunk] = field(...) # VAD time ranges
audio_duration: Optional[float] # Total audio duration in seconds
def to_dict(self) -> Dict[str, Any]: # Dictionary representation
"""Convert to dictionary for JSON serialization."""
return {
'title': self.title,
"Convert to dictionary for JSON serialization."
def from_dict(
cls,
data: Dict[str, Any] # Dictionary representation
) -> "WorkingDocument": # Reconstructed WorkingDocument
"Create from dictionary."
review_card (review_card.ipynb)
Review card component showing assembled segment with timing and source info
Import
from cjm_transcript_review.components.review_card import (
AssembledSegment,
render_review_card,
create_review_card_renderer
)
Functions
def render_review_card(
assembled:AssembledSegment, # Assembled segment with text and timing
card_role:CardRole, # Role of this card in viewport ("focused" or "context")
has_boundary_above:bool=False, # Audio file boundary exists above this card
has_boundary_below:bool=False, # Audio file boundary exists below this card
) -> Any: # Review card component
"Render a single review card with text, timing, source info, playing indicator, and play button."
def create_review_card_renderer(
audio_file_boundaries:Set[int]=None, # Indices where audio_file_index changes
) -> Callable: # Card renderer callback: (item, CardRenderContext) -> FT
"Create a card renderer callback for review cards."
Classes
@dataclass
class AssembledSegment:
"A segment paired with its corresponding VAD chunk for review."
segment: TextSegment # Text segment with content and source info
vad_chunk: VADChunk # VAD chunk with timing
def index(self) -> int: # Segment index for card stack
"""Get the index from the segment."""
return self.segment.index
@property
def text(self) -> str: # Segment text content
"Get the index from the segment."
def text(self) -> str: # Segment text content
"""Get the text content from the segment."""
return self.segment.text
@property
def start_time(self) -> float: # Start time from VAD chunk
"Get the text content from the segment."
def start_time(self) -> float: # Start time from VAD chunk
"""Get the start time from the VAD chunk."""
return self.vad_chunk.start_time
@property
def end_time(self) -> float: # End time from VAD chunk
"Get the start time from the VAD chunk."
def end_time(self) -> float: # End time from VAD chunk
"Get the end time from the VAD chunk."
step_renderer (step_renderer.ipynb)
Composable render functions for the review card stack step
Import
from cjm_transcript_review.components.step_renderer import (
DEBUG_REVIEW_RENDER,
render_review_toolbar,
render_review_stats,
render_review_source_position,
render_review_content,
render_review_footer,
render_review_step
)
Functions
def render_review_toolbar(
playback_speed:float=1.0, # Current playback speed
auto_navigate:bool=False, # Whether auto-navigate is enabled
document_title:str="", # Current document title
urls:ReviewUrls=None, # URL bundle for audio control routes
oob:bool=False, # Whether to render as OOB swap
) -> Any: # Toolbar component
"Render the review toolbar with title input and audio controls."
def render_review_stats(
assembled:List[AssembledSegment], # Assembled segments
oob:bool=False, # Whether to render as OOB swap
) -> Any: # Statistics component
"Render review statistics."
def render_review_source_position(
assembled:List[AssembledSegment], # Assembled segments
focused_index:int=0, # Currently focused segment index
oob:bool=False, # Whether to render as OOB swap
) -> Any: # Audio file position indicator (empty if single file)
"Render audio file position indicator for the focused segment."
def render_review_content(
assembled:List[AssembledSegment], # Assembled segments to display
focused_index:int, # Currently focused segment index
visible_count:int, # Number of visible cards in viewport
card_width:int, # Card stack width in rem
urls:ReviewUrls, # URL bundle for review routes
audio_urls:Optional[List[str]]=None, # Audio file URLs for Web Audio API
) -> Any: # Main content area
"Render the review content area with card stack viewport and keyboard system."
def render_review_footer(
assembled:List[AssembledSegment], # Assembled segments
focused_index:int, # Currently focused segment index
) -> Any: # Footer content with progress indicator, source position, and stats
"Render footer content with progress indicator, source position, and statistics."
def render_review_step(
assembled:List[AssembledSegment], # Assembled segments to display
focused_index:int=0, # Currently focused segment index
visible_count:int=DEFAULT_VISIBLE_COUNT, # Number of visible cards
is_auto_mode:bool=False, # Whether card count is in auto-adjust mode
card_width:int=DEFAULT_CARD_WIDTH, # Card stack width in rem
playback_speed:float=1.0, # Current playback speed
auto_navigate:bool=False, # Whether auto-navigate is enabled
document_title:str="", # Current document title
urls:ReviewUrls=None, # URL bundle for review routes
audio_urls:Optional[List[str]]=None, # Audio file URLs for Web Audio API
) -> Any: # Complete review step component
"Render the complete review step with toolbar, content, and footer."
Variables
DEBUG_REVIEW_RENDER = False
utils (utils.ipynb)
Time formatting and source info display utilities for review cards
Import
from cjm_transcript_review.utils import (
format_time,
format_duration,
truncate_id,
format_char_range,
format_source_info,
generate_document_title
)
Functions
def format_time(
seconds:Optional[float] # Time in seconds
) -> str: # Formatted time string (m:ss.s)
"Format seconds as m:ss.s for sub-second display."
def format_duration(
start:Optional[float], # Start time in seconds
end:Optional[float], # End time in seconds
) -> str: # Formatted duration string (e.g., "3.2s")
"Format duration from start/end times."
def truncate_id(
id_str:Optional[str], # Full ID string
length:int=8, # Number of characters to keep
) -> str: # Truncated ID with ellipsis if needed
"Truncate an ID string for display, adding ellipsis if truncated."
def format_char_range(
start_char:Optional[int], # Start character index
end_char:Optional[int], # End character index
) -> str: # Formatted range string (e.g., "char:25-68")
"Format character range for source reference display."
def format_source_info(
provider_id:Optional[str], # Source provider identifier
source_id:Optional[str], # Source record ID
start_char:Optional[int]=None, # Start character index
end_char:Optional[int]=None, # End character index
) -> str: # Formatted source info string
"Format source info for display in review cards."
def generate_document_title(
media_path:Optional[str], # Path to media file
default:str="Untitled Document", # Fallback title if path is None
) -> str: # Clean document title
"Generate a document title from a media file path."
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cjm_transcript_review-0.0.14.tar.gz.
File metadata
- Download URL: cjm_transcript_review-0.0.14.tar.gz
- Upload date:
- Size: 48.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0205add15359c3156bd575f4ba9f40b56a758075293350cf07d03bee9a1cbc07
|
|
| MD5 |
87e011841c9d971ba1d7f1bd2b65fa02
|
|
| BLAKE2b-256 |
6bc3117531314ff68874f13fcfb17b51439597c84cd8e7c52b9c035f4a9b9288
|
File details
Details for the file cjm_transcript_review-0.0.14-py3-none-any.whl.
File metadata
- Download URL: cjm_transcript_review-0.0.14-py3-none-any.whl
- Upload date:
- Size: 45.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8317f802fe852f7f71dbec3362fced7b28af462540e6d551fd05720156b294fd
|
|
| MD5 |
d9b086e7a73b9b72a3226e85053efc36
|
|
| BLAKE2b-256 |
dceb514e6887c5523d045726ecf664f5e480dcf1535bbff53a81246a410e1fff
|