How to Take Screenshots in Django and Flask (Without Selenium)
Adding screenshot functionality to a Python web app usually means managing ChromeDriver, debugging WebDriverException in production. Here's the lighter path: one HTTP request, one binary response.
Adding screenshot functionality to a Python web app typically means managing a headless browser: installing ChromeDriver, keeping it in sync with Chrome, debugging WebDriverException in production. Selenium and Playwright solve the problem but add significant operational weight.
Here's the lighter path: one HTTP request, one binary response.
Django view
import requests
from django.http import HttpResponse
def screenshot(request):
url = request.GET.get('url', 'https://example.com')
res = requests.post(
'https://pagebolt.dev/api/v1/screenshot',
headers={'x-api-key': settings.PAGEBOLT_API_KEY},
json={'url': url, 'fullPage': True, 'blockBanners': True}
)
return HttpResponse(res.content, content_type='image/png')
Flask route
import requests
from flask import Flask, request, send_file
import io
app = Flask(__name__)
@app.route('/screenshot')
def screenshot():
url = request.args.get('url', 'https://example.com')
res = requests.post(
'https://pagebolt.dev/api/v1/screenshot',
headers={'x-api-key': app.config['PAGEBOLT_API_KEY']},
json={'url': url, 'fullPage': True, 'blockBanners': True}
)
return send_file(io.BytesIO(res.content), mimetype='image/png')
Save to disk (scripts, management commands)
import requests
def capture(url, output_path):
res = requests.post(
'https://pagebolt.dev/api/v1/screenshot',
headers={'x-api-key': 'YOUR_API_KEY'},
json={
'url': url,
'fullPage': True,
'blockBanners': True,
'format': 'png'
}
)
with open(output_path, 'wb') as f:
f.write(res.content)
capture('https://yourapp.com', 'screenshot.png')
Common options
# Mobile viewport
{'url': url, 'viewportDevice': 'iphone_14_pro'}
# Dark mode
{'url': url, 'darkMode': True, 'fullPage': True}
# From HTML string (e.g. a rendered Django template)
html = render_to_string('report_template.html', context)
{'html': html, 'format': 'png'}
# JPEG with quality
{'url': url, 'format': 'jpeg', 'quality': 85}
The html parameter is useful for capturing rendered Django or Jinja2 templates without a running server — handy for generating preview images of reports, emails, or documents.
The upgrade: record a narrated video
Once screenshot infrastructure is in place, the same API handles narrated browser recordings:
res = requests.post(
'https://pagebolt.dev/api/v1/video',
headers={'x-api-key': 'YOUR_API_KEY'},
json={
'steps': [
{'action': 'navigate', 'url': 'https://yourapp.com', 'note': 'Open the app'},
{'action': 'click', 'selector': '#get-started', 'note': 'Get started'}
],
'audioGuide': {
'enabled': True,
'voice': 'nova',
'script': "Here's the app. {{1}} {{2}} One click to begin."
},
'pace': 'slow',
'frame': {'enabled': True, 'style': 'macos'}
}
)
with open('demo.mp4', 'wb') as f:
f.write(res.content)
Same request pattern, binary MP4 response, no browser process.
Deployment
No Selenium, no ChromeDriver, no browser binary. Works on any Python hosting — Heroku, Render, Railway, AWS Lambda (with the requests layer), or bare metal. Add PAGEBOLT_API_KEY to your environment variables and deploy as normal.
Get Started Free
100 requests/month, no credit card
Add screenshots to your Django or Flask app in minutes — no ChromeDriver, no Selenium, no browser to manage.
Get Your Free API Key →