Skip to content

Repository files navigation

Job Apply Assistant

A local, privacy-first web app for finding real jobs, ranking them against your skills, opening employer application pages, and tracking your progress.

The app is designed especially for students and early-career applicants. It includes Singapore-first ranking and related-role searches for mechatronics, robotics, automation, controls, PLC, embedded systems, and other engineering roles.

Important: this project does not blindly submit applications. It queues selected jobs and opens the real employer pages for you to review. Resume upload, answers, consent, and final submission remain under your control.

Features

  • Search by industry, role, company, country, career level, date, job type, and work arrangement.
  • Search Singapore roles through MyCareersFuture, the national job portal. No API key, no quota, and it returns salary and structured skills on nearly every posting.
  • Optionally add a RapidAPI JSearch key for listings outside Singapore.
  • Fall back to free, no-key sources: Remotive, Jobicy, and Arbeitnow.
  • Expand mechatronics searches to related engineering roles in one request.
  • Prioritize Singapore, student-friendly roles, match quality, and recency.
  • Flag agency bulk postings, mislabelled pay, and long-running reposts, so you can spot recruiter spam and probable ghost jobs before spending time on them.
  • Compare advertised pay against a target salary saved in your profile.
  • Upload PDF, DOCX, or TXT resumes and calculate deterministic skill matches.
  • Tailor your resume to a posting: your own lines are reordered by relevance, unevidenced requirements are reported, and the result exports as a .docx.
  • Remember answers to application questions and refill them on the next form.
  • Save profile details, application notes, follow-up dates, and status changes.
  • Export the application tracker as CSV.
  • Cache identical searches in SQLite for six hours to reduce API usage.
  • Display observed RapidAPI usage and remaining requests when the API provides rate-limit headers.
  • Optionally fill contact fields and saved answers with the Chrome extension.

Quick start on Windows

Easiest method

  1. Install Python 3 if it is not already installed.
  2. Double-click start_job_apply_bot.cmd.
  3. The app opens at http://127.0.0.1:8000.
  4. Double-click stop_job_apply_bot.cmd when you want to stop it.

The launcher automatically looks for pyw, pythonw, py, or python, so it does not depend on a specific username or Python installation folder.

Run from a terminal

python -m pip install -r requirements.txt
python server.py

Then open http://127.0.0.1:8000 in a browser. Press Ctrl+C in the terminal to stop the server.

Requirements

  • Python 3.10 or newer recommended
  • A modern web browser
  • Internet access for live job searches
  • pypdf>=5.0 for PDF resume text extraction

The server and web app otherwise use Python's standard library and plain HTML/CSS/JavaScript. DOCX and TXT resume extraction do not require extra packages.

Job sources

Singapore searches go to MyCareersFuture, the Singapore government job portal. It needs no account and no API key, it responds in well under a second, and it publishes a salary range and a structured skills list on nearly every posting. Those skills feed resume matching and tailoring directly.

Searches for other countries use JSearch through RapidAPI when a key is configured, and otherwise fall back to Remotive, Jobicy, and Arbeitnow, which are mostly remote and software focused.

Known issue: at the time of writing, JSearch's /search-v2 endpoint returns an empty result set for every query and takes about 38 seconds to do so. A key is therefore of little use right now, and none is needed for Singapore.

Optional RapidAPI key

  1. Create or sign in to a RapidAPI account.
  2. Find JSearch and subscribe to an available plan.
  3. Open Set RapidAPI key on the app's home screen.
  4. Paste the value of your X-RapidAPI-Key and select Save.

On Windows, a key saved through the interface is encrypted with Windows DPAPI for the current user. The key is stored under the ignored data/ directory and is never returned by the configuration API.

You can instead provide the key only for the current terminal session:

$env:RAPIDAPI_KEY = "your-key-here"
python server.py

The environment variable takes priority over the saved configuration. On non-Windows systems, using RAPIDAPI_KEY is recommended because DPAPI is a Windows-only feature.

Cached searches use zero additional requests; select Refresh jobs only when fresh results are needed.

Posting quality and salary checks

Every result is checked against a few deterministic signals and annotated with flags for you to review. Nothing is deleted, and nothing is hidden unless you tick Hide flagged postings.

  • Agency postings. MyCareersFuture states outright when a listing is posted on behalf of an undisclosed employer, which is used in preference to guessing from company names. One employer flooding a single result set is also flagged.
  • Batch-coded titles, such as 0731 - Project Engineer, which are typical of bulk recruiter posting.
  • Implausible pay, such as an hourly rate published as a monthly salary, and unusually wide salary bands.
  • Long-running reposts. Roles seen three or more times across at least three weeks are flagged as possible ghost jobs. This relies on locally recorded history, so it only becomes useful after the app has been used for a while.

Set a target monthly salary in your profile and each posting is marked as above, meeting, or below it.

Resume tailoring

Select Tailor resume on any job to rank your resume against that posting.

The tailoring is deterministic and does not use a language model. It reorders lines your resume already contains, marks the ones that match the posting, and lists the requirements your resume does not evidence. It never writes new content and never claims experience on your behalf. Requirements you cannot truthfully support are reported as gaps, not filled in.

