Skip to content
Neeraj

Get in touch

Roles, questions, or something you're building — all welcome.

← Work

Prompt-to-Image Generator

A Django app that turns a text prompt into an image via Stability.ai.

Role
Sole author
Timeline
Aug 2024
Status
Coursework
Domain
Generative AI
Stack
Python, Django, Stability.ai API, REST

A prompt goes in, an image comes back, and the API key never touches the browser — the backend owns the credential, the request, and the response parsing.

  • Django backend integrating the Stability.ai generation API.
  • API key held server-side; the client never sees it and cannot call the provider directly.
  • JSON response parsed and the encoded image returned to the page in one flow.
01

The problem

The naive version of this app calls the generation API from JavaScript, which means shipping a paid API key to every visitor. Anyone can read it, and anyone can spend your credits. Putting a backend in the middle is not architecture for its own sake — it is the only place a secret can live.

02

Constraints

  • A paid, rate-limited third-party API — every request costs real money.
  • Generation takes seconds, not milliseconds, so the request cannot feel broken while waiting.
  • The credential must never reach the client.
03

How it fits together

  1. Prompt form

    browser

  2. Django view

    holds the API key

  3. Stability.ai

    generation endpoint

  4. Parse JSON

    extract encoded image

  5. Rendered image

The only reason this has a backend at all: the key lives at the Django view and nowhere else.
04

Decisions and what they cost

Every one of these had a cheaper or more obvious alternative. These are the reasons I didn't take them.

Proxy the API through Django rather than calling it from the client.

Instead ofDirect browser-to-provider calls with a restricted key.

There is no such thing as a client-side secret. Proxying also puts the one place that spends money under my control, which is where any future rate-limiting or caching would have to go anyway.

Server-side response parsing rather than handing raw JSON to the page.

Instead ofReturn the provider's response verbatim and parse it in JavaScript.

It keeps the provider's response shape an implementation detail. If the API changes its envelope, one Django view changes and the frontend does not — and the frontend never learns anything about the provider it does not need to know.

05

What broke

A multi-second generation with no feedback reads as a broken page, and users retry — which costs money on a paid API.

FixMade the pending state explicit in the interface so the wait is legible as work rather than as failure.

06

What I'd do next

The interesting version of this project is the one I did not build: a job queue so generation is asynchronous, a cache so identical prompts do not pay twice, and per-user rate limiting. All three are the same realization — the expensive external call is the thing the architecture should be organized around.