Desktop App

Job Apps Automation v2

PyQt6 desktop app for tracking job applications with built-in AI transformations

Tech Stack

PyQt6OpenAI / Anthropic / OllamaPlaywright + BeautifulSoupPandasLangChain + FAISSWiza APIPython

Overview

Smart Spreadsheet turns a CSV into an intelligent job search command center. Paste a job URL and it auto-scrapes the description with a stealth Playwright browser. Add a LinkedIn profile and it enriches the hiring manager's email via Wiza. One click generates tailored follow-up emails, LinkedIn intro messages, and custom resumes — all with auto-save and transformation history.

The application features a pluggable transformation architecture: each transformation is a self-contained module that defines its inputs, outputs, and processing logic. A ThreadPool executor runs up to 3 transformations concurrently with row-level mutex locking to prevent conflicts. Templates use a custom {{placeholder}} syntax that pulls from row data, user info, and resume files.

Screenshots

Main spreadsheet — Jobs with AI-powered transformations

Main spreadsheet — Jobs with AI-powered transformations

Key Features

9 Built-in Transformations

Web scraper, Wiza enrichment, LinkedIn intro generator, follow-up email writer, resume builder, JD analysis, custom LLM prompts, and more.

Multi-Provider AI

Supports OpenAI, Anthropic, Ollama, and DeepSeek. Switch models per transformation with retry logic for constrained outputs.

Programmatic Resume Generation

Uses FAISS vector store and LangChain to semantically match your experience to job descriptions, then generates tailored resume sections as PDF.

Stealth Web Scraping

Playwright with anti-detection plugins extracts job descriptions from company websites, bypassing bot protection.

Auto-Save + Metadata

Every edit persists immediately. Transformation history stored as JSON sidecar files alongside your data.

Architecture

The application follows a clean separation of concerns: UI components (PyQt6 widgets and delegates), services (file I/O, email, settings, crypto), and transformations (pluggable AI/scraping modules).

The transformation system uses dynamic discovery — new transformations are automatically found by scanning the transformations package. Each inherits from BaseTransformation and defines required inputs, outputs, and a transform() method. The TransformationManager orchestrates execution using QThreadPool with configurable concurrency and row-level QMutex locking.