Have you ever needed to take screenshots of websites automatically – maybe to track visual changes, include them in reports, or generate previews? Doing this manually can be time-consuming, especially if you need to capture multiple pages regularly.
In this tutorial, you’ll learn how to build a simple website screenshot generator using Python and Flask. The app will let users enter any website URL and instantly get a screenshot of that page – all powered by a screenshot API.
You’ll use Flask, a lightweight web framework, to create a simple web interface and handle requests. Then, you’ll integrate an external API to capture website screenshots programmatically.
By the end of this tutorial, you’ll have learned how to:
Build a basic Flask web app
Accept user input through an HTML form
Make HTTP requests to an external API
Display images dynamically on a web page
This project is a great way to learn how APIs can extend the capabilities of your web applications, and how Python can easily handle tasks like image generation and display.
What we’ll cover:
Prerequisites
Before we start building the app, make sure you have a few basics covered:
1. Python Installed
You’ll need Python 3.9 or higher installed on your machine. You can check your version by running:
python --version
If you don’t have it, you can download it from python.org/downloads.
2. Basic Knowledge of Python and Flask
You don’t need to be a Flask expert. Just have some familiarity with how to create routes and templates, and how to handle form data in Flask.
If you’re new to Flask, don’t worry – we’ll go step-by-step.
3. Screenshot API Key
We’ll be using the ScreenshotBase API to capture website screenshots. It provides a simple REST endpoint that takes a URL and returns a screenshot image.
You can get a free API key by signing up on their website. Once you have the key, keep it handy, as we’ll use it when we integrate the API in the later steps.
4. A Code Editor and Terminal
You can use any editor you prefer, like VS Code, PyCharm, or even a simple text editor. Make sure your terminal or command prompt can run Python commands and install packages using pip.
Setting Up the Project
Let’s start by setting up a new Flask project from scratch.
Step 1: Create a New Folder
Create a new folder for your project. You can name it screenshot-generator:
mkdir screenshot-generator
cd screenshot-generator
Step 2: Create a Virtual Environment
A virtual environment helps keep your project dependencies isolated from other Python projects.
Run the following commands:
python -m venv venv
Then activate it:
On macOS/Linux:
source venv/bin/activateOn Windows:
venv\Scripts\activate
Once activated, you should see (venv) at the beginning of your terminal prompt.
Step 3: Install Dependencies
We’ll need two packages for this project:
Flask for building the web app
Requests for making API calls to ScreenshotBase
Install them using pip:
pip install flask requests
Step 4: Set Up the Project Structure
Inside your project folder, create the following files and folders:
screenshot-generator/
├── app.py
├── templates/
│ └── index.html
└── static/
Here’s what each part does:
app.py: main Python file that runs your Flask apptemplates/: stores HTML templatesstatic/: stores images, CSS, and JavaScript files
Step 5: Add a Basic Flask App
Open app.py and add the following starter code:
from flask import Flask, render_template, request
import requests
import os
app = Flask(__name__)
API_KEY = os.getenv("SCREENSHOTBASE_API_KEY")
SCREENSHOTBASE_BASE_ENDPOINT = "
@app.route('/', methods=['GET', 'POST'])
def home():
if request.method == 'POST':
url = request.form.get('url')
# Placeholder: We’ll add the API call here in the next section
return render_template('index.html', url=url)
return render_template('index.html')
if __name__ == '__main__':
app.run(debug=True)
This sets up a minimal Flask application with one route (/). We’ll add the ScreenshotBase API call in the next section.
Step 6: Create a Simple HTML Template
Now that we’ve written the Flask backend to handle the screenshot request, let’s create the frontend for our app.
Inside your project folder, create a new directory named templates, and within it, add a file called index.html. Flask will automatically look for templates in this folder.
Here’s how the template should look:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Website Screenshot Generator</title>
<link
href="
rel="stylesheet"
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB"
crossorigin="anonymous"
/>
<style>
body {
padding-top: 2rem;
}
.screenshot-container {
max-height: 80vh;
overflow-y: auto;
border: 1px solid #ddd;
border-radius: 8px;
padding: 1rem;
background: #f8f9fa;
}
</style>
</head>
<body>
<div class="container text-center">
<h1 class="mb-4">Website Screenshot Generator</h1>
<form method="POST" class="d-flex justify-content-center mb-4">
<input
type="text"
name="url"
placeholder="Enter website URL"
class="form-control w-50 me-2"
required
>
<button type="submit" class="btn btn-primary">Capture Screenshot</button>
</form>
{% if screenshot %}
<h4>Screenshot Preview:</h4>
<div class="screenshot-container mx-auto">
<img src="{{ screenshot }}" alt="Website Screenshot" class="img-fluid rounded shadow">
</div>
{% elif request.method == 'POST' %}
<div class="alert alert-danger mt-3">
Sorry, something went wrong while capturing the screenshot. Please try again.
</div>
{% endif %}
</div>
</body>
</html>
This HTML template uses Bootstrap to keep the design clean and responsive without much custom styling. The form at the top allows users to enter any website URL and submit it to the Flask app using the POST method. Once the app retrieves the screenshot URL from the API, it dynamically renders the image on the page.
The img-fluid class from Bootstrap ensures the screenshot scales properly across all screen sizes while maintaining its aspect ratio. Also, the .screenshot-container provides a scrollable area, which helps display full-page screenshots without shrinking them too much or breaking the layout.
Now your project is set up and ready to capture real screenshots using the ScreenshotBase API.
In the next section, we’ll write the logic to call the ScreenshotBase API and display the resulting screenshot dynamically in the browser.
Integrating the ScreenshotBase API
Now that our Flask app is set up, let’s connect it to the ScreenshotBase API so we can generate real screenshots from any URL.
Step 1: Understanding the API Endpoint
The ScreenshotBase API provides a simple endpoint that takes a website URL and returns a screenshot image.
A typical API call looks like this:
GET
You send the target website URL as a query parameter (url) and include your API key in the request header as apikey.
Here’s the cURL example from their documentation:
curl -G ?url=https%3A%2F%2Fbbc.com \
-H "apikey: YOUR-API-KEY"
This request captures a screenshot of and returns the screenshot image as the response.
Step 2: Add the API Call in Flask
Let’s update our home route in app.py to send a request to the ScreenshotBase API when a user submits a URL.
Here’s the updated version of app.py:
from flask import Flask, render_template, request
import requests
import os
app = Flask(__name__)
API_KEY = os.getenv("SCREENSHOTBASE_API_KEY")
SCREENSHOTBASE_BASE_ENDPOINT = "
@app.route('/', methods=['GET', 'POST'])
def home():
screenshot_url = None
if request.method == 'POST':
target_url = request.form.get('url')
params = {"url": target_url}
headers = {"apikey": API_KEY}
try:
# Send GET request to ScreenshotBase API
response = requests.get(SCREENSHOTBASE_BASE_ENDPOINT, params=params, headers=headers, timeout=30)
response.raise_for_status()
# Save the returned image
image_path = os.path.join('static', 'screenshot.png')
with open(image_path, 'wb') as f:
f.write(response.content)
screenshot_url = image_path
except requests.exceptions.RequestException as e:
print(f"Error capturing screenshot: {e}")
return render_template('index.html', screenshot=screenshot_url)
if __name__ == '__main__':
app.run(debug=True)
Here’s what this code does:
Captures the user input (URL).
Sends a GET request to the
/v1/takeendpoint.Passes your API key in the request header (
apikey).Saves the returned image to the
staticfolder.Displays the screenshot on the page.
Step 3: Test Your App
Run the app again:
python app.py
Enter a URL like:
After submitting, you should see the screenshot of that website displayed below the form.
Your Flask app is now fully functional! It takes a URL, sends it to the ScreenshotBase API, and displays the resulting screenshot.

