DEV Community

Mate Technologies
Mate Technologies

Posted on

Build a Simple Job Recommendation Engine with Python and Tkinter

Ever wanted to create a desktop app that recommends jobs based on your skills? In this tutorial, we’ll build a Job Recommendation Engine using Python, Tkinter, and ttkbootstrap.

We’ll cover:

Setting up the project

Defining the job data structure

Fetching and filtering jobs

Building a simple recommendation engine

Displaying results with Tkinter UI

Adding pagination and search

Let’s get started! 🚀

  1. Setup & Install Dependencies

First, make sure you have Python 3 installed. Then install the required packages:

pip install ttkbootstrap pillow requests
Enter fullscreen mode Exit fullscreen mode

Packages explained:

ttkbootstrap → For modern Tkinter UI styling

Pillow → To handle and display images (company logos)

requests → To fetch logos from URLs

  1. Define the Job Data Structure

We’ll use a dataclass to represent each job. This makes it easy to store and manage job info.

from dataclasses import dataclass
from typing import List

@dataclass
class Job:
    title: str
    company: str
    url: str
    description: str
    skills: List[str]
    location: str
    logo_url: str = ""
    score: float = 0.0
Enter fullscreen mode Exit fullscreen mode

✅ This gives each job a title, company, location, skills, logo, and a score for recommendations.

  1. Fetch Jobs

For this tutorial, we’ll use a static list of jobs. Later, you could replace this with API calls.

def fetch_jobs(query: str) -> List[Job]:
    jobs_data = [
        Job("Python Developer", "TechCorp", "https://example.com/job1",
            "Develop backend applications using Python.", ["Python", "Django"], "Remote",
            "https://via.placeholder.com/100x100.png?text=TechCorp"),
        Job("Frontend Engineer", "Webify", "https://example.com/job2",
            "Build responsive web apps with React.", ["JavaScript", "React"], "NY, USA",
            "https://via.placeholder.com/100x100.png?text=Webify"),
        Job("Data Scientist", "DataWorks", "https://example.com/job3",
            "Analyze large datasets and build ML models.", ["Python", "ML", "Pandas"], "SF, USA",
            "https://via.placeholder.com/100x100.png?text=DataWorks"),
    ]

    # Filter jobs by query keyword
    query_tokens = set(query.lower().split())
    matched_jobs = []
    for job in jobs_data:
        text_to_match = " ".join([
            job.title.lower(),
            job.description.lower(),
            " ".join(job.skills).lower()
        ])
        if any(token in text_to_match for token in query_tokens):
            matched_jobs.append(job)
    return matched_jobs
Enter fullscreen mode Exit fullscreen mode

💡 Tip: This simple search matches keywords in the job title, description, or skills.

  1. Build a Simple Recommendation Engine

We’ll assign a score to each job based on keyword matches to rank results.

def recommend_jobs(query: str, candidates: List[Job], top_n=5):
    query_tokens = set(query.lower().split())
    recommendations = []

    for job in candidates:
        text_to_match = " ".join([
            job.title.lower(),
            job.description.lower(),
            " ".join(job.skills).lower()
        ])
        score = sum(1 for token in query_tokens if token in text_to_match)
        recommendations.append((job, score))

    recommendations.sort(key=lambda x: x[1], reverse=True)
    return recommendations[:top_n]
Enter fullscreen mode Exit fullscreen mode

✅ Higher scores mean better matches. This is a simple content-based recommendation.

  1. Load Company Logos

We’ll use Pillow to fetch and display images in the app.

import requests
from PIL import Image, ImageTk
import io

logo_cache = {}

def load_image(url, size=(80, 80)):
    if not url:
        return None
    if url in logo_cache:
        return logo_cache[url]
    try:
        resp = requests.get(url, timeout=10)
        img = Image.open(io.BytesIO(resp.content))
        img = img.resize(size, Image.ANTIALIAS)
        photo = ImageTk.PhotoImage(img)
        logo_cache[url] = photo
        return photo
    except Exception:
        return None
Enter fullscreen mode Exit fullscreen mode

💡 Tip: Caching avoids downloading the same image multiple times.

  1. Build the Tkinter UI

Now let’s build the user interface with ttkbootstrap.

import ttkbootstrap as tb
from ttkbootstrap.widgets.scrolled import ScrolledText
import tkinter as tk

app = tb.Window(title="Job Recommendation Engine", themename="flatly", size=(980, 720))
Enter fullscreen mode Exit fullscreen mode

Top Section: Search Bar

top = tb.Frame(app, padding=15)
top.pack(fill=tk.X)

tb.Label(top, text="Job Recommendation Engine", font=("Segoe UI", 16, "bold")).pack(anchor=tk.W)

query_entry = tb.Entry(top, font=("Segoe UI", 12))
query_entry.pack(fill=tk.X, pady=8)

tb.Button(top, text="Search", bootstyle="primary", command=lambda: print("Search clicked!")).pack(anchor=tk.E)
Enter fullscreen mode Exit fullscreen mode

Results Area

result_frame = tb.Frame(app, padding=(15, 5))
result_frame.pack(fill=tk.BOTH, expand=True)

result_box = ScrolledText(result_frame, autohide=True)
result_box.pack(fill=tk.BOTH, expand=True)
text = result_box.text
text.configure(state="disabled", wrap="word")
Enter fullscreen mode Exit fullscreen mode

This is where job results will be displayed.

Pagination

nav = tb.Frame(app, padding=10)
nav.pack(fill=tk.X)

prev_btn = tb.Button(nav, text="← Prev", bootstyle="secondary")
prev_btn.pack(side=tk.LEFT)

page_label = tb.Label(nav, text="Page 1", font=("Segoe UI", 10))
page_label.pack(side=tk.LEFT, padx=10)

next_btn = tb.Button(nav, text="Next →", bootstyle="secondary")
next_btn.pack(side=tk.LEFT)
Enter fullscreen mode Exit fullscreen mode

💡 You can now hook these buttons to navigate between result pages.

  1. Putting It All Together

Finally, connect the search input with fetching, recommending, and displaying jobs. Use threading to avoid freezing the UI:

import threading

def perform_search():
    query = query_entry.get().strip()
    if not query:
        return
    threading.Thread(target=search_thread, args=(query,), daemon=True).start()

def search_thread(query):
    candidates = fetch_jobs(query)
    recommendations = recommend_jobs(query, candidates)
    for job, score in recommendations:
        print(f"{job.title} @ {job.company} | Score: {score}")
Enter fullscreen mode Exit fullscreen mode
  1. Try It Out

Run your script:

python job_recommender.py

Type a keyword like Python or React

Double-click a job title to open the link (if implemented)

Navigate with Prev / Next buttons

  1. Full Source Code

You can find the full project on GitHub:

https://github.com/rogers-cyber/JOBREC

Conclusion

Congrats! 🎉 You now have a working Job Recommendation Engine with:

Python data classes

Simple content-based recommendations

Tkinter UI with search, results, and pagination

Next steps:

Replace the static job list with real API calls

Add fuzzy matching for smarter search

Enhance UI with images, icons, and filters

Top comments (0)