Skip to content
Open
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
192 changes: 192 additions & 0 deletions apps/python/meeting-summarizer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
# AI Meeting Summarizer

An AI-powered meeting summarization web application built with **pure Python** (no frameworks). Automatically extracts action items, key points, and generates summaries from meeting transcripts.

## Features

- Upload and analyze meeting transcripts
- AI-powered summary generation
- Automatic action item extraction
- Key points identification
- Participant detection
- Meeting duration estimation
- Modern web interface with authentication
- Real-time meeting statistics
- Pure Python - zero external dependencies

## Tech Stack

- **Backend**: Python 3 standard library only (`http.server`, `sqlite3`, `re`)
- **Frontend**: Vanilla HTML, CSS, and JavaScript
- **Database**: SQLite3
- **No frameworks**: No Django, Flask, FastAPI, or any web framework
- **No AI frameworks**: Custom text analysis using regex and NLP patterns

## Running the Application

```bash
# Navigate to the directory
cd apps/python/meeting-summarizer

# Run the server
python3 server.py
```

The application will start on `http://localhost:8000`

## Demo Account

The application comes with a demo account:

- **[email protected]**

(Any password works in this demo - authentication is simplified)

## Project Structure

```
meeting-summarizer/
├── server.py # Main web server
├── database.py # SQLite database operations
├── models.py # User and Meeting data models
├── ai_summarizer.py # AI summarization engine
├── requirements.txt # Dependencies list (informational)
├── static/
│ ├── login.html # Login page
│ ├── dashboard.html # Meetings dashboard
│ ├── style.css # Styling
│ ├── login.js # Login page JavaScript
│ └── app.js # Dashboard JavaScript
└── README.md
```

## Features in Detail

### AI Summarization

The AI summarizer analyzes meeting transcripts to extract:

- **Summary**: Generated overview of the meeting discussion
- **Action Items**: Automatically identified tasks and follow-ups
- **Key Points**: Important discussion topics and decisions
- **Participants**: Names detected from transcript
- **Duration**: Estimated meeting length based on word count

### Meeting Management

- Upload meeting transcripts with custom titles
- View all meetings in a card-based dashboard
- Click to view detailed meeting analysis
- Delete meetings you no longer need
- Real-time statistics (total meetings, hours, avg duration)

### Authentication

- Session-based authentication with cookies
- 24-hour session expiration
- Secure session management

### Database

- SQLite3 for persistent storage
- Thread-safe database operations
- Automatic table creation
- Supports both users and meetings

## API Endpoints

### Authentication

- `POST /api/auth/login` - Login with email/password
- `POST /api/auth/logout` - Logout and destroy session
- `GET /api/auth/status` - Check authentication status

### Meetings

- `GET /api/meetings` - List all meetings for current user
- `GET /api/meetings/:id` - Get specific meeting details
- `POST /api/meetings` - Create new meeting (analyzes transcript)
- `DELETE /api/meetings/:id` - Delete meeting

### Statistics

- `GET /api/stats` - Get meeting statistics for current user

## How the AI Works

The summarization engine uses pattern matching and natural language processing techniques:

1. **Participant Detection**: Extracts names from "Name:" patterns in transcript
2. **Action Item Extraction**: Identifies sentences with action verbs (will, should, need to, must)
3. **Key Points**: Finds sentences with important keywords (decided, agreed, important, crucial)
4. **Summary Generation**: Combines intro sentences with key topics
5. **Duration Estimation**: Calculates based on ~150 words per minute speaking rate

No external AI APIs or models are used - everything runs locally with pure Python.

## Development

The application uses pure Python standard library modules:

- `http.server` - HTTP server
- `sqlite3` - Database
- `json` - JSON handling
- `http.cookies` - Session management
- `secrets` - Security
- `re` - Regular expressions for text analysis
- `logging` - Application logging
- `threading` - Thread safety
- `mimetypes` - Static file serving

## Why No Frameworks?

This project demonstrates that you can build a sophisticated AI-powered web application using only Python's standard library. Benefits:

- **Zero dependencies** - No installation or version conflicts
- **Educational** - Understand how AI text analysis and web frameworks work
- **Lightweight** - Minimal resource usage
- **Portable** - Runs anywhere Python runs
- **Fast** - No external API calls or model loading
- **Stable** - Built on rock-solid standard library

## Example Meeting Transcript Format

```
Sarah: Good morning everyone. Thanks for joining this meeting.

John: Happy to be here. Should we start with the roadmap?

Sarah: Yes, let's review our Q1 priorities. We need to improve the onboarding flow.

John: Agreed. I'll work on the performance improvements. We should target 40% faster load times.

Sarah: Perfect. Let's schedule weekly check-ins to track progress.
```

The AI will automatically extract:
- Participants: Sarah, John
- Action items: Performance improvements, schedule weekly check-ins
- Key points: Q1 priorities, onboarding improvements
- Summary: Generated overview of the discussion

## Production Considerations

For production use, you would want to add:

