Mini Keep is a tiny note-taking backend + UI shipped as one Python file (server.py). It serves a responsive HTML interface, a JSON API, and handles storage/logging without extra dependencies.
- One-file deploy:
server.pyincludes the HTTP server, API, and embedded HTML/JS/CSS UI. - Zero third-party deps: only Python standard library (tested with Python 3.10+).
- Threaded HTTP server with JSON API for CRUD + search.
- Autosaving browser UI with multilingual labels (EN/ES/PT) and client-side search.
- Persistent storage to plain
.txtfiles under/data; automatic log rotation (keeps last 24h) under/log.
- Install Python 3.10+.
- Run:
python3 server.py -p 8000
- Open http://localhost:8000 to use the UI.
/data and /log are created on startup if missing. Default bind host is 0.0.0.0; change the port with -p or --port.
You can keep settings in a JSON config file (and still override them with CLI flags). Supported keys:
{
"port": 8100,
"password": "s3cret",
"log_retention_hours": 48
}--config path/to/config.jsonloads the file. CLI flags win over the config file.--password(or thepasswordkey) enables a simple shared secret; API calls must send headerX-Password: <value>. The web UI will prompt once and store it locally.--log-retention-hours(orlog_retention_hours) controls how long rotated log files are kept (default 24 hours).
All endpoints are JSON. Names are sanitized to A-Za-z0-9_.- and forced to end with .txt.
GET /– serves the HTML UI.GET /list_files– list all notes (most recent first). Response:{ "files": [{ "name", "content", "modified" }] }wheremodifiedis epoch seconds.POST /create_file– body:{ "name": "foo", "content": "text" }; createsfoo.txt. 400 if exists.POST /update_file– body:{ "name": "foo.txt", "content": "new" }; 400 if missing.POST /delete_file– body:{ "name": "foo" | "foo.txt" }; 400 if missing.POST /search_files– body:{ "query": "needle" }; matches on filename or content (case-insensitive).GET /search_files?q=...is also supported.
- Responsive grid of note cards; click to edit.
- Autosave on title/content changes; delete from the modal.
- Language selector (EN/ES/PT); selections are remembered in localStorage.
- Search box issues debounced requests to
/search_files.
- Notes live as individual
.txtfiles in/data(relative toserver.py). - Logs are written to
/log/<timestamp>.log; files older than 24h are purged when new log entries are written.
- Run the built-in tests:
python -m unittest test_server.py
- Test suite spins up the threaded server against temporary
/dataand/logdirectories.
Because everything (server, templates, styles, scripts) is inside server.py, distribution is just copying that one file to your target host. Keep the data/ and log/ directories writable where you run it; they will be created if missing.