questionary

Beautiful interactive CLI prompts for Python — provides styled terminal question types with keyboard navigation. questionary features: text() for free-text input, password() for hidden input, confirm() for yes/no, select() for single-choice with arrow keys, checkbox() for multi-choice, rawselect() for numbered selection, autocomplete() for filtered selection, path() for file path with completion, print() for styled output, validate= parameter for inline validation, style= for custom colors, ask() and ask_async() for async support, and skip_if()/when() for conditional questions. Successor to inquirer.py with better async support.

Evaluated Mar 06, 2026 (0d ago) v2.x
Homepage ↗ Repo ↗ Developer Tools python questionary cli interactive prompts terminal inquirer
⚙ Agent Friendliness
69
/ 100
Can an agent use this?
🔒 Security
90
/ 100
Is it safe for agents?
⚡ Reliability
86
/ 100
Does it work consistently?

Score Breakdown

⚙ Agent Friendliness

MCP Quality
--
Documentation
88
Error Messages
85
Auth Simplicity
99
Rate Limits
99

🔒 Security

TLS Enforcement
92
Auth Strength
92
Scope Granularity
90
Dep. Hygiene
90
Secret Handling
88

Terminal UI library with no network calls. password() type masks input during typing but value is still a plain Python string after ask() — do not log or print password values. Validate user file paths from path() type before using in file operations.

⚡ Reliability

Uptime/SLA
85
Version Stability
85
Breaking Changes
85
Error Recovery
88
AF Security Reliability

Best When

Building interactive CLI tools and agent setup wizards — questionary provides polished arrow-key selection, validation, and colored output for excellent user experience in terminal tools.

Avoid When

CI/CD automation (no TTY), web interfaces, or when scripted non-interactive input is needed.

Use Cases

  • Agent CLI config wizard — import questionary; host = questionary.text('Database host?', default='localhost').ask(); port = questionary.text('Port?', default='5432', validate=lambda v: v.isdigit()).ask(); db = questionary.select('Database type?', choices=['postgresql', 'mysql', 'sqlite']).ask() — interactive setup; agent CLI guides user through configuration with validation and defaults
  • Agent confirmation prompt — action = questionary.select('What to do?', choices=['deploy', 'rollback', 'cancel']).ask(); if action == 'deploy': confirmed = questionary.confirm(f'Deploy to production?').ask(); if confirmed: execute_deploy() — select then confirm; agent dangerous action requires explicit confirmation; arrow-key selection prevents typos
  • Agent multi-select — features = questionary.checkbox('Enable features?', choices=[questionary.Choice('logging', checked=True), questionary.Choice('metrics'), questionary.Choice('tracing')]).ask() — multi-select with defaults; agent capability selection with pre-checked defaults; returns list of selected strings
  • Agent async prompts — import asyncio; async def setup(): name = await questionary.text('Agent name?').ask_async(); return name; asyncio.run(setup()) — async-compatible; agent async FastAPI startup uses ask_async(); doesn't block event loop during user input
  • Agent autocomplete input — tasks = ['analyze', 'generate', 'validate', 'deploy']; choice = questionary.autocomplete('Command?', choices=tasks, validate=lambda v: v in tasks).ask() — filtered autocomplete; agent CLI with many options filters as user types; validate ensures selection from valid list

Not For

  • Non-interactive environments — questionary requires TTY; CI/CD pipelines without TTY cause failures
  • Web or GUI interfaces — questionary is terminal-only; for web prompts use HTML forms, for GUI use tkinter
  • High-volume automation — questionary requires user interaction; for scripted input use argparse or click

Interface

REST API
No
GraphQL
No
gRPC
No
MCP Server
No
SDK
Yes
Webhooks
No

Authentication

Methods: none
OAuth: No Scopes: No

No auth — local terminal UI library.

Pricing

Model: open_source
Free tier: Yes
Requires CC: No

questionary is MIT licensed. Free for all use.

Agent Metadata

Pagination
none
Idempotent
Partial
Retry Guidance
Not documented

Known Gotchas

  • Returns None on Ctrl+C not KeyboardInterrupt — questionary.text('?').ask() returns None when user presses Ctrl+C; agent code must check: result = q.ask(); if result is None: sys.exit(0); forgetting None check causes AttributeError on result usage; use ask(kbi_msg='Cancelled') to raise KeyboardInterrupt instead
  • No TTY causes hanging or errors — in CI or piped environments (pytest, subprocess), questionary cannot get terminal input; agent CLI tools must detect TTY: import sys; if not sys.stdin.isatty(): use defaults; or test with --no-interactive flag that skips prompts
  • validate= receives the raw string before type coercion — validate=lambda v: v.isdigit() checks string input; agent code must not assume type in validator; for integer validation: check isdigit() in validator, convert after ask(); validate returns True for valid or string error message for invalid
  • checkbox() returns empty list not None for no selection — questionary.checkbox('Select:', choices=['a','b']).ask() returns [] if user selects nothing and presses Enter; agent code checking 'if result:' treats empty list as falsy — correct; but checking 'if result is None:' misses empty selection case
  • Choice values vs labels — questionary.Choice(title='Deploy to prod', value='deploy_prod') shows 'Deploy to prod' but returns 'deploy_prod'; agent code receives value not title string; for simple string choices: questionary.select('?', choices=['a', 'b']).ask() returns the string directly
  • ask_async() requires existing event loop — await questionary.text('?').ask_async() must run inside async context; cannot call ask_async() synchronously; agent code mixing sync/async must use asyncio.run() wrapper or ensure prompt is in async function; ask_async() uses asyncio keyboard interrupt handling different from sync ask()

Alternatives

Full Evaluation Report

Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for questionary.

$99

Scores are editorial opinions as of 2026-03-06.

5208
Packages Evaluated
26151
Need Evaluation
173
Need Re-evaluation
Community Powered