- Real password hashing (bcrypt, argon2)
- HTTPS/TLS support
- Rate limiting
- CSRF protection
- Input sanitization
- File upload support (audio/video transcription)
- Integration with real AI APIs (OpenAI, Anthropic)
- Email notifications for action items
- Calendar integration
- Export functionality (PDF, Markdown)
- Team collaboration features
- Search and filtering
- Proper logging and monitoring

## License

This is a demo application for testing purposes.
157 changes: 157 additions & 0 deletions apps/python/meeting-summarizer/ai_summarizer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
"""Simulated AI summarizer for meeting transcripts."""

import re
from typing import List, Tuple


class AISummarizer:
"""Simulates AI-powered meeting summarization."""

@staticmethod
def analyze_transcript(transcript: str) -> Tuple[str, List[str], List[str], List[str], int]:
"""
Analyze a meeting transcript and extract key information.

Returns:
- summary: Generated summary text
- action_items: List of action items
- key_points: List of key discussion points
- participants: List of identified participants
- duration_minutes: Estimated duration
"""
# Clean and prepare transcript
lines = [line.strip() for line in transcript.split('\n') if line.strip()]
text = ' '.join(lines)

# Extract participants (names followed by colon)
participants = AISummarizer._extract_participants(transcript)

# Extract action items
action_items = AISummarizer._extract_action_items(text)

# Extract key points
key_points = AISummarizer._extract_key_points(lines, text)

# Generate summary
summary = AISummarizer._generate_summary(text, action_items, key_points)

# Estimate duration (roughly 150 words per minute speaking rate)
word_count = len(text.split())
duration_minutes = max(1, round(word_count / 150))

return summary, action_items, key_points, participants, duration_minutes

@staticmethod
def _extract_participants(transcript: str) -> List[str]:
"""Extract participant names from transcript."""
# Look for patterns like "Name:" at the start of lines
pattern = r'^([A-Z][a-z]+(?: [A-Z][a-z]+)?)\s*:'
participants = set()

for line in transcript.split('\n'):
match = re.match(pattern, line.strip())
if match:
participants.add(match.group(1))

return sorted(list(participants))

@staticmethod
def _extract_action_items(text: str) -> List[str]:
"""Extract action items from text."""
action_items = []

# Common action patterns
action_patterns = [
r'(?:will|should|need to|must|have to|going to|plan to)\s+([^.!?]+[.!?])',
r'(?:action item|todo|task):\s*([^.!?]+)',
r'(?:^|\.\s+)([A-Z][^.!?]*(?:will|should|need to)[^.!?]+[.!?])',
]

for pattern in action_patterns:
matches = re.finditer(pattern, text, re.IGNORECASE | re.MULTILINE)
for match in matches:
item = match.group(1).strip()
if len(item) > 10 and len(item) < 200:
# Clean up the action item
item = re.sub(r'\s+', ' ', item)
if not item.endswith(('.', '!', '?')):
item += '.'
if item not in action_items:
action_items.append(item)

# Limit to most relevant action items
return action_items[:8]

@staticmethod
def _extract_key_points(lines: List[str], text: str) -> List[str]:
"""Extract key discussion points."""
key_points = []

# Look for important statements
important_keywords = [
'important', 'crucial', 'critical', 'key', 'main',
'decided', 'agreed', 'conclusion', 'outcome', 'result',
'issue', 'problem', 'challenge', 'concern',
'goal', 'objective', 'target', 'milestone'
]

sentences = re.split(r'[.!?]+', text)

for sentence in sentences:
sentence = sentence.strip()
if len(sentence) < 20 or len(sentence) > 250:
continue

# Check if sentence contains important keywords
lower_sentence = sentence.lower()
if any(keyword in lower_sentence for keyword in important_keywords):
# Clean up the sentence
sentence = re.sub(r'\s+', ' ', sentence)
if not sentence.endswith(('.', '!', '?')):
sentence += '.'
key_points.append(sentence)

# If no key points found, extract first few meaningful sentences
if not key_points:
for sentence in sentences[:5]:
sentence = sentence.strip()
if len(sentence) > 30:
if not sentence.endswith(('.', '!', '?')):
sentence += '.'
key_points.append(sentence)

# Limit to top key points
return key_points[:6]

@staticmethod
def _generate_summary(text: str, action_items: List[str], key_points: List[str]) -> str:
"""Generate a meeting summary."""
# Extract first few sentences as intro
sentences = re.split(r'[.!?]+', text)
intro_sentences = []

for sentence in sentences[:3]:
sentence = sentence.strip()
if len(sentence) > 30:
intro_sentences.append(sentence)

# Build summary
summary_parts = []

if intro_sentences:
summary_parts.append(' '.join(intro_sentences[:2]) + '.')

if key_points:
summary_parts.append('\n\nKey topics discussed:')
for i, point in enumerate(key_points[:3], 1):
summary_parts.append(f"{i}. {point}")

if action_items:
summary_parts.append(f"\n\nThe meeting resulted in {len(action_items)} action items that need to be addressed.")

if not summary_parts:
# Fallback summary
word_count = len(text.split())
return f"This meeting covered various topics across approximately {word_count} words of discussion. The transcript has been processed and key information has been extracted."

return '\n'.join(summary_parts)
Loading