Skip to content

Repository files navigation

🐍🌈 pinq - Complete Python Binding for Inquire

Python 3.8+License: MIT

12

pinq is a production-grade, 100% complete Python binding for the Rust inquire CLI prompt library. It provides an idiomatic Python interface to create beautiful, interactive command-line prompts across all platforms.

Features

  • Complete API Coverage - Every public type, function, and configuration from inquire is exposed in Python

  • 🎨 Interactive Prompts - Text input, selections, multi-select, confirmations, passwords, dates, and more

  • Cross-Platform - Works perfectly on Linux, macOS, and Windows (including WSL)

  • 🔧 Fully Configurable - Defaults, help messages, page sizes, custom formatting

  • 🛡️ Type Safe - Full Python type hints for IDE support and type checking

  • 🚀 Production Ready - Built with PyO3, compiled to native code via Maturin

  • 🎯 Idiomatic Python - Builder pattern, Python enums, exception-based error handling

Installation

pip install pinq

Quick Start

Simple Text Prompt

importpinqname=pinq.prompt_text("What is your name? ")
print(f"Hello, {name}!")

Confirmation

importpinqifpinq.prompt_confirmation("Continue? "):
print("Continuing...")
else:
print("Canceled.")

Selection

importpinqlanguages= ["Python", "Rust", "Go", "JavaScript"]
choice=pinq.SelectPrompt("Pick a language:", languages).prompt()
print(f"You chose: {choice}")

Multi-Select

importpinqoptions= ["Apples", "Bananas", "Carrots", "Dates"]
selected=pinq.MultiSelectPrompt("Select fruits:", options).prompt()
print(f"Selected: {', '.join(selected)}")

Numbers

importpinqage=pinq.prompt_int("Your age: ")
price=pinq.prompt_float("Price: $")

Passwords

importpinqpassword=pinq.PasswordPrompt("Enter password: ").prompt()

Dates

importpinqdate=pinq.prompt_date("Select a date: ")
print(f"Selected: {date}") # YYYY-MM-DD format

Multi-Line Editor

importpinqtext=pinq.EditorPrompt("Write a message: ").prompt()

Builder Pattern

All prompts support method chaining for advanced configuration:

importpinqusername= (pinq.TextPrompt("Username: ")
.with_default("admin")
.with_help_message("System administrator")
.prompt())

Configuration Options

Text Prompts:

  • .with_default(value) - Default value
  • .with_help_message(text) - Help text
  • .with_page_size(n) - Pagination size

Select/MultiSelect:

  • .with_default(index) / .with_defaults(indices) - Default selections
  • .with_help_message(text) - Help text
  • .with_page_size(n) - Items per page

All Prompts:

  • .with_help_message(text) - Display help below prompt
  • .prompt_skippable() - Allow ESC to skip (returns None)

Prompt Types

ClassPurposeExample
TextPromptFree text inputUsername, email
ConfirmPromptYes/no questionDelete confirmation
PasswordPromptHidden text inputPassword
SelectPromptChoose one from listPick an option
MultiSelectPromptChoose multiple from listSelect features
IntPromptInteger inputCount, port number
FloatPromptFloat inputPrice, percentage
DateSelectPromptInteractive calendarMeeting date
EditorPromptMulti-line editorLong form text

One-Liners

For quick prompts without configuration:

importpinqname=pinq.prompt_text("Name: ")
confirm=pinq.prompt_confirmation("Continue? ")
age=pinq.prompt_int("Age: ")
price=pinq.prompt_float("Price: ")
password=pinq.prompt_secret("Password: ")
date=pinq.prompt_date("Date: ")

Error Handling

All prompts can raise RuntimeError for:

  • NotTTY - Not running in a terminal
  • IOError - Terminal communication error
  • OperationCanceled - User pressed Ctrl+C or ESC
  • InvalidConfiguration - Invalid prompt setup
  • Parse errors - Invalid input for typed prompts
importpinqtry:
age=pinq.prompt_int("Age: ")
exceptRuntimeErrorase:
print(f"Error: {e}")

Optional/Skippable Prompts

Use .prompt_skippable() to allow users to skip with ESC:

importpinqoptional_comment= (pinq.TextPrompt("Comment (optional): ")
.prompt_skippable())
ifoptional_commentisNone:
print("Skipped")
else:
print(f"Comment: {optional_comment}")

Comprehensive Documentation

Full documentation available in the docs/ directory:

Examples

User Registration

importpinqusername=pinq.prompt_text("Username: ")
password=pinq.PasswordPrompt("Password: ").prompt()
country=pinq.SelectPrompt("Country:", ["USA", "Canada", "UK"]).prompt()
newsletter=pinq.prompt_confirmation("Subscribe? ")
print(f"Registered: {username} from {country}")

Configuration Wizard

importpinqport= (pinq.IntPrompt("Port: ")
.with_default(3000)
.prompt())
features= (pinq.MultiSelectPrompt("Enable:",
["Auth", "Cache", "Logging"])
.with_defaults([0, 2])
.prompt())
env=pinq.SelectPrompt("Environment:",
["dev", "staging", "prod"]).prompt()
print(f"Config: port={port}, features={features}, env={env}")

Survey

importpinqname=pinq.prompt_text("Name: ")
rating=pinq.SelectPrompt("Rating:",
["Poor", "Fair", "Good", "Great"]).prompt()
feedback=pinq.EditorPrompt("Feedback:").prompt_skippable()
print(f"Survey from {name}: {rating}")
iffeedback:
print(f"Feedback: {feedback}")

Platform Support

  • ✅ Linux
  • ✅ macOS
  • ✅ Windows
  • ✅ WSL (Windows Subsystem for Linux)

Uses the default crossterm backend which works reliably everywhere.

API Reference

All types and functions are documented with full docstrings accessible via Python's help():

importpinqhelp(pinq.SelectPrompt)
help(pinq.prompt_int)

Performance

  • Compiled to native code - PyO3 + Maturin for maximum speed
  • Minimal overhead - Direct FFI to Rust implementation
  • No Python GIL - Concurrent use possible

Version Information

  • pinq: 0.1.0
  • inquire: 0.7
  • Python: 3.8+

License

MIT License - Same as inquire

Contributing

This is a complete, production-ready binding. For bugs or feature requests related to the core prompt functionality, please refer to the inquire repository.

Related Projects

  • inquire - The original Rust library
  • PyO3 - Python bindings for Rust
  • Maturin - Python package build tool

Troubleshooting

"Input is not a TTY" Error

This occurs when running in a non-interactive environment:

importsysifnotsys.stdin.isatty():
print("Cannot use interactive prompts in non-TTY mode")

Ctrl+C Behavior

Pressing Ctrl+C raises RuntimeError with message "Operation canceled by user":

try:
result=pinq.prompt_text("Input: ")
exceptRuntimeErrorase:
if"canceled"instr(e):
print("User interrupted")

Testing with Mocks

Mock pinq functions in unit tests:

fromunittest.mockimportpatch@patch('pinq.prompt_text')deftest_my_function(mock_prompt):
mock_prompt.return_value="test value"# ... test code ...

Support

Acknowledgments

Built with:


Start building interactive CLI applications with Python today! 🚀

About

🐍🌈🌟 Python binding for the Rust inquire CLI prompt library 🖊️🔒💡 — Text, Password, Select, MultiSelect, Date, Editor & more!

Topics

Resources

Stars

5 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages