Many of us have mobile phones and laptops that take screenshots. Have you ever wondered how that was made possible? It was a feature added while designing the software component of the device using programming languages.
This shouldnβt surprise us. Software developers are working tirelessly to make life easy for us. While such a feature was implemented using programming languages for mobile and desktop applications, we can learn how to do so on web applications using Python.
ππ· Many Python libraries can be used to take screenshots. These include pyautogui
, and pillow
. But the drawbacks with these libraries are that they do not offer a nice user experience such as specifying a particular width or height. They do not block ads or banners. What is more, the screenshot is only limited to the current screen.

Therefore, in this tutorial, we will take advantage of an API that is well-suited for such a task using the Django web framework. In the web application, the user will input a URL and will take a screenshot of that website when a button is clicked.
Urlbox is the API we will use. It is a paid service but we can try the features for free for seven days. Register for a free trial account to get your API key and secret key we will use in this project.
Main Libraries Needed
- Django β for creating web application
- Urlbox β to use the Urlbox API
- Pillow β for displaying screenshot images
- Tzdata β for dealing with timezones
- Python-decouple and python-dotenv β for loading environment variables
plus a host of other dependencies.
17 Steps to Create a Screenshot Web Application using Django
We will follow 17 steps to design a screenshot-taking website using Django.

You can follow along even if you have little knowledge of the command line as I will be showing you everything I did. But you are expected to have basic knowledge of Python, and the Ubuntu terminal installed on your system to attempt this project tutorial.
Step 1: Create and move into a new folder
mkdir django_project && cd django_project
Step 2: Create and activate a virtual environment
python3 -m venv .venv source .venv/bin/activate
Step 3: Install django pyautogui pillow tzdata
pip install django urlbox pillow tzdata python-decouple python-dotenv
Step 4: Create a requirements.txt
file
pip freeze > requirements.txt
This will be used in the future if a new version that affects the web application was released.
Step 5: Start Django project in the current folder and Django app
django-admin startproject project . python3 manage.py startapp screenshots
Now, you are expected to have the following files in your current folder.
manage.py project requirements.txt screenshots
Step 6: Create a .env
file to store your API key and secret key
API_KEY = 'YOUR API KEY' SECRET_KEY = 'YOUR SECRET KEY'
Step 7: Create two additional folders for the template files and media files.
mkdir templates media
Step 8: Inform Django in the INSTALLED_APP
section of the settings.py
file that a new Django app is created
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # custom app 'screenshots', ]
Step 9: Register the templates folder in the TEMPLATES section of the settings.py
file
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], # add these 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
Step 10: Register the media folders at the last line of the settings.py
file
MEDIA_URL = 'media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Be sure to import the os
module.
Step 11: Create a database model for storing the screenshots
from django.db import models class Screenshot(models.Model): url = models.CharField(max_length = 100 , blank = False,null = False) photo = models.ImageField( upload_to='images' )
The images will be saved to the images folder inside the media folder. So, make sure you create the folder.
Step 12: Create and apply migrations
python3 manage.py makemigrations screenshots python3 manage.py migrate
Step 13: Register the project-level URLs. Go to projects/urls.py
file
from django.contrib import admin from django.urls import path, include from django.conf import settings from django.conf.urls.static import static urlpatterns = [ path('admin/', admin.site.urls), path('', include('screenshots.urls')), ]+static(settings.MEDIA_URL,document_root = settings.MEDIA_ROOT)
This points to the variables we added in step 10 which in turn points to the media
folder. Whenever we are storing images in a Django application, this action is to be taken.
Step 14: Β Create the view function in screenshots/views.py
file.
from django.shortcuts import render from urlbox import UrlboxClient from django.core.files.base import ContentFile from decouple import config from .models import Screenshot API_KEY = config('API_KEY') SECRET_KEY = config('SECRET_KEY') def index(request): if request.method == 'POST': user_url = request.POST['url'] client = UrlboxClient(api_key=API_KEY, api_secret=SECRET_KEY) response = client.get({'url': user_url, 'full_page': True, 'block_ads': True}) file = ContentFile(response.content) screenshot = Screenshot(url=user_url) screenshot.photo.save('image.png', file) context = { 'img': screenshot } return render(request, 'index.html', context) return render(request, 'index.html')
After importing the necessary modules and classes, we load environmental variables. Then, we create a view
function. The function retrieves the URL from an HTML form and passes it to the UrlboxClient
class of the urlbox
module which already has the API key and secret key.
Notice how we use python-decouple
to retrieve the API key and Secret key without exposing them. These are considered best practices.
In the response variable, we customize how we want the images to appear for a nice user experience. When a request is made, we want to get the full page and block ads from being captured. This is why using the Urlbox
API is one of the best ways to screenshot a web page. You can check the documentation for other customizations.
Once the screenshot is captured, we save it to a ContentFile
object. Django uses this class to handle files.
Afterward, we save it to the Screenshot
model. No doubt, we will like to see the screenshot that is captured by the API. So, we pass the model object to the render
function to be rendered in the index.html
template file.
Step 15: Add templates file in the templates
folder
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Take Screenshots</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css" /> </head> <body> <nav aria-label="main navigation" class="navbar is-dark" role="navigation"> <div class="navbar-brand"> <a class="navbar-item"> Home </a> </div> </nav> <div class="container"> <div class="notification is-primary is-bordered" style="margin-top: 20px;"> <form action=" " , method="post"> {% csrf_token %} <div class="field"> <label class="label">Url</label> <div class="control"> <input class="input is-link" name="url" type="text" placeholder="Enter URL" /> </div> </div> <div class="control"> <button class="button is-link is-centered is-rounded"> Take Screenshot </button> </div> </form> </div> </div> <div class="container"> <img src="{{ img.photo.url }}" /> </div> </body> </html>
Using djangoβs {β¦}
block makes it easy to display the image to the template file. Once the screenshot is taken, the image will be displayed.

Since we are working with form, we pass in the csrf_token
statement for security. As we can see, the form has the method as POST.
Notice that in the img
tag, we did not specify any path, Django already knows where the image will be stored.
Step 16: Register the app-level URLs in the app
folder.
from django.urls import path from .views import index urlpatterns = [ path('', index, name='indexβ), ]
We have to create a urls.py
file inside the screenshots
folder and add the above snippets.
Step 17: Start the local server
python3 manage.py runserver

Conclusion
Congratulation on creating a screenshot-taking website! π·
You have learned how to install Django, load environmental variables, make an API call and render the results to a web page.
You are fully on course to designing complex web applications using the Django framework. Get the full code from my GitHub page.