Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,6 @@ dmypy.json
# Pyre type checker
.pyre/
.username
.idea
.idea
*.json
output/
2 changes: 2 additions & 0 deletions app/commands/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from .curator import commands as curator
from .server import server
from .media import commands as media
from .summary import summary
__all__ = ["media", "curator", "server", "summary"]
103 changes: 103 additions & 0 deletions app/commands/summary.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import os
import click
from ..services.summary import correct_transcript, summarize_transcript, configure_api
from ..config import settings

def do_correct(input, output, provider, model, api_key):
"""Implementation logic for transcript correction"""
if not api_key:
api_key = settings.config.get(f"{provider}_api_key", None)

configure_api(provider=provider, api_key=api_key)

with open(input, 'r', encoding='utf-8') as f:
original_text = f.read()

corrected_text = correct_transcript(original_text, provider=provider, model_name=model)

if corrected_text:
if not output:
base_name = os.path.splitext(os.path.basename(input))[0]
input_dir = os.path.dirname(input) or "."
output = os.path.join(input_dir, f"{base_name}_corrected.txt")

os.makedirs(os.path.dirname(output), exist_ok=True)
with open(output, 'w', encoding='utf-8') as f:
f.write(corrected_text)
click.echo(f"Corrected transcript saved to: {output}")

def do_summarize(input, output, provider, model, api_key, correct_first):
"""Implementation logic for transcript summarization"""
if not api_key:
api_key = settings.config.get(f"{provider}_api_key", None)

configure_api(provider=provider, api_key=api_key)

with open(input, 'r', encoding='utf-8') as f:
original_text = f.read()

text_to_summarize = original_text

if correct_first:
click.echo("Correcting transcript before summarization...")
text_to_summarize = correct_transcript(original_text, provider=provider, model_name=model)

summary_text = summarize_transcript(text_to_summarize, provider=provider, model_name=model)

if summary_text:
if not output:
base_name = os.path.splitext(os.path.basename(input))[0]
input_dir = os.path.dirname(input) or "."
output = os.path.join(input_dir, f"{base_name}_summary.txt")

os.makedirs(os.path.dirname(output), exist_ok=True)
with open(output, 'w', encoding='utf-8') as f:
f.write(summary_text)
click.echo(f"Summary saved to: {output}")

@click.group()
def summary():
"""Transcript correction and summarization commands."""
pass

@summary.command()
@click.option("--input", "-i", required=True, help="Path to input transcript file.")
@click.option("--output", "-o", help="Path to save corrected transcript.")
@click.option("--provider", default="gemini", type=click.Choice(["gemini", "openai", "claude"]), help="AI provider to use.")
@click.option("--model", help="Model name to use with the selected provider.")
@click.option("--api-key", help="Custom API key for the selected provider.")
def correct(input, output, provider, model, api_key):
"""Correct transcription errors in the transcript."""
do_correct(input, output, provider, model, api_key)

@summary.command()
@click.option("--input", "-i", required=True, help="Path to input transcript file.")
@click.option("--output", "-o", help="Path to save summary.")
@click.option("--provider", default="gemini", type=click.Choice(["gemini", "openai", "claude"]), help="AI provider to use.")
@click.option("--model", help="Model name to use with the selected provider.")
@click.option("--api-key", help="Custom API key for the selected provider.")
@click.option("--correct-first/--no-correct", default=False, help="Correct transcript before summarizing.")
def summarize(input, output, provider, model, api_key, correct_first):
"""Generate a summary of the transcript."""
do_summarize(input, output, provider, model, api_key, correct_first)

@click.command(name="correct")
@click.option("--input", "-i", required=True, help="Path to input transcript file.")
@click.option("--output", "-o", help="Path to save corrected transcript.")
@click.option("--provider", default="gemini", type=click.Choice(["gemini", "openai", "claude"]), help="AI provider to use.")
@click.option("--model", help="Model name to use with the selected provider.")
@click.option("--api-key", help="Custom API key for the selected provider.")
def correct_command(input, output, provider, model, api_key):
"""Correct transcription errors in the transcript."""
do_correct(input, output, provider, model, api_key)

