AI Portrait Generator
lab.kudithipudi.org/portrait/
Upload a photo and generate AI-transformed artistic portraits — Renaissance, Van Gogh, anime, and more — using Google Gemini.
Openlab.kudithipudi.org
Small projects I've built, mostly with AI-assisted coding.
GitHub activity streak
github.com/kudithipudi →
lab.kudithipudi.org/portrait/
Upload a photo and generate AI-transformed artistic portraits — Renaissance, Van Gogh, anime, and more — using Google Gemini.
Openlab.kudithipudi.org/sadhu/
A question-answering service backed by a locally hosted SmolLM language model — no external API calls, responses stream in over SSE.
Openlab.kudithipudi.org/compare/
Looks up US property tax info by address: finds the county appraisal site, scrapes it with Playwright, and extracts structured data with an LLM. Kept live as a historical record; no further development planned.
Openlab.kudithipudi.org/worksheets/
Generates print-ready, TEKS-aligned worksheets for any Texas grade level, subject, and topic, backed by a question bank with LLM fallback.
Openlab.kudithipudi.org/sat-prep/
A full SAT vocabulary app: matching games plus AI-generated practice questions across five question types, with progress tracking.
Openlab.kudithipudi.org/compare-wages/
Internal dashboard comparing entry-level wages to local labor-market data, using LLMs as deterministic pipeline components rather than agents.
Openlab.kudithipudi.org/value-investing/
Ingests every Columbia Graham & Doddsville newsletter issue, extracts each student stock pitch with an LLM, and tracks whether the idea actually worked.
Openlab.kudithipudi.org/gout-stopper/
Snap a photo of food and get a gout-risk read — foods are detected by an LLM, then matched deterministically against an admin-managed Avoid/Limit/OK list. Educational only, not medical advice.
Openlab.kudithipudi.org/bounding-box/
Upload a photo or PDF, describe an object in plain language, and a vision LLM locates it — the returned box is drawn as an overlay on your upload.
Openlab.kudithipudi.org/potato/
A party game where players take turns adding to an AI-generated image until someone breaks the coherence and is eliminated.
Openlab.kudithipudi.org/scissors/
Real-time multiplayer Rock Paper Scissors with phone shake (gyroscope) detection. Host a game, share a code or QR, play best-of-N.
Openlab.kudithipudi.org/rummy/
A simple, mobile-friendly scorekeeper for in-person rummy card games.
Openlab.kudithipudi.org/harada/
A guided, step-by-step generator for Harada Method 9×9 goal-achievement charts, printable on legal-size paper.
Openlab.kudithipudi.org/goals/
Tracks personal goals and habits with flexible per-habit measurements and a 24-hour rolling streak window.
Openlab.kudithipudi.org/bookmark/
A simple, self-hosted bookmarking app. Paste a URL and it auto-fetches title, description, and favicon, then tags it with AI.
Openlab.kudithipudi.org/pretty-print/
Paste any URL and get a clean, reader-formatted version stripped of nav, ads, and chrome, ready to print on Letter or A4. Fetches are offloaded to a cloud browser agent, with SSRF and stored-XSS guards built in.
Openlab.kudithipudi.org/research-people/
Username dossier search powered by Maigret (~2500 sites) — enter a username and watch a live-updating list of confirmed profiles as the scan runs in the background.
Openlab.kudithipudi.org/hoa-vendors/
Neighbor-recommended vendors for the Creekside by Heritage Park Community HOA. Upload a group chat screenshot and browse vendors by category with anonymized recommendations.
Openlab.kudithipudi.org/qr-code/
Generates customizable QR codes — URLs, text, email, SMS, WiFi, and vCards — with a live preview, entirely client-side.
Openlab.kudithipudi.org/net-tools/
What your browser reveals about you — network, hardware, display — plus on-demand tools: WebMCP detection and multi-region DNS resolution.
Openlab.kudithipudi.org/workout-timer/
Lets a trainer run independent countdown interval timers for multiple students at once, each with its own color, tone, and rep counter.
Openlab.kudithipudi.org/web-terminal/
Password-gated browser SSH terminal built on WeTTY — login lockout, signed session cookies, and the server's own OS login as a second auth layer.
Openlab.kudithipudi.org/tx_oz/
An interactive map for browsing for-sale properties inside qualified Opportunity Zones across Texas, with county and price filters. Kept live as a historical record; no further development planned.
Openlab.kudithipudi.org/collage/
Auto-arranges photos into free-form collages across common canvas sizes — Instagram, Facebook, desktop, 4K — entirely in the browser.
Openlab.kudithipudi.org/m1assist/
Real-time object detection in the browser with TensorFlow.js — point a camera at a water bottle and see live bounding boxes, no server involved.
Openlab.kudithipudi.org/network-concepts/
Type any text and watch it get wrapped in TCP, IP, and Ethernet headers on its way to the wire — an interactive look at the handshake, teardown, and how little of what actually travels is your data.
Openlab.kudithipudi.org/webmcp-demo/
A walkthrough of a live WebMCP browser tool — the page registers real, agent-invocable tools in your browser and explains the implementation line by line.
Openlab.kudithipudi.org/phps-jersey/
Jersey-number selection form for the PHPS Elite basketball team — players pick a first and second choice, already-claimed numbers are shown and rejected server-side, with the official size chart alongside. A one-off for a single roster; kept live but not maintained.
Openlab.kudithipudi.org/cic-hackathon/
Multi-judge scoring app for a completed hackathon (11 teams, 3 judges, 132 scores). Kept live as a historical record; no further development planned.
OpenNo apps in this category.
approach
The operating calls that don't change from app to app.
All 29 apps run on one box. No managed database, no serverless platform, no orchestrator. I know how to use those, I just don't need them yet at this scale. One box is cheaper and I can see every layer myself.
One nginx server routes every app by path. No new subdomain, DNS entry, or certificate per app. Shipping app 30 is one location block in a config file, not new infrastructure.
SQLite, unix sockets, and systemd do the job that containers and Kubernetes would do
somewhere else. Twenty-nine low-traffic apps don't need a cluster. Each one restarts
and debugs on its own, with systemctl and journalctl.
Public endpoints that write data are rate-limited by IP address, not locked behind accounts. The real risk here is someone hammering a free tool, not identity fraud. An account system would add friction without solving that.
Every app uses relative paths, not hardcoded ones. Moving an app to a new URL or a new server is a two-line config change, not a rewrite. I got that right on day one instead of fixing it later.
Every LLM call and every scraper has a mock mode. Tests and local development don't spend API credits or wait on a third party to be up. I added that from the start, not after the first API bill.
I keep one standards doc for the whole lab: stack, project layout, config pattern, deploy checklist. A new app doesn't start from a blank page, it starts from that doc. That's specific enough that most new apps get built by an AI coding agent in a single prompt, the same way a good design doc lets an engineer build without coming back to ask me questions.
tech stack
Same stack in every app. I don't want 29 different things to remember how to run.
Runtime
Data
Frontend
AI / LLM
Infra
Testing
architecture principles
And why I made them, not just what I built.
Every app that calls an LLM treats the response as untrusted text. Parsing handles
markdown fences, bare arrays, wrapper objects, and the fact that different providers
don't enforce JSON schemas the same way. Calls go through OpenRouter, so I can
swap models for cost or capability without touching that code.
nginx strips an app's URL prefix before proxying to it. Passing that same prefix to FastAPI looks correct and quietly breaks static files. I hit that bug in eight different apps before I fixed it once, as a convention, instead of eight separate patches. Every background job also logs one ID per run now, so tracing a failure doesn't mean grepping blind.
A few apps hold state in memory: a list of open connections, a cron job, a rate
limiter. Those only work with one gunicorn worker, so I pinned workers = 1 with a
comment explaining why. If traffic ever needs more, the fix is Redis and a
connection pool. I'd rather know that now than find it at 2am.
The LLM, the scraper, the email service — each one has a mock built in from the start, not bolted on for tests later. Nothing in CI spends real money or waits on someone else's uptime, and each integration lives behind its own function instead of being scattered through the app.
A public feature gets a magic link: no password, single use, expires fast. An admin
page gets a real login that fails closed — if the password isn't set, nobody
gets in, not the other way around. Different risk gets a different mechanism, and
password checks use a constant-time comparison, not ==.
A URL I fetch, a page I scrape, text an LLM hands back — none of it is trusted until it's checked. I resolve hostnames before fetching so nothing can reach an internal service. I sanitize HTML before storing it. I rate-limit anything that costs money per call. All of that happens at the edge, before the data gets anywhere near the rest of the app.