REDIS Console
An interactive Redis console for learning, exploring, and testing Redis
functionality, built with React + Tailwind on the frontend and Nuvolaris /
Apache OpenServerless actions on the backend. All Redis operations go through a
single public action, v1/console, that uses the generated Redis wiring
(ctx.REDIS / ctx.REDIS_PREFIX).
Architecture
- Frontend (
src/): React + TypeScript + Tailwind, HashRouter, shadcn/ui.src/lib/api.ts— fetch helper that unwraps the OpenServerless{body}envelope.src/lib/sections.tsx— the sidebar section registry (add a section here + a page + a route + a dispatch handler to extend the console).src/components/—AppLayout,Sidebar,Header,ConnectionBadge,SectionShell(shared command-area + output-panel layout),OutputPanel.src/pages/sections/— one page per Redis feature area.
- Backend (
packages/v1/console/console.py): a single dispatch action that routes on acmdfield to handlers grouped by Redis data structure. Every key is built fromctx.REDIS_PREFIX; the generated__main__.pywrapper is left untouched.
Sections
Overview · Keys · Laboratories · Strings · Hashes · Lists · Sets · Sorted Sets · Streams · Pub/Sub · TTL · Transactions · Console · Reference
Overview — Live Dashboard
The Overview section (/overview) is a read-only dashboard fed by Redis
INFO and DBSIZE through the v1/console status action (detail: true).
It surfaces: connection status, Redis version, uptime, connected clients, used
memory (with peak), total keys (DBSIZE), current database (with keyspace
breakdown), hit rate (from keyspace_hits/keyspace_misses), expired keys,
and evicted keys. Hit rate is tone-coded (green ≥ 80%, amber ≥ 50%, red below).
Reference — Educational Command Reference
The Reference section (/reference) is a static, frontend-only curated
reference of common Redis commands (src/lib/redis-commands.ts). It never
calls Redis. Users filter by category (Generic, String, Hash, List, Set,
Sorted Set, Stream, Pub/Sub, Transactions, Server) and search by
command/description/syntax. Each entry expands to show the syntax,
argument explanations (with optional markers), and a worked example with its
expected output. Commands are rendered with token-level syntax highlighting.
Console — Safe Raw Redis Terminal
The Console section (/raw, labelled “Console” in the sidebar) is a
terminal-like raw Redis console. The browser sends each typed command to the
v1/console action with cmd: "raw"; the frontend never connects to Redis
directly.
Frontend behaviour:
- Command history persisted for the browser session (
localStorage), with Up/Down arrow navigation. - Enter executes the command.
- Multi-line, redis-cli-style output rendering (quoted strings, numbered
array elements,
(nil)for null). - Execution duration shown per command (backend-measured
duration_ms). - Errors rendered in red.
- Clear-console button (and a separate clear-history button).
Backend behaviour (packages/v1/console/console.py, cmd_raw):
- Commands are parsed with
shlexso quoted arguments such asSET message "hello world"are handled correctly. Noevalor shell execution is used. - A backend-authoritative denylist blocks destructive / server-compromising
commands:
FLUSHALL,FLUSHDB,SHUTDOWN,CONFIG,DEBUG,MODULE,SLAVEOF,REPLICAOF,MIGRATE,RESTORE,ACL,SCRIPT,FUNCTION, andKEYS(use SCAN instead). The same denylist is enforced on the transactions endpoint. - The denylist cannot be bypassed from the frontend: a browser-supplied
allow_dangerous/allow_metaflag is ignored. An operator can explicitly enable the blocked commands only through backend configuration — the environment variableREDIS_CONSOLE_ALLOW_DANGEROUSor a bound action parameterALLOW_DANGEROUSset to a truthy value. - The first key argument is automatically namespaced with the app prefix; no meta/no-key commands receive a prefix.
- The Redis execution duration is measured and returned as
duration_ms.
Keys — Visual Key Explorer
The Keys section is a visual browser, not a command form:
- Search/filter by a glob
patternwith quick chips (*,user:*,session:*,cache:*), a refresh button, and a live key count (loaded so far + DB size). - Keys are loaded with a cursor-based
SCAN(neverKEYS *),countper page, with a Load more button that continues the cursor. Each row shows the key name, RedisTYPE, andTTL. - Selecting a key detects its type and opens a type-aware inspector with safe,
bounded reads (never the whole huge structure at once):
- String: value, length, edit (
SET). - Hash: fields via
HSCAN(paginated), field count (HLEN), add/edit/remove field (HSET/HDEL). - List: index/value via
LRANGE(pageable), length (LLEN),LPUSH/RPUSH/LPOP/RPOP. - Set: members via
SSCAN(paginated), cardinality (SCARD), add/remove member (SADD/SREM). - Sorted Set: rank/member/score via
ZRANGE ... WITHSCORES(pageable), cardinality (ZCARD), add/update (ZADD), remove (ZREM). - Stream: entry id/fields via
XRANGE(count-bounded), length (XLEN), add entry (XADD).
- String: value, length, edit (
- Every visual operation displays the equivalent raw Redis command so the console doubles as a Redis learning tool.
- Deleting a key asks for confirmation and runs
DEL.
The backend gained three ops on v1/console: keys.scan accepts withmeta
to return {name,type,ttl} per key, and hashes.hscan / sets.sscan provide
cursor-based, bounded iteration over large hashes/sets instead of HGETALL /
SMEMBERS.
The UI is responsive (desktop sidebar, mobile drawer) and includes a Redis connection/status indicator, a command execution area, and an output/result panel for each section.
Notes / limitations
- All keys are automatically namespaced with the app’s Redis prefix
(
redisconsole2:). - Pub/Sub
PUBLISHmay be restricted by the platform Redis ACL;SUBSCRIBErequires a long-lived connection that serverless actions cannot hold, so only publish + channel discovery are exposed. The Pub/Sub section explains this limitation in the UI rather than faking subscription behavior. - Transactions (
/transactions) demonstrateMULTI/EXEC,MULTI/DISCARD, andWATCH/MULTI/EXEC. Because OpenServerless requests may use separate Redis connections, the whole transaction runs in a single backend action on one redis-py pipeline / connection so theWATCHlock is held by the same client that issuesEXEC. A built-in “interfere” toggle mutates the watched key betweenWATCHandEXECon that same connection to deterministically demonstrate the optimistic-lock abort path. - Application
.env/.env.productionare managed by Trustable, not by this code.