Skip to content

Instantly share code, notes, and snippets.

@Ifihan
Last active May 3, 2025 11:22
Show Gist options
  • Save Ifihan/a99c63e40c6ffc6d8557c1465a8f3292 to your computer and use it in GitHub Desktop.
Save Ifihan/a99c63e40c6ffc6d8557c1465a8f3292 to your computer and use it in GitHub Desktop.
Build a Gemini-Powered YouTube Summarizer
import os
from flask import Flask, render_template, request, jsonify
from google import genai
from google.genai import types
app = Flask(__name__)
PROJECT_ID = "build-with-vertex-ai"
client = genai.Client(
vertexai=True,
project=PROJECT_ID,
location="us-central1",
)
# Define the home page route.
@app.route('/', methods=['GET'])
def index():
'''
Renders the home page.
Returns:The rendered template.
'''
return render_template('index.html')
def generate(youtube_link, model, additional_prompt):
# Prepare youtube video using the provided link
youtube_video = types.Part.from_uri(
file_uri=youtube_link,
mime_type="video/*",
)
# If addtional prompt is not provided, just append a space
if not additional_prompt:
additional_prompt = " "
# Prepare content to send to the model
contents = [
youtube_video,
types.Part.from_text(text="""Provide a summary of the video."""),
additional_prompt,
]
# Define content configuration
generate_content_config = types.GenerateContentConfig(
temperature = 1,
top_p = 0.95,
max_output_tokens = 8192,
response_modalities = ["TEXT"],
)
return client.models.generate_content(
model = model,
contents = contents,
config = generate_content_config,
).text
@app.route('/summarize', methods=['POST'])
def summarize():
'''
Summarize the user provided YouTube video.
Returns: JSON with summary.
'''
# Process the form data
youtube_link = request.form['youtube_link']
model = request.form['model']
additional_prompt = request.form['additional_prompt']
# Generate the summary.
try:
summary = generate(youtube_link, model, additional_prompt)
return jsonify({"success": True, "summary": summary})
except ValueError as e:
return jsonify({"success": False, "error": str(e)}), 400
if __name__ == '__main__':
server_port = os.environ.get('PORT', '8080')
app.run(debug=False, port=server_port, host='0.0.0.0')
<!DOCTYPE html>
<html>
<head>
<title>YouTube Summarizer</title>
<style>
body {
font-family: sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #f4f4f4;
margin: 0;
padding: 20px;
}
.container {
background-color: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
text-align: center;
width: 100%;
max-width: 800px;
}
h2 {
text-align: center;
margin-bottom: 20px;
}
input[type="text"], textarea, select {
width: 100%;
padding: 10px;
margin-bottom: 15px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
button {
background-color: #4CAF50;
color: white;
padding: 12px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
#loading {
display: none;
margin-top: 20px;
}
#summary-container {
margin-top: 30px;
display: none;
text-align: left;
}
#summary-text {
background-color: #f9f9f9;
padding: 15px;
border-radius: 4px;
border-left: 4px solid #4CAF50;
white-space: pre-wrap;
}
.error {
color: #f44336;
margin-top: 15px;
}
</style>
</head>
<body>
<div class="container">
<h2>YouTube Summarizer</h2>
<form id="summarize-form">
<input type="text" name="youtube_link" id="youtube_link" placeholder="Enter YouTube Link" required>
<select name="model" id="model">
<option value="gemini-2.0-flash-001">Gemini 2.0 Flash</option>
</select>
<textarea name="additional_prompt" id="additional_prompt" placeholder="Write your additional prompt here. For example: 'explain to me like I am five years old'"></textarea>
<button type="submit">Summarize</button>
</form>
<div id="loading">
<p>Generating summary... This may take a moment.</p>
</div>
<div id="error-message" class="error"></div>
<div id="summary-container">
<h3>Summary</h3>
<div id="summary-text"></div>
</div>
</div>
<script>
document.getElementById('summarize-form').addEventListener('submit', function(e) {
e.preventDefault();
// Show loading message
document.getElementById('loading').style.display = 'block';
document.getElementById('summary-container').style.display = 'none';
document.getElementById('error-message').textContent = '';
// Get form data
const youtubeLink = document.getElementById('youtube_link').value;
const model = document.getElementById('model').value;
const additionalPrompt = document.getElementById('additional_prompt').value;
// Create form data object
const formData = new FormData();
formData.append('youtube_link', youtubeLink);
formData.append('model', model);
formData.append('additional_prompt', additionalPrompt);
// Send AJAX request
fetch('/summarize', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
// Hide loading message
document.getElementById('loading').style.display = 'none';
if (data.success) {
// Show summary
document.getElementById('summary-container').style.display = 'block';
document.getElementById('summary-text').textContent = data.summary;
} else {
// Show error message
document.getElementById('error-message').textContent = data.error || 'An error occurred while generating the summary.';
}
})
.catch(error => {
// Hide loading message and show error
document.getElementById('loading').style.display = 'none';
document.getElementById('error-message').textContent = 'An error occurred. Please try again.';
console.error('Error:', error);
});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment