Skip to content

I automate the boring parts of running a business.

I'm Luka Puhmeister, a Python developer from Slovenia. I've built tools that sort my job search, track my training and handle my PDFs. Now I build them for businesses, along with lightweight websites.

~/jobs · cron

Jobs like these run on a schedule while you do something else.

Tools I built because doing it by hand got old.

Most started as a chore of mine. Two didn't: I built pitwall to see a whole Formula 1 race on one page, and Clearhouse to show how I clean up data I can't trust. Nearly all the code is on GitHub.

Job search automation

napotnica

Pulls student job ads, ranks them against my profile and writes a tailored CV for the ones worth applying to.

Problem
Finding student work meant scrolling a few hundred ads on studentski-servis.com and rewriting a CV for every application.
What I built
A local scraper that stores every listing in SQLite, scores each one with an LLM that has to explain its score, and prints a CV and cover note to PDF.
Outcome
Now I read a short list sorted by fit, with net and gross pay next to each other, instead of hundreds of ads.
  • Python
  • Flask
  • Playwright
  • SQLite
  • Groq

Training dashboard

Loadout

One dashboard for my lifting and my runs, so I can see how hard a week really was.

Problem
Hevy knew about my lifting, my watch knew about my runs, and nothing showed how hard a week was across both.
What I built
A self-hosted Flask app that syncs workouts from the Hevy API, reads the GPX and FIT files from my watch, and turns both into one load score.
Outcome
A 12-week chart that warns me about bad combinations, like a heavy leg day and a 12 km run within 24 hours.
  • Python
  • Flask
  • SQLite
  • Chart.js
  • Hevy API

Desktop app

Folio PDF

Merge, split, compress and batch-process PDFs without uploading them anywhere.

Problem
Merging two PDFs meant uploading private documents to whichever website showed up first.
What I built
A Python desktop app with a drag-and-drop page grid, batch jobs for whole folders, and Word to PDF that runs through Word itself, so the layout doesn't shift.
Outcome
My documents stay on my own computer. I built it on macOS, and it runs on Windows too, with less testing there.
  • Python
  • CustomTkinter
  • PyMuPDF
  • pypdf
Three Rye screens: today's calorie ring and macro bars, the food diary for one day, and a weekly report

iOS app

Rye

Calorie, protein and fibre tracker with Slovenia-first food search that works offline.

Problem
MyFitnessPal tucks fibre away under carbs and comes with ads, a feed and a subscription. Most Slovenian barcodes aren't in the open food database either: 4 of the 5 I tested came back empty.
What I built
A plain web app with no framework or build step, wrapped as a native iPhone app with Capacitor. Search checks Slovenian products first, and anything the database doesn't know gets saved once with its barcode.
Outcome
Fibre sits next to carbs, protein and fat as a fourth macro. Everything stays on the phone, and saved foods come up without a connection.
  • JavaScript
  • Capacitor
  • Open Food Facts

API and dashboard

pitwall

Puts a Formula 1 race on one page: the official result, tyre strategy and lap times, merged from two free APIs.

Problem
One API has the official result and no timing. The other has lap times and tyre stints, but it lists drivers by car number and locks free users out while a session is live.
What I built
A FastAPI service that pulls from both, lines the drivers up and caches every response in SQLite. It stays under each API's rate limits and retries what fails. A dashboard in plain JavaScript shows the result, the tyre strategy and the lap times.
Outcome
I ran all 86 races from 2023 to round 16 of 2026 through it, and every one found its timing data. When one source is down you still get the other, with a label for what's missing. There's no timing before 2023, because the timing API doesn't go back further.
  • Python
  • FastAPI
  • httpx
  • SQLite

Data pipeline

Clearhouse

Cleans up order exports from three systems that don't agree, then checks its own work against a known answer.

Problem
A till, a webshop and a wholesale feed export the same orders in three formats, with some orders in two of them. Cleaned-up data can look right while the totals are wrong.
What I built
A Python pipeline that reads the CSV, JSON and XML, fixes what it can without guessing and sets the rest aside with a reason. I generate the exports myself and log every defect I put in, so a separate scorer can grade each run.
Outcome
On the default dataset it sorts all 1,220 orders correctly and matches the true revenue to the cent. The data is made up, so that covers the defects I thought to inject and nothing more.
  • Python
  • pytest
  • mypy
  • GitHub Actions

One smaller tool, and two experiments that didn't work

Who you'd be working with

Almost everything on this page started as something I was sick of doing by hand. I built a tool for it, used it for a while, and kept whatever stuck.

Client work goes the same way, and it's usually small: a script that runs every morning, or a scraper that fills in the spreadsheet you used to update yourself. I'll explain it in plain language, and if a job isn't worth automating, I'll tell you before you pay for anything.

If you're hiring, nearly all of the code is on GitHub, failed experiments included.

Illustration of Luka Puhmeister working on a laptop, with his black and white dog resting beside him
Based in
Slovenia
Languages
Slovenian, English
Focus
Automation, scrapers, internal tools, websites

Toolbox

  • Scraping and automation

    Python, Playwright, requests, SQLite, SQLAlchemy

    Used in napotnica, Polymarket AI

  • Web and mobile apps

    Flask, FastAPI, Jinja2, Chart.js, Next.js, Capacitor

    Used in Loadout, pitwall, Rye, this site

  • Documents and desktop

    PyMuPDF, pypdf, fpdf2, CustomTkinter

    Used in Folio PDF, Hevy exporter

  • Data and AI

    XGBoost, VADER, Groq, Claude API

    Used in napotnica, Polymarket AI, CryptoBot

What I can take off your hands.

Most of the jobs I take on are small and specific, and you know the price before I start.

How a project goes

  1. You show me the task

    We have a short call or swap a few emails, and you walk me through how the job gets done today.

  2. I send a fixed quote

    It says what I'll build, what it costs and when it'll be ready. Nothing starts until you're happy with it.

  3. We build it in small steps

    You try working pieces early, so if I've misunderstood something, we catch it while it's cheap to fix.

  4. You get the code

    You also get a short guide for running it. Nothing is tied to my accounts, so another developer can pick it up later.

  • Automation

    Copying numbers into the same spreadsheet every Monday, or renaming invoices one at a time. I turn chores like that into a script, or a job that runs on its own.

    • Reports to PDF/Excel
    • Syncing between tools
    • Email and file workflows
  • Web scraping and data

    If the data is on a public website, like prices, listings or a competitor's catalogue, I can collect it on a schedule and put it in a spreadsheet or inbox you already use.

    • Price monitoring
    • Lead lists
    • Listing alerts
  • Internal tools and dashboards

    Small web apps for one team or one job. Your data sits in one place, and the numbers you check every day are on the first screen.

    • Flask + SQLite apps
    • Admin panels
    • KPI dashboards
  • Websites for small businesses

    Simple sites that work well on a phone and have the basics in place so people nearby can find you. Hosting costs next to nothing.

    • Business sites
    • Contact and booking forms
    • Hosting on Cloudflare

Send me the task you repeat every week, and I'll tell you whether it's worth automating.

You don't need a brief. A few sentences is plenty.

Useful to include

  • What the task is and how often you do it
  • Which tools or files it touches, like Excel, a web shop or email
  • Roughly how long it takes you now
  • Any deadline you're working to

Pišem tudi v slovenščini.