In the next section, we’ll enhance the app by adding customization options like full-page screenshots, viewport settings, and delays. Later, we’ll explore the ScreenshotBase SDKs for popular languages like Python, Node.js, and PHP.
Adding Customization Options
Right now, our app simply takes a screenshot of the given website URL using the default settings. However, most screenshot APIs (including the one we’re using) allow you to customize the output by passing additional parameters in the request.
The ScreenshotBase API offers several powerful customization options to help you tailor each screenshot to your needs:
Image format: Choose from
png,jpg,gif, orwebp, depending on your image quality or compression requirements.Full page capture: Capture the entire scrollable webpage (
full_page=1) or just the visible viewport (full_page=0).Viewport dimensions: Set the browser window size with
viewport_widthandviewport_heightto simulate screenshots from desktop, tablet, or mobile screens.
These options make ScreenshotBase ideal for building automation tools, thumbnail generators, testing dashboards, and visual documentation systems. Let’s add these options to make our screenshot generator more flexible.
Updating the Flask Code
Open your app.py file and update the route that handles form submissions to include these optional parameters:
from flask import Flask, render_template, request
import requests
import os
app = Flask(__name__)
API_KEY = os.getenv("SCREENSHOTBASE_API_KEY", "scr_live_9Qkn1gs01rivZqrFk7lusXPiqAUg85J86aU6bHvG")
SCREENSHOTBASE_BASE_ENDPOINT = "
@app.route('/', methods=['GET', 'POST'])
def home():
screenshot_url = None
if request.method == 'POST':
target_url = request.form.get('url')
format_ = request.form.get('format', 'png')
full_page = request.form.get('full_page') == 'on'
params = {
"url": target_url,
"format": format_,
"full_page": int(full_page)
}
headers = {"apikey": API_KEY}
try:
# Send GET request to ScreenshotBase API
response = requests.get(SCREENSHOTBASE_BASE_ENDPOINT, params=params, headers=headers, timeout=30)
response.raise_for_status()
# Save the returned image
image_extension = format_ if format_ != 'jpeg' else 'jpg'
image_path = os.path.join('static', f'screenshot.{image_extension}')
with open(image_path, 'wb') as f:
f.write(response.content)
screenshot_url = image_path
except requests.exceptions.RequestException as e:
print(f"Error capturing screenshot: {e}")
return render_template('index.html', screenshot=screenshot_url)
if __name__ == '__main__':
app.run(debug=True)
Updating the HTML Template
Next, let’s modify the form in our index.html to include the customization options:
<form method="POST" class="d-flex flex-column justify-content-center mb-4">
<!-- URL and Submit Button in One Row -->
<div class="input-group mb-4">
<input
type="text"
name="url"
placeholder="Enter website URL"
class="form-control w-50 me-2"
required
/>
<button type="submit" class="btn btn-primary">Capture Screenshot</button>
</div>
<!-- Options in Two Columns -->
<div class="row g-3">
<!-- Full Page Checkbox -->
<div class="col-md-6">
<div class="form-check">
<input
type="checkbox"
name="full_page"
id="full_page"
class="form-check-input"
/>
<label class="form-check-label" for="full_page">
Capture Full Page Screenshot
</label>
</div>
</div>
<!-- Format Dropdown -->
<div class="col-md-6">
<label for="format" class="form-label">Screenshot Format</label>
<select class="form-select" name="format" id="format" required>
<option value="png">PNG</option>
<option value="jpg">JPG</option>
<option value="gif">GIF</option>
<option value="webp">WEBP</option>
</select>
</div>
<!-- Viewport Width -->
<div class="col-md-6">
<label for="viewport_width" class="form-label">Viewport Width</label>
<input
type="number"
name="viewport_width"
id="viewport_width"
class="form-control"
value="1280"
min="320"
/>
</div>
<!-- Viewport Height -->
<div class="col-md-6">
<label for="viewport_height" class="form-label">Viewport Height</label>
<input
type="number"
name="viewport_height"
id="viewport_height"
class="form-control"
value="720"
min="320"
/>
</div>
</div>
</form>
The updated form gives users control over how the screenshot is generated. The format dropdown lets them choose between PNG, JPG, GIF, or WEBP. The Full Page checkbox toggles whether the API captures the entire scrollable webpage or just the visible viewport. The viewport width and height fields define the browser window dimensions, which is useful if you want to simulate different device sizes or responsive layouts.
When the form is submitted, Flask reads these values and sends them as query parameters in the API request.
For example, a request to capture a full-page, 1920×1080 PNG screenshot of your site would look like this:
?url=https%3A%2F%2Fgithub.com%2Fashutoshkrris&format=png&full_page=1&viewport_width=1920&viewport_height=1080
This flexibility makes it easy to fine-tune screenshots for different use cases – whether you’re generating thumbnails, testing responsiveness, or automating visual reports.

Note: If you prefer working with SDKs instead of direct API calls, ScreenshotBase also offers official SDKs for popular languages like Python, JavaScript, Ruby, PHP, and Go.
These SDKs provide a simpler and more convenient way to interact with the API, handling authentication and request formatting behind the scenes.
You can explore them in the ScreenshotBase SDK documentation.
Wrapping Up
In this tutorial, you learned how to build a simple Flask application that captures website screenshots using a third-party API. We explored how to send requests, handle image responses, and add customization options like image format, full-page capture, and viewport size – all while keeping the project lightweight and easy to extend.
This small project demonstrates how web automation tasks, such as generating previews or visual reports, can be simplified using modern APIs. You can build upon this foundation to create batch screenshot tools, visual monitoring systems, or even integrate screenshots into larger web applications.
The key takeaway is understanding how to interact with external APIs, process responses, and design a clean interface for users. These are skills that are essential for backend and full-stack developers alike.