Untick anything you do not want, then export a .docx built from the remaining lines. Read it through before sending it anywhere.

Typical workflow

  1. Choose an industry and optionally enter a role, company, and country.
  2. Adjust Student Mode filters and search.
  3. Add your skills or upload a readable resume to enable match scores.
  4. Review the flags on each result and tick Hide flagged postings if you want agency bulk listings out of the way.
  5. Select Tailor resume on a promising role, prune the lines, and download the .docx.
  6. Select jobs, or leave everything unselected to target all visible jobs.
  7. Select Prepare & Open to queue the jobs and open up to 15 employer pages.
  8. Review each employer form, attach your resume, answer required questions, and submit it yourself.
  9. Update each item in the tracker and add notes or a follow-up date.
  10. Export the tracker to CSV whenever you need a backup.

Browser popup settings can limit how many application pages open at once. Jobs that do not open remain queued in the tracker.

Optional Chrome autofill helper

The extension fills recognized empty fields from the local profile and from answers you have chosen to remember. It skips passwords, checkboxes, radio buttons you have already set, hidden fields, file inputs, and submit buttons. It never clicks Submit.

  1. Start the Job Apply Assistant.
  2. Double-click install_chrome_extension.cmd.
  3. In chrome://extensions, enable Developer mode.
  4. Select Load unpacked and choose the extension folder.
  5. Open an employer application page, select the extension, and choose Fill this page.
  6. Review every filled value before continuing.

Answer bank

After you fill in an application form, choose Remember answers on this page. The questions and your answers are saved locally, and the next form that asks something equivalent is filled automatically.

Matching ignores punctuation and filler wording, so "What is your expected salary?" and "Please enter your expected salary" resolve to the same answer, while a question the app does not recognise is left blank rather than guessed. Contact details stay in your profile and are not duplicated into the bank.

Review, edit, or delete anything saved under Answer bank on the home screen.

Some forms use custom components or cross-origin frames, so no autofill tool can reliably fill every site. Resume files must always be selected manually.

Privacy and security

  • The server binds only to 127.0.0.1; it is not exposed to the local network.
  • Profile details, resumes, saved answers, applications, posting history, API configuration, and cached jobs stay under data/ on your computer.
  • data/, .env, virtual environments, caches, and generated files are excluded by .gitignore.
  • Search terms are sent to the selected job providers so they can return jobs.
  • Employer pages receive information only when you enter it or deliberately run the optional autofill helper on that page.
  • The app does not upload a resume to an employer, answer screening questions, agree to terms, or submit an application for you.

Before publishing a fork, verify that data/ and .env are not selected for upload. If a real credential was ever committed, remove it from Git history and rotate it at the provider; deleting only the latest copy is not enough.

To erase local app data, stop the server and delete the data folder. It will be recreated automatically the next time the app starts.

Project structure

job_apply_bot/
├── server.py                       # Local HTTP server, APIs, storage, and job sources
├── requirements.txt                # PDF extraction dependency
├── start_job_apply_bot.cmd         # Portable Windows launcher
├── stop_job_apply_bot.cmd          # Stops this project's server process
├── install_chrome_extension.cmd    # Opens Chrome extension setup
├── static/
│   ├── index.html                  # Web interface
│   ├── styles.css                  # Responsive styling
│   └── app.js                      # Search, matching, tracker, and profile UI
├── extension/
│   ├── manifest.json               # Chrome Manifest V3 configuration
│   ├── popup.html
│   ├── popup.css
│   └── popup.js                    # Safe autofill and answer capture
├── tests/
│   └── test_server.py              # Storage, filtering, matching, tailoring, and quality tests
└── data/                            # Private runtime data; created locally and ignored

Run the tests

python -m unittest discover -s tests -v

The tests use temporary directories and do not read or overwrite your real profile, resume, applications, key, or cache.

Troubleshooting

The app does not open

  • Confirm that Python 3 is installed and available as py or python.
  • Run python server.py in a terminal to see the startup error.
  • If port 8000 is already used by another program, stop that program before launching this app.

No Singapore or engineering jobs appear

Singapore results come from MyCareersFuture and need no key. If nothing is returned, broaden the role, clear the company filter, widen the career level, and try again. For countries other than Singapore you need a RapidAPI JSearch key, and see the known issue noted under Job sources.

A search shows old results

Identical searches are cached for six hours. Use Refresh jobs to bypass the cache or Clear cache to remove all cached searches.

PDF matching is unavailable

Install the dependencies from requirements.txt, then upload the PDF again. You can also enter skills manually or use a DOCX/TXT resume.

Employer pages do not all open

Allow popups for 127.0.0.1, or open the remaining queued jobs individually from the tracker. The app intentionally caps each batch at 15 tabs.

Responsible use

Use job-provider data and employer sites in accordance with their terms, robots policies, and rate limits. Avoid duplicate or low-quality submissions. Always verify that a role is genuine and that the application destination is trusted before sharing personal information.

Licence

MIT.

About

Local, privacy-first job search and application tracker for Singapore. Searches MyCareersFuture with no API key, flags agency bulk postings and ghost jobs, tailors your resume to a posting without inventing experience, and remembers application answers — it never auto-submits.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages