or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdhooks-extensions.mdindex.mdmain-api.mdrepository-handling.mdtemplate-processing.mduser-interaction.mdutilities-exceptions.md

user-interaction.mddocs/

0

# User Interaction

1

2

Interactive prompts for template variables with support for different input types including text, choices, boolean, and JSON inputs. This module handles all user interaction during the template generation process.

3

4

## Capabilities

5

6

### Main Prompt Functions

7

8

Core prompting functionality for gathering user input during template generation.

9

10

```python { .api }

11

def prompt_for_config(context, no_input=False):

12

"""

13

Main function to prompt user for project config.

14

15

Parameters:

16

- context: dict - Template context containing variables to prompt for

17

- no_input: bool - Skip prompts and use defaults if True

18

19

Returns:

20

dict - Dictionary of user responses to prompts

21

"""

22

23

def prompt_choice_for_config(cookiecutter_dict, env, key, options, no_input, prompts=None, prefix=""):

24

"""

25

Prompt for config choice from a list of options.

26

27

Parameters:

28

- cookiecutter_dict: dict - Current cookiecutter context

29

- env: Environment - Jinja2 environment for rendering

30

- key: str - Configuration key being prompted for

31

- options: list - Available choices

32

- no_input: bool - Skip prompt if True

33

- prompts: dict, optional - Custom prompt text

34

- prefix: str - Prefix for prompt display

35

36

Returns:

37

str - Selected choice

38

"""

39

```

40

41

### Variable Input Functions

42

43

Functions for different types of user input.

44

45

```python { .api }

46

def read_user_variable(var_name, default_value, prompts=None, prefix=""):

47

"""

48

Prompt user for variable input.

49

50

Parameters:

51

- var_name: str - Name of variable to prompt for

52

- default_value: Any - Default value to use

53

- prompts: dict, optional - Custom prompt messages

54

- prefix: str - Prefix for prompt display

55

56

Returns:

57

str - User input or default value

58

"""

59

60

def read_user_yes_no(var_name, default_value, prompts=None, prefix=""):

61

"""

62

Prompt for yes/no response.

63

64

Parameters:

65

- var_name: str - Name of variable to prompt for

66

- default_value: bool - Default boolean value

67

- prompts: dict, optional - Custom prompt messages

68

- prefix: str - Prefix for prompt display

69

70

Returns:

71

bool - User's yes/no response

72

"""

73

74

def read_user_choice(var_name, options, prompts=None, prefix=""):

75

"""

76

Prompt user to choose from options.

77

78

Parameters:

79

- var_name: str - Name of variable to prompt for

80

- options: list - List of available choices

81

- prompts: dict, optional - Custom prompt messages

82

- prefix: str - Prefix for prompt display

83

84

Returns:

85

str - Selected option

86

"""

87

88

def read_user_dict(var_name, default_value, prompts=None, prefix=""):

89

"""

90

Prompt for dictionary input.

91

92

Parameters:

93

- var_name: str - Name of variable to prompt for

94

- default_value: dict - Default dictionary value

95

- prompts: dict, optional - Custom prompt messages

96

- prefix: str - Prefix for prompt display

97

98

Returns:

99

dict - User-provided dictionary

100

"""

101

```

102

103

### Special Input Functions

104

105

Specialized prompting functions for specific use cases.

106

107

```python { .api }

108

def read_repo_password(question):

109

"""

110

Prompt for password input.

111

112

Parameters:

113

- question: str - Password prompt question

114

115

Returns:

116

str - Password entered by user (input hidden)

117

"""

118

119

def process_json(user_value, default_value=None):

120

"""

121

Load user input as JSON dict.

122

123

Parameters:

124

- user_value: str - JSON string from user input

125

- default_value: Any, optional - Default value if parsing fails

126

127

Returns:

128

dict - Parsed JSON dictionary

129

"""

130

```

131

132

### Template and Context Functions

133

134

Functions for handling template selection and variable rendering.

135

136

```python { .api }

137

def render_variable(env, raw, cookiecutter_dict):

138

"""

139

Render variable for user prompt.

140

141

Parameters:

142

- env: Environment - Jinja2 environment

143

- raw: str - Raw template variable string

144

- cookiecutter_dict: dict - Current cookiecutter context

145

146

Returns:

147

Any - Rendered variable value

148

"""

149

150

def prompt_choice_for_template(key, options, no_input):

151

"""

152

Prompt for template selection.

153

154

Parameters:

155

- key: str - Template key

156

- options: list - Available template options

157

- no_input: bool - Skip prompt if True

158

159

Returns:

160

str - Selected template

161

"""

162

163

def choose_nested_template(context, repo_dir, no_input=False):

164

"""

165

Prompt for nested template selection.

166

167

Parameters:

168

- context: dict - Template context

169

- repo_dir: str - Repository directory

170

- no_input: bool - Skip prompts if True

171

172

Returns:

173

str - Path to selected nested template

174

"""

175

176

def prompt_and_delete(path, no_input=False):

177

"""

178

Ask user about deleting existing files.

179

180

Parameters:

181

- path: str - Path to potentially delete

182

- no_input: bool - Skip prompt if True

183

184

Returns:

185

bool - True if user wants to delete

186

"""

187

```

188

189

## Prompt Classes

190

191

Custom prompt classes for specialized input types.

192

193

```python { .api }

194

class YesNoPrompt(Confirm):

195

"""Boolean prompt for yes/no questions."""

196

197

class JsonPrompt(PromptBase[dict]):

198

"""Prompt that returns dict from JSON string."""

199

```

200

201

## Constants

202

203

```python { .api }

204

DEFAULT_DISPLAY: str # Default display string ('default')

205

```

206

207

## Usage Examples

208

209

### Basic Variable Prompting

210

211

```python

212

from cookiecutter.prompt import read_user_variable, read_user_yes_no, read_user_choice

213

214

# Simple text input

215

project_name = read_user_variable(

216

var_name='project_name',

217

default_value='my-project',

218

prompts={'project_name': 'What is your project name?'}

219

)

220

221

# Yes/no prompt

222

use_docker = read_user_yes_no(

223

var_name='use_docker',

224

default_value=True,

225

prompts={'use_docker': 'Do you want Docker support?'}

226

)

227

228

# Choice from options

229

license_type = read_user_choice(

230

var_name='license',

231

options=['MIT', 'Apache-2.0', 'GPL-3.0', 'BSD-3-Clause'],

232

prompts={'license': 'Choose a license for your project'}

233

)

234

```

235

236

### Complete Configuration Prompting

237

238

```python

239

from cookiecutter.prompt import prompt_for_config

240

from cookiecutter.generate import generate_context

241

242

# Generate context from cookiecutter.json

243

context = generate_context('./template/cookiecutter.json')

244

245

# Prompt user for all configuration values

246

user_config = prompt_for_config(context, no_input=False)

247

248

print("User provided configuration:")

249

for key, value in user_config.items():

250

print(f" {key}: {value}")

251

```

252

253

### Advanced Input Types

254

255

```python

256

from cookiecutter.prompt import read_user_dict, process_json

257

258

# Dictionary input

259

database_config = read_user_dict(

260

var_name='database_settings',

261

default_value={'host': 'localhost', 'port': 5432},

262

prompts={'database_settings': 'Enter database configuration as JSON'}

263

)

264

265

# JSON processing

266

json_input = '{"name": "test", "version": "1.0.0"}'

267

parsed_config = process_json(json_input, default_value={})

268

```

269

270

### Custom Prompts with Context

271

272

```python

273

from cookiecutter.prompt import render_variable, prompt_choice_for_config

274

from cookiecutter.environment import StrictEnvironment

275

276

# Set up Jinja2 environment

277

env = StrictEnvironment()

278

279

# Render dynamic variable

280

cookiecutter_dict = {'project_name': 'my-project', 'year': '2024'}

281

rendered_value = render_variable(

282

env=env,

283

raw='{{cookiecutter.project_name}}-{{cookiecutter.year}}',

284

cookiecutter_dict=cookiecutter_dict

285

)

286

# Returns: 'my-project-2024'

287

288

# Dynamic choice prompting

289

framework_choice = prompt_choice_for_config(

290

cookiecutter_dict=cookiecutter_dict,

291

env=env,

292

key='framework',

293

options=['django', 'flask', 'fastapi'],

294

no_input=False,

295

prompts={'framework': 'Select a web framework'}

296

)

297

```

298

299

### Password and Security

300

301

```python

302

from cookiecutter.prompt import read_repo_password

303

304

# Secure password input

305

repo_password = read_repo_password(

306

"Enter password for private repository: "

307

)

308

# Password input is hidden from terminal display

309

```

310

311

### Template Selection

312

313

```python

314

from cookiecutter.prompt import choose_nested_template, prompt_choice_for_template

315

316

# Choose from nested templates

317

context = {

318

'cookiecutter': {

319

'template': ['basic', 'advanced', 'minimal'],

320

'templates': {

321

'basic': './templates/basic',

322

'advanced': './templates/advanced',

323

'minimal': './templates/minimal'

324

}

325

}

326

}

327

328

selected_template = choose_nested_template(

329

context=context,

330

repo_dir='./template-repo',

331

no_input=False

332

)

333

```

334

335

### Handling Existing Files

336

337

```python

338

from cookiecutter.prompt import prompt_and_delete

339

import os

340

341

output_path = './my-new-project'

342

if os.path.exists(output_path):

343

should_delete = prompt_and_delete(output_path, no_input=False)

344

if should_delete:

345

import shutil

346

shutil.rmtree(output_path)

347

print(f"Deleted existing directory: {output_path}")

348

else:

349

print("Keeping existing directory")

350

```

351

352

### No-Input Mode

353

354

```python

355

from cookiecutter.prompt import prompt_for_config

356

357

# Skip all prompts and use defaults

358

context = generate_context('./template/cookiecutter.json')

359

default_config = prompt_for_config(context, no_input=True)

360

361

# All values will be defaults from cookiecutter.json

362

print("Using default configuration:")

363

for key, value in default_config.items():

364

print(f" {key}: {value}")

365

```

366

367

### Custom Prompt Messages

368

369

```python

370

from cookiecutter.prompt import read_user_variable

371

372

# Custom prompt with detailed help

373

custom_prompts = {

374

'author_email': 'Enter your email address (will be used in setup.py and documentation)',

375

'version': 'Initial version number (use semantic versioning like 0.1.0)',

376

'description': 'Brief description of your project (one line)'

377

}

378

379

author_email = read_user_variable(

380

var_name='author_email',

381

default_value='user@example.com',

382

prompts=custom_prompts

383

)

384

385

version = read_user_variable(

386

var_name='version',

387

default_value='0.1.0',

388

prompts=custom_prompts

389

)

390

```