@click.command(name="summarize")
@click.option("--input", "-i", required=True, help="Path to input transcript file.")
@click.option("--output", "-o", help="Path to save summary.")
@click.option("--provider", default="gemini", type=click.Choice(["gemini", "openai", "claude"]), help="AI provider to use.")
@click.option("--model", help="Model name to use with the selected provider.")
@click.option("--api-key", help="Custom API key for the selected provider.")
@click.option("--correct-first/--no-correct", default=False, help="Correct transcript before summarizing.")
def summarize_command(input, output, provider, model, api_key, correct_first):
"""Generate a summary of the transcript."""
do_summarize(input, output, provider, model, api_key, correct_first)
38 changes: 37 additions & 1 deletion app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,14 @@ def get_config_overview(self):
overview += f"GITHUB_METADATA_REPO_NAME: {self.GITHUB_METADATA_REPO_NAME}\n"
overview += f"TRANSCRIPTION_SERVER_URL: {self.TRANSCRIPTION_SERVER_URL}\n"
overview += f"BTC_TRANSCRIPTS_URL: {self.BTC_TRANSCRIPTS_URL}\n"

overview += f"GEMINI_API_KEY: {'[SET]' if self.GEMINI_API_KEY else '[NOT SET]'}\n"
overview += f"OPENAI_API_KEY: {'[SET]' if self.OPENAI_API_KEY else '[NOT SET]'}\n"
overview += f"ANTHROPIC_API_KEY: {'[SET]' if self.ANTHROPIC_API_KEY else '[NOT SET]'}\n"
overview += f"DEFAULT_SUMMARY_PROVIDER: {self.DEFAULT_SUMMARY_PROVIDER}\n"
overview += f"DEFAULT_GEMINI_MODEL: {self.DEFAULT_GEMINI_MODEL}\n"
overview += f"DEFAULT_OPENAI_MODEL: {self.DEFAULT_OPENAI_MODEL}\n"
overview += f"DEFAULT_CLAUDE_MODEL: {self.DEFAULT_CLAUDE_MODEL}\n"

# Add config.ini settings
overview += "\nSettings from config.ini:\n"
for key, value in self.config.items():
Expand Down Expand Up @@ -80,7 +87,36 @@ def GITHUB_PRIVATE_KEY(self):
def GITHUB_INSTALLATION_ID(self):
return self._get_env_variable('GITHUB_INSTALLATION_ID',
"To use GitHub App integration, you need to define a 'GITHUB_INSTALLATION_ID' in your .env file")
# Add these properties to the Settings class in app/config.py

@property
def GEMINI_API_KEY(self):
# First check environment, then config file
return os.getenv('GEMINI_API_KEY') or self.config.get('gemini_api_key', '')

@property
def OPENAI_API_KEY(self):
return os.getenv('OPENAI_API_KEY') or self.config.get('openai_api_key', '')

@property
def ANTHROPIC_API_KEY(self):
return os.getenv('ANTHROPIC_API_KEY') or self.config.get('anthropic_api_key', '')

@property
def DEFAULT_SUMMARY_PROVIDER(self):
return os.getenv('DEFAULT_SUMMARY_PROVIDER') or self.config.get('default_summary_provider', 'gemini')

@property
def DEFAULT_GEMINI_MODEL(self):
return os.getenv('DEFAULT_GEMINI_MODEL') or self.config.get('default_gemini_model', 'gemma-3-27b-it')

@property
def DEFAULT_OPENAI_MODEL(self):
return os.getenv('DEFAULT_OPENAI_MODEL') or self.config.get('default_openai_model', 'gpt-4o')

@property
def DEFAULT_CLAUDE_MODEL(self):
return os.getenv('DEFAULT_CLAUDE_MODEL') or self.config.get('default_claude_model', 'claude-3-7-sonnet-20250219')
# Initialize the Settings class and expose an instance
settings = Settings()

Expand Down
7 changes: 6 additions & 1 deletion app/services/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
from .whisper import Whisper
from .deepgram import Deepgram
from .deepgram import Deepgram
from .summary import (
correct_transcript,
summarize_transcript,
configure_api
)
Loading
Loading