The web page and containers#
flask serves a paste-and-go page: paste a prompt, copy the redacted
version, paste the model’s reply back, read the restored answer. It needs the
web tier (Flask).
pip install "scikit-plots[cleanprompt-web]"
python -m scikitplot.cleanprompt flask --open
The page shows what is not being detected before you paste anything — the one moment that warning is worth reading.
How it keeps your data#
The vault stays on the server, in a bounded, expiring store keyed by an opaque token. The cookie carries the token and nothing else.
Every form carries a CSRF token, compared in constant time.
The session key is configuration. Without
CLEANPROMPT_SECRET_KEYa local run uses a per-process key (sessions end with the process), and container mode refuses to start.Entity detection uses the same engine selection as every other surface:
flask --ner --ner-engine nltk --lang enruns exactly that, and a request the machine cannot meet refuses to start with the remedy, instead of serving a page whose banner claims names are being found.
Who can reach it#
Command |
Bind and exposure |
|---|---|
|
|
|
refused: reachable from other machines, no authentication |
|
allowed, and the banner names the exposure |
|
|
Debug mode is loopback only. Flask’s debug mode serves an interactive
debugger that runs Python typed into the browser. --debug is therefore
refused with --docker or any non-loopback --host, whatever else is
acknowledged: --allow-remote accepts that the page is reachable, not
that code execution is.
This is Flask’s development server: right for one person on one machine, wrong for a shared deployment. A shared deployment needs authentication, TLS and a production server in front of it, which this command does not provide.
Container files#
python -m scikitplot.cleanprompt docker --write ./deploy
python -m scikitplot.cleanprompt docker --write ./deploy --with-ner
This writes a Dockerfile, a docker-compose.yml, a .dockerignore and
a README.md. Everything in them is derived from the runtime:
Loopback publishing. Both the compose file and the
docker runline publish127.0.0.1:PORT:PORT. Docker’s-p PORT:PORTwithout an address publishes on every interface of the host — do not shorten it.The model it installs is the model it runs. With
--with-nerthe image downloads the model the runtime resolves (en_core_web_smby default) and starts with--ner --ner-engine spacy --ner-modelnaming that same model, so the two cannot drift apart.A secret key with no default.
CLEANPROMPT_SECRET_KEYis required; a default would be a published secret shared by every deployment.Least privilege. The image runs as a non-root user; the compose file mounts the filesystem read-only, drops every capability and sets
no-new-privileges..dockerignorekeeps vault files out of the image.
export CLEANPROMPT_SECRET_KEY="$(python -c 'import secrets;print(secrets.token_hex(32))')"
docker compose -f deploy/docker-compose.yml up --build
# then open http://127.0.0.1:5000
From Python, container_files returns the
same files as strings and takes language and model_size for the model
layer.
The terminal session#
cli is the same loop in a terminal, holding one vault for the session:
$ python -m scikitplot.cleanprompt cli
CleanPrompt interactive session
Paste your text, then press Ctrl-D on a blank line to submit.
Commands: :hide TERM :allow TERM :suggest :why :again :quit