Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/validate-notebooks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Validate notebooks

# Structure/syntax validation only — this does NOT execute the notebooks
# (that would need a Gemini API key and heavy ML dependencies). It catches
# broken JSON and syntax errors before they land, mirroring the local checks.

on:
push:
paths:
- "**/*.ipynb"
- ".github/workflows/validate-notebooks.yml"
pull_request:
paths:
- "**/*.ipynb"
- ".github/workflows/validate-notebooks.yml"

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install nbformat
run: pip install nbformat
- name: Validate structure and compile code cells
run: |
python - <<'EOF'
import glob, sys, nbformat

failed = False
notebooks = sorted(glob.glob("**/*.ipynb", recursive=True))
if not notebooks:
print("No notebooks found."); sys.exit(0)

for path in notebooks:
try:
nb = nbformat.read(path, as_version=4)
nbformat.validate(nb)
except Exception as e:
print(f"::error file={path}::invalid notebook: {e}")
failed = True
continue
for i, cell in enumerate(nb.cells):
if cell.cell_type != "code":
continue
# Drop notebook-only lines (shell '!' and magics '%') before compiling.
code = "\n".join(
line for line in cell.source.splitlines()
if not line.lstrip().startswith(("!", "%"))
)
try:
compile(code, f"{path}[cell {i}]", "exec")
except SyntaxError as e:
print(f"::error file={path}::syntax error in code cell {i}: {e}")
failed = True
print(f"checked {path}")

sys.exit(1 if failed else 0)
EOF
29 changes: 29 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Jupyter
.ipynb_checkpoints/
*/.ipynb_checkpoints/*

# Python
__pycache__/
*.py[cod]
*.egg-info/
.pytest_cache/

# Virtual environments
.venv/
venv/
env/

# Secrets / local config
.env
*.local

# Chroma / embeddings local persistence
.chroma/
chroma/
*.sqlite3

# OS / editor cruft
.DS_Store
Thumbs.db
.vscode/
.idea/
51 changes: 51 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# AI Resume Builder

A hands-on workshop that builds an **AI resume-tailoring tool** in stages — from a single-prompt script to a production-style pipeline with retrieval, a multi-tool agent, and safety guardrails. Each notebook is self-contained and runs in Google Colab.

Given a job description, a resume, and (optionally) a GitHub username, the tool rewrites the resume to fit the role and explains *what changed and why* — while staying grounded in what the source material actually says.

## Notebooks

| Notebook | What it teaches | Open |
| --- | --- | --- |
| **V1 — Learning the Basics** | One Gemini prompt: paste a JD + resume, get a tailored resume back. Introduces the API and the "what changed and why" pattern. | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/camunity/ai_resume_builder/blob/main/AI_Resume_Builder_v1.ipynb) |
| **V2 — Production AI Features** | Rebuilds the tool with production patterns: RAG (chunking, embeddings, retrieval, evaluation), a multi-tool agent with graceful failure, and AI-safety guardrails (prompt-injection screening, rate limiting, audit logging). | [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/camunity/ai_resume_builder/blob/main/AI_Resume_Builder_v2_Phase2.ipynb) |

> **V1.1** is an interim step (URL-based JD fetch, resume file upload, graceful GitHub failures) summarized inside the V1 notebook rather than shipped as a separate file.

## Prerequisites

- A **Google Gemini API key** — create one at [Google AI Studio](https://aistudio.google.com/app/apikey).
- A Google account for Colab (recommended), or a local Jupyter environment.

## Running in Colab (recommended)

1. Open a notebook with a badge above.
2. Add your API key to Colab **Secrets**: click the 🔑 icon in the left sidebar, add a secret named `GOOGLE_API_KEY`, and enable notebook access.
3. Run the cells top to bottom. The first cell installs dependencies.

## Running locally

```bash
git clone https://github.com/camunity/ai_resume_builder.git
cd ai_resume_builder
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
jupyter notebook
```

Locally, the notebooks read the key from Colab Secrets, so replace the
`from google.colab import userdata` / `userdata.get('GOOGLE_API_KEY')` lines with
`os.environ["GOOGLE_API_KEY"]` and export the variable before launching Jupyter:

```bash
export GOOGLE_API_KEY="your-key-here" # Windows: setx GOOGLE_API_KEY "your-key-here"
```

## A note on data / PII

Your resume (name, email, phone) and any scraped job description are sent to the Gemini API, and the optional GitHub step calls the public GitHub API. Don't paste anything you wouldn't share with a third-party service — prefer a redacted resume in a live workshop.

## License

Licensed under the **GNU GPL v3** — see [LICENSE](LICENSE).
12 changes: 12 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Dependencies for the AI Resume Builder notebooks (local / non-Colab runs).
# Colab preinstalls several of these; the notebooks also `!pip install` what they
# need. Versions below are minimums known to work — pin them exactly if you need
# fully reproducible workshop environments.
#
# Note: sentence-transformers pulls in PyTorch, which is a large download.

google-generativeai>=0.8.0 # Gemini API client (import google.generativeai)
chromadb>=0.5.0 # local vector store for RAG retrieval
sentence-transformers>=3.0.0 # all-MiniLM-L6-v2 embeddings
beautifulsoup4>=4.12.0 # scraping JD text from a URL
requests>=2.31.0 # GitHub API + URL fetch