Skip to content

What I build

Python automation & tooling

Scheduled jobs, API clients and monitoring — with measurement you can argue with.

What this is

I write Python that runs without anyone watching it: scheduled collectors, API clients, data extraction and reporting. The piece of it on this site is a deployment monitor that has been checking every project here every thirty minutes since late September, and its source is public.

How it is built

Python 3.11+ with async httpx for the collection, GitHub Actions for the schedule, and a Cloudflare Worker over D1 for storage and aggregation. The collector classifies every failure rather than recording a bare boolean — DNS, connection, TLS, timeout, HTTP status — because "it was down" is not something you can act on.

  • Scheduled runs on cron, with a watchdog that re-dispatches when the scheduler itself is late
  • An authenticated write API: bearer token compared in constant time, every field validated, every query parameterised, writes idempotent so a replayed batch cannot inflate the numbers
  • SQL that does the real work — uptime, coverage, latency percentiles and incidents derived at read time
  • A public read endpoint, cached, that the dashboard on this site renders

Measurement that admits what it does not know

The part worth looking at is not the uptime number, it is what the queries refuse to claim. Coverage and uptime are reported separately and never combined, so a scheduler that missed a run can never be mistaken for a site that was down. Coverage counts schedule slots rather than samples: a thirty-minute slot counts once however many runs land in it, so a duplicate run cannot pay for a slot that never ran, and a slot still in progress counts on neither side. An incident terminates at a gap in the schedule: failed, gap, failed is reported as two observed incidents with an unknown window between them, not one long outage, because the data cannot support the longer claim. Latency percentiles are gated in SQL below fifty samples, so no code path can report a p95 built from a dozen points.

What this is not

This is applied automation, not data science. I am not offering model training, forecasting or analytics pipelines, and I am not offering to be on call for infrastructure I do not run. What I will do is build the tool, schedule it, make its failures legible, and hand it over with the source.

What you get

  • A Python tool that does one job properly, with its failure modes named
  • A schedule — GitHub Actions, cron, or your own runner — and a way to tell when the schedule itself fails
  • Storage and an API where the job produces data worth keeping
  • Reporting you can read: a dashboard, a CSV, or an endpoint your own tools consume
  • Public or private source, documented, handed over

What it does not include

  • Not data science: no model training, forecasting or ML pipelines.
  • Not managed infrastructure: I build and hand over the tool, I am not on call for it.
  • Anything that scrapes or calls a third-party service runs under that service’s terms and your account, not mine.

Scope, timing and support

What you can expect, before you ask

Timing

Custom Package
quoted per project

Automation work is quoted per project, and no fixed timing is published for it. The effort follows the brief rather than a page count: how many sources there are, how awkward the access is, how often it runs, how much data moves, and how much it has to keep working with nobody watching it.

After handover

30 days of bug fixes after handover

The same on every package — it does not scale with the tier.

Covered

  • Anything inside the agreed scope that does not work the way it was agreed.

Not covered

  • New features, content changes and design changes — those are new work, quoted separately.
  • Anything that was never in the agreed scope.
  • Breakage caused by third parties or by editing the delivered code yourself: hosting changes, expired services, dependency changes outside the build I handed over.

The 30 days run from handover. Ongoing support and maintenance are available separately.

Hosting, domains and paid services

Every account is in your name. You own the domain, the hosting and the data; I configure and deploy into them. Nothing is held on my accounts.

You pay third parties directly. Nothing is billed through me.

Many projects run comfortably on free tiers — Vercel, Cloudflare — and I will use them where they genuinely fit. A site with real traffic or heavier requirements may need a paid plan, and I will say so before we start rather than after.

  • Domains always cost money. There is no free tier for a real domain.
  • Paid APIs and services are pass-through, billed to your account.
  • Licensed fonts and stock imagery are pass-through.

Send these six things and the quote means something

  1. Where the data comes from, and how I get to itAn API with a key, a folder of files, a page to read, a database. Access is usually the first thing that blocks a start.
  2. One real example of the input, and the output you want from itA sample file and a sketch of the result settle more scope than a page of description.
  3. How often it runs, and how much data each timeOnce a day over a few hundred rows is a different build from every five minutes over millions.
  4. Where it should runA scheduler like GitHub Actions, a cloud function, your own server, or your machine. That changes how it is built, not only where it lands.
  5. What should happen when it failsRetry quietly, alert someone, write a report, or stop and wait. A job nobody is watching needs this decided before it runs rather than after.
  6. Your deadline, if you have oneIt changes the plan. It is not a problem if I know early.

What happens next

Send the six answers above — two lines each is plenty. I reply with what I would build, how long it would take and what it would cost, usually within a day.