0
# Utilities and Customization
1
2
Styling, validation, separators, and utility functions for prompt customization and enhanced functionality.
3
4
## Capabilities
5
6
### Style Utilities
7
8
Functions and classes for customizing prompt appearance and creating consistent visual themes.
9
10
```python { .api }
11
def get_style(
12
style: Optional[Dict[str, str]] = None,
13
style_override: bool = True
14
) -> InquirerPyStyle
15
```
16
17
**Parameters:**
18
- **style**: Dictionary mapping style elements to color/format specifications
19
- **style_override**: When True, replaces all default styles; when False, merges with defaults
20
21
**Returns:** InquirerPyStyle object for use with prompts
22
23
**Style Elements:**
24
```python
25
style_keys = {
26
"question": "Question text color/format",
27
"answer": "User answer color/format",
28
"pointer": "Selection pointer color/format",
29
"highlighted": "Highlighted choice color/format",
30
"selected": "Selected items color/format (checkbox)",
31
"separator": "Separator line color/format",
32
"instruction": "Instruction text color/format",
33
"text": "General text color/format",
34
"disabled": "Disabled items color/format",
35
"fuzzy_prompt": "Fuzzy search prompt color/format",
36
"fuzzy_info": "Fuzzy search info color/format",
37
"fuzzy_match": "Fuzzy search match highlight"
38
}
39
```
40
41
**Usage Examples:**
42
43
Basic styling:
44
```python
45
from InquirerPy import inquirer
46
from InquirerPy.utils import get_style
47
48
# Create custom style
49
custom_style = get_style({
50
"question": "#ff6600 bold",
51
"answer": "#00aa44 bold",
52
"pointer": "#ff0066",
53
"highlighted": "#ff0066 bold",
54
"instruction": "#888888 italic"
55
})
56
57
# Use with any prompt
58
name = inquirer.text(
59
message="Enter name:",
60
style=custom_style
61
).execute()
62
```
63
64
Theme-based styling:
65
```python
66
# Dark theme
67
dark_theme = get_style({
68
"question": "#ffffff bold",
69
"answer": "#00ff00 bold",
70
"pointer": "#ffff00",
71
"highlighted": "#ffff00 bold reverse",
72
"selected": "#00ffff",
73
"separator": "#666666",
74
"instruction": "#cccccc",
75
"text": "#ffffff"
76
})
77
78
# Light theme
79
light_theme = get_style({
80
"question": "#000066 bold",
81
"answer": "#006600 bold",
82
"pointer": "#660066",
83
"highlighted": "#660066 bold reverse",
84
"selected": "#006666",
85
"separator": "#999999",
86
"instruction": "#666666",
87
"text": "#000000"
88
})
89
```
90
91
### Validation Classes
92
93
Pre-built validators for common input validation scenarios.
94
95
```python { .api }
96
class NumberValidator:
97
def __init__(
98
self,
99
message: str = "Input should be a number",
100
float_allowed: bool = False
101
): ...
102
103
def validate(self, document) -> None: ...
104
```
105
106
```python { .api }
107
class PathValidator:
108
def __init__(
109
self,
110
message: str = "Input is not a valid path",
111
is_file: bool = False,
112
is_dir: bool = False
113
): ...
114
115
def validate(self, document) -> None: ...
116
```
117
118
```python { .api }
119
class EmptyInputValidator:
120
def __init__(
121
self,
122
message: str = "Input cannot be empty"
123
): ...
124
125
def validate(self, document) -> None: ...
126
```
127
128
```python { .api }
129
class PasswordValidator:
130
def __init__(
131
self,
132
length: int = 8,
133
cap: bool = False,
134
special: bool = False,
135
number: bool = False,
136
message: str = "Password does not meet requirements"
137
): ...
138
139
def validate(self, document) -> None: ...
140
```
141
142
**Usage Examples:**
143
144
Number validation:
145
```python
146
from InquirerPy import inquirer
147
from InquirerPy.validator import NumberValidator
148
149
# Integer only
150
port = inquirer.text(
151
message="Port number:",
152
validate=NumberValidator(message="Please enter a valid port number")
153
).execute()
154
155
# Allow floats
156
price = inquirer.text(
157
message="Price:",
158
validate=NumberValidator(
159
message="Please enter a valid price",
160
float_allowed=True
161
)
162
).execute()
163
```
164
165
Path validation:
166
```python
167
from InquirerPy.validator import PathValidator
168
169
# File must exist
170
config_file = inquirer.filepath(
171
message="Config file:",
172
validate=PathValidator(
173
message="File must exist",
174
is_file=True
175
)
176
).execute()
177
178
# Directory must exist
179
output_dir = inquirer.filepath(
180
message="Output directory:",
181
validate=PathValidator(
182
message="Directory must exist",
183
is_dir=True
184
)
185
).execute()
186
```
187
188
Password validation:
189
```python
190
from InquirerPy.validator import PasswordValidator
191
192
# Complex password requirements
193
password = inquirer.secret(
194
message="Create password:",
195
validate=PasswordValidator(
196
length=12,
197
cap=True,
198
special=True,
199
number=True,
200
message="Password must be 12+ chars with uppercase, number, and special character"
201
)
202
).execute()
203
```
204
205
Custom validation:
206
```python
207
# Custom validator function
208
def validate_email(email):
209
import re
210
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
211
if not re.match(pattern, email):
212
return "Please enter a valid email address"
213
return True
214
215
email = inquirer.text(
216
message="Email address:",
217
validate=validate_email
218
).execute()
219
```
220
221
### Separator Class
222
223
Visual separator for organizing choices in list-based prompts.
224
225
```python { .api }
226
class Separator:
227
def __init__(self, line: str = "---------------") -> None: ...
228
229
def __str__(self) -> str: ...
230
```
231
232
**Usage Examples:**
233
234
Basic separators:
235
```python
236
from InquirerPy import inquirer
237
from InquirerPy.separator import Separator
238
239
framework = inquirer.select(
240
message="Choose framework:",
241
choices=[
242
"React",
243
"Vue.js",
244
"Angular",
245
Separator(),
246
"Django",
247
"Flask",
248
"FastAPI",
249
Separator("--- Other ---"),
250
"Express.js",
251
"Spring Boot"
252
]
253
).execute()
254
```
255
256
Custom separators:
257
```python
258
# Different separator styles
259
choices = [
260
"Option 1",
261
"Option 2",
262
Separator("═" * 20),
263
"Option 3",
264
Separator("--- Section B ---"),
265
"Option 4",
266
Separator(), # Default dashes
267
"Option 5"
268
]
269
270
selection = inquirer.select(message="Choose:", choices=choices).execute()
271
```
272
273
### Utility Functions
274
275
Helper functions for display, calculation, and prompt functionality.
276
277
```python { .api }
278
def calculate_height(
279
height: Optional[Union[int, str]],
280
max_height: Optional[Union[int, str]],
281
height_offset: int = 2
282
) -> Tuple[Optional[int], int]
283
```
284
285
Calculates optimal prompt height and max height based on terminal size with offset adjustment.
286
287
```python { .api }
288
def patched_print(*values) -> None
289
```
290
291
Thread-safe printing function that works correctly with prompt-toolkit applications.
292
293
```python { .api }
294
def color_print(
295
formatted_text: List[Tuple[str, str]],
296
style: Optional[Dict[str, str]] = None
297
) -> None
298
```
299
300
Prints colored text using prompt-toolkit formatted text and styling.
301
302
**Parameters:**
303
- **formatted_text**: List of (style_class, text) tuples
304
- **style**: Optional style dictionary mapping classes to colors
305
306
**Usage Examples:**
307
308
Colored output:
309
```python
310
from InquirerPy.utils import color_print
311
312
# Print colored messages using formatted text
313
color_print([("red", "Error: "), ("", "Something went wrong")])
314
color_print([("green", "Success: "), ("", "Operation completed")])
315
316
# With custom styling
317
color_print(
318
[("class:info", "Information: "), ("class:detail", "Process finished")],
319
style={"info": "blue bold", "detail": "cyan"}
320
)
321
```
322
323
Safe printing in prompts:
324
```python
325
from InquirerPy.utils import patched_print
326
327
# Use instead of regular print() when running prompts
328
def custom_prompt_with_output():
329
patched_print("Starting survey...")
330
331
result = inquirer.text(message="Name:").execute()
332
333
patched_print(f"Hello {result}!")
334
return result
335
```
336
337
## Exception Classes
338
339
Custom exceptions for error handling and prompt validation.
340
341
```python { .api }
342
class InvalidArgument(Exception):
343
def __init__(self, message: str = "invalid argument"): ...
344
```
345
346
```python { .api }
347
class RequiredKeyNotFound(Exception):
348
def __init__(self, message: str = "required key not found"): ...
349
```
350
351
**Usage Example:**
352
```python
353
from InquirerPy import prompt
354
from InquirerPy.exceptions import InvalidArgument, RequiredKeyNotFound
355
356
try:
357
questions = [
358
{"type": "invalid_type", "message": "Test"} # Invalid type
359
]
360
result = prompt(questions)
361
362
except RequiredKeyNotFound:
363
print("Question missing required fields")
364
365
except InvalidArgument as e:
366
print(f"Invalid question configuration: {e}")
367
```
368
369
## Constants and Symbols
370
371
Pre-defined Unicode symbols and constants for consistent visual appearance.
372
373
```python { .api }
374
# Available constants
375
INQUIRERPY_KEYBOARD_INTERRUPT = "INQUIRERPY_KEYBOARD_INTERRUPT"
376
INQUIRERPY_POINTER_SEQUENCE = "❯" # Default pointer symbol
377
INQUIRERPY_FILL_CIRCLE_SEQUENCE = "●" # Filled checkbox symbol
378
INQUIRERPY_EMPTY_CIRCLE_SEQUENCE = "○" # Empty checkbox symbol
379
INQUIRERPY_QMARK_SEQUENCE = "?" # Question mark symbol
380
```
381
382
**Usage Example:**
383
```python
384
from InquirerPy import inquirer
385
from InquirerPy.enum import (
386
INQUIRERPY_POINTER_SEQUENCE,
387
INQUIRERPY_FILL_CIRCLE_SEQUENCE,
388
INQUIRERPY_EMPTY_CIRCLE_SEQUENCE
389
)
390
391
# Custom symbols for checkbox
392
features = inquirer.checkbox(
393
message="Select features:",
394
choices=["Auth", "DB", "API"],
395
pointer="→",
396
enabled_symbol="✓",
397
disabled_symbol="✗"
398
).execute()
399
```
400
401
### Spinner Patterns
402
403
Pre-defined spinner patterns for prompts with loading states.
404
405
```python { .api }
406
class SPINNERS(NamedTuple):
407
dots: List[str] # ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
408
dots2: List[str] # ["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"]
409
line: List[str] # ["-", "\\", "|", "/"]
410
line2: List[str] # ["⠂", "-", "–", "—", "–", "-"]
411
pipe: List[str] # ["┤", "┘", "┴", "└", "├", "┌", "┬", "┐"]
412
star: List[str] # ["✶", "✸", "✹", "✺", "✹", "✷"]
413
star2: List[str] # ["+", "x", "*"]
414
flip: List[str] # ["_", "_", "_", "-", "`", "`", "'", "´", "-", "_", "_", "_"]
415
hamburger: List[str] # ["☱", "☲", "☴"]
416
grow_vertical: List[str] # ["▁", "▃", "▄", "▅", "▆", "▇", "▆", "▅", "▄", "▃"]
417
grow_horizontal: List[str] # ["▏", "▎", "▍", "▌", "▋", "▊", "▉", "▊", "▋", "▌", "▍", "▎"]
418
box_bounce: List[str] # ["▖", "▘", "▝", "▗"]
419
triangle: List[str] # ["◢", "◣", "◤", "◥"]
420
arc: List[str] # ["◜", "◠", "◝", "◞", "◡", "◟"]
421
```
422
423
**Usage Example:**
424
```python
425
from InquirerPy import inquirer
426
from InquirerPy.containers import SPINNERS
427
428
# Use predefined spinner patterns in prompts with async operations
429
result = inquirer.select(
430
message="Loading options...",
431
choices=async_load_choices, # Async function
432
spinner_pattern=SPINNERS.dots
433
).execute()
434
```
435
436
### File Path Completer
437
438
Auto-completion class for file system path input.
439
440
```python { .api }
441
class FilePathCompleter(Completer):
442
def __init__(
443
self,
444
only_directories: bool = False,
445
only_files: bool = False
446
): ...
447
```
448
449
**Parameters:**
450
- **only_directories**: Restrict completion to directories only
451
- **only_files**: Restrict completion to files only
452
453
**Usage Example:**
454
```python
455
from InquirerPy.prompts.filepath import FilePathCompleter
456
from InquirerPy import inquirer
457
458
# Custom completer for specific directory
459
custom_completer = FilePathCompleter(only_directories=True)
460
461
path = inquirer.text(
462
message="Enter directory path:",
463
completer=custom_completer
464
).execute()
465
```
466
467
## Type Definitions
468
469
Common type aliases used throughout the InquirerPy API for flexible parameter handling.
470
471
```python { .api }
472
# Message types - strings or functions returning strings
473
InquirerPyMessage = Union[str, Callable[..., str]]
474
475
# Default values - any type or functions returning any type
476
InquirerPyDefault = Union[Any, Callable[..., Any]]
477
478
# Choice lists - static lists or functions returning lists
479
InquirerPyListChoices = Union[List[Any], Callable[..., List[Any]]]
480
481
# Validation - Validator objects or boolean functions
482
InquirerPyValidate = Union[Validator, Callable[[Any], bool]]
483
484
# Keybindings - mapping of actions to key combinations
485
InquirerPyKeybindings = Dict[str, List[str]]
486
487
# Session results - question names/indices mapped to answers
488
InquirerPySessionResult = Dict[Union[str, int], Any]
489
490
# Question definitions - single question or list of questions
491
InquirerPyQuestions = Union[List[Dict[str, Any]], Dict[str, Any]]
492
493
# Style configuration
494
InquirerPyStyle = NamedTuple("InquirerPyStyle", [("style", Style)])
495
```