CVAlchemix
Stop sending the same CV to every job. CVAlchemix scrapes LinkedIn postings and rewrites your CV with AI — tailored, compiled, and PDF-ready in seconds.
🎬 Demo
✨ Features
- Scrapes LinkedIn job title, company, location, and full job description with Playwright.
- Reuses a persistent browser profile so you can keep a logged-in LinkedIn session.
- Prompts for a Gemini API key and a plain-text base CV, then stores them locally for later runs.
- Includes a built-in
cvalchemix logincommand to open LinkedIn and persist an authenticated browser session. - Rewrites the CV into a structured
CVDataschema using Google Gemini. - Renders the final CV through a Jinja2 LaTeX template and compiles it to PDF with
tectonic. - Saves the intermediate
.texfile alongside the PDF so you can inspect the generated LaTeX. - Includes
show-configanddeletecommands for inspection and cleanup.
🎯 Use Cases
- A job seeker can paste a LinkedIn posting and generate a tailored CV PDF that mirrors the role's keywords and structure.
- A candidate applying to several roles can reuse the same base CV and produce a separate PDF for each company and posting.
- A developer can automate a job-application workflow by combining the scraper, Gemini rewrite step, and PDF renderer in one CLI.
- Someone keeping a persistent LinkedIn session can avoid repeated logins when scraping job pages over time.
- A career coach or reviewer can inspect the generated
.texand final PDF to understand how the CV was reshaped for a role.
⚠️ Current Limitations
These are known limitations in the current version. They will be addressed in future releases.
-
LinkedIn URL format: Only the following URL pattern is currently supported:
https://www.linkedin.com/jobs/collections/recommended/?currentJobId={currentJobId}Other LinkedIn URL shapes such as
/jobs/view/and search-result pages are not yet supported. -
AI Provider: Currently only Google Gemini is supported as the AI provider.
-
External renderer: PDF generation depends on a local
tectonicbinary being available onPATH. -
Scraping fragility: The scraper relies on LinkedIn CSS selectors, so LinkedIn DOM changes can break extraction.
-
Template scope: Only one bundled LaTeX template,
classic.tex.j2, is shipped right now. -
No built-in fit score: The repository contains structured analysis models, but there is no user-facing command that emits a standalone job-match score or analysis report yet.
🔩 Prerequisites
- Python >= 3.10
- A Google Gemini API key
tectonicinstalled and available on yourPATH
Playwright and its browsers are installed automatically as part of the Python dependencies — no manual step needed.
📦 Installation
Option 1 — pip
pip install cvalchemix
Option 2 — pipx (recommended for CLI tools)
pipx install cvalchemix
Option 3 — One-command install (macOS/Linux)
curl -fsSL https://raw.githubusercontent.com/kayesFerdous/CVAlchemix/main/install.sh | bash
If you don't have curl:
wget -qO- https://raw.githubusercontent.com/kayesFerdous/CVAlchemix/main/install.sh | bash
Option 4 — Windows (PowerShell)
irm https://raw.githubusercontent.com/kayesFerdous/CVAlchemix/main/install.ps1 | iex
The installer scripts prefer
pipxand fall back topip --userwhen needed. You can override the install source with theCVALCHEMIX_INSTALL_TARGETenvironment variable.
✅ Verify Installation
cvalchemix --help
🚀 Quick Start
1. Configure the app with your Gemini key and a plain-text base CV.
cvalchemix configure
2. Optional but recommended — open a persistent LinkedIn session once so the scraper can reuse it.
cvalchemix login
3. Generate a tailored CV from a LinkedIn job URL.
cvalchemix generate "https://www.linkedin.com/jobs/collections/recommended/?currentJobId=1234567890" -o ./output
The CLI writes the final PDF to ./output/cv/<company>_<timestamp>/cv.pdf and saves the intermediate LaTeX source as cv.tex in the same directory.
📖 Usage
| Command | What it does | Example |
|---|---|---|
cvalchemix configure |
Prompts for a Gemini API key and the path to your base CV text file, then saves them in the local config file. | cvalchemix configure |
cvalchemix login |
Opens LinkedIn in a persistent Playwright browser profile and stores login readiness for later generate runs. | cvalchemix login |
cvalchemix show-config |
Displays the saved configuration and masks the stored API key. | cvalchemix show-config |
cvalchemix generate <job-url> |
Scrapes a LinkedIn job post, rewrites your CV with Gemini, and renders a PDF. Use -o or --output to set the destination directory. |
cvalchemix generate "https://www.linkedin.com/jobs/collections/recommended/?currentJobId=1234567890" -o ./output |
cvalchemix delete |
Removes local CVAlchemix data and uninstalls the package by default. Use --data-only to keep the CLI installed, and -y to skip confirmation. |
cvalchemix delete -y |
⚙️ Configuration
CVAlchemix uses two layers of configuration:
- CLI config — run
cvalchemix configureto save yourgemini_api_keyandbase_cv_pathinto a local JSON config file under your platform user config directory. - LinkedIn session — run
cvalchemix loginonce to open LinkedIn and savelinkedin_login_configuredfor generate preflight checks. - A
.envfile in the working directory is also read if present.
Environment Variables
| Variable | Default | Purpose |
|---|---|---|
GOOGLE_API_KEY |
empty | Gemini API key used by the settings layer. |
DEFAULT_MODEL |
gemini-2.5-flash-lite |
Gemini model name used by the LLM wrapper. |
PROFILE_DIR |
managed app profile directory | Playwright browser profile location for persistent LinkedIn sessions. |
OUTPUT_DIR |
./output |
Default output directory used by the settings layer. |
BROWSER_HEADLESS |
false |
Launch Playwright in headless mode when set to true. |
SCRAPE_TIMEOUT_MS |
30000 |
Timeout in ms while waiting for LinkedIn page content to load. |
MAX_RETRIES |
3 |
Number of retries defined by the configuration layer. |
LOG_LEVEL |
INFO |
Root logging level. |
A .env.example file with starter values for all of the above is included in the repository.
🗺️ Roadmap
- OpenAI / Anthropic provider support
- Additional CV templates
- Job-fit score command
- Broader LinkedIn URL support
🛠️ Local Development
git clone https://github.com/kayesFerdous/CVAlchemix.git
cd CVAlchemix
./install.sh # macOS/Linux
.\install.ps1 # Windows PowerShell
For a development install with editable mode:
pip install -e ".[dev]"
🤝 Contributing
- Fork the repository and create a focused branch for your change.
- Make the smallest practical change and keep the existing CLI behaviour intact unless the change explicitly requires otherwise.
- Verify the project still starts, configure the CLI, and run a sample
generateflow if your change touches the pipeline. - Open a pull request with a clear description of the change, the motivation, and any manual verification you performed.
📄 License
This project is licensed under the MIT License. See LICENSE for details.
Release files for cvalchemix 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cvalchemix-0.1.4.tar.gz | 28.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cvalchemix-0.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 57.1 kB
Release files / cvalchemix-0.1.4.tar.gz
| Download URL | cvalchemix-0.1.4.tar.gz |
|---|---|
| Size | 28.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cb1a776235d889213acc44809e8a1e685405966f80119693be6290e4294531fc
|
|
BLAKE2b-256 checksum How to use checksums |
5a1d5ee534906d14e42117ae68090bd16939bec438e183ba233b70f77917d3ae
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.5
|
Release files / cvalchemix-0.1.4-py3-none-any.whl
| Download URL | cvalchemix-0.1.4-py3-none-any.whl |
|---|---|
| Size | 29.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3037b9875d4db8961fa090ebab9450ff821f5f97b2920d4004591a00437bc0f2
|
|
BLAKE2b-256 checksum How to use checksums |
6bf52fb6f817256ac679b559a98f74a221e9e14bfc73e25d7d524bce3101ceb6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.5
|